From 07c8bfb4e2f5aa241394e503f14eb76b4be2158d Mon Sep 17 00:00:00 2001 From: OpenTelemetry Bot <107717825+opentelemetrybot@users.noreply.github.com> Date: Fri, 8 Sep 2023 09:28:54 -0700 Subject: [PATCH 001/901] Update version to 1.31.0 (#5802) --- CHANGELOG.md | 2 ++ version.gradle.kts | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4afb3d435c4..2e5cba6f72f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,8 @@ ## Unreleased +## Version 1.30.0 (2023-09-08) + ### API #### Incubator diff --git a/version.gradle.kts b/version.gradle.kts index 40a536f0418..c7554cc8708 100644 --- a/version.gradle.kts +++ b/version.gradle.kts @@ -1,7 +1,7 @@ val snapshot = true allprojects { - var ver = "1.30.0" + var ver = "1.31.0" val release = findProperty("otel.release") if (release != null) { ver += "-" + release From 3dd2f41037dcf2a854b6f60a4ae53421da183f1c Mon Sep 17 00:00:00 2001 From: Trask Stalnaker Date: Fri, 8 Sep 2023 09:46:09 -0700 Subject: [PATCH 002/901] Less renovate (pin docker/build-push-action@v4) (#5800) --- .github/workflows/build-tracecontext-testsuite.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build-tracecontext-testsuite.yml b/.github/workflows/build-tracecontext-testsuite.yml index 750a307b017..23c2a6d951f 100644 --- a/.github/workflows/build-tracecontext-testsuite.yml +++ b/.github/workflows/build-tracecontext-testsuite.yml @@ -23,7 +23,7 @@ jobs: password: ${{ secrets.GITHUB_TOKEN }} - name: Build and push - uses: docker/build-push-action@v4.2.1 + uses: docker/build-push-action@v4 with: context: integration-tests/tracecontext/docker push: true From a59b516f1b3d2b284f3d0998ffd8eb4d3e549c53 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 8 Sep 2023 14:07:55 -0500 Subject: [PATCH 003/901] Update dependency com.google.api.grpc:proto-google-common-protos to v2.24.0 (#5804) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- dependencyManagement/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index dc66b95b572..7351dcf67ba 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -54,7 +54,7 @@ val DEPENDENCIES = listOf( "io.prometheus:simpleclient_httpserver:${prometheusClientVersion}", "javax.annotation:javax.annotation-api:1.3.2", "com.github.stefanbirkner:system-rules:1.19.0", - "com.google.api.grpc:proto-google-common-protos:2.23.0", + "com.google.api.grpc:proto-google-common-protos:2.24.0", "com.google.code.findbugs:jsr305:3.0.2", "com.google.guava:guava-beta-checker:1.0", "com.sun.net.httpserver:http:20070405", From d20412413488ae7a8c632a38ca676b7075a9e61a Mon Sep 17 00:00:00 2001 From: jack-berg <34418638+jack-berg@users.noreply.github.com> Date: Mon, 11 Sep 2023 09:32:13 -0500 Subject: [PATCH 004/901] Post release 1.30.0 (#5805) --- README.md | 83 +++++++++---------- .../1.30.0_vs_1.29.0/opentelemetry-api.txt | 2 + .../opentelemetry-context.txt | 2 + .../opentelemetry-exporter-common.txt | 2 + .../opentelemetry-exporter-jaeger-thrift.txt | 2 + .../opentelemetry-exporter-jaeger.txt | 2 + .../opentelemetry-exporter-logging-otlp.txt | 2 + .../opentelemetry-exporter-logging.txt | 10 +++ .../opentelemetry-exporter-otlp-common.txt | 2 + .../opentelemetry-exporter-otlp.txt | 2 + ...y-exporter-sender-grpc-managed-channel.txt | 2 + .../opentelemetry-exporter-sender-okhttp.txt | 2 + .../opentelemetry-exporter-zipkin.txt | 4 + .../opentelemetry-extension-kotlin.txt | 2 + ...ntelemetry-extension-trace-propagators.txt | 2 + .../opentelemetry-opentracing-shim.txt | 2 + .../opentelemetry-sdk-common.txt | 2 + ...emetry-sdk-extension-autoconfigure-spi.txt | 2 + ...ntelemetry-sdk-extension-autoconfigure.txt | 2 + ...ry-sdk-extension-jaeger-remote-sampler.txt | 2 + .../opentelemetry-sdk-logs.txt | 2 + .../opentelemetry-sdk-metrics.txt | 4 + .../opentelemetry-sdk-testing.txt | 2 + .../opentelemetry-sdk-trace.txt | 2 + .../1.30.0_vs_1.29.0/opentelemetry-sdk.txt | 2 + .../opentelemetry-exporter-logging.txt | 10 +-- .../opentelemetry-exporter-zipkin.txt | 4 +- .../opentelemetry-sdk-metrics.txt | 4 +- 28 files changed, 104 insertions(+), 57 deletions(-) create mode 100644 docs/apidiffs/1.30.0_vs_1.29.0/opentelemetry-api.txt create mode 100644 docs/apidiffs/1.30.0_vs_1.29.0/opentelemetry-context.txt create mode 100644 docs/apidiffs/1.30.0_vs_1.29.0/opentelemetry-exporter-common.txt create mode 100644 docs/apidiffs/1.30.0_vs_1.29.0/opentelemetry-exporter-jaeger-thrift.txt create mode 100644 docs/apidiffs/1.30.0_vs_1.29.0/opentelemetry-exporter-jaeger.txt create mode 100644 docs/apidiffs/1.30.0_vs_1.29.0/opentelemetry-exporter-logging-otlp.txt create mode 100644 docs/apidiffs/1.30.0_vs_1.29.0/opentelemetry-exporter-logging.txt create mode 100644 docs/apidiffs/1.30.0_vs_1.29.0/opentelemetry-exporter-otlp-common.txt create mode 100644 docs/apidiffs/1.30.0_vs_1.29.0/opentelemetry-exporter-otlp.txt create mode 100644 docs/apidiffs/1.30.0_vs_1.29.0/opentelemetry-exporter-sender-grpc-managed-channel.txt create mode 100644 docs/apidiffs/1.30.0_vs_1.29.0/opentelemetry-exporter-sender-okhttp.txt create mode 100644 docs/apidiffs/1.30.0_vs_1.29.0/opentelemetry-exporter-zipkin.txt create mode 100644 docs/apidiffs/1.30.0_vs_1.29.0/opentelemetry-extension-kotlin.txt create mode 100644 docs/apidiffs/1.30.0_vs_1.29.0/opentelemetry-extension-trace-propagators.txt create mode 100644 docs/apidiffs/1.30.0_vs_1.29.0/opentelemetry-opentracing-shim.txt create mode 100644 docs/apidiffs/1.30.0_vs_1.29.0/opentelemetry-sdk-common.txt create mode 100644 docs/apidiffs/1.30.0_vs_1.29.0/opentelemetry-sdk-extension-autoconfigure-spi.txt create mode 100644 docs/apidiffs/1.30.0_vs_1.29.0/opentelemetry-sdk-extension-autoconfigure.txt create mode 100644 docs/apidiffs/1.30.0_vs_1.29.0/opentelemetry-sdk-extension-jaeger-remote-sampler.txt create mode 100644 docs/apidiffs/1.30.0_vs_1.29.0/opentelemetry-sdk-logs.txt create mode 100644 docs/apidiffs/1.30.0_vs_1.29.0/opentelemetry-sdk-metrics.txt create mode 100644 docs/apidiffs/1.30.0_vs_1.29.0/opentelemetry-sdk-testing.txt create mode 100644 docs/apidiffs/1.30.0_vs_1.29.0/opentelemetry-sdk-trace.txt create mode 100644 docs/apidiffs/1.30.0_vs_1.29.0/opentelemetry-sdk.txt diff --git a/README.md b/README.md index e912e7ab4ce..a71c35d6ee0 100644 --- a/README.md +++ b/README.md @@ -91,7 +91,7 @@ dependency versions in sync. io.opentelemetry opentelemetry-bom - 1.29.0 + 1.30.0 pom import @@ -110,7 +110,7 @@ dependency versions in sync. ```groovy dependencies { - implementation platform("io.opentelemetry:opentelemetry-bom:1.29.0") + implementation platform("io.opentelemetry:opentelemetry-bom:1.30.0") implementation('io.opentelemetry:opentelemetry-api') } ``` @@ -119,8 +119,8 @@ Note that if you want to use any artifacts that have not fully stabilized yet (s ```groovy dependencies { - implementation platform("io.opentelemetry:opentelemetry-bom:1.29.0") - implementation platform('io.opentelemetry:opentelemetry-bom-alpha:1.29.0-alpha') + implementation platform("io.opentelemetry:opentelemetry-bom:1.30.0") + implementation platform('io.opentelemetry:opentelemetry-bom-alpha:1.30.0-alpha') implementation('io.opentelemetry:opentelemetry-api') implementation('io.opentelemetry:opentelemetry-semconv') @@ -148,7 +148,7 @@ We strongly recommend using our published BOM to keep all dependency versions in io.opentelemetry opentelemetry-bom - 1.30.0-SNAPSHOT + 1.31.0-SNAPSHOT pom import @@ -171,7 +171,7 @@ repositories { } dependencies { - implementation platform("io.opentelemetry:opentelemetry-bom:1.30.0-SNAPSHOT") + implementation platform("io.opentelemetry:opentelemetry-bom:1.31.0-SNAPSHOT") implementation('io.opentelemetry:opentelemetry-api') } ``` @@ -216,54 +216,53 @@ dependency as follows, replacing `{{artifact-id}}` with the value from the "Arti | Component | Description | Artifact ID | Version | Javadoc | |----------------------------------------------|----------------------------------------|---------------------------|-------------------------------------------------------------|---------| -| [Bill of Materials (BOM)](./bom) | Bill of materials for stable artifacts | `opentelemetry-bom` | 1.29.0 | N/A | -| [Alpha Bill of Materials (BOM)](./bom-alpha) | Bill of materials for alpha artifacts | `opentelemetry-bom-alpha` | 1.29.0-alpha | N/A | +| [Bill of Materials (BOM)](./bom) | Bill of materials for stable artifacts | `opentelemetry-bom` | 1.30.0 | N/A | +| [Alpha Bill of Materials (BOM)](./bom-alpha) | Bill of materials for alpha artifacts | `opentelemetry-bom-alpha` | 1.30.0-alpha | N/A | ### API - -| Component | Description | Artifact ID | Version | Javadoc | -| --------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------- | ----------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| [API](./api/all) | OpenTelemetry API, including metrics, traces, baggage, context | `opentelemetry-api` | 1.29.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-api.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-api) | -| [Events API](./api/events) | OpenTelemetry Event API for emitting events. | `opentelemetry-api-events` | 1.29.0-alpha | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-api-events.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-api-events) | -| [Context API](./context) | OpenTelemetry context API | `opentelemetry-context` | 1.29.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-context.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-context) | -| [Semantic Conventions](./semconv) | Generated code for OpenTelemetry semantic conventions (deprecated, moved to [open-telemetry/semantic-conventions-java](https://github.com/open-telemetry/semantic-conventions-java)) | `opentelemetry-semconv` | 1.29.0-alpha | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-semconv.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-semconv) | +| Component | Description | Artifact ID | Version | Javadoc | +|-----------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|----------------------------|-------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------| +| [API](./api/all) | OpenTelemetry API, including metrics, traces, baggage, context | `opentelemetry-api` | 1.30.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-api.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-api) | +| [Events API](./api/events) | OpenTelemetry Event API for emitting events. | `opentelemetry-api-events` | 1.30.0-alpha | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-api-events.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-api-events) | +| [Context API](./context) | OpenTelemetry context API | `opentelemetry-context` | 1.30.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-context.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-context) | +| [Semantic Conventions](./semconv) | Generated code for OpenTelemetry semantic conventions (deprecated, moved to [open-telemetry/semantic-conventions-java](https://github.com/open-telemetry/semantic-conventions-java)) | `opentelemetry-semconv` | 1.30.0-alpha | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-semconv.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-semconv) | ### API Extensions | Component | Description | Artifact ID | Version | Javadoc | |---------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|---------------------------------------------|-------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| [Kotlin Extension](./extensions/kotlin) | Context extension for coroutines | `opentelemetry-extension-kotlin` | 1.29.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-extension-kotlin.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-extension-kotlin) | -| [Trace Propagators Extension](./extensions/trace-propagators) | Trace propagators, including B3, Jaeger, OT Trace | `opentelemetry-extension-trace-propagators` | 1.29.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-extension-trace-propagators.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-extension-trace-propagators) | -| [Incubator Extension](./extensions/incubator) | API incubator, including pass through propagator, and extended tracer | `opentelemetry-extension-incubator` | 1.29.0-alpha | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-extension-incubator.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-extension-incubator) | +| [Kotlin Extension](./extensions/kotlin) | Context extension for coroutines | `opentelemetry-extension-kotlin` | 1.30.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-extension-kotlin.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-extension-kotlin) | +| [Trace Propagators Extension](./extensions/trace-propagators) | Trace propagators, including B3, Jaeger, OT Trace | `opentelemetry-extension-trace-propagators` | 1.30.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-extension-trace-propagators.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-extension-trace-propagators) | +| [Incubator Extension](./extensions/incubator) | API incubator, including pass through propagator, and extended tracer | `opentelemetry-extension-incubator` | 1.30.0-alpha | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-extension-incubator.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-extension-incubator) | ### SDK | Component | Description | Artifact ID | Version | Javadoc | |------------------------------|--------------------------------------------------------|-----------------------------|---------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| [SDK](./sdk/all) | OpenTelemetry SDK, including metrics, traces, and logs | `opentelemetry-sdk` | 1.29.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk) | -| [Metrics SDK](./sdk/metrics) | OpenTelemetry metrics SDK | `opentelemetry-sdk-metrics` | 1.29.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-metrics.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-metrics) | -| [Trace SDK](./sdk/trace) | OpenTelemetry trace SDK | `opentelemetry-sdk-trace` | 1.29.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-trace.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-trace) | -| [Log SDK](./sdk/logs) | OpenTelemetry log SDK | `opentelemetry-sdk-logs` | 1.29.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-logs.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-logs) | -| [SDK Common](./sdk/common) | Shared SDK components | `opentelemetry-sdk-common` | 1.29.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-common.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-common) | -| [SDK Testing](./sdk/testing) | Components for testing OpenTelemetry instrumentation | `opentelemetry-sdk-testing` | 1.29.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-testing.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-testing) | +| [SDK](./sdk/all) | OpenTelemetry SDK, including metrics, traces, and logs | `opentelemetry-sdk` | 1.30.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk) | +| [Metrics SDK](./sdk/metrics) | OpenTelemetry metrics SDK | `opentelemetry-sdk-metrics` | 1.30.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-metrics.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-metrics) | +| [Trace SDK](./sdk/trace) | OpenTelemetry trace SDK | `opentelemetry-sdk-trace` | 1.30.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-trace.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-trace) | +| [Log SDK](./sdk/logs) | OpenTelemetry log SDK | `opentelemetry-sdk-logs` | 1.30.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-logs.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-logs) | +| [SDK Common](./sdk/common) | Shared SDK components | `opentelemetry-sdk-common` | 1.30.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-common.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-common) | +| [SDK Testing](./sdk/testing) | Components for testing OpenTelemetry instrumentation | `opentelemetry-sdk-testing` | 1.30.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-testing.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-testing) | ### SDK Exporters | Component | Description | Artifact ID | Version | Javadoc | |-----------------------------------------------------------------------|------------------------------------------------------------------------------|------------------------------------------------------|-------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| [OTLP Exporters](./exporters/otlp/all) | OTLP gRPC & HTTP exporters, including traces, metrics, and logs | `opentelemetry-exporter-otlp` | 1.29.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-otlp.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-otlp) | -| [OTLP Logging Exporters](./exporters/logging-otlp) | Logging exporters in OTLP JSON encoding, including traces, metrics, and logs | `opentelemetry-exporter-logging-otlp` | 1.29.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-logging-otlp.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-logging-otlp) | -| [OTLP Common](./exporters/otlp/common) | Shared OTLP components (internal) | `opentelemetry-exporter-otlp-common` | 1.29.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-otlp-common.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-otlp-common) | -| [Jaeger gRPC Exporter](./exporters/jaeger) | Jaeger gRPC trace exporter (deprecated [1]) | `opentelemetry-exporter-jaeger` | 1.29.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-jaeger.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-jaeger) | -| [Jaeger Thrift Exporter](./exporters/jaeger-thrift) | Jaeger thrift trace exporter (deprecated [1]) | `opentelemetry-exporter-jaeger-thift` | 1.29.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-jaeger-thrift.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-jaeger-thrift) | -| [Logging Exporter](./exporters/logging) | Logging exporters, including metrics, traces, and logs | `opentelemetry-exporter-logging` | 1.29.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-logging.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-logging) | -| [Zipkin Exporter](./exporters/zipkin) | Zipkin trace exporter | `opentelemetry-exporter-zipkin` | 1.29.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-zipkin.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-zipkin) | -| [Prometheus Exporter](./exporters/prometheus) | Prometheus metric exporter | `opentelemetry-exporter-prometheus` | 1.29.0-alpha | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-prometheus.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-prometheus) | -| [Exporter Common](./exporters/common) | Shared exporter components (internal) | `opentelemetry-exporter-common` | 1.29.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-common.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-common) | -| [OkHttp Sender](./exporters/sender/okhttp) | OkHttp implementation of HttpSender (internal) | `opentelemetry-exporter-sender-okhttp` | 1.29.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-sender-okhttp.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-sender-okhttp) | -| [JDK Sender](./exporters/sender/okhttp) | Java 11+ native HttpClient implementation of HttpSender (internal) | `opentelemetry-exporter-sender-jdk` | 1.29.0-alpha | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-sender-jdk.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-sender-jdk) | | -| [gRPC ManagedChannel Sender](./exporters/sender/grpc-managed-channel) | gRPC ManagedChannel implementation of GrpcSender (internal) | `opentelemetry-exporter-sender-grpc-managed-channel` | 1.29.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-sender-grpc-managed-channel.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-sender-grpc-managed-channel) | | +| [OTLP Exporters](./exporters/otlp/all) | OTLP gRPC & HTTP exporters, including traces, metrics, and logs | `opentelemetry-exporter-otlp` | 1.30.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-otlp.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-otlp) | +| [OTLP Logging Exporters](./exporters/logging-otlp) | Logging exporters in OTLP JSON encoding, including traces, metrics, and logs | `opentelemetry-exporter-logging-otlp` | 1.30.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-logging-otlp.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-logging-otlp) | +| [OTLP Common](./exporters/otlp/common) | Shared OTLP components (internal) | `opentelemetry-exporter-otlp-common` | 1.30.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-otlp-common.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-otlp-common) | +| [Jaeger gRPC Exporter](./exporters/jaeger) | Jaeger gRPC trace exporter (deprecated [1]) | `opentelemetry-exporter-jaeger` | 1.30.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-jaeger.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-jaeger) | +| [Jaeger Thrift Exporter](./exporters/jaeger-thrift) | Jaeger thrift trace exporter (deprecated [1]) | `opentelemetry-exporter-jaeger-thift` | 1.30.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-jaeger-thrift.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-jaeger-thrift) | +| [Logging Exporter](./exporters/logging) | Logging exporters, including metrics, traces, and logs | `opentelemetry-exporter-logging` | 1.30.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-logging.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-logging) | +| [Zipkin Exporter](./exporters/zipkin) | Zipkin trace exporter | `opentelemetry-exporter-zipkin` | 1.30.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-zipkin.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-zipkin) | +| [Prometheus Exporter](./exporters/prometheus) | Prometheus metric exporter | `opentelemetry-exporter-prometheus` | 1.30.0-alpha | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-prometheus.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-prometheus) | +| [Exporter Common](./exporters/common) | Shared exporter components (internal) | `opentelemetry-exporter-common` | 1.30.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-common.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-common) | +| [OkHttp Sender](./exporters/sender/okhttp) | OkHttp implementation of HttpSender (internal) | `opentelemetry-exporter-sender-okhttp` | 1.30.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-sender-okhttp.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-sender-okhttp) | +| [JDK Sender](./exporters/sender/okhttp) | Java 11+ native HttpClient implementation of HttpSender (internal) | `opentelemetry-exporter-sender-jdk` | 1.30.0-alpha | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-sender-jdk.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-sender-jdk) | | +| [gRPC ManagedChannel Sender](./exporters/sender/grpc-managed-channel) | gRPC ManagedChannel implementation of GrpcSender (internal) | `opentelemetry-exporter-sender-grpc-managed-channel` | 1.30.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-sender-grpc-managed-channel.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-sender-grpc-managed-channel) | | **[1]**: Jaeger now has [native support for OTLP](https://opentelemetry.io/blog/2022/jaeger-native-otlp/) and jaeger @@ -276,17 +275,17 @@ additional versions will be published. | Component | Description | Artifact ID | Version | Javadoc | |-------------------------------------------------------------------------------|------------------------------------------------------------------------------------|-----------------------------------------------------|-------------------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| [SDK Autoconfigure](./sdk-extensions/autoconfigure) | Autoconfigure OpenTelemetry SDK from env vars, system properties, and SPI | `opentelemetry-sdk-extension-autoconfigure` | 1.29.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-extension-autoconfigure.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-extension-autoconfigure) | -| [SDK Autoconfigure SPI](./sdk-extensions/autoconfigure-spi) | Service Provider Interface (SPI) definitions for autoconfigure | `opentelemetry-sdk-extension-autoconfigure-spi` | 1.29.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-extension-autoconfigure-spi.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-extension-autoconfigure-spi) | -| [SDK Jaeger Remote Sampler Extension](./sdk-extensions/jaeger-remote-sampler) | Sampler which obtains sampling configuration from remote Jaeger server | `opentelemetry-sdk-extension-jaeger-remote-sampler` | 1.29.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-extension-jaeger-remote-sampler.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-extension-jaeger-remote-sampler) | -| [SDK Incubator](./sdk-extensions/incubator) | SDK incubator, including YAML based view configuration, LeakDetectingSpanProcessor | `opentelemetry-sdk-extension-incubator` | 1.29.0-alpha | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-extension-incubator.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-extension-incubator) | +| [SDK Autoconfigure](./sdk-extensions/autoconfigure) | Autoconfigure OpenTelemetry SDK from env vars, system properties, and SPI | `opentelemetry-sdk-extension-autoconfigure` | 1.30.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-extension-autoconfigure.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-extension-autoconfigure) | +| [SDK Autoconfigure SPI](./sdk-extensions/autoconfigure-spi) | Service Provider Interface (SPI) definitions for autoconfigure | `opentelemetry-sdk-extension-autoconfigure-spi` | 1.30.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-extension-autoconfigure-spi.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-extension-autoconfigure-spi) | +| [SDK Jaeger Remote Sampler Extension](./sdk-extensions/jaeger-remote-sampler) | Sampler which obtains sampling configuration from remote Jaeger server | `opentelemetry-sdk-extension-jaeger-remote-sampler` | 1.30.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-extension-jaeger-remote-sampler.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-extension-jaeger-remote-sampler) | +| [SDK Incubator](./sdk-extensions/incubator) | SDK incubator, including YAML based view configuration, LeakDetectingSpanProcessor | `opentelemetry-sdk-extension-incubator` | 1.30.0-alpha | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-extension-incubator.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-extension-incubator) | ### Shims | Component | Description | Artifact ID | Version | Javadoc | |----------------------------------------|--------------------------------------------------------------|----------------------------------|-------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| [OpenCensus Shim](./opencensus-shim) | Bridge opencensus metrics into the OpenTelemetry metrics SDK | `opentelemetry-opencensus-shim` | 1.29.0-alpha | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-opencensus-shim.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-opencensus-shim) | -| [OpenTracing Shim](./opentracing-shim) | Bridge opentracing spans into the OpenTelemetry trace API | `opentelemetry-opentracing-shim` | 1.29.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-opentracing-shim.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-opentracing-shim) | +| [OpenCensus Shim](./opencensus-shim) | Bridge opencensus metrics into the OpenTelemetry metrics SDK | `opentelemetry-opencensus-shim` | 1.30.0-alpha | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-opencensus-shim.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-opencensus-shim) | +| [OpenTracing Shim](./opentracing-shim) | Bridge opentracing spans into the OpenTelemetry trace API | `opentelemetry-opentracing-shim` | 1.30.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-opentracing-shim.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-opentracing-shim) | ## Contributing diff --git a/docs/apidiffs/1.30.0_vs_1.29.0/opentelemetry-api.txt b/docs/apidiffs/1.30.0_vs_1.29.0/opentelemetry-api.txt new file mode 100644 index 00000000000..df26146497b --- /dev/null +++ b/docs/apidiffs/1.30.0_vs_1.29.0/opentelemetry-api.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of against +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.30.0_vs_1.29.0/opentelemetry-context.txt b/docs/apidiffs/1.30.0_vs_1.29.0/opentelemetry-context.txt new file mode 100644 index 00000000000..df26146497b --- /dev/null +++ b/docs/apidiffs/1.30.0_vs_1.29.0/opentelemetry-context.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of against +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.30.0_vs_1.29.0/opentelemetry-exporter-common.txt b/docs/apidiffs/1.30.0_vs_1.29.0/opentelemetry-exporter-common.txt new file mode 100644 index 00000000000..df26146497b --- /dev/null +++ b/docs/apidiffs/1.30.0_vs_1.29.0/opentelemetry-exporter-common.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of against +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.30.0_vs_1.29.0/opentelemetry-exporter-jaeger-thrift.txt b/docs/apidiffs/1.30.0_vs_1.29.0/opentelemetry-exporter-jaeger-thrift.txt new file mode 100644 index 00000000000..df26146497b --- /dev/null +++ b/docs/apidiffs/1.30.0_vs_1.29.0/opentelemetry-exporter-jaeger-thrift.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of against +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.30.0_vs_1.29.0/opentelemetry-exporter-jaeger.txt b/docs/apidiffs/1.30.0_vs_1.29.0/opentelemetry-exporter-jaeger.txt new file mode 100644 index 00000000000..df26146497b --- /dev/null +++ b/docs/apidiffs/1.30.0_vs_1.29.0/opentelemetry-exporter-jaeger.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of against +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.30.0_vs_1.29.0/opentelemetry-exporter-logging-otlp.txt b/docs/apidiffs/1.30.0_vs_1.29.0/opentelemetry-exporter-logging-otlp.txt new file mode 100644 index 00000000000..df26146497b --- /dev/null +++ b/docs/apidiffs/1.30.0_vs_1.29.0/opentelemetry-exporter-logging-otlp.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of against +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.30.0_vs_1.29.0/opentelemetry-exporter-logging.txt b/docs/apidiffs/1.30.0_vs_1.29.0/opentelemetry-exporter-logging.txt new file mode 100644 index 00000000000..ec040faaf8b --- /dev/null +++ b/docs/apidiffs/1.30.0_vs_1.29.0/opentelemetry-exporter-logging.txt @@ -0,0 +1,10 @@ +Comparing source compatibility of against +*** MODIFIED CLASS: PUBLIC FINAL io.opentelemetry.exporter.logging.LoggingMetricExporter (not serializable) + === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 + +++ NEW METHOD: PUBLIC(+) java.lang.String toString() +*** MODIFIED CLASS: PUBLIC FINAL io.opentelemetry.exporter.logging.LoggingSpanExporter (not serializable) + === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 + +++ NEW METHOD: PUBLIC(+) java.lang.String toString() +*** MODIFIED CLASS: PUBLIC io.opentelemetry.exporter.logging.SystemOutLogRecordExporter (not serializable) + === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 + +++ NEW METHOD: PUBLIC(+) java.lang.String toString() diff --git a/docs/apidiffs/1.30.0_vs_1.29.0/opentelemetry-exporter-otlp-common.txt b/docs/apidiffs/1.30.0_vs_1.29.0/opentelemetry-exporter-otlp-common.txt new file mode 100644 index 00000000000..df26146497b --- /dev/null +++ b/docs/apidiffs/1.30.0_vs_1.29.0/opentelemetry-exporter-otlp-common.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of against +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.30.0_vs_1.29.0/opentelemetry-exporter-otlp.txt b/docs/apidiffs/1.30.0_vs_1.29.0/opentelemetry-exporter-otlp.txt new file mode 100644 index 00000000000..df26146497b --- /dev/null +++ b/docs/apidiffs/1.30.0_vs_1.29.0/opentelemetry-exporter-otlp.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of against +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.30.0_vs_1.29.0/opentelemetry-exporter-sender-grpc-managed-channel.txt b/docs/apidiffs/1.30.0_vs_1.29.0/opentelemetry-exporter-sender-grpc-managed-channel.txt new file mode 100644 index 00000000000..df26146497b --- /dev/null +++ b/docs/apidiffs/1.30.0_vs_1.29.0/opentelemetry-exporter-sender-grpc-managed-channel.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of against +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.30.0_vs_1.29.0/opentelemetry-exporter-sender-okhttp.txt b/docs/apidiffs/1.30.0_vs_1.29.0/opentelemetry-exporter-sender-okhttp.txt new file mode 100644 index 00000000000..df26146497b --- /dev/null +++ b/docs/apidiffs/1.30.0_vs_1.29.0/opentelemetry-exporter-sender-okhttp.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of against +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.30.0_vs_1.29.0/opentelemetry-exporter-zipkin.txt b/docs/apidiffs/1.30.0_vs_1.29.0/opentelemetry-exporter-zipkin.txt new file mode 100644 index 00000000000..772e014e5a0 --- /dev/null +++ b/docs/apidiffs/1.30.0_vs_1.29.0/opentelemetry-exporter-zipkin.txt @@ -0,0 +1,4 @@ +Comparing source compatibility of against +*** MODIFIED CLASS: PUBLIC FINAL io.opentelemetry.exporter.zipkin.ZipkinSpanExporter (not serializable) + === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 + +++ NEW METHOD: PUBLIC(+) java.lang.String toString() diff --git a/docs/apidiffs/1.30.0_vs_1.29.0/opentelemetry-extension-kotlin.txt b/docs/apidiffs/1.30.0_vs_1.29.0/opentelemetry-extension-kotlin.txt new file mode 100644 index 00000000000..df26146497b --- /dev/null +++ b/docs/apidiffs/1.30.0_vs_1.29.0/opentelemetry-extension-kotlin.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of against +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.30.0_vs_1.29.0/opentelemetry-extension-trace-propagators.txt b/docs/apidiffs/1.30.0_vs_1.29.0/opentelemetry-extension-trace-propagators.txt new file mode 100644 index 00000000000..df26146497b --- /dev/null +++ b/docs/apidiffs/1.30.0_vs_1.29.0/opentelemetry-extension-trace-propagators.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of against +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.30.0_vs_1.29.0/opentelemetry-opentracing-shim.txt b/docs/apidiffs/1.30.0_vs_1.29.0/opentelemetry-opentracing-shim.txt new file mode 100644 index 00000000000..df26146497b --- /dev/null +++ b/docs/apidiffs/1.30.0_vs_1.29.0/opentelemetry-opentracing-shim.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of against +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.30.0_vs_1.29.0/opentelemetry-sdk-common.txt b/docs/apidiffs/1.30.0_vs_1.29.0/opentelemetry-sdk-common.txt new file mode 100644 index 00000000000..df26146497b --- /dev/null +++ b/docs/apidiffs/1.30.0_vs_1.29.0/opentelemetry-sdk-common.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of against +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.30.0_vs_1.29.0/opentelemetry-sdk-extension-autoconfigure-spi.txt b/docs/apidiffs/1.30.0_vs_1.29.0/opentelemetry-sdk-extension-autoconfigure-spi.txt new file mode 100644 index 00000000000..df26146497b --- /dev/null +++ b/docs/apidiffs/1.30.0_vs_1.29.0/opentelemetry-sdk-extension-autoconfigure-spi.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of against +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.30.0_vs_1.29.0/opentelemetry-sdk-extension-autoconfigure.txt b/docs/apidiffs/1.30.0_vs_1.29.0/opentelemetry-sdk-extension-autoconfigure.txt new file mode 100644 index 00000000000..df26146497b --- /dev/null +++ b/docs/apidiffs/1.30.0_vs_1.29.0/opentelemetry-sdk-extension-autoconfigure.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of against +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.30.0_vs_1.29.0/opentelemetry-sdk-extension-jaeger-remote-sampler.txt b/docs/apidiffs/1.30.0_vs_1.29.0/opentelemetry-sdk-extension-jaeger-remote-sampler.txt new file mode 100644 index 00000000000..df26146497b --- /dev/null +++ b/docs/apidiffs/1.30.0_vs_1.29.0/opentelemetry-sdk-extension-jaeger-remote-sampler.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of against +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.30.0_vs_1.29.0/opentelemetry-sdk-logs.txt b/docs/apidiffs/1.30.0_vs_1.29.0/opentelemetry-sdk-logs.txt new file mode 100644 index 00000000000..df26146497b --- /dev/null +++ b/docs/apidiffs/1.30.0_vs_1.29.0/opentelemetry-sdk-logs.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of against +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.30.0_vs_1.29.0/opentelemetry-sdk-metrics.txt b/docs/apidiffs/1.30.0_vs_1.29.0/opentelemetry-sdk-metrics.txt new file mode 100644 index 00000000000..dff1c969ed8 --- /dev/null +++ b/docs/apidiffs/1.30.0_vs_1.29.0/opentelemetry-sdk-metrics.txt @@ -0,0 +1,4 @@ +Comparing source compatibility of against +*** MODIFIED CLASS: PUBLIC FINAL io.opentelemetry.sdk.metrics.ViewBuilder (not serializable) + === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 + +++ NEW METHOD: PUBLIC(+) io.opentelemetry.sdk.metrics.ViewBuilder setAttributeFilter(java.util.Set) diff --git a/docs/apidiffs/1.30.0_vs_1.29.0/opentelemetry-sdk-testing.txt b/docs/apidiffs/1.30.0_vs_1.29.0/opentelemetry-sdk-testing.txt new file mode 100644 index 00000000000..df26146497b --- /dev/null +++ b/docs/apidiffs/1.30.0_vs_1.29.0/opentelemetry-sdk-testing.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of against +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.30.0_vs_1.29.0/opentelemetry-sdk-trace.txt b/docs/apidiffs/1.30.0_vs_1.29.0/opentelemetry-sdk-trace.txt new file mode 100644 index 00000000000..df26146497b --- /dev/null +++ b/docs/apidiffs/1.30.0_vs_1.29.0/opentelemetry-sdk-trace.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of against +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.30.0_vs_1.29.0/opentelemetry-sdk.txt b/docs/apidiffs/1.30.0_vs_1.29.0/opentelemetry-sdk.txt new file mode 100644 index 00000000000..df26146497b --- /dev/null +++ b/docs/apidiffs/1.30.0_vs_1.29.0/opentelemetry-sdk.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of against +No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-logging.txt b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-logging.txt index ec040faaf8b..df26146497b 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-logging.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-logging.txt @@ -1,10 +1,2 @@ Comparing source compatibility of against -*** MODIFIED CLASS: PUBLIC FINAL io.opentelemetry.exporter.logging.LoggingMetricExporter (not serializable) - === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 - +++ NEW METHOD: PUBLIC(+) java.lang.String toString() -*** MODIFIED CLASS: PUBLIC FINAL io.opentelemetry.exporter.logging.LoggingSpanExporter (not serializable) - === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 - +++ NEW METHOD: PUBLIC(+) java.lang.String toString() -*** MODIFIED CLASS: PUBLIC io.opentelemetry.exporter.logging.SystemOutLogRecordExporter (not serializable) - === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 - +++ NEW METHOD: PUBLIC(+) java.lang.String toString() +No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-zipkin.txt b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-zipkin.txt index 772e014e5a0..df26146497b 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-zipkin.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-zipkin.txt @@ -1,4 +1,2 @@ Comparing source compatibility of against -*** MODIFIED CLASS: PUBLIC FINAL io.opentelemetry.exporter.zipkin.ZipkinSpanExporter (not serializable) - === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 - +++ NEW METHOD: PUBLIC(+) java.lang.String toString() +No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-metrics.txt b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-metrics.txt index dff1c969ed8..df26146497b 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-metrics.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-metrics.txt @@ -1,4 +1,2 @@ Comparing source compatibility of against -*** MODIFIED CLASS: PUBLIC FINAL io.opentelemetry.sdk.metrics.ViewBuilder (not serializable) - === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 - +++ NEW METHOD: PUBLIC(+) io.opentelemetry.sdk.metrics.ViewBuilder setAttributeFilter(java.util.Set) +No changes. \ No newline at end of file From 4a44474ff0ac07ed973862c075c5d4db9454817d Mon Sep 17 00:00:00 2001 From: jack-berg <34418638+jack-berg@users.noreply.github.com> Date: Mon, 11 Sep 2023 10:00:07 -0500 Subject: [PATCH 005/901] Delete PrometheusCustomizerProvider (#5811) --- .../PrometheusCustomizerProvider.java | 49 ------------------- ...re.spi.AutoConfigurationCustomizerProvider | 1 - 2 files changed, 50 deletions(-) delete mode 100644 exporters/prometheus/src/main/java/io/opentelemetry/exporter/prometheus/internal/PrometheusCustomizerProvider.java delete mode 100644 exporters/prometheus/src/main/resources/META-INF/services/io.opentelemetry.sdk.autoconfigure.spi.AutoConfigurationCustomizerProvider diff --git a/exporters/prometheus/src/main/java/io/opentelemetry/exporter/prometheus/internal/PrometheusCustomizerProvider.java b/exporters/prometheus/src/main/java/io/opentelemetry/exporter/prometheus/internal/PrometheusCustomizerProvider.java deleted file mode 100644 index f657e14eea7..00000000000 --- a/exporters/prometheus/src/main/java/io/opentelemetry/exporter/prometheus/internal/PrometheusCustomizerProvider.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package io.opentelemetry.exporter.prometheus.internal; - -import io.opentelemetry.exporter.prometheus.PrometheusHttpServer; -import io.opentelemetry.exporter.prometheus.PrometheusHttpServerBuilder; -import io.opentelemetry.sdk.autoconfigure.spi.AutoConfigurationCustomizer; -import io.opentelemetry.sdk.autoconfigure.spi.AutoConfigurationCustomizerProvider; -import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties; - -/** - * SPI implementation for {@link PrometheusHttpServer}. - * - *

This class is internal and is hence not for public use. Its APIs are unstable and can change - * at any time. - */ -public class PrometheusCustomizerProvider implements AutoConfigurationCustomizerProvider { - - @Override - public void customize(AutoConfigurationCustomizer autoConfiguration) { - autoConfiguration.addMeterProviderCustomizer( - (builder, config) -> { - boolean prometheusEnabled = - config.getList("otel.metrics.exporter").contains("prometheus"); - if (prometheusEnabled) { - builder.registerMetricReader(configurePrometheusHttpServer(config)); - } - return builder; - }); - } - - // Visible for test - static PrometheusHttpServer configurePrometheusHttpServer(ConfigProperties config) { - PrometheusHttpServerBuilder prometheusBuilder = PrometheusHttpServer.builder(); - - Integer port = config.getInt("otel.exporter.prometheus.port"); - if (port != null) { - prometheusBuilder.setPort(port); - } - String host = config.getString("otel.exporter.prometheus.host"); - if (host != null) { - prometheusBuilder.setHost(host); - } - return prometheusBuilder.build(); - } -} diff --git a/exporters/prometheus/src/main/resources/META-INF/services/io.opentelemetry.sdk.autoconfigure.spi.AutoConfigurationCustomizerProvider b/exporters/prometheus/src/main/resources/META-INF/services/io.opentelemetry.sdk.autoconfigure.spi.AutoConfigurationCustomizerProvider deleted file mode 100644 index 1522bd5c348..00000000000 --- a/exporters/prometheus/src/main/resources/META-INF/services/io.opentelemetry.sdk.autoconfigure.spi.AutoConfigurationCustomizerProvider +++ /dev/null @@ -1 +0,0 @@ -io.opentelemetry.exporter.prometheus.internal.PrometheusCustomizerProvider \ No newline at end of file From b9b1e817ef8e4fad230f873bf20381fabfe274e8 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 11 Sep 2023 10:20:43 -0500 Subject: [PATCH 006/901] Update dependency com.google.auto.value:auto-value-annotations to v1.10.4 (#5809) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- buildSrc/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts index 799a324cbb8..e4f4bb5d769 100644 --- a/buildSrc/build.gradle.kts +++ b/buildSrc/build.gradle.kts @@ -43,7 +43,7 @@ repositories { dependencies { implementation(enforcedPlatform("com.squareup.wire:wire-bom:4.8.1")) - implementation("com.google.auto.value:auto-value-annotations:1.10.3") + implementation("com.google.auto.value:auto-value-annotations:1.10.4") // When updating, update above in plugins too implementation("com.diffplug.spotless:spotless-plugin-gradle:6.21.0") // Needed for japicmp but not automatically brought in for some reason. From e242c1bbf7400196885fa2686faed2b8810700f3 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 11 Sep 2023 10:21:02 -0500 Subject: [PATCH 007/901] Update autoValueVersion to v1.10.4 (#5808) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- dependencyManagement/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index 7351dcf67ba..8c27fb4232e 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -24,7 +24,7 @@ val DEPENDENCY_BOMS = listOf( "org.snakeyaml:snakeyaml-engine:2.7" ) -val autoValueVersion = "1.10.3" +val autoValueVersion = "1.10.4" val errorProneVersion = "2.21.1" val jmhVersion = "1.37" // Mockito 5.x.x requires Java 11 https://github.com/mockito/mockito/releases/tag/v5.0.0 From 80335e35bd46a18d71627e0e095e4a1288302c3c Mon Sep 17 00:00:00 2001 From: OpenTelemetry Bot <107717825+opentelemetrybot@users.noreply.github.com> Date: Mon, 11 Sep 2023 09:27:36 -0700 Subject: [PATCH 008/901] Merge change log updates from release/v1.30.x (#5816) --- CHANGELOG.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2e5cba6f72f..91207791d30 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,11 @@ ## Unreleased +## Version 1.30.1 (2023-09-11) + +* Fix autoconfigure bug creating multiple `PrometheusHttpServer` instances with same port + ([#5911](https://github.com/open-telemetry/opentelemetry-java/pull/5811)) + ## Version 1.30.0 (2023-09-08) ### API From 96c895893c8fb8aeb7e786a050e772d087513f01 Mon Sep 17 00:00:00 2001 From: jack-berg <34418638+jack-berg@users.noreply.github.com> Date: Mon, 11 Sep 2023 17:42:20 -0500 Subject: [PATCH 009/901] Post release v1.30.1 (#5817) --- README.md | 74 +++++++++---------- .../1.30.1_vs_1.30.0/opentelemetry-api.txt | 2 + .../opentelemetry-context.txt | 2 + .../opentelemetry-exporter-common.txt | 2 + .../opentelemetry-exporter-jaeger-thrift.txt | 2 + .../opentelemetry-exporter-jaeger.txt | 2 + .../opentelemetry-exporter-logging-otlp.txt | 2 + .../opentelemetry-exporter-logging.txt | 2 + .../opentelemetry-exporter-otlp-common.txt | 2 + .../opentelemetry-exporter-otlp.txt | 2 + ...y-exporter-sender-grpc-managed-channel.txt | 2 + .../opentelemetry-exporter-sender-okhttp.txt | 2 + .../opentelemetry-exporter-zipkin.txt | 2 + .../opentelemetry-extension-kotlin.txt | 2 + ...ntelemetry-extension-trace-propagators.txt | 2 + .../opentelemetry-opentracing-shim.txt | 2 + .../opentelemetry-sdk-common.txt | 2 + ...emetry-sdk-extension-autoconfigure-spi.txt | 2 + ...ntelemetry-sdk-extension-autoconfigure.txt | 2 + ...ry-sdk-extension-jaeger-remote-sampler.txt | 2 + .../opentelemetry-sdk-logs.txt | 2 + .../opentelemetry-sdk-metrics.txt | 2 + .../opentelemetry-sdk-testing.txt | 2 + .../opentelemetry-sdk-trace.txt | 2 + .../1.30.1_vs_1.30.0/opentelemetry-sdk.txt | 2 + 25 files changed, 85 insertions(+), 37 deletions(-) create mode 100644 docs/apidiffs/1.30.1_vs_1.30.0/opentelemetry-api.txt create mode 100644 docs/apidiffs/1.30.1_vs_1.30.0/opentelemetry-context.txt create mode 100644 docs/apidiffs/1.30.1_vs_1.30.0/opentelemetry-exporter-common.txt create mode 100644 docs/apidiffs/1.30.1_vs_1.30.0/opentelemetry-exporter-jaeger-thrift.txt create mode 100644 docs/apidiffs/1.30.1_vs_1.30.0/opentelemetry-exporter-jaeger.txt create mode 100644 docs/apidiffs/1.30.1_vs_1.30.0/opentelemetry-exporter-logging-otlp.txt create mode 100644 docs/apidiffs/1.30.1_vs_1.30.0/opentelemetry-exporter-logging.txt create mode 100644 docs/apidiffs/1.30.1_vs_1.30.0/opentelemetry-exporter-otlp-common.txt create mode 100644 docs/apidiffs/1.30.1_vs_1.30.0/opentelemetry-exporter-otlp.txt create mode 100644 docs/apidiffs/1.30.1_vs_1.30.0/opentelemetry-exporter-sender-grpc-managed-channel.txt create mode 100644 docs/apidiffs/1.30.1_vs_1.30.0/opentelemetry-exporter-sender-okhttp.txt create mode 100644 docs/apidiffs/1.30.1_vs_1.30.0/opentelemetry-exporter-zipkin.txt create mode 100644 docs/apidiffs/1.30.1_vs_1.30.0/opentelemetry-extension-kotlin.txt create mode 100644 docs/apidiffs/1.30.1_vs_1.30.0/opentelemetry-extension-trace-propagators.txt create mode 100644 docs/apidiffs/1.30.1_vs_1.30.0/opentelemetry-opentracing-shim.txt create mode 100644 docs/apidiffs/1.30.1_vs_1.30.0/opentelemetry-sdk-common.txt create mode 100644 docs/apidiffs/1.30.1_vs_1.30.0/opentelemetry-sdk-extension-autoconfigure-spi.txt create mode 100644 docs/apidiffs/1.30.1_vs_1.30.0/opentelemetry-sdk-extension-autoconfigure.txt create mode 100644 docs/apidiffs/1.30.1_vs_1.30.0/opentelemetry-sdk-extension-jaeger-remote-sampler.txt create mode 100644 docs/apidiffs/1.30.1_vs_1.30.0/opentelemetry-sdk-logs.txt create mode 100644 docs/apidiffs/1.30.1_vs_1.30.0/opentelemetry-sdk-metrics.txt create mode 100644 docs/apidiffs/1.30.1_vs_1.30.0/opentelemetry-sdk-testing.txt create mode 100644 docs/apidiffs/1.30.1_vs_1.30.0/opentelemetry-sdk-trace.txt create mode 100644 docs/apidiffs/1.30.1_vs_1.30.0/opentelemetry-sdk.txt diff --git a/README.md b/README.md index a71c35d6ee0..6b7781c2413 100644 --- a/README.md +++ b/README.md @@ -91,7 +91,7 @@ dependency versions in sync. io.opentelemetry opentelemetry-bom - 1.30.0 + 1.30.1 pom import @@ -110,7 +110,7 @@ dependency versions in sync. ```groovy dependencies { - implementation platform("io.opentelemetry:opentelemetry-bom:1.30.0") + implementation platform("io.opentelemetry:opentelemetry-bom:1.30.1") implementation('io.opentelemetry:opentelemetry-api') } ``` @@ -119,8 +119,8 @@ Note that if you want to use any artifacts that have not fully stabilized yet (s ```groovy dependencies { - implementation platform("io.opentelemetry:opentelemetry-bom:1.30.0") - implementation platform('io.opentelemetry:opentelemetry-bom-alpha:1.30.0-alpha') + implementation platform("io.opentelemetry:opentelemetry-bom:1.30.1") + implementation platform('io.opentelemetry:opentelemetry-bom-alpha:1.30.1-alpha') implementation('io.opentelemetry:opentelemetry-api') implementation('io.opentelemetry:opentelemetry-semconv') @@ -216,53 +216,53 @@ dependency as follows, replacing `{{artifact-id}}` with the value from the "Arti | Component | Description | Artifact ID | Version | Javadoc | |----------------------------------------------|----------------------------------------|---------------------------|-------------------------------------------------------------|---------| -| [Bill of Materials (BOM)](./bom) | Bill of materials for stable artifacts | `opentelemetry-bom` | 1.30.0 | N/A | -| [Alpha Bill of Materials (BOM)](./bom-alpha) | Bill of materials for alpha artifacts | `opentelemetry-bom-alpha` | 1.30.0-alpha | N/A | +| [Bill of Materials (BOM)](./bom) | Bill of materials for stable artifacts | `opentelemetry-bom` | 1.30.1 | N/A | +| [Alpha Bill of Materials (BOM)](./bom-alpha) | Bill of materials for alpha artifacts | `opentelemetry-bom-alpha` | 1.30.1-alpha | N/A | ### API | Component | Description | Artifact ID | Version | Javadoc | |-----------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|----------------------------|-------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------| -| [API](./api/all) | OpenTelemetry API, including metrics, traces, baggage, context | `opentelemetry-api` | 1.30.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-api.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-api) | -| [Events API](./api/events) | OpenTelemetry Event API for emitting events. | `opentelemetry-api-events` | 1.30.0-alpha | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-api-events.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-api-events) | -| [Context API](./context) | OpenTelemetry context API | `opentelemetry-context` | 1.30.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-context.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-context) | -| [Semantic Conventions](./semconv) | Generated code for OpenTelemetry semantic conventions (deprecated, moved to [open-telemetry/semantic-conventions-java](https://github.com/open-telemetry/semantic-conventions-java)) | `opentelemetry-semconv` | 1.30.0-alpha | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-semconv.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-semconv) | +| [API](./api/all) | OpenTelemetry API, including metrics, traces, baggage, context | `opentelemetry-api` | 1.30.1 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-api.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-api) | +| [Events API](./api/events) | OpenTelemetry Event API for emitting events. | `opentelemetry-api-events` | 1.30.1-alpha | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-api-events.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-api-events) | +| [Context API](./context) | OpenTelemetry context API | `opentelemetry-context` | 1.30.1 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-context.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-context) | +| [Semantic Conventions](./semconv) | Generated code for OpenTelemetry semantic conventions (deprecated, moved to [open-telemetry/semantic-conventions-java](https://github.com/open-telemetry/semantic-conventions-java)) | `opentelemetry-semconv` | 1.30.1-alpha | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-semconv.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-semconv) | ### API Extensions | Component | Description | Artifact ID | Version | Javadoc | |---------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|---------------------------------------------|-------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| [Kotlin Extension](./extensions/kotlin) | Context extension for coroutines | `opentelemetry-extension-kotlin` | 1.30.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-extension-kotlin.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-extension-kotlin) | -| [Trace Propagators Extension](./extensions/trace-propagators) | Trace propagators, including B3, Jaeger, OT Trace | `opentelemetry-extension-trace-propagators` | 1.30.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-extension-trace-propagators.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-extension-trace-propagators) | -| [Incubator Extension](./extensions/incubator) | API incubator, including pass through propagator, and extended tracer | `opentelemetry-extension-incubator` | 1.30.0-alpha | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-extension-incubator.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-extension-incubator) | +| [Kotlin Extension](./extensions/kotlin) | Context extension for coroutines | `opentelemetry-extension-kotlin` | 1.30.1 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-extension-kotlin.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-extension-kotlin) | +| [Trace Propagators Extension](./extensions/trace-propagators) | Trace propagators, including B3, Jaeger, OT Trace | `opentelemetry-extension-trace-propagators` | 1.30.1 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-extension-trace-propagators.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-extension-trace-propagators) | +| [Incubator Extension](./extensions/incubator) | API incubator, including pass through propagator, and extended tracer | `opentelemetry-extension-incubator` | 1.30.1-alpha | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-extension-incubator.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-extension-incubator) | ### SDK | Component | Description | Artifact ID | Version | Javadoc | |------------------------------|--------------------------------------------------------|-----------------------------|---------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| [SDK](./sdk/all) | OpenTelemetry SDK, including metrics, traces, and logs | `opentelemetry-sdk` | 1.30.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk) | -| [Metrics SDK](./sdk/metrics) | OpenTelemetry metrics SDK | `opentelemetry-sdk-metrics` | 1.30.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-metrics.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-metrics) | -| [Trace SDK](./sdk/trace) | OpenTelemetry trace SDK | `opentelemetry-sdk-trace` | 1.30.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-trace.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-trace) | -| [Log SDK](./sdk/logs) | OpenTelemetry log SDK | `opentelemetry-sdk-logs` | 1.30.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-logs.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-logs) | -| [SDK Common](./sdk/common) | Shared SDK components | `opentelemetry-sdk-common` | 1.30.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-common.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-common) | -| [SDK Testing](./sdk/testing) | Components for testing OpenTelemetry instrumentation | `opentelemetry-sdk-testing` | 1.30.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-testing.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-testing) | +| [SDK](./sdk/all) | OpenTelemetry SDK, including metrics, traces, and logs | `opentelemetry-sdk` | 1.30.1 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk) | +| [Metrics SDK](./sdk/metrics) | OpenTelemetry metrics SDK | `opentelemetry-sdk-metrics` | 1.30.1 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-metrics.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-metrics) | +| [Trace SDK](./sdk/trace) | OpenTelemetry trace SDK | `opentelemetry-sdk-trace` | 1.30.1 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-trace.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-trace) | +| [Log SDK](./sdk/logs) | OpenTelemetry log SDK | `opentelemetry-sdk-logs` | 1.30.1 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-logs.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-logs) | +| [SDK Common](./sdk/common) | Shared SDK components | `opentelemetry-sdk-common` | 1.30.1 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-common.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-common) | +| [SDK Testing](./sdk/testing) | Components for testing OpenTelemetry instrumentation | `opentelemetry-sdk-testing` | 1.30.1 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-testing.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-testing) | ### SDK Exporters | Component | Description | Artifact ID | Version | Javadoc | |-----------------------------------------------------------------------|------------------------------------------------------------------------------|------------------------------------------------------|-------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| [OTLP Exporters](./exporters/otlp/all) | OTLP gRPC & HTTP exporters, including traces, metrics, and logs | `opentelemetry-exporter-otlp` | 1.30.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-otlp.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-otlp) | -| [OTLP Logging Exporters](./exporters/logging-otlp) | Logging exporters in OTLP JSON encoding, including traces, metrics, and logs | `opentelemetry-exporter-logging-otlp` | 1.30.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-logging-otlp.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-logging-otlp) | -| [OTLP Common](./exporters/otlp/common) | Shared OTLP components (internal) | `opentelemetry-exporter-otlp-common` | 1.30.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-otlp-common.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-otlp-common) | -| [Jaeger gRPC Exporter](./exporters/jaeger) | Jaeger gRPC trace exporter (deprecated [1]) | `opentelemetry-exporter-jaeger` | 1.30.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-jaeger.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-jaeger) | -| [Jaeger Thrift Exporter](./exporters/jaeger-thrift) | Jaeger thrift trace exporter (deprecated [1]) | `opentelemetry-exporter-jaeger-thift` | 1.30.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-jaeger-thrift.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-jaeger-thrift) | -| [Logging Exporter](./exporters/logging) | Logging exporters, including metrics, traces, and logs | `opentelemetry-exporter-logging` | 1.30.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-logging.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-logging) | -| [Zipkin Exporter](./exporters/zipkin) | Zipkin trace exporter | `opentelemetry-exporter-zipkin` | 1.30.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-zipkin.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-zipkin) | -| [Prometheus Exporter](./exporters/prometheus) | Prometheus metric exporter | `opentelemetry-exporter-prometheus` | 1.30.0-alpha | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-prometheus.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-prometheus) | -| [Exporter Common](./exporters/common) | Shared exporter components (internal) | `opentelemetry-exporter-common` | 1.30.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-common.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-common) | -| [OkHttp Sender](./exporters/sender/okhttp) | OkHttp implementation of HttpSender (internal) | `opentelemetry-exporter-sender-okhttp` | 1.30.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-sender-okhttp.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-sender-okhttp) | -| [JDK Sender](./exporters/sender/okhttp) | Java 11+ native HttpClient implementation of HttpSender (internal) | `opentelemetry-exporter-sender-jdk` | 1.30.0-alpha | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-sender-jdk.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-sender-jdk) | | -| [gRPC ManagedChannel Sender](./exporters/sender/grpc-managed-channel) | gRPC ManagedChannel implementation of GrpcSender (internal) | `opentelemetry-exporter-sender-grpc-managed-channel` | 1.30.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-sender-grpc-managed-channel.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-sender-grpc-managed-channel) | | +| [OTLP Exporters](./exporters/otlp/all) | OTLP gRPC & HTTP exporters, including traces, metrics, and logs | `opentelemetry-exporter-otlp` | 1.30.1 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-otlp.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-otlp) | +| [OTLP Logging Exporters](./exporters/logging-otlp) | Logging exporters in OTLP JSON encoding, including traces, metrics, and logs | `opentelemetry-exporter-logging-otlp` | 1.30.1 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-logging-otlp.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-logging-otlp) | +| [OTLP Common](./exporters/otlp/common) | Shared OTLP components (internal) | `opentelemetry-exporter-otlp-common` | 1.30.1 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-otlp-common.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-otlp-common) | +| [Jaeger gRPC Exporter](./exporters/jaeger) | Jaeger gRPC trace exporter (deprecated [1]) | `opentelemetry-exporter-jaeger` | 1.30.1 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-jaeger.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-jaeger) | +| [Jaeger Thrift Exporter](./exporters/jaeger-thrift) | Jaeger thrift trace exporter (deprecated [1]) | `opentelemetry-exporter-jaeger-thift` | 1.30.1 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-jaeger-thrift.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-jaeger-thrift) | +| [Logging Exporter](./exporters/logging) | Logging exporters, including metrics, traces, and logs | `opentelemetry-exporter-logging` | 1.30.1 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-logging.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-logging) | +| [Zipkin Exporter](./exporters/zipkin) | Zipkin trace exporter | `opentelemetry-exporter-zipkin` | 1.30.1 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-zipkin.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-zipkin) | +| [Prometheus Exporter](./exporters/prometheus) | Prometheus metric exporter | `opentelemetry-exporter-prometheus` | 1.30.1-alpha | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-prometheus.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-prometheus) | +| [Exporter Common](./exporters/common) | Shared exporter components (internal) | `opentelemetry-exporter-common` | 1.30.1 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-common.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-common) | +| [OkHttp Sender](./exporters/sender/okhttp) | OkHttp implementation of HttpSender (internal) | `opentelemetry-exporter-sender-okhttp` | 1.30.1 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-sender-okhttp.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-sender-okhttp) | +| [JDK Sender](./exporters/sender/okhttp) | Java 11+ native HttpClient implementation of HttpSender (internal) | `opentelemetry-exporter-sender-jdk` | 1.30.1-alpha | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-sender-jdk.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-sender-jdk) | | +| [gRPC ManagedChannel Sender](./exporters/sender/grpc-managed-channel) | gRPC ManagedChannel implementation of GrpcSender (internal) | `opentelemetry-exporter-sender-grpc-managed-channel` | 1.30.1 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-sender-grpc-managed-channel.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-sender-grpc-managed-channel) | | **[1]**: Jaeger now has [native support for OTLP](https://opentelemetry.io/blog/2022/jaeger-native-otlp/) and jaeger @@ -275,17 +275,17 @@ additional versions will be published. | Component | Description | Artifact ID | Version | Javadoc | |-------------------------------------------------------------------------------|------------------------------------------------------------------------------------|-----------------------------------------------------|-------------------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| [SDK Autoconfigure](./sdk-extensions/autoconfigure) | Autoconfigure OpenTelemetry SDK from env vars, system properties, and SPI | `opentelemetry-sdk-extension-autoconfigure` | 1.30.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-extension-autoconfigure.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-extension-autoconfigure) | -| [SDK Autoconfigure SPI](./sdk-extensions/autoconfigure-spi) | Service Provider Interface (SPI) definitions for autoconfigure | `opentelemetry-sdk-extension-autoconfigure-spi` | 1.30.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-extension-autoconfigure-spi.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-extension-autoconfigure-spi) | -| [SDK Jaeger Remote Sampler Extension](./sdk-extensions/jaeger-remote-sampler) | Sampler which obtains sampling configuration from remote Jaeger server | `opentelemetry-sdk-extension-jaeger-remote-sampler` | 1.30.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-extension-jaeger-remote-sampler.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-extension-jaeger-remote-sampler) | -| [SDK Incubator](./sdk-extensions/incubator) | SDK incubator, including YAML based view configuration, LeakDetectingSpanProcessor | `opentelemetry-sdk-extension-incubator` | 1.30.0-alpha | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-extension-incubator.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-extension-incubator) | +| [SDK Autoconfigure](./sdk-extensions/autoconfigure) | Autoconfigure OpenTelemetry SDK from env vars, system properties, and SPI | `opentelemetry-sdk-extension-autoconfigure` | 1.30.1 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-extension-autoconfigure.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-extension-autoconfigure) | +| [SDK Autoconfigure SPI](./sdk-extensions/autoconfigure-spi) | Service Provider Interface (SPI) definitions for autoconfigure | `opentelemetry-sdk-extension-autoconfigure-spi` | 1.30.1 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-extension-autoconfigure-spi.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-extension-autoconfigure-spi) | +| [SDK Jaeger Remote Sampler Extension](./sdk-extensions/jaeger-remote-sampler) | Sampler which obtains sampling configuration from remote Jaeger server | `opentelemetry-sdk-extension-jaeger-remote-sampler` | 1.30.1 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-extension-jaeger-remote-sampler.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-extension-jaeger-remote-sampler) | +| [SDK Incubator](./sdk-extensions/incubator) | SDK incubator, including YAML based view configuration, LeakDetectingSpanProcessor | `opentelemetry-sdk-extension-incubator` | 1.30.1-alpha | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-extension-incubator.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-extension-incubator) | ### Shims | Component | Description | Artifact ID | Version | Javadoc | |----------------------------------------|--------------------------------------------------------------|----------------------------------|-------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| [OpenCensus Shim](./opencensus-shim) | Bridge opencensus metrics into the OpenTelemetry metrics SDK | `opentelemetry-opencensus-shim` | 1.30.0-alpha | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-opencensus-shim.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-opencensus-shim) | -| [OpenTracing Shim](./opentracing-shim) | Bridge opentracing spans into the OpenTelemetry trace API | `opentelemetry-opentracing-shim` | 1.30.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-opentracing-shim.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-opentracing-shim) | +| [OpenCensus Shim](./opencensus-shim) | Bridge opencensus metrics into the OpenTelemetry metrics SDK | `opentelemetry-opencensus-shim` | 1.30.1-alpha | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-opencensus-shim.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-opencensus-shim) | +| [OpenTracing Shim](./opentracing-shim) | Bridge opentracing spans into the OpenTelemetry trace API | `opentelemetry-opentracing-shim` | 1.30.1 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-opentracing-shim.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-opentracing-shim) | ## Contributing diff --git a/docs/apidiffs/1.30.1_vs_1.30.0/opentelemetry-api.txt b/docs/apidiffs/1.30.1_vs_1.30.0/opentelemetry-api.txt new file mode 100644 index 00000000000..df26146497b --- /dev/null +++ b/docs/apidiffs/1.30.1_vs_1.30.0/opentelemetry-api.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of against +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.30.1_vs_1.30.0/opentelemetry-context.txt b/docs/apidiffs/1.30.1_vs_1.30.0/opentelemetry-context.txt new file mode 100644 index 00000000000..df26146497b --- /dev/null +++ b/docs/apidiffs/1.30.1_vs_1.30.0/opentelemetry-context.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of against +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.30.1_vs_1.30.0/opentelemetry-exporter-common.txt b/docs/apidiffs/1.30.1_vs_1.30.0/opentelemetry-exporter-common.txt new file mode 100644 index 00000000000..df26146497b --- /dev/null +++ b/docs/apidiffs/1.30.1_vs_1.30.0/opentelemetry-exporter-common.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of against +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.30.1_vs_1.30.0/opentelemetry-exporter-jaeger-thrift.txt b/docs/apidiffs/1.30.1_vs_1.30.0/opentelemetry-exporter-jaeger-thrift.txt new file mode 100644 index 00000000000..df26146497b --- /dev/null +++ b/docs/apidiffs/1.30.1_vs_1.30.0/opentelemetry-exporter-jaeger-thrift.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of against +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.30.1_vs_1.30.0/opentelemetry-exporter-jaeger.txt b/docs/apidiffs/1.30.1_vs_1.30.0/opentelemetry-exporter-jaeger.txt new file mode 100644 index 00000000000..df26146497b --- /dev/null +++ b/docs/apidiffs/1.30.1_vs_1.30.0/opentelemetry-exporter-jaeger.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of against +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.30.1_vs_1.30.0/opentelemetry-exporter-logging-otlp.txt b/docs/apidiffs/1.30.1_vs_1.30.0/opentelemetry-exporter-logging-otlp.txt new file mode 100644 index 00000000000..df26146497b --- /dev/null +++ b/docs/apidiffs/1.30.1_vs_1.30.0/opentelemetry-exporter-logging-otlp.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of against +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.30.1_vs_1.30.0/opentelemetry-exporter-logging.txt b/docs/apidiffs/1.30.1_vs_1.30.0/opentelemetry-exporter-logging.txt new file mode 100644 index 00000000000..df26146497b --- /dev/null +++ b/docs/apidiffs/1.30.1_vs_1.30.0/opentelemetry-exporter-logging.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of against +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.30.1_vs_1.30.0/opentelemetry-exporter-otlp-common.txt b/docs/apidiffs/1.30.1_vs_1.30.0/opentelemetry-exporter-otlp-common.txt new file mode 100644 index 00000000000..df26146497b --- /dev/null +++ b/docs/apidiffs/1.30.1_vs_1.30.0/opentelemetry-exporter-otlp-common.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of against +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.30.1_vs_1.30.0/opentelemetry-exporter-otlp.txt b/docs/apidiffs/1.30.1_vs_1.30.0/opentelemetry-exporter-otlp.txt new file mode 100644 index 00000000000..df26146497b --- /dev/null +++ b/docs/apidiffs/1.30.1_vs_1.30.0/opentelemetry-exporter-otlp.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of against +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.30.1_vs_1.30.0/opentelemetry-exporter-sender-grpc-managed-channel.txt b/docs/apidiffs/1.30.1_vs_1.30.0/opentelemetry-exporter-sender-grpc-managed-channel.txt new file mode 100644 index 00000000000..df26146497b --- /dev/null +++ b/docs/apidiffs/1.30.1_vs_1.30.0/opentelemetry-exporter-sender-grpc-managed-channel.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of against +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.30.1_vs_1.30.0/opentelemetry-exporter-sender-okhttp.txt b/docs/apidiffs/1.30.1_vs_1.30.0/opentelemetry-exporter-sender-okhttp.txt new file mode 100644 index 00000000000..df26146497b --- /dev/null +++ b/docs/apidiffs/1.30.1_vs_1.30.0/opentelemetry-exporter-sender-okhttp.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of against +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.30.1_vs_1.30.0/opentelemetry-exporter-zipkin.txt b/docs/apidiffs/1.30.1_vs_1.30.0/opentelemetry-exporter-zipkin.txt new file mode 100644 index 00000000000..df26146497b --- /dev/null +++ b/docs/apidiffs/1.30.1_vs_1.30.0/opentelemetry-exporter-zipkin.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of against +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.30.1_vs_1.30.0/opentelemetry-extension-kotlin.txt b/docs/apidiffs/1.30.1_vs_1.30.0/opentelemetry-extension-kotlin.txt new file mode 100644 index 00000000000..df26146497b --- /dev/null +++ b/docs/apidiffs/1.30.1_vs_1.30.0/opentelemetry-extension-kotlin.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of against +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.30.1_vs_1.30.0/opentelemetry-extension-trace-propagators.txt b/docs/apidiffs/1.30.1_vs_1.30.0/opentelemetry-extension-trace-propagators.txt new file mode 100644 index 00000000000..df26146497b --- /dev/null +++ b/docs/apidiffs/1.30.1_vs_1.30.0/opentelemetry-extension-trace-propagators.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of against +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.30.1_vs_1.30.0/opentelemetry-opentracing-shim.txt b/docs/apidiffs/1.30.1_vs_1.30.0/opentelemetry-opentracing-shim.txt new file mode 100644 index 00000000000..df26146497b --- /dev/null +++ b/docs/apidiffs/1.30.1_vs_1.30.0/opentelemetry-opentracing-shim.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of against +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.30.1_vs_1.30.0/opentelemetry-sdk-common.txt b/docs/apidiffs/1.30.1_vs_1.30.0/opentelemetry-sdk-common.txt new file mode 100644 index 00000000000..df26146497b --- /dev/null +++ b/docs/apidiffs/1.30.1_vs_1.30.0/opentelemetry-sdk-common.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of against +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.30.1_vs_1.30.0/opentelemetry-sdk-extension-autoconfigure-spi.txt b/docs/apidiffs/1.30.1_vs_1.30.0/opentelemetry-sdk-extension-autoconfigure-spi.txt new file mode 100644 index 00000000000..df26146497b --- /dev/null +++ b/docs/apidiffs/1.30.1_vs_1.30.0/opentelemetry-sdk-extension-autoconfigure-spi.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of against +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.30.1_vs_1.30.0/opentelemetry-sdk-extension-autoconfigure.txt b/docs/apidiffs/1.30.1_vs_1.30.0/opentelemetry-sdk-extension-autoconfigure.txt new file mode 100644 index 00000000000..df26146497b --- /dev/null +++ b/docs/apidiffs/1.30.1_vs_1.30.0/opentelemetry-sdk-extension-autoconfigure.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of against +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.30.1_vs_1.30.0/opentelemetry-sdk-extension-jaeger-remote-sampler.txt b/docs/apidiffs/1.30.1_vs_1.30.0/opentelemetry-sdk-extension-jaeger-remote-sampler.txt new file mode 100644 index 00000000000..df26146497b --- /dev/null +++ b/docs/apidiffs/1.30.1_vs_1.30.0/opentelemetry-sdk-extension-jaeger-remote-sampler.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of against +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.30.1_vs_1.30.0/opentelemetry-sdk-logs.txt b/docs/apidiffs/1.30.1_vs_1.30.0/opentelemetry-sdk-logs.txt new file mode 100644 index 00000000000..df26146497b --- /dev/null +++ b/docs/apidiffs/1.30.1_vs_1.30.0/opentelemetry-sdk-logs.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of against +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.30.1_vs_1.30.0/opentelemetry-sdk-metrics.txt b/docs/apidiffs/1.30.1_vs_1.30.0/opentelemetry-sdk-metrics.txt new file mode 100644 index 00000000000..df26146497b --- /dev/null +++ b/docs/apidiffs/1.30.1_vs_1.30.0/opentelemetry-sdk-metrics.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of against +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.30.1_vs_1.30.0/opentelemetry-sdk-testing.txt b/docs/apidiffs/1.30.1_vs_1.30.0/opentelemetry-sdk-testing.txt new file mode 100644 index 00000000000..df26146497b --- /dev/null +++ b/docs/apidiffs/1.30.1_vs_1.30.0/opentelemetry-sdk-testing.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of against +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.30.1_vs_1.30.0/opentelemetry-sdk-trace.txt b/docs/apidiffs/1.30.1_vs_1.30.0/opentelemetry-sdk-trace.txt new file mode 100644 index 00000000000..df26146497b --- /dev/null +++ b/docs/apidiffs/1.30.1_vs_1.30.0/opentelemetry-sdk-trace.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of against +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.30.1_vs_1.30.0/opentelemetry-sdk.txt b/docs/apidiffs/1.30.1_vs_1.30.0/opentelemetry-sdk.txt new file mode 100644 index 00000000000..df26146497b --- /dev/null +++ b/docs/apidiffs/1.30.1_vs_1.30.0/opentelemetry-sdk.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of against +No changes. \ No newline at end of file From 5d5093636b0e8fdcb48888c73f3014d7aa2543d7 Mon Sep 17 00:00:00 2001 From: jack-berg <34418638+jack-berg@users.noreply.github.com> Date: Fri, 15 Sep 2023 10:48:51 -0500 Subject: [PATCH 010/901] ConfigurationReader handles null values as empty (#5829) --- sdk-extensions/incubator/build.gradle.kts | 2 +- .../fileconfig/ConfigurationReader.java | 7 ++- .../fileconfig/AggregationFactoryTest.java | 10 ++-- .../fileconfig/ConfigurationReaderTest.java | 58 +++++++++++++++++++ 4 files changed, 71 insertions(+), 6 deletions(-) diff --git a/sdk-extensions/incubator/build.gradle.kts b/sdk-extensions/incubator/build.gradle.kts index 35a58968fa8..7a07f3c8fa6 100644 --- a/sdk-extensions/incubator/build.gradle.kts +++ b/sdk-extensions/incubator/build.gradle.kts @@ -55,7 +55,7 @@ dependencies { // ... proceed with normal sourcesJar, compileJava, etc // TODO(jack-berg): update ref to be released version when available -val configurationRef = "0eb96de17c6533f668163873d95bd026bce1d8fb" +val configurationRef = "0508846f82ed54b230fa638e1e7556c52efee25e" val configurationRepoZip = "https://github.com/open-telemetry/opentelemetry-configuration/archive/$configurationRef.zip" val buildDirectory = layout.buildDirectory.asFile.get() diff --git a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/ConfigurationReader.java b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/ConfigurationReader.java index 04aaaa894ef..4fe765ee344 100644 --- a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/ConfigurationReader.java +++ b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/ConfigurationReader.java @@ -5,6 +5,8 @@ package io.opentelemetry.sdk.extension.incubator.fileconfig; +import com.fasterxml.jackson.annotation.JsonSetter; +import com.fasterxml.jackson.annotation.Nulls; import com.fasterxml.jackson.databind.ObjectMapper; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.OpenTelemetryConfiguration; import java.io.InputStream; @@ -13,7 +15,10 @@ final class ConfigurationReader { - private static final ObjectMapper MAPPER = new ObjectMapper(); + private static final ObjectMapper MAPPER = + new ObjectMapper() + // Create empty object instances for keys which are present but have null values + .setDefaultSetterInfo(JsonSetter.Value.forValueNulls(Nulls.AS_EMPTY)); private ConfigurationReader() {} diff --git a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/AggregationFactoryTest.java b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/AggregationFactoryTest.java index 3b37e2077ad..62c5e457606 100644 --- a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/AggregationFactoryTest.java +++ b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/AggregationFactoryTest.java @@ -11,7 +11,10 @@ import io.opentelemetry.sdk.autoconfigure.internal.SpiHelper; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.Aggregation; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.Base2ExponentialBucketHistogram; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.Drop; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.ExplicitBucketHistogram; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.LastValue; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.Sum; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; @@ -45,13 +48,12 @@ private static Stream createTestCases() { Arguments.of( new Aggregation(), io.opentelemetry.sdk.metrics.Aggregation.defaultAggregation()), Arguments.of( - new Aggregation().withDrop(new Object()), + new Aggregation().withDrop(new Drop()), io.opentelemetry.sdk.metrics.Aggregation.drop()), Arguments.of( - new Aggregation().withSum(new Object()), - io.opentelemetry.sdk.metrics.Aggregation.sum()), + new Aggregation().withSum(new Sum()), io.opentelemetry.sdk.metrics.Aggregation.sum()), Arguments.of( - new Aggregation().withLastValue(new Object()), + new Aggregation().withLastValue(new LastValue()), io.opentelemetry.sdk.metrics.Aggregation.lastValue()), Arguments.of( new Aggregation() diff --git a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/ConfigurationReaderTest.java b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/ConfigurationReaderTest.java index 9df4b15d25f..27d6e14cc0a 100644 --- a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/ConfigurationReaderTest.java +++ b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/ConfigurationReaderTest.java @@ -44,8 +44,10 @@ import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.TracerProvider; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.View; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.Zipkin; +import java.io.ByteArrayInputStream; import java.io.FileInputStream; import java.io.IOException; +import java.nio.charset.StandardCharsets; import java.util.Arrays; import java.util.Collections; import java.util.List; @@ -276,4 +278,60 @@ void read_KitchenSinkExampleFile() throws IOException { assertThat(config).isEqualTo(expected); } } + + @Test + void nullValuesParsedToEmptyObjects() { + String objectPlaceholderString = + "file_format: \"0.1\"\n" + + "tracer_provider:\n" + + " processors:\n" + + " - batch:\n" + + " exporter:\n" + + " console: {}\n" + + "meter_provider:\n" + + " views:\n" + + " - selector:\n" + + " instrument_type: histogram\n" + + " stream:\n" + + " aggregation:\n" + + " drop: {}\n"; + OpenTelemetryConfiguration objectPlaceholderModel = + ConfigurationReader.parse( + new ByteArrayInputStream(objectPlaceholderString.getBytes(StandardCharsets.UTF_8))); + + String noOjbectPlaceholderString = + "file_format: \"0.1\"\n" + + "tracer_provider:\n" + + " processors:\n" + + " - batch:\n" + + " exporter:\n" + + " console:\n" + + "meter_provider:\n" + + " views:\n" + + " - selector:\n" + + " instrument_type: histogram\n" + + " stream:\n" + + " aggregation:\n" + + " drop:\n"; + OpenTelemetryConfiguration noObjectPlaceholderModel = + ConfigurationReader.parse( + new ByteArrayInputStream(noOjbectPlaceholderString.getBytes(StandardCharsets.UTF_8))); + + SpanExporter exporter = + noObjectPlaceholderModel + .getTracerProvider() + .getProcessors() + .get(0) + .getBatch() + .getExporter(); + assertThat(exporter.getConsole()).isNotNull(); + assertThat(exporter.getOtlp()).isNull(); + + Aggregation aggregation = + noObjectPlaceholderModel.getMeterProvider().getViews().get(0).getStream().getAggregation(); + assertThat(aggregation.getDrop()).isNotNull(); + assertThat(aggregation.getSum()).isNull(); + + assertThat(objectPlaceholderModel).isEqualTo(noObjectPlaceholderModel); + } } From 736b0ceb6f1f624a958d9b33d9e7fe903ebd47e8 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 15 Sep 2023 12:58:13 -0500 Subject: [PATCH 011/901] Update plugin com.gradle.enterprise to v3.15 (#5826) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- settings.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/settings.gradle.kts b/settings.gradle.kts index cc4903adc9c..dbe27012ad9 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -1,7 +1,7 @@ pluginManagement { plugins { id("com.github.johnrengelman.shadow") version "8.1.1" - id("com.gradle.enterprise") version "3.14.1" + id("com.gradle.enterprise") version "3.15" id("de.undercouch.download") version "5.5.0" id("org.jsonschema2pojo") version "1.2.1" id("io.github.gradle-nexus.publish-plugin") version "1.3.0" From 766e055879a7a368ce4e184604a757dddfa976eb Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 15 Sep 2023 12:58:24 -0500 Subject: [PATCH 012/901] Update docker/login-action action to v3 (#5822) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/build-tracecontext-testsuite.yml | 2 +- .github/workflows/docker-test-containers-daily.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build-tracecontext-testsuite.yml b/.github/workflows/build-tracecontext-testsuite.yml index 23c2a6d951f..66105391fe4 100644 --- a/.github/workflows/build-tracecontext-testsuite.yml +++ b/.github/workflows/build-tracecontext-testsuite.yml @@ -16,7 +16,7 @@ jobs: - uses: actions/checkout@v4 - name: Login to GitHub package registry - uses: docker/login-action@v2 + uses: docker/login-action@v3 with: registry: ghcr.io username: ${{ github.repository_owner }} diff --git a/.github/workflows/docker-test-containers-daily.yml b/.github/workflows/docker-test-containers-daily.yml index 3d3e2876dbf..ba9f627d22b 100644 --- a/.github/workflows/docker-test-containers-daily.yml +++ b/.github/workflows/docker-test-containers-daily.yml @@ -21,7 +21,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Docker login - uses: docker/login-action@v2 + uses: docker/login-action@v3 with: registry: ghcr.io username: ${{ github.repository_owner }} From e3cc1f0edb430d44ee107bfbe94d1cb58dcd1ca7 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 15 Sep 2023 12:58:39 -0500 Subject: [PATCH 013/901] Update docker/build-push-action action to v5 (#5821) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/build-tracecontext-testsuite.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build-tracecontext-testsuite.yml b/.github/workflows/build-tracecontext-testsuite.yml index 66105391fe4..abded031b00 100644 --- a/.github/workflows/build-tracecontext-testsuite.yml +++ b/.github/workflows/build-tracecontext-testsuite.yml @@ -23,7 +23,7 @@ jobs: password: ${{ secrets.GITHUB_TOKEN }} - name: Build and push - uses: docker/build-push-action@v4 + uses: docker/build-push-action@v5 with: context: integration-tests/tracecontext/docker push: true From 9b081e19339dd636f5b37e72987cdf4f2a198532 Mon Sep 17 00:00:00 2001 From: jason plumb <75337021+breedx-splk@users.noreply.github.com> Date: Fri, 15 Sep 2023 13:15:35 -0700 Subject: [PATCH 014/901] Allow instrument names to contain a forward slash (#5824) --- .../src/main/java/io/opentelemetry/sdk/metrics/SdkMeter.java | 4 ++-- .../test/java/io/opentelemetry/sdk/metrics/SdkMeterTest.java | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkMeter.java b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkMeter.java index 5b36cef4e87..02eb45a26ff 100644 --- a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkMeter.java +++ b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkMeter.java @@ -42,12 +42,12 @@ final class SdkMeter implements Meter { *

  • They are not null or empty strings. *
  • They are case-insensitive, ASCII strings. *
  • The first character must be an alphabetic character. - *
  • Subsequent characters must belong to the alphanumeric characters, '_', '.', and '-'. + *
  • Subsequent characters must belong to the alphanumeric characters, '_', '.', '/', and '-'. *
  • They can have a maximum length of 255 characters. * */ private static final Pattern VALID_INSTRUMENT_NAME_PATTERN = - Pattern.compile("([A-Za-z]){1}([A-Za-z0-9\\_\\-\\.]){0,254}"); + Pattern.compile("([A-Za-z]){1}([A-Za-z0-9\\_\\-\\./]){0,254}"); private static final Meter NOOP_METER = MeterProvider.noop().get("noop"); private static final String NOOP_INSTRUMENT_NAME = "noop"; diff --git a/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/SdkMeterTest.java b/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/SdkMeterTest.java index 8cf501da64b..4bc44bf46cb 100644 --- a/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/SdkMeterTest.java +++ b/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/SdkMeterTest.java @@ -110,6 +110,7 @@ void checkValidInstrumentNameTest() { assertThat(checkValidInstrumentName("a1234567890")).isTrue(); assertThat(checkValidInstrumentName("a_-.")).isTrue(); assertThat(checkValidInstrumentName(new String(new char[255]).replace('\0', 'a'))).isTrue(); + assertThat(checkValidInstrumentName("a/b")).isTrue(); // Empty and null not allowed assertThat(checkValidInstrumentName(null)).isFalse(); From 9a931556fb05dadc1419736d3fecaec96af5f18c Mon Sep 17 00:00:00 2001 From: David Ashpole Date: Wed, 20 Sep 2023 16:12:15 -0400 Subject: [PATCH 015/901] Prometheus exporter: handle colliding metric attribute keys (#5717) Co-authored-by: Jack Berg --- .../exporter/prometheus/Serializer.java | 54 ++++++-- .../exporter/prometheus/SerializerTest.java | 121 +++++++++++++++++- .../exporter/prometheus/TestConstants.java | 18 +++ 3 files changed, 182 insertions(+), 11 deletions(-) diff --git a/exporters/prometheus/src/main/java/io/opentelemetry/exporter/prometheus/Serializer.java b/exporters/prometheus/src/main/java/io/opentelemetry/exporter/prometheus/Serializer.java index 7a074d0663b..c77923b80de 100644 --- a/exporters/prometheus/src/main/java/io/opentelemetry/exporter/prometheus/Serializer.java +++ b/exporters/prometheus/src/main/java/io/opentelemetry/exporter/prometheus/Serializer.java @@ -25,6 +25,7 @@ import io.opentelemetry.api.common.Attributes; import io.opentelemetry.api.trace.SpanContext; import io.opentelemetry.sdk.common.InstrumentationScopeInfo; +import io.opentelemetry.sdk.internal.ThrottlingLogger; import io.opentelemetry.sdk.metrics.data.AggregationTemporality; import io.opentelemetry.sdk.metrics.data.DoubleExemplarData; import io.opentelemetry.sdk.metrics.data.DoublePointData; @@ -58,12 +59,18 @@ import java.util.concurrent.TimeUnit; import java.util.function.BiConsumer; import java.util.function.Predicate; +import java.util.logging.Level; +import java.util.logging.Logger; import javax.annotation.Nullable; /** Serializes metrics into Prometheus exposition formats. */ // Adapted from // https://github.com/prometheus/client_java/blob/master/simpleclient_common/src/main/java/io/prometheus/client/exporter/common/TextFormat.java abstract class Serializer { + + private static final Logger LOGGER = Logger.getLogger(Serializer.class.getName()); + private static final ThrottlingLogger THROTTLING_LOGGER = new ThrottlingLogger(LOGGER); + static Serializer create(@Nullable String acceptHeader, Predicate filter) { if (acceptHeader == null) { return new Prometheus004Serializer(filter); @@ -445,27 +452,58 @@ private static void writeScopeNameAndVersion( private static void writeAttributePairs( Writer writer, boolean initialComma, Attributes attributes) throws IOException { try { + // This logic handles colliding attribute keys by joining the values, + // separated by a semicolon. It relies on the attributes being sorted, so that + // colliding attribute keys are in subsequent iterations of the for loop. attributes.forEach( new BiConsumer, Object>() { - private boolean prefixWithComma = initialComma; + boolean initialAttribute = true; + String previousKey = ""; + String previousValue = ""; @Override public void accept(AttributeKey key, Object value) { try { - if (prefixWithComma) { - writer.write(','); + String sanitizedKey = NameSanitizer.INSTANCE.apply(key.getKey()); + int compare = sanitizedKey.compareTo(previousKey); + if (compare == 0) { + // This key collides with the previous one. Append the value + // to the previous value instead of writing the key again. + writer.write(';'); } else { - prefixWithComma = true; + if (compare < 0) { + THROTTLING_LOGGER.log( + Level.WARNING, + "Dropping out-of-order attribute " + + sanitizedKey + + "=" + + value + + ", which occurred after " + + previousKey + + ". This can occur when an alternative Attribute implementation is used."); + } + if (!initialAttribute) { + writer.write('"'); + } + if (initialComma || !initialAttribute) { + writer.write(','); + } + writer.write(sanitizedKey); + writer.write("=\""); } - writer.write(NameSanitizer.INSTANCE.apply(key.getKey())); - writer.write("=\""); - writeEscapedLabelValue(writer, value.toString()); - writer.write('"'); + String stringValue = value.toString(); + writeEscapedLabelValue(writer, stringValue); + previousKey = sanitizedKey; + previousValue = stringValue; + initialAttribute = false; } catch (IOException e) { throw new UncheckedIOException(e); } } }); + if (!attributes.isEmpty()) { + writer.write('"'); + } } catch (UncheckedIOException e) { throw e.getCause(); } diff --git a/exporters/prometheus/src/test/java/io/opentelemetry/exporter/prometheus/SerializerTest.java b/exporters/prometheus/src/test/java/io/opentelemetry/exporter/prometheus/SerializerTest.java index 13bc2752ce5..210e399ac0f 100644 --- a/exporters/prometheus/src/test/java/io/opentelemetry/exporter/prometheus/SerializerTest.java +++ b/exporters/prometheus/src/test/java/io/opentelemetry/exporter/prometheus/SerializerTest.java @@ -11,6 +11,7 @@ import static io.opentelemetry.exporter.prometheus.TestConstants.DELTA_HISTOGRAM; import static io.opentelemetry.exporter.prometheus.TestConstants.DELTA_LONG_SUM; import static io.opentelemetry.exporter.prometheus.TestConstants.DOUBLE_GAUGE; +import static io.opentelemetry.exporter.prometheus.TestConstants.DOUBLE_GAUGE_COLLIDING_ATTRIBUTES; import static io.opentelemetry.exporter.prometheus.TestConstants.DOUBLE_GAUGE_MULTIPLE_ATTRIBUTES; import static io.opentelemetry.exporter.prometheus.TestConstants.DOUBLE_GAUGE_NO_ATTRIBUTES; import static io.opentelemetry.exporter.prometheus.TestConstants.LONG_GAUGE; @@ -22,15 +23,36 @@ import static io.opentelemetry.exporter.prometheus.TestConstants.SUMMARY; import static org.assertj.core.api.Assertions.assertThat; +import io.github.netmikey.logunit.api.LogCapturer; +import io.opentelemetry.api.common.AttributeKey; +import io.opentelemetry.api.common.Attributes; +import io.opentelemetry.api.common.AttributesBuilder; +import io.opentelemetry.internal.testing.slf4j.SuppressLogger; +import io.opentelemetry.sdk.common.InstrumentationScopeInfo; +import io.opentelemetry.sdk.metrics.data.AggregationTemporality; import io.opentelemetry.sdk.metrics.data.MetricData; +import io.opentelemetry.sdk.metrics.internal.data.ImmutableDoublePointData; +import io.opentelemetry.sdk.metrics.internal.data.ImmutableMetricData; +import io.opentelemetry.sdk.metrics.internal.data.ImmutableSumData; +import io.opentelemetry.sdk.resources.Resource; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.UncheckedIOException; import java.util.Arrays; +import java.util.Collections; +import java.util.LinkedHashMap; +import java.util.Map; +import java.util.function.BiConsumer; +import org.jetbrains.annotations.Nullable; import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; class SerializerTest { + @RegisterExtension + private final LogCapturer logCapturer = + LogCapturer.create().captureForLogger(Serializer.class.getName()); + @Test void prometheus004() { // Same output as prometheus client library except for these changes which are compatible with @@ -53,7 +75,8 @@ void prometheus004() { CUMULATIVE_HISTOGRAM_NO_ATTRIBUTES, CUMULATIVE_HISTOGRAM_SINGLE_ATTRIBUTE, DOUBLE_GAUGE_NO_ATTRIBUTES, - DOUBLE_GAUGE_MULTIPLE_ATTRIBUTES)) + DOUBLE_GAUGE_MULTIPLE_ATTRIBUTES, + DOUBLE_GAUGE_COLLIDING_ATTRIBUTES)) .isEqualTo( "# TYPE target info\n" + "# HELP target Target metadata\n" @@ -103,7 +126,11 @@ void prometheus004() { + "double_gauge_no_attributes_seconds{otel_scope_name=\"full\",otel_scope_version=\"version\"} 7.0 1633950672000\n" + "# TYPE double_gauge_multiple_attributes_seconds gauge\n" + "# HELP double_gauge_multiple_attributes_seconds unused\n" - + "double_gauge_multiple_attributes_seconds{otel_scope_name=\"full\",otel_scope_version=\"version\",animal=\"bear\",type=\"dgma\"} 8.0 1633950672000\n"); + + "double_gauge_multiple_attributes_seconds{otel_scope_name=\"full\",otel_scope_version=\"version\",animal=\"bear\",type=\"dgma\"} 8.0 1633950672000\n" + + "# TYPE double_gauge_colliding_attributes_seconds gauge\n" + + "# HELP double_gauge_colliding_attributes_seconds unused\n" + + "double_gauge_colliding_attributes_seconds{otel_scope_name=\"full\",otel_scope_version=\"version\",foo_bar=\"a;b\",type=\"dgma\"} 8.0 1633950672000\n"); + assertThat(logCapturer.size()).isZero(); } @Test @@ -124,7 +151,8 @@ void openMetrics() { CUMULATIVE_HISTOGRAM_NO_ATTRIBUTES, CUMULATIVE_HISTOGRAM_SINGLE_ATTRIBUTE, DOUBLE_GAUGE_NO_ATTRIBUTES, - DOUBLE_GAUGE_MULTIPLE_ATTRIBUTES)) + DOUBLE_GAUGE_MULTIPLE_ATTRIBUTES, + DOUBLE_GAUGE_COLLIDING_ATTRIBUTES)) .isEqualTo( "# TYPE target info\n" + "# HELP target Target metadata\n" @@ -175,7 +203,52 @@ void openMetrics() { + "# TYPE double_gauge_multiple_attributes_seconds gauge\n" + "# HELP double_gauge_multiple_attributes_seconds unused\n" + "double_gauge_multiple_attributes_seconds{otel_scope_name=\"full\",otel_scope_version=\"version\",animal=\"bear\",type=\"dgma\"} 8.0 1633950672.000\n" + + "# TYPE double_gauge_colliding_attributes_seconds gauge\n" + + "# HELP double_gauge_colliding_attributes_seconds unused\n" + + "double_gauge_colliding_attributes_seconds{otel_scope_name=\"full\",otel_scope_version=\"version\",foo_bar=\"a;b\",type=\"dgma\"} 8.0 1633950672.000\n" + "# EOF\n"); + assertThat(logCapturer.size()).isZero(); + } + + @Test + @SuppressLogger(Serializer.class) + void outOfOrderedAttributes() { + // Alternative attributes implementation which sorts entries by the order they were added rather + // than lexicographically + // all attributes are retained, we log a warning, and b_key and b.key are not be merged + LinkedHashMap, Object> attributesMap = new LinkedHashMap<>(); + attributesMap.put(AttributeKey.stringKey("b_key"), "val1"); + attributesMap.put(AttributeKey.stringKey("a_key"), "val2"); + attributesMap.put(AttributeKey.stringKey("b.key"), "val3"); + Attributes attributes = new MapAttributes(attributesMap); + + MetricData metricData = + ImmutableMetricData.createDoubleSum( + Resource.builder().put("kr", "vr").build(), + InstrumentationScopeInfo.builder("scope").setVersion("1.0.0").build(), + "sum", + "description", + "s", + ImmutableSumData.create( + /* isMonotonic= */ true, + AggregationTemporality.CUMULATIVE, + Collections.singletonList( + ImmutableDoublePointData.create( + 1633947011000000000L, 1633950672000000000L, attributes, 5)))); + + assertThat(serialize004(metricData)) + .isEqualTo( + "# TYPE target info\n" + + "# HELP target Target metadata\n" + + "target_info{kr=\"vr\"} 1\n" + + "# TYPE otel_scope_info info\n" + + "# HELP otel_scope_info Scope metadata\n" + + "otel_scope_info{otel_scope_name=\"scope\",otel_scope_version=\"1.0.0\"} 1\n" + + "# TYPE sum_seconds_total counter\n" + + "# HELP sum_seconds_total description\n" + + "sum_seconds_total{otel_scope_name=\"scope\",otel_scope_version=\"1.0.0\",b_key=\"val1\",a_key=\"val2\",b_key=\"val3\"} 5.0 1633950672000\n"); + logCapturer.assertContains( + "Dropping out-of-order attribute a_key=val2, which occurred after b_key. This can occur when an alternative Attribute implementation is used."); } private static String serialize004(MetricData... metrics) { @@ -197,4 +270,46 @@ private static String serializeOpenMetrics(MetricData... metrics) { throw new UncheckedIOException(e); } } + + @SuppressWarnings("unchecked") + private static class MapAttributes implements Attributes { + + private final LinkedHashMap, Object> map; + + @SuppressWarnings("NonApiType") + private MapAttributes(LinkedHashMap, Object> map) { + this.map = map; + } + + @Nullable + @Override + public T get(AttributeKey key) { + return (T) map.get(key); + } + + @Override + public void forEach(BiConsumer, ? super Object> consumer) { + map.forEach(consumer); + } + + @Override + public int size() { + return map.size(); + } + + @Override + public boolean isEmpty() { + return map.isEmpty(); + } + + @Override + public Map, Object> asMap() { + return map; + } + + @Override + public AttributesBuilder toBuilder() { + throw new UnsupportedOperationException("not supported"); + } + } } diff --git a/exporters/prometheus/src/test/java/io/opentelemetry/exporter/prometheus/TestConstants.java b/exporters/prometheus/src/test/java/io/opentelemetry/exporter/prometheus/TestConstants.java index 10869229e06..3edc286c9ee 100644 --- a/exporters/prometheus/src/test/java/io/opentelemetry/exporter/prometheus/TestConstants.java +++ b/exporters/prometheus/src/test/java/io/opentelemetry/exporter/prometheus/TestConstants.java @@ -357,4 +357,22 @@ private TestConstants() { 1633950672000000000L, Attributes.of(TYPE, "dgma", stringKey("animal"), "bear"), 8)))); + static final MetricData DOUBLE_GAUGE_COLLIDING_ATTRIBUTES = + ImmutableMetricData.createDoubleGauge( + Resource.create(Attributes.of(stringKey("kr"), "vr")), + InstrumentationScopeInfo.builder("full") + .setVersion("version") + .setAttributes(Attributes.of(stringKey("ks"), "vs")) + .build(), + "double.gauge.colliding.attributes", + "unused", + "s", + ImmutableGaugeData.create( + Collections.singletonList( + ImmutableDoublePointData.create( + 1633947011000000000L, + 1633950672000000000L, + Attributes.of( + TYPE, "dgma", stringKey("foo.bar"), "a", stringKey("foo_bar"), "b"), + 8)))); } From b0c337b075f287d6df91f48c37358706917bd8a0 Mon Sep 17 00:00:00 2001 From: Asaf Mesika Date: Tue, 26 Sep 2023 21:21:46 +0300 Subject: [PATCH 016/901] Memory Mode support: Adding memory mode, and implementing it for Asynchronous Instruments (#5709) Co-authored-by: jack-berg <34418638+jack-berg@users.noreply.github.com> --- CONTRIBUTING.md | 5 +- dependencyManagement/build.gradle.kts | 1 + .../opentelemetry-sdk-common.txt | 11 +- .../opentelemetry-sdk-metrics.txt | 10 +- .../opentelemetry-sdk-testing.txt | 12 +- .../sdk/common/export/MemoryMode.java | 26 ++ sdk/metrics/build.gradle.kts | 7 + ...tricStorageGarbageCollectionBenchmark.java | 128 +++++++++ ...StorageGarbageCollectionBenchmarkTest.java | 106 +++++++ .../internal/state/AttributesGenerator.java | 45 +++ .../internal/state/NoopMetricExporter.java | 63 +++++ .../sdk/metrics/data/DoublePointData.java | 2 - .../sdk/metrics/data/LongPointData.java | 2 - .../sdk/metrics/data/PointData.java | 2 - .../sdk/metrics/export/MetricExporter.java | 13 + .../sdk/metrics/export/MetricReader.java | 13 + .../metrics/export/PeriodicMetricReader.java | 6 + .../internal/aggregator/Aggregator.java | 35 +++ .../aggregator/DoubleLastValueAggregator.java | 26 ++ .../aggregator/DoubleSumAggregator.java | 32 +++ .../aggregator/LongLastValueAggregator.java | 26 ++ .../aggregator/LongSumAggregator.java | 32 +++ .../internal/data/MutableDoublePointData.java | 138 +++++++++ .../internal/data/MutableLongPointData.java | 136 +++++++++ .../internal/export/MetricProducer.java | 5 + .../internal/state/ArrayBasedStack.java | 79 ++++++ .../state/AsynchronousMetricStorage.java | 136 ++++++--- .../internal/state/ImmutableMeasurement.java | 64 +++++ .../metrics/internal/state/Measurement.java | 78 +++-- .../internal/state/MutableMeasurement.java | 125 ++++++++ .../metrics/internal/state/ObjectPool.java | 53 ++++ .../metrics/internal/state/PooledHashMap.java | 267 ++++++++++++++++++ .../state/SdkObservableMeasurement.java | 60 +++- .../DoubleLastValueAggregatorTest.java | 89 ++++++ .../aggregator/DoubleSumAggregatorTest.java | 89 ++++++ .../LongLastValueAggregatorTest.java | 96 +++++++ .../aggregator/LongSumAggregatorTest.java | 91 ++++++ .../internal/state/ArrayBasedStackTest.java | 63 +++++ .../state/AsynchronousMetricStorageTest.java | 162 ++++++++--- .../state/CallbackRegistrationTest.java | 22 +- .../internal/state/ObjectPoolTest.java | 62 ++++ .../internal/state/PooledHashMapTest.java | 75 +++++ .../state/SdkObservableMeasurementTest.java | 175 ++++++++++++ sdk/metrics/testing-internal/build.gradle.kts | 13 + .../sdk/testing/assertj/LongSumAssert.java | 4 +- .../exporter/InMemoryMetricReader.java | 28 ++ .../exporter/InMemoryMetricReaderBuilder.java | 63 +++++ 47 files changed, 2620 insertions(+), 156 deletions(-) create mode 100644 sdk/common/src/main/java/io/opentelemetry/sdk/common/export/MemoryMode.java create mode 100644 sdk/metrics/src/jmhBasedTest/java/io/opentelemetry/sdk/metrics/internal/state/AsynchronousMetricStorageGarbageCollectionBenchmark.java create mode 100644 sdk/metrics/src/jmhBasedTest/java/io/opentelemetry/sdk/metrics/internal/state/AsynchronousMetricStorageGarbageCollectionBenchmarkTest.java create mode 100644 sdk/metrics/src/jmhBasedTest/java/io/opentelemetry/sdk/metrics/internal/state/AttributesGenerator.java create mode 100644 sdk/metrics/src/jmhBasedTest/java/io/opentelemetry/sdk/metrics/internal/state/NoopMetricExporter.java create mode 100644 sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/data/MutableDoublePointData.java create mode 100644 sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/data/MutableLongPointData.java create mode 100644 sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/state/ArrayBasedStack.java create mode 100644 sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/state/ImmutableMeasurement.java create mode 100644 sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/state/MutableMeasurement.java create mode 100644 sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/state/ObjectPool.java create mode 100644 sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/state/PooledHashMap.java create mode 100644 sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/internal/state/ArrayBasedStackTest.java create mode 100644 sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/internal/state/ObjectPoolTest.java create mode 100644 sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/internal/state/PooledHashMapTest.java create mode 100644 sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/internal/state/SdkObservableMeasurementTest.java create mode 100644 sdk/metrics/testing-internal/build.gradle.kts create mode 100644 sdk/testing/src/main/java/io/opentelemetry/sdk/testing/exporter/InMemoryMetricReaderBuilder.java diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 8171d76655b..b599a32fb3b 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -8,7 +8,7 @@ requirements and recommendations. If you want to add new features or change behavior, please make sure your changes follow the [OpenTelemetry Specification](https://github.com/open-telemetry/opentelemetry-specification). -Otherwise file an issue or submit a PR to the specification repo first. +Otherwise, file an issue or submit a PR to the specification repo first. Make sure to review the projects [license](LICENSE) and sign the [CNCF CLA](https://identity.linuxfoundation.org/projects/cncf). A signed CLA will be enforced by an @@ -52,7 +52,8 @@ $ ./gradlew check Note: this gradle task will potentially generate changes to files in the `docs/apidiffs/current_vs_latest` -directory. Please make sure to include any changes to these files in your pull request. +directory. Please make sure to include any changes to these files in your pull request (i.e. +add those files to your commits in the PR). ## PR Review diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index 8c27fb4232e..46aa12a1343 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -45,6 +45,7 @@ val DEPENDENCIES = listOf( "io.opencensus:opencensus-contrib-exemplar-util:${opencensusVersion}", "org.openjdk.jmh:jmh-core:${jmhVersion}", "org.openjdk.jmh:jmh-generator-bytecode:${jmhVersion}", + "org.openjdk.jmh:jmh-generator-annprocess:${jmhVersion}", "org.mockito:mockito-core:${mockitoVersion}", "org.mockito:mockito-junit-jupiter:${mockitoVersion}", "org.slf4j:slf4j-simple:${slf4jVersion}", diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-common.txt b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-common.txt index df26146497b..cc95503822e 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-common.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-common.txt @@ -1,2 +1,11 @@ Comparing source compatibility of against -No changes. \ No newline at end of file ++++ NEW ENUM: PUBLIC(+) FINAL(+) io.opentelemetry.sdk.common.export.MemoryMode (compatible) + +++ CLASS FILE FORMAT VERSION: 52.0 <- n.a. + +++ NEW INTERFACE: java.lang.constant.Constable + +++ NEW INTERFACE: java.lang.Comparable + +++ NEW INTERFACE: java.io.Serializable + +++ NEW SUPERCLASS: java.lang.Enum + +++ NEW FIELD: PUBLIC(+) STATIC(+) FINAL(+) io.opentelemetry.sdk.common.export.MemoryMode REUSABLE_DATA + +++ NEW FIELD: PUBLIC(+) STATIC(+) FINAL(+) io.opentelemetry.sdk.common.export.MemoryMode IMMUTABLE_DATA + +++ NEW METHOD: PUBLIC(+) STATIC(+) io.opentelemetry.sdk.common.export.MemoryMode valueOf(java.lang.String) + +++ NEW METHOD: PUBLIC(+) STATIC(+) io.opentelemetry.sdk.common.export.MemoryMode[] values() diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-metrics.txt b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-metrics.txt index df26146497b..5753f2fee9b 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-metrics.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-metrics.txt @@ -1,2 +1,10 @@ Comparing source compatibility of against -No changes. \ No newline at end of file +*** MODIFIED INTERFACE: PUBLIC ABSTRACT io.opentelemetry.sdk.metrics.export.MetricExporter (not serializable) + === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 + +++ NEW METHOD: PUBLIC(+) io.opentelemetry.sdk.common.export.MemoryMode getMemoryMode() +*** MODIFIED INTERFACE: PUBLIC ABSTRACT io.opentelemetry.sdk.metrics.export.MetricReader (not serializable) + === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 + +++ NEW METHOD: PUBLIC(+) io.opentelemetry.sdk.common.export.MemoryMode getMemoryMode() +*** MODIFIED CLASS: PUBLIC FINAL io.opentelemetry.sdk.metrics.export.PeriodicMetricReader (not serializable) + === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 + +++ NEW METHOD: PUBLIC(+) io.opentelemetry.sdk.common.export.MemoryMode getMemoryMode() diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-testing.txt b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-testing.txt index df26146497b..24ed11618d8 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-testing.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-testing.txt @@ -1,2 +1,12 @@ Comparing source compatibility of against -No changes. \ No newline at end of file +*** MODIFIED CLASS: PUBLIC io.opentelemetry.sdk.testing.exporter.InMemoryMetricReader (not serializable) + === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 + +++ NEW METHOD: PUBLIC(+) STATIC(+) io.opentelemetry.sdk.testing.exporter.InMemoryMetricReaderBuilder builder() + +++ NEW METHOD: PUBLIC(+) io.opentelemetry.sdk.common.export.MemoryMode getMemoryMode() ++++ NEW CLASS: PUBLIC(+) FINAL(+) io.opentelemetry.sdk.testing.exporter.InMemoryMetricReaderBuilder (not serializable) + +++ CLASS FILE FORMAT VERSION: 52.0 <- n.a. + +++ NEW SUPERCLASS: java.lang.Object + +++ NEW METHOD: PUBLIC(+) io.opentelemetry.sdk.testing.exporter.InMemoryMetricReader build() + +++ NEW METHOD: PUBLIC(+) io.opentelemetry.sdk.testing.exporter.InMemoryMetricReaderBuilder setAggregationTemporalitySelector(io.opentelemetry.sdk.metrics.export.AggregationTemporalitySelector) + +++ NEW METHOD: PUBLIC(+) io.opentelemetry.sdk.testing.exporter.InMemoryMetricReaderBuilder setDefaultAggregationSelector(io.opentelemetry.sdk.metrics.export.DefaultAggregationSelector) + +++ NEW METHOD: PUBLIC(+) io.opentelemetry.sdk.testing.exporter.InMemoryMetricReaderBuilder setMemoryMode(io.opentelemetry.sdk.common.export.MemoryMode) diff --git a/sdk/common/src/main/java/io/opentelemetry/sdk/common/export/MemoryMode.java b/sdk/common/src/main/java/io/opentelemetry/sdk/common/export/MemoryMode.java new file mode 100644 index 00000000000..24c87d13de6 --- /dev/null +++ b/sdk/common/src/main/java/io/opentelemetry/sdk/common/export/MemoryMode.java @@ -0,0 +1,26 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.sdk.common.export; + +/** The memory semantics of the SDK. */ +public enum MemoryMode { + + /** + * Reuses objects to reduce allocations. + * + *

    In this mode, the SDK reuses objects to reduce allocations, at the expense of disallowing + * concurrent collections / exports. + */ + REUSABLE_DATA, + + /** + * Uses immutable data structures. + * + *

    In this mode, the SDK passes immutable objects to exporters / readers, increasing + * allocations but ensuring safe concurrent exports. + */ + IMMUTABLE_DATA +} diff --git a/sdk/metrics/build.gradle.kts b/sdk/metrics/build.gradle.kts index 326f1750a61..010291e3d72 100644 --- a/sdk/metrics/build.gradle.kts +++ b/sdk/metrics/build.gradle.kts @@ -41,6 +41,13 @@ testing { } } } + register("jmhBasedTest") { + dependencies { + implementation("org.openjdk.jmh:jmh-core") + implementation("org.openjdk.jmh:jmh-generator-bytecode") + annotationProcessor("org.openjdk.jmh:jmh-generator-annprocess") + } + } } } diff --git a/sdk/metrics/src/jmhBasedTest/java/io/opentelemetry/sdk/metrics/internal/state/AsynchronousMetricStorageGarbageCollectionBenchmark.java b/sdk/metrics/src/jmhBasedTest/java/io/opentelemetry/sdk/metrics/internal/state/AsynchronousMetricStorageGarbageCollectionBenchmark.java new file mode 100644 index 00000000000..b1d845773dd --- /dev/null +++ b/sdk/metrics/src/jmhBasedTest/java/io/opentelemetry/sdk/metrics/internal/state/AsynchronousMetricStorageGarbageCollectionBenchmark.java @@ -0,0 +1,128 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.sdk.metrics.internal.state; + +import io.opentelemetry.api.common.Attributes; +import io.opentelemetry.sdk.common.export.MemoryMode; +import io.opentelemetry.sdk.metrics.Aggregation; +import io.opentelemetry.sdk.metrics.SdkMeterProvider; +import io.opentelemetry.sdk.metrics.SdkMeterProviderBuilder; +import io.opentelemetry.sdk.metrics.data.AggregationTemporality; +import io.opentelemetry.sdk.metrics.export.PeriodicMetricReader; +import io.opentelemetry.sdk.metrics.internal.SdkMeterProviderUtil; +import io.opentelemetry.sdk.metrics.internal.exemplar.ExemplarFilter; +import java.time.Duration; +import java.util.List; +import java.util.Random; +import java.util.concurrent.TimeUnit; +import org.openjdk.jmh.annotations.Benchmark; +import org.openjdk.jmh.annotations.BenchmarkMode; +import org.openjdk.jmh.annotations.Fork; +import org.openjdk.jmh.annotations.Measurement; +import org.openjdk.jmh.annotations.Mode; +import org.openjdk.jmh.annotations.OutputTimeUnit; +import org.openjdk.jmh.annotations.Param; +import org.openjdk.jmh.annotations.Scope; +import org.openjdk.jmh.annotations.Setup; +import org.openjdk.jmh.annotations.State; +import org.openjdk.jmh.annotations.TearDown; +import org.openjdk.jmh.annotations.Threads; +import org.openjdk.jmh.annotations.Warmup; + +/** + * Run this through {@link AsynchronousMetricStorageGarbageCollectionBenchmarkTest}, as it runs it + * embedded with the GC profiler which what this test designed for (No need for command line run) + * + *

    This test creates 10 asynchronous counters (any asynchronous instrument will do as the code + * path is almost the same for all async instrument types), and 1000 attribute sets. Each time the + * test runs, it calls `flush` which effectively calls the callback for each counter. Each such + * callback records a random number for each of the 1000 attribute sets. The result list ends up in + * {@link NoopMetricExporter} which does nothing with it. + * + *

    This is repeated 100 times, collectively called Operation in the statistics and each such + * operation is repeated 20 times - known as Iteration. + * + *

    Each such test is repeated, with a brand new JVM, for all combinations of {@link MemoryMode} + * and {@link AggregationTemporality}. This is done since each combination has a different code + * path. + */ +@BenchmarkMode(Mode.SingleShotTime) +@OutputTimeUnit(TimeUnit.NANOSECONDS) +@Measurement(iterations = 20, batchSize = 100) +@Warmup(iterations = 10, batchSize = 10) +@Fork(1) +public class AsynchronousMetricStorageGarbageCollectionBenchmark { + + @State(value = Scope.Benchmark) + @SuppressWarnings("SystemOut") + public static class ThreadState { + private final int cardinality; + private final int countersCount; + @Param public AggregationTemporality aggregationTemporality; + @Param public MemoryMode memoryMode; + SdkMeterProvider sdkMeterProvider; + private final Random random = new Random(); + List attributesList; + + /** Creates a ThreadState. */ + @SuppressWarnings("unused") + public ThreadState() { + cardinality = 1000; + countersCount = 10; + } + + @SuppressWarnings("SpellCheckingInspection") + @Setup + public void setup() { + PeriodicMetricReader metricReader = + PeriodicMetricReader.builder( + // Configure an exporter that configures the temporality and aggregation + // for the test case, but otherwise drops the data on export + new NoopMetricExporter(aggregationTemporality, Aggregation.sum(), memoryMode)) + // Effectively disable periodic reading so reading is only done on #flush() + .setInterval(Duration.ofSeconds(Integer.MAX_VALUE)) + .build(); + SdkMeterProviderBuilder builder = SdkMeterProvider.builder(); + SdkMeterProviderUtil.registerMetricReaderWithCardinalitySelector( + builder, metricReader, unused -> cardinality + 1); + + attributesList = AttributesGenerator.generate(cardinality); + + // Disable examplars + SdkMeterProviderUtil.setExemplarFilter(builder, ExemplarFilter.alwaysOff()); + + sdkMeterProvider = builder.build(); + for (int i = 0; i < countersCount; i++) { + sdkMeterProvider + .get("meter") + .counterBuilder("counter" + i) + .buildWithCallback( + observableLongMeasurement -> { + for (int j = 0; j < attributesList.size(); j++) { + Attributes attributes = attributesList.get(j); + observableLongMeasurement.record(random.nextInt(10_000), attributes); + } + }); + } + } + + @TearDown + public void tearDown() { + sdkMeterProvider.shutdown().join(10, TimeUnit.SECONDS); + } + } + + /** + * Collects all asynchronous instruments metric data. + * + * @param threadState thread-state + */ + @Benchmark + @Threads(value = 1) + public void recordAndCollect(ThreadState threadState) { + threadState.sdkMeterProvider.forceFlush().join(10, TimeUnit.SECONDS); + } +} diff --git a/sdk/metrics/src/jmhBasedTest/java/io/opentelemetry/sdk/metrics/internal/state/AsynchronousMetricStorageGarbageCollectionBenchmarkTest.java b/sdk/metrics/src/jmhBasedTest/java/io/opentelemetry/sdk/metrics/internal/state/AsynchronousMetricStorageGarbageCollectionBenchmarkTest.java new file mode 100644 index 00000000000..a5b5f5cc5d2 --- /dev/null +++ b/sdk/metrics/src/jmhBasedTest/java/io/opentelemetry/sdk/metrics/internal/state/AsynchronousMetricStorageGarbageCollectionBenchmarkTest.java @@ -0,0 +1,106 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.sdk.metrics.internal.state; + +import static org.assertj.core.api.Assertions.assertThat; + +import io.opentelemetry.sdk.common.InstrumentationScopeInfo; +import io.opentelemetry.sdk.common.export.MemoryMode; +import io.opentelemetry.sdk.metrics.data.AggregationTemporality; +import io.opentelemetry.sdk.resources.Resource; +import java.util.Collection; +import java.util.HashMap; +import java.util.Map; +import org.assertj.core.data.Offset; +import org.junit.jupiter.api.Assumptions; +import org.junit.jupiter.api.Test; +import org.openjdk.jmh.infra.BenchmarkParams; +import org.openjdk.jmh.results.BenchmarkResult; +import org.openjdk.jmh.results.Result; +import org.openjdk.jmh.results.RunResult; +import org.openjdk.jmh.runner.Runner; +import org.openjdk.jmh.runner.RunnerException; +import org.openjdk.jmh.runner.options.Options; +import org.openjdk.jmh.runner.options.OptionsBuilder; + +public class AsynchronousMetricStorageGarbageCollectionBenchmarkTest { + + /** + * This test validates that in {@link MemoryMode#REUSABLE_DATA}, {@link + * AsynchronousMetricStorage#collect(Resource, InstrumentationScopeInfo, long, long)} barely + * allocates memory which is then subsequently garbage collected. It is done so comparatively to + * {@link MemoryMode#IMMUTABLE_DATA}, + * + *

    It runs the JMH test {@link AsynchronousMetricStorageGarbageCollectionBenchmark} with GC + * profiler, and measures for each parameter combination the garbage collector normalized rate + * (bytes allocated per Operation). + * + *

    Memory allocations can be hidden even at an innocent foreach loop on a collection, which + * under the hood allocates an internal object O(N) times. Someone can accidentally refactor such + * loop, resulting in 30% increase of garbage collected objects during a single collect() run. + */ + @SuppressWarnings("rawtypes") + @Test + public void normalizedAllocationRateTest() throws RunnerException { + // GitHub CI has an environment variable (CI=true). We can use it to skip + // this test since it's a lengthy one (roughly 10 seconds) and have it running + // only in GitHub CI + Assumptions.assumeTrue( + "true".equals(System.getenv("CI")), + "This test should only run in GitHub CI since it's long"); + + // Runs AsynchronousMetricStorageMemoryProfilingBenchmark + // with garbage collection profiler + Options opt = + new OptionsBuilder() + .include(AsynchronousMetricStorageGarbageCollectionBenchmark.class.getSimpleName()) + .addProfiler("gc") + .shouldFailOnError(true) + .jvmArgs("-Xmx1500m") + .build(); + Collection results = new Runner(opt).run(); + + // Collect the normalized GC allocation rate per parameters combination + Map> resultMap = new HashMap<>(); + for (RunResult result : results) { + for (BenchmarkResult benchmarkResult : result.getBenchmarkResults()) { + BenchmarkParams benchmarkParams = benchmarkResult.getParams(); + + String memoryMode = benchmarkParams.getParam("memoryMode"); + String aggregationTemporality = benchmarkParams.getParam("aggregationTemporality"); + assertThat(memoryMode).isNotNull(); + assertThat(aggregationTemporality).isNotNull(); + + Map secondaryResults = benchmarkResult.getSecondaryResults(); + Result allocRateNorm = secondaryResults.get("gc.alloc.rate.norm"); + assertThat(allocRateNorm) + .describedAs("Allocation rate in secondary results: %s", secondaryResults) + .isNotNull(); + + resultMap + .computeIfAbsent(aggregationTemporality, k -> new HashMap<>()) + .put(memoryMode, allocRateNorm.getScore()); + } + } + + assertThat(resultMap).hasSameSizeAs(AggregationTemporality.values()); + + // Asserts that reusable data GC allocation rate is a tiny fraction of immutable data + // GC allocation rate + resultMap.forEach( + (aggregationTemporality, memoryModeToAllocRateMap) -> { + Double immutableDataAllocRate = + memoryModeToAllocRateMap.get(MemoryMode.IMMUTABLE_DATA.toString()); + Double reusableDataAllocRate = + memoryModeToAllocRateMap.get(MemoryMode.REUSABLE_DATA.toString()); + + assertThat(immutableDataAllocRate).isNotNull().isNotZero(); + assertThat(reusableDataAllocRate).isNotNull().isNotZero(); + assertThat(100 - (reusableDataAllocRate / immutableDataAllocRate) * 100) + .isCloseTo(99.8, Offset.offset(2.0)); + }); + } +} diff --git a/sdk/metrics/src/jmhBasedTest/java/io/opentelemetry/sdk/metrics/internal/state/AttributesGenerator.java b/sdk/metrics/src/jmhBasedTest/java/io/opentelemetry/sdk/metrics/internal/state/AttributesGenerator.java new file mode 100644 index 00000000000..3aea1dbd6d6 --- /dev/null +++ b/sdk/metrics/src/jmhBasedTest/java/io/opentelemetry/sdk/metrics/internal/state/AttributesGenerator.java @@ -0,0 +1,45 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.sdk.metrics.internal.state; + +import io.opentelemetry.api.common.Attributes; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Random; + +public class AttributesGenerator { + + private AttributesGenerator() {} + + /** + * Generates a list of unique attributes, with a single attribute key, and random value. + * + * @param uniqueAttributesCount The amount of unique attribute sets to generate + * @return The list of generates {@link Attributes} + */ + public static List generate(int uniqueAttributesCount) { + Random random = new Random(); + HashSet attributeSet = new HashSet<>(); + ArrayList attributesList = new ArrayList<>(uniqueAttributesCount); + String last = "aaaaaaaaaaaaaaaaaaaaaaaaaa"; + for (int i = 0; i < uniqueAttributesCount; i++) { + char[] chars = last.toCharArray(); + int attempts = 0; + do { + chars[random.nextInt(last.length())] = (char) (random.nextInt(26) + 'a'); + } while (attributeSet.contains(new String(chars)) && ++attempts < 1000); + if (attributeSet.contains(new String(chars))) { + throw new IllegalStateException("Couldn't create new random attributes"); + } + last = new String(chars); + attributesList.add(Attributes.builder().put("key", last).build()); + attributeSet.add(last); + } + + return attributesList; + } +} diff --git a/sdk/metrics/src/jmhBasedTest/java/io/opentelemetry/sdk/metrics/internal/state/NoopMetricExporter.java b/sdk/metrics/src/jmhBasedTest/java/io/opentelemetry/sdk/metrics/internal/state/NoopMetricExporter.java new file mode 100644 index 00000000000..533a3cc34dc --- /dev/null +++ b/sdk/metrics/src/jmhBasedTest/java/io/opentelemetry/sdk/metrics/internal/state/NoopMetricExporter.java @@ -0,0 +1,63 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.sdk.metrics.internal.state; + +import io.opentelemetry.sdk.common.CompletableResultCode; +import io.opentelemetry.sdk.common.export.MemoryMode; +import io.opentelemetry.sdk.metrics.Aggregation; +import io.opentelemetry.sdk.metrics.InstrumentType; +import io.opentelemetry.sdk.metrics.data.AggregationTemporality; +import io.opentelemetry.sdk.metrics.data.MetricData; +import io.opentelemetry.sdk.metrics.export.MetricExporter; +import java.util.Collection; + +public class NoopMetricExporter implements MetricExporter { + private final AggregationTemporality aggregationTemporality; + private final Aggregation aggregation; + private final MemoryMode memoryMode; + + /** + * Create a {@link NoopMetricExporter} with aggregationTemporality, aggregation and memory mode. + */ + public NoopMetricExporter( + AggregationTemporality aggregationTemporality, + Aggregation aggregation, + MemoryMode memoryMode) { + this.aggregationTemporality = aggregationTemporality; + this.aggregation = aggregation; + this.memoryMode = memoryMode; + } + + @Override + public CompletableResultCode export(Collection metrics) { + return CompletableResultCode.ofSuccess(); + } + + @Override + public CompletableResultCode flush() { + return CompletableResultCode.ofSuccess(); + } + + @Override + public CompletableResultCode shutdown() { + return CompletableResultCode.ofSuccess(); + } + + @Override + public Aggregation getDefaultAggregation(InstrumentType instrumentType) { + return aggregation; + } + + @Override + public AggregationTemporality getAggregationTemporality(InstrumentType instrumentType) { + return aggregationTemporality; + } + + @Override + public MemoryMode getMemoryMode() { + return memoryMode; + } +} diff --git a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/data/DoublePointData.java b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/data/DoublePointData.java index bcb90a3d96a..fefbd27f547 100644 --- a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/data/DoublePointData.java +++ b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/data/DoublePointData.java @@ -6,14 +6,12 @@ package io.opentelemetry.sdk.metrics.data; import java.util.List; -import javax.annotation.concurrent.Immutable; /** * Point data with a {@code double} aggregation value. * * @since 1.14.0 */ -@Immutable public interface DoublePointData extends PointData { /** Returns the value of the data point. */ double getValue(); diff --git a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/data/LongPointData.java b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/data/LongPointData.java index 8cf3129119b..18b42cb9d06 100644 --- a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/data/LongPointData.java +++ b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/data/LongPointData.java @@ -6,14 +6,12 @@ package io.opentelemetry.sdk.metrics.data; import java.util.List; -import javax.annotation.concurrent.Immutable; /** * A point data with a {@code double} aggregation value. * * @since 1.14.0 */ -@Immutable public interface LongPointData extends PointData { /** Returns the value of the data point. */ long getValue(); diff --git a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/data/PointData.java b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/data/PointData.java index bb4684cfa6e..4e19c603e99 100644 --- a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/data/PointData.java +++ b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/data/PointData.java @@ -7,7 +7,6 @@ import io.opentelemetry.api.common.Attributes; import java.util.List; -import javax.annotation.concurrent.Immutable; /** * A point in the metric data model. @@ -17,7 +16,6 @@ * * @since 1.14.0 */ -@Immutable public interface PointData { /** Returns the start time of the aggregation in epoch nanos. */ long getStartEpochNanos(); diff --git a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/export/MetricExporter.java b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/export/MetricExporter.java index af9f5f4747c..f4f8f569055 100644 --- a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/export/MetricExporter.java +++ b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/export/MetricExporter.java @@ -5,7 +5,10 @@ package io.opentelemetry.sdk.metrics.export; +import static io.opentelemetry.sdk.common.export.MemoryMode.IMMUTABLE_DATA; + import io.opentelemetry.sdk.common.CompletableResultCode; +import io.opentelemetry.sdk.common.export.MemoryMode; import io.opentelemetry.sdk.metrics.Aggregation; import io.opentelemetry.sdk.metrics.InstrumentType; import io.opentelemetry.sdk.metrics.SdkMeterProvider; @@ -38,6 +41,16 @@ default Aggregation getDefaultAggregation(InstrumentType instrumentType) { return Aggregation.defaultAggregation(); } + /** + * Returns the memory mode used by this exporter's associated reader. + * + * @return The {@link MemoryMode} used by this exporter's associated reader + * @since 1.29.0 + */ + default MemoryMode getMemoryMode() { + return IMMUTABLE_DATA; + } + /** * Exports the {@code metrics}. The caller (i.e. {@link PeriodicMetricReader} will not call export * until the previous call completes. diff --git a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/export/MetricReader.java b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/export/MetricReader.java index 3752ba2640c..0b0fb974d78 100644 --- a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/export/MetricReader.java +++ b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/export/MetricReader.java @@ -5,7 +5,10 @@ package io.opentelemetry.sdk.metrics.export; +import static io.opentelemetry.sdk.common.export.MemoryMode.IMMUTABLE_DATA; + import io.opentelemetry.sdk.common.CompletableResultCode; +import io.opentelemetry.sdk.common.export.MemoryMode; import io.opentelemetry.sdk.metrics.Aggregation; import io.opentelemetry.sdk.metrics.InstrumentType; import io.opentelemetry.sdk.metrics.SdkMeterProvider; @@ -44,6 +47,16 @@ default Aggregation getDefaultAggregation(InstrumentType instrumentType) { return Aggregation.defaultAggregation(); } + /** + * Returns the memory mode used by this reader. + * + * @return The {@link MemoryMode} used by this instance + * @since 1.29.0 + */ + default MemoryMode getMemoryMode() { + return IMMUTABLE_DATA; + } + /** * Read and export the metrics. * diff --git a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/export/PeriodicMetricReader.java b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/export/PeriodicMetricReader.java index a03e10e35d2..d22133677fb 100644 --- a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/export/PeriodicMetricReader.java +++ b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/export/PeriodicMetricReader.java @@ -6,6 +6,7 @@ package io.opentelemetry.sdk.metrics.export; import io.opentelemetry.sdk.common.CompletableResultCode; +import io.opentelemetry.sdk.common.export.MemoryMode; import io.opentelemetry.sdk.metrics.Aggregation; import io.opentelemetry.sdk.metrics.InstrumentType; import io.opentelemetry.sdk.metrics.SdkMeterProvider; @@ -74,6 +75,11 @@ public Aggregation getDefaultAggregation(InstrumentType instrumentType) { return exporter.getDefaultAggregation(instrumentType); } + @Override + public MemoryMode getMemoryMode() { + return exporter.getMemoryMode(); + } + @Override public CompletableResultCode forceFlush() { return scheduled.doRun(); diff --git a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/aggregator/Aggregator.java b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/aggregator/Aggregator.java index 863aff87300..e44eb2de33e 100644 --- a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/aggregator/Aggregator.java +++ b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/aggregator/Aggregator.java @@ -53,6 +53,21 @@ default T diff(T previousCumulative, T currentCumulative) { throw new UnsupportedOperationException("This aggregator does not support diff."); } + /** + * Resets one reusable point to be a DELTA point by computing the difference between two + * cumulative points. + * + *

    The delta between the two points is set on {@code previousCumulativeReusable} + * + *

    Aggregators MUST implement diff if it can be used with asynchronous instruments. + * + * @param previousCumulativeReusable the previously captured point. + * @param currentCumulative the newly captured (cumulative) point. + */ + default void diffInPlace(T previousCumulativeReusable, T currentCumulative) { + throw new UnsupportedOperationException("This aggregator does not support diffInPlace."); + } + /** * Return a new point representing the measurement. * @@ -62,6 +77,26 @@ default T toPoint(Measurement measurement) { throw new UnsupportedOperationException("This aggregator does not support toPoint."); } + /** + * Resets {@code reusablePoint} to represent the {@code measurement}. + * + *

    Aggregators MUST implement diff if it can be used with asynchronous instruments. + */ + default void toPoint(Measurement measurement, T reusablePoint) { + throw new UnsupportedOperationException("This aggregator does not support toPoint."); + } + + /** Creates a new reusable point. */ + default T createReusablePoint() { + throw new UnsupportedOperationException( + "This aggregator does not support createReusablePoint."); + } + + /** Copies {@code point} into {@code toReusablePoint}. */ + default void copyPoint(T point, T toReusablePoint) { + throw new UnsupportedOperationException("This aggregator does not support toPoint."); + } + /** * Returns the {@link MetricData} that this {@code Aggregation} will produce. * diff --git a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/aggregator/DoubleLastValueAggregator.java b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/aggregator/DoubleLastValueAggregator.java index a56df5860ce..8f0a622e3af 100644 --- a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/aggregator/DoubleLastValueAggregator.java +++ b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/aggregator/DoubleLastValueAggregator.java @@ -14,6 +14,7 @@ import io.opentelemetry.sdk.metrics.internal.data.ImmutableDoublePointData; import io.opentelemetry.sdk.metrics.internal.data.ImmutableGaugeData; import io.opentelemetry.sdk.metrics.internal.data.ImmutableMetricData; +import io.opentelemetry.sdk.metrics.internal.data.MutableDoublePointData; import io.opentelemetry.sdk.metrics.internal.descriptor.MetricDescriptor; import io.opentelemetry.sdk.metrics.internal.exemplar.ExemplarReservoir; import io.opentelemetry.sdk.metrics.internal.state.Measurement; @@ -57,6 +58,11 @@ public DoublePointData diff(DoublePointData previous, DoublePointData current) { return current; } + @Override + public void diffInPlace(DoublePointData previousReusable, DoublePointData current) { + ((MutableDoublePointData) previousReusable).set(current); + } + @Override public DoublePointData toPoint(Measurement measurement) { return ImmutableDoublePointData.create( @@ -66,6 +72,26 @@ public DoublePointData toPoint(Measurement measurement) { measurement.doubleValue()); } + @Override + public void toPoint(Measurement measurement, DoublePointData reusablePoint) { + ((MutableDoublePointData) reusablePoint) + .set( + measurement.startEpochNanos(), + measurement.epochNanos(), + measurement.attributes(), + measurement.doubleValue()); + } + + @Override + public DoublePointData createReusablePoint() { + return new MutableDoublePointData(); + } + + @Override + public void copyPoint(DoublePointData point, DoublePointData toReusablePoint) { + ((MutableDoublePointData) toReusablePoint).set(point); + } + @Override public MetricData toMetricData( Resource resource, diff --git a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/aggregator/DoubleSumAggregator.java b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/aggregator/DoubleSumAggregator.java index 42189ac3d58..c88217114c7 100644 --- a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/aggregator/DoubleSumAggregator.java +++ b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/aggregator/DoubleSumAggregator.java @@ -16,6 +16,7 @@ import io.opentelemetry.sdk.metrics.internal.data.ImmutableDoublePointData; import io.opentelemetry.sdk.metrics.internal.data.ImmutableMetricData; import io.opentelemetry.sdk.metrics.internal.data.ImmutableSumData; +import io.opentelemetry.sdk.metrics.internal.data.MutableDoublePointData; import io.opentelemetry.sdk.metrics.internal.descriptor.InstrumentDescriptor; import io.opentelemetry.sdk.metrics.internal.descriptor.MetricDescriptor; import io.opentelemetry.sdk.metrics.internal.exemplar.ExemplarReservoir; @@ -64,6 +65,17 @@ public DoublePointData diff(DoublePointData previousPoint, DoublePointData curre currentPoint.getExemplars()); } + @Override + public void diffInPlace(DoublePointData previousReusablePoint, DoublePointData currentPoint) { + ((MutableDoublePointData) previousReusablePoint) + .set( + currentPoint.getStartEpochNanos(), + currentPoint.getEpochNanos(), + currentPoint.getAttributes(), + currentPoint.getValue() - previousReusablePoint.getValue(), + currentPoint.getExemplars()); + } + @Override public DoublePointData toPoint(Measurement measurement) { return ImmutableDoublePointData.create( @@ -73,6 +85,26 @@ public DoublePointData toPoint(Measurement measurement) { measurement.doubleValue()); } + @Override + public void toPoint(Measurement measurement, DoublePointData reusablePoint) { + ((MutableDoublePointData) reusablePoint) + .set( + measurement.startEpochNanos(), + measurement.epochNanos(), + measurement.attributes(), + measurement.doubleValue()); + } + + @Override + public DoublePointData createReusablePoint() { + return new MutableDoublePointData(); + } + + @Override + public void copyPoint(DoublePointData point, DoublePointData toReusablePoint) { + ((MutableDoublePointData) toReusablePoint).set(point); + } + @Override public MetricData toMetricData( Resource resource, diff --git a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/aggregator/LongLastValueAggregator.java b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/aggregator/LongLastValueAggregator.java index e1c310207d6..5b3064822c9 100644 --- a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/aggregator/LongLastValueAggregator.java +++ b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/aggregator/LongLastValueAggregator.java @@ -14,6 +14,7 @@ import io.opentelemetry.sdk.metrics.internal.data.ImmutableGaugeData; import io.opentelemetry.sdk.metrics.internal.data.ImmutableLongPointData; import io.opentelemetry.sdk.metrics.internal.data.ImmutableMetricData; +import io.opentelemetry.sdk.metrics.internal.data.MutableLongPointData; import io.opentelemetry.sdk.metrics.internal.descriptor.MetricDescriptor; import io.opentelemetry.sdk.metrics.internal.exemplar.ExemplarReservoir; import io.opentelemetry.sdk.metrics.internal.state.Measurement; @@ -53,6 +54,11 @@ public LongPointData diff(LongPointData previous, LongPointData current) { return current; } + @Override + public void diffInPlace(LongPointData previousReusablePoint, LongPointData currentPoint) { + ((MutableLongPointData) previousReusablePoint).set(currentPoint); + } + @Override public LongPointData toPoint(Measurement measurement) { return ImmutableLongPointData.create( @@ -62,6 +68,26 @@ public LongPointData toPoint(Measurement measurement) { measurement.longValue()); } + @Override + public void toPoint(Measurement measurement, LongPointData reusablePoint) { + ((MutableLongPointData) reusablePoint) + .set( + measurement.startEpochNanos(), + measurement.epochNanos(), + measurement.attributes(), + measurement.longValue()); + } + + @Override + public LongPointData createReusablePoint() { + return new MutableLongPointData(); + } + + @Override + public void copyPoint(LongPointData point, LongPointData toReusablePoint) { + ((MutableLongPointData) toReusablePoint).set(point); + } + @Override public MetricData toMetricData( Resource resource, diff --git a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/aggregator/LongSumAggregator.java b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/aggregator/LongSumAggregator.java index 3899476591a..131c82ce3e9 100644 --- a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/aggregator/LongSumAggregator.java +++ b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/aggregator/LongSumAggregator.java @@ -16,6 +16,7 @@ import io.opentelemetry.sdk.metrics.internal.data.ImmutableLongPointData; import io.opentelemetry.sdk.metrics.internal.data.ImmutableMetricData; import io.opentelemetry.sdk.metrics.internal.data.ImmutableSumData; +import io.opentelemetry.sdk.metrics.internal.data.MutableLongPointData; import io.opentelemetry.sdk.metrics.internal.descriptor.InstrumentDescriptor; import io.opentelemetry.sdk.metrics.internal.descriptor.MetricDescriptor; import io.opentelemetry.sdk.metrics.internal.exemplar.ExemplarReservoir; @@ -58,6 +59,17 @@ public LongPointData diff(LongPointData previousPoint, LongPointData currentPoin currentPoint.getExemplars()); } + @Override + public void diffInPlace(LongPointData previousReusablePoint, LongPointData currentPoint) { + ((MutableLongPointData) previousReusablePoint) + .set( + currentPoint.getStartEpochNanos(), + currentPoint.getEpochNanos(), + currentPoint.getAttributes(), + currentPoint.getValue() - previousReusablePoint.getValue(), + currentPoint.getExemplars()); + } + @Override public LongPointData toPoint(Measurement measurement) { return ImmutableLongPointData.create( @@ -67,6 +79,26 @@ public LongPointData toPoint(Measurement measurement) { measurement.longValue()); } + @Override + public void toPoint(Measurement measurement, LongPointData reusablePoint) { + ((MutableLongPointData) reusablePoint) + .set( + measurement.startEpochNanos(), + measurement.epochNanos(), + measurement.attributes(), + measurement.longValue()); + } + + @Override + public LongPointData createReusablePoint() { + return new MutableLongPointData(); + } + + @Override + public void copyPoint(LongPointData point, LongPointData toReusablePoint) { + ((MutableLongPointData) toReusablePoint).set(point); + } + @Override public MetricData toMetricData( Resource resource, diff --git a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/data/MutableDoublePointData.java b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/data/MutableDoublePointData.java new file mode 100644 index 00000000000..fb412e6f2a8 --- /dev/null +++ b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/data/MutableDoublePointData.java @@ -0,0 +1,138 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.sdk.metrics.internal.data; + +import io.opentelemetry.api.common.Attributes; +import io.opentelemetry.sdk.metrics.data.DoubleExemplarData; +import io.opentelemetry.sdk.metrics.data.DoublePointData; +import java.util.Collections; +import java.util.List; +import java.util.Objects; + +/** + * A mutable {@link DoublePointData} + * + *

    This class is internal and is hence not for public use. Its APIs are unstable and can change + * at any time. + * + *

    This class is not thread-safe. + */ +public class MutableDoublePointData implements DoublePointData { + + private long startEpochNanos; + private long epochNanos; + + private Attributes attributes = Attributes.empty(); + + private double value; + private List exemplars = Collections.emptyList(); + + @Override + public double getValue() { + return value; + } + + @Override + public long getStartEpochNanos() { + return startEpochNanos; + } + + @Override + public long getEpochNanos() { + return epochNanos; + } + + @Override + public Attributes getAttributes() { + return attributes; + } + + @Override + public List getExemplars() { + return exemplars; + } + + /** + * Sets all {@link MutableDoublePointData} values based on {@code point}. + * + * @param point The point to take the values from + */ + public void set(DoublePointData point) { + set( + point.getStartEpochNanos(), + point.getEpochNanos(), + point.getAttributes(), + point.getValue(), + point.getExemplars()); + } + + /** Sets all {@link MutableDoublePointData} values , besides exemplars which are set to empty. */ + public void set(long startEpochNanos, long epochNanos, Attributes attributes, double value) { + set(startEpochNanos, epochNanos, attributes, value, Collections.emptyList()); + } + + /** Sets all {@link MutableDoublePointData} values. */ + public void set( + long startEpochNanos, + long epochNanos, + Attributes attributes, + double value, + List exemplars) { + this.startEpochNanos = startEpochNanos; + this.epochNanos = epochNanos; + this.attributes = attributes; + this.value = value; + this.exemplars = exemplars; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || !(o instanceof MutableDoublePointData)) { + return false; + } + MutableDoublePointData pointData = (MutableDoublePointData) o; + return startEpochNanos == pointData.startEpochNanos + && epochNanos == pointData.epochNanos + && Double.doubleToLongBits(value) == Double.doubleToLongBits(pointData.value) + && Objects.equals(attributes, pointData.attributes) + && Objects.equals(exemplars, pointData.exemplars); + } + + @Override + public int hashCode() { + int hashcode = 1; + hashcode *= 1000003; + hashcode ^= (int) ((startEpochNanos >>> 32) ^ startEpochNanos); + hashcode *= 1000003; + hashcode ^= (int) ((epochNanos >>> 32) ^ epochNanos); + hashcode *= 1000003; + hashcode ^= attributes.hashCode(); + hashcode *= 1000003; + hashcode ^= (int) ((Double.doubleToLongBits(value) >>> 32) ^ Double.doubleToLongBits(value)); + hashcode *= 1000003; + hashcode ^= exemplars.hashCode(); + return hashcode; + } + + @Override + public String toString() { + return "MutableDoublePointData{" + + "startEpochNanos=" + + startEpochNanos + + ", epochNanos=" + + epochNanos + + ", attributes=" + + attributes + + ", value=" + + value + + ", exemplars=" + + exemplars + + '}'; + } +} diff --git a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/data/MutableLongPointData.java b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/data/MutableLongPointData.java new file mode 100644 index 00000000000..179accaf486 --- /dev/null +++ b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/data/MutableLongPointData.java @@ -0,0 +1,136 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.sdk.metrics.internal.data; + +import io.opentelemetry.api.common.Attributes; +import io.opentelemetry.sdk.metrics.data.LongExemplarData; +import io.opentelemetry.sdk.metrics.data.LongPointData; +import java.util.Collections; +import java.util.List; +import java.util.Objects; + +/** + * Mutable {@link LongPointData} + * + *

    This class is internal and is hence not for public use. Its APIs are unstable and can change + * at any time. + * + *

    This class is not thread-safe. + */ +public class MutableLongPointData implements LongPointData { + + private long value; + private long startEpochNanos; + private long epochNanos; + private Attributes attributes = Attributes.empty(); + private List exemplars = Collections.emptyList(); + + @Override + public long getValue() { + return value; + } + + @Override + public long getStartEpochNanos() { + return startEpochNanos; + } + + @Override + public long getEpochNanos() { + return epochNanos; + } + + @Override + public Attributes getAttributes() { + return attributes; + } + + @Override + public List getExemplars() { + return exemplars; + } + + /** + * Sets all {@link MutableDoublePointData} based on {@code point}. + * + * @param point The point to set values upon + */ + public void set(LongPointData point) { + set( + point.getStartEpochNanos(), + point.getEpochNanos(), + point.getAttributes(), + point.getValue(), + point.getExemplars()); + } + + /** Sets all {@link MutableDoublePointData} values besides exemplars which are set to be empty. */ + public void set(long startEpochNanos, long epochNanos, Attributes attributes, long value) { + set(startEpochNanos, epochNanos, attributes, value, Collections.emptyList()); + } + + /** Sets all {@link MutableDoublePointData} values. */ + public void set( + long startEpochNanos, + long epochNanos, + Attributes attributes, + long value, + List exemplars) { + this.startEpochNanos = startEpochNanos; + this.epochNanos = epochNanos; + this.attributes = attributes; + this.value = value; + this.exemplars = exemplars; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || !(o instanceof MutableLongPointData)) { + return false; + } + MutableLongPointData that = (MutableLongPointData) o; + return value == that.value + && startEpochNanos == that.startEpochNanos + && epochNanos == that.epochNanos + && Objects.equals(attributes, that.attributes) + && Objects.equals(exemplars, that.exemplars); + } + + @Override + public int hashCode() { + int hashcode = 1; + hashcode *= 1000003; + hashcode ^= (int) ((startEpochNanos >>> 32) ^ startEpochNanos); + hashcode *= 1000003; + hashcode ^= (int) ((epochNanos >>> 32) ^ epochNanos); + hashcode *= 1000003; + hashcode ^= attributes.hashCode(); + hashcode *= 1000003; + hashcode ^= (int) ((value >>> 32) ^ value); + hashcode *= 1000003; + hashcode ^= exemplars.hashCode(); + return hashcode; + } + + @Override + public String toString() { + return "MutableLongPointData{" + + "value=" + + value + + ", startEpochNanos=" + + startEpochNanos + + ", epochNanos=" + + epochNanos + + ", attributes=" + + attributes + + ", exemplars=" + + exemplars + + '}'; + } +} diff --git a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/export/MetricProducer.java b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/export/MetricProducer.java index 32e036b9d10..63bb152f638 100644 --- a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/export/MetricProducer.java +++ b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/export/MetricProducer.java @@ -5,6 +5,7 @@ package io.opentelemetry.sdk.metrics.internal.export; +import io.opentelemetry.sdk.common.export.MemoryMode; import io.opentelemetry.sdk.metrics.data.MetricData; import io.opentelemetry.sdk.metrics.export.CollectionRegistration; import io.opentelemetry.sdk.metrics.export.MetricReader; @@ -43,6 +44,10 @@ static MetricProducer noop() { * Returns a collection of produced {@link MetricData}s to be exported. This will only be those * metrics that have been produced since the last time this method was called. * + *

    If {@link MetricReader#getMemoryMode()} is configured to {@link MemoryMode#REUSABLE_DATA} do + * not keep the result or any of its contained objects as they are to be reused to return the + * result for the next call of {@code collectAllMetrics} + * * @return a collection of produced {@link MetricData}s to be exported. */ Collection collectAllMetrics(); diff --git a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/state/ArrayBasedStack.java b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/state/ArrayBasedStack.java new file mode 100644 index 00000000000..627955b3403 --- /dev/null +++ b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/state/ArrayBasedStack.java @@ -0,0 +1,79 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.sdk.metrics.internal.state; + +import javax.annotation.Nullable; + +/** + * Array-based Stack. + * + *

    This class is internal and is hence not for public use. Its APIs are unstable and can change + * at any time. + * + *

    This class is not thread-safe. + */ +public class ArrayBasedStack { + static final int DEFAULT_CAPACITY = 10; + + // NOTE (asafm): Using native array instead of ArrayList since I plan to add eviction + // if the initial portion of the stack is not used for several cycles of collection + private T[] array; + + private int size; + + @SuppressWarnings("unchecked") + public ArrayBasedStack() { + array = (T[]) new Object[DEFAULT_CAPACITY]; + size = 0; + } + + /** + * Add {@code element} to the top of the stack (LIFO). + * + * @param element The element to add + * @throws NullPointerException if {@code element} is null + */ + public void push(T element) { + if (element == null) { + throw new NullPointerException("Null is not permitted as element in the stack"); + } + if (size == array.length) { + resizeArray(array.length * 2); + } + array[size++] = element; + } + + /** + * Removes and returns an element from the top of the stack (LIFO). + * + * @return the top most element in the stack (last one added) + */ + @Nullable + public T pop() { + if (isEmpty()) { + return null; + } + T element = array[size - 1]; + array[size - 1] = null; + size--; + return element; + } + + public boolean isEmpty() { + return size == 0; + } + + public int size() { + return size; + } + + @SuppressWarnings("unchecked") + private void resizeArray(int newCapacity) { + T[] newArray = (T[]) new Object[newCapacity]; + System.arraycopy(array, 0, newArray, 0, size); + array = newArray; + } +} diff --git a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/state/AsynchronousMetricStorage.java b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/state/AsynchronousMetricStorage.java index 2e088541d10..4da3d653207 100644 --- a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/state/AsynchronousMetricStorage.java +++ b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/state/AsynchronousMetricStorage.java @@ -5,11 +5,14 @@ package io.opentelemetry.sdk.metrics.internal.state; +import static io.opentelemetry.sdk.common.export.MemoryMode.REUSABLE_DATA; + import io.opentelemetry.api.common.Attributes; import io.opentelemetry.api.metrics.ObservableDoubleMeasurement; import io.opentelemetry.api.metrics.ObservableLongMeasurement; import io.opentelemetry.context.Context; import io.opentelemetry.sdk.common.InstrumentationScopeInfo; +import io.opentelemetry.sdk.common.export.MemoryMode; import io.opentelemetry.sdk.internal.ThrottlingLogger; import io.opentelemetry.sdk.metrics.View; import io.opentelemetry.sdk.metrics.data.AggregationTemporality; @@ -25,6 +28,8 @@ import io.opentelemetry.sdk.metrics.internal.view.AttributesProcessor; import io.opentelemetry.sdk.metrics.internal.view.RegisteredView; import io.opentelemetry.sdk.resources.Resource; +import java.util.ArrayList; +import java.util.Collection; import java.util.HashMap; import java.util.Map; import java.util.logging.Level; @@ -53,9 +58,18 @@ final class AsynchronousMetricStorage points = new HashMap<>(); - private Map lastPoints = - new HashMap<>(); // Only populated if aggregationTemporality == DELTA + private Map points; + + // Only populated if aggregationTemporality == DELTA + private Map lastPoints; + + // Only populated if memoryMode == REUSABLE_DATA + private final ObjectPool reusablePointsPool; + + // Only populated if memoryMode == REUSABLE_DATA + private final ArrayList reusableResultList = new ArrayList<>(); + + private final MemoryMode memoryMode; private AsynchronousMetricStorage( RegisteredReader registeredReader, @@ -69,9 +83,18 @@ private AsynchronousMetricStorage( registeredReader .getReader() .getAggregationTemporality(metricDescriptor.getSourceInstrument().getType()); + this.memoryMode = registeredReader.getReader().getMemoryMode(); this.aggregator = aggregator; this.attributesProcessor = attributesProcessor; this.maxCardinality = maxCardinality - 1; + this.reusablePointsPool = new ObjectPool<>(aggregator::createReusablePoint); + if (memoryMode == REUSABLE_DATA) { + lastPoints = new PooledHashMap<>(); + points = new PooledHashMap<>(); + } else { + lastPoints = new HashMap<>(); + points = new HashMap<>(); + } } /** @@ -107,12 +130,9 @@ void record(Measurement measurement) { aggregationTemporality == AggregationTemporality.DELTA ? registeredReader.getLastCollectEpochNanos() : measurement.startEpochNanos(); - measurement = - measurement.hasDoubleValue() - ? Measurement.doubleMeasurement( - start, measurement.epochNanos(), measurement.doubleValue(), processedAttributes) - : Measurement.longMeasurement( - start, measurement.epochNanos(), measurement.longValue(), processedAttributes); + + measurement = measurement.withAttributes(processedAttributes).withStartEpochNanos(start); + recordPoint(processedAttributes, measurement); } @@ -126,18 +146,7 @@ private void recordPoint(Attributes attributes, Measurement measurement) { + maxCardinality + ")."); attributes = MetricStorage.CARDINALITY_OVERFLOW; - measurement = - measurement.hasDoubleValue() - ? Measurement.doubleMeasurement( - measurement.startEpochNanos(), - measurement.epochNanos(), - measurement.doubleValue(), - attributes) - : Measurement.longMeasurement( - measurement.startEpochNanos(), - measurement.epochNanos(), - measurement.longValue(), - attributes); + measurement = measurement.withAttributes(attributes); } else if (points.containsKey( attributes)) { // Check there is not already a recording for the attributes throttlingLogger.log( @@ -149,7 +158,15 @@ private void recordPoint(Attributes attributes, Measurement measurement) { return; } - points.put(attributes, aggregator.toPoint(measurement)); + T dataPoint; + if (memoryMode == REUSABLE_DATA) { + dataPoint = reusablePointsPool.borrowObject(); + aggregator.toPoint(measurement, dataPoint); + } else { + dataPoint = aggregator.toPoint(measurement); + } + + points.put(attributes, dataPoint); } @Override @@ -168,25 +185,76 @@ public MetricData collect( InstrumentationScopeInfo instrumentationScopeInfo, long startEpochNanos, long epochNanos) { - Map result; + if (memoryMode == REUSABLE_DATA) { + // Collect can not run concurrently for same reader, hence we safely assume + // the previous collect result has been used and done with + reusableResultList.forEach(reusablePointsPool::returnObject); + reusableResultList.clear(); + } + + Collection result; if (aggregationTemporality == AggregationTemporality.DELTA) { Map points = this.points; Map lastPoints = this.lastPoints; - lastPoints.entrySet().removeIf(entry -> !points.containsKey(entry.getKey())); + + Collection deltaPoints; + if (memoryMode == REUSABLE_DATA) { + deltaPoints = reusableResultList; + } else { + deltaPoints = new ArrayList<>(); + } + points.forEach( - (k, v) -> lastPoints.compute(k, (k2, v2) -> v2 == null ? v : aggregator.diff(v2, v))); - result = lastPoints; + (k, v) -> { + T lastPoint = lastPoints.get(k); + + T deltaPoint; + if (lastPoint == null) { + if (memoryMode == REUSABLE_DATA) { + deltaPoint = reusablePointsPool.borrowObject(); + aggregator.copyPoint(v, deltaPoint); + } else { + deltaPoint = v; + } + } else { + if (memoryMode == REUSABLE_DATA) { + aggregator.diffInPlace(lastPoint, v); + deltaPoint = lastPoint; + + // Remaining last points are returned to reusablePointsPool, but + // this reusable point is still used, so don't return it to pool yet + lastPoints.remove(k); + } else { + deltaPoint = aggregator.diff(lastPoint, v); + } + } + + deltaPoints.add(deltaPoint); + }); + + if (memoryMode == REUSABLE_DATA) { + lastPoints.forEach((k, v) -> reusablePointsPool.returnObject(v)); + lastPoints.clear(); + this.points = lastPoints; + } else { + this.points = new HashMap<>(); + } + this.lastPoints = points; - } else { - result = points; + result = deltaPoints; + } else /* CUMULATIVE */ { + if (memoryMode == REUSABLE_DATA) { + points.forEach((k, v) -> reusableResultList.add(v)); + points.clear(); + result = reusableResultList; + } else { + result = points.values(); + points = new HashMap<>(); + } } - this.points = new HashMap<>(); + return aggregator.toMetricData( - resource, - instrumentationScopeInfo, - metricDescriptor, - result.values(), - aggregationTemporality); + resource, instrumentationScopeInfo, metricDescriptor, result, aggregationTemporality); } @Override diff --git a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/state/ImmutableMeasurement.java b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/state/ImmutableMeasurement.java new file mode 100644 index 00000000000..9cac89e96e9 --- /dev/null +++ b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/state/ImmutableMeasurement.java @@ -0,0 +1,64 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.sdk.metrics.internal.state; + +import com.google.auto.value.AutoValue; +import io.opentelemetry.api.common.Attributes; +import io.opentelemetry.api.metrics.ObservableDoubleMeasurement; +import io.opentelemetry.api.metrics.ObservableLongMeasurement; + +/** + * A long or double measurement recorded from {@link ObservableLongMeasurement} or {@link + * ObservableDoubleMeasurement}. + * + *

    This class is internal and is hence not for public use. Its APIs are unstable and can change + * at any time. + */ +@AutoValue +public abstract class ImmutableMeasurement implements Measurement { + + static ImmutableMeasurement createDouble( + long startEpochNanos, long epochNanos, double value, Attributes attributes) { + return new AutoValue_ImmutableMeasurement( + startEpochNanos, + epochNanos, + /* hasLongValue= */ false, + 0L, + /* hasDoubleValue= */ true, + value, + attributes); + } + + static ImmutableMeasurement createLong( + long startEpochNanos, long epochNanos, long value, Attributes attributes) { + return new AutoValue_ImmutableMeasurement( + startEpochNanos, + epochNanos, + /* hasLongValue= */ true, + value, + /* hasDoubleValue= */ false, + 0.0, + attributes); + } + + @Override + public Measurement withAttributes(Attributes attributes) { + if (hasDoubleValue()) { + return createDouble(startEpochNanos(), epochNanos(), doubleValue(), attributes); + } else { + return createLong(startEpochNanos(), epochNanos(), longValue(), attributes); + } + } + + @Override + public Measurement withStartEpochNanos(long startEpochNanos) { + if (hasDoubleValue()) { + return createDouble(startEpochNanos, epochNanos(), doubleValue(), attributes()); + } else { + return createLong(startEpochNanos, epochNanos(), longValue(), attributes()); + } + } +} diff --git a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/state/Measurement.java b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/state/Measurement.java index 43370bb571f..a5023995dad 100644 --- a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/state/Measurement.java +++ b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/state/Measurement.java @@ -5,7 +5,6 @@ package io.opentelemetry.sdk.metrics.internal.state; -import com.google.auto.value.AutoValue; import io.opentelemetry.api.common.Attributes; import io.opentelemetry.api.metrics.ObservableDoubleMeasurement; import io.opentelemetry.api.metrics.ObservableLongMeasurement; @@ -13,45 +12,42 @@ /** * A long or double measurement recorded from {@link ObservableLongMeasurement} or {@link * ObservableDoubleMeasurement}. + * + *

    This class is internal and is hence not for public use. Its APIs are unstable and can change + * at any time. */ -@AutoValue -public abstract class Measurement { - - static Measurement doubleMeasurement( - long startEpochNanos, long epochNanos, double value, Attributes attributes) { - return new AutoValue_Measurement( - startEpochNanos, - epochNanos, - /* hasLongValue= */ false, - 0L, - /* hasDoubleValue= */ true, - value, - attributes); - } - - static Measurement longMeasurement( - long startEpochNanos, long epochNanos, long value, Attributes attributes) { - return new AutoValue_Measurement( - startEpochNanos, - epochNanos, - /* hasLongValue= */ true, - value, - /* hasDoubleValue= */ false, - 0.0, - attributes); - } - - public abstract long startEpochNanos(); - - public abstract long epochNanos(); - - public abstract boolean hasLongValue(); - - public abstract long longValue(); - - public abstract boolean hasDoubleValue(); - - public abstract double doubleValue(); - - public abstract Attributes attributes(); +public interface Measurement { + long startEpochNanos(); + + long epochNanos(); + + boolean hasLongValue(); + + long longValue(); + + boolean hasDoubleValue(); + + double doubleValue(); + + Attributes attributes(); + + /** + * Updates the attributes. + * + * @param attributes The attributes to update + * @return The updated object. For {@link ImmutableMeasurement} it will be a new object with the + * updated attributes and for {@link MutableMeasurement} it will return itself with the + * attributes updated + */ + Measurement withAttributes(Attributes attributes); + + /** + * Updates the startEpochNanos. + * + * @param startEpochNanos start epoch nanosecond + * @return The updated object. For {@link ImmutableMeasurement} it will be a new object with the + * updated startEpochNanos and for {@link MutableMeasurement} it will return itself with the + * startEpochNanos updated + */ + Measurement withStartEpochNanos(long startEpochNanos); } diff --git a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/state/MutableMeasurement.java b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/state/MutableMeasurement.java new file mode 100644 index 00000000000..9c88712d487 --- /dev/null +++ b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/state/MutableMeasurement.java @@ -0,0 +1,125 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.sdk.metrics.internal.state; + +import io.opentelemetry.api.common.Attributes; + +/** + * A mutable {@link Measurement} implementation + * + *

    This class is internal and is hence not for public use. Its APIs are unstable and can change + * at any time. + * + *

    This class is not thread-safe. + */ +public class MutableMeasurement implements Measurement { + + static void setDoubleMeasurement( + MutableMeasurement mutableMeasurement, + long startEpochNanos, + long epochNanos, + double value, + Attributes attributes) { + mutableMeasurement.set( + startEpochNanos, + epochNanos, + /* hasLongValue= */ false, + 0L, + /* hasDoubleValue= */ true, + value, + attributes); + } + + static void setLongMeasurement( + MutableMeasurement mutableMeasurement, + long startEpochNanos, + long epochNanos, + long value, + Attributes attributes) { + mutableMeasurement.set( + startEpochNanos, + epochNanos, + /* hasLongValue= */ true, + value, + /* hasDoubleValue= */ false, + 0.0, + attributes); + } + + private long startEpochNanos; + private long epochNanos; + private boolean hasLongValue; + private long longValue; + private boolean hasDoubleValue; + private double doubleValue; + + private Attributes attributes = Attributes.empty(); + + /** Sets the values. */ + private void set( + long startEpochNanos, + long epochNanos, + boolean hasLongValue, + long longValue, + boolean hasDoubleValue, + double doubleValue, + Attributes attributes) { + this.startEpochNanos = startEpochNanos; + this.epochNanos = epochNanos; + this.hasLongValue = hasLongValue; + this.longValue = longValue; + this.hasDoubleValue = hasDoubleValue; + this.doubleValue = doubleValue; + this.attributes = attributes; + } + + @Override + public Measurement withStartEpochNanos(long startEpochNanos) { + this.startEpochNanos = startEpochNanos; + return this; + } + + @Override + public Measurement withAttributes(Attributes attributes) { + this.attributes = attributes; + return this; + } + + @Override + public long startEpochNanos() { + return startEpochNanos; + } + + @Override + public long epochNanos() { + return epochNanos; + } + + @Override + public boolean hasLongValue() { + return hasLongValue; + } + + @Override + public long longValue() { + return longValue; + } + + @Override + public boolean hasDoubleValue() { + return hasDoubleValue; + } + + @Override + public double doubleValue() { + return doubleValue; + } + + @Override + public Attributes attributes() { + return attributes; + } +} diff --git a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/state/ObjectPool.java b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/state/ObjectPool.java new file mode 100644 index 00000000000..3a129613d87 --- /dev/null +++ b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/state/ObjectPool.java @@ -0,0 +1,53 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.sdk.metrics.internal.state; + +import java.util.function.Supplier; + +/** + * A pool of objects of type {@code T}. + * + *

    When an object is borrowed from an empty pool, an object will be created by the supplied + * {@code objectCreator} and returned immediately. When the pool is not empty, an object is removed + * from the pool and returned. The user is expected to return the object to the pool when it is no + * longer used. + * + *

    This class is internal and is hence not for public use. Its APIs are unstable and can change + * at any time. + * + *

    This class is not thread-safe. + */ +public class ObjectPool { + private final ArrayBasedStack pool; + private final Supplier objectCreator; + + /** + * Constructs an object pool. + * + * @param objectCreator Supplier used to create an object when the pool is empty + */ + public ObjectPool(Supplier objectCreator) { + this.pool = new ArrayBasedStack<>(); + this.objectCreator = objectCreator; + } + + /** + * Gets an object from the pool. + * + * @return An object from the pool, or a new object if the pool is empty + */ + public T borrowObject() { + T object = pool.pop(); + if (object == null) { + object = objectCreator.get(); + } + return object; + } + + public void returnObject(T object) { + pool.push(object); + } +} diff --git a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/state/PooledHashMap.java b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/state/PooledHashMap.java new file mode 100644 index 00000000000..452ed9d50ea --- /dev/null +++ b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/state/PooledHashMap.java @@ -0,0 +1,267 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.sdk.metrics.internal.state; + +import static java.util.Objects.requireNonNull; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Map; +import java.util.Objects; +import java.util.Set; +import java.util.function.BiConsumer; +import javax.annotation.Nullable; + +/** + * A bucket-based hash map with an internal re-usable map entry objects pool + * + *

    The goal of this map is to minimize memory allocation, leading to reduced time spent in + * garbage collection. + * + *

    This map avoids allocating a new map entry on each put operation by maintaining a pool of + * reusable (mutable) map entries and borrowing a map entry object from the pool to hold the given + * key-value of the put operation. The borrowed object is returned to the pool when the map entry + * key is removed from the map. + * + *

    This class is internal and is hence not for public use. Its APIs are unstable and can change + * at any time. + * + *

    This class is not thread-safe. + * + * @param The map key type + * @param The map value type + */ +@SuppressWarnings("ForLoopReplaceableByForEach") +public class PooledHashMap implements Map { + private static final int DEFAULT_CAPACITY = 16; + private static final float LOAD_FACTOR = 0.75f; + + private ArrayList>[] table; + private final ObjectPool> entryPool; + private int size; + + /** + * Creates a {@link PooledHashMap} with {@code capacity} buckets. + * + *

    The hashmap contains an array of buckets, each is an array-list of items. The number of + * buckets expands over time to avoid having too many items in one bucket, otherwise accessing an + * item by key won't be a constant time complexity. + * + * @param capacity The initial number of buckets to start with + */ + @SuppressWarnings({"unchecked"}) + public PooledHashMap(int capacity) { + this.table = (ArrayList>[]) new ArrayList[capacity]; + this.entryPool = new ObjectPool<>(Entry::new); + this.size = 0; + } + + /** + * Creates a new {@link PooledHashMap} with a default amount of buckets (capacity). + * + * @see PooledHashMap#PooledHashMap(int) + */ + public PooledHashMap() { + this(DEFAULT_CAPACITY); + } + + /** + * Add a key, value pair to the map. + * + *

    Internally it uses a MapEntry from a pool of entries, to store this mapping + * + * @param key key with which the specified value is to be associated + * @param value value to be associated with the specified key + * @return Null if the was no previous mapping for this key, or the value of the previous mapping + * of this key + */ + @Override + @Nullable + public V put(K key, V value) { + requireNonNull(key, "This map does not support null keys"); + requireNonNull(value, "This map does not support null values"); + if (size > LOAD_FACTOR * table.length) { + rehash(); + } + + int bucket = getBucket(key); + ArrayList> entries = table[bucket]; + if (entries == null) { + entries = new ArrayList<>(); + table[bucket] = entries; + } else { + // Don't optimize to enhanced for-loop since implicit iterator used allocated memory in O(n) + for (int i = 0; i < entries.size(); i++) { + Entry entry = entries.get(i); + if (Objects.equals(entry.key, key)) { + V oldValue = entry.value; + entry.value = value; + return oldValue; + } + } + } + Entry entry = entryPool.borrowObject(); + entry.key = key; + entry.value = value; + entries.add(entry); + size++; + return null; + } + + @SuppressWarnings({"unchecked"}) + private void rehash() { + ArrayList>[] oldTable = table; + table = (ArrayList>[]) new ArrayList[2 * oldTable.length]; + + // put() to new table below will reset size back to correct number + size = 0; + + for (int i = 0; i < oldTable.length; i++) { + ArrayList> bucket = oldTable[i]; + if (bucket != null) { + for (Entry entry : bucket) { + put(requireNonNull(entry.key), requireNonNull(entry.value)); + entryPool.returnObject(entry); + } + bucket.clear(); + } + } + } + + /** + * Retrieves the mapped value for {@code key}. + * + * @param key the key whose associated value is to be returned + * @return The mapped value for {@code key} or null if there is no such mapping + */ + @Override + @Nullable + @SuppressWarnings("unchecked") + public V get(Object key) { + requireNonNull(key, "This map does not support null keys"); + + int bucket = getBucket((K) key); + ArrayList> entries = table[bucket]; + if (entries != null) { + for (int i = 0; i < entries.size(); i++) { + Entry entry = entries.get(i); + if (Objects.equals(entry.key, key)) { + return entry.value; + } + } + } + return null; + } + + /** + * Removes the mapping for the given {@code key}. + * + * @param key key whose mapping is to be removed from the map + * @return The value mapped to this key, if the mapping exists, or null otherwise + */ + @Override + @Nullable + @SuppressWarnings("unchecked") + public V remove(Object key) { + requireNonNull(key, "This map does not support null keys"); + + int bucket = getBucket((K) key); + ArrayList> entries = table[bucket]; + if (entries != null) { + for (int i = 0; i < entries.size(); i++) { + Entry entry = entries.get(i); + if (Objects.equals(entry.key, key)) { + V oldValue = entry.value; + entries.remove(i); + entryPool.returnObject(entry); + size--; + return oldValue; + } + } + } + return null; + } + + @Override + public int size() { + return size; + } + + @Override + public boolean isEmpty() { + return size == 0; + } + + @Override + public boolean containsKey(Object key) { + requireNonNull(key, "This map does not support null keys"); + + return get(key) != null; + } + + @Override + public boolean containsValue(Object value) { + throw new UnsupportedOperationException(); + } + + @Override + public void clear() { + for (int i = 0; i < table.length; i++) { + ArrayList> bucket = table[i]; + if (bucket != null) { + for (int j = 0; j < bucket.size(); j++) { + Entry entry = bucket.get(j); + entryPool.returnObject(entry); + } + bucket.clear(); + } + } + size = 0; + } + + @Override + public void forEach(BiConsumer action) { + for (int j = 0; j < table.length; j++) { + ArrayList> bucket = table[j]; + if (bucket != null) { + for (int i = 0; i < bucket.size(); i++) { + Entry entry = bucket.get(i); + action.accept(entry.key, entry.value); + } + } + } + } + + private int getBucket(K key) { + return Math.abs(key.hashCode() % table.length); + } + + @Override + public Set> entrySet() { + throw new UnsupportedOperationException(); + } + + @Override + public Collection values() { + throw new UnsupportedOperationException(); + } + + @Override + public void putAll(Map m) { + throw new UnsupportedOperationException(); + } + + @Override + public Set keySet() { + throw new UnsupportedOperationException(); + } + + private static class Entry { + @Nullable K key; + + @Nullable V value; + } +} diff --git a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/state/SdkObservableMeasurement.java b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/state/SdkObservableMeasurement.java index df2d2b6512c..6d0187b443b 100644 --- a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/state/SdkObservableMeasurement.java +++ b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/state/SdkObservableMeasurement.java @@ -5,17 +5,19 @@ package io.opentelemetry.sdk.metrics.internal.state; -import static io.opentelemetry.sdk.metrics.internal.state.Measurement.doubleMeasurement; -import static io.opentelemetry.sdk.metrics.internal.state.Measurement.longMeasurement; +import static io.opentelemetry.sdk.metrics.internal.state.ImmutableMeasurement.createDouble; +import static io.opentelemetry.sdk.metrics.internal.state.ImmutableMeasurement.createLong; import io.opentelemetry.api.common.Attributes; import io.opentelemetry.api.metrics.ObservableDoubleMeasurement; import io.opentelemetry.api.metrics.ObservableLongMeasurement; import io.opentelemetry.sdk.common.InstrumentationScopeInfo; +import io.opentelemetry.sdk.common.export.MemoryMode; import io.opentelemetry.sdk.internal.ThrottlingLogger; import io.opentelemetry.sdk.metrics.internal.descriptor.InstrumentDescriptor; import io.opentelemetry.sdk.metrics.internal.export.RegisteredReader; import java.util.List; +import java.util.Objects; import java.util.logging.Level; import java.util.logging.Logger; import javax.annotation.Nullable; @@ -36,6 +38,9 @@ public final class SdkObservableMeasurement private final InstrumentDescriptor instrumentDescriptor; private final List> storages; + /** Only used when {@code activeReader}'s memoryMode is {@link MemoryMode#REUSABLE_DATA}. */ + private final MutableMeasurement mutableMeasurement = new MutableMeasurement(); + // These fields are set before invoking callbacks. They allow measurements to be recorded to the // storages for correct reader, and with the correct time. @Nullable private volatile RegisteredReader activeReader; @@ -104,7 +109,23 @@ public void record(long value) { @Override public void record(long value, Attributes attributes) { - doRecord(longMeasurement(startEpochNanos, epochNanos, value, attributes)); + if (activeReader == null) { + logNoActiveReader(); + return; + } + + Measurement measurement; + + MemoryMode memoryMode = activeReader.getReader().getMemoryMode(); + if (Objects.requireNonNull(memoryMode) == MemoryMode.IMMUTABLE_DATA) { + measurement = createLong(startEpochNanos, epochNanos, value, attributes); + } else { + MutableMeasurement.setLongMeasurement( + mutableMeasurement, startEpochNanos, epochNanos, value, attributes); + measurement = mutableMeasurement; + } + + doRecord(measurement); } @Override @@ -114,23 +135,38 @@ public void record(double value) { @Override public void record(double value, Attributes attributes) { - doRecord(doubleMeasurement(startEpochNanos, epochNanos, value, attributes)); + if (activeReader == null) { + logNoActiveReader(); + return; + } + + Measurement measurement; + MemoryMode memoryMode = activeReader.getReader().getMemoryMode(); + if (Objects.requireNonNull(memoryMode) == MemoryMode.IMMUTABLE_DATA) { + measurement = createDouble(startEpochNanos, epochNanos, value, attributes); + } else { + MutableMeasurement.setDoubleMeasurement( + mutableMeasurement, startEpochNanos, epochNanos, value, attributes); + measurement = mutableMeasurement; + } + + doRecord(measurement); } private void doRecord(Measurement measurement) { RegisteredReader activeReader = this.activeReader; - if (activeReader == null) { - throttlingLogger.log( - Level.FINE, - "Measurement recorded for instrument " - + instrumentDescriptor.getName() - + " outside callback registered to instrument. Dropping measurement."); - return; - } for (AsynchronousMetricStorage storage : storages) { if (storage.getRegisteredReader().equals(activeReader)) { storage.record(measurement); } } } + + private void logNoActiveReader() { + throttlingLogger.log( + Level.FINE, + "Measurement recorded for instrument " + + instrumentDescriptor.getName() + + " outside callback registered to instrument. Dropping measurement."); + } } diff --git a/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/internal/aggregator/DoubleLastValueAggregatorTest.java b/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/internal/aggregator/DoubleLastValueAggregatorTest.java index 2decaf97821..fa0dd75caa4 100644 --- a/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/internal/aggregator/DoubleLastValueAggregatorTest.java +++ b/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/internal/aggregator/DoubleLastValueAggregatorTest.java @@ -7,6 +7,7 @@ import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.assertThat; +import io.opentelemetry.api.common.AttributeKey; import io.opentelemetry.api.common.Attributes; import io.opentelemetry.api.trace.SpanContext; import io.opentelemetry.api.trace.TraceFlags; @@ -18,11 +19,13 @@ import io.opentelemetry.sdk.metrics.data.MetricData; import io.opentelemetry.sdk.metrics.internal.data.ImmutableDoubleExemplarData; import io.opentelemetry.sdk.metrics.internal.data.ImmutableDoublePointData; +import io.opentelemetry.sdk.metrics.internal.data.MutableDoublePointData; import io.opentelemetry.sdk.metrics.internal.descriptor.MetricDescriptor; import io.opentelemetry.sdk.metrics.internal.exemplar.ExemplarReservoir; import io.opentelemetry.sdk.resources.Resource; import java.util.Collections; import java.util.List; +import org.assertj.core.api.Assertions; import org.junit.jupiter.api.Test; /** Unit tests for {@link AggregatorHandle}. */ @@ -113,6 +116,92 @@ void diff() { .isEqualTo(ImmutableDoublePointData.create(0, 1, Attributes.empty(), 2, exemplars)); } + @Test + void diffInPlace() { + Attributes attributes = Attributes.builder().put("test", "value").build(); + DoubleExemplarData exemplar = + ImmutableDoubleExemplarData.create( + attributes, + 2L, + SpanContext.create( + "00000000000000000000000000000001", + "0000000000000002", + TraceFlags.getDefault(), + TraceState.getDefault()), + 1); + List exemplars = Collections.singletonList(exemplar); + List previousExemplars = + Collections.singletonList( + ImmutableDoubleExemplarData.create( + attributes, + 1L, + SpanContext.create( + "00000000000000000000000000000001", + "0000000000000002", + TraceFlags.getDefault(), + TraceState.getDefault()), + 2)); + + MutableDoublePointData previous = new MutableDoublePointData(); + MutableDoublePointData current = new MutableDoublePointData(); + + previous.set(0, 1, Attributes.empty(), 1, previousExemplars); + current.set(0, 1, Attributes.empty(), 2, exemplars); + + aggregator.diffInPlace(previous, current); + + /* Assert that latest measurement is kept and set on {@code previous} */ + assertThat(previous.getStartEpochNanos()).isEqualTo(0); + assertThat(previous.getEpochNanos()).isEqualTo(1); + assertThat(previous.getAttributes()).isEqualTo(Attributes.empty()); + assertThat(previous.getValue()).isEqualTo(2); + assertThat(previous.getExemplars()).isEqualTo(exemplars); + } + + @Test + void copyPoint() { + MutableDoublePointData pointData = (MutableDoublePointData) aggregator.createReusablePoint(); + + Attributes attributes = Attributes.of(AttributeKey.longKey("test"), 100L); + List examplarsFrom = + Collections.singletonList( + ImmutableDoubleExemplarData.create( + attributes, + 2L, + SpanContext.create( + "00000000000000000000000000000001", + "0000000000000002", + TraceFlags.getDefault(), + TraceState.getDefault()), + 1)); + pointData.set(0, 1, attributes, 2000, examplarsFrom); + + MutableDoublePointData toPointData = (MutableDoublePointData) aggregator.createReusablePoint(); + + Attributes toAttributes = Attributes.of(AttributeKey.longKey("test"), 100L); + List examplarsTo = + Collections.singletonList( + ImmutableDoubleExemplarData.create( + attributes, + 4L, + SpanContext.create( + "00000000000000000000000000000001", + "0000000000000002", + TraceFlags.getDefault(), + TraceState.getDefault()), + 2)); + toPointData.set(0, 2, toAttributes, 4000, examplarsTo); + + aggregator.copyPoint(pointData, toPointData); + + Assertions.assertThat(toPointData.getStartEpochNanos()) + .isEqualTo(pointData.getStartEpochNanos()); + Assertions.assertThat(toPointData.getEpochNanos()).isEqualTo(pointData.getEpochNanos()); + assertThat(toPointData.getAttributes()).isEqualTo(pointData.getAttributes()); + Assertions.assertThat(toPointData.getValue()).isEqualTo(pointData.getValue()); + Assertions.assertThat(toPointData.getExemplars()).isEqualTo(pointData.getExemplars()); + } + @Test void toMetricData() { AggregatorHandle aggregatorHandle = diff --git a/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/internal/aggregator/DoubleSumAggregatorTest.java b/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/internal/aggregator/DoubleSumAggregatorTest.java index 15377186150..06651798bf2 100644 --- a/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/internal/aggregator/DoubleSumAggregatorTest.java +++ b/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/internal/aggregator/DoubleSumAggregatorTest.java @@ -7,6 +7,7 @@ import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.assertThat; +import io.opentelemetry.api.common.AttributeKey; import io.opentelemetry.api.common.Attributes; import io.opentelemetry.api.trace.SpanContext; import io.opentelemetry.api.trace.TraceFlags; @@ -21,6 +22,7 @@ import io.opentelemetry.sdk.metrics.data.MetricData; import io.opentelemetry.sdk.metrics.internal.data.ImmutableDoubleExemplarData; import io.opentelemetry.sdk.metrics.internal.data.ImmutableDoublePointData; +import io.opentelemetry.sdk.metrics.internal.data.MutableDoublePointData; import io.opentelemetry.sdk.metrics.internal.descriptor.Advice; import io.opentelemetry.sdk.metrics.internal.descriptor.InstrumentDescriptor; import io.opentelemetry.sdk.metrics.internal.descriptor.MetricDescriptor; @@ -28,6 +30,7 @@ import io.opentelemetry.sdk.resources.Resource; import java.util.Collections; import java.util.List; +import org.assertj.core.api.Assertions; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.Mock; @@ -190,6 +193,92 @@ void mergeAndDiff() { } } + @Test + void diffInPlace() { + Attributes attributes = Attributes.builder().put("test", "value").build(); + DoubleExemplarData exemplar = + ImmutableDoubleExemplarData.create( + attributes, + 2L, + SpanContext.create( + "00000000000000000000000000000001", + "0000000000000002", + TraceFlags.getDefault(), + TraceState.getDefault()), + 1); + List exemplars = Collections.singletonList(exemplar); + List previousExemplars = + Collections.singletonList( + ImmutableDoubleExemplarData.create( + attributes, + 1L, + SpanContext.create( + "00000000000000000000000000000001", + "0000000000000002", + TraceFlags.getDefault(), + TraceState.getDefault()), + 2)); + + MutableDoublePointData previous = new MutableDoublePointData(); + MutableDoublePointData current = new MutableDoublePointData(); + + previous.set(0, 1, Attributes.empty(), 1, previousExemplars); + current.set(0, 1, Attributes.empty(), 3, exemplars); + + aggregator.diffInPlace(previous, current); + + /* Assert that latest measurement is kept and set on {@code previous} */ + Assertions.assertThat(previous.getStartEpochNanos()).isEqualTo(current.getStartEpochNanos()); + Assertions.assertThat(previous.getEpochNanos()).isEqualTo(current.getEpochNanos()); + assertThat(previous.getAttributes()).isEqualTo(current.getAttributes()); + Assertions.assertThat(previous.getValue()).isEqualTo(2); + Assertions.assertThat(previous.getExemplars()).isEqualTo(exemplars); + } + + @Test + void copyPoint() { + MutableDoublePointData pointData = (MutableDoublePointData) aggregator.createReusablePoint(); + + Attributes attributes = Attributes.of(AttributeKey.longKey("test"), 100L); + List examplarsFrom = + Collections.singletonList( + ImmutableDoubleExemplarData.create( + attributes, + 2L, + SpanContext.create( + "00000000000000000000000000000001", + "0000000000000002", + TraceFlags.getDefault(), + TraceState.getDefault()), + 1)); + pointData.set(0, 1, attributes, 2000, examplarsFrom); + + MutableDoublePointData toPointData = (MutableDoublePointData) aggregator.createReusablePoint(); + + Attributes toAttributes = Attributes.of(AttributeKey.longKey("test"), 100L); + List examplarsTo = + Collections.singletonList( + ImmutableDoubleExemplarData.create( + attributes, + 4L, + SpanContext.create( + "00000000000000000000000000000001", + "0000000000000002", + TraceFlags.getDefault(), + TraceState.getDefault()), + 2)); + toPointData.set(0, 2, toAttributes, 4000, examplarsTo); + + aggregator.copyPoint(pointData, toPointData); + + Assertions.assertThat(toPointData.getStartEpochNanos()) + .isEqualTo(pointData.getStartEpochNanos()); + Assertions.assertThat(toPointData.getEpochNanos()).isEqualTo(pointData.getEpochNanos()); + assertThat(toPointData.getAttributes()).isEqualTo(pointData.getAttributes()); + Assertions.assertThat(toPointData.getValue()).isEqualTo(pointData.getValue()); + Assertions.assertThat(toPointData.getExemplars()).isEqualTo(pointData.getExemplars()); + } + @Test void toMetricData() { AggregatorHandle aggregatorHandle = diff --git a/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/internal/aggregator/LongLastValueAggregatorTest.java b/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/internal/aggregator/LongLastValueAggregatorTest.java index 7eda2d345c4..e7d4140309f 100644 --- a/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/internal/aggregator/LongLastValueAggregatorTest.java +++ b/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/internal/aggregator/LongLastValueAggregatorTest.java @@ -7,19 +7,28 @@ import static org.assertj.core.api.Assertions.assertThat; +import io.opentelemetry.api.common.AttributeKey; import io.opentelemetry.api.common.Attributes; +import io.opentelemetry.api.trace.SpanContext; +import io.opentelemetry.api.trace.TraceFlags; +import io.opentelemetry.api.trace.TraceState; import io.opentelemetry.sdk.common.InstrumentationScopeInfo; import io.opentelemetry.sdk.metrics.data.AggregationTemporality; import io.opentelemetry.sdk.metrics.data.LongExemplarData; import io.opentelemetry.sdk.metrics.data.LongPointData; import io.opentelemetry.sdk.metrics.data.MetricData; import io.opentelemetry.sdk.metrics.internal.data.ImmutableGaugeData; +import io.opentelemetry.sdk.metrics.internal.data.ImmutableLongExemplarData; import io.opentelemetry.sdk.metrics.internal.data.ImmutableLongPointData; import io.opentelemetry.sdk.metrics.internal.data.ImmutableMetricData; +import io.opentelemetry.sdk.metrics.internal.data.MutableLongPointData; import io.opentelemetry.sdk.metrics.internal.descriptor.MetricDescriptor; import io.opentelemetry.sdk.metrics.internal.exemplar.ExemplarReservoir; import io.opentelemetry.sdk.resources.Resource; +import io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions; import java.util.Collections; +import java.util.List; +import org.assertj.core.api.Assertions; import org.junit.jupiter.api.Test; /** Unit tests for {@link LongLastValueAggregator}. */ @@ -74,6 +83,93 @@ void aggregateThenMaybeReset() { .isEqualTo(12L); } + @Test + void diffInPlace() { + Attributes attributes = Attributes.builder().put("test", "value").build(); + LongExemplarData exemplar = + ImmutableLongExemplarData.create( + attributes, + 2L, + SpanContext.create( + "00000000000000000000000000000001", + "0000000000000002", + TraceFlags.getDefault(), + TraceState.getDefault()), + 1); + List exemplars = Collections.singletonList(exemplar); + List previousExemplars = + Collections.singletonList( + ImmutableLongExemplarData.create( + attributes, + 1L, + SpanContext.create( + "00000000000000000000000000000001", + "0000000000000002", + TraceFlags.getDefault(), + TraceState.getDefault()), + 2)); + + MutableLongPointData previous = new MutableLongPointData(); + MutableLongPointData current = new MutableLongPointData(); + + previous.set(0, 1, Attributes.empty(), 1, previousExemplars); + current.set(0, 1, Attributes.empty(), 2, exemplars); + + aggregator.diffInPlace(previous, current); + + /* Assert that latest measurement is kept and set on {@code previous} */ + assertThat(previous.getStartEpochNanos()).isEqualTo(0); + assertThat(previous.getEpochNanos()).isEqualTo(1); + OpenTelemetryAssertions.assertThat(previous.getAttributes()).isEqualTo(Attributes.empty()); + assertThat(previous.getValue()).isEqualTo(2); + assertThat(previous.getExemplars()).isEqualTo(exemplars); + } + + @Test + void copyPoint() { + MutableLongPointData pointData = (MutableLongPointData) aggregator.createReusablePoint(); + + Attributes attributes = Attributes.of(AttributeKey.longKey("test"), 100L); + List examplarsFrom = + Collections.singletonList( + ImmutableLongExemplarData.create( + attributes, + 2L, + SpanContext.create( + "00000000000000000000000000000001", + "0000000000000002", + TraceFlags.getDefault(), + TraceState.getDefault()), + 1)); + pointData.set(0, 1, attributes, 2000, examplarsFrom); + + MutableLongPointData toPointData = (MutableLongPointData) aggregator.createReusablePoint(); + + Attributes toAttributes = Attributes.of(AttributeKey.longKey("test"), 100L); + List examplarsTo = + Collections.singletonList( + ImmutableLongExemplarData.create( + attributes, + 4L, + SpanContext.create( + "00000000000000000000000000000001", + "0000000000000002", + TraceFlags.getDefault(), + TraceState.getDefault()), + 2)); + toPointData.set(0, 2, toAttributes, 4000, examplarsTo); + + aggregator.copyPoint(pointData, toPointData); + + Assertions.assertThat(toPointData.getStartEpochNanos()) + .isEqualTo(pointData.getStartEpochNanos()); + Assertions.assertThat(toPointData.getEpochNanos()).isEqualTo(pointData.getEpochNanos()); + OpenTelemetryAssertions.assertThat(toPointData.getAttributes()) + .isEqualTo(pointData.getAttributes()); + Assertions.assertThat(toPointData.getValue()).isEqualTo(pointData.getValue()); + Assertions.assertThat(toPointData.getExemplars()).isEqualTo(pointData.getExemplars()); + } + @Test void toMetricData() { AggregatorHandle aggregatorHandle = aggregator.createHandle(); diff --git a/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/internal/aggregator/LongSumAggregatorTest.java b/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/internal/aggregator/LongSumAggregatorTest.java index d6f0f189834..81e6f40a8b7 100644 --- a/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/internal/aggregator/LongSumAggregatorTest.java +++ b/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/internal/aggregator/LongSumAggregatorTest.java @@ -7,6 +7,7 @@ import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.assertThat; +import io.opentelemetry.api.common.AttributeKey; import io.opentelemetry.api.common.Attributes; import io.opentelemetry.api.trace.SpanContext; import io.opentelemetry.api.trace.TraceFlags; @@ -21,13 +22,16 @@ import io.opentelemetry.sdk.metrics.data.MetricData; import io.opentelemetry.sdk.metrics.internal.data.ImmutableLongExemplarData; import io.opentelemetry.sdk.metrics.internal.data.ImmutableLongPointData; +import io.opentelemetry.sdk.metrics.internal.data.MutableLongPointData; import io.opentelemetry.sdk.metrics.internal.descriptor.Advice; import io.opentelemetry.sdk.metrics.internal.descriptor.InstrumentDescriptor; import io.opentelemetry.sdk.metrics.internal.descriptor.MetricDescriptor; import io.opentelemetry.sdk.metrics.internal.exemplar.ExemplarReservoir; import io.opentelemetry.sdk.resources.Resource; +import io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions; import java.util.Collections; import java.util.List; +import org.assertj.core.api.Assertions; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.Mock; @@ -184,6 +188,93 @@ void mergeAndDiff() { } } + @Test + void diffInPlace() { + Attributes attributes = Attributes.builder().put("test", "value").build(); + LongExemplarData exemplar = + ImmutableLongExemplarData.create( + attributes, + 2L, + SpanContext.create( + "00000000000000000000000000000001", + "0000000000000002", + TraceFlags.getDefault(), + TraceState.getDefault()), + 1); + List exemplars = Collections.singletonList(exemplar); + List previousExemplars = + Collections.singletonList( + ImmutableLongExemplarData.create( + attributes, + 1L, + SpanContext.create( + "00000000000000000000000000000001", + "0000000000000002", + TraceFlags.getDefault(), + TraceState.getDefault()), + 2)); + + MutableLongPointData previous = new MutableLongPointData(); + MutableLongPointData current = new MutableLongPointData(); + + previous.set(0, 1, Attributes.empty(), 1, previousExemplars); + current.set(0, 1, Attributes.empty(), 3, exemplars); + + aggregator.diffInPlace(previous, current); + + /* Assert that latest measurement is kept and set on {@code previous} */ + Assertions.assertThat(previous.getStartEpochNanos()).isEqualTo(current.getStartEpochNanos()); + Assertions.assertThat(previous.getEpochNanos()).isEqualTo(current.getEpochNanos()); + OpenTelemetryAssertions.assertThat(previous.getAttributes()).isEqualTo(current.getAttributes()); + Assertions.assertThat(previous.getValue()).isEqualTo(2); + Assertions.assertThat(previous.getExemplars()).isEqualTo(current.getExemplars()); + } + + @Test + void copyPoint() { + MutableLongPointData pointData = (MutableLongPointData) aggregator.createReusablePoint(); + + Attributes attributes = Attributes.of(AttributeKey.longKey("test"), 100L); + List examplarsFrom = + Collections.singletonList( + ImmutableLongExemplarData.create( + attributes, + 2L, + SpanContext.create( + "00000000000000000000000000000001", + "0000000000000002", + TraceFlags.getDefault(), + TraceState.getDefault()), + 1)); + pointData.set(0, 1, attributes, 2000, examplarsFrom); + + MutableLongPointData toPointData = (MutableLongPointData) aggregator.createReusablePoint(); + + Attributes toAttributes = Attributes.of(AttributeKey.longKey("test"), 100L); + List examplarsTo = + Collections.singletonList( + ImmutableLongExemplarData.create( + attributes, + 4L, + SpanContext.create( + "00000000000000000000000000000001", + "0000000000000002", + TraceFlags.getDefault(), + TraceState.getDefault()), + 2)); + toPointData.set(0, 2, toAttributes, 4000, examplarsTo); + + aggregator.copyPoint(pointData, toPointData); + + Assertions.assertThat(toPointData.getStartEpochNanos()) + .isEqualTo(pointData.getStartEpochNanos()); + Assertions.assertThat(toPointData.getEpochNanos()).isEqualTo(pointData.getEpochNanos()); + OpenTelemetryAssertions.assertThat(toPointData.getAttributes()) + .isEqualTo(pointData.getAttributes()); + Assertions.assertThat(toPointData.getValue()).isEqualTo(pointData.getValue()); + Assertions.assertThat(toPointData.getExemplars()).isEqualTo(pointData.getExemplars()); + } + @Test @SuppressWarnings("unchecked") void toMetricData() { diff --git a/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/internal/state/ArrayBasedStackTest.java b/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/internal/state/ArrayBasedStackTest.java new file mode 100644 index 00000000000..e8cbda1764c --- /dev/null +++ b/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/internal/state/ArrayBasedStackTest.java @@ -0,0 +1,63 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.sdk.metrics.internal.state; + +import static org.assertj.core.api.AssertionsForClassTypes.assertThat; +import static org.assertj.core.api.AssertionsForClassTypes.assertThatThrownBy; + +import org.junit.jupiter.api.Test; + +class ArrayBasedStackTest { + + @Test + void testPushAndPop() { + ArrayBasedStack stack = new ArrayBasedStack<>(); + stack.push(1); + stack.push(2); + assertThat(stack.pop()).isEqualTo(2); + assertThat(stack.pop()).isEqualTo(1); + } + + @Test + void testIsEmpty() { + ArrayBasedStack stack = new ArrayBasedStack<>(); + assertThat(stack.isEmpty()).isTrue(); + stack.push(1); + assertThat(stack.isEmpty()).isFalse(); + } + + @Test + void testSize() { + ArrayBasedStack stack = new ArrayBasedStack<>(); + assertThat(stack.size()).isEqualTo(0); + stack.push(1); + assertThat(stack.size()).isEqualTo(1); + } + + @Test + void testPushBeyondInitialCapacity() { + ArrayBasedStack stack = new ArrayBasedStack<>(); + for (int i = 0; i < ArrayBasedStack.DEFAULT_CAPACITY + 5; i++) { + stack.push(i); + } + assertThat(stack.size()).isEqualTo(ArrayBasedStack.DEFAULT_CAPACITY + 5); + for (int i = ArrayBasedStack.DEFAULT_CAPACITY + 4; i >= 0; i--) { + assertThat(stack.pop()).isEqualTo(i); + } + } + + @Test + void testPopOnEmptyStack() { + ArrayBasedStack stack = new ArrayBasedStack<>(); + assertThat(stack.pop()).isNull(); + } + + @Test + void testPushNullElement() { + ArrayBasedStack stack = new ArrayBasedStack<>(); + assertThatThrownBy(() -> stack.push(null)).isInstanceOf(NullPointerException.class); + } +} diff --git a/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/internal/state/AsynchronousMetricStorageTest.java b/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/internal/state/AsynchronousMetricStorageTest.java index fb1d147e4c5..109b8eef7a4 100644 --- a/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/internal/state/AsynchronousMetricStorageTest.java +++ b/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/internal/state/AsynchronousMetricStorageTest.java @@ -5,8 +5,9 @@ package io.opentelemetry.sdk.metrics.internal.state; -import static io.opentelemetry.sdk.metrics.internal.state.Measurement.doubleMeasurement; -import static io.opentelemetry.sdk.metrics.internal.state.Measurement.longMeasurement; +import static io.opentelemetry.sdk.common.export.MemoryMode.REUSABLE_DATA; +import static io.opentelemetry.sdk.metrics.internal.state.ImmutableMeasurement.createDouble; +import static io.opentelemetry.sdk.metrics.internal.state.ImmutableMeasurement.createLong; import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.assertThat; import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.attributeEntry; import static org.mockito.ArgumentMatchers.any; @@ -16,12 +17,16 @@ import io.opentelemetry.api.common.Attributes; import io.opentelemetry.internal.testing.slf4j.SuppressLogger; import io.opentelemetry.sdk.common.InstrumentationScopeInfo; +import io.opentelemetry.sdk.common.export.MemoryMode; import io.opentelemetry.sdk.metrics.InstrumentSelector; import io.opentelemetry.sdk.metrics.InstrumentType; import io.opentelemetry.sdk.metrics.InstrumentValueType; import io.opentelemetry.sdk.metrics.View; import io.opentelemetry.sdk.metrics.data.AggregationTemporality; +import io.opentelemetry.sdk.metrics.data.MetricData; +import io.opentelemetry.sdk.metrics.data.PointData; import io.opentelemetry.sdk.metrics.export.MetricReader; +import io.opentelemetry.sdk.metrics.internal.data.MutableLongPointData; import io.opentelemetry.sdk.metrics.internal.debug.SourceInfo; import io.opentelemetry.sdk.metrics.internal.descriptor.Advice; import io.opentelemetry.sdk.metrics.internal.descriptor.InstrumentDescriptor; @@ -31,10 +36,12 @@ import io.opentelemetry.sdk.metrics.internal.view.ViewRegistry; import io.opentelemetry.sdk.resources.Resource; import io.opentelemetry.sdk.testing.time.TestClock; -import org.junit.jupiter.api.BeforeEach; +import java.util.Collection; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.junit.jupiter.api.extension.RegisterExtension; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.EnumSource; import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; @@ -65,9 +72,10 @@ class AsynchronousMetricStorageTest { private AsynchronousMetricStorage longCounterStorage; private AsynchronousMetricStorage doubleCounterStorage; - @BeforeEach - void setup() { + // Not using @BeforeEach since many methods require executing them for each MemoryMode + void setup(MemoryMode memoryMode) { when(reader.getAggregationTemporality(any())).thenReturn(AggregationTemporality.CUMULATIVE); + when(reader.getMemoryMode()).thenReturn(memoryMode); registeredReader = RegisteredReader.create(reader, ViewRegistry.create()); longCounterStorage = @@ -94,14 +102,14 @@ void setup() { Advice.empty())); } - @Test - void recordLong() { - longCounterStorage.record( - longMeasurement(0, 1, 1, Attributes.builder().put("key", "a").build())); - longCounterStorage.record( - longMeasurement(0, 1, 2, Attributes.builder().put("key", "b").build())); - longCounterStorage.record( - longMeasurement(0, 1, 3, Attributes.builder().put("key", "c").build())); + @ParameterizedTest + @EnumSource(MemoryMode.class) + void recordLong(MemoryMode memoryMode) { + setup(memoryMode); + + longCounterStorage.record(createLong(0, 1, 1, Attributes.builder().put("key", "a").build())); + longCounterStorage.record(createLong(0, 1, 2, Attributes.builder().put("key", "b").build())); + longCounterStorage.record(createLong(0, 1, 3, Attributes.builder().put("key", "c").build())); assertThat(longCounterStorage.collect(resource, scope, 0, testClock.nanoTime())) .satisfies( @@ -119,14 +127,17 @@ void recordLong() { assertThat(logs.size()).isEqualTo(0); } - @Test - void recordDouble() { + @ParameterizedTest + @EnumSource(MemoryMode.class) + void recordDouble(MemoryMode memoryMode) { + setup(memoryMode); + doubleCounterStorage.record( - doubleMeasurement(0, 1, 1.1, Attributes.builder().put("key", "a").build())); + createDouble(0, 1, 1.1, Attributes.builder().put("key", "a").build())); doubleCounterStorage.record( - doubleMeasurement(0, 1, 2.2, Attributes.builder().put("key", "b").build())); + createDouble(0, 1, 2.2, Attributes.builder().put("key", "b").build())); doubleCounterStorage.record( - doubleMeasurement(0, 1, 3.3, Attributes.builder().put("key", "c").build())); + createDouble(0, 1, 3.3, Attributes.builder().put("key", "c").build())); assertThat(doubleCounterStorage.collect(resource, scope, 0, testClock.nanoTime())) .satisfies( @@ -146,8 +157,11 @@ void recordDouble() { assertThat(logs.size()).isEqualTo(0); } - @Test - void record_ProcessesAttributes() { + @ParameterizedTest + @EnumSource(MemoryMode.class) + void record_ProcessesAttributes(MemoryMode memoryMode) { + setup(memoryMode); + AsynchronousMetricStorage storage = AsynchronousMetricStorage.create( registeredReader, @@ -166,7 +180,7 @@ void record_ProcessesAttributes() { Advice.empty())); storage.record( - longMeasurement(0, 1, 1, Attributes.builder().put("key1", "a").put("key2", "b").build())); + createLong(0, 1, 1, Attributes.builder().put("key1", "a").put("key2", "b").build())); assertThat(storage.collect(resource, scope, 0, testClock.nanoTime())) .satisfies( @@ -180,11 +194,14 @@ void record_ProcessesAttributes() { assertThat(logs.size()).isEqualTo(0); } - @Test - void record_MaxCardinality() { + @ParameterizedTest + @EnumSource(MemoryMode.class) + void record_MaxCardinality(MemoryMode memoryMode) { + setup(memoryMode); + for (int i = 0; i <= CARDINALITY_LIMIT + 1; i++) { longCounterStorage.record( - longMeasurement(0, 1, 1, Attributes.builder().put("key" + i, "val").build())); + createLong(0, 1, 1, Attributes.builder().put("key" + i, "val").build())); } assertThat(longCounterStorage.collect(resource, scope, 0, testClock.nanoTime())) @@ -194,12 +211,13 @@ void record_MaxCardinality() { logs.assertContains("Instrument long-counter has exceeded the maximum allowed cardinality"); } - @Test - void record_DuplicateAttributes() { - longCounterStorage.record( - longMeasurement(0, 1, 1, Attributes.builder().put("key1", "a").build())); - longCounterStorage.record( - longMeasurement(0, 1, 2, Attributes.builder().put("key1", "a").build())); + @ParameterizedTest + @EnumSource(MemoryMode.class) + void record_DuplicateAttributes(MemoryMode memoryMode) { + setup(memoryMode); + + longCounterStorage.record(createLong(0, 1, 1, Attributes.builder().put("key1", "a").build())); + longCounterStorage.record(createLong(0, 1, 2, Attributes.builder().put("key1", "a").build())); assertThat(longCounterStorage.collect(resource, scope, 0, testClock.nanoTime())) .satisfies( @@ -214,10 +232,13 @@ void record_DuplicateAttributes() { "Instrument long-counter has recorded multiple values for the same attributes: {key1=\"a\"}"); } - @Test - void collect_CumulativeReportsCumulativeObservations() { + @ParameterizedTest + @EnumSource(MemoryMode.class) + void collect_CumulativeReportsCumulativeObservations(MemoryMode memoryMode) { + setup(memoryMode); + // Record measurement and collect at time 10 - longCounterStorage.record(longMeasurement(0, 10, 3, Attributes.empty())); + longCounterStorage.record(createLong(0, 10, 3, Attributes.empty())); assertThat(longCounterStorage.collect(resource, scope, 0, 0)) .hasLongSumSatisfying( sum -> @@ -232,9 +253,9 @@ void collect_CumulativeReportsCumulativeObservations() { registeredReader.setLastCollectEpochNanos(10); // Record measurements and collect at time 30 - longCounterStorage.record(longMeasurement(0, 30, 3, Attributes.empty())); + longCounterStorage.record(createLong(0, 30, 3, Attributes.empty())); longCounterStorage.record( - longMeasurement(0, 30, 6, Attributes.builder().put("key", "value1").build())); + createLong(0, 30, 6, Attributes.builder().put("key", "value1").build())); assertThat(longCounterStorage.collect(resource, scope, 0, 0)) .hasLongSumSatisfying( sum -> @@ -255,9 +276,9 @@ void collect_CumulativeReportsCumulativeObservations() { registeredReader.setLastCollectEpochNanos(30); // Record measurement and collect at time 35 - longCounterStorage.record(longMeasurement(0, 35, 4, Attributes.empty())); + longCounterStorage.record(createLong(0, 35, 4, Attributes.empty())); longCounterStorage.record( - longMeasurement(0, 35, 5, Attributes.builder().put("key", "value2").build())); + createLong(0, 35, 5, Attributes.builder().put("key", "value2").build())); assertThat(longCounterStorage.collect(resource, scope, 0, 0)) .hasLongSumSatisfying( sum -> @@ -277,8 +298,11 @@ void collect_CumulativeReportsCumulativeObservations() { .hasAttributes(Attributes.builder().put("key", "value2").build()))); } - @Test - void collect_DeltaComputesDiff() { + @ParameterizedTest + @EnumSource(MemoryMode.class) + void collect_DeltaComputesDiff(MemoryMode memoryMode) { + setup(memoryMode); + when(reader.getAggregationTemporality(any())).thenReturn(AggregationTemporality.DELTA); longCounterStorage = AsynchronousMetricStorage.create( @@ -293,7 +317,7 @@ void collect_DeltaComputesDiff() { Advice.empty())); // Record measurement and collect at time 10 - longCounterStorage.record(longMeasurement(0, 10, 3, Attributes.empty())); + longCounterStorage.record(createLong(0, 10, 3, Attributes.empty())); assertThat(longCounterStorage.collect(resource, scope, 0, 0)) .hasLongSumSatisfying( sum -> @@ -308,9 +332,9 @@ void collect_DeltaComputesDiff() { registeredReader.setLastCollectEpochNanos(10); // Record measurement and collect at time 30 - longCounterStorage.record(longMeasurement(0, 30, 3, Attributes.empty())); + longCounterStorage.record(createLong(0, 30, 3, Attributes.empty())); longCounterStorage.record( - longMeasurement(0, 30, 6, Attributes.builder().put("key", "value1").build())); + createLong(0, 30, 6, Attributes.builder().put("key", "value1").build())); assertThat(longCounterStorage.collect(resource, scope, 0, 0)) .hasLongSumSatisfying( sum -> @@ -331,9 +355,9 @@ void collect_DeltaComputesDiff() { registeredReader.setLastCollectEpochNanos(30); // Record measurement and collect at time 35 - longCounterStorage.record(longMeasurement(0, 35, 4, Attributes.empty())); + longCounterStorage.record(createLong(0, 35, 4, Attributes.empty())); longCounterStorage.record( - longMeasurement(0, 35, 5, Attributes.builder().put("key", "value2").build())); + createLong(0, 35, 5, Attributes.builder().put("key", "value2").build())); assertThat(longCounterStorage.collect(resource, scope, 0, 0)) .hasLongSumSatisfying( sum -> @@ -352,4 +376,54 @@ void collect_DeltaComputesDiff() { .hasValue(5) .hasAttributes(Attributes.builder().put("key", "value2").build()))); } + + @Test + public void collect_reusableData_reusedObjectsAreReturnedOnSecondCall() { + setup(REUSABLE_DATA); + + longCounterStorage.record(createLong(0, 1, 1, Attributes.builder().put("key", "a").build())); + longCounterStorage.record(createLong(0, 1, 2, Attributes.builder().put("key", "b").build())); + longCounterStorage.record(createLong(0, 1, 3, Attributes.builder().put("key", "c").build())); + + MetricData firstCollectMetricData = + longCounterStorage.collect(resource, scope, 0, testClock.nanoTime()); + assertThat(firstCollectMetricData) + .satisfies( + metricData -> + assertThat(metricData) + .hasLongSumSatisfying( + sum -> + sum.hasPointsSatisfying( + point -> + point + .hasValue(1) + .hasAttributes(attributeEntry("key", "a")) + .isInstanceOf(MutableLongPointData.class), + point -> + point + .hasValue(2) + .hasAttributes(attributeEntry("key", "b")) + .isInstanceOf(MutableLongPointData.class), + point -> + point + .hasValue(3) + .hasAttributes(attributeEntry("key", "c")) + .isInstanceOf(MutableLongPointData.class)))); + + MetricData secondCollectMetricData = + longCounterStorage.collect(resource, scope, 0, testClock.nanoTime()); + + Collection secondCollectPoints = + secondCollectMetricData.getData().getPoints(); + Collection firstCollectionPoints = + firstCollectMetricData.getData().getPoints(); + assertThat(secondCollectPoints).hasSameSizeAs(firstCollectionPoints); + + // Show that second returned objects have been used in first collect response as well + // which proves there is reuse. + for (PointData firstCollectionPoint : firstCollectionPoints) { + assertThat(secondCollectPoints) + .anySatisfy(point -> assertThat(point).isSameAs(firstCollectionPoint)); + } + } } diff --git a/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/internal/state/CallbackRegistrationTest.java b/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/internal/state/CallbackRegistrationTest.java index a15f8e4affd..a8b424dfcd5 100644 --- a/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/internal/state/CallbackRegistrationTest.java +++ b/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/internal/state/CallbackRegistrationTest.java @@ -5,8 +5,8 @@ package io.opentelemetry.sdk.metrics.internal.state; -import static io.opentelemetry.sdk.metrics.internal.state.Measurement.doubleMeasurement; -import static io.opentelemetry.sdk.metrics.internal.state.Measurement.longMeasurement; +import static io.opentelemetry.sdk.metrics.internal.state.ImmutableMeasurement.createDouble; +import static io.opentelemetry.sdk.metrics.internal.state.ImmutableMeasurement.createLong; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.mockito.ArgumentMatchers.any; @@ -19,6 +19,7 @@ import io.opentelemetry.api.common.Attributes; import io.opentelemetry.internal.testing.slf4j.SuppressLogger; import io.opentelemetry.sdk.common.InstrumentationScopeInfo; +import io.opentelemetry.sdk.common.export.MemoryMode; import io.opentelemetry.sdk.metrics.InstrumentType; import io.opentelemetry.sdk.metrics.InstrumentValueType; import io.opentelemetry.sdk.metrics.export.MetricReader; @@ -76,6 +77,7 @@ class CallbackRegistrationTest { @BeforeEach void setup() { + when(reader.getMemoryMode()).thenReturn(MemoryMode.IMMUTABLE_DATA); registeredReader = RegisteredReader.create(reader, ViewRegistry.create()); when(storage1.getRegisteredReader()).thenReturn(registeredReader); when(storage2.getRegisteredReader()).thenReturn(registeredReader); @@ -145,7 +147,7 @@ void invokeCallback_Double() { assertThat(counter.get()).isEqualTo(1.1); verify(storage1) - .record(doubleMeasurement(0, 1, 1.1, Attributes.builder().put("key", "val").build())); + .record(createDouble(0, 1, 1.1, Attributes.builder().put("key", "val").build())); verify(storage2, never()).record(any()); verify(storage3, never()).record(any()); } @@ -164,10 +166,8 @@ void invokeCallback_Long() { assertThat(counter.get()).isEqualTo(1); verify(storage1, never()).record(any()); - verify(storage2) - .record(longMeasurement(0, 1, 1, Attributes.builder().put("key", "val").build())); - verify(storage3) - .record(longMeasurement(0, 1, 1, Attributes.builder().put("key", "val").build())); + verify(storage2).record(createLong(0, 1, 1, Attributes.builder().put("key", "val").build())); + verify(storage3).record(createLong(0, 1, 1, Attributes.builder().put("key", "val").build())); } @Test @@ -189,11 +189,9 @@ void invokeCallback_MultipleMeasurements() { assertThat(doubleCounter.get()).isEqualTo(1.1); assertThat(longCounter.get()).isEqualTo(1); verify(storage1) - .record(doubleMeasurement(0, 1, 1.1, Attributes.builder().put("key", "val").build())); - verify(storage2) - .record(longMeasurement(0, 1, 1, Attributes.builder().put("key", "val").build())); - verify(storage3) - .record(longMeasurement(0, 1, 1, Attributes.builder().put("key", "val").build())); + .record(createDouble(0, 1, 1.1, Attributes.builder().put("key", "val").build())); + verify(storage2).record(createLong(0, 1, 1, Attributes.builder().put("key", "val").build())); + verify(storage3).record(createLong(0, 1, 1, Attributes.builder().put("key", "val").build())); } @Test diff --git a/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/internal/state/ObjectPoolTest.java b/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/internal/state/ObjectPoolTest.java new file mode 100644 index 00000000000..ee90d303783 --- /dev/null +++ b/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/internal/state/ObjectPoolTest.java @@ -0,0 +1,62 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.sdk.metrics.internal.state; + +import static org.assertj.core.api.AssertionsForInterfaceTypes.assertThat; + +import java.util.Arrays; +import java.util.List; +import java.util.function.Supplier; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +class ObjectPoolTest { + private ObjectPool objectPool; + + @BeforeEach + void setUp() { + Supplier supplier = StringBuilder::new; + objectPool = new ObjectPool<>(supplier); + } + + @Test + void testBorrowObjectWhenPoolIsEmpty() { + StringBuilder result = objectPool.borrowObject(); + assertThat(result.toString()).isEmpty(); + } + + @Test + void testReturnAndBorrowMultipleObjects() { + // Borrow three objects + StringBuilder borrowed1 = objectPool.borrowObject(); + StringBuilder borrowed2 = objectPool.borrowObject(); + StringBuilder borrowed3 = objectPool.borrowObject(); + + // Modify and return the borrowed objects + borrowed1.append("pooledObject1"); + objectPool.returnObject(borrowed1); + borrowed2.append("pooledObject2"); + objectPool.returnObject(borrowed2); + borrowed3.append("pooledObject3"); + objectPool.returnObject(borrowed3); + + // Borrow three objects, which should be the same ones we just returned + StringBuilder result1 = objectPool.borrowObject(); + StringBuilder result2 = objectPool.borrowObject(); + StringBuilder result3 = objectPool.borrowObject(); + + // Verify the results using AssertJ assertions and reference comparison + List originalObjects = Arrays.asList(borrowed1, borrowed2, borrowed3); + List borrowedObjects = Arrays.asList(result1, result2, result3); + + assertThat(originalObjects).hasSize(3); + assertThat(borrowedObjects).hasSize(3); + + for (StringBuilder original : originalObjects) { + assertThat(borrowedObjects).anySatisfy(borrowed -> assertThat(borrowed).isSameAs(original)); + } + } +} diff --git a/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/internal/state/PooledHashMapTest.java b/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/internal/state/PooledHashMapTest.java new file mode 100644 index 00000000000..f53aec03f90 --- /dev/null +++ b/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/internal/state/PooledHashMapTest.java @@ -0,0 +1,75 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.sdk.metrics.internal.state; + +import java.util.HashMap; +import java.util.Map; +import org.assertj.core.api.Assertions; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +public class PooledHashMapTest { + + private PooledHashMap map; + + @BeforeEach + public void setup() { + map = new PooledHashMap<>(); + } + + @Test + public void putAndGetTest() { + map.put("One", 1); + Assertions.assertThat(map.get("One")).isEqualTo(1); + } + + @Test + public void removeTest() { + map.put("One", 1); + map.remove("One"); + Assertions.assertThat(map.get("One")).isNull(); + } + + @Test + public void sizeTest() { + map.put("One", 1); + map.put("Two", 2); + Assertions.assertThat(map.size()).isEqualTo(2); + } + + @Test + public void isEmptyTest() { + Assertions.assertThat(map.isEmpty()).isTrue(); + map.put("One", 1); + Assertions.assertThat(map.isEmpty()).isFalse(); + } + + @Test + public void containsKeyTest() { + map.put("One", 1); + Assertions.assertThat(map.containsKey("One")).isTrue(); + Assertions.assertThat(map.containsKey("Two")).isFalse(); + } + + @Test + public void clearTest() { + map.put("One", 1); + map.put("Two", 2); + map.clear(); + Assertions.assertThat(map.isEmpty()).isTrue(); + } + + @Test + public void forEachTest() { + map.put("One", 1); + map.put("Two", 2); + + Map actualMap = new HashMap<>(); + map.forEach(actualMap::put); + + Assertions.assertThat(actualMap).containsOnlyKeys("One", "Two").containsValues(1, 2); + } +} diff --git a/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/internal/state/SdkObservableMeasurementTest.java b/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/internal/state/SdkObservableMeasurementTest.java new file mode 100644 index 00000000000..ca3590f1fd4 --- /dev/null +++ b/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/internal/state/SdkObservableMeasurementTest.java @@ -0,0 +1,175 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.sdk.metrics.internal.state; + +import static io.opentelemetry.sdk.metrics.data.AggregationTemporality.CUMULATIVE; +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import io.opentelemetry.sdk.common.InstrumentationScopeInfo; +import io.opentelemetry.sdk.common.export.MemoryMode; +import io.opentelemetry.sdk.metrics.InstrumentType; +import io.opentelemetry.sdk.metrics.InstrumentValueType; +import io.opentelemetry.sdk.metrics.internal.descriptor.Advice; +import io.opentelemetry.sdk.metrics.internal.descriptor.InstrumentDescriptor; +import io.opentelemetry.sdk.metrics.internal.export.RegisteredReader; +import io.opentelemetry.sdk.metrics.internal.view.ViewRegistry; +import io.opentelemetry.sdk.testing.exporter.InMemoryMetricReader; +import org.assertj.core.util.Lists; +import org.junit.jupiter.api.Test; +import org.mockito.ArgumentCaptor; + +@SuppressWarnings("rawtypes") +public class SdkObservableMeasurementTest { + + private AsynchronousMetricStorage mockAsyncStorage1; + private RegisteredReader registeredReader1; + private SdkObservableMeasurement sdkObservableMeasurement; + private ArgumentCaptor measurementArgumentCaptor; + + @SuppressWarnings("unchecked") + private void setup(MemoryMode memoryMode) { + InstrumentationScopeInfo instrumentationScopeInfo = + InstrumentationScopeInfo.builder("test-scope").build(); + InstrumentDescriptor instrumentDescriptor = + InstrumentDescriptor.create( + "testCounter", + "an instrument for testing purposes", + "ms", + InstrumentType.COUNTER, + InstrumentValueType.LONG, + Advice.empty()); + + InMemoryMetricReader reader1 = + InMemoryMetricReader.builder() + .setAggregationTemporalitySelector(instrumentType -> CUMULATIVE) + .setMemoryMode(memoryMode) + .build(); + registeredReader1 = RegisteredReader.create(reader1, ViewRegistry.create()); + + InMemoryMetricReader reader2 = InMemoryMetricReader.builder().setMemoryMode(memoryMode).build(); + RegisteredReader registeredReader2 = RegisteredReader.create(reader2, ViewRegistry.create()); + + measurementArgumentCaptor = ArgumentCaptor.forClass(Measurement.class); + mockAsyncStorage1 = mock(AsynchronousMetricStorage.class); + when(mockAsyncStorage1.getRegisteredReader()).thenReturn(registeredReader1); + AsynchronousMetricStorage mockAsyncStorage2 = mock(AsynchronousMetricStorage.class); + when(mockAsyncStorage2.getRegisteredReader()).thenReturn(registeredReader2); + + sdkObservableMeasurement = + SdkObservableMeasurement.create( + instrumentationScopeInfo, + instrumentDescriptor, + Lists.newArrayList(mockAsyncStorage1, mockAsyncStorage2)); + } + + @Test + public void testRecordLongImmutableData() { + setup(MemoryMode.IMMUTABLE_DATA); + + sdkObservableMeasurement.setActiveReader(registeredReader1, 0, 10); + + try { + sdkObservableMeasurement.record(5); + + verify(mockAsyncStorage1).record(measurementArgumentCaptor.capture()); + Measurement passedMeasurement = measurementArgumentCaptor.getValue(); + assertThat(passedMeasurement).isInstanceOf(ImmutableMeasurement.class); + assertThat(passedMeasurement.longValue()).isEqualTo(5); + assertThat(passedMeasurement.startEpochNanos()).isEqualTo(0); + assertThat(passedMeasurement.epochNanos()).isEqualTo(10); + } finally { + sdkObservableMeasurement.unsetActiveReader(); + } + } + + @Test + public void testRecordDoubleReturnImmutableData() { + setup(MemoryMode.IMMUTABLE_DATA); + + sdkObservableMeasurement.setActiveReader(registeredReader1, 0, 10); + + try { + sdkObservableMeasurement.record(4.3); + + verify(mockAsyncStorage1).record(measurementArgumentCaptor.capture()); + Measurement passedMeasurement = measurementArgumentCaptor.getValue(); + assertThat(passedMeasurement).isInstanceOf(ImmutableMeasurement.class); + assertThat(passedMeasurement.doubleValue()).isEqualTo(4.3); + assertThat(passedMeasurement.startEpochNanos()).isEqualTo(0); + assertThat(passedMeasurement.epochNanos()).isEqualTo(10); + } finally { + sdkObservableMeasurement.unsetActiveReader(); + } + } + + @Test + public void testRecordDoubleReturnReusableData() { + setup(MemoryMode.REUSABLE_DATA); + + sdkObservableMeasurement.setActiveReader(registeredReader1, 0, 10); + + try { + sdkObservableMeasurement.record(4.3); + + verify(mockAsyncStorage1).record(measurementArgumentCaptor.capture()); + Measurement firstMeasurement = measurementArgumentCaptor.getValue(); + assertThat(firstMeasurement).isInstanceOf(MutableMeasurement.class); + assertThat(firstMeasurement.doubleValue()).isEqualTo(4.3); + assertThat(firstMeasurement.startEpochNanos()).isEqualTo(0); + assertThat(firstMeasurement.epochNanos()).isEqualTo(10); + + sdkObservableMeasurement.record(5.3); + + verify(mockAsyncStorage1, times(2)).record(measurementArgumentCaptor.capture()); + Measurement secondMeasurement = measurementArgumentCaptor.getValue(); + assertThat(secondMeasurement).isInstanceOf(MutableMeasurement.class); + assertThat(secondMeasurement.doubleValue()).isEqualTo(5.3); + assertThat(secondMeasurement.startEpochNanos()).isEqualTo(0); + assertThat(secondMeasurement.epochNanos()).isEqualTo(10); + + // LeasedMeasurement should be re-used + assertThat(secondMeasurement).isSameAs(firstMeasurement); + } finally { + sdkObservableMeasurement.unsetActiveReader(); + } + } + + @Test + public void testRecordLongReturnReusableData() { + setup(MemoryMode.REUSABLE_DATA); + + sdkObservableMeasurement.setActiveReader(registeredReader1, 0, 10); + + try { + sdkObservableMeasurement.record(2); + + verify(mockAsyncStorage1).record(measurementArgumentCaptor.capture()); + Measurement firstMeasurement = measurementArgumentCaptor.getValue(); + assertThat(firstMeasurement).isInstanceOf(MutableMeasurement.class); + assertThat(firstMeasurement.longValue()).isEqualTo(2); + assertThat(firstMeasurement.startEpochNanos()).isEqualTo(0); + assertThat(firstMeasurement.epochNanos()).isEqualTo(10); + + sdkObservableMeasurement.record(6); + + verify(mockAsyncStorage1, times(2)).record(measurementArgumentCaptor.capture()); + Measurement secondMeasurement = measurementArgumentCaptor.getValue(); + assertThat(secondMeasurement).isInstanceOf(MutableMeasurement.class); + assertThat(secondMeasurement.longValue()).isEqualTo(6); + assertThat(secondMeasurement.startEpochNanos()).isEqualTo(0); + assertThat(secondMeasurement.epochNanos()).isEqualTo(10); + + // LeasedMeasurement should be re-used + assertThat(secondMeasurement).isSameAs(firstMeasurement); + } finally { + sdkObservableMeasurement.unsetActiveReader(); + } + } +} diff --git a/sdk/metrics/testing-internal/build.gradle.kts b/sdk/metrics/testing-internal/build.gradle.kts new file mode 100644 index 00000000000..df76bebe8fb --- /dev/null +++ b/sdk/metrics/testing-internal/build.gradle.kts @@ -0,0 +1,13 @@ +plugins { + id("otel.java-conventions") +} + +description = "OpenTelemetry Metrics Testing (Internal)" +otelJava.moduleName.set("io.opentelemetry.metrics.internal.testing") + +dependencies { + api("org.junit.jupiter:junit-jupiter-api") + implementation("org.slf4j:jul-to-slf4j") + api(project(":sdk:common")) + api(project(":sdk:metrics")) +} diff --git a/sdk/testing/src/main/java/io/opentelemetry/sdk/testing/assertj/LongSumAssert.java b/sdk/testing/src/main/java/io/opentelemetry/sdk/testing/assertj/LongSumAssert.java index 16ec2109e9a..128a95ebce8 100644 --- a/sdk/testing/src/main/java/io/opentelemetry/sdk/testing/assertj/LongSumAssert.java +++ b/sdk/testing/src/main/java/io/opentelemetry/sdk/testing/assertj/LongSumAssert.java @@ -73,14 +73,14 @@ public LongSumAssert isDelta() { return myself; } - /** Asserts the sum has points matching all of the given assertions and no more, in any order. */ + /** Asserts the sum has points matching all the given assertions and no more, in any order. */ @SafeVarargs @SuppressWarnings("varargs") public final LongSumAssert hasPointsSatisfying(Consumer... assertions) { return hasPointsSatisfying(Arrays.asList(assertions)); } - /** Asserts the sum has points matching all of the given assertions and no more, in any order. */ + /** Asserts the sum has points matching all the given assertions and no more, in any order. */ public LongSumAssert hasPointsSatisfying( Iterable> assertions) { assertThat(actual.getPoints()) diff --git a/sdk/testing/src/main/java/io/opentelemetry/sdk/testing/exporter/InMemoryMetricReader.java b/sdk/testing/src/main/java/io/opentelemetry/sdk/testing/exporter/InMemoryMetricReader.java index 7957035b2ed..d9aa8bfb3c5 100644 --- a/sdk/testing/src/main/java/io/opentelemetry/sdk/testing/exporter/InMemoryMetricReader.java +++ b/sdk/testing/src/main/java/io/opentelemetry/sdk/testing/exporter/InMemoryMetricReader.java @@ -5,7 +5,10 @@ package io.opentelemetry.sdk.testing.exporter; +import static io.opentelemetry.sdk.common.export.MemoryMode.IMMUTABLE_DATA; + import io.opentelemetry.sdk.common.CompletableResultCode; +import io.opentelemetry.sdk.common.export.MemoryMode; import io.opentelemetry.sdk.metrics.Aggregation; import io.opentelemetry.sdk.metrics.InstrumentType; import io.opentelemetry.sdk.metrics.data.AggregationTemporality; @@ -52,6 +55,18 @@ public class InMemoryMetricReader implements MetricReader { private final DefaultAggregationSelector defaultAggregationSelector; private final AtomicBoolean isShutdown = new AtomicBoolean(false); private volatile MetricProducer metricProducer = MetricProducer.noop(); + private final MemoryMode memoryMode; + + /** + * Creates an {@link InMemoryMetricReaderBuilder} with defaults. + * + * @return a builder with always-cumulative {@link AggregationTemporalitySelector}, default {@link + * DefaultAggregationSelector} and {@link MemoryMode#IMMUTABLE_DATA} {@link MemoryMode} + * @since 1.29.0 + */ + public static InMemoryMetricReaderBuilder builder() { + return new InMemoryMetricReaderBuilder(); + } /** Returns a new {@link InMemoryMetricReader}. */ public static InMemoryMetricReader create() { @@ -79,8 +94,16 @@ public static InMemoryMetricReader createDelta() { private InMemoryMetricReader( AggregationTemporalitySelector aggregationTemporalitySelector, DefaultAggregationSelector defaultAggregationSelector) { + this(aggregationTemporalitySelector, defaultAggregationSelector, IMMUTABLE_DATA); + } + + InMemoryMetricReader( + AggregationTemporalitySelector aggregationTemporalitySelector, + DefaultAggregationSelector defaultAggregationSelector, + MemoryMode memoryMode) { this.aggregationTemporalitySelector = aggregationTemporalitySelector; this.defaultAggregationSelector = defaultAggregationSelector; + this.memoryMode = memoryMode; } /** Returns all metrics accumulated since the last call. */ @@ -118,6 +141,11 @@ public CompletableResultCode shutdown() { return CompletableResultCode.ofSuccess(); } + @Override + public MemoryMode getMemoryMode() { + return memoryMode; + } + @Override public String toString() { return "InMemoryMetricReader{}"; diff --git a/sdk/testing/src/main/java/io/opentelemetry/sdk/testing/exporter/InMemoryMetricReaderBuilder.java b/sdk/testing/src/main/java/io/opentelemetry/sdk/testing/exporter/InMemoryMetricReaderBuilder.java new file mode 100644 index 00000000000..e3824e6cae7 --- /dev/null +++ b/sdk/testing/src/main/java/io/opentelemetry/sdk/testing/exporter/InMemoryMetricReaderBuilder.java @@ -0,0 +1,63 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.sdk.testing.exporter; + +import static io.opentelemetry.sdk.common.export.MemoryMode.IMMUTABLE_DATA; + +import io.opentelemetry.sdk.common.export.MemoryMode; +import io.opentelemetry.sdk.metrics.export.AggregationTemporalitySelector; +import io.opentelemetry.sdk.metrics.export.DefaultAggregationSelector; + +public final class InMemoryMetricReaderBuilder { + private AggregationTemporalitySelector aggregationTemporalitySelector = + AggregationTemporalitySelector.alwaysCumulative(); + private DefaultAggregationSelector defaultAggregationSelector = + DefaultAggregationSelector.getDefault(); + private MemoryMode memoryMode = IMMUTABLE_DATA; + + /** + * Creates an {@link InMemoryMetricReaderBuilder} with defaults. + * + *

    Creates a builder with always-cumulative {@link AggregationTemporalitySelector}, default + * {@link DefaultAggregationSelector} and {@link MemoryMode#IMMUTABLE_DATA} {@link MemoryMode} + */ + InMemoryMetricReaderBuilder() {} + + public InMemoryMetricReaderBuilder setAggregationTemporalitySelector( + AggregationTemporalitySelector aggregationTemporalitySelector) { + this.aggregationTemporalitySelector = aggregationTemporalitySelector; + return this; + } + + /** + * Sets the {@link DefaultAggregationSelector}. + * + * @param defaultAggregationSelector the {@link DefaultAggregationSelector} to set + * @return this {@link InMemoryMetricReaderBuilder} + */ + @SuppressWarnings("unused") + public InMemoryMetricReaderBuilder setDefaultAggregationSelector( + DefaultAggregationSelector defaultAggregationSelector) { + this.defaultAggregationSelector = defaultAggregationSelector; + return this; + } + + /** + * Sets the {@link MemoryMode}. + * + * @param memoryMode the {@link MemoryMode} to set + * @return this {@link InMemoryMetricReaderBuilder} + */ + public InMemoryMetricReaderBuilder setMemoryMode(MemoryMode memoryMode) { + this.memoryMode = memoryMode; + return this; + } + + public InMemoryMetricReader build() { + return new InMemoryMetricReader( + aggregationTemporalitySelector, defaultAggregationSelector, memoryMode); + } +} From 7083f440b90f3a8a421546234acc1d2474d9e34b Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 26 Sep 2023 13:23:04 -0500 Subject: [PATCH 017/901] Update dependency nl.jqno.equalsverifier:equalsverifier to v3.15.2 (#5852) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- dependencyManagement/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index 46aa12a1343..afb0cf04900 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -70,7 +70,7 @@ val DEPENDENCIES = listOf( "io.opentracing:opentracing-api:0.33.0", "io.opentracing:opentracing-noop:0.33.0", "junit:junit:4.13.2", - "nl.jqno.equalsverifier:equalsverifier:3.15.1", + "nl.jqno.equalsverifier:equalsverifier:3.15.2", "org.awaitility:awaitility:4.2.0", "org.bouncycastle:bcpkix-jdk15on:1.70", "org.codehaus.mojo:animal-sniffer-annotations:1.23", From f09487a6fbb532edc6a1ca3659a5877ccb594eb5 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 26 Sep 2023 13:23:21 -0500 Subject: [PATCH 018/901] Update dependency com.google.api.grpc:proto-google-common-protos to v2.25.1 (#5851) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- dependencyManagement/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index afb0cf04900..b6049833ca7 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -55,7 +55,7 @@ val DEPENDENCIES = listOf( "io.prometheus:simpleclient_httpserver:${prometheusClientVersion}", "javax.annotation:javax.annotation-api:1.3.2", "com.github.stefanbirkner:system-rules:1.19.0", - "com.google.api.grpc:proto-google-common-protos:2.24.0", + "com.google.api.grpc:proto-google-common-protos:2.25.1", "com.google.code.findbugs:jsr305:3.0.2", "com.google.guava:guava-beta-checker:1.0", "com.sun.net.httpserver:http:20070405", From 4b4e894f0edd80543aaa1627308e6aba1a1e0397 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 26 Sep 2023 13:23:39 -0500 Subject: [PATCH 019/901] Update errorProneVersion to v2.22.0 (#5850) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- dependencyManagement/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index b6049833ca7..3a9333b5b4d 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -25,7 +25,7 @@ val DEPENDENCY_BOMS = listOf( ) val autoValueVersion = "1.10.4" -val errorProneVersion = "2.21.1" +val errorProneVersion = "2.22.0" val jmhVersion = "1.37" // Mockito 5.x.x requires Java 11 https://github.com/mockito/mockito/releases/tag/v5.0.0 val mockitoVersion = "4.11.0" From 0f6b894f3494065f5601a36b7df282ada13216ae Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 26 Sep 2023 13:23:56 -0500 Subject: [PATCH 020/901] Update dependency com.squareup.wire:wire-bom to v4.9.1 (#5843) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- buildSrc/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts index e4f4bb5d769..1bb924ca1ab 100644 --- a/buildSrc/build.gradle.kts +++ b/buildSrc/build.gradle.kts @@ -42,7 +42,7 @@ repositories { } dependencies { - implementation(enforcedPlatform("com.squareup.wire:wire-bom:4.8.1")) + implementation(enforcedPlatform("com.squareup.wire:wire-bom:4.9.1")) implementation("com.google.auto.value:auto-value-annotations:1.10.4") // When updating, update above in plugins too implementation("com.diffplug.spotless:spotless-plugin-gradle:6.21.0") From 3f4793407d88dab61b39feeceb298b424215629f Mon Sep 17 00:00:00 2001 From: jason plumb <75337021+breedx-splk@users.noreply.github.com> Date: Tue, 26 Sep 2023 11:45:25 -0700 Subject: [PATCH 021/901] Add addAllAttributes() to ReadWriteLogRecord. (#5825) --- .../opentelemetry-sdk-logs.txt | 4 +- .../sdk/logs/ReadWriteLogRecord.java | 19 +++++ .../sdk/logs/ReadWriteLogRecordTest.java | 73 +++++++++++++++++++ .../metrics/SdkDoubleUpDownCounterTest.java | 14 ++++ 4 files changed, 109 insertions(+), 1 deletion(-) create mode 100644 sdk/logs/src/test/java/io/opentelemetry/sdk/logs/ReadWriteLogRecordTest.java diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-logs.txt b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-logs.txt index df26146497b..11010a0b08b 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-logs.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-logs.txt @@ -1,2 +1,4 @@ Comparing source compatibility of against -No changes. \ No newline at end of file +*** MODIFIED INTERFACE: PUBLIC ABSTRACT io.opentelemetry.sdk.logs.ReadWriteLogRecord (not serializable) + === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 + +++ NEW METHOD: PUBLIC(+) io.opentelemetry.sdk.logs.ReadWriteLogRecord setAllAttributes(io.opentelemetry.api.common.Attributes) diff --git a/sdk/logs/src/main/java/io/opentelemetry/sdk/logs/ReadWriteLogRecord.java b/sdk/logs/src/main/java/io/opentelemetry/sdk/logs/ReadWriteLogRecord.java index 8f6701c3adf..d99267d9acd 100644 --- a/sdk/logs/src/main/java/io/opentelemetry/sdk/logs/ReadWriteLogRecord.java +++ b/sdk/logs/src/main/java/io/opentelemetry/sdk/logs/ReadWriteLogRecord.java @@ -6,6 +6,7 @@ package io.opentelemetry.sdk.logs; import io.opentelemetry.api.common.AttributeKey; +import io.opentelemetry.api.common.Attributes; import io.opentelemetry.sdk.logs.data.LogRecordData; /** @@ -25,6 +26,24 @@ public interface ReadWriteLogRecord { // TODO: add additional setters + /** + * Sets attributes to the {@link ReadWriteLogRecord}. If the {@link ReadWriteLogRecord} previously + * contained a mapping for any of the keys, the old values are replaced by the specified values. + * + * @param attributes the attributes + * @return this. + * @since 1.31.0 + */ + @SuppressWarnings("unchecked") + default ReadWriteLogRecord setAllAttributes(Attributes attributes) { + if (attributes == null || attributes.isEmpty()) { + return this; + } + attributes.forEach( + (attributeKey, value) -> this.setAttribute((AttributeKey) attributeKey, value)); + return this; + } + /** Return an immutable {@link LogRecordData} instance representing this log record. */ LogRecordData toLogRecordData(); diff --git a/sdk/logs/src/test/java/io/opentelemetry/sdk/logs/ReadWriteLogRecordTest.java b/sdk/logs/src/test/java/io/opentelemetry/sdk/logs/ReadWriteLogRecordTest.java new file mode 100644 index 00000000000..ccb6c56ebbc --- /dev/null +++ b/sdk/logs/src/test/java/io/opentelemetry/sdk/logs/ReadWriteLogRecordTest.java @@ -0,0 +1,73 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.sdk.logs; + +import static io.opentelemetry.api.common.AttributeKey.stringKey; +import static org.assertj.core.api.Assertions.assertThat; + +import io.opentelemetry.api.common.Attributes; +import io.opentelemetry.api.logs.Severity; +import io.opentelemetry.api.trace.SpanContext; +import io.opentelemetry.sdk.common.InstrumentationScopeInfo; +import io.opentelemetry.sdk.internal.AttributesMap; +import io.opentelemetry.sdk.logs.data.Body; +import io.opentelemetry.sdk.resources.Resource; +import org.junit.jupiter.api.Test; + +class ReadWriteLogRecordTest { + + @Test + void addAllAttributes() { + Attributes newAttributes = Attributes.of(stringKey("foo"), "bar", stringKey("bar"), "buzz"); + SdkReadWriteLogRecord logRecord = buildLogRecord(); + + logRecord.setAllAttributes(newAttributes); + + Attributes result = logRecord.toLogRecordData().getAttributes(); + assertThat(result.get(stringKey("foo"))).isEqualTo("bar"); + assertThat(result.get(stringKey("bar"))).isEqualTo("buzz"); + assertThat(result.get(stringKey("untouched"))).isEqualTo("yes"); + } + + @Test + void addAllHandlesNull() { + SdkReadWriteLogRecord logRecord = buildLogRecord(); + Attributes originalAttributes = logRecord.toLogRecordData().getAttributes(); + ReadWriteLogRecord result = logRecord.setAllAttributes(null); + assertThat(result.toLogRecordData().getAttributes()).isEqualTo(originalAttributes); + } + + @Test + void allHandlesEmpty() { + SdkReadWriteLogRecord logRecord = buildLogRecord(); + Attributes originalAttributes = logRecord.toLogRecordData().getAttributes(); + ReadWriteLogRecord result = logRecord.setAllAttributes(Attributes.empty()); + assertThat(result.toLogRecordData().getAttributes()).isEqualTo(originalAttributes); + } + + SdkReadWriteLogRecord buildLogRecord() { + Body body = Body.string("bod"); + AttributesMap initialAttributes = AttributesMap.create(100, 200); + initialAttributes.put(stringKey("foo"), "aaiosjfjioasdiojfjioasojifja"); + initialAttributes.put(stringKey("untouched"), "yes"); + LogLimits limits = LogLimits.getDefault(); + Resource resource = Resource.empty(); + InstrumentationScopeInfo scope = InstrumentationScopeInfo.create("test"); + SpanContext spanContext = SpanContext.getInvalid(); + + return SdkReadWriteLogRecord.create( + limits, + resource, + scope, + 0L, + 0L, + spanContext, + Severity.DEBUG, + "buggin", + body, + initialAttributes); + } +} diff --git a/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/SdkDoubleUpDownCounterTest.java b/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/SdkDoubleUpDownCounterTest.java index 6b30b2b13a5..a8dc0041c0d 100644 --- a/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/SdkDoubleUpDownCounterTest.java +++ b/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/SdkDoubleUpDownCounterTest.java @@ -254,4 +254,18 @@ void stressTest_WithDifferentLabelSet() { .hasValue(20_000) .hasAttributes(attributeEntry(keys[3], values[3]))))); } + + @Test + void testToString() { + String expected = + "SdkDoubleUpDownCounter{descriptor=InstrumentDescriptor{name=testUpDownCounter, description=description, unit=ms, type=UP_DOWN_COUNTER, valueType=DOUBLE, advice=Advice{explicitBucketBoundaries=null, attributes=null}}}"; + DoubleUpDownCounter counter = + sdkMeter + .upDownCounterBuilder("testUpDownCounter") + .ofDoubles() + .setDescription("description") + .setUnit("ms") + .build(); + assertThat(counter).hasToString(expected); + } } From 6c8f5435db78ac306bfc56218a5a0fab6cf550ab Mon Sep 17 00:00:00 2001 From: jack-berg <34418638+jack-berg@users.noreply.github.com> Date: Tue, 26 Sep 2023 15:37:28 -0500 Subject: [PATCH 022/901] Cleanup a few typos (#5855) --- .../sdk/metrics/export/MetricExporter.java | 2 +- .../sdk/metrics/export/MetricReader.java | 2 +- .../internal/state/ArrayBasedStack.java | 3 +- .../internal/state/MutableMeasurement.java | 2 +- .../metrics/internal/state/ObjectPool.java | 2 +- .../metrics/internal/state/PooledHashMap.java | 2 +- .../DoubleLastValueAggregatorTest.java | 11 +++--- .../aggregator/DoubleSumAggregatorTest.java | 19 +++++---- .../LongLastValueAggregatorTest.java | 16 +++----- .../aggregator/LongSumAggregatorTest.java | 26 ++++++------- .../state/AsynchronousMetricStorageTest.java | 2 +- .../internal/state/PooledHashMapTest.java | 39 ++++++++++--------- sdk/metrics/testing-internal/build.gradle.kts | 13 ------- .../exporter/InMemoryMetricReader.java | 2 +- .../exporter/InMemoryMetricReaderBuilder.java | 18 ++++++++- 15 files changed, 77 insertions(+), 82 deletions(-) delete mode 100644 sdk/metrics/testing-internal/build.gradle.kts diff --git a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/export/MetricExporter.java b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/export/MetricExporter.java index f4f8f569055..685c5f09bf1 100644 --- a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/export/MetricExporter.java +++ b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/export/MetricExporter.java @@ -45,7 +45,7 @@ default Aggregation getDefaultAggregation(InstrumentType instrumentType) { * Returns the memory mode used by this exporter's associated reader. * * @return The {@link MemoryMode} used by this exporter's associated reader - * @since 1.29.0 + * @since 1.31.0 */ default MemoryMode getMemoryMode() { return IMMUTABLE_DATA; diff --git a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/export/MetricReader.java b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/export/MetricReader.java index 0b0fb974d78..4ff4155f9bd 100644 --- a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/export/MetricReader.java +++ b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/export/MetricReader.java @@ -51,7 +51,7 @@ default Aggregation getDefaultAggregation(InstrumentType instrumentType) { * Returns the memory mode used by this reader. * * @return The {@link MemoryMode} used by this instance - * @since 1.29.0 + * @since 1.31.0 */ default MemoryMode getMemoryMode() { return IMMUTABLE_DATA; diff --git a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/state/ArrayBasedStack.java b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/state/ArrayBasedStack.java index 627955b3403..907ec7e2234 100644 --- a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/state/ArrayBasedStack.java +++ b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/state/ArrayBasedStack.java @@ -15,7 +15,8 @@ * *

    This class is not thread-safe. */ -public class ArrayBasedStack { +public final class ArrayBasedStack { + // Visible for test static final int DEFAULT_CAPACITY = 10; // NOTE (asafm): Using native array instead of ArrayList since I plan to add eviction diff --git a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/state/MutableMeasurement.java b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/state/MutableMeasurement.java index 9c88712d487..7bac8202447 100644 --- a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/state/MutableMeasurement.java +++ b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/state/MutableMeasurement.java @@ -15,7 +15,7 @@ * *

    This class is not thread-safe. */ -public class MutableMeasurement implements Measurement { +public final class MutableMeasurement implements Measurement { static void setDoubleMeasurement( MutableMeasurement mutableMeasurement, diff --git a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/state/ObjectPool.java b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/state/ObjectPool.java index 3a129613d87..8be6abcb5dd 100644 --- a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/state/ObjectPool.java +++ b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/state/ObjectPool.java @@ -20,7 +20,7 @@ * *

    This class is not thread-safe. */ -public class ObjectPool { +public final class ObjectPool { private final ArrayBasedStack pool; private final Supplier objectCreator; diff --git a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/state/PooledHashMap.java b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/state/PooledHashMap.java index 452ed9d50ea..2a9bfd8cc6b 100644 --- a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/state/PooledHashMap.java +++ b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/state/PooledHashMap.java @@ -35,7 +35,7 @@ * @param The map value type */ @SuppressWarnings("ForLoopReplaceableByForEach") -public class PooledHashMap implements Map { +public final class PooledHashMap implements Map { private static final int DEFAULT_CAPACITY = 16; private static final float LOAD_FACTOR = 0.75f; diff --git a/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/internal/aggregator/DoubleLastValueAggregatorTest.java b/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/internal/aggregator/DoubleLastValueAggregatorTest.java index fa0dd75caa4..5f7a276e1e9 100644 --- a/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/internal/aggregator/DoubleLastValueAggregatorTest.java +++ b/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/internal/aggregator/DoubleLastValueAggregatorTest.java @@ -6,6 +6,7 @@ package io.opentelemetry.sdk.metrics.internal.aggregator; import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.assertThat; +import static org.assertj.core.api.Assertions.assertThat; import io.opentelemetry.api.common.AttributeKey; import io.opentelemetry.api.common.Attributes; @@ -25,7 +26,6 @@ import io.opentelemetry.sdk.resources.Resource; import java.util.Collections; import java.util.List; -import org.assertj.core.api.Assertions; import org.junit.jupiter.api.Test; /** Unit tests for {@link AggregatorHandle}. */ @@ -194,12 +194,11 @@ void copyPoint() { aggregator.copyPoint(pointData, toPointData); - Assertions.assertThat(toPointData.getStartEpochNanos()) - .isEqualTo(pointData.getStartEpochNanos()); - Assertions.assertThat(toPointData.getEpochNanos()).isEqualTo(pointData.getEpochNanos()); + assertThat(toPointData.getStartEpochNanos()).isEqualTo(pointData.getStartEpochNanos()); + assertThat(toPointData.getEpochNanos()).isEqualTo(pointData.getEpochNanos()); assertThat(toPointData.getAttributes()).isEqualTo(pointData.getAttributes()); - Assertions.assertThat(toPointData.getValue()).isEqualTo(pointData.getValue()); - Assertions.assertThat(toPointData.getExemplars()).isEqualTo(pointData.getExemplars()); + assertThat(toPointData.getValue()).isEqualTo(pointData.getValue()); + assertThat(toPointData.getExemplars()).isEqualTo(pointData.getExemplars()); } @Test diff --git a/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/internal/aggregator/DoubleSumAggregatorTest.java b/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/internal/aggregator/DoubleSumAggregatorTest.java index 06651798bf2..edd1f0fc077 100644 --- a/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/internal/aggregator/DoubleSumAggregatorTest.java +++ b/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/internal/aggregator/DoubleSumAggregatorTest.java @@ -6,6 +6,7 @@ package io.opentelemetry.sdk.metrics.internal.aggregator; import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.assertThat; +import static org.assertj.core.api.Assertions.assertThat; import io.opentelemetry.api.common.AttributeKey; import io.opentelemetry.api.common.Attributes; @@ -30,7 +31,6 @@ import io.opentelemetry.sdk.resources.Resource; import java.util.Collections; import java.util.List; -import org.assertj.core.api.Assertions; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.Mock; @@ -228,11 +228,11 @@ void diffInPlace() { aggregator.diffInPlace(previous, current); /* Assert that latest measurement is kept and set on {@code previous} */ - Assertions.assertThat(previous.getStartEpochNanos()).isEqualTo(current.getStartEpochNanos()); - Assertions.assertThat(previous.getEpochNanos()).isEqualTo(current.getEpochNanos()); + assertThat(previous.getStartEpochNanos()).isEqualTo(current.getStartEpochNanos()); + assertThat(previous.getEpochNanos()).isEqualTo(current.getEpochNanos()); assertThat(previous.getAttributes()).isEqualTo(current.getAttributes()); - Assertions.assertThat(previous.getValue()).isEqualTo(2); - Assertions.assertThat(previous.getExemplars()).isEqualTo(exemplars); + assertThat(previous.getValue()).isEqualTo(2); + assertThat(previous.getExemplars()).isEqualTo(exemplars); } @Test @@ -271,12 +271,11 @@ void copyPoint() { aggregator.copyPoint(pointData, toPointData); - Assertions.assertThat(toPointData.getStartEpochNanos()) - .isEqualTo(pointData.getStartEpochNanos()); - Assertions.assertThat(toPointData.getEpochNanos()).isEqualTo(pointData.getEpochNanos()); + assertThat(toPointData.getStartEpochNanos()).isEqualTo(pointData.getStartEpochNanos()); + assertThat(toPointData.getEpochNanos()).isEqualTo(pointData.getEpochNanos()); assertThat(toPointData.getAttributes()).isEqualTo(pointData.getAttributes()); - Assertions.assertThat(toPointData.getValue()).isEqualTo(pointData.getValue()); - Assertions.assertThat(toPointData.getExemplars()).isEqualTo(pointData.getExemplars()); + assertThat(toPointData.getValue()).isEqualTo(pointData.getValue()); + assertThat(toPointData.getExemplars()).isEqualTo(pointData.getExemplars()); } @Test diff --git a/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/internal/aggregator/LongLastValueAggregatorTest.java b/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/internal/aggregator/LongLastValueAggregatorTest.java index e7d4140309f..0ac5104898f 100644 --- a/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/internal/aggregator/LongLastValueAggregatorTest.java +++ b/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/internal/aggregator/LongLastValueAggregatorTest.java @@ -25,10 +25,8 @@ import io.opentelemetry.sdk.metrics.internal.descriptor.MetricDescriptor; import io.opentelemetry.sdk.metrics.internal.exemplar.ExemplarReservoir; import io.opentelemetry.sdk.resources.Resource; -import io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions; import java.util.Collections; import java.util.List; -import org.assertj.core.api.Assertions; import org.junit.jupiter.api.Test; /** Unit tests for {@link LongLastValueAggregator}. */ @@ -120,7 +118,7 @@ void diffInPlace() { /* Assert that latest measurement is kept and set on {@code previous} */ assertThat(previous.getStartEpochNanos()).isEqualTo(0); assertThat(previous.getEpochNanos()).isEqualTo(1); - OpenTelemetryAssertions.assertThat(previous.getAttributes()).isEqualTo(Attributes.empty()); + assertThat(previous.getAttributes()).isEqualTo(Attributes.empty()); assertThat(previous.getValue()).isEqualTo(2); assertThat(previous.getExemplars()).isEqualTo(exemplars); } @@ -161,13 +159,11 @@ void copyPoint() { aggregator.copyPoint(pointData, toPointData); - Assertions.assertThat(toPointData.getStartEpochNanos()) - .isEqualTo(pointData.getStartEpochNanos()); - Assertions.assertThat(toPointData.getEpochNanos()).isEqualTo(pointData.getEpochNanos()); - OpenTelemetryAssertions.assertThat(toPointData.getAttributes()) - .isEqualTo(pointData.getAttributes()); - Assertions.assertThat(toPointData.getValue()).isEqualTo(pointData.getValue()); - Assertions.assertThat(toPointData.getExemplars()).isEqualTo(pointData.getExemplars()); + assertThat(toPointData.getStartEpochNanos()).isEqualTo(pointData.getStartEpochNanos()); + assertThat(toPointData.getEpochNanos()).isEqualTo(pointData.getEpochNanos()); + assertThat(toPointData.getAttributes()).isEqualTo(pointData.getAttributes()); + assertThat(toPointData.getValue()).isEqualTo(pointData.getValue()); + assertThat(toPointData.getExemplars()).isEqualTo(pointData.getExemplars()); } @Test diff --git a/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/internal/aggregator/LongSumAggregatorTest.java b/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/internal/aggregator/LongSumAggregatorTest.java index 81e6f40a8b7..11b98233b07 100644 --- a/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/internal/aggregator/LongSumAggregatorTest.java +++ b/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/internal/aggregator/LongSumAggregatorTest.java @@ -6,6 +6,7 @@ package io.opentelemetry.sdk.metrics.internal.aggregator; import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.assertThat; +import static org.assertj.core.api.Assertions.assertThat; import io.opentelemetry.api.common.AttributeKey; import io.opentelemetry.api.common.Attributes; @@ -28,10 +29,8 @@ import io.opentelemetry.sdk.metrics.internal.descriptor.MetricDescriptor; import io.opentelemetry.sdk.metrics.internal.exemplar.ExemplarReservoir; import io.opentelemetry.sdk.resources.Resource; -import io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions; import java.util.Collections; import java.util.List; -import org.assertj.core.api.Assertions; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.Mock; @@ -223,11 +222,11 @@ void diffInPlace() { aggregator.diffInPlace(previous, current); /* Assert that latest measurement is kept and set on {@code previous} */ - Assertions.assertThat(previous.getStartEpochNanos()).isEqualTo(current.getStartEpochNanos()); - Assertions.assertThat(previous.getEpochNanos()).isEqualTo(current.getEpochNanos()); - OpenTelemetryAssertions.assertThat(previous.getAttributes()).isEqualTo(current.getAttributes()); - Assertions.assertThat(previous.getValue()).isEqualTo(2); - Assertions.assertThat(previous.getExemplars()).isEqualTo(current.getExemplars()); + assertThat(previous.getStartEpochNanos()).isEqualTo(current.getStartEpochNanos()); + assertThat(previous.getEpochNanos()).isEqualTo(current.getEpochNanos()); + assertThat(previous.getAttributes()).isEqualTo(current.getAttributes()); + assertThat(previous.getValue()).isEqualTo(2); + assertThat(previous.getExemplars()).isEqualTo(current.getExemplars()); } @Test @@ -266,17 +265,14 @@ void copyPoint() { aggregator.copyPoint(pointData, toPointData); - Assertions.assertThat(toPointData.getStartEpochNanos()) - .isEqualTo(pointData.getStartEpochNanos()); - Assertions.assertThat(toPointData.getEpochNanos()).isEqualTo(pointData.getEpochNanos()); - OpenTelemetryAssertions.assertThat(toPointData.getAttributes()) - .isEqualTo(pointData.getAttributes()); - Assertions.assertThat(toPointData.getValue()).isEqualTo(pointData.getValue()); - Assertions.assertThat(toPointData.getExemplars()).isEqualTo(pointData.getExemplars()); + assertThat(toPointData.getStartEpochNanos()).isEqualTo(pointData.getStartEpochNanos()); + assertThat(toPointData.getEpochNanos()).isEqualTo(pointData.getEpochNanos()); + assertThat(toPointData.getAttributes()).isEqualTo(pointData.getAttributes()); + assertThat(toPointData.getValue()).isEqualTo(pointData.getValue()); + assertThat(toPointData.getExemplars()).isEqualTo(pointData.getExemplars()); } @Test - @SuppressWarnings("unchecked") void toMetricData() { AggregatorHandle aggregatorHandle = aggregator.createHandle(); aggregatorHandle.recordLong(10); diff --git a/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/internal/state/AsynchronousMetricStorageTest.java b/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/internal/state/AsynchronousMetricStorageTest.java index 109b8eef7a4..23c45a9349f 100644 --- a/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/internal/state/AsynchronousMetricStorageTest.java +++ b/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/internal/state/AsynchronousMetricStorageTest.java @@ -378,7 +378,7 @@ void collect_DeltaComputesDiff(MemoryMode memoryMode) { } @Test - public void collect_reusableData_reusedObjectsAreReturnedOnSecondCall() { + void collect_reusableData_reusedObjectsAreReturnedOnSecondCall() { setup(REUSABLE_DATA); longCounterStorage.record(createLong(0, 1, 1, Attributes.builder().put("key", "a").build())); diff --git a/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/internal/state/PooledHashMapTest.java b/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/internal/state/PooledHashMapTest.java index f53aec03f90..0e4a5ab0328 100644 --- a/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/internal/state/PooledHashMapTest.java +++ b/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/internal/state/PooledHashMapTest.java @@ -5,71 +5,72 @@ package io.opentelemetry.sdk.metrics.internal.state; +import static org.assertj.core.api.Assertions.assertThat; + import java.util.HashMap; import java.util.Map; -import org.assertj.core.api.Assertions; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; -public class PooledHashMapTest { +class PooledHashMapTest { private PooledHashMap map; @BeforeEach - public void setup() { + void setup() { map = new PooledHashMap<>(); } @Test - public void putAndGetTest() { + void putAndGetTest() { map.put("One", 1); - Assertions.assertThat(map.get("One")).isEqualTo(1); + assertThat(map.get("One")).isEqualTo(1); } @Test - public void removeTest() { + void removeTest() { map.put("One", 1); map.remove("One"); - Assertions.assertThat(map.get("One")).isNull(); + assertThat(map.get("One")).isNull(); } @Test - public void sizeTest() { + void sizeTest() { map.put("One", 1); map.put("Two", 2); - Assertions.assertThat(map.size()).isEqualTo(2); + assertThat(map.size()).isEqualTo(2); } @Test - public void isEmptyTest() { - Assertions.assertThat(map.isEmpty()).isTrue(); + void isEmptyTest() { + assertThat(map.isEmpty()).isTrue(); map.put("One", 1); - Assertions.assertThat(map.isEmpty()).isFalse(); + assertThat(map.isEmpty()).isFalse(); } @Test - public void containsKeyTest() { + void containsKeyTest() { map.put("One", 1); - Assertions.assertThat(map.containsKey("One")).isTrue(); - Assertions.assertThat(map.containsKey("Two")).isFalse(); + assertThat(map.containsKey("One")).isTrue(); + assertThat(map.containsKey("Two")).isFalse(); } @Test - public void clearTest() { + void clearTest() { map.put("One", 1); map.put("Two", 2); map.clear(); - Assertions.assertThat(map.isEmpty()).isTrue(); + assertThat(map.isEmpty()).isTrue(); } @Test - public void forEachTest() { + void forEachTest() { map.put("One", 1); map.put("Two", 2); Map actualMap = new HashMap<>(); map.forEach(actualMap::put); - Assertions.assertThat(actualMap).containsOnlyKeys("One", "Two").containsValues(1, 2); + assertThat(actualMap).containsOnlyKeys("One", "Two").containsValues(1, 2); } } diff --git a/sdk/metrics/testing-internal/build.gradle.kts b/sdk/metrics/testing-internal/build.gradle.kts deleted file mode 100644 index df76bebe8fb..00000000000 --- a/sdk/metrics/testing-internal/build.gradle.kts +++ /dev/null @@ -1,13 +0,0 @@ -plugins { - id("otel.java-conventions") -} - -description = "OpenTelemetry Metrics Testing (Internal)" -otelJava.moduleName.set("io.opentelemetry.metrics.internal.testing") - -dependencies { - api("org.junit.jupiter:junit-jupiter-api") - implementation("org.slf4j:jul-to-slf4j") - api(project(":sdk:common")) - api(project(":sdk:metrics")) -} diff --git a/sdk/testing/src/main/java/io/opentelemetry/sdk/testing/exporter/InMemoryMetricReader.java b/sdk/testing/src/main/java/io/opentelemetry/sdk/testing/exporter/InMemoryMetricReader.java index d9aa8bfb3c5..e72a78c52ee 100644 --- a/sdk/testing/src/main/java/io/opentelemetry/sdk/testing/exporter/InMemoryMetricReader.java +++ b/sdk/testing/src/main/java/io/opentelemetry/sdk/testing/exporter/InMemoryMetricReader.java @@ -62,7 +62,7 @@ public class InMemoryMetricReader implements MetricReader { * * @return a builder with always-cumulative {@link AggregationTemporalitySelector}, default {@link * DefaultAggregationSelector} and {@link MemoryMode#IMMUTABLE_DATA} {@link MemoryMode} - * @since 1.29.0 + * @since 1.31.0 */ public static InMemoryMetricReaderBuilder builder() { return new InMemoryMetricReaderBuilder(); diff --git a/sdk/testing/src/main/java/io/opentelemetry/sdk/testing/exporter/InMemoryMetricReaderBuilder.java b/sdk/testing/src/main/java/io/opentelemetry/sdk/testing/exporter/InMemoryMetricReaderBuilder.java index e3824e6cae7..8a0c934bb2d 100644 --- a/sdk/testing/src/main/java/io/opentelemetry/sdk/testing/exporter/InMemoryMetricReaderBuilder.java +++ b/sdk/testing/src/main/java/io/opentelemetry/sdk/testing/exporter/InMemoryMetricReaderBuilder.java @@ -8,9 +8,16 @@ import static io.opentelemetry.sdk.common.export.MemoryMode.IMMUTABLE_DATA; import io.opentelemetry.sdk.common.export.MemoryMode; +import io.opentelemetry.sdk.metrics.InstrumentType; import io.opentelemetry.sdk.metrics.export.AggregationTemporalitySelector; import io.opentelemetry.sdk.metrics.export.DefaultAggregationSelector; +import io.opentelemetry.sdk.metrics.export.MetricExporter; +/** + * Builder for {@link InMemoryMetricReader}. + * + * @since 1.31.0 + */ public final class InMemoryMetricReaderBuilder { private AggregationTemporalitySelector aggregationTemporalitySelector = AggregationTemporalitySelector.alwaysCumulative(); @@ -26,6 +33,13 @@ public final class InMemoryMetricReaderBuilder { */ InMemoryMetricReaderBuilder() {} + /** + * Sets the {@link AggregationTemporalitySelector} used by {@link + * MetricExporter#getAggregationTemporality(InstrumentType)}. + * + * @param aggregationTemporalitySelector the {@link AggregationTemporalitySelector} to set + * @return this {@link InMemoryMetricReaderBuilder} + */ public InMemoryMetricReaderBuilder setAggregationTemporalitySelector( AggregationTemporalitySelector aggregationTemporalitySelector) { this.aggregationTemporalitySelector = aggregationTemporalitySelector; @@ -33,7 +47,8 @@ public InMemoryMetricReaderBuilder setAggregationTemporalitySelector( } /** - * Sets the {@link DefaultAggregationSelector}. + * Sets the {@link DefaultAggregationSelector} used by {@link + * MetricExporter#getDefaultAggregation(InstrumentType)}. * * @param defaultAggregationSelector the {@link DefaultAggregationSelector} to set * @return this {@link InMemoryMetricReaderBuilder} @@ -56,6 +71,7 @@ public InMemoryMetricReaderBuilder setMemoryMode(MemoryMode memoryMode) { return this; } + /** Constructs a {@link InMemoryMetricReader} based on the builder's values. */ public InMemoryMetricReader build() { return new InMemoryMetricReader( aggregationTemporalitySelector, defaultAggregationSelector, memoryMode); From f421ef1e73906f6332f4a5ab39698b00efb4525c Mon Sep 17 00:00:00 2001 From: jack-berg <34418638+jack-berg@users.noreply.github.com> Date: Wed, 27 Sep 2023 13:55:41 -0500 Subject: [PATCH 023/901] Stabilize MetricProducer, allow custom MetricReaders (#5835) --- .../opentelemetry-sdk-metrics.txt | 11 ++++ .../prometheus/PrometheusHttpServer.java | 17 ++---- .../prometheus/PrometheusHttpServerTest.java | 12 +++- .../OpenCensusMetricProducer.java | 53 +++++++++++++++++ .../metrics/MultiMetricProducer.java | 30 ---------- .../OpenCensusAttachingMetricReader.java | 49 ---------------- .../metrics/OpenCensusMetricProducer.java | 58 ------------------- .../metrics/OpenCensusMetrics.java | 23 -------- .../metrics/OpenCensusMetricProducerTest.java | 8 +-- .../metrics/OpenCensusMetricsTest.java | 8 ++- .../sdk/OpenTelemetrySdkTest.java | 1 + .../sdk/metrics/SdkMeterProvider.java | 44 ++++++++++++-- .../sdk/metrics/SdkMeterProviderBuilder.java | 21 +++++-- .../export/CollectionRegistration.java | 32 +++++++++- .../sdk/metrics/export/MetricProducer.java | 42 ++++++++++++++ .../sdk/metrics/export/MetricReader.java | 11 +--- .../metrics/export/PeriodicMetricReader.java | 9 ++- .../internal/export/MetricProducer.java | 54 ----------------- .../internal/export/RegisteredReader.java | 1 + .../export/PeriodicMetricReaderTest.java | 25 ++++---- .../exporter/InMemoryMetricReader.java | 9 ++- 21 files changed, 242 insertions(+), 276 deletions(-) create mode 100644 opencensus-shim/src/main/java/io/opentelemetry/opencensusshim/OpenCensusMetricProducer.java delete mode 100644 opencensus-shim/src/main/java/io/opentelemetry/opencensusshim/metrics/MultiMetricProducer.java delete mode 100644 opencensus-shim/src/main/java/io/opentelemetry/opencensusshim/metrics/OpenCensusAttachingMetricReader.java delete mode 100644 opencensus-shim/src/main/java/io/opentelemetry/opencensusshim/metrics/OpenCensusMetricProducer.java delete mode 100644 opencensus-shim/src/main/java/io/opentelemetry/opencensusshim/metrics/OpenCensusMetrics.java create mode 100644 sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/export/MetricProducer.java delete mode 100644 sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/export/MetricProducer.java diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-metrics.txt b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-metrics.txt index 5753f2fee9b..6cf519e2823 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-metrics.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-metrics.txt @@ -1,10 +1,21 @@ Comparing source compatibility of against +*** MODIFIED INTERFACE: PUBLIC ABSTRACT io.opentelemetry.sdk.metrics.export.CollectionRegistration (not serializable) + === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 + +++ NEW METHOD: PUBLIC(+) java.util.Collection collectAllMetrics() + +++ NEW METHOD: PUBLIC(+) STATIC(+) io.opentelemetry.sdk.metrics.export.CollectionRegistration noop() *** MODIFIED INTERFACE: PUBLIC ABSTRACT io.opentelemetry.sdk.metrics.export.MetricExporter (not serializable) === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 +++ NEW METHOD: PUBLIC(+) io.opentelemetry.sdk.common.export.MemoryMode getMemoryMode() ++++ NEW INTERFACE: PUBLIC(+) ABSTRACT(+) io.opentelemetry.sdk.metrics.export.MetricProducer (not serializable) + +++ CLASS FILE FORMAT VERSION: 52.0 <- n.a. + +++ NEW SUPERCLASS: java.lang.Object + +++ NEW METHOD: PUBLIC(+) ABSTRACT(+) java.util.Collection produce(io.opentelemetry.sdk.resources.Resource) *** MODIFIED INTERFACE: PUBLIC ABSTRACT io.opentelemetry.sdk.metrics.export.MetricReader (not serializable) === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 +++ NEW METHOD: PUBLIC(+) io.opentelemetry.sdk.common.export.MemoryMode getMemoryMode() *** MODIFIED CLASS: PUBLIC FINAL io.opentelemetry.sdk.metrics.export.PeriodicMetricReader (not serializable) === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 +++ NEW METHOD: PUBLIC(+) io.opentelemetry.sdk.common.export.MemoryMode getMemoryMode() +*** MODIFIED CLASS: PUBLIC FINAL io.opentelemetry.sdk.metrics.SdkMeterProviderBuilder (not serializable) + === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 + +++ NEW METHOD: PUBLIC(+) io.opentelemetry.sdk.metrics.SdkMeterProviderBuilder registerMetricProducer(io.opentelemetry.sdk.metrics.export.MetricProducer) diff --git a/exporters/prometheus/src/main/java/io/opentelemetry/exporter/prometheus/PrometheusHttpServer.java b/exporters/prometheus/src/main/java/io/opentelemetry/exporter/prometheus/PrometheusHttpServer.java index cd8f22b1cde..cf1515a645e 100644 --- a/exporters/prometheus/src/main/java/io/opentelemetry/exporter/prometheus/PrometheusHttpServer.java +++ b/exporters/prometheus/src/main/java/io/opentelemetry/exporter/prometheus/PrometheusHttpServer.java @@ -22,7 +22,6 @@ import io.opentelemetry.sdk.metrics.data.MetricData; import io.opentelemetry.sdk.metrics.export.CollectionRegistration; import io.opentelemetry.sdk.metrics.export.MetricReader; -import io.opentelemetry.sdk.metrics.internal.export.MetricProducer; import java.io.IOException; import java.io.OutputStream; import java.io.UncheckedIOException; @@ -60,7 +59,7 @@ public final class PrometheusHttpServer implements MetricReader { private final HttpServer server; private final ExecutorService executor; - private volatile MetricProducer metricProducer = MetricProducer.noop(); + private volatile CollectionRegistration collectionRegistration = CollectionRegistration.noop(); /** * Returns a new {@link PrometheusHttpServer} which can be registered to an {@link @@ -83,7 +82,7 @@ public static PrometheusHttpServerBuilder builder() { throw new UncheckedIOException("Could not create Prometheus HTTP server", e); } MetricsHandler metricsHandler = - new MetricsHandler(() -> getMetricProducer().collectAllMetrics()); + new MetricsHandler(() -> collectionRegistration.collectAllMetrics()); server.createContext("/", metricsHandler); server.createContext("/metrics", metricsHandler); server.createContext("/-/healthy", HealthHandler.INSTANCE); @@ -110,10 +109,6 @@ private static HttpServer createServer(String host, int port) throws IOException throw exception; } - private MetricProducer getMetricProducer() { - return metricProducer; - } - private void start() { // server.start must be called from a daemon thread for it to be a daemon. if (Thread.currentThread().isDaemon()) { @@ -131,13 +126,13 @@ private void start() { } @Override - public void register(CollectionRegistration registration) { - this.metricProducer = MetricProducer.asMetricProducer(registration); + public AggregationTemporality getAggregationTemporality(InstrumentType instrumentType) { + return AggregationTemporality.CUMULATIVE; } @Override - public AggregationTemporality getAggregationTemporality(InstrumentType instrumentType) { - return AggregationTemporality.CUMULATIVE; + public void register(CollectionRegistration registration) { + this.collectionRegistration = registration; } @Override diff --git a/exporters/prometheus/src/test/java/io/opentelemetry/exporter/prometheus/PrometheusHttpServerTest.java b/exporters/prometheus/src/test/java/io/opentelemetry/exporter/prometheus/PrometheusHttpServerTest.java index c6b5cd8d086..cbda79c4183 100644 --- a/exporters/prometheus/src/test/java/io/opentelemetry/exporter/prometheus/PrometheusHttpServerTest.java +++ b/exporters/prometheus/src/test/java/io/opentelemetry/exporter/prometheus/PrometheusHttpServerTest.java @@ -26,17 +26,18 @@ import io.opentelemetry.sdk.common.InstrumentationScopeInfo; import io.opentelemetry.sdk.metrics.data.AggregationTemporality; import io.opentelemetry.sdk.metrics.data.MetricData; +import io.opentelemetry.sdk.metrics.export.CollectionRegistration; import io.opentelemetry.sdk.metrics.internal.data.ImmutableDoublePointData; import io.opentelemetry.sdk.metrics.internal.data.ImmutableGaugeData; import io.opentelemetry.sdk.metrics.internal.data.ImmutableLongPointData; import io.opentelemetry.sdk.metrics.internal.data.ImmutableMetricData; import io.opentelemetry.sdk.metrics.internal.data.ImmutableSumData; -import io.opentelemetry.sdk.metrics.internal.export.MetricProducer; import io.opentelemetry.sdk.resources.Resource; import java.io.ByteArrayInputStream; import java.io.IOException; import java.net.ServerSocket; import java.nio.charset.StandardCharsets; +import java.util.Collection; import java.util.Collections; import java.util.List; import java.util.concurrent.Executors; @@ -56,7 +57,6 @@ class PrometheusHttpServerTest { private static final AtomicReference> metricData = new AtomicReference<>(); - private static final MetricProducer metricProducer = metricData::get; static PrometheusHttpServer prometheusServer; static WebClient client; @@ -68,7 +68,13 @@ class PrometheusHttpServerTest { static void beforeAll() { // Register the SDK metric producer with the prometheus reader. prometheusServer = PrometheusHttpServer.builder().setHost("localhost").setPort(0).build(); - prometheusServer.register(metricProducer); + prometheusServer.register( + new CollectionRegistration() { + @Override + public Collection collectAllMetrics() { + return metricData.get(); + } + }); client = WebClient.builder("http://localhost:" + prometheusServer.getAddress().getPort()) diff --git a/opencensus-shim/src/main/java/io/opentelemetry/opencensusshim/OpenCensusMetricProducer.java b/opencensus-shim/src/main/java/io/opentelemetry/opencensusshim/OpenCensusMetricProducer.java new file mode 100644 index 00000000000..9a2e29a2bc2 --- /dev/null +++ b/opencensus-shim/src/main/java/io/opentelemetry/opencensusshim/OpenCensusMetricProducer.java @@ -0,0 +1,53 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.opencensusshim; + +import io.opencensus.metrics.Metrics; +import io.opencensus.metrics.export.MetricProducerManager; +import io.opentelemetry.opencensusshim.internal.metrics.MetricAdapter; +import io.opentelemetry.sdk.metrics.SdkMeterProviderBuilder; +import io.opentelemetry.sdk.metrics.data.MetricData; +import io.opentelemetry.sdk.metrics.export.MetricProducer; +import io.opentelemetry.sdk.metrics.export.MetricReader; +import io.opentelemetry.sdk.resources.Resource; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +/** + * {@link MetricProducer} for OpenCensus metrics, which allows {@link MetricReader}s to read from + * both OpenTelemetry and OpenCensus metrics. + * + *

    To use, register with {@link SdkMeterProviderBuilder#registerMetricProducer(MetricProducer)}. + */ +public final class OpenCensusMetricProducer implements MetricProducer { + private final MetricProducerManager openCensusMetricStorage; + + OpenCensusMetricProducer(MetricProducerManager openCensusMetricStorage) { + this.openCensusMetricStorage = openCensusMetricStorage; + } + + /** + * Constructs a new {@link OpenCensusMetricProducer} that reports against the given {@link + * Resource}. + */ + public static MetricProducer create() { + return new OpenCensusMetricProducer(Metrics.getExportComponent().getMetricProducerManager()); + } + + @Override + public Collection produce(Resource resource) { + List result = new ArrayList<>(); + openCensusMetricStorage + .getAllMetricProducer() + .forEach( + producer -> + producer + .getMetrics() + .forEach(metric -> result.add(MetricAdapter.convert(resource, metric)))); + return result; + } +} diff --git a/opencensus-shim/src/main/java/io/opentelemetry/opencensusshim/metrics/MultiMetricProducer.java b/opencensus-shim/src/main/java/io/opentelemetry/opencensusshim/metrics/MultiMetricProducer.java deleted file mode 100644 index a2494faf783..00000000000 --- a/opencensus-shim/src/main/java/io/opentelemetry/opencensusshim/metrics/MultiMetricProducer.java +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package io.opentelemetry.opencensusshim.metrics; - -import io.opentelemetry.sdk.metrics.data.MetricData; -import io.opentelemetry.sdk.metrics.internal.export.MetricProducer; -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; - -/** Class that wraps multiple metric producers into one. */ -final class MultiMetricProducer implements MetricProducer { - private final Collection producers; - - public MultiMetricProducer(Collection producers) { - this.producers = producers; - } - - @Override - public Collection collectAllMetrics() { - List result = new ArrayList<>(); - for (MetricProducer p : producers) { - result.addAll(p.collectAllMetrics()); - } - return result; - } -} diff --git a/opencensus-shim/src/main/java/io/opentelemetry/opencensusshim/metrics/OpenCensusAttachingMetricReader.java b/opencensus-shim/src/main/java/io/opentelemetry/opencensusshim/metrics/OpenCensusAttachingMetricReader.java deleted file mode 100644 index 46e0f9534c2..00000000000 --- a/opencensus-shim/src/main/java/io/opentelemetry/opencensusshim/metrics/OpenCensusAttachingMetricReader.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package io.opentelemetry.opencensusshim.metrics; - -import io.opentelemetry.sdk.common.CompletableResultCode; -import io.opentelemetry.sdk.metrics.InstrumentType; -import io.opentelemetry.sdk.metrics.data.AggregationTemporality; -import io.opentelemetry.sdk.metrics.export.CollectionRegistration; -import io.opentelemetry.sdk.metrics.export.MetricReader; -import io.opentelemetry.sdk.metrics.internal.export.MetricProducer; -import io.opentelemetry.sdk.resources.Resource; -import java.util.Arrays; - -/** {@link MetricReader} that appends OpenCensus metrics to anything read. */ -final class OpenCensusAttachingMetricReader implements MetricReader { - private final MetricReader adapted; - - OpenCensusAttachingMetricReader(MetricReader adapted) { - this.adapted = adapted; - } - - @Override - public void register(CollectionRegistration registration) { - // TODO: Find a way to pull the resource off of the SDK. - adapted.register( - new MultiMetricProducer( - Arrays.asList( - MetricProducer.asMetricProducer(registration), - OpenCensusMetricProducer.create(Resource.getDefault())))); - } - - @Override - public AggregationTemporality getAggregationTemporality(InstrumentType instrumentType) { - return adapted.getAggregationTemporality(instrumentType); - } - - @Override - public CompletableResultCode forceFlush() { - return adapted.forceFlush(); - } - - @Override - public CompletableResultCode shutdown() { - return adapted.shutdown(); - } -} diff --git a/opencensus-shim/src/main/java/io/opentelemetry/opencensusshim/metrics/OpenCensusMetricProducer.java b/opencensus-shim/src/main/java/io/opentelemetry/opencensusshim/metrics/OpenCensusMetricProducer.java deleted file mode 100644 index 77af7ecf5ee..00000000000 --- a/opencensus-shim/src/main/java/io/opentelemetry/opencensusshim/metrics/OpenCensusMetricProducer.java +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package io.opentelemetry.opencensusshim.metrics; - -import io.opencensus.metrics.Metrics; -import io.opencensus.metrics.export.MetricProducerManager; -import io.opentelemetry.opencensusshim.internal.metrics.MetricAdapter; -import io.opentelemetry.sdk.metrics.SdkMeterProvider; -import io.opentelemetry.sdk.metrics.data.MetricData; -import io.opentelemetry.sdk.metrics.export.MetricReader; -import io.opentelemetry.sdk.metrics.internal.export.MetricProducer; -import io.opentelemetry.sdk.resources.Resource; -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; - -/** - * A producer instance of OpenCensus metrics. - * - *

    The idea here is we can register a merged {@link MetricProducer} combining this with the - * {@link SdkMeterProvider} producer with a {@link MetricReader}, allowing the reader to pull - * metrics from both OpenTelemetry and OpenCensus backends. - */ -final class OpenCensusMetricProducer implements MetricProducer { - private final Resource resource; - private final MetricProducerManager openCensusMetricStorage; - - OpenCensusMetricProducer(Resource resource, MetricProducerManager openCensusMetricStorage) { - this.resource = resource; - this.openCensusMetricStorage = openCensusMetricStorage; - } - - /** - * Constructs a new {@link OpenCensusMetricProducer} that reports against the given {@link - * Resource}. - */ - static MetricProducer create(Resource resource) { - return new OpenCensusMetricProducer( - resource, Metrics.getExportComponent().getMetricProducerManager()); - } - - @Override - public Collection collectAllMetrics() { - List result = new ArrayList<>(); - openCensusMetricStorage - .getAllMetricProducer() - .forEach( - producer -> { - producer - .getMetrics() - .forEach(metric -> result.add(MetricAdapter.convert(resource, metric))); - }); - return result; - } -} diff --git a/opencensus-shim/src/main/java/io/opentelemetry/opencensusshim/metrics/OpenCensusMetrics.java b/opencensus-shim/src/main/java/io/opentelemetry/opencensusshim/metrics/OpenCensusMetrics.java deleted file mode 100644 index fc4d5a2b22c..00000000000 --- a/opencensus-shim/src/main/java/io/opentelemetry/opencensusshim/metrics/OpenCensusMetrics.java +++ /dev/null @@ -1,23 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package io.opentelemetry.opencensusshim.metrics; - -import io.opentelemetry.sdk.metrics.export.MetricReader; - -/** Convenience methods for adapting OpenCensus metrics into OpenTelemetry. */ -public final class OpenCensusMetrics { - private OpenCensusMetrics() {} - - /** - * Attaches OpenCensus metrics to metrics read by the given input. - * - * @param input A {@link MetricReader} that will receive OpenCensus metrics. - * @return The adapted MetricReaderFactory. - */ - public static MetricReader attachTo(MetricReader input) { - return new OpenCensusAttachingMetricReader(input); - } -} diff --git a/opencensus-shim/src/test/java/io/opentelemetry/opencensusshim/metrics/OpenCensusMetricProducerTest.java b/opencensus-shim/src/test/java/io/opentelemetry/opencensusshim/metrics/OpenCensusMetricProducerTest.java index 1e9f756ca47..c2465522296 100644 --- a/opencensus-shim/src/test/java/io/opentelemetry/opencensusshim/metrics/OpenCensusMetricProducerTest.java +++ b/opencensus-shim/src/test/java/io/opentelemetry/opencensusshim/metrics/OpenCensusMetricProducerTest.java @@ -21,7 +21,8 @@ import io.opencensus.trace.TraceOptions; import io.opencensus.trace.Tracestate; import io.opentelemetry.api.common.Attributes; -import io.opentelemetry.sdk.metrics.internal.export.MetricProducer; +import io.opentelemetry.opencensusshim.OpenCensusMetricProducer; +import io.opentelemetry.sdk.metrics.export.MetricProducer; import io.opentelemetry.sdk.resources.Resource; import java.time.Duration; import java.util.Arrays; @@ -31,8 +32,7 @@ import org.junit.jupiter.api.Test; class OpenCensusMetricProducerTest { - private final MetricProducer openCensusMetrics = - OpenCensusMetricProducer.create(Resource.empty()); + private final MetricProducer openCensusMetrics = OpenCensusMetricProducer.create(); private static final Measure.MeasureLong LATENCY_MS = Measure.MeasureLong.create("task_latency", "The task latency in milliseconds", "ms"); @@ -69,7 +69,7 @@ void extractHistogram() throws InterruptedException { .atMost(Duration.ofSeconds(10)) .untilAsserted( () -> - assertThat(openCensusMetrics.collectAllMetrics()) + assertThat(openCensusMetrics.produce(Resource.empty())) .satisfiesExactly( metric -> assertThat(metric) diff --git a/opencensus-shim/src/test/java/io/opentelemetry/opencensusshim/metrics/OpenCensusMetricsTest.java b/opencensus-shim/src/test/java/io/opentelemetry/opencensusshim/metrics/OpenCensusMetricsTest.java index 661054ecc1b..368e08ccb2f 100644 --- a/opencensus-shim/src/test/java/io/opentelemetry/opencensusshim/metrics/OpenCensusMetricsTest.java +++ b/opencensus-shim/src/test/java/io/opentelemetry/opencensusshim/metrics/OpenCensusMetricsTest.java @@ -12,6 +12,7 @@ import io.opencensus.stats.Stats; import io.opencensus.stats.StatsRecorder; import io.opencensus.stats.View; +import io.opentelemetry.opencensusshim.OpenCensusMetricProducer; import io.opentelemetry.sdk.metrics.SdkMeterProvider; import io.opentelemetry.sdk.testing.exporter.InMemoryMetricReader; import java.time.Duration; @@ -26,7 +27,10 @@ class OpenCensusMetricsTest { void capturesOpenCensusAndOtelMetrics() throws InterruptedException { InMemoryMetricReader reader = InMemoryMetricReader.create(); SdkMeterProvider otelMetrics = - SdkMeterProvider.builder().registerMetricReader(OpenCensusMetrics.attachTo(reader)).build(); + SdkMeterProvider.builder() + .registerMetricReader(reader) + .registerMetricProducer(OpenCensusMetricProducer.create()) + .build(); // Record an otel metric. otelMetrics.meterBuilder("otel").build().counterBuilder("otel.sum").build().add(1); // Record an OpenCensus metric. @@ -47,7 +51,7 @@ void capturesOpenCensusAndOtelMetrics() throws InterruptedException { .untilAsserted( () -> assertThat(reader.collectAllMetrics()) - .satisfiesExactly( + .satisfiesExactlyInAnyOrder( metric -> assertThat(metric).hasName("otel.sum").hasLongSumSatisfying(sum -> {}), metric -> diff --git a/sdk/all/src/test/java/io/opentelemetry/sdk/OpenTelemetrySdkTest.java b/sdk/all/src/test/java/io/opentelemetry/sdk/OpenTelemetrySdkTest.java index 09e1a402671..d3216fc9fa2 100644 --- a/sdk/all/src/test/java/io/opentelemetry/sdk/OpenTelemetrySdkTest.java +++ b/sdk/all/src/test/java/io/opentelemetry/sdk/OpenTelemetrySdkTest.java @@ -421,6 +421,7 @@ void stringRepresentation() { + "clock=SystemClock{}, " + "resource=Resource{schemaUrl=null, attributes={service.name=\"otel-test\"}}, " + "metricReaders=[PeriodicMetricReader{exporter=MockMetricExporter{}, intervalNanos=60000000000}], " + + "metricProducers=[], " + "views=[RegisteredView{instrumentSelector=InstrumentSelector{instrumentName=instrument}, view=View{name=new-instrument, aggregation=DefaultAggregation, attributesProcessor=NoopAttributesProcessor{}, cardinalityLimit=2000}}]" + "}, " + "loggerProvider=SdkLoggerProvider{" diff --git a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkMeterProvider.java b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkMeterProvider.java index 431fc41ab30..63b241bc5b1 100644 --- a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkMeterProvider.java +++ b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkMeterProvider.java @@ -13,11 +13,12 @@ import io.opentelemetry.sdk.common.CompletableResultCode; import io.opentelemetry.sdk.internal.ComponentRegistry; import io.opentelemetry.sdk.metrics.data.MetricData; +import io.opentelemetry.sdk.metrics.export.CollectionRegistration; +import io.opentelemetry.sdk.metrics.export.MetricProducer; import io.opentelemetry.sdk.metrics.export.MetricReader; import io.opentelemetry.sdk.metrics.internal.SdkMeterProviderUtil; import io.opentelemetry.sdk.metrics.internal.exemplar.ExemplarFilter; import io.opentelemetry.sdk.metrics.internal.export.CardinalityLimitSelector; -import io.opentelemetry.sdk.metrics.internal.export.MetricProducer; import io.opentelemetry.sdk.metrics.internal.export.RegisteredReader; import io.opentelemetry.sdk.metrics.internal.state.MeterProviderSharedState; import io.opentelemetry.sdk.metrics.internal.view.RegisteredView; @@ -45,6 +46,7 @@ public final class SdkMeterProvider implements MeterProvider, Closeable { private final List registeredViews; private final List registeredReaders; + private final List metricProducers; private final MeterProviderSharedState sharedState; private final ComponentRegistry registry; private final AtomicBoolean isClosed = new AtomicBoolean(false); @@ -57,6 +59,7 @@ public static SdkMeterProviderBuilder builder() { SdkMeterProvider( List registeredViews, IdentityHashMap metricReaders, + List metricProducers, Clock clock, Resource resource, ExemplarFilter exemplarFilter) { @@ -70,6 +73,7 @@ public static SdkMeterProviderBuilder builder() { entry.getKey(), ViewRegistry.create(entry.getKey(), entry.getValue(), registeredViews))) .collect(toList()); + this.metricProducers = metricProducers; this.sharedState = MeterProviderSharedState.create(clock, resource, exemplarFilter, startEpochNanos); this.registry = @@ -77,8 +81,11 @@ public static SdkMeterProviderBuilder builder() { instrumentationLibraryInfo -> new SdkMeter(sharedState, instrumentationLibraryInfo, registeredReaders)); for (RegisteredReader registeredReader : registeredReaders) { - MetricProducer producer = new LeasedMetricProducer(registry, sharedState, registeredReader); - registeredReader.getReader().register(producer); + List readerMetricProducers = new ArrayList<>(metricProducers); + readerMetricProducers.add(new LeasedMetricProducer(registry, sharedState, registeredReader)); + registeredReader + .getReader() + .register(new SdkCollectionRegistration(readerMetricProducers, sharedState)); registeredReader.setLastCollectEpochNanos(startEpochNanos); } } @@ -154,6 +161,8 @@ public String toString() { + sharedState.getResource() + ", metricReaders=" + registeredReaders.stream().map(RegisteredReader::getReader).collect(toList()) + + ", metricProducers=" + + metricProducers + ", views=" + registeredViews + "}"; @@ -176,7 +185,7 @@ private static class LeasedMetricProducer implements MetricProducer { } @Override - public Collection collectAllMetrics() { + public Collection produce(Resource unused) { Collection meters = registry.getComponents(); List result = new ArrayList<>(); long collectTime = sharedState.getClock().now(); @@ -187,4 +196,31 @@ public Collection collectAllMetrics() { return Collections.unmodifiableCollection(result); } } + + private static class SdkCollectionRegistration implements CollectionRegistration { + private final List metricProducers; + private final MeterProviderSharedState sharedState; + + private SdkCollectionRegistration( + List metricProducers, MeterProviderSharedState sharedState) { + this.metricProducers = metricProducers; + this.sharedState = sharedState; + } + + @Override + public Collection collectAllMetrics() { + if (metricProducers.isEmpty()) { + return Collections.emptyList(); + } + Resource resource = sharedState.getResource(); + if (metricProducers.size() == 1) { + return metricProducers.get(0).produce(resource); + } + List metricData = new ArrayList<>(); + for (MetricProducer metricProducer : metricProducers) { + metricData.addAll(metricProducer.produce(resource)); + } + return Collections.unmodifiableList(metricData); + } + } } diff --git a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkMeterProviderBuilder.java b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkMeterProviderBuilder.java index 1ad5efc0c22..3e444f10f93 100644 --- a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkMeterProviderBuilder.java +++ b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkMeterProviderBuilder.java @@ -6,6 +6,7 @@ package io.opentelemetry.sdk.metrics; import io.opentelemetry.sdk.common.Clock; +import io.opentelemetry.sdk.metrics.export.MetricProducer; import io.opentelemetry.sdk.metrics.export.MetricReader; import io.opentelemetry.sdk.metrics.internal.SdkMeterProviderUtil; import io.opentelemetry.sdk.metrics.internal.debug.SourceInfo; @@ -36,6 +37,7 @@ public final class SdkMeterProviderBuilder { private Resource resource = Resource.getDefault(); private final IdentityHashMap metricReaders = new IdentityHashMap<>(); + private final List metricProducers = new ArrayList<>(); private final List registeredViews = new ArrayList<>(); private ExemplarFilter exemplarFilter = DEFAULT_EXEMPLAR_FILTER; @@ -119,11 +121,7 @@ public SdkMeterProviderBuilder registerView(InstrumentSelector selector, View vi return this; } - /** - * Registers a {@link MetricReader}. - * - *

    Note: custom implementations of {@link MetricReader} are not currently supported. - */ + /** Registers a {@link MetricReader}. */ public SdkMeterProviderBuilder registerMetricReader(MetricReader reader) { metricReaders.put(reader, CardinalityLimitSelector.defaultCardinalityLimitSelector()); return this; @@ -142,8 +140,19 @@ SdkMeterProviderBuilder registerMetricReader( return this; } + /** + * Registers a {@link MetricProducer}. + * + * @since 1.31.0 + */ + public SdkMeterProviderBuilder registerMetricProducer(MetricProducer metricProducer) { + metricProducers.add(metricProducer); + return this; + } + /** Returns an {@link SdkMeterProvider} built with the configuration of this builder. */ public SdkMeterProvider build() { - return new SdkMeterProvider(registeredViews, metricReaders, clock, resource, exemplarFilter); + return new SdkMeterProvider( + registeredViews, metricReaders, metricProducers, clock, resource, exemplarFilter); } } diff --git a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/export/CollectionRegistration.java b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/export/CollectionRegistration.java index 707da70ea95..c8511700cb4 100644 --- a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/export/CollectionRegistration.java +++ b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/export/CollectionRegistration.java @@ -5,7 +5,11 @@ package io.opentelemetry.sdk.metrics.export; +import io.opentelemetry.sdk.common.export.MemoryMode; import io.opentelemetry.sdk.metrics.SdkMeterProvider; +import io.opentelemetry.sdk.metrics.data.MetricData; +import java.util.Collection; +import java.util.Collections; /** * A {@link CollectionRegistration} is passed to each {@link MetricReader} registered with {@link @@ -13,5 +17,29 @@ * * @since 1.14.0 */ -// TODO(jack-berg): Have methods when custom MetricReaders are supported -public interface CollectionRegistration {} +public interface CollectionRegistration { + + /** + * Returns a noop {@link CollectionRegistration}, useful for {@link MetricReader}s to hold before + * {@link MetricReader#register(CollectionRegistration)} is called. + */ + static CollectionRegistration noop() { + return new CollectionRegistration() { + @Override + public Collection collectAllMetrics() { + return Collections.emptyList(); + } + }; + } + + /** + * Collect all metrics, including metrics from the SDK and any registered {@link MetricProducer}s. + * + *

    If {@link MetricReader#getMemoryMode()} is configured to {@link MemoryMode#REUSABLE_DATA} do + * not keep the result or any of its contained objects as they are to be reused to return the + * result for the next call to this method. + */ + default Collection collectAllMetrics() { + return Collections.emptyList(); + } +} diff --git a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/export/MetricProducer.java b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/export/MetricProducer.java new file mode 100644 index 00000000000..723eb7e1e92 --- /dev/null +++ b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/export/MetricProducer.java @@ -0,0 +1,42 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.sdk.metrics.export; + +import io.opentelemetry.sdk.metrics.SdkMeterProviderBuilder; +import io.opentelemetry.sdk.metrics.data.MetricData; +import io.opentelemetry.sdk.resources.Resource; +import java.util.Collection; +import javax.annotation.concurrent.ThreadSafe; + +/** + * {@link MetricProducer} is the interface that is used to make metric data available to the {@link + * MetricReader}s. The primary implementation is provided by {@link + * io.opentelemetry.sdk.metrics.SdkMeterProvider}. + * + *

    Alternative {@link MetricProducer} implementations can be used to bridge aggregated metrics + * from other frameworks, and are registered with {@link + * SdkMeterProviderBuilder#registerMetricProducer(MetricProducer)}. NOTE: When possible, metrics + * from other frameworks SHOULD be bridged using the metric API, normally with asynchronous + * instruments which observe the aggregated state of the other framework. However, {@link + * MetricProducer} exists to accommodate scenarios where the metric API is insufficient. It should + * be used with caution as it requires the bridge to take a dependency on {@code + * opentelemetry-sdk-metrics}, which is generally not advised. + * + *

    Implementations must be thread-safe. + * + * @since 1.31.0 + */ +@ThreadSafe +public interface MetricProducer { + + /** + * Returns a collection of produced {@link MetricData}s to be exported. This will only be those + * metrics that have been produced since the last time this method was called. + * + * @return a collection of produced {@link MetricData}s to be exported. + */ + Collection produce(Resource resource); +} diff --git a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/export/MetricReader.java b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/export/MetricReader.java index 4ff4155f9bd..7ddab97dfc1 100644 --- a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/export/MetricReader.java +++ b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/export/MetricReader.java @@ -19,20 +19,15 @@ /** * A metric reader reads metrics from an {@link SdkMeterProvider}. * - *

    Custom implementations of {@link MetricReader} are not currently supported. Please use one of - * the built-in readers such as {@link PeriodicMetricReader}. - * * @since 1.14.0 */ public interface MetricReader extends AggregationTemporalitySelector, DefaultAggregationSelector, Closeable { /** - * Called by {@link SdkMeterProvider} and supplies the {@link MetricReader} with a handle to - * collect metrics. - * - *

    {@link CollectionRegistration} is currently an empty interface because custom - * implementations of {@link MetricReader} are not currently supported. + * Called by {@link SdkMeterProvider} on initialization to supply the {@link MetricReader} with + * {@link MetricProducer}s used to collect metrics. {@link MetricReader} implementations call + * {@link CollectionRegistration#collectAllMetrics()} to read metrics. */ void register(CollectionRegistration registration); diff --git a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/export/PeriodicMetricReader.java b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/export/PeriodicMetricReader.java index d22133677fb..a19dbae5781 100644 --- a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/export/PeriodicMetricReader.java +++ b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/export/PeriodicMetricReader.java @@ -13,7 +13,6 @@ import io.opentelemetry.sdk.metrics.SdkMeterProviderBuilder; import io.opentelemetry.sdk.metrics.data.AggregationTemporality; import io.opentelemetry.sdk.metrics.data.MetricData; -import io.opentelemetry.sdk.metrics.internal.export.MetricProducer; import java.util.Collection; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.ScheduledFuture; @@ -40,8 +39,8 @@ public final class PeriodicMetricReader implements MetricReader { private final ScheduledExecutorService scheduler; private final Scheduled scheduled; private final Object lock = new Object(); + private volatile CollectionRegistration collectionRegistration = CollectionRegistration.noop(); - private volatile MetricProducer metricProducer = MetricProducer.noop(); @Nullable private volatile ScheduledFuture scheduledFuture; /** @@ -117,8 +116,8 @@ public CompletableResultCode shutdown() { } @Override - public void register(CollectionRegistration registration) { - this.metricProducer = MetricProducer.asMetricProducer(registration); + public void register(CollectionRegistration collectionRegistration) { + this.collectionRegistration = collectionRegistration; start(); } @@ -159,7 +158,7 @@ CompletableResultCode doRun() { CompletableResultCode flushResult = new CompletableResultCode(); if (exportAvailable.compareAndSet(true, false)) { try { - Collection metricData = metricProducer.collectAllMetrics(); + Collection metricData = collectionRegistration.collectAllMetrics(); if (metricData.isEmpty()) { logger.log(Level.FINE, "No metric data to export - skipping export."); flushResult.succeed(); diff --git a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/export/MetricProducer.java b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/export/MetricProducer.java deleted file mode 100644 index 63bb152f638..00000000000 --- a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/export/MetricProducer.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package io.opentelemetry.sdk.metrics.internal.export; - -import io.opentelemetry.sdk.common.export.MemoryMode; -import io.opentelemetry.sdk.metrics.data.MetricData; -import io.opentelemetry.sdk.metrics.export.CollectionRegistration; -import io.opentelemetry.sdk.metrics.export.MetricReader; -import java.util.Collection; -import java.util.Collections; -import javax.annotation.concurrent.ThreadSafe; - -/** - * {@code MetricProducer} is the interface that is used to make metric data available to the {@link - * MetricReader}s. Implementations should be stateful, in that each call to {@link - * #collectAllMetrics()} will return any metric generated since the last call was made. - * - *

    Implementations must be thread-safe. - * - *

    This class is internal and is hence not for public use. Its APIs are unstable and can change - * at any time. - */ -@ThreadSafe -public interface MetricProducer extends CollectionRegistration { - - /** Cast the registration to a {@link MetricProducer}. */ - static MetricProducer asMetricProducer(CollectionRegistration registration) { - if (!(registration instanceof MetricProducer)) { - throw new IllegalArgumentException( - "unrecognized CollectionRegistration, custom MetricReader implementations are not currently supported"); - } - return (MetricProducer) registration; - } - - /** Return a noop {@link MetricProducer}. */ - static MetricProducer noop() { - return Collections::emptyList; - } - - /** - * Returns a collection of produced {@link MetricData}s to be exported. This will only be those - * metrics that have been produced since the last time this method was called. - * - *

    If {@link MetricReader#getMemoryMode()} is configured to {@link MemoryMode#REUSABLE_DATA} do - * not keep the result or any of its contained objects as they are to be reused to return the - * result for the next call of {@code collectAllMetrics} - * - * @return a collection of produced {@link MetricData}s to be exported. - */ - Collection collectAllMetrics(); -} diff --git a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/export/RegisteredReader.java b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/export/RegisteredReader.java index fbb587741b0..c56d01b9cda 100644 --- a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/export/RegisteredReader.java +++ b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/export/RegisteredReader.java @@ -8,6 +8,7 @@ import io.opentelemetry.sdk.metrics.SdkMeterProvider; import io.opentelemetry.sdk.metrics.data.AggregationTemporality; import io.opentelemetry.sdk.metrics.data.PointData; +import io.opentelemetry.sdk.metrics.export.MetricProducer; import io.opentelemetry.sdk.metrics.export.MetricReader; import io.opentelemetry.sdk.metrics.internal.view.ViewRegistry; import java.util.concurrent.atomic.AtomicInteger; diff --git a/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/export/PeriodicMetricReaderTest.java b/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/export/PeriodicMetricReaderTest.java index 142e8816366..03c8d05cfaa 100644 --- a/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/export/PeriodicMetricReaderTest.java +++ b/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/export/PeriodicMetricReaderTest.java @@ -26,7 +26,6 @@ import io.opentelemetry.sdk.metrics.internal.data.ImmutableLongPointData; import io.opentelemetry.sdk.metrics.internal.data.ImmutableMetricData; import io.opentelemetry.sdk.metrics.internal.data.ImmutableSumData; -import io.opentelemetry.sdk.metrics.internal.export.MetricProducer; import io.opentelemetry.sdk.resources.Resource; import java.io.IOException; import java.time.Duration; @@ -67,17 +66,19 @@ class PeriodicMetricReaderTest { ImmutableSumData.create( /* isMonotonic= */ true, AggregationTemporality.CUMULATIVE, LONG_POINT_LIST)); - @Mock private MetricProducer metricProducer; + @Mock private CollectionRegistration collectionRegistration; @Mock private MetricExporter metricExporter; @BeforeEach void setup() { - when(metricProducer.collectAllMetrics()).thenReturn(Collections.singletonList(METRIC_DATA)); + when(collectionRegistration.collectAllMetrics()) + .thenReturn(Collections.singletonList(METRIC_DATA)); } @Test @SuppressWarnings({"rawtypes", "unchecked"}) void startOnlyOnce() { + ScheduledExecutorService scheduler = mock(ScheduledExecutorService.class); ScheduledFuture mock = mock(ScheduledFuture.class); @@ -89,7 +90,7 @@ void startOnlyOnce() { .setExecutor(scheduler) .build(); - reader.register(metricProducer); + reader.register(collectionRegistration); verify(scheduler, times(1)).scheduleAtFixedRate(any(), anyLong(), anyLong(), any()); } @@ -102,7 +103,7 @@ void periodicExport() throws Exception { .setInterval(Duration.ofMillis(100)) .build(); - reader.register(metricProducer); + reader.register(collectionRegistration); try { assertThat(waitingMetricExporter.waitForNumberOfExports(1)) .containsExactly(Collections.singletonList(METRIC_DATA)); @@ -122,12 +123,12 @@ void periodicExport_NoMetricsSkipsExport() { PeriodicMetricReader.builder(waitingMetricExporter) .setInterval(Duration.ofMillis(100)) .build(); - when(metricProducer.collectAllMetrics()).thenReturn(Collections.emptyList()); - reader.register(metricProducer); + when(collectionRegistration.collectAllMetrics()).thenReturn(Collections.emptyList()); + reader.register(collectionRegistration); try { assertThat(reader.forceFlush().join(10, TimeUnit.SECONDS).isSuccess()).isTrue(); - verify(metricProducer).collectAllMetrics(); + verify(collectionRegistration).collectAllMetrics(); assertThat(waitingMetricExporter.exportTimes.size()).isEqualTo(0); } finally { reader.shutdown(); @@ -142,7 +143,7 @@ void flush() throws Exception { .setInterval(Duration.ofNanos(Long.MAX_VALUE)) .build(); - reader.register(metricProducer); + reader.register(collectionRegistration); assertThat(reader.forceFlush().join(10, TimeUnit.SECONDS).isSuccess()).isTrue(); try { @@ -164,7 +165,7 @@ public void intervalExport_exporterThrowsException() throws Exception { .setInterval(Duration.ofMillis(100)) .build(); - reader.register(metricProducer); + reader.register(collectionRegistration); try { assertThat(waitingMetricExporter.waitForNumberOfExports(2)) .containsExactly( @@ -181,7 +182,7 @@ void shutdown_ExportsOneLastTime() throws Exception { PeriodicMetricReader.builder(waitingMetricExporter) .setInterval(Duration.ofSeconds(Integer.MAX_VALUE)) .build(); - reader.register(metricProducer); + reader.register(collectionRegistration); reader.shutdown(); // This export was called during shutdown. @@ -198,7 +199,7 @@ void close_CallsShutdown() throws IOException { PeriodicMetricReader.builder(new WaitingMetricExporter()) .setInterval(Duration.ofSeconds(Integer.MAX_VALUE)) .build()); - reader.register(metricProducer); + reader.register(collectionRegistration); reader.close(); verify(reader, times(1)).shutdown(); diff --git a/sdk/testing/src/main/java/io/opentelemetry/sdk/testing/exporter/InMemoryMetricReader.java b/sdk/testing/src/main/java/io/opentelemetry/sdk/testing/exporter/InMemoryMetricReader.java index e72a78c52ee..3b79affe346 100644 --- a/sdk/testing/src/main/java/io/opentelemetry/sdk/testing/exporter/InMemoryMetricReader.java +++ b/sdk/testing/src/main/java/io/opentelemetry/sdk/testing/exporter/InMemoryMetricReader.java @@ -17,7 +17,6 @@ import io.opentelemetry.sdk.metrics.export.CollectionRegistration; import io.opentelemetry.sdk.metrics.export.DefaultAggregationSelector; import io.opentelemetry.sdk.metrics.export.MetricReader; -import io.opentelemetry.sdk.metrics.internal.export.MetricProducer; import java.util.Collection; import java.util.Collections; import java.util.concurrent.atomic.AtomicBoolean; @@ -54,7 +53,7 @@ public class InMemoryMetricReader implements MetricReader { private final AggregationTemporalitySelector aggregationTemporalitySelector; private final DefaultAggregationSelector defaultAggregationSelector; private final AtomicBoolean isShutdown = new AtomicBoolean(false); - private volatile MetricProducer metricProducer = MetricProducer.noop(); + private volatile CollectionRegistration collectionRegistration = CollectionRegistration.noop(); private final MemoryMode memoryMode; /** @@ -111,12 +110,12 @@ public Collection collectAllMetrics() { if (isShutdown.get()) { return Collections.emptyList(); } - return metricProducer.collectAllMetrics(); + return collectionRegistration.collectAllMetrics(); } @Override - public void register(CollectionRegistration registration) { - this.metricProducer = MetricProducer.asMetricProducer(registration); + public void register(CollectionRegistration collectionRegistration) { + this.collectionRegistration = collectionRegistration; } @Override From aff4e124254a95465fb3b45ffe20019cea5c96bb Mon Sep 17 00:00:00 2001 From: Tyler Benson Date: Wed, 27 Sep 2023 15:00:39 -0400 Subject: [PATCH 024/901] Add Benchmark workflows (#5842) --- .github/repository-settings.md | 8 +++ .github/workflows/benchmark-tags.yml | 74 ++++++++++++++++++++++++++++ .github/workflows/benchmark.yml | 43 ++++++++++++++++ 3 files changed, 125 insertions(+) create mode 100644 .github/workflows/benchmark-tags.yml create mode 100644 .github/workflows/benchmark.yml diff --git a/.github/repository-settings.md b/.github/repository-settings.md index 0d836539b5e..e066f5fc18b 100644 --- a/.github/repository-settings.md +++ b/.github/repository-settings.md @@ -54,6 +54,14 @@ Same settings as above for `main`, except: (So that bot PR branches can be deleted) +### `benchmarks` + +- Everything UNCHECKED + + (This branch is currently only used for directly pushing benchmarking results from the + [overhead benchmark](https://github.com/open-telemetry/opentelemetry-java/actions/workflows/benchmark.yml) + job) + ## Secrets and variables > Actions * `GPG_PASSWORD` - stored in OpenTelemetry-Java 1Password diff --git a/.github/workflows/benchmark-tags.yml b/.github/workflows/benchmark-tags.yml new file mode 100644 index 00000000000..96cb0c248fe --- /dev/null +++ b/.github/workflows/benchmark-tags.yml @@ -0,0 +1,74 @@ +name: Benchmark Tags + +on: + workflow_dispatch: + +jobs: + sdk-benchmark: + name: Benchmark SDK + runs-on: self-hosted + timeout-minutes: 10 + strategy: + fail-fast: false + matrix: + tag-version: + - v1.6.0 + - v1.7.0 + - v1.7.1 + - v1.10.0 + - v1.10.1 + - v1.11.0 + - v1.12.0 + - v1.13.0 + - v1.14.0 + - v1.15.0 + - v1.16.0 + - v1.17.0 + - v1.18.0 + - v1.19.0 + - v1.21.0 + - v1.22.0 + - v1.23.0 + - v1.23.1 + - v1.24.0 + - v1.25.0 + - v1.26.0 + - v1.27.0 + - v1.28.0 + - v1.29.0 + - v1.30.0 + - v1.30.1 + steps: + - uses: actions/checkout@v4 + with: + ref: ${{ matrix.tag-version }} + + - id: setup-java + name: Set up Java for build + uses: actions/setup-java@v3 + with: + distribution: temurin + java-version: 17 + + - uses: gradle/gradle-build-action@v2 + with: + arguments: | + jmhJar + env: + GRADLE_ENTERPRISE_ACCESS_KEY: ${{ secrets.GRADLE_ENTERPRISE_ACCESS_KEY }} + + - name: Run Benchmark + run: | + cd sdk/trace/build + java -jar libs/opentelemetry-sdk-trace-*-jmh.jar -rf json SpanBenchmark SpanPipelineBenchmark ExporterBenchmark + + - name: Store benchmark results + uses: benchmark-action/github-action-benchmark@v1 + with: + tool: 'jmh' + output-file-path: sdk/trace/build/jmh-result.json + gh-pages-branch: benchmarks + github-token: ${{ secrets.GITHUB_TOKEN }} + benchmark-data-dir-path: "" + auto-push: true + ref: ${{ matrix.tag-version }} diff --git a/.github/workflows/benchmark.yml b/.github/workflows/benchmark.yml new file mode 100644 index 00000000000..9aaa9994b2e --- /dev/null +++ b/.github/workflows/benchmark.yml @@ -0,0 +1,43 @@ +name: Benchmark Main + +on: + push: + branches: [ main ] + workflow_dispatch: + +jobs: + sdk-benchmark: + name: Benchmark SDK + runs-on: self-hosted + timeout-minutes: 10 + steps: + - uses: actions/checkout@v4 + + - id: setup-java + name: Set up Java for build + uses: actions/setup-java@v3 + with: + distribution: temurin + java-version: 17 + + - uses: gradle/gradle-build-action@v2 + with: + arguments: | + jmhJar + env: + GRADLE_ENTERPRISE_ACCESS_KEY: ${{ secrets.GRADLE_ENTERPRISE_ACCESS_KEY }} + + - name: Run Benchmark + run: | + cd sdk/trace/build + java -jar libs/opentelemetry-sdk-trace-*-jmh.jar -rf json SpanBenchmark SpanPipelineBenchmark ExporterBenchmark + + - name: Store benchmark results + uses: benchmark-action/github-action-benchmark@v1 + with: + tool: 'jmh' + output-file-path: sdk/trace/build/jmh-result.json + gh-pages-branch: benchmarks + github-token: ${{ secrets.GITHUB_TOKEN }} + benchmark-data-dir-path: "" + auto-push: true From 1bd41e2b790e22e148d013e3287588317e01997b Mon Sep 17 00:00:00 2001 From: jack-berg <34418638+jack-berg@users.noreply.github.com> Date: Wed, 27 Sep 2023 14:42:04 -0500 Subject: [PATCH 025/901] Remove semconv (#5807) --- CONTRIBUTING.md | 2 - README.md | 13 +- all/build.gradle.kts | 1 - buildscripts/checkstyle-suppressions.xml | 1 - buildscripts/semantic-convention/.gitignore | 1 - buildscripts/semantic-convention/generate.sh | 52 - .../templates/SemanticAttributes.java.j2 | 486 ---- sdk-extensions/autoconfigure/README.md | 2 +- semconv/README.md | 5 - semconv/build.gradle.kts | 13 - semconv/gradle.properties | 1 - .../attributes/ResourceAttributes.java | 980 ------- .../resource/attributes/package-info.java | 14 - .../trace/attributes/SemanticAttributes.java | 2322 ----------------- .../trace/attributes/package-info.java | 14 - settings.gradle.kts | 1 - 16 files changed, 10 insertions(+), 3898 deletions(-) delete mode 100644 buildscripts/semantic-convention/.gitignore delete mode 100755 buildscripts/semantic-convention/generate.sh delete mode 100644 buildscripts/semantic-convention/templates/SemanticAttributes.java.j2 delete mode 100644 semconv/README.md delete mode 100644 semconv/build.gradle.kts delete mode 100644 semconv/gradle.properties delete mode 100644 semconv/src/main/java/io/opentelemetry/semconv/resource/attributes/ResourceAttributes.java delete mode 100644 semconv/src/main/java/io/opentelemetry/semconv/resource/attributes/package-info.java delete mode 100644 semconv/src/main/java/io/opentelemetry/semconv/trace/attributes/SemanticAttributes.java delete mode 100644 semconv/src/main/java/io/opentelemetry/semconv/trace/attributes/package-info.java diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index b599a32fb3b..eb879a169ba 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -77,8 +77,6 @@ with a few exceptions / comments: * Components like the [Kotlin Extension](./extensions/kotlin) are included which are required for the API / SDK to function in key areas of the Java ecosystem. Inclusion is subject to maintainers' discretion. -* The [semconv](./semconv) module contains generated classes representing - the [semantic conventions](https://github.com/open-telemetry/semantic-conventions). * As a general rule, components which implement semantic conventions belong elsewhere. Other repositories in the OpenTelemetry Java ecosystem include: diff --git a/README.md b/README.md index 6b7781c2413..3be94db91d1 100644 --- a/README.md +++ b/README.md @@ -17,6 +17,10 @@ write your own **manual instrumentation**, or how to set up the OpenTelemetry Java SDK, see [Manual instrumentation][]. Fully-functional examples are available in [opentelemetry-java-docs][]. +If you are looking for generated classes for +the [OpenTelemetry semantic conventions][opentelemetry-semantic-conventions], +see [semantic-conventions-java][opentelemetry-semantic-conventions-java]. + For a general overview of OpenTelemetry, visit [opentelemetry.io][]. Would you like to get involved with the project? Read our [contributing guide](CONTRIBUTING.md). We welcome @@ -40,7 +44,6 @@ This project contains the following top level components: * [OpenTelemetry API](api/): * [stable apis](api/all/src/main/java/io/opentelemetry/api/) including `Tracer`, `Span`, `SpanContext`, `Meter`, and `Baggage` - * [semantic conventions](semconv/) Generated code for the OpenTelemetry semantic conventions. * [context api](context/src/main/java/io/opentelemetry/context/) The OpenTelemetry Context implementation. * [extensions](extensions/) define additional API extensions, which are not part of the core API. * [sdk](sdk/) defines the implementation of the OpenTelemetry API. @@ -115,7 +118,7 @@ dependencies { } ``` -Note that if you want to use any artifacts that have not fully stabilized yet (such as the [semantic conventions constants](https://github.com/open-telemetry/opentelemetry-java/tree/main/semconv), then you will need to add an entry for the Alpha BOM as well, e.g. +Note that if you want to use any artifacts that have not fully stabilized yet (such as the [prometheus exporter](https://github.com/open-telemetry/opentelemetry-java/tree/main/exporters/prometheus), then you will need to add an entry for the Alpha BOM as well, e.g. ```groovy dependencies { @@ -123,7 +126,7 @@ dependencies { implementation platform('io.opentelemetry:opentelemetry-bom-alpha:1.30.1-alpha') implementation('io.opentelemetry:opentelemetry-api') - implementation('io.opentelemetry:opentelemetry-semconv') + implementation('io.opentelemetry:opentelemetry-exporter-prometheus') implementation('io.opentelemetry:opentelemetry-sdk-extension-autoconfigure') } ``` @@ -221,12 +224,12 @@ dependency as follows, replacing `{{artifact-id}}` with the value from the "Arti ### API + | Component | Description | Artifact ID | Version | Javadoc | |-----------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|----------------------------|-------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------| | [API](./api/all) | OpenTelemetry API, including metrics, traces, baggage, context | `opentelemetry-api` | 1.30.1 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-api.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-api) | | [Events API](./api/events) | OpenTelemetry Event API for emitting events. | `opentelemetry-api-events` | 1.30.1-alpha | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-api-events.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-api-events) | | [Context API](./context) | OpenTelemetry context API | `opentelemetry-context` | 1.30.1 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-context.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-context) | -| [Semantic Conventions](./semconv) | Generated code for OpenTelemetry semantic conventions (deprecated, moved to [open-telemetry/semantic-conventions-java](https://github.com/open-telemetry/semantic-conventions-java)) | `opentelemetry-semconv` | 1.30.1-alpha | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-semconv.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-semconv) | ### API Extensions @@ -334,5 +337,7 @@ Made with [contrib.rocks](https://contrib.rocks). [maven-url]: https://maven-badges.herokuapp.com/maven-central/io.opentelemetry/opentelemetry-api [opentelemetry-java-instrumentation]: https://github.com/open-telemetry/opentelemetry-java-instrumentation [opentelemetry-java-docs]: https://github.com/open-telemetry/opentelemetry-java-docs +[opentelemetry-semantic-conventions]: https://opentelemetry.io/docs/specs/semconv/ +[opentelemetry-semantic-conventions-java]: https://github.com/open-telemetry/semantic-conventions-java [opentelemetry.io]: https://opentelemetry.io [otel-java-status]: https://opentelemetry.io/docs/instrumentation/java/#status-and-releases diff --git a/all/build.gradle.kts b/all/build.gradle.kts index e659d58d1a8..b205e053fe1 100644 --- a/all/build.gradle.kts +++ b/all/build.gradle.kts @@ -97,7 +97,6 @@ tasks.named("jacocoTestReport") { !it.absolutePath.contains("io/opentelemetry/exporter/jaeger/proto/") && !it.absolutePath.contains("io/opentelemetry/exporter/jaeger/internal/protobuf/") && !it.absolutePath.contains("io/opentelemetry/sdk/extension/trace/jaeger/proto/") && - !it.absolutePath.contains("io/opentelemetry/semconv/trace/attributes/") && !it.absolutePath.contains("AutoValue_") }, ) diff --git a/buildscripts/checkstyle-suppressions.xml b/buildscripts/checkstyle-suppressions.xml index bee50be5ec9..f5501405d3a 100644 --- a/buildscripts/checkstyle-suppressions.xml +++ b/buildscripts/checkstyle-suppressions.xml @@ -6,7 +6,6 @@ - diff --git a/buildscripts/semantic-convention/.gitignore b/buildscripts/semantic-convention/.gitignore deleted file mode 100644 index a93b221beb5..00000000000 --- a/buildscripts/semantic-convention/.gitignore +++ /dev/null @@ -1 +0,0 @@ -opentelemetry-specification/ diff --git a/buildscripts/semantic-convention/generate.sh b/buildscripts/semantic-convention/generate.sh deleted file mode 100755 index 9e8e51ec36b..00000000000 --- a/buildscripts/semantic-convention/generate.sh +++ /dev/null @@ -1,52 +0,0 @@ -#!/bin/bash - -SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" -ROOT_DIR="${SCRIPT_DIR}/../../" - -# freeze the spec & generator tools versions to make SemanticAttributes generation reproducible -SEMCONV_VERSION=1.20.0 -SPEC_VERSION=v$SEMCONV_VERSION -SCHEMA_URL=https://opentelemetry.io/schemas/$SEMCONV_VERSION -GENERATOR_VERSION=0.18.0 - -cd ${SCRIPT_DIR} - -rm -rf opentelemetry-specification || true -mkdir opentelemetry-specification -cd opentelemetry-specification - -git init -git remote add origin https://github.com/open-telemetry/opentelemetry-specification.git -git fetch origin "$SPEC_VERSION" -git reset --hard FETCH_HEAD -cd ${SCRIPT_DIR} - -docker run --rm \ - -v ${SCRIPT_DIR}/opentelemetry-specification/semantic_conventions:/source \ - -v ${SCRIPT_DIR}/templates:/templates \ - -v ${ROOT_DIR}/semconv/src/main/java/io/opentelemetry/semconv/trace/attributes/:/output \ - otel/semconvgen:$GENERATOR_VERSION \ - --only span,event,attribute_group,scope \ - -f /source code \ - --template /templates/SemanticAttributes.java.j2 \ - --output /output/SemanticAttributes.java \ - -Dsemconv=trace \ - -Dclass=SemanticAttributes \ - -DschemaUrl=$SCHEMA_URL \ - -Dpkg=io.opentelemetry.semconv.trace.attributes - -docker run --rm \ - -v ${SCRIPT_DIR}/opentelemetry-specification/semantic_conventions:/source \ - -v ${SCRIPT_DIR}/templates:/templates \ - -v ${ROOT_DIR}/semconv/src/main/java/io/opentelemetry/semconv/resource/attributes/:/output \ - otel/semconvgen:$GENERATOR_VERSION \ - --only resource \ - -f /source code \ - --template /templates/SemanticAttributes.java.j2 \ - --output /output/ResourceAttributes.java \ - -Dclass=ResourceAttributes \ - -DschemaUrl=$SCHEMA_URL \ - -Dpkg=io.opentelemetry.semconv.resource.attributes - -cd "$ROOT_DIR" -./gradlew spotlessApply diff --git a/buildscripts/semantic-convention/templates/SemanticAttributes.java.j2 b/buildscripts/semantic-convention/templates/SemanticAttributes.java.j2 deleted file mode 100644 index 8c224df92f9..00000000000 --- a/buildscripts/semantic-convention/templates/SemanticAttributes.java.j2 +++ /dev/null @@ -1,486 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - - -{%- macro to_java_return_type(type) -%} - {%- if type == "string" -%} - String - {%- elif type == "string[]" -%} - List - {%- elif type == "boolean" -%} - boolean - {%- elif type == "int" -%} - long - {%- elif type == "double" -%} - double - {%- else -%} - {{type}} - {%- endif -%} -{%- endmacro %} -{%- macro to_java_key_type(type) -%} - {%- if type == "string" -%} - stringKey - {%- elif type == "string[]" -%} - stringArrayKey - {%- elif type == "boolean" -%} - booleanKey - {%- elif type == "int" -%} - longKey - {%- elif type == "double" -%} - doubleKey - {%- else -%} - {{lowerFirst(type)}}Key - {%- endif -%} -{%- endmacro %} -{%- macro print_value(type, value) -%} - {{ "\"" if type == "String"}}{{value}}{{ "\"" if type == "String"}} -{%- endmacro %} -{%- macro upFirst(text) -%} - {{ text[0]|upper}}{{text[1:] }} -{%- endmacro %} -{%- macro lowerFirst(text) -%} - {{ text[0]|lower}}{{text[1:] }} -{%- endmacro %} - -package {{pkg | trim}}; - -import static io.opentelemetry.api.common.AttributeKey.booleanKey; -import static io.opentelemetry.api.common.AttributeKey.doubleKey; -import static io.opentelemetry.api.common.AttributeKey.longKey; -import static io.opentelemetry.api.common.AttributeKey.stringKey; -import static io.opentelemetry.api.common.AttributeKey.stringArrayKey; - -import io.opentelemetry.api.common.AttributeKey; -import java.util.List; - -// DO NOT EDIT, this is an Auto-generated file from buildscripts/semantic-convention{{template}} -@SuppressWarnings("unused") -public final class {{class}} { - /** - * The URL of the OpenTelemetry schema for these keys and values. - */ - public static final String SCHEMA_URL = "{{schemaUrl}}"; - {%- for attribute in attributes if attribute.is_local and not attribute.ref %} - - /** - * {{attribute.brief | render_markdown(code="{{@code {0}}}", paragraph="{0}")}} - {%- if attribute.note %} - * - *

    Notes: -

      {{attribute.note | render_markdown(code="{{@code {0}}}", paragraph="
    • {0}
    • ", list="{0}")}}
    - {%- endif %} - {%- if (attribute.stability | string()) == "StabilityLevel.DEPRECATED" %} - * - * @deprecated {{attribute.brief | to_doc_brief}}. - {%- endif %} - */ - {%- if (attribute.stability | string()) == "StabilityLevel.DEPRECATED" %} - @Deprecated - {%- endif %} - public static final AttributeKey<{{upFirst(to_java_return_type(attribute.attr_type | string))}}> {{attribute.fqn | to_const_name}} = {{to_java_key_type(attribute.attr_type | string)}}("{{attribute.fqn}}"); - {%- endfor %} - - // Enum definitions - {%- for attribute in attributes if attribute.is_local and not attribute.ref %} - {%- if attribute.is_enum %} - {%- set class_name = attribute.fqn | to_camelcase(True) ~ "Values" %} - {%- set type = to_java_return_type(attribute.attr_type.enum_type) %} - public static final class {{class_name}} { - {%- for member in attribute.attr_type.members %} - /** {% filter escape %}{{member.brief | to_doc_brief}}.{% endfilter %} */ - public static final {{ type }} {{ member.member_id | to_const_name }} = {{ print_value(type, member.value) }}; - - {%- endfor %} - - {%- if class_name == "NetTransportValues" %} - /** @deprecated This item has been removed as of 1.13.0 of the semantic conventions. */ - @Deprecated - public static final String IP = "ip"; - - /** @deprecated This item has been removed as of 1.13.0 of the semantic conventions. */ - @Deprecated - public static final String UNIX = "unix"; - {%- endif %} - - private {{ class_name }}() {} - } - - {% endif %} - {%- endfor %} - - {%- if class == "SemanticAttributes" %} - // Manually defined and not YET in the YAML - /** - * The name of an event describing an exception. - * - *

    Typically an event with that name should not be manually created. Instead {@link - * io.opentelemetry.api.trace.Span#recordException(Throwable)} should be used. - */ - public static final String EXCEPTION_EVENT_NAME = "exception"; - - /** - * The name of the keyspace being accessed. - * - * @deprecated this item has been removed as of 1.8.0 of the semantic conventions. Please use {@link SemanticAttributes#DB_NAME} instead. - */ - @Deprecated - public static final AttributeKey DB_CASSANDRA_KEYSPACE = - stringKey("db.cassandra.keyspace"); - - /** - * The HBase namespace being accessed. - * - * @deprecated this item has been removed as of 1.8.0 of the semantic conventions. Please use {@link SemanticAttributes#DB_NAME} instead. - */ - @Deprecated - public static final AttributeKey DB_HBASE_NAMESPACE = stringKey("db.hbase.namespace"); - - /** - * The size of the uncompressed request payload body after transport decoding. Not set if - * transport encoding not used. - * - * @deprecated this item has been removed as of 1.13.0 of the semantic conventions. Please use {@link SemanticAttributes#HTTP_REQUEST_CONTENT_LENGTH} instead. - */ - @Deprecated - public static final AttributeKey HTTP_REQUEST_CONTENT_LENGTH_UNCOMPRESSED = - longKey("http.request_content_length_uncompressed"); - - /** - * @deprecated This item has been removed as of 1.13.0 of the semantic conventions. Please use {@link SemanticAttributes#HTTP_RESPONSE_CONTENT_LENGTH} instead. - */ - @Deprecated - public static final AttributeKey HTTP_RESPONSE_CONTENT_LENGTH_UNCOMPRESSED = - longKey("http.response_content_length_uncompressed"); - - /** - * @deprecated This item has been removed as of 1.13.0 of the semantic conventions. Please use - * {@link SemanticAttributes#NET_HOST_NAME} instead. - */ - @Deprecated - public static final AttributeKey HTTP_SERVER_NAME = stringKey("http.server_name"); - - /** - * @deprecated This item has been removed as of 1.13.0 of the semantic conventions. Please use - * {@link SemanticAttributes#NET_HOST_NAME} instead. - */ - @Deprecated - public static final AttributeKey HTTP_HOST = stringKey("http.host"); - - /** - * @deprecated This item has been removed as of 1.13.0 of the semantic conventions. Please use {@link SemanticAttributes#NET_SOCK_PEER_ADDR} instead. - */ - @Deprecated - public static final AttributeKey NET_PEER_IP = stringKey("net.peer.ip"); - - /** - * @deprecated This item has been removed as of 1.13.0 of the semantic conventions. Please use {@link SemanticAttributes#NET_SOCK_HOST_ADDR} instead. - */ - @Deprecated - public static final AttributeKey NET_HOST_IP = stringKey("net.host.ip"); - - /** - * The ordinal number of request re-sending attempt. - * @deprecated This item has been removed as of 1.15.0 of the semantic conventions. Use {@link SemanticAttributes#HTTP_RESEND_COUNT} instead. - */ - @Deprecated - public static final AttributeKey HTTP_RETRY_COUNT = longKey("http.retry_count"); - - - /** - * A string identifying the messaging system. - * @deprecated This item has been removed as of 1.17.0 of the semantic conventions. Use {@link SemanticAttributes#MESSAGING_DESTINATION_NAME} instead. - */ - @Deprecated - public static final AttributeKey MESSAGING_DESTINATION = - stringKey("messaging.destination"); - - /** - * A boolean that is true if the message destination is temporary. - * @deprecated This item has been removed as of 1.17.0 of the semantic conventions. Use {@link SemanticAttributes#MESSAGING_DESTINATION_TEMPORARY} instead. - */ - @Deprecated - public static final AttributeKey MESSAGING_TEMP_DESTINATION = - booleanKey("messaging.temp_destination"); - - /** - * The name of the transport protocol. - * @deprecated This item has been removed as of 1.17.0 of the semantic conventions. Use {@link SemanticAttributes#NET_PROTOCOL_NAME} instead. - */ - @Deprecated - public static final AttributeKey MESSAGING_PROTOCOL = stringKey("messaging.protocol"); - - /** - * The version of the transport protocol. - * @deprecated This item has been removed as of 1.17.0 of the semantic conventions. Use {@link SemanticAttributes#NET_PROTOCOL_VERSION} instead. - */ - @Deprecated - public static final AttributeKey MESSAGING_PROTOCOL_VERSION = - stringKey("messaging.protocol_version"); - - /** - * Connection string. - * @deprecated This item has been removed as of 1.17.0 of the semantic conventions. There is no replacement. - */ - @Deprecated - public static final AttributeKey MESSAGING_URL = stringKey("messaging.url"); - - /** - * The conversation ID identifying the conversation to which the - * message belongs, represented as a string. Sometimes called "Correlation ID". - * @deprecated This item has been removed as of 1.17.0 of the semantic conventions. Use {@link SemanticAttributes#MESSAGING_MESSAGE_CONVERSATION_ID} instead. - */ - @Deprecated - public static final AttributeKey MESSAGING_CONVERSATION_ID = - stringKey("messaging.conversation_id"); - - /** - * RabbitMQ message routing key. - * @deprecated This item has been removed as of 1.17.0 of the semantic conventions. Use {@link SemanticAttributes#MESSAGING_RABBITMQ_DESTINATION_ROUTING_KEY} instead. - */ - @Deprecated - public static final AttributeKey MESSAGING_RABBITMQ_ROUTING_KEY = - stringKey("messaging.rabbitmq.routing_key"); - - /** - * Partition the message is received from. - * @deprecated This item has been removed as of 1.17.0 of the semantic conventions. Use {@link SemanticAttributes#MESSAGING_KAFKA_SOURCE_PARTITION} instead. - */ - @Deprecated - public static final AttributeKey MESSAGING_KAFKA_PARTITION = - longKey("messaging.kafka.partition"); - - /** - * A boolean that is true if the message is a tombstone. - * @deprecated This item has been removed as of 1.17.0 of the semantic conventions. Use {@link SemanticAttributes#MESSAGING_KAFKA_MESSAGE_TOMBSTONE} instead. - */ - @Deprecated - public static final AttributeKey MESSAGING_KAFKA_TOMBSTONE = - booleanKey("messaging.kafka.tombstone"); - - /** - * The timestamp in milliseconds that the delay message is expected to be delivered to consumer. - * @deprecated This item has been removed as of 1.17.0 of the semantic conventions. Use {@link SemanticAttributes#MESSAGING_ROCKETMQ_MESSAGE_DELIVERY_TIMESTAMP} instead. - */ - @Deprecated - public static final AttributeKey MESSAGING_ROCKETMQ_DELIVERY_TIMESTAMP = - longKey("messaging.rocketmq.delivery_timestamp"); - - - /** - * The delay time level for delay message, which determines the message delay time. - * @deprecated This item has been removed as of 1.17.0 of the semantic conventions. Use {@link SemanticAttributes#MESSAGING_ROCKETMQ_MESSAGE_DELAY_TIME_LEVEL} instead. - */ - @Deprecated - public static final AttributeKey MESSAGING_ROCKETMQ_DELAY_TIME_LEVEL = - longKey("messaging.rocketmq.delay_time_level"); - - /** - * The name of the instrumentation scope - ({@code InstrumentationScope.Name} in OTLP). - * @deprecated This item has been moved, use {@link io.opentelemetry.semconv.resource.attributes.ResourceAttributes#OTEL_SCOPE_NAME} instead. - */ - @Deprecated - public static final AttributeKey OTEL_SCOPE_NAME = stringKey("otel.scope.name"); - - /** - * The version of the instrumentation scope - ({@code InstrumentationScope.Version} in OTLP). - * @deprecated This item has been moved, use {@link io.opentelemetry.semconv.resource.attributes.ResourceAttributes#OTEL_SCOPE_VERSION} instead. - */ - @Deprecated - public static final AttributeKey OTEL_SCOPE_VERSION = stringKey("otel.scope.version"); - - /** - * The execution ID of the current function execution. - * @deprecated This item has been renamed in 1.19.0 version of the semantic conventions. - * Use {@link SemanticAttributes#FAAS_INVOCATION_ID} instead. - */ - @Deprecated - public static final AttributeKey FAAS_EXECUTION = stringKey("faas.execution"); - - /** - * Value of the HTTP - * User-Agent header sent by the client. - * @deprecated This item has been renamed in 1.19.0 version of the semantic conventions. - * Use {@link SemanticAttributes#USER_AGENT_ORIGINAL} instead. - */ - @Deprecated - public static final AttributeKey HTTP_USER_AGENT = stringKey("http.user_agent"); - - /** - * Deprecated. - * - * @deprecated Deprecated, use the {@link io.opentelemetry.semconv.resource.attributes.ResourceAttributes#OTEL_SCOPE_NAME} attribute. - */ - @Deprecated - public static final AttributeKey OTEL_LIBRARY_NAME = stringKey("otel.library.name"); - - /** - * Deprecated. - * - * @deprecated Deprecated, use the {@link io.opentelemetry.semconv.resource.attributes.ResourceAttributes#OTEL_SCOPE_VERSION} attribute. - */ - @Deprecated - public static final AttributeKey OTEL_LIBRARY_VERSION = stringKey("otel.library.version"); - - /** - * Kind of HTTP protocol used. - * @deprecated This item has been removed as of 1.20.0 of the semantic conventions. - */ - @Deprecated - public static final AttributeKey HTTP_FLAVOR = stringKey("http.flavor"); - - /** - * Enum definitions for {@link #HTTP_FLAVOR}. - * @deprecated This item has been removed as of 1.20.0 of the semantic conventions. - */ - @Deprecated - public static final class HttpFlavorValues { - /** HTTP/1.0. */ - public static final String HTTP_1_0 = "1.0"; - - /** HTTP/1.1. */ - public static final String HTTP_1_1 = "1.1"; - - /** HTTP/2. */ - public static final String HTTP_2_0 = "2.0"; - - /** HTTP/3. */ - public static final String HTTP_3_0 = "3.0"; - - /** SPDY protocol. */ - public static final String SPDY = "SPDY"; - - /** QUIC protocol. */ - public static final String QUIC = "QUIC"; - - private HttpFlavorValues() {} - } - - /** - * Application layer protocol used. The value SHOULD be normalized to lowercase. - * @deprecated This item has been removed as of 1.20.0 of the semantic conventions. Use {@link SemanticAttributes#NET_PROTOCOL_NAME} instead. - */ - @Deprecated - public static final AttributeKey NET_APP_PROTOCOL_NAME = stringKey("net.app.protocol.name"); - - /** - * Version of the application layer protocol used. See note below. - * - *

    Notes: - * - *

      - *
    • {@code net.app.protocol.version} refers to the version of the protocol used and might be - * different from the protocol client's version. If the HTTP client used has a version of - * {@code 0.27.2}, but sends HTTP version {@code 1.1}, this attribute should be set to - * {@code 1.1}. - *
    - * @deprecated This item has been removed as of 1.20.0 of the semantic conventions. Use {@link SemanticAttributes#NET_PROTOCOL_VERSION} instead. - */ - @Deprecated - public static final AttributeKey NET_APP_PROTOCOL_VERSION = stringKey("net.app.protocol.version"); - - /** - * The kind of message destination. - * @deprecated This item has been removed as of 1.20.0 of the semantic conventions. - */ - @Deprecated - public static final AttributeKey MESSAGING_DESTINATION_KIND = stringKey("messaging.destination.kind"); - - /** - * Enum values for {@link #MESSAGING_DESTINATION_KIND}. - * @deprecated This item has been removed as of 1.20.0 of the semantic conventions. - */ - @Deprecated - public static final class MessagingDestinationKindValues { - /** A message sent to a queue. */ - public static final String QUEUE = "queue"; - - /** A message sent to a topic. */ - public static final String TOPIC = "topic"; - - private MessagingDestinationKindValues() {} - } - - /** - * The kind of message source. - * @deprecated This item has been removed as of 1.20.0 of the semantic conventions. - */ - @Deprecated - public static final AttributeKey MESSAGING_SOURCE_KIND = stringKey("messaging.source.kind"); - - /** - * Enum values for {@link #MESSAGING_SOURCE_KIND}. - * @deprecated This item has been removed as of 1.20.0 of the semantic conventions. - */ - @Deprecated - public static final class MessagingSourceKindValues { - /** A message received from a queue. */ - public static final String QUEUE = "queue"; - - /** A message received from a topic. */ - public static final String TOPIC = "topic"; - - private MessagingSourceKindValues() {} - } - - {% endif %} - - {%- if class == "ResourceAttributes" %} - - /** - * Red Hat OpenShift on Google Cloud. - * @deprecated This item has been removed as of 1.18.0 of the semantic conventions. Use {@link ResourceAttributes#GCP_OPENSHIFT} instead. - */ - @Deprecated - public static final String GCP_OPENSHIFT = "gcp_openshift"; - - /** - * Full user-agent string provided by the browser - * - *

    Notes: - * - *

      - *
    • The user-agent value SHOULD be provided only from browsers that do not have a mechanism - * to retrieve brands and platform individually from the User-Agent Client Hints API. To - * retrieve the value, the legacy {@code navigator.userAgent} API can be used. - *
    - * @deprecated This item has been renamed in 1.19.0 version of the semantic conventions. Use {@link io.opentelemetry.semconv.trace.attributes.SemanticAttributes#USER_AGENT_ORIGINAL} instead. - */ - @Deprecated - public static final AttributeKey BROWSER_USER_AGENT = stringKey("browser.user_agent"); - - /** - * The unique ID of the single function that this runtime instance executes. - * - *

    Notes: - * - *

      - *
    • On some cloud providers, it may not be possible to determine the full ID at startup, so - * consider setting {@code faas.id} as a span attribute instead. - *
    • The exact value to use for {@code faas.id} depends on the cloud provider: - *
    • AWS Lambda: The function ARN. - * Take care not to use the "invoked ARN" directly but replace any alias - * suffix with the resolved function version, as the same runtime instance may be - * invokable with multiple different aliases. - *
    • GCP: The URI of the resource - *
    • Azure: The Fully - * Qualified Resource ID of the invoked function, not the function app, having - * the form {@code - * /subscriptions//resourceGroups//providers/Microsoft.Web/sites//functions/}. - * This means that a span attribute MUST be used, as an Azure function app can host multiple - * functions that would usually share a TracerProvider. - *
    - * @deprecated This item has been removed in 1.19.0 version of the semantic conventions. Use {@link ResourceAttributes#CLOUD_RESOURCE_ID} instead. - */ - @Deprecated - public static final AttributeKey FAAS_ID = stringKey("faas.id"); - - {% endif %} - - private {{class}}() {} -} diff --git a/sdk-extensions/autoconfigure/README.md b/sdk-extensions/autoconfigure/README.md index 65dd75ac01f..0653fb38061 100644 --- a/sdk-extensions/autoconfigure/README.md +++ b/sdk-extensions/autoconfigure/README.md @@ -170,7 +170,7 @@ is a representation of the entity producing telemetry. | otel.service.name | OTEL_SERVICE_NAME | Specify logical service name. Takes precedence over `service.name` defined with `otel.resource.attributes` | | otel.experimental.resource.disabled-keys | OTEL_EXPERIMENTAL_RESOURCE_DISABLED_KEYS | Specify resource attribute keys that are filtered. | -You almost always want to specify the [`service.name`](https://github.com/open-telemetry/opentelemetry-specification/tree/main/specification/resource/semantic_conventions#service) for your application. +You almost always want to specify the [`service.name`](https://opentelemetry.io/docs/specs/semconv/resource/#service) for your application. It corresponds to how you describe the application, for example `authservice` could be an application that authenticates requests, and `cats` could be an application that returns information about [cats](https://en.wikipedia.org/wiki/Cat). You would specify that by setting service name property in one of the following ways: * directly via `OTEL_SERVICE_NAME=authservice` or `-Dotel.service.name=cats` diff --git a/semconv/README.md b/semconv/README.md deleted file mode 100644 index c70c47abe06..00000000000 --- a/semconv/README.md +++ /dev/null @@ -1,5 +0,0 @@ -# OpenTelemetry Semantic Conventions - -* This module contains generated code for the Semantic Conventions defined by the OpenTelemetry specification. -* Scripts for generating the classes live in the `buildscripts/semantic-convention` directory -at the top level of the project. diff --git a/semconv/build.gradle.kts b/semconv/build.gradle.kts deleted file mode 100644 index 6ddee0bd7b2..00000000000 --- a/semconv/build.gradle.kts +++ /dev/null @@ -1,13 +0,0 @@ -plugins { - id("otel.java-conventions") - id("otel.publish-conventions") - - id("otel.animalsniffer-conventions") -} - -description = "OpenTelemetry Semantic Conventions" -otelJava.moduleName.set("io.opentelemetry.semconv") - -dependencies { - api(project(":api:all")) -} diff --git a/semconv/gradle.properties b/semconv/gradle.properties deleted file mode 100644 index 4476ae57e31..00000000000 --- a/semconv/gradle.properties +++ /dev/null @@ -1 +0,0 @@ -otel.release=alpha diff --git a/semconv/src/main/java/io/opentelemetry/semconv/resource/attributes/ResourceAttributes.java b/semconv/src/main/java/io/opentelemetry/semconv/resource/attributes/ResourceAttributes.java deleted file mode 100644 index af2dccf3274..00000000000 --- a/semconv/src/main/java/io/opentelemetry/semconv/resource/attributes/ResourceAttributes.java +++ /dev/null @@ -1,980 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package io.opentelemetry.semconv.resource.attributes; - -import static io.opentelemetry.api.common.AttributeKey.booleanKey; -import static io.opentelemetry.api.common.AttributeKey.longKey; -import static io.opentelemetry.api.common.AttributeKey.stringArrayKey; -import static io.opentelemetry.api.common.AttributeKey.stringKey; - -import io.opentelemetry.api.common.AttributeKey; -import java.util.List; - -/** - * @deprecated Use {@code io.opentelemetry.semconv.ResourceAttributes} from io.opentelemetry.semconv:opentelemetry-semconv:{{version}} - * instead. - */ -@Deprecated -// DO NOT EDIT, this is an Auto-generated file from -// buildscripts/semantic-convention/templates/SemanticAttributes.java.j2 -@SuppressWarnings("unused") -public final class ResourceAttributes { - /** The URL of the OpenTelemetry schema for these keys and values. */ - public static final String SCHEMA_URL = "https://opentelemetry.io/schemas/1.20.0"; - - /** - * Array of brand name and version separated by a space - * - *

    Notes: - * - *

      - *
    • This value is intended to be taken from the UA client hints API ({@code - * navigator.userAgentData.brands}). - *
    - */ - public static final AttributeKey> BROWSER_BRANDS = stringArrayKey("browser.brands"); - - /** - * The platform on which the browser is running - * - *

    Notes: - * - *

      - *
    • This value is intended to be taken from the UA client hints API ({@code - * navigator.userAgentData.platform}). If unavailable, the legacy {@code navigator.platform} - * API SHOULD NOT be used instead and this attribute SHOULD be left unset in order for the - * values to be consistent. The list of possible values is defined in the W3C User-Agent Client - * Hints specification. Note that some (but not all) of these values can overlap with - * values in the {@code os.type} and {@code os.name} attributes. - * However, for consistency, the values in the {@code browser.platform} attribute should - * capture the exact value that the user agent provides. - *
    - */ - public static final AttributeKey BROWSER_PLATFORM = stringKey("browser.platform"); - - /** - * A boolean that is true if the browser is running on a mobile device - * - *

    Notes: - * - *

      - *
    • This value is intended to be taken from the UA client hints API ({@code - * navigator.userAgentData.mobile}). If unavailable, this attribute SHOULD be left unset. - *
    - */ - public static final AttributeKey BROWSER_MOBILE = booleanKey("browser.mobile"); - - /** - * Preferred language of the user using the browser - * - *

    Notes: - * - *

      - *
    • This value is intended to be taken from the Navigator API {@code navigator.language}. - *
    - */ - public static final AttributeKey BROWSER_LANGUAGE = stringKey("browser.language"); - - /** Name of the cloud provider. */ - public static final AttributeKey CLOUD_PROVIDER = stringKey("cloud.provider"); - - /** The cloud account ID the resource is assigned to. */ - public static final AttributeKey CLOUD_ACCOUNT_ID = stringKey("cloud.account.id"); - - /** - * The geographical region the resource is running. - * - *

    Notes: - * - *

    - */ - public static final AttributeKey CLOUD_REGION = stringKey("cloud.region"); - - /** - * Cloud provider-specific native identifier of the monitored cloud resource (e.g. an ARN on - * AWS, a fully - * qualified resource ID on Azure, a full resource - * name on GCP) - * - *

    Notes: - * - *

      - *
    • On some cloud providers, it may not be possible to determine the full ID at startup, so - * it may be necessary to set {@code cloud.resource_id} as a span attribute instead. - *
    • The exact value to use for {@code cloud.resource_id} depends on the cloud provider. The - * following well-known definitions MUST be used if you set this attribute and they apply: - *
    • AWS Lambda: The function ARN. - * Take care not to use the "invoked ARN" directly but replace any alias - * suffix with the resolved function version, as the same runtime instance may be - * invokable with multiple different aliases. - *
    • GCP: The URI of the resource - *
    • Azure: The Fully - * Qualified Resource ID of the invoked function, not the function app, having - * the form {@code - * /subscriptions//resourceGroups//providers/Microsoft.Web/sites//functions/}. - * This means that a span attribute MUST be used, as an Azure function app can host multiple - * functions that would usually share a TracerProvider. - *
    - */ - public static final AttributeKey CLOUD_RESOURCE_ID = stringKey("cloud.resource_id"); - - /** - * Cloud regions often have multiple, isolated locations known as zones to increase availability. - * Availability zone represents the zone where the resource is running. - * - *

    Notes: - * - *

      - *
    • Availability zones are called "zones" on Alibaba Cloud and Google Cloud. - *
    - */ - public static final AttributeKey CLOUD_AVAILABILITY_ZONE = - stringKey("cloud.availability_zone"); - - /** - * The cloud platform in use. - * - *

    Notes: - * - *

      - *
    • The prefix of the service SHOULD match the one specified in {@code cloud.provider}. - *
    - */ - public static final AttributeKey CLOUD_PLATFORM = stringKey("cloud.platform"); - - /** - * The Amazon Resource Name (ARN) of an ECS - * container instance. - */ - public static final AttributeKey AWS_ECS_CONTAINER_ARN = - stringKey("aws.ecs.container.arn"); - - /** - * The ARN of an ECS - * cluster. - */ - public static final AttributeKey AWS_ECS_CLUSTER_ARN = stringKey("aws.ecs.cluster.arn"); - - /** - * The launch - * type for an ECS task. - */ - public static final AttributeKey AWS_ECS_LAUNCHTYPE = stringKey("aws.ecs.launchtype"); - - /** - * The ARN of an ECS - * task definition. - */ - public static final AttributeKey AWS_ECS_TASK_ARN = stringKey("aws.ecs.task.arn"); - - /** The task definition family this task definition is a member of. */ - public static final AttributeKey AWS_ECS_TASK_FAMILY = stringKey("aws.ecs.task.family"); - - /** The revision for this task definition. */ - public static final AttributeKey AWS_ECS_TASK_REVISION = - stringKey("aws.ecs.task.revision"); - - /** The ARN of an EKS cluster. */ - public static final AttributeKey AWS_EKS_CLUSTER_ARN = stringKey("aws.eks.cluster.arn"); - - /** - * The name(s) of the AWS log group(s) an application is writing to. - * - *

    Notes: - * - *

      - *
    • Multiple log groups must be supported for cases like multi-container applications, where - * a single application has sidecar containers, and each write to their own log group. - *
    - */ - public static final AttributeKey> AWS_LOG_GROUP_NAMES = - stringArrayKey("aws.log.group.names"); - - /** - * The Amazon Resource Name(s) (ARN) of the AWS log group(s). - * - *

    Notes: - * - *

    - */ - public static final AttributeKey> AWS_LOG_GROUP_ARNS = - stringArrayKey("aws.log.group.arns"); - - /** The name(s) of the AWS log stream(s) an application is writing to. */ - public static final AttributeKey> AWS_LOG_STREAM_NAMES = - stringArrayKey("aws.log.stream.names"); - - /** - * The ARN(s) of the AWS log stream(s). - * - *

    Notes: - * - *

    - */ - public static final AttributeKey> AWS_LOG_STREAM_ARNS = - stringArrayKey("aws.log.stream.arns"); - - /** Time and date the release was created */ - public static final AttributeKey HEROKU_RELEASE_CREATION_TIMESTAMP = - stringKey("heroku.release.creation_timestamp"); - - /** Commit hash for the current release */ - public static final AttributeKey HEROKU_RELEASE_COMMIT = - stringKey("heroku.release.commit"); - - /** Unique identifier for the application */ - public static final AttributeKey HEROKU_APP_ID = stringKey("heroku.app.id"); - - /** Container name used by container runtime. */ - public static final AttributeKey CONTAINER_NAME = stringKey("container.name"); - - /** - * Container ID. Usually a UUID, as for example used to identify Docker - * containers. The UUID might be abbreviated. - */ - public static final AttributeKey CONTAINER_ID = stringKey("container.id"); - - /** The container runtime managing this container. */ - public static final AttributeKey CONTAINER_RUNTIME = stringKey("container.runtime"); - - /** Name of the image the container was built on. */ - public static final AttributeKey CONTAINER_IMAGE_NAME = stringKey("container.image.name"); - - /** Container image tag. */ - public static final AttributeKey CONTAINER_IMAGE_TAG = stringKey("container.image.tag"); - - /** - * Name of the deployment - * environment (aka deployment tier). - */ - public static final AttributeKey DEPLOYMENT_ENVIRONMENT = - stringKey("deployment.environment"); - - /** - * A unique identifier representing the device - * - *

    Notes: - * - *

      - *
    • The device identifier MUST only be defined using the values outlined below. This value is - * not an advertising identifier and MUST NOT be used as such. On iOS (Swift or - * Objective-C), this value MUST be equal to the vendor - * identifier. On Android (Java or Kotlin), this value MUST be equal to the Firebase - * Installation ID or a globally unique UUID which is persisted across sessions in your - * application. More information can be found here on best - * practices and exact implementation details. Caution should be taken when storing personal - * data or anything which can identify a user. GDPR and data protection laws may apply, - * ensure you do your own due diligence. - *
    - */ - public static final AttributeKey DEVICE_ID = stringKey("device.id"); - - /** - * The model identifier for the device - * - *

    Notes: - * - *

      - *
    • It's recommended this value represents a machine readable version of the model identifier - * rather than the market or consumer-friendly name of the device. - *
    - */ - public static final AttributeKey DEVICE_MODEL_IDENTIFIER = - stringKey("device.model.identifier"); - - /** - * The marketing name for the device model - * - *

    Notes: - * - *

      - *
    • It's recommended this value represents a human readable version of the device model - * rather than a machine readable alternative. - *
    - */ - public static final AttributeKey DEVICE_MODEL_NAME = stringKey("device.model.name"); - - /** - * The name of the device manufacturer - * - *

    Notes: - * - *

      - *
    • The Android OS provides this field via Build. - * iOS apps SHOULD hardcode the value {@code Apple}. - *
    - */ - public static final AttributeKey DEVICE_MANUFACTURER = stringKey("device.manufacturer"); - - /** - * The name of the single function that this runtime instance executes. - * - *

    Notes: - * - *

      - *
    • This is the name of the function as configured/deployed on the FaaS platform and is - * usually different from the name of the callback function (which may be stored in the {@code - * code.namespace}/{@code code.function} span attributes). - *
    • For some cloud providers, the above definition is ambiguous. The following definition of - * function name MUST be used for this attribute (and consequently the span name) for the - * listed cloud providers/products: - *
    • Azure: The full name {@code /}, i.e., function app name - * followed by a forward slash followed by the function name (this form can also be seen in - * the resource JSON for the function). This means that a span attribute MUST be used, as an - * Azure function app can host multiple functions that would usually share a TracerProvider - * (see also the {@code cloud.resource_id} attribute). - *
    - */ - public static final AttributeKey FAAS_NAME = stringKey("faas.name"); - - /** - * The immutable version of the function being executed. - * - *

    Notes: - * - *

      - *
    • Depending on the cloud provider and platform, use: - *
    • AWS Lambda: The function - * version (an integer represented as a decimal string). - *
    • Google Cloud Run: The revision (i.e., the - * function name plus the revision suffix). - *
    • Google Cloud Functions: The value of the {@code - * K_REVISION} environment variable. - *
    • Azure Functions: Not applicable. Do not set this attribute. - *
    - */ - public static final AttributeKey FAAS_VERSION = stringKey("faas.version"); - - /** - * The execution environment ID as a string, that will be potentially reused for other invocations - * to the same function/function version. - * - *

    Notes: - * - *

      - *
    • AWS Lambda: Use the (full) log stream name. - *
    - */ - public static final AttributeKey FAAS_INSTANCE = stringKey("faas.instance"); - - /** - * The amount of memory available to the serverless function converted to Bytes. - * - *

    Notes: - * - *

      - *
    • It's recommended to set this attribute since e.g. too little memory can easily stop a - * Java AWS Lambda function from working correctly. On AWS Lambda, the environment variable - * {@code AWS_LAMBDA_FUNCTION_MEMORY_SIZE} provides this information (which must be - * multiplied by 1,048,576). - *
    - */ - public static final AttributeKey FAAS_MAX_MEMORY = longKey("faas.max_memory"); - - /** - * Unique host ID. For Cloud, this must be the instance_id assigned by the cloud provider. For - * non-containerized systems, this should be the {@code machine-id}. See the table below for the - * sources to use to determine the {@code machine-id} based on operating system. - */ - public static final AttributeKey HOST_ID = stringKey("host.id"); - - /** - * Name of the host. On Unix systems, it may contain what the hostname command returns, or the - * fully qualified hostname, or another name specified by the user. - */ - public static final AttributeKey HOST_NAME = stringKey("host.name"); - - /** Type of host. For Cloud, this must be the machine type. */ - public static final AttributeKey HOST_TYPE = stringKey("host.type"); - - /** The CPU architecture the host system is running on. */ - public static final AttributeKey HOST_ARCH = stringKey("host.arch"); - - /** Name of the VM image or OS install the host was instantiated from. */ - public static final AttributeKey HOST_IMAGE_NAME = stringKey("host.image.name"); - - /** VM image ID. For Cloud, this value is from the provider. */ - public static final AttributeKey HOST_IMAGE_ID = stringKey("host.image.id"); - - /** - * The version string of the VM image as defined in Version - * Attributes. - */ - public static final AttributeKey HOST_IMAGE_VERSION = stringKey("host.image.version"); - - /** The name of the cluster. */ - public static final AttributeKey K8S_CLUSTER_NAME = stringKey("k8s.cluster.name"); - - /** The name of the Node. */ - public static final AttributeKey K8S_NODE_NAME = stringKey("k8s.node.name"); - - /** The UID of the Node. */ - public static final AttributeKey K8S_NODE_UID = stringKey("k8s.node.uid"); - - /** The name of the namespace that the pod is running in. */ - public static final AttributeKey K8S_NAMESPACE_NAME = stringKey("k8s.namespace.name"); - - /** The UID of the Pod. */ - public static final AttributeKey K8S_POD_UID = stringKey("k8s.pod.uid"); - - /** The name of the Pod. */ - public static final AttributeKey K8S_POD_NAME = stringKey("k8s.pod.name"); - - /** - * The name of the Container from Pod specification, must be unique within a Pod. Container - * runtime usually uses different globally unique name ({@code container.name}). - */ - public static final AttributeKey K8S_CONTAINER_NAME = stringKey("k8s.container.name"); - - /** - * Number of times the container was restarted. This attribute can be used to identify a - * particular container (running or stopped) within a container spec. - */ - public static final AttributeKey K8S_CONTAINER_RESTART_COUNT = - longKey("k8s.container.restart_count"); - - /** The UID of the ReplicaSet. */ - public static final AttributeKey K8S_REPLICASET_UID = stringKey("k8s.replicaset.uid"); - - /** The name of the ReplicaSet. */ - public static final AttributeKey K8S_REPLICASET_NAME = stringKey("k8s.replicaset.name"); - - /** The UID of the Deployment. */ - public static final AttributeKey K8S_DEPLOYMENT_UID = stringKey("k8s.deployment.uid"); - - /** The name of the Deployment. */ - public static final AttributeKey K8S_DEPLOYMENT_NAME = stringKey("k8s.deployment.name"); - - /** The UID of the StatefulSet. */ - public static final AttributeKey K8S_STATEFULSET_UID = stringKey("k8s.statefulset.uid"); - - /** The name of the StatefulSet. */ - public static final AttributeKey K8S_STATEFULSET_NAME = stringKey("k8s.statefulset.name"); - - /** The UID of the DaemonSet. */ - public static final AttributeKey K8S_DAEMONSET_UID = stringKey("k8s.daemonset.uid"); - - /** The name of the DaemonSet. */ - public static final AttributeKey K8S_DAEMONSET_NAME = stringKey("k8s.daemonset.name"); - - /** The UID of the Job. */ - public static final AttributeKey K8S_JOB_UID = stringKey("k8s.job.uid"); - - /** The name of the Job. */ - public static final AttributeKey K8S_JOB_NAME = stringKey("k8s.job.name"); - - /** The UID of the CronJob. */ - public static final AttributeKey K8S_CRONJOB_UID = stringKey("k8s.cronjob.uid"); - - /** The name of the CronJob. */ - public static final AttributeKey K8S_CRONJOB_NAME = stringKey("k8s.cronjob.name"); - - /** The operating system type. */ - public static final AttributeKey OS_TYPE = stringKey("os.type"); - - /** - * Human readable (not intended to be parsed) OS version information, like e.g. reported by {@code - * ver} or {@code lsb_release -a} commands. - */ - public static final AttributeKey OS_DESCRIPTION = stringKey("os.description"); - - /** Human readable operating system name. */ - public static final AttributeKey OS_NAME = stringKey("os.name"); - - /** - * The version string of the operating system as defined in Version Attributes. - */ - public static final AttributeKey OS_VERSION = stringKey("os.version"); - - /** Process identifier (PID). */ - public static final AttributeKey PROCESS_PID = longKey("process.pid"); - - /** Parent Process identifier (PID). */ - public static final AttributeKey PROCESS_PARENT_PID = longKey("process.parent_pid"); - - /** - * The name of the process executable. On Linux based systems, can be set to the {@code Name} in - * {@code proc/[pid]/status}. On Windows, can be set to the base name of {@code - * GetProcessImageFileNameW}. - */ - public static final AttributeKey PROCESS_EXECUTABLE_NAME = - stringKey("process.executable.name"); - - /** - * The full path to the process executable. On Linux based systems, can be set to the target of - * {@code proc/[pid]/exe}. On Windows, can be set to the result of {@code - * GetProcessImageFileNameW}. - */ - public static final AttributeKey PROCESS_EXECUTABLE_PATH = - stringKey("process.executable.path"); - - /** - * The command used to launch the process (i.e. the command name). On Linux based systems, can be - * set to the zeroth string in {@code proc/[pid]/cmdline}. On Windows, can be set to the first - * parameter extracted from {@code GetCommandLineW}. - */ - public static final AttributeKey PROCESS_COMMAND = stringKey("process.command"); - - /** - * The full command used to launch the process as a single string representing the full command. - * On Windows, can be set to the result of {@code GetCommandLineW}. Do not set this if you have to - * assemble it just for monitoring; use {@code process.command_args} instead. - */ - public static final AttributeKey PROCESS_COMMAND_LINE = stringKey("process.command_line"); - - /** - * All the command arguments (including the command/executable itself) as received by the process. - * On Linux-based systems (and some other Unixoid systems supporting procfs), can be set according - * to the list of null-delimited strings extracted from {@code proc/[pid]/cmdline}. For libc-based - * executables, this would be the full argv vector passed to {@code main}. - */ - public static final AttributeKey> PROCESS_COMMAND_ARGS = - stringArrayKey("process.command_args"); - - /** The username of the user that owns the process. */ - public static final AttributeKey PROCESS_OWNER = stringKey("process.owner"); - - /** - * The name of the runtime of this process. For compiled native binaries, this SHOULD be the name - * of the compiler. - */ - public static final AttributeKey PROCESS_RUNTIME_NAME = stringKey("process.runtime.name"); - - /** - * The version of the runtime of this process, as returned by the runtime without modification. - */ - public static final AttributeKey PROCESS_RUNTIME_VERSION = - stringKey("process.runtime.version"); - - /** - * An additional description about the runtime of the process, for example a specific vendor - * customization of the runtime environment. - */ - public static final AttributeKey PROCESS_RUNTIME_DESCRIPTION = - stringKey("process.runtime.description"); - - /** - * Logical name of the service. - * - *

    Notes: - * - *

      - *
    • MUST be the same for all instances of horizontally scaled services. If the value was not - * specified, SDKs MUST fallback to {@code unknown_service:} concatenated with {@code process.executable.name}, e.g. {@code - * unknown_service:bash}. If {@code process.executable.name} is not available, the value - * MUST be set to {@code unknown_service}. - *
    - */ - public static final AttributeKey SERVICE_NAME = stringKey("service.name"); - - /** - * A namespace for {@code service.name}. - * - *

    Notes: - * - *

      - *
    • A string value having a meaning that helps to distinguish a group of services, for - * example the team name that owns a group of services. {@code service.name} is expected to - * be unique within the same namespace. If {@code service.namespace} is not specified in the - * Resource then {@code service.name} is expected to be unique for all services that have no - * explicit namespace defined (so the empty/unspecified namespace is simply one more valid - * namespace). Zero-length namespace string is assumed equal to unspecified namespace. - *
    - */ - public static final AttributeKey SERVICE_NAMESPACE = stringKey("service.namespace"); - - /** - * The string ID of the service instance. - * - *

    Notes: - * - *

      - *
    • MUST be unique for each instance of the same {@code service.namespace,service.name} pair - * (in other words {@code service.namespace,service.name,service.instance.id} triplet MUST - * be globally unique). The ID helps to distinguish instances of the same service that exist - * at the same time (e.g. instances of a horizontally scaled service). It is preferable for - * the ID to be persistent and stay the same for the lifetime of the service instance, - * however it is acceptable that the ID is ephemeral and changes during important lifetime - * events for the service (e.g. service restarts). If the service has no inherent unique ID - * that can be used as the value of this attribute it is recommended to generate a random - * Version 1 or Version 4 RFC 4122 UUID (services aiming for reproducible UUIDs may also use - * Version 5, see RFC 4122 for more recommendations). - *
    - */ - public static final AttributeKey SERVICE_INSTANCE_ID = stringKey("service.instance.id"); - - /** The version string of the service API or implementation. */ - public static final AttributeKey SERVICE_VERSION = stringKey("service.version"); - - /** The name of the telemetry SDK as defined above. */ - public static final AttributeKey TELEMETRY_SDK_NAME = stringKey("telemetry.sdk.name"); - - /** The language of the telemetry SDK. */ - public static final AttributeKey TELEMETRY_SDK_LANGUAGE = - stringKey("telemetry.sdk.language"); - - /** The version string of the telemetry SDK. */ - public static final AttributeKey TELEMETRY_SDK_VERSION = - stringKey("telemetry.sdk.version"); - - /** The version string of the auto instrumentation agent, if used. */ - public static final AttributeKey TELEMETRY_AUTO_VERSION = - stringKey("telemetry.auto.version"); - - /** The name of the web engine. */ - public static final AttributeKey WEBENGINE_NAME = stringKey("webengine.name"); - - /** The version of the web engine. */ - public static final AttributeKey WEBENGINE_VERSION = stringKey("webengine.version"); - - /** Additional description of the web engine (e.g. detailed version and edition information). */ - public static final AttributeKey WEBENGINE_DESCRIPTION = - stringKey("webengine.description"); - - /** The name of the instrumentation scope - ({@code InstrumentationScope.Name} in OTLP). */ - public static final AttributeKey OTEL_SCOPE_NAME = stringKey("otel.scope.name"); - - /** The version of the instrumentation scope - ({@code InstrumentationScope.Version} in OTLP). */ - public static final AttributeKey OTEL_SCOPE_VERSION = stringKey("otel.scope.version"); - - /** - * Deprecated, use the {@code otel.scope.name} attribute. - * - * @deprecated Deprecated, use the `otel.scope.name` attribute. - */ - @Deprecated - public static final AttributeKey OTEL_LIBRARY_NAME = stringKey("otel.library.name"); - - /** - * Deprecated, use the {@code otel.scope.version} attribute. - * - * @deprecated Deprecated, use the `otel.scope.version` attribute. - */ - @Deprecated - public static final AttributeKey OTEL_LIBRARY_VERSION = stringKey("otel.library.version"); - - // Enum definitions - public static final class CloudProviderValues { - /** Alibaba Cloud. */ - public static final String ALIBABA_CLOUD = "alibaba_cloud"; - - /** Amazon Web Services. */ - public static final String AWS = "aws"; - - /** Microsoft Azure. */ - public static final String AZURE = "azure"; - - /** Google Cloud Platform. */ - public static final String GCP = "gcp"; - - /** Heroku Platform as a Service. */ - public static final String HEROKU = "heroku"; - - /** IBM Cloud. */ - public static final String IBM_CLOUD = "ibm_cloud"; - - /** Tencent Cloud. */ - public static final String TENCENT_CLOUD = "tencent_cloud"; - - private CloudProviderValues() {} - } - - public static final class CloudPlatformValues { - /** Alibaba Cloud Elastic Compute Service. */ - public static final String ALIBABA_CLOUD_ECS = "alibaba_cloud_ecs"; - - /** Alibaba Cloud Function Compute. */ - public static final String ALIBABA_CLOUD_FC = "alibaba_cloud_fc"; - - /** Red Hat OpenShift on Alibaba Cloud. */ - public static final String ALIBABA_CLOUD_OPENSHIFT = "alibaba_cloud_openshift"; - - /** AWS Elastic Compute Cloud. */ - public static final String AWS_EC2 = "aws_ec2"; - - /** AWS Elastic Container Service. */ - public static final String AWS_ECS = "aws_ecs"; - - /** AWS Elastic Kubernetes Service. */ - public static final String AWS_EKS = "aws_eks"; - - /** AWS Lambda. */ - public static final String AWS_LAMBDA = "aws_lambda"; - - /** AWS Elastic Beanstalk. */ - public static final String AWS_ELASTIC_BEANSTALK = "aws_elastic_beanstalk"; - - /** AWS App Runner. */ - public static final String AWS_APP_RUNNER = "aws_app_runner"; - - /** Red Hat OpenShift on AWS (ROSA). */ - public static final String AWS_OPENSHIFT = "aws_openshift"; - - /** Azure Virtual Machines. */ - public static final String AZURE_VM = "azure_vm"; - - /** Azure Container Instances. */ - public static final String AZURE_CONTAINER_INSTANCES = "azure_container_instances"; - - /** Azure Kubernetes Service. */ - public static final String AZURE_AKS = "azure_aks"; - - /** Azure Functions. */ - public static final String AZURE_FUNCTIONS = "azure_functions"; - - /** Azure App Service. */ - public static final String AZURE_APP_SERVICE = "azure_app_service"; - - /** Azure Red Hat OpenShift. */ - public static final String AZURE_OPENSHIFT = "azure_openshift"; - - /** Google Cloud Compute Engine (GCE). */ - public static final String GCP_COMPUTE_ENGINE = "gcp_compute_engine"; - - /** Google Cloud Run. */ - public static final String GCP_CLOUD_RUN = "gcp_cloud_run"; - - /** Google Cloud Kubernetes Engine (GKE). */ - public static final String GCP_KUBERNETES_ENGINE = "gcp_kubernetes_engine"; - - /** Google Cloud Functions (GCF). */ - public static final String GCP_CLOUD_FUNCTIONS = "gcp_cloud_functions"; - - /** Google Cloud App Engine (GAE). */ - public static final String GCP_APP_ENGINE = "gcp_app_engine"; - - /** Red Hat OpenShift on Google Cloud. */ - public static final String GCP_OPENSHIFT = "gcp_openshift"; - - /** Red Hat OpenShift on IBM Cloud. */ - public static final String IBM_CLOUD_OPENSHIFT = "ibm_cloud_openshift"; - - /** Tencent Cloud Cloud Virtual Machine (CVM). */ - public static final String TENCENT_CLOUD_CVM = "tencent_cloud_cvm"; - - /** Tencent Cloud Elastic Kubernetes Service (EKS). */ - public static final String TENCENT_CLOUD_EKS = "tencent_cloud_eks"; - - /** Tencent Cloud Serverless Cloud Function (SCF). */ - public static final String TENCENT_CLOUD_SCF = "tencent_cloud_scf"; - - private CloudPlatformValues() {} - } - - public static final class AwsEcsLaunchtypeValues { - /** ec2. */ - public static final String EC2 = "ec2"; - - /** fargate. */ - public static final String FARGATE = "fargate"; - - private AwsEcsLaunchtypeValues() {} - } - - public static final class HostArchValues { - /** AMD64. */ - public static final String AMD64 = "amd64"; - - /** ARM32. */ - public static final String ARM32 = "arm32"; - - /** ARM64. */ - public static final String ARM64 = "arm64"; - - /** Itanium. */ - public static final String IA64 = "ia64"; - - /** 32-bit PowerPC. */ - public static final String PPC32 = "ppc32"; - - /** 64-bit PowerPC. */ - public static final String PPC64 = "ppc64"; - - /** IBM z/Architecture. */ - public static final String S390X = "s390x"; - - /** 32-bit x86. */ - public static final String X86 = "x86"; - - private HostArchValues() {} - } - - public static final class OsTypeValues { - /** Microsoft Windows. */ - public static final String WINDOWS = "windows"; - - /** Linux. */ - public static final String LINUX = "linux"; - - /** Apple Darwin. */ - public static final String DARWIN = "darwin"; - - /** FreeBSD. */ - public static final String FREEBSD = "freebsd"; - - /** NetBSD. */ - public static final String NETBSD = "netbsd"; - - /** OpenBSD. */ - public static final String OPENBSD = "openbsd"; - - /** DragonFly BSD. */ - public static final String DRAGONFLYBSD = "dragonflybsd"; - - /** HP-UX (Hewlett Packard Unix). */ - public static final String HPUX = "hpux"; - - /** AIX (Advanced Interactive eXecutive). */ - public static final String AIX = "aix"; - - /** SunOS, Oracle Solaris. */ - public static final String SOLARIS = "solaris"; - - /** IBM z/OS. */ - public static final String Z_OS = "z_os"; - - private OsTypeValues() {} - } - - public static final class TelemetrySdkLanguageValues { - /** cpp. */ - public static final String CPP = "cpp"; - - /** dotnet. */ - public static final String DOTNET = "dotnet"; - - /** erlang. */ - public static final String ERLANG = "erlang"; - - /** go. */ - public static final String GO = "go"; - - /** java. */ - public static final String JAVA = "java"; - - /** nodejs. */ - public static final String NODEJS = "nodejs"; - - /** php. */ - public static final String PHP = "php"; - - /** python. */ - public static final String PYTHON = "python"; - - /** ruby. */ - public static final String RUBY = "ruby"; - - /** webjs. */ - public static final String WEBJS = "webjs"; - - /** swift. */ - public static final String SWIFT = "swift"; - - private TelemetrySdkLanguageValues() {} - } - - /** - * Red Hat OpenShift on Google Cloud. - * - * @deprecated This item has been removed as of 1.18.0 of the semantic conventions. Use {@link - * ResourceAttributes#GCP_OPENSHIFT} instead. - */ - @Deprecated public static final String GCP_OPENSHIFT = "gcp_openshift"; - - /** - * Full user-agent string provided by the browser - * - *

    Notes: - * - *

      - *
    • The user-agent value SHOULD be provided only from browsers that do not have a mechanism - * to retrieve brands and platform individually from the User-Agent Client Hints API. To - * retrieve the value, the legacy {@code navigator.userAgent} API can be used. - *
    - * - * @deprecated This item has been renamed in 1.19.0 version of the semantic conventions. Use - * {@link io.opentelemetry.semconv.trace.attributes.SemanticAttributes#USER_AGENT_ORIGINAL} - * instead. - */ - @Deprecated - public static final AttributeKey BROWSER_USER_AGENT = stringKey("browser.user_agent"); - - /** - * The unique ID of the single function that this runtime instance executes. - * - *

    Notes: - * - *

      - *
    • On some cloud providers, it may not be possible to determine the full ID at startup, so - * consider setting {@code faas.id} as a span attribute instead. - *
    • The exact value to use for {@code faas.id} depends on the cloud provider: - *
    • AWS Lambda: The function ARN. - * Take care not to use the "invoked ARN" directly but replace any alias - * suffix with the resolved function version, as the same runtime instance may be - * invokable with multiple different aliases. - *
    • GCP: The URI of the resource - *
    • Azure: The Fully - * Qualified Resource ID of the invoked function, not the function app, having - * the form {@code - * /subscriptions//resourceGroups//providers/Microsoft.Web/sites//functions/}. - * This means that a span attribute MUST be used, as an Azure function app can host multiple - * functions that would usually share a TracerProvider. - *
    - * - * @deprecated This item has been removed in 1.19.0 version of the semantic conventions. Use - * {@link ResourceAttributes#CLOUD_RESOURCE_ID} instead. - */ - @Deprecated public static final AttributeKey FAAS_ID = stringKey("faas.id"); - - private ResourceAttributes() {} -} diff --git a/semconv/src/main/java/io/opentelemetry/semconv/resource/attributes/package-info.java b/semconv/src/main/java/io/opentelemetry/semconv/resource/attributes/package-info.java deleted file mode 100644 index d893dd794bf..00000000000 --- a/semconv/src/main/java/io/opentelemetry/semconv/resource/attributes/package-info.java +++ /dev/null @@ -1,14 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -/** - * OpenTelemetry semantic attributes for resources. - * - * @see io.opentelemetry.semconv.resource.attributes.ResourceAttributes - */ -@ParametersAreNonnullByDefault -package io.opentelemetry.semconv.resource.attributes; - -import javax.annotation.ParametersAreNonnullByDefault; diff --git a/semconv/src/main/java/io/opentelemetry/semconv/trace/attributes/SemanticAttributes.java b/semconv/src/main/java/io/opentelemetry/semconv/trace/attributes/SemanticAttributes.java deleted file mode 100644 index d05fbf85ae1..00000000000 --- a/semconv/src/main/java/io/opentelemetry/semconv/trace/attributes/SemanticAttributes.java +++ /dev/null @@ -1,2322 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package io.opentelemetry.semconv.trace.attributes; - -import static io.opentelemetry.api.common.AttributeKey.booleanKey; -import static io.opentelemetry.api.common.AttributeKey.doubleKey; -import static io.opentelemetry.api.common.AttributeKey.longKey; -import static io.opentelemetry.api.common.AttributeKey.stringArrayKey; -import static io.opentelemetry.api.common.AttributeKey.stringKey; - -import io.opentelemetry.api.common.AttributeKey; -import java.util.List; - -/** - * @deprecated Use {@code io.opentelemetry.semconv.SemanticAttributes} from io.opentelemetry.semconv:opentelemetry-semconv:{{version}} - * instead. - */ -@Deprecated -// DO NOT EDIT, this is an Auto-generated file from -// buildscripts/semantic-convention/templates/SemanticAttributes.java.j2 -@SuppressWarnings("unused") -public final class SemanticAttributes { - /** The URL of the OpenTelemetry schema for these keys and values. */ - public static final String SCHEMA_URL = "https://opentelemetry.io/schemas/1.20.0"; - - /** - * The type of the exception (its fully-qualified class name, if applicable). The dynamic type of - * the exception should be preferred over the static type in languages that support it. - */ - public static final AttributeKey EXCEPTION_TYPE = stringKey("exception.type"); - - /** The exception message. */ - public static final AttributeKey EXCEPTION_MESSAGE = stringKey("exception.message"); - - /** - * A stacktrace as a string in the natural representation for the language runtime. The - * representation is to be determined and documented by each language SIG. - */ - public static final AttributeKey EXCEPTION_STACKTRACE = stringKey("exception.stacktrace"); - - /** HTTP request method. */ - public static final AttributeKey HTTP_METHOD = stringKey("http.method"); - - /** HTTP response status code. */ - public static final AttributeKey HTTP_STATUS_CODE = longKey("http.status_code"); - - /** The URI scheme identifying the used protocol. */ - public static final AttributeKey HTTP_SCHEME = stringKey("http.scheme"); - - /** - * The matched route (path template in the format used by the respective server framework). See - * note below - * - *

    Notes: - * - *

      - *
    • MUST NOT be populated when this is not supported by the HTTP server framework as the - * route attribute should have low-cardinality and the URI path can NOT substitute it. - * SHOULD include the application - * root if there is one. - *
    - */ - public static final AttributeKey HTTP_ROUTE = stringKey("http.route"); - - /** The name identifies the event. */ - public static final AttributeKey EVENT_NAME = stringKey("event.name"); - - /** - * The domain identifies the business context for the events. - * - *

    Notes: - * - *

      - *
    • Events across different domains may have same {@code event.name}, yet be unrelated - * events. - *
    - */ - public static final AttributeKey EVENT_DOMAIN = stringKey("event.domain"); - - /** - * A unique identifier for the Log Record. - * - *

    Notes: - * - *

      - *
    • If an id is provided, other log records with the same id will be considered duplicates - * and can be removed safely. This means, that two distinguishable log records MUST have - * different values. The id MAY be an Universally - * Unique Lexicographically Sortable Identifier (ULID), but other identifiers (e.g. - * UUID) may be used as needed. - *
    - */ - public static final AttributeKey LOG_RECORD_UID = stringKey("log.record.uid"); - - /** - * The full invoked ARN as provided on the {@code Context} passed to the function ({@code - * Lambda-Runtime-Invoked-Function-Arn} header on the {@code /runtime/invocation/next} - * applicable). - * - *

    Notes: - * - *

      - *
    • This may be different from {@code cloud.resource_id} if an alias is involved. - *
    - */ - public static final AttributeKey AWS_LAMBDA_INVOKED_ARN = - stringKey("aws.lambda.invoked_arn"); - - /** - * The event_id - * uniquely identifies the event. - */ - public static final AttributeKey CLOUDEVENTS_EVENT_ID = stringKey("cloudevents.event_id"); - - /** - * The source - * identifies the context in which an event happened. - */ - public static final AttributeKey CLOUDEVENTS_EVENT_SOURCE = - stringKey("cloudevents.event_source"); - - /** - * The version - * of the CloudEvents specification which the event uses. - */ - public static final AttributeKey CLOUDEVENTS_EVENT_SPEC_VERSION = - stringKey("cloudevents.event_spec_version"); - - /** - * The event_type - * contains a value describing the type of event related to the originating occurrence. - */ - public static final AttributeKey CLOUDEVENTS_EVENT_TYPE = - stringKey("cloudevents.event_type"); - - /** - * The subject - * of the event in the context of the event producer (identified by source). - */ - public static final AttributeKey CLOUDEVENTS_EVENT_SUBJECT = - stringKey("cloudevents.event_subject"); - - /** - * Parent-child Reference type - * - *

    Notes: - * - *

      - *
    • The causal relationship between a child Span and a parent Span. - *
    - */ - public static final AttributeKey OPENTRACING_REF_TYPE = stringKey("opentracing.ref_type"); - - /** - * An identifier for the database management system (DBMS) product being used. See below for a - * list of well-known identifiers. - */ - public static final AttributeKey DB_SYSTEM = stringKey("db.system"); - - /** - * The connection string used to connect to the database. It is recommended to remove embedded - * credentials. - */ - public static final AttributeKey DB_CONNECTION_STRING = stringKey("db.connection_string"); - - /** Username for accessing the database. */ - public static final AttributeKey DB_USER = stringKey("db.user"); - - /** - * The fully-qualified class name of the Java Database Connectivity - * (JDBC) driver used to connect. - */ - public static final AttributeKey DB_JDBC_DRIVER_CLASSNAME = - stringKey("db.jdbc.driver_classname"); - - /** - * This attribute is used to report the name of the database being accessed. For commands that - * switch the database, this should be set to the target database (even if the command fails). - * - *

    Notes: - * - *

      - *
    • In some SQL databases, the database name to be used is called "schema name". In - * case there are multiple layers that could be considered for database name (e.g. Oracle - * instance name and schema name), the database name to be used is the more specific layer - * (e.g. Oracle schema name). - *
    - */ - public static final AttributeKey DB_NAME = stringKey("db.name"); - - /** The database statement being executed. */ - public static final AttributeKey DB_STATEMENT = stringKey("db.statement"); - - /** - * The name of the operation being executed, e.g. the MongoDB command - * name such as {@code findAndModify}, or the SQL keyword. - * - *

    Notes: - * - *

      - *
    • When setting this to an SQL keyword, it is not recommended to attempt any client-side - * parsing of {@code db.statement} just to get this property, but it should be set if the - * operation name is provided by the library being instrumented. If the SQL statement has an - * ambiguous operation, or performs more than one operation, this value may be omitted. - *
    - */ - public static final AttributeKey DB_OPERATION = stringKey("db.operation"); - - /** - * The Microsoft SQL Server instance - * name connecting to. This name is used to determine the port of a named instance. - * - *

    Notes: - * - *

      - *
    • If setting a {@code db.mssql.instance_name}, {@code net.peer.port} is no longer required - * (but still recommended if non-standard). - *
    - */ - public static final AttributeKey DB_MSSQL_INSTANCE_NAME = - stringKey("db.mssql.instance_name"); - - /** The fetch size used for paging, i.e. how many rows will be returned at once. */ - public static final AttributeKey DB_CASSANDRA_PAGE_SIZE = longKey("db.cassandra.page_size"); - - /** - * The consistency level of the query. Based on consistency values from CQL. - */ - public static final AttributeKey DB_CASSANDRA_CONSISTENCY_LEVEL = - stringKey("db.cassandra.consistency_level"); - - /** - * The name of the primary table that the operation is acting upon, including the keyspace name - * (if applicable). - * - *

    Notes: - * - *

      - *
    • This mirrors the db.sql.table attribute but references cassandra rather than sql. It is - * not recommended to attempt any client-side parsing of {@code db.statement} just to get - * this property, but it should be set if it is provided by the library being instrumented. - * If the operation is acting upon an anonymous table, or more than one table, this value - * MUST NOT be set. - *
    - */ - public static final AttributeKey DB_CASSANDRA_TABLE = stringKey("db.cassandra.table"); - - /** Whether or not the query is idempotent. */ - public static final AttributeKey DB_CASSANDRA_IDEMPOTENCE = - booleanKey("db.cassandra.idempotence"); - - /** - * The number of times a query was speculatively executed. Not set or {@code 0} if the query was - * not executed speculatively. - */ - public static final AttributeKey DB_CASSANDRA_SPECULATIVE_EXECUTION_COUNT = - longKey("db.cassandra.speculative_execution_count"); - - /** The ID of the coordinating node for a query. */ - public static final AttributeKey DB_CASSANDRA_COORDINATOR_ID = - stringKey("db.cassandra.coordinator.id"); - - /** The data center of the coordinating node for a query. */ - public static final AttributeKey DB_CASSANDRA_COORDINATOR_DC = - stringKey("db.cassandra.coordinator.dc"); - - /** - * The index of the database being accessed as used in the {@code SELECT} command, provided as an integer. To - * be used instead of the generic {@code db.name} attribute. - */ - public static final AttributeKey DB_REDIS_DATABASE_INDEX = - longKey("db.redis.database_index"); - - /** The collection being accessed within the database stated in {@code db.name}. */ - public static final AttributeKey DB_MONGODB_COLLECTION = - stringKey("db.mongodb.collection"); - - /** - * The name of the primary table that the operation is acting upon, including the database name - * (if applicable). - * - *

    Notes: - * - *

      - *
    • It is not recommended to attempt any client-side parsing of {@code db.statement} just to - * get this property, but it should be set if it is provided by the library being - * instrumented. If the operation is acting upon an anonymous table, or more than one table, - * this value MUST NOT be set. - *
    - */ - public static final AttributeKey DB_SQL_TABLE = stringKey("db.sql.table"); - - /** Unique Cosmos client instance id. */ - public static final AttributeKey DB_COSMOSDB_CLIENT_ID = - stringKey("db.cosmosdb.client_id"); - - /** CosmosDB Operation Type. */ - public static final AttributeKey DB_COSMOSDB_OPERATION_TYPE = - stringKey("db.cosmosdb.operation_type"); - - /** Cosmos client connection mode. */ - public static final AttributeKey DB_COSMOSDB_CONNECTION_MODE = - stringKey("db.cosmosdb.connection_mode"); - - /** Cosmos DB container name. */ - public static final AttributeKey DB_COSMOSDB_CONTAINER = - stringKey("db.cosmosdb.container"); - - /** Request payload size in bytes */ - public static final AttributeKey DB_COSMOSDB_REQUEST_CONTENT_LENGTH = - longKey("db.cosmosdb.request_content_length"); - - /** Cosmos DB status code. */ - public static final AttributeKey DB_COSMOSDB_STATUS_CODE = - longKey("db.cosmosdb.status_code"); - - /** Cosmos DB sub status code. */ - public static final AttributeKey DB_COSMOSDB_SUB_STATUS_CODE = - longKey("db.cosmosdb.sub_status_code"); - - /** RU consumed for that operation */ - public static final AttributeKey DB_COSMOSDB_REQUEST_CHARGE = - doubleKey("db.cosmosdb.request_charge"); - - /** - * Name of the code, either "OK" or "ERROR". MUST NOT be set if the status - * code is UNSET. - */ - public static final AttributeKey OTEL_STATUS_CODE = stringKey("otel.status_code"); - - /** Description of the Status if it has a value, otherwise not set. */ - public static final AttributeKey OTEL_STATUS_DESCRIPTION = - stringKey("otel.status_description"); - - /** - * Type of the trigger which caused this function invocation. - * - *

    Notes: - * - *

      - *
    • For the server/consumer span on the incoming side, {@code faas.trigger} MUST be set. - *
    • Clients invoking FaaS instances usually cannot set {@code faas.trigger}, since they would - * typically need to look in the payload to determine the event type. If clients set it, it - * should be the same as the trigger that corresponding incoming would have (i.e., this has - * nothing to do with the underlying transport used to make the API call to invoke the - * lambda, which is often HTTP). - *
    - */ - public static final AttributeKey FAAS_TRIGGER = stringKey("faas.trigger"); - - /** The invocation ID of the current function invocation. */ - public static final AttributeKey FAAS_INVOCATION_ID = stringKey("faas.invocation_id"); - - /** - * The name of the source on which the triggering operation was performed. For example, in Cloud - * Storage or S3 corresponds to the bucket name, and in Cosmos DB to the database name. - */ - public static final AttributeKey FAAS_DOCUMENT_COLLECTION = - stringKey("faas.document.collection"); - - /** Describes the type of the operation that was performed on the data. */ - public static final AttributeKey FAAS_DOCUMENT_OPERATION = - stringKey("faas.document.operation"); - - /** - * A string containing the time when the data was accessed in the ISO 8601 format expressed in - * UTC. - */ - public static final AttributeKey FAAS_DOCUMENT_TIME = stringKey("faas.document.time"); - - /** - * The document name/table subjected to the operation. For example, in Cloud Storage or S3 is the - * name of the file, and in Cosmos DB the table name. - */ - public static final AttributeKey FAAS_DOCUMENT_NAME = stringKey("faas.document.name"); - - /** - * A string containing the function invocation time in the ISO 8601 format expressed in - * UTC. - */ - public static final AttributeKey FAAS_TIME = stringKey("faas.time"); - - /** - * A string containing the schedule period as Cron - * Expression. - */ - public static final AttributeKey FAAS_CRON = stringKey("faas.cron"); - - /** - * A boolean that is true if the serverless function is executed for the first time (aka - * cold-start). - */ - public static final AttributeKey FAAS_COLDSTART = booleanKey("faas.coldstart"); - - /** - * The name of the invoked function. - * - *

    Notes: - * - *

      - *
    • SHOULD be equal to the {@code faas.name} resource attribute of the invoked function. - *
    - */ - public static final AttributeKey FAAS_INVOKED_NAME = stringKey("faas.invoked_name"); - - /** - * The cloud provider of the invoked function. - * - *

    Notes: - * - *

      - *
    • SHOULD be equal to the {@code cloud.provider} resource attribute of the invoked function. - *
    - */ - public static final AttributeKey FAAS_INVOKED_PROVIDER = - stringKey("faas.invoked_provider"); - - /** - * The cloud region of the invoked function. - * - *

    Notes: - * - *

      - *
    • SHOULD be equal to the {@code cloud.region} resource attribute of the invoked function. - *
    - */ - public static final AttributeKey FAAS_INVOKED_REGION = stringKey("faas.invoked_region"); - - /** The unique identifier of the feature flag. */ - public static final AttributeKey FEATURE_FLAG_KEY = stringKey("feature_flag.key"); - - /** The name of the service provider that performs the flag evaluation. */ - public static final AttributeKey FEATURE_FLAG_PROVIDER_NAME = - stringKey("feature_flag.provider_name"); - - /** - * SHOULD be a semantic identifier for a value. If one is unavailable, a stringified version of - * the value can be used. - * - *

    Notes: - * - *

      - *
    • A semantic identifier, commonly referred to as a variant, provides a means for referring - * to a value without including the value itself. This can provide additional context for - * understanding the meaning behind a value. For example, the variant {@code red} maybe be - * used for the value {@code #c05543}. - *
    • A stringified version of the value can be used in situations where a semantic identifier - * is unavailable. String representation of the value should be determined by the - * implementer. - *
    - */ - public static final AttributeKey FEATURE_FLAG_VARIANT = stringKey("feature_flag.variant"); - - /** Transport protocol used. See note below. */ - public static final AttributeKey NET_TRANSPORT = stringKey("net.transport"); - - /** Application layer protocol used. The value SHOULD be normalized to lowercase. */ - public static final AttributeKey NET_PROTOCOL_NAME = stringKey("net.protocol.name"); - - /** - * Version of the application layer protocol used. See note below. - * - *

    Notes: - * - *

      - *
    • {@code net.protocol.version} refers to the version of the protocol used and might be - * different from the protocol client's version. If the HTTP client used has a version of - * {@code 0.27.2}, but sends HTTP version {@code 1.1}, this attribute should be set to - * {@code 1.1}. - *
    - */ - public static final AttributeKey NET_PROTOCOL_VERSION = stringKey("net.protocol.version"); - - /** Remote socket peer name. */ - public static final AttributeKey NET_SOCK_PEER_NAME = stringKey("net.sock.peer.name"); - - /** - * Remote socket peer address: IPv4 or IPv6 for internet protocols, path for local communication, - * etc. - */ - public static final AttributeKey NET_SOCK_PEER_ADDR = stringKey("net.sock.peer.addr"); - - /** Remote socket peer port. */ - public static final AttributeKey NET_SOCK_PEER_PORT = longKey("net.sock.peer.port"); - - /** - * Protocol address - * family which is used for communication. - */ - public static final AttributeKey NET_SOCK_FAMILY = stringKey("net.sock.family"); - - /** - * Logical remote hostname, see note below. - * - *

    Notes: - * - *

      - *
    • {@code net.peer.name} SHOULD NOT be set if capturing it would require an extra DNS - * lookup. - *
    - */ - public static final AttributeKey NET_PEER_NAME = stringKey("net.peer.name"); - - /** Logical remote port number */ - public static final AttributeKey NET_PEER_PORT = longKey("net.peer.port"); - - /** Logical local hostname or similar, see note below. */ - public static final AttributeKey NET_HOST_NAME = stringKey("net.host.name"); - - /** Logical local port number, preferably the one that the peer used to connect */ - public static final AttributeKey NET_HOST_PORT = longKey("net.host.port"); - - /** Local socket address. Useful in case of a multi-IP host. */ - public static final AttributeKey NET_SOCK_HOST_ADDR = stringKey("net.sock.host.addr"); - - /** Local socket port number. */ - public static final AttributeKey NET_SOCK_HOST_PORT = longKey("net.sock.host.port"); - - /** The internet connection type currently being used by the host. */ - public static final AttributeKey NET_HOST_CONNECTION_TYPE = - stringKey("net.host.connection.type"); - - /** - * This describes more details regarding the connection.type. It may be the type of cell - * technology connection, but it could be used for describing details about a wifi connection. - */ - public static final AttributeKey NET_HOST_CONNECTION_SUBTYPE = - stringKey("net.host.connection.subtype"); - - /** The name of the mobile carrier. */ - public static final AttributeKey NET_HOST_CARRIER_NAME = - stringKey("net.host.carrier.name"); - - /** The mobile carrier country code. */ - public static final AttributeKey NET_HOST_CARRIER_MCC = stringKey("net.host.carrier.mcc"); - - /** The mobile carrier network code. */ - public static final AttributeKey NET_HOST_CARRIER_MNC = stringKey("net.host.carrier.mnc"); - - /** The ISO 3166-1 alpha-2 2-character country code associated with the mobile carrier network. */ - public static final AttributeKey NET_HOST_CARRIER_ICC = stringKey("net.host.carrier.icc"); - - /** - * The {@code service.name} of - * the remote service. SHOULD be equal to the actual {@code service.name} resource attribute of - * the remote service if any. - */ - public static final AttributeKey PEER_SERVICE = stringKey("peer.service"); - - /** - * Username or client_id extracted from the access token or Authorization header in the inbound - * request from outside the system. - */ - public static final AttributeKey ENDUSER_ID = stringKey("enduser.id"); - - /** - * Actual/assumed role the client is making the request under extracted from token or application - * security context. - */ - public static final AttributeKey ENDUSER_ROLE = stringKey("enduser.role"); - - /** - * Scopes or granted authorities the client currently possesses extracted from token or - * application security context. The value would come from the scope associated with an OAuth 2.0 Access Token or an - * attribute value in a SAML - * 2.0 Assertion. - */ - public static final AttributeKey ENDUSER_SCOPE = stringKey("enduser.scope"); - - /** Current "managed" thread ID (as opposed to OS thread ID). */ - public static final AttributeKey THREAD_ID = longKey("thread.id"); - - /** Current thread name. */ - public static final AttributeKey THREAD_NAME = stringKey("thread.name"); - - /** - * The method or function name, or equivalent (usually rightmost part of the code unit's name). - */ - public static final AttributeKey CODE_FUNCTION = stringKey("code.function"); - - /** - * The "namespace" within which {@code code.function} is defined. Usually the qualified - * class or module name, such that {@code code.namespace} + some separator + {@code code.function} - * form a unique identifier for the code unit. - */ - public static final AttributeKey CODE_NAMESPACE = stringKey("code.namespace"); - - /** - * The source code file name that identifies the code unit as uniquely as possible (preferably an - * absolute file path). - */ - public static final AttributeKey CODE_FILEPATH = stringKey("code.filepath"); - - /** - * The line number in {@code code.filepath} best representing the operation. It SHOULD point - * within the code unit named in {@code code.function}. - */ - public static final AttributeKey CODE_LINENO = longKey("code.lineno"); - - /** - * The column number in {@code code.filepath} best representing the operation. It SHOULD point - * within the code unit named in {@code code.function}. - */ - public static final AttributeKey CODE_COLUMN = longKey("code.column"); - - /** - * The size of the request payload body in bytes. This is the number of bytes transferred - * excluding headers and is often, but not always, present as the Content-Length - * header. For requests using transport encoding, this should be the compressed size. - */ - public static final AttributeKey HTTP_REQUEST_CONTENT_LENGTH = - longKey("http.request_content_length"); - - /** - * The size of the response payload body in bytes. This is the number of bytes transferred - * excluding headers and is often, but not always, present as the Content-Length - * header. For requests using transport encoding, this should be the compressed size. - */ - public static final AttributeKey HTTP_RESPONSE_CONTENT_LENGTH = - longKey("http.response_content_length"); - - /** - * Full HTTP request URL in the form {@code scheme://host[:port]/path?query[#fragment]}. Usually - * the fragment is not transmitted over HTTP, but if it is known, it should be included - * nevertheless. - * - *

    Notes: - * - *

      - *
    • {@code http.url} MUST NOT contain credentials passed via URL in form of {@code - * https://username:password@www.example.com/}. In such case the attribute's value should be - * {@code https://www.example.com/}. - *
    - */ - public static final AttributeKey HTTP_URL = stringKey("http.url"); - - /** - * The ordinal number of request resending attempt (for any reason, including redirects). - * - *

    Notes: - * - *

      - *
    • The resend count SHOULD be updated each time an HTTP request gets resent by the client, - * regardless of what was the cause of the resending (e.g. redirection, authorization - * failure, 503 Server Unavailable, network issues, or any other). - *
    - */ - public static final AttributeKey HTTP_RESEND_COUNT = longKey("http.resend_count"); - - /** The full request target as passed in a HTTP request line or equivalent. */ - public static final AttributeKey HTTP_TARGET = stringKey("http.target"); - - /** - * The IP address of the original client behind all proxies, if known (e.g. from X-Forwarded-For). - * - *

    Notes: - * - *

      - *
    • This is not necessarily the same as {@code net.sock.peer.addr}, which would identify the - * network-level peer, which may be a proxy. - *
    • This attribute should be set when a source of information different from the one used for - * {@code net.sock.peer.addr}, is available even if that other source just confirms the same - * value as {@code net.sock.peer.addr}. Rationale: For {@code net.sock.peer.addr}, one - * typically does not know if it comes from a proxy, reverse proxy, or the actual client. - * Setting {@code http.client_ip} when it's the same as {@code net.sock.peer.addr} means - * that one is at least somewhat confident that the address is not that of the closest - * proxy. - *
    - */ - public static final AttributeKey HTTP_CLIENT_IP = stringKey("http.client_ip"); - - /** - * The AWS request ID as returned in the response headers {@code x-amz-request-id} or {@code - * x-amz-requestid}. - */ - public static final AttributeKey AWS_REQUEST_ID = stringKey("aws.request_id"); - - /** The keys in the {@code RequestItems} object field. */ - public static final AttributeKey> AWS_DYNAMODB_TABLE_NAMES = - stringArrayKey("aws.dynamodb.table_names"); - - /** The JSON-serialized value of each item in the {@code ConsumedCapacity} response field. */ - public static final AttributeKey> AWS_DYNAMODB_CONSUMED_CAPACITY = - stringArrayKey("aws.dynamodb.consumed_capacity"); - - /** The JSON-serialized value of the {@code ItemCollectionMetrics} response field. */ - public static final AttributeKey AWS_DYNAMODB_ITEM_COLLECTION_METRICS = - stringKey("aws.dynamodb.item_collection_metrics"); - - /** The value of the {@code ProvisionedThroughput.ReadCapacityUnits} request parameter. */ - public static final AttributeKey AWS_DYNAMODB_PROVISIONED_READ_CAPACITY = - doubleKey("aws.dynamodb.provisioned_read_capacity"); - - /** The value of the {@code ProvisionedThroughput.WriteCapacityUnits} request parameter. */ - public static final AttributeKey AWS_DYNAMODB_PROVISIONED_WRITE_CAPACITY = - doubleKey("aws.dynamodb.provisioned_write_capacity"); - - /** The value of the {@code ConsistentRead} request parameter. */ - public static final AttributeKey AWS_DYNAMODB_CONSISTENT_READ = - booleanKey("aws.dynamodb.consistent_read"); - - /** The value of the {@code ProjectionExpression} request parameter. */ - public static final AttributeKey AWS_DYNAMODB_PROJECTION = - stringKey("aws.dynamodb.projection"); - - /** The value of the {@code Limit} request parameter. */ - public static final AttributeKey AWS_DYNAMODB_LIMIT = longKey("aws.dynamodb.limit"); - - /** The value of the {@code AttributesToGet} request parameter. */ - public static final AttributeKey> AWS_DYNAMODB_ATTRIBUTES_TO_GET = - stringArrayKey("aws.dynamodb.attributes_to_get"); - - /** The value of the {@code IndexName} request parameter. */ - public static final AttributeKey AWS_DYNAMODB_INDEX_NAME = - stringKey("aws.dynamodb.index_name"); - - /** The value of the {@code Select} request parameter. */ - public static final AttributeKey AWS_DYNAMODB_SELECT = stringKey("aws.dynamodb.select"); - - /** The JSON-serialized value of each item of the {@code GlobalSecondaryIndexes} request field */ - public static final AttributeKey> AWS_DYNAMODB_GLOBAL_SECONDARY_INDEXES = - stringArrayKey("aws.dynamodb.global_secondary_indexes"); - - /** The JSON-serialized value of each item of the {@code LocalSecondaryIndexes} request field. */ - public static final AttributeKey> AWS_DYNAMODB_LOCAL_SECONDARY_INDEXES = - stringArrayKey("aws.dynamodb.local_secondary_indexes"); - - /** The value of the {@code ExclusiveStartTableName} request parameter. */ - public static final AttributeKey AWS_DYNAMODB_EXCLUSIVE_START_TABLE = - stringKey("aws.dynamodb.exclusive_start_table"); - - /** The the number of items in the {@code TableNames} response parameter. */ - public static final AttributeKey AWS_DYNAMODB_TABLE_COUNT = - longKey("aws.dynamodb.table_count"); - - /** The value of the {@code ScanIndexForward} request parameter. */ - public static final AttributeKey AWS_DYNAMODB_SCAN_FORWARD = - booleanKey("aws.dynamodb.scan_forward"); - - /** The value of the {@code Segment} request parameter. */ - public static final AttributeKey AWS_DYNAMODB_SEGMENT = longKey("aws.dynamodb.segment"); - - /** The value of the {@code TotalSegments} request parameter. */ - public static final AttributeKey AWS_DYNAMODB_TOTAL_SEGMENTS = - longKey("aws.dynamodb.total_segments"); - - /** The value of the {@code Count} response parameter. */ - public static final AttributeKey AWS_DYNAMODB_COUNT = longKey("aws.dynamodb.count"); - - /** The value of the {@code ScannedCount} response parameter. */ - public static final AttributeKey AWS_DYNAMODB_SCANNED_COUNT = - longKey("aws.dynamodb.scanned_count"); - - /** The JSON-serialized value of each item in the {@code AttributeDefinitions} request field. */ - public static final AttributeKey> AWS_DYNAMODB_ATTRIBUTE_DEFINITIONS = - stringArrayKey("aws.dynamodb.attribute_definitions"); - - /** - * The JSON-serialized value of each item in the the {@code GlobalSecondaryIndexUpdates} request - * field. - */ - public static final AttributeKey> AWS_DYNAMODB_GLOBAL_SECONDARY_INDEX_UPDATES = - stringArrayKey("aws.dynamodb.global_secondary_index_updates"); - - /** - * The S3 bucket name the request refers to. Corresponds to the {@code --bucket} parameter of the - * S3 API - * operations. - * - *

    Notes: - * - *

      - *
    • The {@code bucket} attribute is applicable to all S3 operations that reference a bucket, - * i.e. that require the bucket name as a mandatory parameter. This applies to almost all S3 - * operations except {@code list-buckets}. - *
    - */ - public static final AttributeKey AWS_S3_BUCKET = stringKey("aws.s3.bucket"); - - /** - * The S3 object key the request refers to. Corresponds to the {@code --key} parameter of the S3 API operations. - * - *

    Notes: - * - *

    - */ - public static final AttributeKey AWS_S3_KEY = stringKey("aws.s3.key"); - - /** - * The source object (in the form {@code bucket}/{@code key}) for the copy operation. - * - *

    Notes: - * - *

    - */ - public static final AttributeKey AWS_S3_COPY_SOURCE = stringKey("aws.s3.copy_source"); - - /** - * Upload ID that identifies the multipart upload. - * - *

    Notes: - * - *

    - */ - public static final AttributeKey AWS_S3_UPLOAD_ID = stringKey("aws.s3.upload_id"); - - /** - * The delete request container that specifies the objects to be deleted. - * - *

    Notes: - * - *

    - */ - public static final AttributeKey AWS_S3_DELETE = stringKey("aws.s3.delete"); - - /** - * The part number of the part being uploaded in a multipart-upload operation. This is a positive - * integer between 1 and 10,000. - * - *

    Notes: - * - *

    - */ - public static final AttributeKey AWS_S3_PART_NUMBER = longKey("aws.s3.part_number"); - - /** The name of the operation being executed. */ - public static final AttributeKey GRAPHQL_OPERATION_NAME = - stringKey("graphql.operation.name"); - - /** The type of the operation being executed. */ - public static final AttributeKey GRAPHQL_OPERATION_TYPE = - stringKey("graphql.operation.type"); - - /** - * The GraphQL document being executed. - * - *

    Notes: - * - *

      - *
    • The value may be sanitized to exclude sensitive information. - *
    - */ - public static final AttributeKey GRAPHQL_DOCUMENT = stringKey("graphql.document"); - - /** - * A value used by the messaging system as an identifier for the message, represented as a string. - */ - public static final AttributeKey MESSAGING_MESSAGE_ID = stringKey("messaging.message.id"); - - /** - * The conversation ID identifying the conversation to which the - * message belongs, represented as a string. Sometimes called "Correlation ID". - */ - public static final AttributeKey MESSAGING_MESSAGE_CONVERSATION_ID = - stringKey("messaging.message.conversation_id"); - - /** - * The (uncompressed) size of the message payload in bytes. Also use this attribute if it is - * unknown whether the compressed or uncompressed payload size is reported. - */ - public static final AttributeKey MESSAGING_MESSAGE_PAYLOAD_SIZE_BYTES = - longKey("messaging.message.payload_size_bytes"); - - /** The compressed size of the message payload in bytes. */ - public static final AttributeKey MESSAGING_MESSAGE_PAYLOAD_COMPRESSED_SIZE_BYTES = - longKey("messaging.message.payload_compressed_size_bytes"); - - /** - * The message destination name - * - *

    Notes: - * - *

      - *
    • Destination name SHOULD uniquely identify a specific queue, topic or other entity within - * the broker. If the broker does not have such notion, the destination name SHOULD uniquely - * identify the broker. - *
    - */ - public static final AttributeKey MESSAGING_DESTINATION_NAME = - stringKey("messaging.destination.name"); - - /** - * Low cardinality representation of the messaging destination name - * - *

    Notes: - * - *

      - *
    • Destination names could be constructed from templates. An example would be a destination - * name involving a user name or product id. Although the destination name in this case is - * of high cardinality, the underlying template is of low cardinality and can be effectively - * used for grouping and aggregation. - *
    - */ - public static final AttributeKey MESSAGING_DESTINATION_TEMPLATE = - stringKey("messaging.destination.template"); - - /** - * A boolean that is true if the message destination is temporary and might not exist anymore - * after messages are processed. - */ - public static final AttributeKey MESSAGING_DESTINATION_TEMPORARY = - booleanKey("messaging.destination.temporary"); - - /** - * A boolean that is true if the message destination is anonymous (could be unnamed or have - * auto-generated name). - */ - public static final AttributeKey MESSAGING_DESTINATION_ANONYMOUS = - booleanKey("messaging.destination.anonymous"); - - /** - * The message source name - * - *

    Notes: - * - *

      - *
    • Source name SHOULD uniquely identify a specific queue, topic, or other entity within the - * broker. If the broker does not have such notion, the source name SHOULD uniquely identify - * the broker. - *
    - */ - public static final AttributeKey MESSAGING_SOURCE_NAME = - stringKey("messaging.source.name"); - - /** - * Low cardinality representation of the messaging source name - * - *

    Notes: - * - *

      - *
    • Source names could be constructed from templates. An example would be a source name - * involving a user name or product id. Although the source name in this case is of high - * cardinality, the underlying template is of low cardinality and can be effectively used - * for grouping and aggregation. - *
    - */ - public static final AttributeKey MESSAGING_SOURCE_TEMPLATE = - stringKey("messaging.source.template"); - - /** - * A boolean that is true if the message source is temporary and might not exist anymore after - * messages are processed. - */ - public static final AttributeKey MESSAGING_SOURCE_TEMPORARY = - booleanKey("messaging.source.temporary"); - - /** - * A boolean that is true if the message source is anonymous (could be unnamed or have - * auto-generated name). - */ - public static final AttributeKey MESSAGING_SOURCE_ANONYMOUS = - booleanKey("messaging.source.anonymous"); - - /** A string identifying the messaging system. */ - public static final AttributeKey MESSAGING_SYSTEM = stringKey("messaging.system"); - - /** - * A string identifying the kind of messaging operation as defined in the Operation names section above. - * - *

    Notes: - * - *

      - *
    • If a custom value is used, it MUST be of low cardinality. - *
    - */ - public static final AttributeKey MESSAGING_OPERATION = stringKey("messaging.operation"); - - /** - * The number of messages sent, received, or processed in the scope of the batching operation. - * - *

    Notes: - * - *

      - *
    • Instrumentations SHOULD NOT set {@code messaging.batch.message_count} on spans that - * operate with a single message. When a messaging client library supports both batch and - * single-message API for the same operation, instrumentations SHOULD use {@code - * messaging.batch.message_count} for batching APIs and SHOULD NOT use it for single-message - * APIs. - *
    - */ - public static final AttributeKey MESSAGING_BATCH_MESSAGE_COUNT = - longKey("messaging.batch.message_count"); - - /** - * The identifier for the consumer receiving a message. For Kafka, set it to {@code - * {messaging.kafka.consumer.group} - {messaging.kafka.client_id}}, if both are present, or only - * {@code messaging.kafka.consumer.group}. For brokers, such as RabbitMQ and Artemis, set it to - * the {@code client_id} of the client consuming the message. - */ - public static final AttributeKey MESSAGING_CONSUMER_ID = - stringKey("messaging.consumer.id"); - - /** RabbitMQ message routing key. */ - public static final AttributeKey MESSAGING_RABBITMQ_DESTINATION_ROUTING_KEY = - stringKey("messaging.rabbitmq.destination.routing_key"); - - /** - * Message keys in Kafka are used for grouping alike messages to ensure they're processed on the - * same partition. They differ from {@code messaging.message.id} in that they're not unique. If - * the key is {@code null}, the attribute MUST NOT be set. - * - *

    Notes: - * - *

      - *
    • If the key type is not string, it's string representation has to be supplied for the - * attribute. If the key has no unambiguous, canonical string form, don't include its value. - *
    - */ - public static final AttributeKey MESSAGING_KAFKA_MESSAGE_KEY = - stringKey("messaging.kafka.message.key"); - - /** - * Name of the Kafka Consumer Group that is handling the message. Only applies to consumers, not - * producers. - */ - public static final AttributeKey MESSAGING_KAFKA_CONSUMER_GROUP = - stringKey("messaging.kafka.consumer.group"); - - /** Client Id for the Consumer or Producer that is handling the message. */ - public static final AttributeKey MESSAGING_KAFKA_CLIENT_ID = - stringKey("messaging.kafka.client_id"); - - /** Partition the message is sent to. */ - public static final AttributeKey MESSAGING_KAFKA_DESTINATION_PARTITION = - longKey("messaging.kafka.destination.partition"); - - /** Partition the message is received from. */ - public static final AttributeKey MESSAGING_KAFKA_SOURCE_PARTITION = - longKey("messaging.kafka.source.partition"); - - /** The offset of a record in the corresponding Kafka partition. */ - public static final AttributeKey MESSAGING_KAFKA_MESSAGE_OFFSET = - longKey("messaging.kafka.message.offset"); - - /** A boolean that is true if the message is a tombstone. */ - public static final AttributeKey MESSAGING_KAFKA_MESSAGE_TOMBSTONE = - booleanKey("messaging.kafka.message.tombstone"); - - /** Namespace of RocketMQ resources, resources in different namespaces are individual. */ - public static final AttributeKey MESSAGING_ROCKETMQ_NAMESPACE = - stringKey("messaging.rocketmq.namespace"); - - /** - * Name of the RocketMQ producer/consumer group that is handling the message. The client type is - * identified by the SpanKind. - */ - public static final AttributeKey MESSAGING_ROCKETMQ_CLIENT_GROUP = - stringKey("messaging.rocketmq.client_group"); - - /** The unique identifier for each client. */ - public static final AttributeKey MESSAGING_ROCKETMQ_CLIENT_ID = - stringKey("messaging.rocketmq.client_id"); - - /** - * The timestamp in milliseconds that the delay message is expected to be delivered to consumer. - */ - public static final AttributeKey MESSAGING_ROCKETMQ_MESSAGE_DELIVERY_TIMESTAMP = - longKey("messaging.rocketmq.message.delivery_timestamp"); - - /** The delay time level for delay message, which determines the message delay time. */ - public static final AttributeKey MESSAGING_ROCKETMQ_MESSAGE_DELAY_TIME_LEVEL = - longKey("messaging.rocketmq.message.delay_time_level"); - - /** - * It is essential for FIFO message. Messages that belong to the same message group are always - * processed one by one within the same consumer group. - */ - public static final AttributeKey MESSAGING_ROCKETMQ_MESSAGE_GROUP = - stringKey("messaging.rocketmq.message.group"); - - /** Type of message. */ - public static final AttributeKey MESSAGING_ROCKETMQ_MESSAGE_TYPE = - stringKey("messaging.rocketmq.message.type"); - - /** The secondary classifier of message besides topic. */ - public static final AttributeKey MESSAGING_ROCKETMQ_MESSAGE_TAG = - stringKey("messaging.rocketmq.message.tag"); - - /** Key(s) of message, another way to mark message besides message id. */ - public static final AttributeKey> MESSAGING_ROCKETMQ_MESSAGE_KEYS = - stringArrayKey("messaging.rocketmq.message.keys"); - - /** Model of message consumption. This only applies to consumer spans. */ - public static final AttributeKey MESSAGING_ROCKETMQ_CONSUMPTION_MODEL = - stringKey("messaging.rocketmq.consumption_model"); - - /** A string identifying the remoting system. See below for a list of well-known identifiers. */ - public static final AttributeKey RPC_SYSTEM = stringKey("rpc.system"); - - /** - * The full (logical) name of the service being called, including its package name, if applicable. - * - *

    Notes: - * - *

      - *
    • This is the logical name of the service from the RPC interface perspective, which can be - * different from the name of any implementing class. The {@code code.namespace} attribute - * may be used to store the latter (despite the attribute name, it may include a class name; - * e.g., class with method actually executing the call on the server side, RPC client stub - * class on the client side). - *
    - */ - public static final AttributeKey RPC_SERVICE = stringKey("rpc.service"); - - /** - * The name of the (logical) method being called, must be equal to the $method part in the span - * name. - * - *

    Notes: - * - *

      - *
    • This is the logical name of the method from the RPC interface perspective, which can be - * different from the name of any implementing method/function. The {@code code.function} - * attribute may be used to store the latter (e.g., method actually executing the call on - * the server side, RPC client stub method on the client side). - *
    - */ - public static final AttributeKey RPC_METHOD = stringKey("rpc.method"); - - /** - * The numeric status - * code of the gRPC request. - */ - public static final AttributeKey RPC_GRPC_STATUS_CODE = longKey("rpc.grpc.status_code"); - - /** - * Protocol version as in {@code jsonrpc} property of request/response. Since JSON-RPC 1.0 does - * not specify this, the value can be omitted. - */ - public static final AttributeKey RPC_JSONRPC_VERSION = stringKey("rpc.jsonrpc.version"); - - /** - * {@code id} property of request or response. Since protocol allows id to be int, string, {@code - * null} or missing (for notifications), value is expected to be cast to string for simplicity. - * Use empty string in case of {@code null} value. Omit entirely if this is a notification. - */ - public static final AttributeKey RPC_JSONRPC_REQUEST_ID = - stringKey("rpc.jsonrpc.request_id"); - - /** {@code error.code} property of response if it is an error response. */ - public static final AttributeKey RPC_JSONRPC_ERROR_CODE = longKey("rpc.jsonrpc.error_code"); - - /** {@code error.message} property of response if it is an error response. */ - public static final AttributeKey RPC_JSONRPC_ERROR_MESSAGE = - stringKey("rpc.jsonrpc.error_message"); - - /** Whether this is a received or sent message. */ - public static final AttributeKey MESSAGE_TYPE = stringKey("message.type"); - - /** - * MUST be calculated as two different counters starting from {@code 1} one for sent messages and - * one for received message. - * - *

    Notes: - * - *

      - *
    • This way we guarantee that the values will be consistent between different - * implementations. - *
    - */ - public static final AttributeKey MESSAGE_ID = longKey("message.id"); - - /** Compressed size of the message in bytes. */ - public static final AttributeKey MESSAGE_COMPRESSED_SIZE = - longKey("message.compressed_size"); - - /** Uncompressed size of the message in bytes. */ - public static final AttributeKey MESSAGE_UNCOMPRESSED_SIZE = - longKey("message.uncompressed_size"); - - /** - * The error codes of the Connect - * request. Error codes are always string values. - */ - public static final AttributeKey RPC_CONNECT_RPC_ERROR_CODE = - stringKey("rpc.connect_rpc.error_code"); - - /** - * SHOULD be set to true if the exception event is recorded at a point where it is known that the - * exception is escaping the scope of the span. - * - *

    Notes: - * - *

      - *
    • An exception is considered to have escaped (or left) the scope of a span, if that span is - * ended while the exception is still logically "in flight". This may be actually - * "in flight" in some languages (e.g. if the exception is passed to a Context - * manager's {@code __exit__} method in Python) but will usually be caught at the point of - * recording the exception in most languages. - *
    • It is usually not possible to determine at the point where an exception is thrown whether - * it will escape the scope of a span. However, it is trivial to know that an exception will - * escape, if one checks for an active exception just before ending the span, as done in the - * example above. - *
    • It follows that an exception may still escape the scope of the span even if the {@code - * exception.escaped} attribute was not set or set to false, since the event might have been - * recorded at a time where it was not clear whether the exception will escape. - *
    - */ - public static final AttributeKey EXCEPTION_ESCAPED = booleanKey("exception.escaped"); - - /** - * Value of the HTTP - * User-Agent header sent by the client. - */ - public static final AttributeKey USER_AGENT_ORIGINAL = stringKey("user_agent.original"); - - // Enum definitions - public static final class EventDomainValues { - /** Events from browser apps. */ - public static final String BROWSER = "browser"; - - /** Events from mobile apps. */ - public static final String DEVICE = "device"; - - /** Events from Kubernetes. */ - public static final String K8S = "k8s"; - - private EventDomainValues() {} - } - - public static final class OpentracingRefTypeValues { - /** The parent Span depends on the child Span in some capacity. */ - public static final String CHILD_OF = "child_of"; - - /** The parent Span does not depend in any way on the result of the child Span. */ - public static final String FOLLOWS_FROM = "follows_from"; - - private OpentracingRefTypeValues() {} - } - - public static final class DbSystemValues { - /** Some other SQL database. Fallback only. See notes. */ - public static final String OTHER_SQL = "other_sql"; - - /** Microsoft SQL Server. */ - public static final String MSSQL = "mssql"; - - /** Microsoft SQL Server Compact. */ - public static final String MSSQLCOMPACT = "mssqlcompact"; - - /** MySQL. */ - public static final String MYSQL = "mysql"; - - /** Oracle Database. */ - public static final String ORACLE = "oracle"; - - /** IBM Db2. */ - public static final String DB2 = "db2"; - - /** PostgreSQL. */ - public static final String POSTGRESQL = "postgresql"; - - /** Amazon Redshift. */ - public static final String REDSHIFT = "redshift"; - - /** Apache Hive. */ - public static final String HIVE = "hive"; - - /** Cloudscape. */ - public static final String CLOUDSCAPE = "cloudscape"; - - /** HyperSQL DataBase. */ - public static final String HSQLDB = "hsqldb"; - - /** Progress Database. */ - public static final String PROGRESS = "progress"; - - /** SAP MaxDB. */ - public static final String MAXDB = "maxdb"; - - /** SAP HANA. */ - public static final String HANADB = "hanadb"; - - /** Ingres. */ - public static final String INGRES = "ingres"; - - /** FirstSQL. */ - public static final String FIRSTSQL = "firstsql"; - - /** EnterpriseDB. */ - public static final String EDB = "edb"; - - /** InterSystems Caché. */ - public static final String CACHE = "cache"; - - /** Adabas (Adaptable Database System). */ - public static final String ADABAS = "adabas"; - - /** Firebird. */ - public static final String FIREBIRD = "firebird"; - - /** Apache Derby. */ - public static final String DERBY = "derby"; - - /** FileMaker. */ - public static final String FILEMAKER = "filemaker"; - - /** Informix. */ - public static final String INFORMIX = "informix"; - - /** InstantDB. */ - public static final String INSTANTDB = "instantdb"; - - /** InterBase. */ - public static final String INTERBASE = "interbase"; - - /** MariaDB. */ - public static final String MARIADB = "mariadb"; - - /** Netezza. */ - public static final String NETEZZA = "netezza"; - - /** Pervasive PSQL. */ - public static final String PERVASIVE = "pervasive"; - - /** PointBase. */ - public static final String POINTBASE = "pointbase"; - - /** SQLite. */ - public static final String SQLITE = "sqlite"; - - /** Sybase. */ - public static final String SYBASE = "sybase"; - - /** Teradata. */ - public static final String TERADATA = "teradata"; - - /** Vertica. */ - public static final String VERTICA = "vertica"; - - /** H2. */ - public static final String H2 = "h2"; - - /** ColdFusion IMQ. */ - public static final String COLDFUSION = "coldfusion"; - - /** Apache Cassandra. */ - public static final String CASSANDRA = "cassandra"; - - /** Apache HBase. */ - public static final String HBASE = "hbase"; - - /** MongoDB. */ - public static final String MONGODB = "mongodb"; - - /** Redis. */ - public static final String REDIS = "redis"; - - /** Couchbase. */ - public static final String COUCHBASE = "couchbase"; - - /** CouchDB. */ - public static final String COUCHDB = "couchdb"; - - /** Microsoft Azure Cosmos DB. */ - public static final String COSMOSDB = "cosmosdb"; - - /** Amazon DynamoDB. */ - public static final String DYNAMODB = "dynamodb"; - - /** Neo4j. */ - public static final String NEO4J = "neo4j"; - - /** Apache Geode. */ - public static final String GEODE = "geode"; - - /** Elasticsearch. */ - public static final String ELASTICSEARCH = "elasticsearch"; - - /** Memcached. */ - public static final String MEMCACHED = "memcached"; - - /** CockroachDB. */ - public static final String COCKROACHDB = "cockroachdb"; - - /** OpenSearch. */ - public static final String OPENSEARCH = "opensearch"; - - /** ClickHouse. */ - public static final String CLICKHOUSE = "clickhouse"; - - /** Cloud Spanner. */ - public static final String SPANNER = "spanner"; - - /** Trino. */ - public static final String TRINO = "trino"; - - private DbSystemValues() {} - } - - public static final class DbCassandraConsistencyLevelValues { - /** all. */ - public static final String ALL = "all"; - - /** each_quorum. */ - public static final String EACH_QUORUM = "each_quorum"; - - /** quorum. */ - public static final String QUORUM = "quorum"; - - /** local_quorum. */ - public static final String LOCAL_QUORUM = "local_quorum"; - - /** one. */ - public static final String ONE = "one"; - - /** two. */ - public static final String TWO = "two"; - - /** three. */ - public static final String THREE = "three"; - - /** local_one. */ - public static final String LOCAL_ONE = "local_one"; - - /** any. */ - public static final String ANY = "any"; - - /** serial. */ - public static final String SERIAL = "serial"; - - /** local_serial. */ - public static final String LOCAL_SERIAL = "local_serial"; - - private DbCassandraConsistencyLevelValues() {} - } - - public static final class DbCosmosdbOperationTypeValues { - /** invalid. */ - public static final String INVALID = "Invalid"; - - /** create. */ - public static final String CREATE = "Create"; - - /** patch. */ - public static final String PATCH = "Patch"; - - /** read. */ - public static final String READ = "Read"; - - /** read_feed. */ - public static final String READ_FEED = "ReadFeed"; - - /** delete. */ - public static final String DELETE = "Delete"; - - /** replace. */ - public static final String REPLACE = "Replace"; - - /** execute. */ - public static final String EXECUTE = "Execute"; - - /** query. */ - public static final String QUERY = "Query"; - - /** head. */ - public static final String HEAD = "Head"; - - /** head_feed. */ - public static final String HEAD_FEED = "HeadFeed"; - - /** upsert. */ - public static final String UPSERT = "Upsert"; - - /** batch. */ - public static final String BATCH = "Batch"; - - /** query_plan. */ - public static final String QUERY_PLAN = "QueryPlan"; - - /** execute_javascript. */ - public static final String EXECUTE_JAVASCRIPT = "ExecuteJavaScript"; - - private DbCosmosdbOperationTypeValues() {} - } - - public static final class DbCosmosdbConnectionModeValues { - /** Gateway (HTTP) connections mode. */ - public static final String GATEWAY = "gateway"; - - /** Direct connection. */ - public static final String DIRECT = "direct"; - - private DbCosmosdbConnectionModeValues() {} - } - - public static final class OtelStatusCodeValues { - /** - * The operation has been validated by an Application developer or Operator to have completed - * successfully. - */ - public static final String OK = "OK"; - - /** The operation contains an error. */ - public static final String ERROR = "ERROR"; - - private OtelStatusCodeValues() {} - } - - public static final class FaasTriggerValues { - /** A response to some data source operation such as a database or filesystem read/write. */ - public static final String DATASOURCE = "datasource"; - - /** To provide an answer to an inbound HTTP request. */ - public static final String HTTP = "http"; - - /** A function is set to be executed when messages are sent to a messaging system. */ - public static final String PUBSUB = "pubsub"; - - /** A function is scheduled to be executed regularly. */ - public static final String TIMER = "timer"; - - /** If none of the others apply. */ - public static final String OTHER = "other"; - - private FaasTriggerValues() {} - } - - public static final class FaasDocumentOperationValues { - /** When a new object is created. */ - public static final String INSERT = "insert"; - - /** When an object is modified. */ - public static final String EDIT = "edit"; - - /** When an object is deleted. */ - public static final String DELETE = "delete"; - - private FaasDocumentOperationValues() {} - } - - public static final class FaasInvokedProviderValues { - /** Alibaba Cloud. */ - public static final String ALIBABA_CLOUD = "alibaba_cloud"; - - /** Amazon Web Services. */ - public static final String AWS = "aws"; - - /** Microsoft Azure. */ - public static final String AZURE = "azure"; - - /** Google Cloud Platform. */ - public static final String GCP = "gcp"; - - /** Tencent Cloud. */ - public static final String TENCENT_CLOUD = "tencent_cloud"; - - private FaasInvokedProviderValues() {} - } - - public static final class NetTransportValues { - /** ip_tcp. */ - public static final String IP_TCP = "ip_tcp"; - - /** ip_udp. */ - public static final String IP_UDP = "ip_udp"; - - /** Named or anonymous pipe. See note below. */ - public static final String PIPE = "pipe"; - - /** In-process communication. */ - public static final String INPROC = "inproc"; - - /** Something else (non IP-based). */ - public static final String OTHER = "other"; - - /** - * @deprecated This item has been removed as of 1.13.0 of the semantic conventions. - */ - @Deprecated public static final String IP = "ip"; - - /** - * @deprecated This item has been removed as of 1.13.0 of the semantic conventions. - */ - @Deprecated public static final String UNIX = "unix"; - - private NetTransportValues() {} - } - - public static final class NetSockFamilyValues { - /** IPv4 address. */ - public static final String INET = "inet"; - - /** IPv6 address. */ - public static final String INET6 = "inet6"; - - /** Unix domain socket path. */ - public static final String UNIX = "unix"; - - private NetSockFamilyValues() {} - } - - public static final class NetHostConnectionTypeValues { - /** wifi. */ - public static final String WIFI = "wifi"; - - /** wired. */ - public static final String WIRED = "wired"; - - /** cell. */ - public static final String CELL = "cell"; - - /** unavailable. */ - public static final String UNAVAILABLE = "unavailable"; - - /** unknown. */ - public static final String UNKNOWN = "unknown"; - - private NetHostConnectionTypeValues() {} - } - - public static final class NetHostConnectionSubtypeValues { - /** GPRS. */ - public static final String GPRS = "gprs"; - - /** EDGE. */ - public static final String EDGE = "edge"; - - /** UMTS. */ - public static final String UMTS = "umts"; - - /** CDMA. */ - public static final String CDMA = "cdma"; - - /** EVDO Rel. 0. */ - public static final String EVDO_0 = "evdo_0"; - - /** EVDO Rev. A. */ - public static final String EVDO_A = "evdo_a"; - - /** CDMA2000 1XRTT. */ - public static final String CDMA2000_1XRTT = "cdma2000_1xrtt"; - - /** HSDPA. */ - public static final String HSDPA = "hsdpa"; - - /** HSUPA. */ - public static final String HSUPA = "hsupa"; - - /** HSPA. */ - public static final String HSPA = "hspa"; - - /** IDEN. */ - public static final String IDEN = "iden"; - - /** EVDO Rev. B. */ - public static final String EVDO_B = "evdo_b"; - - /** LTE. */ - public static final String LTE = "lte"; - - /** EHRPD. */ - public static final String EHRPD = "ehrpd"; - - /** HSPAP. */ - public static final String HSPAP = "hspap"; - - /** GSM. */ - public static final String GSM = "gsm"; - - /** TD-SCDMA. */ - public static final String TD_SCDMA = "td_scdma"; - - /** IWLAN. */ - public static final String IWLAN = "iwlan"; - - /** 5G NR (New Radio). */ - public static final String NR = "nr"; - - /** 5G NRNSA (New Radio Non-Standalone). */ - public static final String NRNSA = "nrnsa"; - - /** LTE CA. */ - public static final String LTE_CA = "lte_ca"; - - private NetHostConnectionSubtypeValues() {} - } - - public static final class GraphqlOperationTypeValues { - /** GraphQL query. */ - public static final String QUERY = "query"; - - /** GraphQL mutation. */ - public static final String MUTATION = "mutation"; - - /** GraphQL subscription. */ - public static final String SUBSCRIPTION = "subscription"; - - private GraphqlOperationTypeValues() {} - } - - public static final class MessagingOperationValues { - /** publish. */ - public static final String PUBLISH = "publish"; - - /** receive. */ - public static final String RECEIVE = "receive"; - - /** process. */ - public static final String PROCESS = "process"; - - private MessagingOperationValues() {} - } - - public static final class MessagingRocketmqMessageTypeValues { - /** Normal message. */ - public static final String NORMAL = "normal"; - - /** FIFO message. */ - public static final String FIFO = "fifo"; - - /** Delay message. */ - public static final String DELAY = "delay"; - - /** Transaction message. */ - public static final String TRANSACTION = "transaction"; - - private MessagingRocketmqMessageTypeValues() {} - } - - public static final class MessagingRocketmqConsumptionModelValues { - /** Clustering consumption model. */ - public static final String CLUSTERING = "clustering"; - - /** Broadcasting consumption model. */ - public static final String BROADCASTING = "broadcasting"; - - private MessagingRocketmqConsumptionModelValues() {} - } - - public static final class RpcSystemValues { - /** gRPC. */ - public static final String GRPC = "grpc"; - - /** Java RMI. */ - public static final String JAVA_RMI = "java_rmi"; - - /** .NET WCF. */ - public static final String DOTNET_WCF = "dotnet_wcf"; - - /** Apache Dubbo. */ - public static final String APACHE_DUBBO = "apache_dubbo"; - - /** Connect RPC. */ - public static final String CONNECT_RPC = "connect_rpc"; - - private RpcSystemValues() {} - } - - public static final class RpcGrpcStatusCodeValues { - /** OK. */ - public static final long OK = 0; - - /** CANCELLED. */ - public static final long CANCELLED = 1; - - /** UNKNOWN. */ - public static final long UNKNOWN = 2; - - /** INVALID_ARGUMENT. */ - public static final long INVALID_ARGUMENT = 3; - - /** DEADLINE_EXCEEDED. */ - public static final long DEADLINE_EXCEEDED = 4; - - /** NOT_FOUND. */ - public static final long NOT_FOUND = 5; - - /** ALREADY_EXISTS. */ - public static final long ALREADY_EXISTS = 6; - - /** PERMISSION_DENIED. */ - public static final long PERMISSION_DENIED = 7; - - /** RESOURCE_EXHAUSTED. */ - public static final long RESOURCE_EXHAUSTED = 8; - - /** FAILED_PRECONDITION. */ - public static final long FAILED_PRECONDITION = 9; - - /** ABORTED. */ - public static final long ABORTED = 10; - - /** OUT_OF_RANGE. */ - public static final long OUT_OF_RANGE = 11; - - /** UNIMPLEMENTED. */ - public static final long UNIMPLEMENTED = 12; - - /** INTERNAL. */ - public static final long INTERNAL = 13; - - /** UNAVAILABLE. */ - public static final long UNAVAILABLE = 14; - - /** DATA_LOSS. */ - public static final long DATA_LOSS = 15; - - /** UNAUTHENTICATED. */ - public static final long UNAUTHENTICATED = 16; - - private RpcGrpcStatusCodeValues() {} - } - - public static final class MessageTypeValues { - /** sent. */ - public static final String SENT = "SENT"; - - /** received. */ - public static final String RECEIVED = "RECEIVED"; - - private MessageTypeValues() {} - } - - public static final class RpcConnectRpcErrorCodeValues { - /** cancelled. */ - public static final String CANCELLED = "cancelled"; - - /** unknown. */ - public static final String UNKNOWN = "unknown"; - - /** invalid_argument. */ - public static final String INVALID_ARGUMENT = "invalid_argument"; - - /** deadline_exceeded. */ - public static final String DEADLINE_EXCEEDED = "deadline_exceeded"; - - /** not_found. */ - public static final String NOT_FOUND = "not_found"; - - /** already_exists. */ - public static final String ALREADY_EXISTS = "already_exists"; - - /** permission_denied. */ - public static final String PERMISSION_DENIED = "permission_denied"; - - /** resource_exhausted. */ - public static final String RESOURCE_EXHAUSTED = "resource_exhausted"; - - /** failed_precondition. */ - public static final String FAILED_PRECONDITION = "failed_precondition"; - - /** aborted. */ - public static final String ABORTED = "aborted"; - - /** out_of_range. */ - public static final String OUT_OF_RANGE = "out_of_range"; - - /** unimplemented. */ - public static final String UNIMPLEMENTED = "unimplemented"; - - /** internal. */ - public static final String INTERNAL = "internal"; - - /** unavailable. */ - public static final String UNAVAILABLE = "unavailable"; - - /** data_loss. */ - public static final String DATA_LOSS = "data_loss"; - - /** unauthenticated. */ - public static final String UNAUTHENTICATED = "unauthenticated"; - - private RpcConnectRpcErrorCodeValues() {} - } - - // Manually defined and not YET in the YAML - /** - * The name of an event describing an exception. - * - *

    Typically an event with that name should not be manually created. Instead {@link - * io.opentelemetry.api.trace.Span#recordException(Throwable)} should be used. - */ - public static final String EXCEPTION_EVENT_NAME = "exception"; - - /** - * The name of the keyspace being accessed. - * - * @deprecated this item has been removed as of 1.8.0 of the semantic conventions. Please use - * {@link SemanticAttributes#DB_NAME} instead. - */ - @Deprecated - public static final AttributeKey DB_CASSANDRA_KEYSPACE = - stringKey("db.cassandra.keyspace"); - - /** - * The HBase namespace being accessed. - * - * @deprecated this item has been removed as of 1.8.0 of the semantic conventions. Please use - * {@link SemanticAttributes#DB_NAME} instead. - */ - @Deprecated - public static final AttributeKey DB_HBASE_NAMESPACE = stringKey("db.hbase.namespace"); - - /** - * The size of the uncompressed request payload body after transport decoding. Not set if - * transport encoding not used. - * - * @deprecated this item has been removed as of 1.13.0 of the semantic conventions. Please use - * {@link SemanticAttributes#HTTP_REQUEST_CONTENT_LENGTH} instead. - */ - @Deprecated - public static final AttributeKey HTTP_REQUEST_CONTENT_LENGTH_UNCOMPRESSED = - longKey("http.request_content_length_uncompressed"); - - /** - * @deprecated This item has been removed as of 1.13.0 of the semantic conventions. Please use - * {@link SemanticAttributes#HTTP_RESPONSE_CONTENT_LENGTH} instead. - */ - @Deprecated - public static final AttributeKey HTTP_RESPONSE_CONTENT_LENGTH_UNCOMPRESSED = - longKey("http.response_content_length_uncompressed"); - - /** - * @deprecated This item has been removed as of 1.13.0 of the semantic conventions. Please use - * {@link SemanticAttributes#NET_HOST_NAME} instead. - */ - @Deprecated - public static final AttributeKey HTTP_SERVER_NAME = stringKey("http.server_name"); - - /** - * @deprecated This item has been removed as of 1.13.0 of the semantic conventions. Please use - * {@link SemanticAttributes#NET_HOST_NAME} instead. - */ - @Deprecated public static final AttributeKey HTTP_HOST = stringKey("http.host"); - - /** - * @deprecated This item has been removed as of 1.13.0 of the semantic conventions. Please use - * {@link SemanticAttributes#NET_SOCK_PEER_ADDR} instead. - */ - @Deprecated public static final AttributeKey NET_PEER_IP = stringKey("net.peer.ip"); - - /** - * @deprecated This item has been removed as of 1.13.0 of the semantic conventions. Please use - * {@link SemanticAttributes#NET_SOCK_HOST_ADDR} instead. - */ - @Deprecated public static final AttributeKey NET_HOST_IP = stringKey("net.host.ip"); - - /** - * The ordinal number of request re-sending attempt. - * - * @deprecated This item has been removed as of 1.15.0 of the semantic conventions. Use {@link - * SemanticAttributes#HTTP_RESEND_COUNT} instead. - */ - @Deprecated public static final AttributeKey HTTP_RETRY_COUNT = longKey("http.retry_count"); - - /** - * A string identifying the messaging system. - * - * @deprecated This item has been removed as of 1.17.0 of the semantic conventions. Use {@link - * SemanticAttributes#MESSAGING_DESTINATION_NAME} instead. - */ - @Deprecated - public static final AttributeKey MESSAGING_DESTINATION = - stringKey("messaging.destination"); - - /** - * A boolean that is true if the message destination is temporary. - * - * @deprecated This item has been removed as of 1.17.0 of the semantic conventions. Use {@link - * SemanticAttributes#MESSAGING_DESTINATION_TEMPORARY} instead. - */ - @Deprecated - public static final AttributeKey MESSAGING_TEMP_DESTINATION = - booleanKey("messaging.temp_destination"); - - /** - * The name of the transport protocol. - * - * @deprecated This item has been removed as of 1.17.0 of the semantic conventions. Use {@link - * SemanticAttributes#NET_PROTOCOL_NAME} instead. - */ - @Deprecated - public static final AttributeKey MESSAGING_PROTOCOL = stringKey("messaging.protocol"); - - /** - * The version of the transport protocol. - * - * @deprecated This item has been removed as of 1.17.0 of the semantic conventions. Use {@link - * SemanticAttributes#NET_PROTOCOL_VERSION} instead. - */ - @Deprecated - public static final AttributeKey MESSAGING_PROTOCOL_VERSION = - stringKey("messaging.protocol_version"); - - /** - * Connection string. - * - * @deprecated This item has been removed as of 1.17.0 of the semantic conventions. There is no - * replacement. - */ - @Deprecated public static final AttributeKey MESSAGING_URL = stringKey("messaging.url"); - - /** - * The conversation ID identifying the conversation to which the - * message belongs, represented as a string. Sometimes called "Correlation ID". - * - * @deprecated This item has been removed as of 1.17.0 of the semantic conventions. Use {@link - * SemanticAttributes#MESSAGING_MESSAGE_CONVERSATION_ID} instead. - */ - @Deprecated - public static final AttributeKey MESSAGING_CONVERSATION_ID = - stringKey("messaging.conversation_id"); - - /** - * RabbitMQ message routing key. - * - * @deprecated This item has been removed as of 1.17.0 of the semantic conventions. Use {@link - * SemanticAttributes#MESSAGING_RABBITMQ_DESTINATION_ROUTING_KEY} instead. - */ - @Deprecated - public static final AttributeKey MESSAGING_RABBITMQ_ROUTING_KEY = - stringKey("messaging.rabbitmq.routing_key"); - - /** - * Partition the message is received from. - * - * @deprecated This item has been removed as of 1.17.0 of the semantic conventions. Use {@link - * SemanticAttributes#MESSAGING_KAFKA_SOURCE_PARTITION} instead. - */ - @Deprecated - public static final AttributeKey MESSAGING_KAFKA_PARTITION = - longKey("messaging.kafka.partition"); - - /** - * A boolean that is true if the message is a tombstone. - * - * @deprecated This item has been removed as of 1.17.0 of the semantic conventions. Use {@link - * SemanticAttributes#MESSAGING_KAFKA_MESSAGE_TOMBSTONE} instead. - */ - @Deprecated - public static final AttributeKey MESSAGING_KAFKA_TOMBSTONE = - booleanKey("messaging.kafka.tombstone"); - - /** - * The timestamp in milliseconds that the delay message is expected to be delivered to consumer. - * - * @deprecated This item has been removed as of 1.17.0 of the semantic conventions. Use {@link - * SemanticAttributes#MESSAGING_ROCKETMQ_MESSAGE_DELIVERY_TIMESTAMP} instead. - */ - @Deprecated - public static final AttributeKey MESSAGING_ROCKETMQ_DELIVERY_TIMESTAMP = - longKey("messaging.rocketmq.delivery_timestamp"); - - /** - * The delay time level for delay message, which determines the message delay time. - * - * @deprecated This item has been removed as of 1.17.0 of the semantic conventions. Use {@link - * SemanticAttributes#MESSAGING_ROCKETMQ_MESSAGE_DELAY_TIME_LEVEL} instead. - */ - @Deprecated - public static final AttributeKey MESSAGING_ROCKETMQ_DELAY_TIME_LEVEL = - longKey("messaging.rocketmq.delay_time_level"); - - /** - * The name of the instrumentation scope - ({@code InstrumentationScope.Name} in OTLP). - * - * @deprecated This item has been moved, use {@link - * io.opentelemetry.semconv.resource.attributes.ResourceAttributes#OTEL_SCOPE_NAME} instead. - */ - @Deprecated - public static final AttributeKey OTEL_SCOPE_NAME = stringKey("otel.scope.name"); - - /** - * The version of the instrumentation scope - ({@code InstrumentationScope.Version} in OTLP). - * - * @deprecated This item has been moved, use {@link - * io.opentelemetry.semconv.resource.attributes.ResourceAttributes#OTEL_SCOPE_VERSION} - * instead. - */ - @Deprecated - public static final AttributeKey OTEL_SCOPE_VERSION = stringKey("otel.scope.version"); - - /** - * The execution ID of the current function execution. - * - * @deprecated This item has been renamed in 1.19.0 version of the semantic conventions. Use - * {@link SemanticAttributes#FAAS_INVOCATION_ID} instead. - */ - @Deprecated public static final AttributeKey FAAS_EXECUTION = stringKey("faas.execution"); - - /** - * Value of the HTTP - * User-Agent header sent by the client. - * - * @deprecated This item has been renamed in 1.19.0 version of the semantic conventions. Use - * {@link SemanticAttributes#USER_AGENT_ORIGINAL} instead. - */ - @Deprecated - public static final AttributeKey HTTP_USER_AGENT = stringKey("http.user_agent"); - - /** - * Deprecated. - * - * @deprecated Deprecated, use the {@link - * io.opentelemetry.semconv.resource.attributes.ResourceAttributes#OTEL_SCOPE_NAME} attribute. - */ - @Deprecated - public static final AttributeKey OTEL_LIBRARY_NAME = stringKey("otel.library.name"); - - /** - * Deprecated. - * - * @deprecated Deprecated, use the {@link - * io.opentelemetry.semconv.resource.attributes.ResourceAttributes#OTEL_SCOPE_VERSION} - * attribute. - */ - @Deprecated - public static final AttributeKey OTEL_LIBRARY_VERSION = stringKey("otel.library.version"); - - /** - * Kind of HTTP protocol used. - * - * @deprecated This item has been removed as of 1.20.0 of the semantic conventions. - */ - @Deprecated public static final AttributeKey HTTP_FLAVOR = stringKey("http.flavor"); - - /** - * Enum definitions for {@link #HTTP_FLAVOR}. - * - * @deprecated This item has been removed as of 1.20.0 of the semantic conventions. - */ - @Deprecated - public static final class HttpFlavorValues { - /** HTTP/1.0. */ - public static final String HTTP_1_0 = "1.0"; - - /** HTTP/1.1. */ - public static final String HTTP_1_1 = "1.1"; - - /** HTTP/2. */ - public static final String HTTP_2_0 = "2.0"; - - /** HTTP/3. */ - public static final String HTTP_3_0 = "3.0"; - - /** SPDY protocol. */ - public static final String SPDY = "SPDY"; - - /** QUIC protocol. */ - public static final String QUIC = "QUIC"; - - private HttpFlavorValues() {} - } - - /** - * Application layer protocol used. The value SHOULD be normalized to lowercase. - * - * @deprecated This item has been removed as of 1.20.0 of the semantic conventions. Use {@link - * SemanticAttributes#NET_PROTOCOL_NAME} instead. - */ - @Deprecated - public static final AttributeKey NET_APP_PROTOCOL_NAME = - stringKey("net.app.protocol.name"); - - /** - * Version of the application layer protocol used. See note below. - * - *

    Notes: - * - *

      - *
    • {@code net.app.protocol.version} refers to the version of the protocol used and might be - * different from the protocol client's version. If the HTTP client used has a version of - * {@code 0.27.2}, but sends HTTP version {@code 1.1}, this attribute should be set to - * {@code 1.1}. - *
    - * - * @deprecated This item has been removed as of 1.20.0 of the semantic conventions. Use {@link - * SemanticAttributes#NET_PROTOCOL_VERSION} instead. - */ - @Deprecated - public static final AttributeKey NET_APP_PROTOCOL_VERSION = - stringKey("net.app.protocol.version"); - - /** - * The kind of message destination. - * - * @deprecated This item has been removed as of 1.20.0 of the semantic conventions. - */ - @Deprecated - public static final AttributeKey MESSAGING_DESTINATION_KIND = - stringKey("messaging.destination.kind"); - - /** - * Enum values for {@link #MESSAGING_DESTINATION_KIND}. - * - * @deprecated This item has been removed as of 1.20.0 of the semantic conventions. - */ - @Deprecated - public static final class MessagingDestinationKindValues { - /** A message sent to a queue. */ - public static final String QUEUE = "queue"; - - /** A message sent to a topic. */ - public static final String TOPIC = "topic"; - - private MessagingDestinationKindValues() {} - } - - /** - * The kind of message source. - * - * @deprecated This item has been removed as of 1.20.0 of the semantic conventions. - */ - @Deprecated - public static final AttributeKey MESSAGING_SOURCE_KIND = - stringKey("messaging.source.kind"); - - /** - * Enum values for {@link #MESSAGING_SOURCE_KIND}. - * - * @deprecated This item has been removed as of 1.20.0 of the semantic conventions. - */ - @Deprecated - public static final class MessagingSourceKindValues { - /** A message received from a queue. */ - public static final String QUEUE = "queue"; - - /** A message received from a topic. */ - public static final String TOPIC = "topic"; - - private MessagingSourceKindValues() {} - } - - private SemanticAttributes() {} -} diff --git a/semconv/src/main/java/io/opentelemetry/semconv/trace/attributes/package-info.java b/semconv/src/main/java/io/opentelemetry/semconv/trace/attributes/package-info.java deleted file mode 100644 index 15f7b0cb460..00000000000 --- a/semconv/src/main/java/io/opentelemetry/semconv/trace/attributes/package-info.java +++ /dev/null @@ -1,14 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -/** - * OpenTelemetry semantic attributes for traces. - * - * @see io.opentelemetry.semconv.trace.attributes.SemanticAttributes - */ -@ParametersAreNonnullByDefault -package io.opentelemetry.semconv.trace.attributes; - -import javax.annotation.ParametersAreNonnullByDefault; diff --git a/settings.gradle.kts b/settings.gradle.kts index dbe27012ad9..1fae63fd2c0 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -24,7 +24,6 @@ rootProject.name = "opentelemetry-java" include(":all") include(":api:all") include(":api:events") -include(":semconv") include(":bom") include(":bom-alpha") include(":context") From 8d27e24b213aa12fdb743eea6b18d385fee9c822 Mon Sep 17 00:00:00 2001 From: Pierre Tessier Date: Thu, 28 Sep 2023 11:30:49 -0400 Subject: [PATCH 026/901] Unify `queueSize` metric description and attribute (#5836) --- CHANGELOG.md | 3 +++ .../sdk/logs/export/BatchLogRecordProcessor.java | 4 ++-- .../io/opentelemetry/sdk/trace/export/BatchSpanProcessor.java | 4 ++-- 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 91207791d30..4ba8f3c1469 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,9 @@ ## Unreleased +* Update `queueSize` metric description and attribute name for `processorType` + ([#5836](https://github.com/open-telemetry/opentelemetry-java/pull/5836)) + ## Version 1.30.1 (2023-09-11) * Fix autoconfigure bug creating multiple `PrometheusHttpServer` instances with same port diff --git a/sdk/logs/src/main/java/io/opentelemetry/sdk/logs/export/BatchLogRecordProcessor.java b/sdk/logs/src/main/java/io/opentelemetry/sdk/logs/export/BatchLogRecordProcessor.java index 26ac5005574..1c8833fcaf8 100644 --- a/sdk/logs/src/main/java/io/opentelemetry/sdk/logs/export/BatchLogRecordProcessor.java +++ b/sdk/logs/src/main/java/io/opentelemetry/sdk/logs/export/BatchLogRecordProcessor.java @@ -45,7 +45,7 @@ public final class BatchLogRecordProcessor implements LogRecordProcessor { private static final String WORKER_THREAD_NAME = BatchLogRecordProcessor.class.getSimpleName() + "_WorkerThread"; private static final AttributeKey LOG_RECORD_PROCESSOR_TYPE_LABEL = - AttributeKey.stringKey("logRecordProcessorType"); + AttributeKey.stringKey("processorType"); private static final AttributeKey LOG_RECORD_PROCESSOR_DROPPED_LABEL = AttributeKey.booleanKey("dropped"); private static final String LOG_RECORD_PROCESSOR_TYPE_VALUE = @@ -172,7 +172,7 @@ private Worker( meter .gaugeBuilder("queueSize") .ofLongs() - .setDescription("The number of logs queued") + .setDescription("The number of items queued") .setUnit("1") .buildWithCallback( result -> diff --git a/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/export/BatchSpanProcessor.java b/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/export/BatchSpanProcessor.java index 8163522c16c..126ef59c6c2 100644 --- a/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/export/BatchSpanProcessor.java +++ b/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/export/BatchSpanProcessor.java @@ -48,7 +48,7 @@ public final class BatchSpanProcessor implements SpanProcessor { private static final String WORKER_THREAD_NAME = BatchSpanProcessor.class.getSimpleName() + "_WorkerThread"; private static final AttributeKey SPAN_PROCESSOR_TYPE_LABEL = - AttributeKey.stringKey("spanProcessorType"); + AttributeKey.stringKey("processorType"); private static final AttributeKey SPAN_PROCESSOR_DROPPED_LABEL = AttributeKey.booleanKey("dropped"); private static final String SPAN_PROCESSOR_TYPE_VALUE = BatchSpanProcessor.class.getSimpleName(); @@ -189,7 +189,7 @@ private Worker( meter .gaugeBuilder("queueSize") .ofLongs() - .setDescription("The number of spans queued") + .setDescription("The number of items queued") .setUnit("1") .buildWithCallback( result -> From 15fbac58f4d7a1a8ea1eb1878372a56253e28cc2 Mon Sep 17 00:00:00 2001 From: Stephen Cprek Date: Thu, 28 Sep 2023 11:31:36 -0400 Subject: [PATCH 027/901] Add clearer docs around coroutine support with an example (#5799) --- extensions/kotlin/README.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 extensions/kotlin/README.md diff --git a/extensions/kotlin/README.md b/extensions/kotlin/README.md new file mode 100644 index 00000000000..3637e9e6e26 --- /dev/null +++ b/extensions/kotlin/README.md @@ -0,0 +1,12 @@ +# OpenTelemetry Kotlin Extension + +Kotlin [Extensions](src/main/kotlin/io/opentelemetry/extension/kotlin/ContextExtensions.kt) to propagate +OpenTelemetry context into coroutines. + +For example, you could do the following with coroutines + +```kotlin +launch(Context.current().asContextElement()) { +// trace ids propagated here +} +``` From bdeb1e95cd24748523592877d82d64212496e96e Mon Sep 17 00:00:00 2001 From: jack-berg <34418638+jack-berg@users.noreply.github.com> Date: Thu, 28 Sep 2023 11:00:02 -0500 Subject: [PATCH 028/901] Add breedx-splk as approver (#5860) --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 3be94db91d1..afd156596d8 100644 --- a/README.md +++ b/README.md @@ -302,6 +302,7 @@ Triagers: Approvers ([@open-telemetry/java-approvers](https://github.com/orgs/open-telemetry/teams/java-approvers)): +- [Jason Plumb](https://github.com/breedx-splk), Splunk - [Josh Suereth](https://github.com/jsuereth), Google - [Mateusz Rzeszutek](https://github.com/mateuszrzeszutek), Splunk - [Trask Stalnaker](https://github.com/trask), Microsoft From c66a51c4682ee4784168f23029c4421434066f4a Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 29 Sep 2023 11:56:19 -0500 Subject: [PATCH 029/901] Update dependency io.netty:netty-bom to v4.1.99.Final (#5845) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- dependencyManagement/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index 3a9333b5b4d..ff60de2960b 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -15,7 +15,7 @@ val DEPENDENCY_BOMS = listOf( "com.squareup.okhttp3:okhttp-bom:4.11.0", "com.squareup.okio:okio-bom:3.5.0", // applies to transitive dependencies of okhttp "io.grpc:grpc-bom:1.58.0", - "io.netty:netty-bom:4.1.97.Final", + "io.netty:netty-bom:4.1.99.Final", "io.zipkin.brave:brave-bom:5.16.0", "io.zipkin.reporter2:zipkin-reporter-bom:2.16.4", "org.assertj:assertj-bom:3.24.2", From bac9941a587582ba43f3cfa7d82bfedcc5e1cb05 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 29 Sep 2023 11:56:44 -0500 Subject: [PATCH 030/901] Update dependency com.diffplug.spotless:spotless-plugin-gradle to v6.22.0 (#5863) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- buildSrc/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts index 1bb924ca1ab..c4f99f90838 100644 --- a/buildSrc/build.gradle.kts +++ b/buildSrc/build.gradle.kts @@ -45,7 +45,7 @@ dependencies { implementation(enforcedPlatform("com.squareup.wire:wire-bom:4.9.1")) implementation("com.google.auto.value:auto-value-annotations:1.10.4") // When updating, update above in plugins too - implementation("com.diffplug.spotless:spotless-plugin-gradle:6.21.0") + implementation("com.diffplug.spotless:spotless-plugin-gradle:6.22.0") // Needed for japicmp but not automatically brought in for some reason. implementation("com.google.guava:guava:32.1.2-jre") implementation("com.squareup:javapoet:1.13.0") From bb4c2193aa39ae29aa1af4526a3067d715df9011 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 29 Sep 2023 12:39:57 -0500 Subject: [PATCH 031/901] Update plugin com.diffplug.spotless to v6.22.0 (#5864) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- buildSrc/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts index c4f99f90838..8b5fe115442 100644 --- a/buildSrc/build.gradle.kts +++ b/buildSrc/build.gradle.kts @@ -2,7 +2,7 @@ plugins { `kotlin-dsl` // When updating, update below in dependencies too - id("com.diffplug.spotless") version "6.21.0" + id("com.diffplug.spotless") version "6.22.0" } if (!JavaVersion.current().isCompatibleWith(JavaVersion.VERSION_17)) { From 7e67a84ed31edeac5dbd1ba683df3e1c44f17f22 Mon Sep 17 00:00:00 2001 From: jack-berg <34418638+jack-berg@users.noreply.github.com> Date: Mon, 2 Oct 2023 10:17:27 -0500 Subject: [PATCH 032/901] Drop NaN measurements to metric instruments (#5859) --- .../DefaultSynchronousMetricStorage.java | 10 ++++++ .../state/SdkObservableMeasurement.java | 10 ++++++ .../sdk/metrics/SdkDoubleCounterTest.java | 9 +++++ .../sdk/metrics/SdkDoubleGaugeTest.java | 25 +++++++++++-- .../sdk/metrics/SdkDoubleHistogramTest.java | 9 +++++ .../SdkObservableDoubleCounterTest.java | 17 +++++++++ .../SdkObservableDoubleUpDownCounterTest.java | 17 +++++++++ .../state/SdkObservableMeasurementTest.java | 36 +++++++++++++++---- .../state/SynchronousMetricStorageTest.java | 25 ++++++++++++- 9 files changed, 147 insertions(+), 11 deletions(-) diff --git a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/state/DefaultSynchronousMetricStorage.java b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/state/DefaultSynchronousMetricStorage.java index 44c5050dbd4..3a359d75d23 100644 --- a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/state/DefaultSynchronousMetricStorage.java +++ b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/state/DefaultSynchronousMetricStorage.java @@ -89,6 +89,16 @@ public void recordLong(long value, Attributes attributes, Context context) { @Override public void recordDouble(double value, Attributes attributes, Context context) { + if (Double.isNaN(value)) { + logger.log( + Level.FINE, + "Instrument " + + metricDescriptor.getSourceInstrument().getName() + + " has recorded measurement Not-a-Number (NaN) value with attributes " + + attributes + + ". Dropping measurement."); + return; + } AggregatorHandle handle = getAggregatorHandle(attributes, context); handle.recordDouble(value, attributes, context); } diff --git a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/state/SdkObservableMeasurement.java b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/state/SdkObservableMeasurement.java index 6d0187b443b..27eeac81190 100644 --- a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/state/SdkObservableMeasurement.java +++ b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/state/SdkObservableMeasurement.java @@ -139,6 +139,16 @@ public void record(double value, Attributes attributes) { logNoActiveReader(); return; } + if (Double.isNaN(value)) { + logger.log( + Level.FINE, + "Instrument " + + instrumentDescriptor.getName() + + " has recorded measurement Not-a-Number (NaN) value with attributes " + + attributes + + ". Dropping measurement."); + return; + } Measurement measurement; MemoryMode memoryMode = activeReader.getReader().getMemoryMode(); diff --git a/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/SdkDoubleCounterTest.java b/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/SdkDoubleCounterTest.java index 215eaa2fe31..d733821972b 100644 --- a/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/SdkDoubleCounterTest.java +++ b/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/SdkDoubleCounterTest.java @@ -16,6 +16,7 @@ import io.opentelemetry.api.metrics.Meter; import io.opentelemetry.internal.testing.slf4j.SuppressLogger; import io.opentelemetry.sdk.common.InstrumentationScopeInfo; +import io.opentelemetry.sdk.metrics.internal.state.DefaultSynchronousMetricStorage; import io.opentelemetry.sdk.resources.Resource; import io.opentelemetry.sdk.testing.exporter.InMemoryMetricReader; import io.opentelemetry.sdk.testing.time.TestClock; @@ -166,6 +167,14 @@ void doubleCounterAdd_Monotonicity() { "Counters can only increase. Instrument testCounter has recorded a negative value."); } + @Test + @SuppressLogger(DefaultSynchronousMetricStorage.class) + void doubleCounterAdd_NaN() { + DoubleCounter doubleCounter = sdkMeter.counterBuilder("testCounter").ofDoubles().build(); + doubleCounter.add(Double.NaN); + assertThat(sdkMeterReader.collectAllMetrics()).hasSize(0); + } + @Test void stressTest() { DoubleCounter doubleCounter = sdkMeter.counterBuilder("testCounter").ofDoubles().build(); diff --git a/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/SdkDoubleGaugeTest.java b/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/SdkDoubleGaugeTest.java index 404ed738d83..cb13c2c9e95 100644 --- a/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/SdkDoubleGaugeTest.java +++ b/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/SdkDoubleGaugeTest.java @@ -15,13 +15,15 @@ import io.opentelemetry.api.metrics.ObservableDoubleGauge; import io.opentelemetry.extension.incubator.metrics.DoubleGauge; import io.opentelemetry.extension.incubator.metrics.ExtendedDoubleGaugeBuilder; +import io.opentelemetry.internal.testing.slf4j.SuppressLogger; import io.opentelemetry.sdk.common.InstrumentationScopeInfo; +import io.opentelemetry.sdk.metrics.internal.state.DefaultSynchronousMetricStorage; +import io.opentelemetry.sdk.metrics.internal.state.SdkObservableMeasurement; import io.opentelemetry.sdk.resources.Resource; import io.opentelemetry.sdk.testing.exporter.InMemoryMetricReader; import io.opentelemetry.sdk.testing.time.TestClock; import java.time.Duration; import java.util.stream.IntStream; -import org.assertj.core.api.Assertions; import org.junit.jupiter.api.Test; /** Unit tests for {@link SdkDoubleGauge}. */ @@ -54,12 +56,20 @@ void set_PreventNullAttributes() { .hasMessage("attributes"); } + @Test + @SuppressLogger(DefaultSynchronousMetricStorage.class) + void set_NaN() { + DoubleGauge gauge = ((ExtendedDoubleGaugeBuilder) sdkMeter.gaugeBuilder("testGauge")).build(); + gauge.set(Double.NaN); + assertThat(cumulativeReader.collectAllMetrics()).hasSize(0); + } + @Test void observable_RemoveCallback() { ObservableDoubleGauge gauge = sdkMeter.gaugeBuilder("testGauge").buildWithCallback(measurement -> measurement.record(10)); - Assertions.assertThat(cumulativeReader.collectAllMetrics()) + assertThat(cumulativeReader.collectAllMetrics()) .satisfiesExactly( metric -> assertThat(metric) @@ -69,7 +79,16 @@ void observable_RemoveCallback() { gauge.close(); - Assertions.assertThat(cumulativeReader.collectAllMetrics()).hasSize(0); + assertThat(cumulativeReader.collectAllMetrics()).hasSize(0); + } + + @Test + @SuppressLogger(SdkObservableMeasurement.class) + void observable_NaN() { + sdkMeter + .gaugeBuilder("testGauge") + .buildWithCallback(measurement -> measurement.record(Double.NaN)); + assertThat(cumulativeReader.collectAllMetrics()).hasSize(0); } @Test diff --git a/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/SdkDoubleHistogramTest.java b/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/SdkDoubleHistogramTest.java index 6862a1d8fc9..dd060736ed6 100644 --- a/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/SdkDoubleHistogramTest.java +++ b/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/SdkDoubleHistogramTest.java @@ -16,6 +16,7 @@ import io.opentelemetry.api.metrics.Meter; import io.opentelemetry.internal.testing.slf4j.SuppressLogger; import io.opentelemetry.sdk.common.InstrumentationScopeInfo; +import io.opentelemetry.sdk.metrics.internal.state.DefaultSynchronousMetricStorage; import io.opentelemetry.sdk.resources.Resource; import io.opentelemetry.sdk.testing.exporter.InMemoryMetricReader; import io.opentelemetry.sdk.testing.time.TestClock; @@ -266,6 +267,14 @@ void doubleHistogramRecord_NonNegativeCheck() { "Histograms can only record non-negative values. Instrument testHistogram has recorded a negative value."); } + @Test + @SuppressLogger(DefaultSynchronousMetricStorage.class) + void doubleHistogramRecord_NaN() { + DoubleHistogram histogram = sdkMeter.histogramBuilder("testHistogram").build(); + histogram.record(Double.NaN); + assertThat(sdkMeterReader.collectAllMetrics()).hasSize(0); + } + @Test void stressTest() { DoubleHistogram doubleHistogram = sdkMeter.histogramBuilder("testHistogram").build(); diff --git a/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/SdkObservableDoubleCounterTest.java b/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/SdkObservableDoubleCounterTest.java index a568a3ffb2d..cc1c887bf3a 100644 --- a/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/SdkObservableDoubleCounterTest.java +++ b/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/SdkObservableDoubleCounterTest.java @@ -8,10 +8,13 @@ import static io.opentelemetry.api.common.AttributeKey.stringKey; import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.assertThat; import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.attributeEntry; +import static org.assertj.core.api.Assertions.assertThat; import io.opentelemetry.api.common.Attributes; import io.opentelemetry.api.metrics.ObservableDoubleCounter; +import io.opentelemetry.internal.testing.slf4j.SuppressLogger; import io.opentelemetry.sdk.common.InstrumentationScopeInfo; +import io.opentelemetry.sdk.metrics.internal.state.SdkObservableMeasurement; import io.opentelemetry.sdk.resources.Resource; import io.opentelemetry.sdk.testing.exporter.InMemoryMetricReader; import io.opentelemetry.sdk.testing.time.TestClock; @@ -53,6 +56,20 @@ void removeCallback() { assertThat(sdkMeterReader.collectAllMetrics()).hasSize(0); } + @Test + @SuppressLogger(SdkObservableMeasurement.class) + void observable_NaN() { + InMemoryMetricReader sdkMeterReader = InMemoryMetricReader.create(); + SdkMeterProvider sdkMeterProvider = + sdkMeterProviderBuilder.registerMetricReader(sdkMeterReader).build(); + sdkMeterProvider + .get(getClass().getName()) + .counterBuilder("testObserver") + .ofDoubles() + .buildWithCallback(measurement -> measurement.record(Double.NaN)); + assertThat(sdkMeterReader.collectAllMetrics()).hasSize(0); + } + @Test void collectMetrics_NoRecords() { InMemoryMetricReader sdkMeterReader = InMemoryMetricReader.create(); diff --git a/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/SdkObservableDoubleUpDownCounterTest.java b/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/SdkObservableDoubleUpDownCounterTest.java index daf0dc0f18e..8b212220093 100644 --- a/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/SdkObservableDoubleUpDownCounterTest.java +++ b/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/SdkObservableDoubleUpDownCounterTest.java @@ -8,12 +8,15 @@ import static io.opentelemetry.api.common.AttributeKey.stringKey; import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.assertThat; import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.attributeEntry; +import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.mockito.Mockito.mock; import io.opentelemetry.api.common.Attributes; import io.opentelemetry.api.metrics.ObservableDoubleUpDownCounter; +import io.opentelemetry.internal.testing.slf4j.SuppressLogger; import io.opentelemetry.sdk.common.InstrumentationScopeInfo; +import io.opentelemetry.sdk.metrics.internal.state.SdkObservableMeasurement; import io.opentelemetry.sdk.resources.Resource; import io.opentelemetry.sdk.testing.exporter.InMemoryMetricReader; import io.opentelemetry.sdk.testing.time.TestClock; @@ -55,6 +58,20 @@ void removeCallback() { assertThat(sdkMeterReader.collectAllMetrics()).hasSize(0); } + @Test + @SuppressLogger(SdkObservableMeasurement.class) + void observable_NaN() { + InMemoryMetricReader sdkMeterReader = InMemoryMetricReader.create(); + SdkMeterProvider sdkMeterProvider = + sdkMeterProviderBuilder.registerMetricReader(sdkMeterReader).build(); + sdkMeterProvider + .get(getClass().getName()) + .upDownCounterBuilder("testCounter") + .ofDoubles() + .buildWithCallback(measurement -> measurement.record(Double.NaN)); + assertThat(sdkMeterReader.collectAllMetrics()).hasSize(0); + } + @Test void collectMetrics_NoRecords() { InMemoryMetricReader sdkMeterReader = InMemoryMetricReader.create(); diff --git a/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/internal/state/SdkObservableMeasurementTest.java b/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/internal/state/SdkObservableMeasurementTest.java index ca3590f1fd4..aaef2c841fe 100644 --- a/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/internal/state/SdkObservableMeasurementTest.java +++ b/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/internal/state/SdkObservableMeasurementTest.java @@ -7,11 +7,15 @@ import static io.opentelemetry.sdk.metrics.data.AggregationTemporality.CUMULATIVE; import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.never; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; +import io.github.netmikey.logunit.api.LogCapturer; +import io.opentelemetry.internal.testing.slf4j.SuppressLogger; import io.opentelemetry.sdk.common.InstrumentationScopeInfo; import io.opentelemetry.sdk.common.export.MemoryMode; import io.opentelemetry.sdk.metrics.InstrumentType; @@ -21,12 +25,18 @@ import io.opentelemetry.sdk.metrics.internal.export.RegisteredReader; import io.opentelemetry.sdk.metrics.internal.view.ViewRegistry; import io.opentelemetry.sdk.testing.exporter.InMemoryMetricReader; -import org.assertj.core.util.Lists; +import java.util.Arrays; import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; import org.mockito.ArgumentCaptor; +import org.slf4j.event.Level; @SuppressWarnings("rawtypes") -public class SdkObservableMeasurementTest { +class SdkObservableMeasurementTest { + + @RegisterExtension + final LogCapturer logs = + LogCapturer.create().captureForLogger(SdkObservableMeasurement.class.getName(), Level.DEBUG); private AsynchronousMetricStorage mockAsyncStorage1; private RegisteredReader registeredReader1; @@ -66,11 +76,11 @@ private void setup(MemoryMode memoryMode) { SdkObservableMeasurement.create( instrumentationScopeInfo, instrumentDescriptor, - Lists.newArrayList(mockAsyncStorage1, mockAsyncStorage2)); + Arrays.asList(mockAsyncStorage1, mockAsyncStorage2)); } @Test - public void testRecordLongImmutableData() { + void recordLong_ImmutableData() { setup(MemoryMode.IMMUTABLE_DATA); sdkObservableMeasurement.setActiveReader(registeredReader1, 0, 10); @@ -90,7 +100,7 @@ public void testRecordLongImmutableData() { } @Test - public void testRecordDoubleReturnImmutableData() { + void recordDouble_ImmutableData() { setup(MemoryMode.IMMUTABLE_DATA); sdkObservableMeasurement.setActiveReader(registeredReader1, 0, 10); @@ -110,7 +120,7 @@ public void testRecordDoubleReturnImmutableData() { } @Test - public void testRecordDoubleReturnReusableData() { + void recordDouble_ReusableData() { setup(MemoryMode.REUSABLE_DATA); sdkObservableMeasurement.setActiveReader(registeredReader1, 0, 10); @@ -142,7 +152,7 @@ public void testRecordDoubleReturnReusableData() { } @Test - public void testRecordLongReturnReusableData() { + void recordLong_ReusableData() { setup(MemoryMode.REUSABLE_DATA); sdkObservableMeasurement.setActiveReader(registeredReader1, 0, 10); @@ -172,4 +182,16 @@ public void testRecordLongReturnReusableData() { sdkObservableMeasurement.unsetActiveReader(); } } + + @Test + @SuppressLogger(SdkObservableMeasurement.class) + void recordDouble_NaN() { + setup(MemoryMode.REUSABLE_DATA); + sdkObservableMeasurement.setActiveReader(registeredReader1, 0, 10); + sdkObservableMeasurement.record(Double.NaN); + + verify(mockAsyncStorage1, never()).record(any()); + logs.assertContains( + "Instrument testCounter has recorded measurement Not-a-Number (NaN) value with attributes {}. Dropping measurement."); + } } diff --git a/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/internal/state/SynchronousMetricStorageTest.java b/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/internal/state/SynchronousMetricStorageTest.java index 96f4d6274b7..aa6fe1d3999 100644 --- a/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/internal/state/SynchronousMetricStorageTest.java +++ b/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/internal/state/SynchronousMetricStorageTest.java @@ -7,6 +7,7 @@ import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.assertThat; import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.attributeEntry; +import static org.mockito.Mockito.never; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; @@ -25,6 +26,7 @@ import io.opentelemetry.sdk.metrics.data.MetricData; import io.opentelemetry.sdk.metrics.internal.aggregator.Aggregator; import io.opentelemetry.sdk.metrics.internal.aggregator.AggregatorFactory; +import io.opentelemetry.sdk.metrics.internal.aggregator.EmptyMetricData; import io.opentelemetry.sdk.metrics.internal.descriptor.Advice; import io.opentelemetry.sdk.metrics.internal.descriptor.InstrumentDescriptor; import io.opentelemetry.sdk.metrics.internal.descriptor.MetricDescriptor; @@ -37,6 +39,7 @@ import io.opentelemetry.sdk.testing.time.TestClock; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.RegisterExtension; +import org.slf4j.event.Level; @SuppressLogger(DefaultSynchronousMetricStorage.class) public class SynchronousMetricStorageTest { @@ -56,7 +59,8 @@ public class SynchronousMetricStorageTest { private static final int CARDINALITY_LIMIT = 25; @RegisterExtension - LogCapturer logs = LogCapturer.create().captureForType(DefaultSynchronousMetricStorage.class); + LogCapturer logs = + LogCapturer.create().captureForType(DefaultSynchronousMetricStorage.class, Level.DEBUG); private final RegisteredReader deltaReader = RegisteredReader.create(InMemoryMetricReader.createDelta(), ViewRegistry.create()); @@ -69,6 +73,25 @@ public class SynchronousMetricStorageTest { .createAggregator(DESCRIPTOR, ExemplarFilter.alwaysOff())); private final AttributesProcessor attributesProcessor = AttributesProcessor.noop(); + @Test + void recordDouble_NaN() { + DefaultSynchronousMetricStorage storage = + new DefaultSynchronousMetricStorage<>( + cumulativeReader, + METRIC_DESCRIPTOR, + aggregator, + attributesProcessor, + CARDINALITY_LIMIT); + + storage.recordDouble(Double.NaN, Attributes.empty(), Context.current()); + + logs.assertContains( + "Instrument name has recorded measurement Not-a-Number (NaN) value with attributes {}. Dropping measurement."); + verify(aggregator, never()).createHandle(); + assertThat(storage.collect(RESOURCE, INSTRUMENTATION_SCOPE_INFO, 0, 10)) + .isEqualTo(EmptyMetricData.getInstance()); + } + @Test void attributesProcessor_applied() { Attributes attributes = Attributes.builder().put("K", "V").build(); From 1ef437785aa31f7e24ce4698ff2397b7f2f531c4 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 2 Oct 2023 10:17:41 -0500 Subject: [PATCH 033/901] Update dependency com.squareup.okio:okio-bom to v3.6.0 (#5869) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- dependencyManagement/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index ff60de2960b..2033ea96589 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -13,7 +13,7 @@ val DEPENDENCY_BOMS = listOf( "com.google.protobuf:protobuf-bom:3.24.3", "com.linecorp.armeria:armeria-bom:1.25.2", "com.squareup.okhttp3:okhttp-bom:4.11.0", - "com.squareup.okio:okio-bom:3.5.0", // applies to transitive dependencies of okhttp + "com.squareup.okio:okio-bom:3.6.0", // applies to transitive dependencies of okhttp "io.grpc:grpc-bom:1.58.0", "io.netty:netty-bom:4.1.99.Final", "io.zipkin.brave:brave-bom:5.16.0", From 5ccc7fccb3fd0bdfa902bfea7bcee43384cdcf3e Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 2 Oct 2023 10:42:36 -0500 Subject: [PATCH 034/901] Update dependency checkstyle to v10.12.4 (#5868) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- buildSrc/src/main/kotlin/otel.java-conventions.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/buildSrc/src/main/kotlin/otel.java-conventions.gradle.kts b/buildSrc/src/main/kotlin/otel.java-conventions.gradle.kts index bf63d7db4c5..43791644017 100644 --- a/buildSrc/src/main/kotlin/otel.java-conventions.gradle.kts +++ b/buildSrc/src/main/kotlin/otel.java-conventions.gradle.kts @@ -35,7 +35,7 @@ java { checkstyle { configDirectory.set(file("$rootDir/buildscripts/")) - toolVersion = "10.12.3" + toolVersion = "10.12.4" isIgnoreFailures = false configProperties["rootDir"] = rootDir } From 7310b90530ea33eaf1f1a246140dbcc877f50805 Mon Sep 17 00:00:00 2001 From: Lauri Tulmin Date: Thu, 5 Oct 2023 21:34:19 +0300 Subject: [PATCH 035/901] Ignore javadoc.io links (#5878) --- .github/config/markdown-link-check-config.json | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.github/config/markdown-link-check-config.json b/.github/config/markdown-link-check-config.json index a458029d5d9..0f74f443f52 100644 --- a/.github/config/markdown-link-check-config.json +++ b/.github/config/markdown-link-check-config.json @@ -3,5 +3,10 @@ "aliveStatusCodes": [ 200, 403 + ], + "ignorePatterns": [ + { + "pattern": "^https://(www\\.)?javadoc\\.io" + } ] } From 1ad621b3f0dc6c5a8e6fde0dbe78585bb4558e9e Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 5 Oct 2023 13:43:24 -0500 Subject: [PATCH 036/901] Update dependency org.testcontainers:testcontainers-bom to v1.19.1 (#5871) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- dependencyManagement/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index 2033ea96589..5bc5d804f83 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -20,7 +20,7 @@ val DEPENDENCY_BOMS = listOf( "io.zipkin.reporter2:zipkin-reporter-bom:2.16.4", "org.assertj:assertj-bom:3.24.2", "org.junit:junit-bom:5.10.0", - "org.testcontainers:testcontainers-bom:1.19.0", + "org.testcontainers:testcontainers-bom:1.19.1", "org.snakeyaml:snakeyaml-engine:2.7" ) From 847d117db1854566b15941f36bf6a02abdc3eb5d Mon Sep 17 00:00:00 2001 From: Tyler Benson Date: Thu, 5 Oct 2023 15:16:58 -0400 Subject: [PATCH 037/901] Move data dir to `benchmarks` (#5874) --- .github/workflows/benchmark-tags.yml | 2 +- .github/workflows/benchmark.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/benchmark-tags.yml b/.github/workflows/benchmark-tags.yml index 96cb0c248fe..7fb9a182150 100644 --- a/.github/workflows/benchmark-tags.yml +++ b/.github/workflows/benchmark-tags.yml @@ -69,6 +69,6 @@ jobs: output-file-path: sdk/trace/build/jmh-result.json gh-pages-branch: benchmarks github-token: ${{ secrets.GITHUB_TOKEN }} - benchmark-data-dir-path: "" + benchmark-data-dir-path: "benchmarks" auto-push: true ref: ${{ matrix.tag-version }} diff --git a/.github/workflows/benchmark.yml b/.github/workflows/benchmark.yml index 9aaa9994b2e..493e695909d 100644 --- a/.github/workflows/benchmark.yml +++ b/.github/workflows/benchmark.yml @@ -39,5 +39,5 @@ jobs: output-file-path: sdk/trace/build/jmh-result.json gh-pages-branch: benchmarks github-token: ${{ secrets.GITHUB_TOKEN }} - benchmark-data-dir-path: "" + benchmark-data-dir-path: "benchmarks" auto-push: true From 80201515e93757902877dcb5ff737fe0f4e61008 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 5 Oct 2023 14:18:07 -0500 Subject: [PATCH 038/901] Update dependency gradle to v8.4 (#5881) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- gradle/wrapper/gradle-wrapper.properties | 4 ++-- gradlew | 14 +++++++------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 864d6c47512..46671acb6e1 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,7 +1,7 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionSha256Sum=591855b517fc635b9e04de1d05d5e76ada3f89f5fc76f87978d1b245b4f69225 -distributionUrl=https\://services.gradle.org/distributions/gradle-8.3-bin.zip +distributionSha256Sum=3e1af3ae886920c3ac87f7a91f816c0c7c436f276a6eefdb3da152100fef72ae +distributionUrl=https\://services.gradle.org/distributions/gradle-8.4-bin.zip networkTimeout=10000 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME diff --git a/gradlew b/gradlew index 0adc8e1a532..1aa94a42690 100755 --- a/gradlew +++ b/gradlew @@ -145,7 +145,7 @@ if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then case $MAX_FD in #( max*) # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. - # shellcheck disable=SC3045 + # shellcheck disable=SC2039,SC3045 MAX_FD=$( ulimit -H -n ) || warn "Could not query maximum file descriptor limit" esac @@ -153,7 +153,7 @@ if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then '' | soft) :;; #( *) # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. - # shellcheck disable=SC3045 + # shellcheck disable=SC2039,SC3045 ulimit -n "$MAX_FD" || warn "Could not set maximum file descriptor limit to $MAX_FD" esac @@ -202,11 +202,11 @@ fi # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' -# Collect all arguments for the java command; -# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of -# shell script including quotes and variable substitutions, so put them in -# double quotes to make sure that they get re-expanded; and -# * put everything else in single quotes, so that it's not re-expanded. +# Collect all arguments for the java command: +# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# and any embedded shellness will be escaped. +# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be +# treated as '${Hostname}' itself on the command line. set -- \ "-Dorg.gradle.appname=$APP_BASE_NAME" \ From 4addd7f4a129305b32a104ee2b1758efe0286cc6 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 5 Oct 2023 14:18:26 -0500 Subject: [PATCH 039/901] Update plugin com.gradle.enterprise to v3.15.1 (#5882) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- settings.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/settings.gradle.kts b/settings.gradle.kts index 1fae63fd2c0..735cc2f5ccf 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -1,7 +1,7 @@ pluginManagement { plugins { id("com.github.johnrengelman.shadow") version "8.1.1" - id("com.gradle.enterprise") version "3.15" + id("com.gradle.enterprise") version "3.15.1" id("de.undercouch.download") version "5.5.0" id("org.jsonschema2pojo") version "1.2.1" id("io.github.gradle-nexus.publish-plugin") version "1.3.0" From c39ebfee25e32754f85afb61724d3bc8f0e74ba2 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 5 Oct 2023 14:18:45 -0500 Subject: [PATCH 040/901] Update dependency com.google.protobuf:protobuf-bom to v3.24.4 (#5879) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- dependencyManagement/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index 5bc5d804f83..ba9b1bfdb1e 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -10,7 +10,7 @@ rootProject.extra["versions"] = dependencyVersions val DEPENDENCY_BOMS = listOf( "com.fasterxml.jackson:jackson-bom:2.15.2", "com.google.guava:guava-bom:32.1.2-jre", - "com.google.protobuf:protobuf-bom:3.24.3", + "com.google.protobuf:protobuf-bom:3.24.4", "com.linecorp.armeria:armeria-bom:1.25.2", "com.squareup.okhttp3:okhttp-bom:4.11.0", "com.squareup.okio:okio-bom:3.6.0", // applies to transitive dependencies of okhttp From 533c30ae02ed99425beec75d1319902178df6942 Mon Sep 17 00:00:00 2001 From: Lauri Tulmin Date: Thu, 5 Oct 2023 22:19:18 +0300 Subject: [PATCH 041/901] Fix flaky MetricExporterConfigurationTest (#5877) --- .../MetricExporterConfigurationTest.java | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/sdk-extensions/autoconfigure/src/testFullConfig/java/io/opentelemetry/sdk/autoconfigure/MetricExporterConfigurationTest.java b/sdk-extensions/autoconfigure/src/testFullConfig/java/io/opentelemetry/sdk/autoconfigure/MetricExporterConfigurationTest.java index 205eb674254..6db4b23f82e 100644 --- a/sdk-extensions/autoconfigure/src/testFullConfig/java/io/opentelemetry/sdk/autoconfigure/MetricExporterConfigurationTest.java +++ b/sdk-extensions/autoconfigure/src/testFullConfig/java/io/opentelemetry/sdk/autoconfigure/MetricExporterConfigurationTest.java @@ -34,8 +34,9 @@ class MetricExporterConfigurationTest { - private static final ConfigProperties EMPTY = - DefaultConfigProperties.createFromMap(Collections.emptyMap()); + private static final ConfigProperties CONFIG_PROPERTIES = + DefaultConfigProperties.createFromMap( + Collections.singletonMap("otel.exporter.prometheus.port", "0")); @RegisterExtension CleanupExtension cleanup = new CleanupExtension(); @@ -48,7 +49,7 @@ void configureReader_PrometheusOnClasspath() { MetricReader reader = MetricExporterConfiguration.configureReader( - "prometheus", EMPTY, spiHelper, (a, b) -> a, closeables); + "prometheus", CONFIG_PROPERTIES, spiHelper, (a, b) -> a, closeables); cleanup.addCloseables(closeables); assertThat(reader).isInstanceOf(PrometheusHttpServer.class); @@ -60,7 +61,7 @@ void configureReader_PrometheusOnClasspath() { void configureExporter_KnownSpiExportersOnClasspath( String exporterName, Class expectedExporter) { NamedSpiManager spiExportersManager = - MetricExporterConfiguration.metricExporterSpiManager(EMPTY, spiHelper); + MetricExporterConfiguration.metricExporterSpiManager(CONFIG_PROPERTIES, spiHelper); MetricExporter metricExporter = MetricExporterConfiguration.configureExporter(exporterName, spiExportersManager); @@ -81,7 +82,7 @@ private static Stream knownExporters() { void configureMetricReader_KnownSpiExportersOnClasspath( String exporterName, Class expectedExporter) { NamedSpiManager spiMetricReadersManager = - MetricExporterConfiguration.metricReadersSpiManager(EMPTY, spiHelper); + MetricExporterConfiguration.metricReadersSpiManager(CONFIG_PROPERTIES, spiHelper); MetricReader metricReader = MetricExporterConfiguration.configureMetricReader(exporterName, spiMetricReadersManager); From 92abcb823b0d13301cc0064520c0a07f4e55091e Mon Sep 17 00:00:00 2001 From: jack-berg <34418638+jack-berg@users.noreply.github.com> Date: Fri, 6 Oct 2023 13:33:10 -0500 Subject: [PATCH 042/901] Refactor advice API (#5848) --- .../DoubleCounterAdviceConfigurer.java | 17 ---------------- .../metrics/DoubleGaugeAdviceConfigurer.java | 16 --------------- .../DoubleHistogramAdviceConfigurer.java | 20 ------------------- .../DoubleUpDownCounterAdviceConfigurer.java | 17 ---------------- .../metrics/ExtendedDoubleCounterBuilder.java | 10 +++++++--- .../metrics/ExtendedDoubleGaugeBuilder.java | 9 +++++++-- .../ExtendedDoubleHistogramBuilder.java | 20 +++++++++++++++---- .../ExtendedDoubleUpDownCounterBuilder.java | 11 ++++++---- .../metrics/ExtendedLongCounterBuilder.java | 10 +++++++--- .../metrics/ExtendedLongGaugeBuilder.java | 9 +++++++-- .../metrics/ExtendedLongHistogramBuilder.java | 19 +++++++++++++++--- .../ExtendedLongUpDownCounterBuilder.java | 11 ++++++---- .../metrics/LongCounterAdviceConfigurer.java | 17 ---------------- .../metrics/LongGaugeAdviceConfigurer.java | 16 --------------- .../LongHistogramAdviceConfigurer.java | 20 ------------------- .../LongUpDownCounterAdviceConfigurer.java | 17 ---------------- .../sdk/metrics/SdkDoubleCounter.java | 12 ++--------- .../sdk/metrics/SdkDoubleGauge.java | 12 ++--------- .../sdk/metrics/SdkDoubleHistogram.java | 15 +++----------- .../sdk/metrics/SdkDoubleUpDownCounter.java | 14 +++---------- .../sdk/metrics/SdkLongCounter.java | 12 ++--------- .../sdk/metrics/SdkLongGauge.java | 12 ++--------- .../sdk/metrics/SdkLongHistogram.java | 16 ++++----------- .../sdk/metrics/SdkLongUpDownCounter.java | 13 ++---------- .../sdk/metrics/AttributesAdviceTest.java | 16 +++++++-------- .../ExplicitBucketBoundariesAdviceTest.java | 9 ++------- .../sdk/metrics/IdentityTest.java | 4 ++-- 27 files changed, 106 insertions(+), 268 deletions(-) delete mode 100644 extensions/incubator/src/main/java/io/opentelemetry/extension/incubator/metrics/DoubleCounterAdviceConfigurer.java delete mode 100644 extensions/incubator/src/main/java/io/opentelemetry/extension/incubator/metrics/DoubleGaugeAdviceConfigurer.java delete mode 100644 extensions/incubator/src/main/java/io/opentelemetry/extension/incubator/metrics/DoubleHistogramAdviceConfigurer.java delete mode 100644 extensions/incubator/src/main/java/io/opentelemetry/extension/incubator/metrics/DoubleUpDownCounterAdviceConfigurer.java delete mode 100644 extensions/incubator/src/main/java/io/opentelemetry/extension/incubator/metrics/LongCounterAdviceConfigurer.java delete mode 100644 extensions/incubator/src/main/java/io/opentelemetry/extension/incubator/metrics/LongGaugeAdviceConfigurer.java delete mode 100644 extensions/incubator/src/main/java/io/opentelemetry/extension/incubator/metrics/LongHistogramAdviceConfigurer.java delete mode 100644 extensions/incubator/src/main/java/io/opentelemetry/extension/incubator/metrics/LongUpDownCounterAdviceConfigurer.java diff --git a/extensions/incubator/src/main/java/io/opentelemetry/extension/incubator/metrics/DoubleCounterAdviceConfigurer.java b/extensions/incubator/src/main/java/io/opentelemetry/extension/incubator/metrics/DoubleCounterAdviceConfigurer.java deleted file mode 100644 index 51c3a6c3447..00000000000 --- a/extensions/incubator/src/main/java/io/opentelemetry/extension/incubator/metrics/DoubleCounterAdviceConfigurer.java +++ /dev/null @@ -1,17 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package io.opentelemetry.extension.incubator.metrics; - -import io.opentelemetry.api.common.AttributeKey; -import io.opentelemetry.api.metrics.DoubleCounter; -import java.util.List; - -/** Configure advice for implementation of {@link DoubleCounter}. */ -public interface DoubleCounterAdviceConfigurer { - - /** Specify the recommended set of attribute keys to be used for this counter. */ - DoubleCounterAdviceConfigurer setAttributes(List> attributes); -} diff --git a/extensions/incubator/src/main/java/io/opentelemetry/extension/incubator/metrics/DoubleGaugeAdviceConfigurer.java b/extensions/incubator/src/main/java/io/opentelemetry/extension/incubator/metrics/DoubleGaugeAdviceConfigurer.java deleted file mode 100644 index 3c99c1d6df5..00000000000 --- a/extensions/incubator/src/main/java/io/opentelemetry/extension/incubator/metrics/DoubleGaugeAdviceConfigurer.java +++ /dev/null @@ -1,16 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package io.opentelemetry.extension.incubator.metrics; - -import io.opentelemetry.api.common.AttributeKey; -import java.util.List; - -/** Configure advice for implementation of {@code DoubleGauge}. */ -public interface DoubleGaugeAdviceConfigurer { - - /** Specify the recommended set of attribute keys to be used for this gauge. */ - DoubleGaugeAdviceConfigurer setAttributes(List> attributes); -} diff --git a/extensions/incubator/src/main/java/io/opentelemetry/extension/incubator/metrics/DoubleHistogramAdviceConfigurer.java b/extensions/incubator/src/main/java/io/opentelemetry/extension/incubator/metrics/DoubleHistogramAdviceConfigurer.java deleted file mode 100644 index 404a3db9d16..00000000000 --- a/extensions/incubator/src/main/java/io/opentelemetry/extension/incubator/metrics/DoubleHistogramAdviceConfigurer.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package io.opentelemetry.extension.incubator.metrics; - -import io.opentelemetry.api.common.AttributeKey; -import io.opentelemetry.api.metrics.DoubleHistogram; -import java.util.List; - -/** Configure advice for implementations of {@link DoubleHistogram}. */ -public interface DoubleHistogramAdviceConfigurer { - - /** Specify recommended set of explicit bucket boundaries for this histogram. */ - DoubleHistogramAdviceConfigurer setExplicitBucketBoundaries(List bucketBoundaries); - - /** Specify the recommended set of attribute keys to be used for this histogram. */ - DoubleHistogramAdviceConfigurer setAttributes(List> attributes); -} diff --git a/extensions/incubator/src/main/java/io/opentelemetry/extension/incubator/metrics/DoubleUpDownCounterAdviceConfigurer.java b/extensions/incubator/src/main/java/io/opentelemetry/extension/incubator/metrics/DoubleUpDownCounterAdviceConfigurer.java deleted file mode 100644 index 06acffb4e3a..00000000000 --- a/extensions/incubator/src/main/java/io/opentelemetry/extension/incubator/metrics/DoubleUpDownCounterAdviceConfigurer.java +++ /dev/null @@ -1,17 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package io.opentelemetry.extension.incubator.metrics; - -import io.opentelemetry.api.common.AttributeKey; -import io.opentelemetry.api.metrics.DoubleUpDownCounter; -import java.util.List; - -/** Configure advice for implementation of {@link DoubleUpDownCounter}. */ -public interface DoubleUpDownCounterAdviceConfigurer { - - /** Specify the recommended set of attribute keys to be used for this up down counter. */ - DoubleUpDownCounterAdviceConfigurer setAttributes(List> attributes); -} diff --git a/extensions/incubator/src/main/java/io/opentelemetry/extension/incubator/metrics/ExtendedDoubleCounterBuilder.java b/extensions/incubator/src/main/java/io/opentelemetry/extension/incubator/metrics/ExtendedDoubleCounterBuilder.java index a6bcc97a8c2..af295db6e63 100644 --- a/extensions/incubator/src/main/java/io/opentelemetry/extension/incubator/metrics/ExtendedDoubleCounterBuilder.java +++ b/extensions/incubator/src/main/java/io/opentelemetry/extension/incubator/metrics/ExtendedDoubleCounterBuilder.java @@ -5,14 +5,18 @@ package io.opentelemetry.extension.incubator.metrics; +import io.opentelemetry.api.common.AttributeKey; import io.opentelemetry.api.metrics.DoubleCounterBuilder; -import java.util.function.Consumer; +import java.util.List; /** Extended {@link DoubleCounterBuilder} with experimental APIs. */ public interface ExtendedDoubleCounterBuilder extends DoubleCounterBuilder { - /** Specify advice for counter implementations. */ - default DoubleCounterBuilder setAdvice(Consumer adviceConsumer) { + /** + * Specify the attribute advice, which suggests the recommended set of attribute keys to be used + * for this counter. + */ + default ExtendedDoubleCounterBuilder setAttributesAdvice(List> attributes) { return this; } } diff --git a/extensions/incubator/src/main/java/io/opentelemetry/extension/incubator/metrics/ExtendedDoubleGaugeBuilder.java b/extensions/incubator/src/main/java/io/opentelemetry/extension/incubator/metrics/ExtendedDoubleGaugeBuilder.java index 208dba0c32f..0ee94b6522c 100644 --- a/extensions/incubator/src/main/java/io/opentelemetry/extension/incubator/metrics/ExtendedDoubleGaugeBuilder.java +++ b/extensions/incubator/src/main/java/io/opentelemetry/extension/incubator/metrics/ExtendedDoubleGaugeBuilder.java @@ -5,7 +5,9 @@ package io.opentelemetry.extension.incubator.metrics; +import io.opentelemetry.api.common.AttributeKey; import io.opentelemetry.api.metrics.DoubleGaugeBuilder; +import java.util.List; import java.util.function.Consumer; /** Extended {@link DoubleGaugeBuilder} with experimental APIs. */ @@ -22,8 +24,11 @@ public interface ExtendedDoubleGaugeBuilder extends DoubleGaugeBuilder { */ DoubleGauge build(); - /** Specify advice for gauge implementations. */ - default DoubleGaugeBuilder setAdvice(Consumer adviceConsumer) { + /** + * Specify the attribute advice, which suggests the recommended set of attribute keys to be used + * for this gauge. + */ + default ExtendedDoubleGaugeBuilder setAttributesAdvice(List> attributes) { return this; } } diff --git a/extensions/incubator/src/main/java/io/opentelemetry/extension/incubator/metrics/ExtendedDoubleHistogramBuilder.java b/extensions/incubator/src/main/java/io/opentelemetry/extension/incubator/metrics/ExtendedDoubleHistogramBuilder.java index c48cf9420de..881727538c2 100644 --- a/extensions/incubator/src/main/java/io/opentelemetry/extension/incubator/metrics/ExtendedDoubleHistogramBuilder.java +++ b/extensions/incubator/src/main/java/io/opentelemetry/extension/incubator/metrics/ExtendedDoubleHistogramBuilder.java @@ -5,15 +5,27 @@ package io.opentelemetry.extension.incubator.metrics; +import io.opentelemetry.api.common.AttributeKey; import io.opentelemetry.api.metrics.DoubleHistogramBuilder; -import java.util.function.Consumer; +import java.util.List; /** Extended {@link DoubleHistogramBuilder} with experimental APIs. */ public interface ExtendedDoubleHistogramBuilder extends DoubleHistogramBuilder { - /** Specify advice for histogram implementations. */ - default DoubleHistogramBuilder setAdvice( - Consumer adviceConsumer) { + /** + * Specify the explicit bucket buckets boundaries advice, which suggests the recommended set of + * explicit bucket boundaries for this histogram. + */ + default ExtendedDoubleHistogramBuilder setExplicitBucketBoundariesAdvice( + List bucketBoundaries) { + return this; + } + + /** + * Specify the attribute advice, which suggests the recommended set of attribute keys to be used + * for this histogram. + */ + default ExtendedDoubleHistogramBuilder setAttributesAdvice(List> attributes) { return this; } } diff --git a/extensions/incubator/src/main/java/io/opentelemetry/extension/incubator/metrics/ExtendedDoubleUpDownCounterBuilder.java b/extensions/incubator/src/main/java/io/opentelemetry/extension/incubator/metrics/ExtendedDoubleUpDownCounterBuilder.java index b50e0e155db..9905f323d9a 100644 --- a/extensions/incubator/src/main/java/io/opentelemetry/extension/incubator/metrics/ExtendedDoubleUpDownCounterBuilder.java +++ b/extensions/incubator/src/main/java/io/opentelemetry/extension/incubator/metrics/ExtendedDoubleUpDownCounterBuilder.java @@ -5,15 +5,18 @@ package io.opentelemetry.extension.incubator.metrics; +import io.opentelemetry.api.common.AttributeKey; import io.opentelemetry.api.metrics.DoubleUpDownCounterBuilder; -import java.util.function.Consumer; +import java.util.List; /** Extended {@link DoubleUpDownCounterBuilder} with experimental APIs. */ public interface ExtendedDoubleUpDownCounterBuilder extends DoubleUpDownCounterBuilder { - /** Specify advice for up down counter implementations. */ - default DoubleUpDownCounterBuilder setAdvice( - Consumer adviceConsumer) { + /** + * Specify the attribute advice, which suggests the recommended set of attribute keys to be used + * for this up down counter. + */ + default ExtendedDoubleUpDownCounterBuilder setAttributesAdvice(List> attributes) { return this; } } diff --git a/extensions/incubator/src/main/java/io/opentelemetry/extension/incubator/metrics/ExtendedLongCounterBuilder.java b/extensions/incubator/src/main/java/io/opentelemetry/extension/incubator/metrics/ExtendedLongCounterBuilder.java index 9171156d8ae..02bbf1b83e0 100644 --- a/extensions/incubator/src/main/java/io/opentelemetry/extension/incubator/metrics/ExtendedLongCounterBuilder.java +++ b/extensions/incubator/src/main/java/io/opentelemetry/extension/incubator/metrics/ExtendedLongCounterBuilder.java @@ -5,14 +5,18 @@ package io.opentelemetry.extension.incubator.metrics; +import io.opentelemetry.api.common.AttributeKey; import io.opentelemetry.api.metrics.LongCounterBuilder; -import java.util.function.Consumer; +import java.util.List; /** Extended {@link LongCounterBuilder} with experimental APIs. */ public interface ExtendedLongCounterBuilder extends LongCounterBuilder { - /** Specify advice for counter implementations. */ - default LongCounterBuilder setAdvice(Consumer adviceConsumer) { + /** + * Specify the attribute advice, which suggests the recommended set of attribute keys to be used + * for this counter. + */ + default ExtendedLongCounterBuilder setAttributesAdvice(List> attributes) { return this; } } diff --git a/extensions/incubator/src/main/java/io/opentelemetry/extension/incubator/metrics/ExtendedLongGaugeBuilder.java b/extensions/incubator/src/main/java/io/opentelemetry/extension/incubator/metrics/ExtendedLongGaugeBuilder.java index 1c42952834f..e1ca168f10b 100644 --- a/extensions/incubator/src/main/java/io/opentelemetry/extension/incubator/metrics/ExtendedLongGaugeBuilder.java +++ b/extensions/incubator/src/main/java/io/opentelemetry/extension/incubator/metrics/ExtendedLongGaugeBuilder.java @@ -5,7 +5,9 @@ package io.opentelemetry.extension.incubator.metrics; +import io.opentelemetry.api.common.AttributeKey; import io.opentelemetry.api.metrics.LongGaugeBuilder; +import java.util.List; import java.util.function.Consumer; /** Extended {@link LongGaugeBuilder} with experimental APIs. */ @@ -22,8 +24,11 @@ public interface ExtendedLongGaugeBuilder extends LongGaugeBuilder { */ LongGauge build(); - /** Specify advice for gauge implementations. */ - default LongGaugeBuilder setAdvice(Consumer adviceConsumer) { + /** + * Specify the attribute advice, which suggests the recommended set of attribute keys to be used + * for this gauge. + */ + default ExtendedLongGaugeBuilder setAttributesAdvice(List> attributes) { return this; } } diff --git a/extensions/incubator/src/main/java/io/opentelemetry/extension/incubator/metrics/ExtendedLongHistogramBuilder.java b/extensions/incubator/src/main/java/io/opentelemetry/extension/incubator/metrics/ExtendedLongHistogramBuilder.java index 211c86fe7cd..665e4e3555e 100644 --- a/extensions/incubator/src/main/java/io/opentelemetry/extension/incubator/metrics/ExtendedLongHistogramBuilder.java +++ b/extensions/incubator/src/main/java/io/opentelemetry/extension/incubator/metrics/ExtendedLongHistogramBuilder.java @@ -5,14 +5,27 @@ package io.opentelemetry.extension.incubator.metrics; +import io.opentelemetry.api.common.AttributeKey; import io.opentelemetry.api.metrics.LongHistogramBuilder; -import java.util.function.Consumer; +import java.util.List; /** Extended {@link LongHistogramBuilder} with experimental APIs. */ public interface ExtendedLongHistogramBuilder extends LongHistogramBuilder { - /** Specify advice for histogram implementations. */ - default LongHistogramBuilder setAdvice(Consumer adviceConsumer) { + /** + * Specify the explicit bucket buckets boundaries advice, which suggests the recommended set of + * explicit bucket boundaries for this histogram. + */ + default ExtendedLongHistogramBuilder setExplicitBucketBoundariesAdvice( + List bucketBoundaries) { + return this; + } + + /** + * Specify the attribute advice, which suggests the recommended set of attribute keys to be used + * for this histogram. + */ + default ExtendedLongHistogramBuilder setAttributesAdvice(List> attributes) { return this; } } diff --git a/extensions/incubator/src/main/java/io/opentelemetry/extension/incubator/metrics/ExtendedLongUpDownCounterBuilder.java b/extensions/incubator/src/main/java/io/opentelemetry/extension/incubator/metrics/ExtendedLongUpDownCounterBuilder.java index 75cb286376e..0d0ae2781ee 100644 --- a/extensions/incubator/src/main/java/io/opentelemetry/extension/incubator/metrics/ExtendedLongUpDownCounterBuilder.java +++ b/extensions/incubator/src/main/java/io/opentelemetry/extension/incubator/metrics/ExtendedLongUpDownCounterBuilder.java @@ -5,15 +5,18 @@ package io.opentelemetry.extension.incubator.metrics; +import io.opentelemetry.api.common.AttributeKey; import io.opentelemetry.api.metrics.LongUpDownCounterBuilder; -import java.util.function.Consumer; +import java.util.List; /** Extended {@link LongUpDownCounterBuilder} with experimental APIs. */ public interface ExtendedLongUpDownCounterBuilder extends LongUpDownCounterBuilder { - /** Specify advice for up down counter implementations. */ - default LongUpDownCounterBuilder setAdvice( - Consumer adviceConsumer) { + /** + * Specify the attribute advice, which suggests the recommended set of attribute keys to be used + * for this up down counter. + */ + default ExtendedLongUpDownCounterBuilder setAttributesAdvice(List> attributes) { return this; } } diff --git a/extensions/incubator/src/main/java/io/opentelemetry/extension/incubator/metrics/LongCounterAdviceConfigurer.java b/extensions/incubator/src/main/java/io/opentelemetry/extension/incubator/metrics/LongCounterAdviceConfigurer.java deleted file mode 100644 index 3a0e9bbe70d..00000000000 --- a/extensions/incubator/src/main/java/io/opentelemetry/extension/incubator/metrics/LongCounterAdviceConfigurer.java +++ /dev/null @@ -1,17 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package io.opentelemetry.extension.incubator.metrics; - -import io.opentelemetry.api.common.AttributeKey; -import io.opentelemetry.api.metrics.LongCounter; -import java.util.List; - -/** Configure advice for implementation of {@link LongCounter}. */ -public interface LongCounterAdviceConfigurer { - - /** Specify the recommended set of attribute keys to be used for this counter. */ - LongCounterAdviceConfigurer setAttributes(List> attributes); -} diff --git a/extensions/incubator/src/main/java/io/opentelemetry/extension/incubator/metrics/LongGaugeAdviceConfigurer.java b/extensions/incubator/src/main/java/io/opentelemetry/extension/incubator/metrics/LongGaugeAdviceConfigurer.java deleted file mode 100644 index c424a878971..00000000000 --- a/extensions/incubator/src/main/java/io/opentelemetry/extension/incubator/metrics/LongGaugeAdviceConfigurer.java +++ /dev/null @@ -1,16 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package io.opentelemetry.extension.incubator.metrics; - -import io.opentelemetry.api.common.AttributeKey; -import java.util.List; - -/** Configure advice for implementation of {@code LongGauge}. */ -public interface LongGaugeAdviceConfigurer { - - /** Specify the recommended set of attribute keys to be used for this gauge. */ - LongGaugeAdviceConfigurer setAttributes(List> attributes); -} diff --git a/extensions/incubator/src/main/java/io/opentelemetry/extension/incubator/metrics/LongHistogramAdviceConfigurer.java b/extensions/incubator/src/main/java/io/opentelemetry/extension/incubator/metrics/LongHistogramAdviceConfigurer.java deleted file mode 100644 index 0c5fc91ad27..00000000000 --- a/extensions/incubator/src/main/java/io/opentelemetry/extension/incubator/metrics/LongHistogramAdviceConfigurer.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package io.opentelemetry.extension.incubator.metrics; - -import io.opentelemetry.api.common.AttributeKey; -import io.opentelemetry.api.metrics.LongHistogram; -import java.util.List; - -/** Configure advice for implementations of {@link LongHistogram}. */ -public interface LongHistogramAdviceConfigurer { - - /** Specify recommended set of explicit bucket boundaries for this histogram. */ - LongHistogramAdviceConfigurer setExplicitBucketBoundaries(List bucketBoundaries); - - /** Specify the recommended set of attribute keys to be used for this histogram. */ - LongHistogramAdviceConfigurer setAttributes(List> attributes); -} diff --git a/extensions/incubator/src/main/java/io/opentelemetry/extension/incubator/metrics/LongUpDownCounterAdviceConfigurer.java b/extensions/incubator/src/main/java/io/opentelemetry/extension/incubator/metrics/LongUpDownCounterAdviceConfigurer.java deleted file mode 100644 index 5090a824997..00000000000 --- a/extensions/incubator/src/main/java/io/opentelemetry/extension/incubator/metrics/LongUpDownCounterAdviceConfigurer.java +++ /dev/null @@ -1,17 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package io.opentelemetry.extension.incubator.metrics; - -import io.opentelemetry.api.common.AttributeKey; -import io.opentelemetry.api.metrics.LongUpDownCounter; -import java.util.List; - -/** Configure advice for implementation of {@link LongUpDownCounter}. */ -public interface LongUpDownCounterAdviceConfigurer { - - /** Specify the recommended set of attribute keys to be used for this up down counter. */ - LongUpDownCounterAdviceConfigurer setAttributes(List> attributes); -} diff --git a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkDoubleCounter.java b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkDoubleCounter.java index 04372eeb886..1b54f8a623d 100644 --- a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkDoubleCounter.java +++ b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkDoubleCounter.java @@ -8,11 +8,9 @@ import io.opentelemetry.api.common.AttributeKey; import io.opentelemetry.api.common.Attributes; import io.opentelemetry.api.metrics.DoubleCounter; -import io.opentelemetry.api.metrics.DoubleCounterBuilder; import io.opentelemetry.api.metrics.ObservableDoubleCounter; import io.opentelemetry.api.metrics.ObservableDoubleMeasurement; import io.opentelemetry.context.Context; -import io.opentelemetry.extension.incubator.metrics.DoubleCounterAdviceConfigurer; import io.opentelemetry.extension.incubator.metrics.ExtendedDoubleCounterBuilder; import io.opentelemetry.sdk.internal.ThrottlingLogger; import io.opentelemetry.sdk.metrics.internal.descriptor.Advice; @@ -61,7 +59,7 @@ public void add(double increment) { static final class SdkDoubleCounterBuilder extends AbstractInstrumentBuilder - implements ExtendedDoubleCounterBuilder, DoubleCounterAdviceConfigurer { + implements ExtendedDoubleCounterBuilder { SdkDoubleCounterBuilder( MeterProviderSharedState meterProviderSharedState, @@ -86,12 +84,6 @@ protected SdkDoubleCounterBuilder getThis() { return this; } - @Override - public DoubleCounterBuilder setAdvice(Consumer adviceConsumer) { - adviceConsumer.accept(this); - return this; - } - @Override public SdkDoubleCounter build() { return buildSynchronousInstrument(SdkDoubleCounter::new); @@ -109,7 +101,7 @@ public ObservableDoubleMeasurement buildObserver() { } @Override - public DoubleCounterAdviceConfigurer setAttributes(List> attributes) { + public ExtendedDoubleCounterBuilder setAttributesAdvice(List> attributes) { adviceBuilder.setAttributes(attributes); return this; } diff --git a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkDoubleGauge.java b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkDoubleGauge.java index a7456008da4..008745b2652 100644 --- a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkDoubleGauge.java +++ b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkDoubleGauge.java @@ -7,13 +7,11 @@ import io.opentelemetry.api.common.AttributeKey; import io.opentelemetry.api.common.Attributes; -import io.opentelemetry.api.metrics.DoubleGaugeBuilder; import io.opentelemetry.api.metrics.LongGaugeBuilder; import io.opentelemetry.api.metrics.ObservableDoubleGauge; import io.opentelemetry.api.metrics.ObservableDoubleMeasurement; import io.opentelemetry.context.Context; import io.opentelemetry.extension.incubator.metrics.DoubleGauge; -import io.opentelemetry.extension.incubator.metrics.DoubleGaugeAdviceConfigurer; import io.opentelemetry.extension.incubator.metrics.ExtendedDoubleGaugeBuilder; import io.opentelemetry.sdk.metrics.internal.descriptor.InstrumentDescriptor; import io.opentelemetry.sdk.metrics.internal.state.MeterProviderSharedState; @@ -42,7 +40,7 @@ public void set(double increment) { } static final class SdkDoubleGaugeBuilder extends AbstractInstrumentBuilder - implements ExtendedDoubleGaugeBuilder, DoubleGaugeAdviceConfigurer { + implements ExtendedDoubleGaugeBuilder { SdkDoubleGaugeBuilder( MeterProviderSharedState meterProviderSharedState, @@ -70,13 +68,7 @@ public SdkDoubleGauge build() { } @Override - public DoubleGaugeBuilder setAdvice(Consumer adviceConsumer) { - adviceConsumer.accept(this); - return this; - } - - @Override - public DoubleGaugeAdviceConfigurer setAttributes(List> attributes) { + public ExtendedDoubleGaugeBuilder setAttributesAdvice(List> attributes) { adviceBuilder.setAttributes(attributes); return this; } diff --git a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkDoubleHistogram.java b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkDoubleHistogram.java index e9b671a3d6e..c2e8d9b4126 100644 --- a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkDoubleHistogram.java +++ b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkDoubleHistogram.java @@ -10,7 +10,6 @@ import io.opentelemetry.api.metrics.DoubleHistogram; import io.opentelemetry.api.metrics.LongHistogramBuilder; import io.opentelemetry.context.Context; -import io.opentelemetry.extension.incubator.metrics.DoubleHistogramAdviceConfigurer; import io.opentelemetry.extension.incubator.metrics.ExtendedDoubleHistogramBuilder; import io.opentelemetry.sdk.internal.ThrottlingLogger; import io.opentelemetry.sdk.metrics.internal.descriptor.InstrumentDescriptor; @@ -18,7 +17,6 @@ import io.opentelemetry.sdk.metrics.internal.state.MeterSharedState; import io.opentelemetry.sdk.metrics.internal.state.WriteableMetricStorage; import java.util.List; -import java.util.function.Consumer; import java.util.logging.Level; import java.util.logging.Logger; @@ -58,7 +56,7 @@ public void record(double value) { static final class SdkDoubleHistogramBuilder extends AbstractInstrumentBuilder - implements ExtendedDoubleHistogramBuilder, DoubleHistogramAdviceConfigurer { + implements ExtendedDoubleHistogramBuilder { SdkDoubleHistogramBuilder( MeterProviderSharedState meterProviderSharedState, @@ -79,13 +77,6 @@ protected SdkDoubleHistogramBuilder getThis() { return this; } - @Override - public SdkDoubleHistogramBuilder setAdvice( - Consumer adviceConsumer) { - adviceConsumer.accept(this); - return this; - } - @Override public SdkDoubleHistogram build() { return buildSynchronousInstrument(SdkDoubleHistogram::new); @@ -97,14 +88,14 @@ public LongHistogramBuilder ofLongs() { } @Override - public DoubleHistogramAdviceConfigurer setExplicitBucketBoundaries( + public ExtendedDoubleHistogramBuilder setExplicitBucketBoundariesAdvice( List bucketBoundaries) { adviceBuilder.setExplicitBucketBoundaries(bucketBoundaries); return this; } @Override - public DoubleHistogramAdviceConfigurer setAttributes(List> attributes) { + public ExtendedDoubleHistogramBuilder setAttributesAdvice(List> attributes) { adviceBuilder.setAttributes(attributes); return this; } diff --git a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkDoubleUpDownCounter.java b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkDoubleUpDownCounter.java index 22a6b68b6e3..a11fd3f2f61 100644 --- a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkDoubleUpDownCounter.java +++ b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkDoubleUpDownCounter.java @@ -8,11 +8,9 @@ import io.opentelemetry.api.common.AttributeKey; import io.opentelemetry.api.common.Attributes; import io.opentelemetry.api.metrics.DoubleUpDownCounter; -import io.opentelemetry.api.metrics.DoubleUpDownCounterBuilder; import io.opentelemetry.api.metrics.ObservableDoubleMeasurement; import io.opentelemetry.api.metrics.ObservableDoubleUpDownCounter; import io.opentelemetry.context.Context; -import io.opentelemetry.extension.incubator.metrics.DoubleUpDownCounterAdviceConfigurer; import io.opentelemetry.extension.incubator.metrics.ExtendedDoubleUpDownCounterBuilder; import io.opentelemetry.sdk.metrics.internal.descriptor.Advice; import io.opentelemetry.sdk.metrics.internal.descriptor.InstrumentDescriptor; @@ -48,7 +46,7 @@ public void add(double increment) { static final class SdkDoubleUpDownCounterBuilder extends AbstractInstrumentBuilder - implements ExtendedDoubleUpDownCounterBuilder, DoubleUpDownCounterAdviceConfigurer { + implements ExtendedDoubleUpDownCounterBuilder { SdkDoubleUpDownCounterBuilder( MeterProviderSharedState meterProviderSharedState, @@ -73,13 +71,6 @@ protected SdkDoubleUpDownCounterBuilder getThis() { return this; } - @Override - public DoubleUpDownCounterBuilder setAdvice( - Consumer adviceConsumer) { - adviceConsumer.accept(this); - return this; - } - @Override public DoubleUpDownCounter build() { return buildSynchronousInstrument(SdkDoubleUpDownCounter::new); @@ -98,7 +89,8 @@ public ObservableDoubleMeasurement buildObserver() { } @Override - public DoubleUpDownCounterAdviceConfigurer setAttributes(List> attributes) { + public ExtendedDoubleUpDownCounterBuilder setAttributesAdvice( + List> attributes) { adviceBuilder.setAttributes(attributes); return this; } diff --git a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkLongCounter.java b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkLongCounter.java index dcdca53858a..58383d9e783 100644 --- a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkLongCounter.java +++ b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkLongCounter.java @@ -9,12 +9,10 @@ import io.opentelemetry.api.common.Attributes; import io.opentelemetry.api.metrics.DoubleCounterBuilder; import io.opentelemetry.api.metrics.LongCounter; -import io.opentelemetry.api.metrics.LongCounterBuilder; import io.opentelemetry.api.metrics.ObservableLongCounter; import io.opentelemetry.api.metrics.ObservableLongMeasurement; import io.opentelemetry.context.Context; import io.opentelemetry.extension.incubator.metrics.ExtendedLongCounterBuilder; -import io.opentelemetry.extension.incubator.metrics.LongCounterAdviceConfigurer; import io.opentelemetry.sdk.internal.ThrottlingLogger; import io.opentelemetry.sdk.metrics.internal.descriptor.InstrumentDescriptor; import io.opentelemetry.sdk.metrics.internal.state.MeterProviderSharedState; @@ -61,7 +59,7 @@ public void add(long increment) { } static final class SdkLongCounterBuilder extends AbstractInstrumentBuilder - implements ExtendedLongCounterBuilder, LongCounterAdviceConfigurer { + implements ExtendedLongCounterBuilder { SdkLongCounterBuilder( MeterProviderSharedState meterProviderSharedState, @@ -82,12 +80,6 @@ protected SdkLongCounterBuilder getThis() { return this; } - @Override - public LongCounterBuilder setAdvice(Consumer adviceConsumer) { - adviceConsumer.accept(this); - return this; - } - @Override public SdkLongCounter build() { return buildSynchronousInstrument(SdkLongCounter::new); @@ -109,7 +101,7 @@ public ObservableLongMeasurement buildObserver() { } @Override - public LongCounterAdviceConfigurer setAttributes(List> attributes) { + public ExtendedLongCounterBuilder setAttributesAdvice(List> attributes) { adviceBuilder.setAttributes(attributes); return this; } diff --git a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkLongGauge.java b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkLongGauge.java index 475f80bba1f..24e6be8e6a5 100644 --- a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkLongGauge.java +++ b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkLongGauge.java @@ -7,13 +7,11 @@ import io.opentelemetry.api.common.AttributeKey; import io.opentelemetry.api.common.Attributes; -import io.opentelemetry.api.metrics.LongGaugeBuilder; import io.opentelemetry.api.metrics.ObservableLongGauge; import io.opentelemetry.api.metrics.ObservableLongMeasurement; import io.opentelemetry.context.Context; import io.opentelemetry.extension.incubator.metrics.ExtendedLongGaugeBuilder; import io.opentelemetry.extension.incubator.metrics.LongGauge; -import io.opentelemetry.extension.incubator.metrics.LongGaugeAdviceConfigurer; import io.opentelemetry.sdk.metrics.internal.descriptor.Advice; import io.opentelemetry.sdk.metrics.internal.descriptor.InstrumentDescriptor; import io.opentelemetry.sdk.metrics.internal.state.MeterProviderSharedState; @@ -42,7 +40,7 @@ public void set(long increment) { } static final class SdkLongGaugeBuilder extends AbstractInstrumentBuilder - implements ExtendedLongGaugeBuilder, LongGaugeAdviceConfigurer { + implements ExtendedLongGaugeBuilder { SdkLongGaugeBuilder( MeterProviderSharedState meterProviderSharedState, @@ -74,13 +72,7 @@ public SdkLongGauge build() { } @Override - public LongGaugeBuilder setAdvice(Consumer adviceConsumer) { - adviceConsumer.accept(this); - return this; - } - - @Override - public LongGaugeAdviceConfigurer setAttributes(List> attributes) { + public ExtendedLongGaugeBuilder setAttributesAdvice(List> attributes) { adviceBuilder.setAttributes(attributes); return this; } diff --git a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkLongHistogram.java b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkLongHistogram.java index 5e0d33b6578..c087a0c282e 100644 --- a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkLongHistogram.java +++ b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkLongHistogram.java @@ -10,7 +10,6 @@ import io.opentelemetry.api.metrics.LongHistogram; import io.opentelemetry.context.Context; import io.opentelemetry.extension.incubator.metrics.ExtendedLongHistogramBuilder; -import io.opentelemetry.extension.incubator.metrics.LongHistogramAdviceConfigurer; import io.opentelemetry.sdk.internal.ThrottlingLogger; import io.opentelemetry.sdk.metrics.internal.descriptor.Advice; import io.opentelemetry.sdk.metrics.internal.descriptor.InstrumentDescriptor; @@ -18,7 +17,6 @@ import io.opentelemetry.sdk.metrics.internal.state.MeterSharedState; import io.opentelemetry.sdk.metrics.internal.state.WriteableMetricStorage; import java.util.List; -import java.util.function.Consumer; import java.util.logging.Level; import java.util.logging.Logger; import java.util.stream.Collectors; @@ -59,7 +57,7 @@ public void record(long value) { static final class SdkLongHistogramBuilder extends AbstractInstrumentBuilder - implements ExtendedLongHistogramBuilder, LongHistogramAdviceConfigurer { + implements ExtendedLongHistogramBuilder { SdkLongHistogramBuilder( MeterProviderSharedState meterProviderSharedState, @@ -84,20 +82,14 @@ protected SdkLongHistogramBuilder getThis() { return this; } - @Override - public SdkLongHistogramBuilder setAdvice( - Consumer adviceConsumer) { - adviceConsumer.accept(this); - return this; - } - @Override public SdkLongHistogram build() { return buildSynchronousInstrument(SdkLongHistogram::new); } @Override - public LongHistogramAdviceConfigurer setExplicitBucketBoundaries(List bucketBoundaries) { + public ExtendedLongHistogramBuilder setExplicitBucketBoundariesAdvice( + List bucketBoundaries) { List doubleBoundaries = bucketBoundaries.stream().map(Long::doubleValue).collect(Collectors.toList()); adviceBuilder.setExplicitBucketBoundaries(doubleBoundaries); @@ -105,7 +97,7 @@ public LongHistogramAdviceConfigurer setExplicitBucketBoundaries(List buck } @Override - public LongHistogramAdviceConfigurer setAttributes(List> attributes) { + public ExtendedLongHistogramBuilder setAttributesAdvice(List> attributes) { adviceBuilder.setAttributes(attributes); return this; } diff --git a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkLongUpDownCounter.java b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkLongUpDownCounter.java index 7c167acc28f..4351b28e5ce 100644 --- a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkLongUpDownCounter.java +++ b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkLongUpDownCounter.java @@ -9,12 +9,10 @@ import io.opentelemetry.api.common.Attributes; import io.opentelemetry.api.metrics.DoubleUpDownCounterBuilder; import io.opentelemetry.api.metrics.LongUpDownCounter; -import io.opentelemetry.api.metrics.LongUpDownCounterBuilder; import io.opentelemetry.api.metrics.ObservableLongMeasurement; import io.opentelemetry.api.metrics.ObservableLongUpDownCounter; import io.opentelemetry.context.Context; import io.opentelemetry.extension.incubator.metrics.ExtendedLongUpDownCounterBuilder; -import io.opentelemetry.extension.incubator.metrics.LongUpDownCounterAdviceConfigurer; import io.opentelemetry.sdk.metrics.internal.descriptor.InstrumentDescriptor; import io.opentelemetry.sdk.metrics.internal.state.MeterProviderSharedState; import io.opentelemetry.sdk.metrics.internal.state.MeterSharedState; @@ -48,7 +46,7 @@ public void add(long increment) { static final class SdkLongUpDownCounterBuilder extends AbstractInstrumentBuilder - implements ExtendedLongUpDownCounterBuilder, LongUpDownCounterAdviceConfigurer { + implements ExtendedLongUpDownCounterBuilder { SdkLongUpDownCounterBuilder( MeterProviderSharedState meterProviderSharedState, @@ -69,13 +67,6 @@ protected SdkLongUpDownCounterBuilder getThis() { return this; } - @Override - public LongUpDownCounterBuilder setAdvice( - Consumer adviceConsumer) { - adviceConsumer.accept(this); - return this; - } - @Override public LongUpDownCounter build() { return buildSynchronousInstrument(SdkLongUpDownCounter::new); @@ -99,7 +90,7 @@ public ObservableLongMeasurement buildObserver() { } @Override - public LongUpDownCounterAdviceConfigurer setAttributes(List> attributes) { + public ExtendedLongUpDownCounterBuilder setAttributesAdvice(List> attributes) { adviceBuilder.setAttributes(attributes); return this; } diff --git a/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/AttributesAdviceTest.java b/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/AttributesAdviceTest.java index efc1aff53f5..0e673021556 100644 --- a/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/AttributesAdviceTest.java +++ b/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/AttributesAdviceTest.java @@ -153,7 +153,7 @@ public Stream provideArguments(ExtensionContext context) { meterProvider.get("meter").counterBuilder(name).ofDoubles(); if (attributesAdvice != null) { ((ExtendedDoubleCounterBuilder) doubleCounterBuilder) - .setAdvice(advice -> advice.setAttributes(attributesAdvice)); + .setAttributesAdvice(attributesAdvice); } DoubleCounter counter = doubleCounterBuilder.build(); return counter::add; @@ -170,7 +170,7 @@ public Stream provideArguments(ExtensionContext context) { meterProvider.get("meter").counterBuilder(name); if (attributesAdvice != null) { ((ExtendedLongCounterBuilder) doubleCounterBuilder) - .setAdvice(advice -> advice.setAttributes(attributesAdvice)); + .setAttributesAdvice(attributesAdvice); } LongCounter counter = doubleCounterBuilder.build(); return counter::add; @@ -187,7 +187,7 @@ public Stream provideArguments(ExtensionContext context) { meterProvider.get("meter").gaugeBuilder(name); if (attributesAdvice != null) { ((ExtendedDoubleGaugeBuilder) doubleGaugeBuilder) - .setAdvice(advice -> advice.setAttributes(attributesAdvice)); + .setAttributesAdvice(attributesAdvice); } AtomicDouble valueRef = new AtomicDouble(); AtomicReference attributesRef = new AtomicReference<>(); @@ -211,7 +211,7 @@ public Stream provideArguments(ExtensionContext context) { meterProvider.get("meter").gaugeBuilder(name).ofLongs(); if (attributesAdvice != null) { ((ExtendedLongGaugeBuilder) doubleGaugeBuilder) - .setAdvice(advice -> advice.setAttributes(attributesAdvice)); + .setAttributesAdvice(attributesAdvice); } AtomicLong valueRef = new AtomicLong(); AtomicReference attributesRef = new AtomicReference<>(); @@ -235,7 +235,7 @@ public Stream provideArguments(ExtensionContext context) { meterProvider.get("meter").histogramBuilder(name); if (attributesAdvice != null) { ((ExtendedDoubleHistogramBuilder) doubleHistogramBuilder) - .setAdvice(advice -> advice.setAttributes(attributesAdvice)); + .setAttributesAdvice(attributesAdvice); } DoubleHistogram histogram = doubleHistogramBuilder.build(); return histogram::record; @@ -252,7 +252,7 @@ public Stream provideArguments(ExtensionContext context) { meterProvider.get("meter").histogramBuilder(name).ofLongs(); if (attributesAdvice != null) { ((ExtendedLongHistogramBuilder) doubleHistogramBuilder) - .setAdvice(advice -> advice.setAttributes(attributesAdvice)); + .setAttributesAdvice(attributesAdvice); } LongHistogram histogram = doubleHistogramBuilder.build(); return histogram::record; @@ -269,7 +269,7 @@ public Stream provideArguments(ExtensionContext context) { meterProvider.get("meter").upDownCounterBuilder(name).ofDoubles(); if (attributesAdvice != null) { ((ExtendedDoubleUpDownCounterBuilder) doubleUpDownCounterBuilder) - .setAdvice(advice -> advice.setAttributes(attributesAdvice)); + .setAttributesAdvice(attributesAdvice); } DoubleUpDownCounter upDownCounter = doubleUpDownCounterBuilder.build(); return upDownCounter::add; @@ -286,7 +286,7 @@ public Stream provideArguments(ExtensionContext context) { meterProvider.get("meter").upDownCounterBuilder(name); if (attributesAdvice != null) { ((ExtendedLongUpDownCounterBuilder) doubleUpDownCounterBuilder) - .setAdvice(advice -> advice.setAttributes(attributesAdvice)); + .setAttributesAdvice(attributesAdvice); } LongUpDownCounter upDownCounter = doubleUpDownCounterBuilder.build(); return upDownCounter::add; diff --git a/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/ExplicitBucketBoundariesAdviceTest.java b/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/ExplicitBucketBoundariesAdviceTest.java index e25eb098e9e..555f852df1d 100644 --- a/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/ExplicitBucketBoundariesAdviceTest.java +++ b/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/ExplicitBucketBoundariesAdviceTest.java @@ -179,10 +179,7 @@ private static Stream histogramsWithAdvice() { DoubleHistogram build = ((ExtendedDoubleHistogramBuilder) meterProvider.get("meter").histogramBuilder("histogram")) - .setAdvice( - advice -> - advice.setExplicitBucketBoundaries( - Arrays.asList(10.0, 20.0, 30.0))) + .setExplicitBucketBoundariesAdvice(Arrays.asList(10.0, 20.0, 30.0)) .build(); return build::record; }), @@ -192,9 +189,7 @@ private static Stream histogramsWithAdvice() { LongHistogram build = ((ExtendedLongHistogramBuilder) meterProvider.get("meter").histogramBuilder("histogram").ofLongs()) - .setAdvice( - advice -> - advice.setExplicitBucketBoundaries(Arrays.asList(10L, 20L, 30L))) + .setExplicitBucketBoundariesAdvice(Arrays.asList(10L, 20L, 30L)) .build(); return build::record; })); diff --git a/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/IdentityTest.java b/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/IdentityTest.java index 9982e2e439b..7332e3d0dba 100644 --- a/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/IdentityTest.java +++ b/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/IdentityTest.java @@ -223,13 +223,13 @@ void sameMeterSameInstrumentNameDifferentNonIdentifyingFieldsNoViews() { // Register histogram1, with and without advice. First registration without advice wins. meterProvider.get("meter1").histogramBuilder("histogram1").build().record(8); ((ExtendedDoubleHistogramBuilder) meterProvider.get("meter1").histogramBuilder("histogram1")) - .setAdvice(advice -> advice.setExplicitBucketBoundaries(Arrays.asList(10.0, 20.0, 30.0))) + .setExplicitBucketBoundariesAdvice(Arrays.asList(10.0, 20.0, 30.0)) .build() .record(8); // Register histogram2, with and without advice. First registration with advice wins. ((ExtendedDoubleHistogramBuilder) meterProvider.get("meter1").histogramBuilder("histogram2")) - .setAdvice(advice -> advice.setExplicitBucketBoundaries(Arrays.asList(10.0, 20.0, 30.0))) + .setExplicitBucketBoundariesAdvice(Arrays.asList(10.0, 20.0, 30.0)) .build() .record(8); meterProvider.get("meter1").histogramBuilder("histogram2").build().record(8); From bf37a4ca58c1969756848f48f97a36015efa0b47 Mon Sep 17 00:00:00 2001 From: jack-berg <34418638+jack-berg@users.noreply.github.com> Date: Fri, 6 Oct 2023 15:10:48 -0500 Subject: [PATCH 043/901] Prepare 1.31.0 (#5888) --- CHANGELOG.md | 60 ++++++++++++++++++- .../sdk/common/export/MemoryMode.java | 6 +- .../export/CollectionRegistration.java | 11 ++-- 3 files changed, 68 insertions(+), 9 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4ba8f3c1469..27ea1aa4891 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,13 +2,69 @@ ## Unreleased -* Update `queueSize` metric description and attribute name for `processorType` +### API + +#### Incubator + +* Refactor advice API to simplify usage + ([#5848](https://github.com/open-telemetry/opentelemetry-java/pull/5848)) + +### SDK + +* BatchLogRecordProcessor and BatchSpanProcessor unify `queueSize` metric + description and attribute name for `processorType` ([#5836](https://github.com/open-telemetry/opentelemetry-java/pull/5836)) +#### Metrics + +* Allow instrument names to contain a forward slash + ([#5824](https://github.com/open-telemetry/opentelemetry-java/pull/5824)) +* Memory Mode support: Adding memory mode, and implementing it for Asynchronous Instruments + ([#5709](https://github.com/open-telemetry/opentelemetry-java/pull/5709), + [#5855](https://github.com/open-telemetry/opentelemetry-java/pull/5855)) +* Stabilize MetricProducer, allow custom MetricReaders + ([#5835](https://github.com/open-telemetry/opentelemetry-java/pull/5835)) +* Drop NaN measurements to metric instruments + ([#5859](https://github.com/open-telemetry/opentelemetry-java/pull/5859)) +* Fix flaky MetricExporterConfigurationTest + ([#5877](https://github.com/open-telemetry/opentelemetry-java/pull/5877)) + +#### Logs + +* Add addAllAttributes() to ReadWriteLogRecord. + ([#5825](https://github.com/open-telemetry/opentelemetry-java/pull/5825)) + +#### Exporters + +* Prometheus exporter: handle colliding metric attribute keys + ([#5717](https://github.com/open-telemetry/opentelemetry-java/pull/5717)) + +#### SDK Extensions + +* File configuration ConfigurationReader handles null values as empty + ([#5829](https://github.com/open-telemetry/opentelemetry-java/pull/5829)) + +#### Semantic conventions + +* BREAKING: Stop publishing `io.opentelemetry:opentelemetry-semconv`. Please use + `io.opentelemetry.semconv:opentelemetry-semconv:1.21.0-alpha` instead, which is published + from [open-telemetry/semantic-conventions-java](https://github.com/open-telemetry/semantic-conventions-java). + The new repository is published in lockstep + with [open-telemetry/semantic-conventions](https://github.com/open-telemetry/semantic-conventions). + ([#5807](https://github.com/open-telemetry/opentelemetry-java/pull/5807)) + +### Project Tooling + +* Add Benchmark workflows + ([#5842](https://github.com/open-telemetry/opentelemetry-java/pull/5842), + [#5874](https://github.com/open-telemetry/opentelemetry-java/pull/5874)) +* Add clearer docs around coroutine support with an example + ([#5799](https://github.com/open-telemetry/opentelemetry-java/pull/5799)) + ## Version 1.30.1 (2023-09-11) * Fix autoconfigure bug creating multiple `PrometheusHttpServer` instances with same port - ([#5911](https://github.com/open-telemetry/opentelemetry-java/pull/5811)) + ([#5811](https://github.com/open-telemetry/opentelemetry-java/pull/5811)) ## Version 1.30.0 (2023-09-08) diff --git a/sdk/common/src/main/java/io/opentelemetry/sdk/common/export/MemoryMode.java b/sdk/common/src/main/java/io/opentelemetry/sdk/common/export/MemoryMode.java index 24c87d13de6..5cd9fea40f8 100644 --- a/sdk/common/src/main/java/io/opentelemetry/sdk/common/export/MemoryMode.java +++ b/sdk/common/src/main/java/io/opentelemetry/sdk/common/export/MemoryMode.java @@ -5,7 +5,11 @@ package io.opentelemetry.sdk.common.export; -/** The memory semantics of the SDK. */ +/** + * The memory semantics of the SDK. + * + * @since 1.31.0 + */ public enum MemoryMode { /** diff --git a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/export/CollectionRegistration.java b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/export/CollectionRegistration.java index c8511700cb4..fbe117aecba 100644 --- a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/export/CollectionRegistration.java +++ b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/export/CollectionRegistration.java @@ -22,14 +22,11 @@ public interface CollectionRegistration { /** * Returns a noop {@link CollectionRegistration}, useful for {@link MetricReader}s to hold before * {@link MetricReader#register(CollectionRegistration)} is called. + * + * @since 1.31.0 */ static CollectionRegistration noop() { - return new CollectionRegistration() { - @Override - public Collection collectAllMetrics() { - return Collections.emptyList(); - } - }; + return new CollectionRegistration() {}; } /** @@ -38,6 +35,8 @@ public Collection collectAllMetrics() { *

    If {@link MetricReader#getMemoryMode()} is configured to {@link MemoryMode#REUSABLE_DATA} do * not keep the result or any of its contained objects as they are to be reused to return the * result for the next call to this method. + * + * @since 1.31.0 */ default Collection collectAllMetrics() { return Collections.emptyList(); From 905184fb95e3a34f97ec39a6abfd1f19505cf35c Mon Sep 17 00:00:00 2001 From: OpenTelemetry Bot <107717825+opentelemetrybot@users.noreply.github.com> Date: Fri, 6 Oct 2023 22:51:00 +0200 Subject: [PATCH 044/901] Update version to 1.32.0 (#5890) --- CHANGELOG.md | 2 ++ version.gradle.kts | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 27ea1aa4891..5d9004b6e62 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,8 @@ ## Unreleased +## Version 1.31.0 (2023-10-06) + ### API #### Incubator diff --git a/version.gradle.kts b/version.gradle.kts index c7554cc8708..6778cc99912 100644 --- a/version.gradle.kts +++ b/version.gradle.kts @@ -1,7 +1,7 @@ val snapshot = true allprojects { - var ver = "1.31.0" + var ver = "1.32.0" val release = findProperty("otel.release") if (release != null) { ver += "-" + release From 3c0bf72a5ebd66d45933d5886cfd0e444acae410 Mon Sep 17 00:00:00 2001 From: jack-berg <34418638+jack-berg@users.noreply.github.com> Date: Mon, 9 Oct 2023 09:24:11 -0500 Subject: [PATCH 045/901] Post release 1.31.0 (#5892) --- README.md | 76 +++++++++---------- .../1.31.0_vs_1.30.1/opentelemetry-api.txt | 2 + .../opentelemetry-context.txt | 2 + .../opentelemetry-exporter-common.txt | 2 + .../opentelemetry-exporter-jaeger-thrift.txt | 2 + .../opentelemetry-exporter-jaeger.txt | 2 + .../opentelemetry-exporter-logging-otlp.txt | 2 + .../opentelemetry-exporter-logging.txt | 2 + .../opentelemetry-exporter-otlp-common.txt | 2 + .../opentelemetry-exporter-otlp.txt | 2 + ...y-exporter-sender-grpc-managed-channel.txt | 2 + .../opentelemetry-exporter-sender-okhttp.txt | 2 + .../opentelemetry-exporter-zipkin.txt | 2 + .../opentelemetry-extension-kotlin.txt | 2 + ...ntelemetry-extension-trace-propagators.txt | 2 + .../opentelemetry-opentracing-shim.txt | 2 + .../opentelemetry-sdk-common.txt | 11 +++ ...emetry-sdk-extension-autoconfigure-spi.txt | 2 + ...ntelemetry-sdk-extension-autoconfigure.txt | 2 + ...ry-sdk-extension-jaeger-remote-sampler.txt | 2 + .../opentelemetry-sdk-logs.txt | 4 + .../opentelemetry-sdk-metrics.txt | 21 +++++ .../opentelemetry-sdk-testing.txt | 12 +++ .../opentelemetry-sdk-trace.txt | 2 + .../1.31.0_vs_1.30.1/opentelemetry-sdk.txt | 2 + .../opentelemetry-sdk-common.txt | 11 +-- .../opentelemetry-sdk-logs.txt | 4 +- .../opentelemetry-sdk-metrics.txt | 21 +---- .../opentelemetry-sdk-testing.txt | 12 +-- 29 files changed, 130 insertions(+), 82 deletions(-) create mode 100644 docs/apidiffs/1.31.0_vs_1.30.1/opentelemetry-api.txt create mode 100644 docs/apidiffs/1.31.0_vs_1.30.1/opentelemetry-context.txt create mode 100644 docs/apidiffs/1.31.0_vs_1.30.1/opentelemetry-exporter-common.txt create mode 100644 docs/apidiffs/1.31.0_vs_1.30.1/opentelemetry-exporter-jaeger-thrift.txt create mode 100644 docs/apidiffs/1.31.0_vs_1.30.1/opentelemetry-exporter-jaeger.txt create mode 100644 docs/apidiffs/1.31.0_vs_1.30.1/opentelemetry-exporter-logging-otlp.txt create mode 100644 docs/apidiffs/1.31.0_vs_1.30.1/opentelemetry-exporter-logging.txt create mode 100644 docs/apidiffs/1.31.0_vs_1.30.1/opentelemetry-exporter-otlp-common.txt create mode 100644 docs/apidiffs/1.31.0_vs_1.30.1/opentelemetry-exporter-otlp.txt create mode 100644 docs/apidiffs/1.31.0_vs_1.30.1/opentelemetry-exporter-sender-grpc-managed-channel.txt create mode 100644 docs/apidiffs/1.31.0_vs_1.30.1/opentelemetry-exporter-sender-okhttp.txt create mode 100644 docs/apidiffs/1.31.0_vs_1.30.1/opentelemetry-exporter-zipkin.txt create mode 100644 docs/apidiffs/1.31.0_vs_1.30.1/opentelemetry-extension-kotlin.txt create mode 100644 docs/apidiffs/1.31.0_vs_1.30.1/opentelemetry-extension-trace-propagators.txt create mode 100644 docs/apidiffs/1.31.0_vs_1.30.1/opentelemetry-opentracing-shim.txt create mode 100644 docs/apidiffs/1.31.0_vs_1.30.1/opentelemetry-sdk-common.txt create mode 100644 docs/apidiffs/1.31.0_vs_1.30.1/opentelemetry-sdk-extension-autoconfigure-spi.txt create mode 100644 docs/apidiffs/1.31.0_vs_1.30.1/opentelemetry-sdk-extension-autoconfigure.txt create mode 100644 docs/apidiffs/1.31.0_vs_1.30.1/opentelemetry-sdk-extension-jaeger-remote-sampler.txt create mode 100644 docs/apidiffs/1.31.0_vs_1.30.1/opentelemetry-sdk-logs.txt create mode 100644 docs/apidiffs/1.31.0_vs_1.30.1/opentelemetry-sdk-metrics.txt create mode 100644 docs/apidiffs/1.31.0_vs_1.30.1/opentelemetry-sdk-testing.txt create mode 100644 docs/apidiffs/1.31.0_vs_1.30.1/opentelemetry-sdk-trace.txt create mode 100644 docs/apidiffs/1.31.0_vs_1.30.1/opentelemetry-sdk.txt diff --git a/README.md b/README.md index afd156596d8..7a1efa3374f 100644 --- a/README.md +++ b/README.md @@ -94,7 +94,7 @@ dependency versions in sync. io.opentelemetry opentelemetry-bom - 1.30.1 + 1.31.0 pom import @@ -113,7 +113,7 @@ dependency versions in sync. ```groovy dependencies { - implementation platform("io.opentelemetry:opentelemetry-bom:1.30.1") + implementation platform("io.opentelemetry:opentelemetry-bom:1.31.0") implementation('io.opentelemetry:opentelemetry-api') } ``` @@ -122,8 +122,8 @@ Note that if you want to use any artifacts that have not fully stabilized yet (s ```groovy dependencies { - implementation platform("io.opentelemetry:opentelemetry-bom:1.30.1") - implementation platform('io.opentelemetry:opentelemetry-bom-alpha:1.30.1-alpha') + implementation platform("io.opentelemetry:opentelemetry-bom:1.31.0") + implementation platform('io.opentelemetry:opentelemetry-bom-alpha:1.31.0-alpha') implementation('io.opentelemetry:opentelemetry-api') implementation('io.opentelemetry:opentelemetry-exporter-prometheus') @@ -151,7 +151,7 @@ We strongly recommend using our published BOM to keep all dependency versions in io.opentelemetry opentelemetry-bom - 1.31.0-SNAPSHOT + 1.32.0-SNAPSHOT pom import @@ -174,7 +174,7 @@ repositories { } dependencies { - implementation platform("io.opentelemetry:opentelemetry-bom:1.31.0-SNAPSHOT") + implementation platform("io.opentelemetry:opentelemetry-bom:1.32.0-SNAPSHOT") implementation('io.opentelemetry:opentelemetry-api') } ``` @@ -219,53 +219,53 @@ dependency as follows, replacing `{{artifact-id}}` with the value from the "Arti | Component | Description | Artifact ID | Version | Javadoc | |----------------------------------------------|----------------------------------------|---------------------------|-------------------------------------------------------------|---------| -| [Bill of Materials (BOM)](./bom) | Bill of materials for stable artifacts | `opentelemetry-bom` | 1.30.1 | N/A | -| [Alpha Bill of Materials (BOM)](./bom-alpha) | Bill of materials for alpha artifacts | `opentelemetry-bom-alpha` | 1.30.1-alpha | N/A | +| [Bill of Materials (BOM)](./bom) | Bill of materials for stable artifacts | `opentelemetry-bom` | 1.31.0 | N/A | +| [Alpha Bill of Materials (BOM)](./bom-alpha) | Bill of materials for alpha artifacts | `opentelemetry-bom-alpha` | 1.31.0-alpha | N/A | ### API | Component | Description | Artifact ID | Version | Javadoc | |-----------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|----------------------------|-------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------| -| [API](./api/all) | OpenTelemetry API, including metrics, traces, baggage, context | `opentelemetry-api` | 1.30.1 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-api.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-api) | -| [Events API](./api/events) | OpenTelemetry Event API for emitting events. | `opentelemetry-api-events` | 1.30.1-alpha | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-api-events.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-api-events) | -| [Context API](./context) | OpenTelemetry context API | `opentelemetry-context` | 1.30.1 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-context.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-context) | +| [API](./api/all) | OpenTelemetry API, including metrics, traces, baggage, context | `opentelemetry-api` | 1.31.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-api.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-api) | +| [Events API](./api/events) | OpenTelemetry Event API for emitting events. | `opentelemetry-api-events` | 1.31.0-alpha | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-api-events.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-api-events) | +| [Context API](./context) | OpenTelemetry context API | `opentelemetry-context` | 1.31.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-context.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-context) | ### API Extensions | Component | Description | Artifact ID | Version | Javadoc | |---------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|---------------------------------------------|-------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| [Kotlin Extension](./extensions/kotlin) | Context extension for coroutines | `opentelemetry-extension-kotlin` | 1.30.1 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-extension-kotlin.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-extension-kotlin) | -| [Trace Propagators Extension](./extensions/trace-propagators) | Trace propagators, including B3, Jaeger, OT Trace | `opentelemetry-extension-trace-propagators` | 1.30.1 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-extension-trace-propagators.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-extension-trace-propagators) | -| [Incubator Extension](./extensions/incubator) | API incubator, including pass through propagator, and extended tracer | `opentelemetry-extension-incubator` | 1.30.1-alpha | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-extension-incubator.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-extension-incubator) | +| [Kotlin Extension](./extensions/kotlin) | Context extension for coroutines | `opentelemetry-extension-kotlin` | 1.31.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-extension-kotlin.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-extension-kotlin) | +| [Trace Propagators Extension](./extensions/trace-propagators) | Trace propagators, including B3, Jaeger, OT Trace | `opentelemetry-extension-trace-propagators` | 1.31.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-extension-trace-propagators.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-extension-trace-propagators) | +| [Incubator Extension](./extensions/incubator) | API incubator, including pass through propagator, and extended tracer | `opentelemetry-extension-incubator` | 1.31.0-alpha | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-extension-incubator.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-extension-incubator) | ### SDK | Component | Description | Artifact ID | Version | Javadoc | |------------------------------|--------------------------------------------------------|-----------------------------|---------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| [SDK](./sdk/all) | OpenTelemetry SDK, including metrics, traces, and logs | `opentelemetry-sdk` | 1.30.1 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk) | -| [Metrics SDK](./sdk/metrics) | OpenTelemetry metrics SDK | `opentelemetry-sdk-metrics` | 1.30.1 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-metrics.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-metrics) | -| [Trace SDK](./sdk/trace) | OpenTelemetry trace SDK | `opentelemetry-sdk-trace` | 1.30.1 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-trace.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-trace) | -| [Log SDK](./sdk/logs) | OpenTelemetry log SDK | `opentelemetry-sdk-logs` | 1.30.1 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-logs.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-logs) | -| [SDK Common](./sdk/common) | Shared SDK components | `opentelemetry-sdk-common` | 1.30.1 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-common.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-common) | -| [SDK Testing](./sdk/testing) | Components for testing OpenTelemetry instrumentation | `opentelemetry-sdk-testing` | 1.30.1 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-testing.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-testing) | +| [SDK](./sdk/all) | OpenTelemetry SDK, including metrics, traces, and logs | `opentelemetry-sdk` | 1.31.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk) | +| [Metrics SDK](./sdk/metrics) | OpenTelemetry metrics SDK | `opentelemetry-sdk-metrics` | 1.31.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-metrics.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-metrics) | +| [Trace SDK](./sdk/trace) | OpenTelemetry trace SDK | `opentelemetry-sdk-trace` | 1.31.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-trace.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-trace) | +| [Log SDK](./sdk/logs) | OpenTelemetry log SDK | `opentelemetry-sdk-logs` | 1.31.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-logs.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-logs) | +| [SDK Common](./sdk/common) | Shared SDK components | `opentelemetry-sdk-common` | 1.31.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-common.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-common) | +| [SDK Testing](./sdk/testing) | Components for testing OpenTelemetry instrumentation | `opentelemetry-sdk-testing` | 1.31.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-testing.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-testing) | ### SDK Exporters | Component | Description | Artifact ID | Version | Javadoc | |-----------------------------------------------------------------------|------------------------------------------------------------------------------|------------------------------------------------------|-------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| [OTLP Exporters](./exporters/otlp/all) | OTLP gRPC & HTTP exporters, including traces, metrics, and logs | `opentelemetry-exporter-otlp` | 1.30.1 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-otlp.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-otlp) | -| [OTLP Logging Exporters](./exporters/logging-otlp) | Logging exporters in OTLP JSON encoding, including traces, metrics, and logs | `opentelemetry-exporter-logging-otlp` | 1.30.1 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-logging-otlp.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-logging-otlp) | -| [OTLP Common](./exporters/otlp/common) | Shared OTLP components (internal) | `opentelemetry-exporter-otlp-common` | 1.30.1 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-otlp-common.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-otlp-common) | -| [Jaeger gRPC Exporter](./exporters/jaeger) | Jaeger gRPC trace exporter (deprecated [1]) | `opentelemetry-exporter-jaeger` | 1.30.1 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-jaeger.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-jaeger) | -| [Jaeger Thrift Exporter](./exporters/jaeger-thrift) | Jaeger thrift trace exporter (deprecated [1]) | `opentelemetry-exporter-jaeger-thift` | 1.30.1 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-jaeger-thrift.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-jaeger-thrift) | -| [Logging Exporter](./exporters/logging) | Logging exporters, including metrics, traces, and logs | `opentelemetry-exporter-logging` | 1.30.1 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-logging.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-logging) | -| [Zipkin Exporter](./exporters/zipkin) | Zipkin trace exporter | `opentelemetry-exporter-zipkin` | 1.30.1 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-zipkin.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-zipkin) | -| [Prometheus Exporter](./exporters/prometheus) | Prometheus metric exporter | `opentelemetry-exporter-prometheus` | 1.30.1-alpha | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-prometheus.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-prometheus) | -| [Exporter Common](./exporters/common) | Shared exporter components (internal) | `opentelemetry-exporter-common` | 1.30.1 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-common.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-common) | -| [OkHttp Sender](./exporters/sender/okhttp) | OkHttp implementation of HttpSender (internal) | `opentelemetry-exporter-sender-okhttp` | 1.30.1 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-sender-okhttp.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-sender-okhttp) | -| [JDK Sender](./exporters/sender/okhttp) | Java 11+ native HttpClient implementation of HttpSender (internal) | `opentelemetry-exporter-sender-jdk` | 1.30.1-alpha | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-sender-jdk.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-sender-jdk) | | -| [gRPC ManagedChannel Sender](./exporters/sender/grpc-managed-channel) | gRPC ManagedChannel implementation of GrpcSender (internal) | `opentelemetry-exporter-sender-grpc-managed-channel` | 1.30.1 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-sender-grpc-managed-channel.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-sender-grpc-managed-channel) | | +| [OTLP Exporters](./exporters/otlp/all) | OTLP gRPC & HTTP exporters, including traces, metrics, and logs | `opentelemetry-exporter-otlp` | 1.31.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-otlp.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-otlp) | +| [OTLP Logging Exporters](./exporters/logging-otlp) | Logging exporters in OTLP JSON encoding, including traces, metrics, and logs | `opentelemetry-exporter-logging-otlp` | 1.31.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-logging-otlp.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-logging-otlp) | +| [OTLP Common](./exporters/otlp/common) | Shared OTLP components (internal) | `opentelemetry-exporter-otlp-common` | 1.31.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-otlp-common.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-otlp-common) | +| [Jaeger gRPC Exporter](./exporters/jaeger) | Jaeger gRPC trace exporter (deprecated [1]) | `opentelemetry-exporter-jaeger` | 1.31.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-jaeger.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-jaeger) | +| [Jaeger Thrift Exporter](./exporters/jaeger-thrift) | Jaeger thrift trace exporter (deprecated [1]) | `opentelemetry-exporter-jaeger-thift` | 1.31.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-jaeger-thrift.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-jaeger-thrift) | +| [Logging Exporter](./exporters/logging) | Logging exporters, including metrics, traces, and logs | `opentelemetry-exporter-logging` | 1.31.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-logging.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-logging) | +| [Zipkin Exporter](./exporters/zipkin) | Zipkin trace exporter | `opentelemetry-exporter-zipkin` | 1.31.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-zipkin.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-zipkin) | +| [Prometheus Exporter](./exporters/prometheus) | Prometheus metric exporter | `opentelemetry-exporter-prometheus` | 1.31.0-alpha | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-prometheus.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-prometheus) | +| [Exporter Common](./exporters/common) | Shared exporter components (internal) | `opentelemetry-exporter-common` | 1.31.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-common.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-common) | +| [OkHttp Sender](./exporters/sender/okhttp) | OkHttp implementation of HttpSender (internal) | `opentelemetry-exporter-sender-okhttp` | 1.31.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-sender-okhttp.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-sender-okhttp) | +| [JDK Sender](./exporters/sender/okhttp) | Java 11+ native HttpClient implementation of HttpSender (internal) | `opentelemetry-exporter-sender-jdk` | 1.31.0-alpha | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-sender-jdk.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-sender-jdk) | | +| [gRPC ManagedChannel Sender](./exporters/sender/grpc-managed-channel) | gRPC ManagedChannel implementation of GrpcSender (internal) | `opentelemetry-exporter-sender-grpc-managed-channel` | 1.31.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-sender-grpc-managed-channel.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-sender-grpc-managed-channel) | | **[1]**: Jaeger now has [native support for OTLP](https://opentelemetry.io/blog/2022/jaeger-native-otlp/) and jaeger @@ -278,17 +278,17 @@ additional versions will be published. | Component | Description | Artifact ID | Version | Javadoc | |-------------------------------------------------------------------------------|------------------------------------------------------------------------------------|-----------------------------------------------------|-------------------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| [SDK Autoconfigure](./sdk-extensions/autoconfigure) | Autoconfigure OpenTelemetry SDK from env vars, system properties, and SPI | `opentelemetry-sdk-extension-autoconfigure` | 1.30.1 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-extension-autoconfigure.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-extension-autoconfigure) | -| [SDK Autoconfigure SPI](./sdk-extensions/autoconfigure-spi) | Service Provider Interface (SPI) definitions for autoconfigure | `opentelemetry-sdk-extension-autoconfigure-spi` | 1.30.1 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-extension-autoconfigure-spi.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-extension-autoconfigure-spi) | -| [SDK Jaeger Remote Sampler Extension](./sdk-extensions/jaeger-remote-sampler) | Sampler which obtains sampling configuration from remote Jaeger server | `opentelemetry-sdk-extension-jaeger-remote-sampler` | 1.30.1 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-extension-jaeger-remote-sampler.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-extension-jaeger-remote-sampler) | -| [SDK Incubator](./sdk-extensions/incubator) | SDK incubator, including YAML based view configuration, LeakDetectingSpanProcessor | `opentelemetry-sdk-extension-incubator` | 1.30.1-alpha | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-extension-incubator.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-extension-incubator) | +| [SDK Autoconfigure](./sdk-extensions/autoconfigure) | Autoconfigure OpenTelemetry SDK from env vars, system properties, and SPI | `opentelemetry-sdk-extension-autoconfigure` | 1.31.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-extension-autoconfigure.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-extension-autoconfigure) | +| [SDK Autoconfigure SPI](./sdk-extensions/autoconfigure-spi) | Service Provider Interface (SPI) definitions for autoconfigure | `opentelemetry-sdk-extension-autoconfigure-spi` | 1.31.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-extension-autoconfigure-spi.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-extension-autoconfigure-spi) | +| [SDK Jaeger Remote Sampler Extension](./sdk-extensions/jaeger-remote-sampler) | Sampler which obtains sampling configuration from remote Jaeger server | `opentelemetry-sdk-extension-jaeger-remote-sampler` | 1.31.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-extension-jaeger-remote-sampler.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-extension-jaeger-remote-sampler) | +| [SDK Incubator](./sdk-extensions/incubator) | SDK incubator, including YAML based view configuration, LeakDetectingSpanProcessor | `opentelemetry-sdk-extension-incubator` | 1.31.0-alpha | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-extension-incubator.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-extension-incubator) | ### Shims | Component | Description | Artifact ID | Version | Javadoc | |----------------------------------------|--------------------------------------------------------------|----------------------------------|-------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| [OpenCensus Shim](./opencensus-shim) | Bridge opencensus metrics into the OpenTelemetry metrics SDK | `opentelemetry-opencensus-shim` | 1.30.1-alpha | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-opencensus-shim.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-opencensus-shim) | -| [OpenTracing Shim](./opentracing-shim) | Bridge opentracing spans into the OpenTelemetry trace API | `opentelemetry-opentracing-shim` | 1.30.1 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-opentracing-shim.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-opentracing-shim) | +| [OpenCensus Shim](./opencensus-shim) | Bridge opencensus metrics into the OpenTelemetry metrics SDK | `opentelemetry-opencensus-shim` | 1.31.0-alpha | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-opencensus-shim.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-opencensus-shim) | +| [OpenTracing Shim](./opentracing-shim) | Bridge opentracing spans into the OpenTelemetry trace API | `opentelemetry-opentracing-shim` | 1.31.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-opentracing-shim.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-opentracing-shim) | ## Contributing diff --git a/docs/apidiffs/1.31.0_vs_1.30.1/opentelemetry-api.txt b/docs/apidiffs/1.31.0_vs_1.30.1/opentelemetry-api.txt new file mode 100644 index 00000000000..df26146497b --- /dev/null +++ b/docs/apidiffs/1.31.0_vs_1.30.1/opentelemetry-api.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of against +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.31.0_vs_1.30.1/opentelemetry-context.txt b/docs/apidiffs/1.31.0_vs_1.30.1/opentelemetry-context.txt new file mode 100644 index 00000000000..df26146497b --- /dev/null +++ b/docs/apidiffs/1.31.0_vs_1.30.1/opentelemetry-context.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of against +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.31.0_vs_1.30.1/opentelemetry-exporter-common.txt b/docs/apidiffs/1.31.0_vs_1.30.1/opentelemetry-exporter-common.txt new file mode 100644 index 00000000000..df26146497b --- /dev/null +++ b/docs/apidiffs/1.31.0_vs_1.30.1/opentelemetry-exporter-common.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of against +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.31.0_vs_1.30.1/opentelemetry-exporter-jaeger-thrift.txt b/docs/apidiffs/1.31.0_vs_1.30.1/opentelemetry-exporter-jaeger-thrift.txt new file mode 100644 index 00000000000..df26146497b --- /dev/null +++ b/docs/apidiffs/1.31.0_vs_1.30.1/opentelemetry-exporter-jaeger-thrift.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of against +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.31.0_vs_1.30.1/opentelemetry-exporter-jaeger.txt b/docs/apidiffs/1.31.0_vs_1.30.1/opentelemetry-exporter-jaeger.txt new file mode 100644 index 00000000000..df26146497b --- /dev/null +++ b/docs/apidiffs/1.31.0_vs_1.30.1/opentelemetry-exporter-jaeger.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of against +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.31.0_vs_1.30.1/opentelemetry-exporter-logging-otlp.txt b/docs/apidiffs/1.31.0_vs_1.30.1/opentelemetry-exporter-logging-otlp.txt new file mode 100644 index 00000000000..df26146497b --- /dev/null +++ b/docs/apidiffs/1.31.0_vs_1.30.1/opentelemetry-exporter-logging-otlp.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of against +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.31.0_vs_1.30.1/opentelemetry-exporter-logging.txt b/docs/apidiffs/1.31.0_vs_1.30.1/opentelemetry-exporter-logging.txt new file mode 100644 index 00000000000..df26146497b --- /dev/null +++ b/docs/apidiffs/1.31.0_vs_1.30.1/opentelemetry-exporter-logging.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of against +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.31.0_vs_1.30.1/opentelemetry-exporter-otlp-common.txt b/docs/apidiffs/1.31.0_vs_1.30.1/opentelemetry-exporter-otlp-common.txt new file mode 100644 index 00000000000..df26146497b --- /dev/null +++ b/docs/apidiffs/1.31.0_vs_1.30.1/opentelemetry-exporter-otlp-common.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of against +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.31.0_vs_1.30.1/opentelemetry-exporter-otlp.txt b/docs/apidiffs/1.31.0_vs_1.30.1/opentelemetry-exporter-otlp.txt new file mode 100644 index 00000000000..df26146497b --- /dev/null +++ b/docs/apidiffs/1.31.0_vs_1.30.1/opentelemetry-exporter-otlp.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of against +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.31.0_vs_1.30.1/opentelemetry-exporter-sender-grpc-managed-channel.txt b/docs/apidiffs/1.31.0_vs_1.30.1/opentelemetry-exporter-sender-grpc-managed-channel.txt new file mode 100644 index 00000000000..df26146497b --- /dev/null +++ b/docs/apidiffs/1.31.0_vs_1.30.1/opentelemetry-exporter-sender-grpc-managed-channel.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of against +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.31.0_vs_1.30.1/opentelemetry-exporter-sender-okhttp.txt b/docs/apidiffs/1.31.0_vs_1.30.1/opentelemetry-exporter-sender-okhttp.txt new file mode 100644 index 00000000000..df26146497b --- /dev/null +++ b/docs/apidiffs/1.31.0_vs_1.30.1/opentelemetry-exporter-sender-okhttp.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of against +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.31.0_vs_1.30.1/opentelemetry-exporter-zipkin.txt b/docs/apidiffs/1.31.0_vs_1.30.1/opentelemetry-exporter-zipkin.txt new file mode 100644 index 00000000000..df26146497b --- /dev/null +++ b/docs/apidiffs/1.31.0_vs_1.30.1/opentelemetry-exporter-zipkin.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of against +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.31.0_vs_1.30.1/opentelemetry-extension-kotlin.txt b/docs/apidiffs/1.31.0_vs_1.30.1/opentelemetry-extension-kotlin.txt new file mode 100644 index 00000000000..df26146497b --- /dev/null +++ b/docs/apidiffs/1.31.0_vs_1.30.1/opentelemetry-extension-kotlin.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of against +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.31.0_vs_1.30.1/opentelemetry-extension-trace-propagators.txt b/docs/apidiffs/1.31.0_vs_1.30.1/opentelemetry-extension-trace-propagators.txt new file mode 100644 index 00000000000..df26146497b --- /dev/null +++ b/docs/apidiffs/1.31.0_vs_1.30.1/opentelemetry-extension-trace-propagators.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of against +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.31.0_vs_1.30.1/opentelemetry-opentracing-shim.txt b/docs/apidiffs/1.31.0_vs_1.30.1/opentelemetry-opentracing-shim.txt new file mode 100644 index 00000000000..df26146497b --- /dev/null +++ b/docs/apidiffs/1.31.0_vs_1.30.1/opentelemetry-opentracing-shim.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of against +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.31.0_vs_1.30.1/opentelemetry-sdk-common.txt b/docs/apidiffs/1.31.0_vs_1.30.1/opentelemetry-sdk-common.txt new file mode 100644 index 00000000000..cc95503822e --- /dev/null +++ b/docs/apidiffs/1.31.0_vs_1.30.1/opentelemetry-sdk-common.txt @@ -0,0 +1,11 @@ +Comparing source compatibility of against ++++ NEW ENUM: PUBLIC(+) FINAL(+) io.opentelemetry.sdk.common.export.MemoryMode (compatible) + +++ CLASS FILE FORMAT VERSION: 52.0 <- n.a. + +++ NEW INTERFACE: java.lang.constant.Constable + +++ NEW INTERFACE: java.lang.Comparable + +++ NEW INTERFACE: java.io.Serializable + +++ NEW SUPERCLASS: java.lang.Enum + +++ NEW FIELD: PUBLIC(+) STATIC(+) FINAL(+) io.opentelemetry.sdk.common.export.MemoryMode REUSABLE_DATA + +++ NEW FIELD: PUBLIC(+) STATIC(+) FINAL(+) io.opentelemetry.sdk.common.export.MemoryMode IMMUTABLE_DATA + +++ NEW METHOD: PUBLIC(+) STATIC(+) io.opentelemetry.sdk.common.export.MemoryMode valueOf(java.lang.String) + +++ NEW METHOD: PUBLIC(+) STATIC(+) io.opentelemetry.sdk.common.export.MemoryMode[] values() diff --git a/docs/apidiffs/1.31.0_vs_1.30.1/opentelemetry-sdk-extension-autoconfigure-spi.txt b/docs/apidiffs/1.31.0_vs_1.30.1/opentelemetry-sdk-extension-autoconfigure-spi.txt new file mode 100644 index 00000000000..df26146497b --- /dev/null +++ b/docs/apidiffs/1.31.0_vs_1.30.1/opentelemetry-sdk-extension-autoconfigure-spi.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of against +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.31.0_vs_1.30.1/opentelemetry-sdk-extension-autoconfigure.txt b/docs/apidiffs/1.31.0_vs_1.30.1/opentelemetry-sdk-extension-autoconfigure.txt new file mode 100644 index 00000000000..df26146497b --- /dev/null +++ b/docs/apidiffs/1.31.0_vs_1.30.1/opentelemetry-sdk-extension-autoconfigure.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of against +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.31.0_vs_1.30.1/opentelemetry-sdk-extension-jaeger-remote-sampler.txt b/docs/apidiffs/1.31.0_vs_1.30.1/opentelemetry-sdk-extension-jaeger-remote-sampler.txt new file mode 100644 index 00000000000..df26146497b --- /dev/null +++ b/docs/apidiffs/1.31.0_vs_1.30.1/opentelemetry-sdk-extension-jaeger-remote-sampler.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of against +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.31.0_vs_1.30.1/opentelemetry-sdk-logs.txt b/docs/apidiffs/1.31.0_vs_1.30.1/opentelemetry-sdk-logs.txt new file mode 100644 index 00000000000..11010a0b08b --- /dev/null +++ b/docs/apidiffs/1.31.0_vs_1.30.1/opentelemetry-sdk-logs.txt @@ -0,0 +1,4 @@ +Comparing source compatibility of against +*** MODIFIED INTERFACE: PUBLIC ABSTRACT io.opentelemetry.sdk.logs.ReadWriteLogRecord (not serializable) + === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 + +++ NEW METHOD: PUBLIC(+) io.opentelemetry.sdk.logs.ReadWriteLogRecord setAllAttributes(io.opentelemetry.api.common.Attributes) diff --git a/docs/apidiffs/1.31.0_vs_1.30.1/opentelemetry-sdk-metrics.txt b/docs/apidiffs/1.31.0_vs_1.30.1/opentelemetry-sdk-metrics.txt new file mode 100644 index 00000000000..6cf519e2823 --- /dev/null +++ b/docs/apidiffs/1.31.0_vs_1.30.1/opentelemetry-sdk-metrics.txt @@ -0,0 +1,21 @@ +Comparing source compatibility of against +*** MODIFIED INTERFACE: PUBLIC ABSTRACT io.opentelemetry.sdk.metrics.export.CollectionRegistration (not serializable) + === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 + +++ NEW METHOD: PUBLIC(+) java.util.Collection collectAllMetrics() + +++ NEW METHOD: PUBLIC(+) STATIC(+) io.opentelemetry.sdk.metrics.export.CollectionRegistration noop() +*** MODIFIED INTERFACE: PUBLIC ABSTRACT io.opentelemetry.sdk.metrics.export.MetricExporter (not serializable) + === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 + +++ NEW METHOD: PUBLIC(+) io.opentelemetry.sdk.common.export.MemoryMode getMemoryMode() ++++ NEW INTERFACE: PUBLIC(+) ABSTRACT(+) io.opentelemetry.sdk.metrics.export.MetricProducer (not serializable) + +++ CLASS FILE FORMAT VERSION: 52.0 <- n.a. + +++ NEW SUPERCLASS: java.lang.Object + +++ NEW METHOD: PUBLIC(+) ABSTRACT(+) java.util.Collection produce(io.opentelemetry.sdk.resources.Resource) +*** MODIFIED INTERFACE: PUBLIC ABSTRACT io.opentelemetry.sdk.metrics.export.MetricReader (not serializable) + === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 + +++ NEW METHOD: PUBLIC(+) io.opentelemetry.sdk.common.export.MemoryMode getMemoryMode() +*** MODIFIED CLASS: PUBLIC FINAL io.opentelemetry.sdk.metrics.export.PeriodicMetricReader (not serializable) + === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 + +++ NEW METHOD: PUBLIC(+) io.opentelemetry.sdk.common.export.MemoryMode getMemoryMode() +*** MODIFIED CLASS: PUBLIC FINAL io.opentelemetry.sdk.metrics.SdkMeterProviderBuilder (not serializable) + === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 + +++ NEW METHOD: PUBLIC(+) io.opentelemetry.sdk.metrics.SdkMeterProviderBuilder registerMetricProducer(io.opentelemetry.sdk.metrics.export.MetricProducer) diff --git a/docs/apidiffs/1.31.0_vs_1.30.1/opentelemetry-sdk-testing.txt b/docs/apidiffs/1.31.0_vs_1.30.1/opentelemetry-sdk-testing.txt new file mode 100644 index 00000000000..24ed11618d8 --- /dev/null +++ b/docs/apidiffs/1.31.0_vs_1.30.1/opentelemetry-sdk-testing.txt @@ -0,0 +1,12 @@ +Comparing source compatibility of against +*** MODIFIED CLASS: PUBLIC io.opentelemetry.sdk.testing.exporter.InMemoryMetricReader (not serializable) + === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 + +++ NEW METHOD: PUBLIC(+) STATIC(+) io.opentelemetry.sdk.testing.exporter.InMemoryMetricReaderBuilder builder() + +++ NEW METHOD: PUBLIC(+) io.opentelemetry.sdk.common.export.MemoryMode getMemoryMode() ++++ NEW CLASS: PUBLIC(+) FINAL(+) io.opentelemetry.sdk.testing.exporter.InMemoryMetricReaderBuilder (not serializable) + +++ CLASS FILE FORMAT VERSION: 52.0 <- n.a. + +++ NEW SUPERCLASS: java.lang.Object + +++ NEW METHOD: PUBLIC(+) io.opentelemetry.sdk.testing.exporter.InMemoryMetricReader build() + +++ NEW METHOD: PUBLIC(+) io.opentelemetry.sdk.testing.exporter.InMemoryMetricReaderBuilder setAggregationTemporalitySelector(io.opentelemetry.sdk.metrics.export.AggregationTemporalitySelector) + +++ NEW METHOD: PUBLIC(+) io.opentelemetry.sdk.testing.exporter.InMemoryMetricReaderBuilder setDefaultAggregationSelector(io.opentelemetry.sdk.metrics.export.DefaultAggregationSelector) + +++ NEW METHOD: PUBLIC(+) io.opentelemetry.sdk.testing.exporter.InMemoryMetricReaderBuilder setMemoryMode(io.opentelemetry.sdk.common.export.MemoryMode) diff --git a/docs/apidiffs/1.31.0_vs_1.30.1/opentelemetry-sdk-trace.txt b/docs/apidiffs/1.31.0_vs_1.30.1/opentelemetry-sdk-trace.txt new file mode 100644 index 00000000000..df26146497b --- /dev/null +++ b/docs/apidiffs/1.31.0_vs_1.30.1/opentelemetry-sdk-trace.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of against +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.31.0_vs_1.30.1/opentelemetry-sdk.txt b/docs/apidiffs/1.31.0_vs_1.30.1/opentelemetry-sdk.txt new file mode 100644 index 00000000000..df26146497b --- /dev/null +++ b/docs/apidiffs/1.31.0_vs_1.30.1/opentelemetry-sdk.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of against +No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-common.txt b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-common.txt index cc95503822e..df26146497b 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-common.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-common.txt @@ -1,11 +1,2 @@ Comparing source compatibility of against -+++ NEW ENUM: PUBLIC(+) FINAL(+) io.opentelemetry.sdk.common.export.MemoryMode (compatible) - +++ CLASS FILE FORMAT VERSION: 52.0 <- n.a. - +++ NEW INTERFACE: java.lang.constant.Constable - +++ NEW INTERFACE: java.lang.Comparable - +++ NEW INTERFACE: java.io.Serializable - +++ NEW SUPERCLASS: java.lang.Enum - +++ NEW FIELD: PUBLIC(+) STATIC(+) FINAL(+) io.opentelemetry.sdk.common.export.MemoryMode REUSABLE_DATA - +++ NEW FIELD: PUBLIC(+) STATIC(+) FINAL(+) io.opentelemetry.sdk.common.export.MemoryMode IMMUTABLE_DATA - +++ NEW METHOD: PUBLIC(+) STATIC(+) io.opentelemetry.sdk.common.export.MemoryMode valueOf(java.lang.String) - +++ NEW METHOD: PUBLIC(+) STATIC(+) io.opentelemetry.sdk.common.export.MemoryMode[] values() +No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-logs.txt b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-logs.txt index 11010a0b08b..df26146497b 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-logs.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-logs.txt @@ -1,4 +1,2 @@ Comparing source compatibility of against -*** MODIFIED INTERFACE: PUBLIC ABSTRACT io.opentelemetry.sdk.logs.ReadWriteLogRecord (not serializable) - === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 - +++ NEW METHOD: PUBLIC(+) io.opentelemetry.sdk.logs.ReadWriteLogRecord setAllAttributes(io.opentelemetry.api.common.Attributes) +No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-metrics.txt b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-metrics.txt index 6cf519e2823..df26146497b 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-metrics.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-metrics.txt @@ -1,21 +1,2 @@ Comparing source compatibility of against -*** MODIFIED INTERFACE: PUBLIC ABSTRACT io.opentelemetry.sdk.metrics.export.CollectionRegistration (not serializable) - === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 - +++ NEW METHOD: PUBLIC(+) java.util.Collection collectAllMetrics() - +++ NEW METHOD: PUBLIC(+) STATIC(+) io.opentelemetry.sdk.metrics.export.CollectionRegistration noop() -*** MODIFIED INTERFACE: PUBLIC ABSTRACT io.opentelemetry.sdk.metrics.export.MetricExporter (not serializable) - === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 - +++ NEW METHOD: PUBLIC(+) io.opentelemetry.sdk.common.export.MemoryMode getMemoryMode() -+++ NEW INTERFACE: PUBLIC(+) ABSTRACT(+) io.opentelemetry.sdk.metrics.export.MetricProducer (not serializable) - +++ CLASS FILE FORMAT VERSION: 52.0 <- n.a. - +++ NEW SUPERCLASS: java.lang.Object - +++ NEW METHOD: PUBLIC(+) ABSTRACT(+) java.util.Collection produce(io.opentelemetry.sdk.resources.Resource) -*** MODIFIED INTERFACE: PUBLIC ABSTRACT io.opentelemetry.sdk.metrics.export.MetricReader (not serializable) - === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 - +++ NEW METHOD: PUBLIC(+) io.opentelemetry.sdk.common.export.MemoryMode getMemoryMode() -*** MODIFIED CLASS: PUBLIC FINAL io.opentelemetry.sdk.metrics.export.PeriodicMetricReader (not serializable) - === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 - +++ NEW METHOD: PUBLIC(+) io.opentelemetry.sdk.common.export.MemoryMode getMemoryMode() -*** MODIFIED CLASS: PUBLIC FINAL io.opentelemetry.sdk.metrics.SdkMeterProviderBuilder (not serializable) - === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 - +++ NEW METHOD: PUBLIC(+) io.opentelemetry.sdk.metrics.SdkMeterProviderBuilder registerMetricProducer(io.opentelemetry.sdk.metrics.export.MetricProducer) +No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-testing.txt b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-testing.txt index 24ed11618d8..df26146497b 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-testing.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-testing.txt @@ -1,12 +1,2 @@ Comparing source compatibility of against -*** MODIFIED CLASS: PUBLIC io.opentelemetry.sdk.testing.exporter.InMemoryMetricReader (not serializable) - === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 - +++ NEW METHOD: PUBLIC(+) STATIC(+) io.opentelemetry.sdk.testing.exporter.InMemoryMetricReaderBuilder builder() - +++ NEW METHOD: PUBLIC(+) io.opentelemetry.sdk.common.export.MemoryMode getMemoryMode() -+++ NEW CLASS: PUBLIC(+) FINAL(+) io.opentelemetry.sdk.testing.exporter.InMemoryMetricReaderBuilder (not serializable) - +++ CLASS FILE FORMAT VERSION: 52.0 <- n.a. - +++ NEW SUPERCLASS: java.lang.Object - +++ NEW METHOD: PUBLIC(+) io.opentelemetry.sdk.testing.exporter.InMemoryMetricReader build() - +++ NEW METHOD: PUBLIC(+) io.opentelemetry.sdk.testing.exporter.InMemoryMetricReaderBuilder setAggregationTemporalitySelector(io.opentelemetry.sdk.metrics.export.AggregationTemporalitySelector) - +++ NEW METHOD: PUBLIC(+) io.opentelemetry.sdk.testing.exporter.InMemoryMetricReaderBuilder setDefaultAggregationSelector(io.opentelemetry.sdk.metrics.export.DefaultAggregationSelector) - +++ NEW METHOD: PUBLIC(+) io.opentelemetry.sdk.testing.exporter.InMemoryMetricReaderBuilder setMemoryMode(io.opentelemetry.sdk.common.export.MemoryMode) +No changes. \ No newline at end of file From ef3fef9f42d69243ac857c3e06dfc8b342d50039 Mon Sep 17 00:00:00 2001 From: jack-berg <34418638+jack-berg@users.noreply.github.com> Date: Mon, 9 Oct 2023 09:41:26 -0500 Subject: [PATCH 046/901] Add file configuration to autoconfigure (#5831) --- sdk-extensions/autoconfigure/README.md | 26 ++- sdk-extensions/autoconfigure/build.gradle.kts | 1 + ...AutoConfiguredOpenTelemetrySdkBuilder.java | 78 ++++++-- .../autoconfigure/FileConfigurationTest.java | 46 +++++ .../autoconfigure/FileConfigurationTest.java | 178 ++++++++++++++++++ 5 files changed, 314 insertions(+), 15 deletions(-) create mode 100644 sdk-extensions/autoconfigure/src/test/java/io/opentelemetry/sdk/autoconfigure/FileConfigurationTest.java create mode 100644 sdk-extensions/autoconfigure/src/testFullConfig/java/io/opentelemetry/sdk/autoconfigure/FileConfigurationTest.java diff --git a/sdk-extensions/autoconfigure/README.md b/sdk-extensions/autoconfigure/README.md index 0653fb38061..a5ae3413f28 100644 --- a/sdk-extensions/autoconfigure/README.md +++ b/sdk-extensions/autoconfigure/README.md @@ -40,10 +40,11 @@ environment variables, e.g., `OTEL_TRACES_EXPORTER=zipkin`. * [Periodic Metric Reader](#periodic-metric-reader) * [Metric exporters](#metric-exporters) + [Prometheus exporter](#prometheus-exporter) - * [Cardinality limits](#cardinality-limits) + * [Cardinality Limits](#cardinality-limits) - [Logger provider](#logger-provider) -- [Batch log record processor](#batch-log-record-processor) + * [Batch log record processor](#batch-log-record-processor) - [Customizing the OpenTelemetry SDK](#customizing-the-opentelemetry-sdk) +- [File Configuration](#file-configuration) @@ -347,7 +348,7 @@ a Prometheus server scrapes from. The following configuration options are specific to `SdkLoggerProvider`. See [general configuration](#general-configuration) for general configuration. -## Batch log record processor +### Batch log record processor | System property | Environment variable | Description | |---------------------------------|---------------------------------|------------------------------------------------------------------------------------| @@ -361,3 +362,22 @@ The following configuration options are specific to `SdkLoggerProvider`. See [ge Autoconfiguration exposes SPI [hooks](../autoconfigure-spi/src/main/java/io/opentelemetry/sdk/autoconfigure/spi) for customizing behavior programmatically as needed. It's recommended to use the above configuration properties where possible, only implementing the SPI to add functionality not found in the SDK by default. + +## File Configuration + +**Experimental**: File based configuration is experimental and subject to breaking changes. + +File configuration allows for configuration via a YAML as described +in [opentelemetry-configuration](https://github.com/open-telemetry/opentelemetry-configuration) +and [file configuration](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/configuration/file-configuration.md). + +To use, include `io.opentelemetry:opentelemetry-sdk-extension:incubator:` and specify the +path to the config file as described in the table below. + +| System property | Environment variable | Purpose | +|------------------|----------------------|------------------------------------------------------------| +| otel.config.file | OTEL_CONFIG_FILE | The path to the SDK configuration file. Defaults to unset. | + +NOTE: When a config file is specified, other environment variables described in this document along +with SPI [customizations](#customizing-the-opentelemetry-sdk) are ignored. The contents of the file +alone dictate SDK configuration. diff --git a/sdk-extensions/autoconfigure/build.gradle.kts b/sdk-extensions/autoconfigure/build.gradle.kts index 23099336337..cc47e419045 100644 --- a/sdk-extensions/autoconfigure/build.gradle.kts +++ b/sdk-extensions/autoconfigure/build.gradle.kts @@ -58,6 +58,7 @@ testing { implementation(project(":sdk:testing")) implementation(project(":sdk:trace-shaded-deps")) implementation(project(":sdk-extensions:jaeger-remote-sampler")) + implementation(project(":sdk-extensions:incubator")) implementation("com.google.guava:guava") implementation("io.opentelemetry.proto:opentelemetry-proto") diff --git a/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/AutoConfiguredOpenTelemetrySdkBuilder.java b/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/AutoConfiguredOpenTelemetrySdkBuilder.java index 14a25e93a62..7a89123ef65 100644 --- a/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/AutoConfiguredOpenTelemetrySdkBuilder.java +++ b/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/AutoConfiguredOpenTelemetrySdkBuilder.java @@ -32,7 +32,12 @@ import io.opentelemetry.sdk.trace.export.SpanExporter; import io.opentelemetry.sdk.trace.samplers.Sampler; import java.io.Closeable; +import java.io.FileInputStream; +import java.io.FileNotFoundException; import java.io.IOException; +import java.io.InputStream; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; @@ -331,6 +336,13 @@ public AutoConfiguredOpenTelemetrySdk build() { ConfigProperties config = getConfig(); + AutoConfiguredOpenTelemetrySdk fromFileConfiguration = maybeConfigureFromFile(config); + if (fromFileConfiguration != null) { + maybeRegisterShutdownHook(fromFileConfiguration.getOpenTelemetrySdk()); + maybeSetAsGlobal(fromFileConfiguration.getOpenTelemetrySdk()); + return fromFileConfiguration; + } + Resource resource = ResourceConfiguration.configureResource(config, spiHelper, resourceCustomizer); @@ -391,18 +403,8 @@ public AutoConfiguredOpenTelemetrySdk build() { openTelemetrySdk = sdkBuilder.build(); } - // NOTE: Shutdown hook registration is untested. Modify with caution. - if (registerShutdownHook) { - Runtime.getRuntime().addShutdownHook(shutdownHook(openTelemetrySdk)); - } - - if (setResultAsGlobal) { - GlobalOpenTelemetry.set(openTelemetrySdk); - GlobalEventEmitterProvider.set( - SdkEventEmitterProvider.create(openTelemetrySdk.getSdkLoggerProvider())); - logger.log( - Level.FINE, "Global OpenTelemetry set to {0} by autoconfiguration", openTelemetrySdk); - } + maybeRegisterShutdownHook(openTelemetrySdk); + maybeSetAsGlobal(openTelemetrySdk); return AutoConfiguredOpenTelemetrySdk.create(openTelemetrySdk, resource, config); } catch (RuntimeException e) { @@ -424,6 +426,58 @@ public AutoConfiguredOpenTelemetrySdk build() { } } + @Nullable + private static AutoConfiguredOpenTelemetrySdk maybeConfigureFromFile(ConfigProperties config) { + String configurationFile = config.getString("OTEL_CONFIG_FILE"); + if (configurationFile == null || configurationFile.isEmpty()) { + return null; + } + FileInputStream fis; + try { + fis = new FileInputStream(configurationFile); + } catch (FileNotFoundException e) { + throw new ConfigurationException("Configuration file not found", e); + } + try { + Class configurationFactory = + Class.forName("io.opentelemetry.sdk.extension.incubator.fileconfig.ConfigurationFactory"); + Method parseAndInterpret = + configurationFactory.getMethod("parseAndInterpret", InputStream.class); + OpenTelemetrySdk sdk = (OpenTelemetrySdk) parseAndInterpret.invoke(null, fis); + // Note: can't access file configuration resource without reflection so setting a dummy + // resource + return AutoConfiguredOpenTelemetrySdk.create(sdk, Resource.getDefault(), config); + } catch (ClassNotFoundException | NoSuchMethodException | IllegalAccessException e) { + throw new ConfigurationException( + "Error configuring from file. Is opentelemetry-sdk-extension-incubator on the classpath?", + e); + } catch (InvocationTargetException e) { + Throwable cause = e.getCause(); + if (cause instanceof ConfigurationException) { + throw (ConfigurationException) cause; + } + throw new ConfigurationException("Unexpected error configuring from file", e); + } + } + + private void maybeRegisterShutdownHook(OpenTelemetrySdk openTelemetrySdk) { + if (!registerShutdownHook) { + return; + } + Runtime.getRuntime().addShutdownHook(shutdownHook(openTelemetrySdk)); + } + + private void maybeSetAsGlobal(OpenTelemetrySdk openTelemetrySdk) { + if (!setResultAsGlobal) { + return; + } + GlobalOpenTelemetry.set(openTelemetrySdk); + GlobalEventEmitterProvider.set( + SdkEventEmitterProvider.create(openTelemetrySdk.getSdkLoggerProvider())); + logger.log( + Level.FINE, "Global OpenTelemetry set to {0} by autoconfiguration", openTelemetrySdk); + } + @SuppressWarnings("deprecation") // Support deprecated SdkTracerProviderConfigurer private void mergeSdkTracerProviderConfigurer() { for (io.opentelemetry.sdk.autoconfigure.spi.traces.SdkTracerProviderConfigurer configurer : diff --git a/sdk-extensions/autoconfigure/src/test/java/io/opentelemetry/sdk/autoconfigure/FileConfigurationTest.java b/sdk-extensions/autoconfigure/src/test/java/io/opentelemetry/sdk/autoconfigure/FileConfigurationTest.java new file mode 100644 index 00000000000..e6aa1759d32 --- /dev/null +++ b/sdk-extensions/autoconfigure/src/test/java/io/opentelemetry/sdk/autoconfigure/FileConfigurationTest.java @@ -0,0 +1,46 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.sdk.autoconfigure; + +import static org.assertj.core.api.Assertions.assertThatThrownBy; + +import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties; +import io.opentelemetry.sdk.autoconfigure.spi.ConfigurationException; +import io.opentelemetry.sdk.autoconfigure.spi.internal.DefaultConfigProperties; +import java.io.IOException; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.Collections; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.io.TempDir; + +class FileConfigurationTest { + + @Test + void configFile(@TempDir Path tempDir) throws IOException { + String yaml = + "file_format: \"0.1\"\n" + + "resource:\n" + + " attributes:\n" + + " service.name: test\n" + + "tracer_provider:\n" + + " processors:\n" + + " - simple:\n" + + " exporter:\n" + + " console: {}\n"; + Path path = tempDir.resolve("otel-config.yaml"); + Files.write(path, yaml.getBytes(StandardCharsets.UTF_8)); + ConfigProperties config = + DefaultConfigProperties.createFromMap( + Collections.singletonMap("OTEL_CONFIG_FILE", path.toString())); + + assertThatThrownBy(() -> AutoConfiguredOpenTelemetrySdk.builder().setConfig(config).build()) + .isInstanceOf(ConfigurationException.class) + .hasMessage( + "Error configuring from file. Is opentelemetry-sdk-extension-incubator on the classpath?"); + } +} diff --git a/sdk-extensions/autoconfigure/src/testFullConfig/java/io/opentelemetry/sdk/autoconfigure/FileConfigurationTest.java b/sdk-extensions/autoconfigure/src/testFullConfig/java/io/opentelemetry/sdk/autoconfigure/FileConfigurationTest.java new file mode 100644 index 00000000000..dd11494958f --- /dev/null +++ b/sdk-extensions/autoconfigure/src/testFullConfig/java/io/opentelemetry/sdk/autoconfigure/FileConfigurationTest.java @@ -0,0 +1,178 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.sdk.autoconfigure; + +import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.assertThat; +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; + +import io.opentelemetry.api.GlobalOpenTelemetry; +import io.opentelemetry.api.OpenTelemetry; +import io.opentelemetry.api.baggage.propagation.W3CBaggagePropagator; +import io.opentelemetry.api.events.GlobalEventEmitterProvider; +import io.opentelemetry.api.trace.propagation.W3CTraceContextPropagator; +import io.opentelemetry.context.propagation.ContextPropagators; +import io.opentelemetry.context.propagation.TextMapPropagator; +import io.opentelemetry.exporter.logging.LoggingSpanExporter; +import io.opentelemetry.internal.testing.CleanupExtension; +import io.opentelemetry.sdk.OpenTelemetrySdk; +import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties; +import io.opentelemetry.sdk.autoconfigure.spi.ConfigurationException; +import io.opentelemetry.sdk.autoconfigure.spi.internal.DefaultConfigProperties; +import io.opentelemetry.sdk.logs.internal.SdkEventEmitterProvider; +import io.opentelemetry.sdk.resources.Resource; +import io.opentelemetry.sdk.trace.SdkTracerProvider; +import io.opentelemetry.sdk.trace.export.SimpleSpanProcessor; +import java.io.IOException; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.Collections; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; +import org.junit.jupiter.api.io.TempDir; + +class FileConfigurationTest { + + @RegisterExtension private static final CleanupExtension cleanup = new CleanupExtension(); + + @TempDir private Path tempDir; + private Path configFilePath; + + @BeforeEach + void setup() throws IOException { + String yaml = + "file_format: \"0.1\"\n" + + "resource:\n" + + " attributes:\n" + + " service.name: test\n" + + "tracer_provider:\n" + + " processors:\n" + + " - simple:\n" + + " exporter:\n" + + " console: {}\n"; + configFilePath = tempDir.resolve("otel-config.yaml"); + Files.write(configFilePath, yaml.getBytes(StandardCharsets.UTF_8)); + GlobalOpenTelemetry.resetForTest(); + GlobalEventEmitterProvider.resetForTest(); + } + + @Test + void configFile_Valid() { + ConfigProperties config = + DefaultConfigProperties.createFromMap( + Collections.singletonMap("OTEL_CONFIG_FILE", configFilePath.toString())); + OpenTelemetrySdk expectedSdk = + OpenTelemetrySdk.builder() + .setTracerProvider( + SdkTracerProvider.builder() + .setResource( + Resource.getDefault().toBuilder().put("service.name", "test").build()) + .addSpanProcessor(SimpleSpanProcessor.create(LoggingSpanExporter.create())) + .build()) + .setPropagators( + ContextPropagators.create( + TextMapPropagator.composite( + W3CTraceContextPropagator.getInstance(), + W3CBaggagePropagator.getInstance()))) + .build(); + cleanup.addCloseable(expectedSdk); + AutoConfiguredOpenTelemetrySdkBuilder builder = spy(AutoConfiguredOpenTelemetrySdk.builder()); + Thread thread = new Thread(); + doReturn(thread).when(builder).shutdownHook(any()); + + AutoConfiguredOpenTelemetrySdk autoConfiguredOpenTelemetrySdk = + builder.setConfig(config).build(); + cleanup.addCloseable(autoConfiguredOpenTelemetrySdk.getOpenTelemetrySdk()); + + assertThat(autoConfiguredOpenTelemetrySdk.getOpenTelemetrySdk().toString()) + .isEqualTo(expectedSdk.toString()); + // AutoConfiguredOpenTelemetrySdk#getResource() is set to a dummy value when configuring from + // file + assertThat(autoConfiguredOpenTelemetrySdk.getResource()).isEqualTo(Resource.getDefault()); + verify(builder, times(1)).shutdownHook(autoConfiguredOpenTelemetrySdk.getOpenTelemetrySdk()); + assertThat(Runtime.getRuntime().removeShutdownHook(thread)).isTrue(); + } + + @Test + void configFile_NoShutdownHook() { + ConfigProperties config = + DefaultConfigProperties.createFromMap( + Collections.singletonMap("OTEL_CONFIG_FILE", configFilePath.toString())); + AutoConfiguredOpenTelemetrySdkBuilder builder = spy(AutoConfiguredOpenTelemetrySdk.builder()); + + AutoConfiguredOpenTelemetrySdk autoConfiguredOpenTelemetrySdk = + builder.setConfig(config).disableShutdownHook().build(); + cleanup.addCloseable(autoConfiguredOpenTelemetrySdk.getOpenTelemetrySdk()); + + verify(builder, never()).shutdownHook(any()); + } + + @Test + void configFile_setResultAsGlobalFalse() { + GlobalOpenTelemetry.set(OpenTelemetry.noop()); + ConfigProperties config = + DefaultConfigProperties.createFromMap( + Collections.singletonMap("OTEL_CONFIG_FILE", configFilePath.toString())); + + AutoConfiguredOpenTelemetrySdk autoConfiguredOpenTelemetrySdk = + AutoConfiguredOpenTelemetrySdk.builder().setConfig(config).build(); + OpenTelemetrySdk openTelemetrySdk = autoConfiguredOpenTelemetrySdk.getOpenTelemetrySdk(); + cleanup.addCloseable(openTelemetrySdk); + + assertThat(GlobalOpenTelemetry.get()).extracting("delegate").isNotSameAs(openTelemetrySdk); + assertThat(GlobalEventEmitterProvider.get()) + .isNotSameAs(openTelemetrySdk.getSdkLoggerProvider()); + } + + @Test + void configFile_setResultAsGlobalTrue() { + ConfigProperties config = + DefaultConfigProperties.createFromMap( + Collections.singletonMap("OTEL_CONFIG_FILE", configFilePath.toString())); + + AutoConfiguredOpenTelemetrySdk autoConfiguredOpenTelemetrySdk = + AutoConfiguredOpenTelemetrySdk.builder().setConfig(config).setResultAsGlobal().build(); + OpenTelemetrySdk openTelemetrySdk = autoConfiguredOpenTelemetrySdk.getOpenTelemetrySdk(); + cleanup.addCloseable(openTelemetrySdk); + + assertThat(GlobalOpenTelemetry.get()).extracting("delegate").isSameAs(openTelemetrySdk); + assertThat(GlobalEventEmitterProvider.get()) + .isInstanceOf(SdkEventEmitterProvider.class) + .extracting("delegateLoggerProvider") + .isSameAs(openTelemetrySdk.getSdkLoggerProvider()); + } + + @Test + void configFile_Error(@TempDir Path tempDir) throws IOException { + String yaml = + "file_format: \"0.1\"\n" + + "resource:\n" + + " attributes:\n" + + " service.name: test\n" + + "tracer_provider:\n" + + " processors:\n" + + " - simple:\n" + + " exporter:\n" + + " foo: {}\n"; + Path path = tempDir.resolve("otel-config.yaml"); + Files.write(path, yaml.getBytes(StandardCharsets.UTF_8)); + ConfigProperties config = + DefaultConfigProperties.createFromMap( + Collections.singletonMap("OTEL_CONFIG_FILE", path.toString())); + + assertThatThrownBy(() -> AutoConfiguredOpenTelemetrySdk.builder().setConfig(config).build()) + .isInstanceOf(ConfigurationException.class) + .hasMessage("Unrecognized span exporter(s): [foo]"); + } +} From 1523dedb555b033adce27475863e1464b1fb76cf Mon Sep 17 00:00:00 2001 From: jack-berg <34418638+jack-berg@users.noreply.github.com> Date: Wed, 11 Oct 2023 10:24:32 -0500 Subject: [PATCH 047/901] Update to opentelemetry-configuration v0.1.0 (#5899) --- sdk-extensions/incubator/build.gradle.kts | 4 +- .../OpenTelemetryConfigurationFactory.java | 2 +- .../fileconfig/PropagatorFactory.java | 37 ++++++++++++ ...ory.java => TextMapPropagatorFactory.java} | 17 +++--- .../fileconfig/ConfigurationReaderTest.java | 13 ++-- ...OpenTelemetryConfigurationFactoryTest.java | 14 ++++- .../fileconfig/PropagatorFactoryTest.java | 60 +++++++++++++++++++ ...java => TextMapPropagatorFactoryTest.java} | 46 +++++++------- 8 files changed, 148 insertions(+), 45 deletions(-) create mode 100644 sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/PropagatorFactory.java rename sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/{PropagatorsFactory.java => TextMapPropagatorFactory.java} (80%) create mode 100644 sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/PropagatorFactoryTest.java rename sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/{PropagatorsFactoryTest.java => TextMapPropagatorFactoryTest.java} (58%) diff --git a/sdk-extensions/incubator/build.gradle.kts b/sdk-extensions/incubator/build.gradle.kts index 7a07f3c8fa6..847a3b039e6 100644 --- a/sdk-extensions/incubator/build.gradle.kts +++ b/sdk-extensions/incubator/build.gradle.kts @@ -54,8 +54,8 @@ dependencies { // 6. deleteJs2pTmp - delete tmp directory // ... proceed with normal sourcesJar, compileJava, etc -// TODO(jack-berg): update ref to be released version when available -val configurationRef = "0508846f82ed54b230fa638e1e7556c52efee25e" +val configurationTag = "0.1.0" +val configurationRef = "refs/tags/v$configurationTag" // Replace with commit SHA to point to experiment with a specific commit val configurationRepoZip = "https://github.com/open-telemetry/opentelemetry-configuration/archive/$configurationRef.zip" val buildDirectory = layout.buildDirectory.asFile.get() diff --git a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/OpenTelemetryConfigurationFactory.java b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/OpenTelemetryConfigurationFactory.java index 17c68f9ada2..cb2b52a8472 100644 --- a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/OpenTelemetryConfigurationFactory.java +++ b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/OpenTelemetryConfigurationFactory.java @@ -45,7 +45,7 @@ public OpenTelemetrySdk create( } builder.setPropagators( - PropagatorsFactory.getInstance().create(model.getPropagators(), spiHelper, closeables)); + PropagatorFactory.getInstance().create(model.getPropagator(), spiHelper, closeables)); Resource resource = ResourceFactory.getInstance().create(model.getResource(), spiHelper, closeables); diff --git a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/PropagatorFactory.java b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/PropagatorFactory.java new file mode 100644 index 00000000000..d53c3beda76 --- /dev/null +++ b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/PropagatorFactory.java @@ -0,0 +1,37 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.sdk.extension.incubator.fileconfig; + +import io.opentelemetry.context.propagation.ContextPropagators; +import io.opentelemetry.context.propagation.TextMapPropagator; +import io.opentelemetry.sdk.autoconfigure.internal.SpiHelper; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.Propagator; +import java.io.Closeable; +import java.util.List; +import javax.annotation.Nullable; + +final class PropagatorFactory implements Factory { + + private static final PropagatorFactory INSTANCE = new PropagatorFactory(); + + private PropagatorFactory() {} + + static PropagatorFactory getInstance() { + return INSTANCE; + } + + @Override + public ContextPropagators create( + @Nullable Propagator model, SpiHelper spiHelper, List closeables) { + List compositeModel = null; + if (model != null) { + compositeModel = model.getComposite(); + } + TextMapPropagator textMapPropagator = + TextMapPropagatorFactory.getInstance().create(compositeModel, spiHelper, closeables); + return ContextPropagators.create(textMapPropagator); + } +} diff --git a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/PropagatorsFactory.java b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/TextMapPropagatorFactory.java similarity index 80% rename from sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/PropagatorsFactory.java rename to sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/TextMapPropagatorFactory.java index cbd6c82bbc0..4451ac98516 100644 --- a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/PropagatorsFactory.java +++ b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/TextMapPropagatorFactory.java @@ -7,7 +7,6 @@ import io.opentelemetry.api.baggage.propagation.W3CBaggagePropagator; import io.opentelemetry.api.trace.propagation.W3CTraceContextPropagator; -import io.opentelemetry.context.propagation.ContextPropagators; import io.opentelemetry.context.propagation.TextMapPropagator; import io.opentelemetry.sdk.autoconfigure.internal.NamedSpiManager; import io.opentelemetry.sdk.autoconfigure.internal.SpiHelper; @@ -22,18 +21,18 @@ import java.util.Set; import javax.annotation.Nullable; -final class PropagatorsFactory implements Factory, ContextPropagators> { +final class TextMapPropagatorFactory implements Factory, TextMapPropagator> { - private static final PropagatorsFactory INSTANCE = new PropagatorsFactory(); + private static final TextMapPropagatorFactory INSTANCE = new TextMapPropagatorFactory(); - private PropagatorsFactory() {} + private TextMapPropagatorFactory() {} - static PropagatorsFactory getInstance() { + static TextMapPropagatorFactory getInstance() { return INSTANCE; } @Override - public ContextPropagators create( + public TextMapPropagator create( @Nullable List model, SpiHelper spiHelper, List closeables) { if (model == null || model.isEmpty()) { model = Arrays.asList("tracecontext", "baggage"); @@ -44,7 +43,7 @@ public ContextPropagators create( throw new ConfigurationException( "propagators contains \"none\" along with other propagators"); } - return ContextPropagators.noop(); + return TextMapPropagator.noop(); } NamedSpiManager spiPropagatorsManager = @@ -58,7 +57,7 @@ public ContextPropagators create( propagators.add(getPropagator(propagator, spiPropagatorsManager)); } - return ContextPropagators.create(TextMapPropagator.composite(propagators)); + return TextMapPropagator.composite(propagators); } private static TextMapPropagator getPropagator( @@ -74,6 +73,6 @@ private static TextMapPropagator getPropagator( if (spiPropagator != null) { return spiPropagator; } - throw new ConfigurationException("Unrecognized value for otel.propagators: " + name); + throw new ConfigurationException("Unrecognized propagator: " + name); } } diff --git a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/ConfigurationReaderTest.java b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/ConfigurationReaderTest.java index 27d6e14cc0a..afdb4cac33e 100644 --- a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/ConfigurationReaderTest.java +++ b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/ConfigurationReaderTest.java @@ -31,6 +31,7 @@ import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.ParentBased; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.PeriodicMetricReader; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.Prometheus; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.Propagator; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.PullMetricReader; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.Resource; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.Sampler; @@ -50,7 +51,6 @@ import java.nio.charset.StandardCharsets; import java.util.Arrays; import java.util.Collections; -import java.util.List; import org.junit.jupiter.api.Test; class ConfigurationReaderTest { @@ -71,9 +71,12 @@ void read_KitchenSinkExampleFile() throws IOException { new AttributeLimits().withAttributeValueLengthLimit(4096).withAttributeCountLimit(128); expected.withAttributeLimits(attributeLimits); - List propagators = - Arrays.asList("tracecontext", "baggage", "b3", "b3multi", "jaeger", "xray", "ottrace"); - expected.withPropagators(propagators); + Propagator propagator = + new Propagator() + .withComposite( + Arrays.asList( + "tracecontext", "baggage", "b3", "b3multi", "jaeger", "xray", "ottrace")); + expected.withPropagator(propagator); // TracerProvider config TracerProvider tracerProvider = new TracerProvider(); @@ -253,7 +256,7 @@ void read_KitchenSinkExampleFile() throws IOException { assertThat(config.getFileFormat()).isEqualTo("0.1"); assertThat(config.getResource()).isEqualTo(resource); assertThat(config.getAttributeLimits()).isEqualTo(attributeLimits); - assertThat(config.getPropagators()).isEqualTo(propagators); + assertThat(config.getPropagator()).isEqualTo(propagator); // TracerProvider config TracerProvider configTracerProvider = config.getTracerProvider(); diff --git a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/OpenTelemetryConfigurationFactoryTest.java b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/OpenTelemetryConfigurationFactoryTest.java index 3bede9ea2e5..ac249c94b9a 100644 --- a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/OpenTelemetryConfigurationFactoryTest.java +++ b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/OpenTelemetryConfigurationFactoryTest.java @@ -38,6 +38,7 @@ import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.Otlp; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.OtlpMetric; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.PeriodicMetricReader; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.Propagator; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.Resource; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.Sampler; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.Selector; @@ -223,9 +224,16 @@ void create_Configured() { .create( new OpenTelemetryConfiguration() .withFileFormat("0.1") - .withPropagators( - Arrays.asList( - "tracecontext", "baggage", "ottrace", "b3multi", "b3", "jaeger")) + .withPropagator( + new Propagator() + .withComposite( + Arrays.asList( + "tracecontext", + "baggage", + "ottrace", + "b3multi", + "b3", + "jaeger"))) .withResource( new Resource() .withAttributes( diff --git a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/PropagatorFactoryTest.java b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/PropagatorFactoryTest.java new file mode 100644 index 00000000000..ba9f6190e95 --- /dev/null +++ b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/PropagatorFactoryTest.java @@ -0,0 +1,60 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.sdk.extension.incubator.fileconfig; + +import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.assertThat; + +import io.opentelemetry.api.baggage.propagation.W3CBaggagePropagator; +import io.opentelemetry.api.trace.propagation.W3CTraceContextPropagator; +import io.opentelemetry.context.propagation.ContextPropagators; +import io.opentelemetry.context.propagation.TextMapPropagator; +import io.opentelemetry.extension.trace.propagation.B3Propagator; +import io.opentelemetry.extension.trace.propagation.JaegerPropagator; +import io.opentelemetry.extension.trace.propagation.OtTracePropagator; +import io.opentelemetry.sdk.autoconfigure.internal.SpiHelper; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.Propagator; +import java.util.Arrays; +import java.util.Collections; +import java.util.stream.Stream; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; + +class PropagatorFactoryTest { + + private final SpiHelper spiHelper = + SpiHelper.create(PropagatorFactoryTest.class.getClassLoader()); + + @ParameterizedTest + @MethodSource("createArguments") + void create(Propagator model, ContextPropagators expectedPropagators) { + ContextPropagators propagators = + PropagatorFactory.getInstance().create(model, spiHelper, Collections.emptyList()); + + assertThat(propagators.toString()).isEqualTo(expectedPropagators.toString()); + } + + private static Stream createArguments() { + return Stream.of( + Arguments.of( + null, + ContextPropagators.create( + TextMapPropagator.composite( + W3CTraceContextPropagator.getInstance(), W3CBaggagePropagator.getInstance()))), + Arguments.of( + new Propagator() + .withComposite( + Arrays.asList("tracecontext", "baggage", "ottrace", "b3multi", "b3", "jaeger")), + ContextPropagators.create( + TextMapPropagator.composite( + W3CTraceContextPropagator.getInstance(), + W3CBaggagePropagator.getInstance(), + OtTracePropagator.getInstance(), + B3Propagator.injectingMultiHeaders(), + B3Propagator.injectingSingleHeader(), + JaegerPropagator.getInstance())))); + } +} diff --git a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/PropagatorsFactoryTest.java b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/TextMapPropagatorFactoryTest.java similarity index 58% rename from sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/PropagatorsFactoryTest.java rename to sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/TextMapPropagatorFactoryTest.java index 293d40717ab..a0a0f6de49d 100644 --- a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/PropagatorsFactoryTest.java +++ b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/TextMapPropagatorFactoryTest.java @@ -10,7 +10,6 @@ import io.opentelemetry.api.baggage.propagation.W3CBaggagePropagator; import io.opentelemetry.api.trace.propagation.W3CTraceContextPropagator; -import io.opentelemetry.context.propagation.ContextPropagators; import io.opentelemetry.context.propagation.TextMapPropagator; import io.opentelemetry.extension.trace.propagation.B3Propagator; import io.opentelemetry.extension.trace.propagation.JaegerPropagator; @@ -26,50 +25,47 @@ import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.MethodSource; -class PropagatorsFactoryTest { +class TextMapPropagatorFactoryTest { private final SpiHelper spiHelper = - SpiHelper.create(PropagatorsFactoryTest.class.getClassLoader()); + SpiHelper.create(TextMapPropagatorFactoryTest.class.getClassLoader()); @ParameterizedTest @MethodSource("createArguments") - void create(List model, ContextPropagators expectedPropagators) { - ContextPropagators propagators = - PropagatorsFactory.getInstance().create(model, spiHelper, Collections.emptyList()); + void create(List model, TextMapPropagator expectedPropagator) { + TextMapPropagator propagator = + TextMapPropagatorFactory.getInstance().create(model, spiHelper, Collections.emptyList()); - assertThat(propagators.toString()).isEqualTo(expectedPropagators.toString()); + assertThat(propagator.toString()).isEqualTo(expectedPropagator.toString()); } private static Stream createArguments() { return Stream.of( Arguments.of( null, - ContextPropagators.create( - TextMapPropagator.composite( - W3CTraceContextPropagator.getInstance(), W3CBaggagePropagator.getInstance()))), + TextMapPropagator.composite( + W3CTraceContextPropagator.getInstance(), W3CBaggagePropagator.getInstance())), Arguments.of( Collections.emptyList(), - ContextPropagators.create( - TextMapPropagator.composite( - W3CTraceContextPropagator.getInstance(), W3CBaggagePropagator.getInstance()))), - Arguments.of(Collections.singletonList("none"), ContextPropagators.noop()), + TextMapPropagator.composite( + W3CTraceContextPropagator.getInstance(), W3CBaggagePropagator.getInstance())), + Arguments.of(Collections.singletonList("none"), TextMapPropagator.noop()), Arguments.of( Arrays.asList("tracecontext", "baggage", "ottrace", "b3multi", "b3", "jaeger"), - ContextPropagators.create( - TextMapPropagator.composite( - W3CTraceContextPropagator.getInstance(), - W3CBaggagePropagator.getInstance(), - OtTracePropagator.getInstance(), - B3Propagator.injectingMultiHeaders(), - B3Propagator.injectingSingleHeader(), - JaegerPropagator.getInstance())))); + TextMapPropagator.composite( + W3CTraceContextPropagator.getInstance(), + W3CBaggagePropagator.getInstance(), + OtTracePropagator.getInstance(), + B3Propagator.injectingMultiHeaders(), + B3Propagator.injectingSingleHeader(), + JaegerPropagator.getInstance()))); } @Test void create_NoneAndOther() { assertThatThrownBy( () -> - PropagatorsFactory.getInstance() + TextMapPropagatorFactory.getInstance() .create(Arrays.asList("none", "foo"), spiHelper, Collections.emptyList())) .isInstanceOf(ConfigurationException.class) .hasMessage("propagators contains \"none\" along with other propagators"); @@ -79,9 +75,9 @@ void create_NoneAndOther() { void create_UnknownSpiPropagator() { assertThatThrownBy( () -> - PropagatorsFactory.getInstance() + TextMapPropagatorFactory.getInstance() .create(Collections.singletonList("foo"), spiHelper, Collections.emptyList())) .isInstanceOf(ConfigurationException.class) - .hasMessage("Unrecognized value for otel.propagators: foo"); + .hasMessage("Unrecognized propagator: foo"); } } From b60eff369862031f111b2fcd880027a0e8cc67d5 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 11 Oct 2023 13:20:26 -0500 Subject: [PATCH 048/901] Update dependency com.google.guava:guava-bom to v32.1.3-jre (#5901) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- dependencyManagement/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index ba9b1bfdb1e..5294048dd7f 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -9,7 +9,7 @@ rootProject.extra["versions"] = dependencyVersions val DEPENDENCY_BOMS = listOf( "com.fasterxml.jackson:jackson-bom:2.15.2", - "com.google.guava:guava-bom:32.1.2-jre", + "com.google.guava:guava-bom:32.1.3-jre", "com.google.protobuf:protobuf-bom:3.24.4", "com.linecorp.armeria:armeria-bom:1.25.2", "com.squareup.okhttp3:okhttp-bom:4.11.0", From 311fc0a7bec42810765e2f90089abffc3e8e74a6 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 11 Oct 2023 13:20:53 -0500 Subject: [PATCH 049/901] Update dependency com.google.guava:guava to v32.1.3-jre (#5900) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- buildSrc/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts index 8b5fe115442..34a1a20cd1c 100644 --- a/buildSrc/build.gradle.kts +++ b/buildSrc/build.gradle.kts @@ -47,7 +47,7 @@ dependencies { // When updating, update above in plugins too implementation("com.diffplug.spotless:spotless-plugin-gradle:6.22.0") // Needed for japicmp but not automatically brought in for some reason. - implementation("com.google.guava:guava:32.1.2-jre") + implementation("com.google.guava:guava:32.1.3-jre") implementation("com.squareup:javapoet:1.13.0") implementation("com.squareup.wire:wire-compiler") implementation("com.squareup.wire:wire-gradle-plugin") From cc8774fa0fa13dd63c293c9379151e1bed714cc8 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 11 Oct 2023 13:21:52 -0500 Subject: [PATCH 050/901] Update dependency io.netty:netty-bom to v4.1.100.Final (#5898) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- dependencyManagement/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index 5294048dd7f..2a66466b910 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -15,7 +15,7 @@ val DEPENDENCY_BOMS = listOf( "com.squareup.okhttp3:okhttp-bom:4.11.0", "com.squareup.okio:okio-bom:3.6.0", // applies to transitive dependencies of okhttp "io.grpc:grpc-bom:1.58.0", - "io.netty:netty-bom:4.1.99.Final", + "io.netty:netty-bom:4.1.100.Final", "io.zipkin.brave:brave-bom:5.16.0", "io.zipkin.reporter2:zipkin-reporter-bom:2.16.4", "org.assertj:assertj-bom:3.24.2", From 3c52cdf7f710568881baa13d5f6d502bb941382d Mon Sep 17 00:00:00 2001 From: Lauri Tulmin Date: Wed, 11 Oct 2023 21:42:06 +0300 Subject: [PATCH 051/901] Prometheus exporter: omit empty otel_scope_info and otel_target_info metrics (#5887) --- .../exporter/prometheus/Serializer.java | 8 ++++++ .../prometheus/PrometheusHttpServerTest.java | 27 ------------------- .../exporter/prometheus/SerializerTest.java | 26 +++++++++++++++--- 3 files changed, 31 insertions(+), 30 deletions(-) diff --git a/exporters/prometheus/src/main/java/io/opentelemetry/exporter/prometheus/Serializer.java b/exporters/prometheus/src/main/java/io/opentelemetry/exporter/prometheus/Serializer.java index c77923b80de..a7089d03abb 100644 --- a/exporters/prometheus/src/main/java/io/opentelemetry/exporter/prometheus/Serializer.java +++ b/exporters/prometheus/src/main/java/io/opentelemetry/exporter/prometheus/Serializer.java @@ -244,6 +244,10 @@ private static boolean isDeltaTemporality(MetricData metricData) { } private static void writeResource(Resource resource, Writer writer) throws IOException { + if (resource.getAttributes().isEmpty()) { + return; + } + writer.write("# TYPE target info\n"); writer.write("# HELP target Target metadata\n"); writer.write("target_info{"); @@ -253,6 +257,10 @@ private static void writeResource(Resource resource, Writer writer) throws IOExc private static void writeScopeInfo( InstrumentationScopeInfo instrumentationScopeInfo, Writer writer) throws IOException { + if (instrumentationScopeInfo.getAttributes().isEmpty()) { + return; + } + writer.write("# TYPE otel_scope_info info\n"); writer.write("# HELP otel_scope_info Scope metadata\n"); writer.write("otel_scope_info{"); diff --git a/exporters/prometheus/src/test/java/io/opentelemetry/exporter/prometheus/PrometheusHttpServerTest.java b/exporters/prometheus/src/test/java/io/opentelemetry/exporter/prometheus/PrometheusHttpServerTest.java index cbda79c4183..2c6245fd1d4 100644 --- a/exporters/prometheus/src/test/java/io/opentelemetry/exporter/prometheus/PrometheusHttpServerTest.java +++ b/exporters/prometheus/src/test/java/io/opentelemetry/exporter/prometheus/PrometheusHttpServerTest.java @@ -117,12 +117,6 @@ void fetchPrometheus(String endpoint) { "# TYPE target info\n" + "# HELP target Target metadata\n" + "target_info{kr=\"vr\"} 1\n" - + "# TYPE otel_scope_info info\n" - + "# HELP otel_scope_info Scope metadata\n" - + "otel_scope_info{otel_scope_name=\"grpc\",otel_scope_version=\"version\"} 1\n" - + "# TYPE otel_scope_info info\n" - + "# HELP otel_scope_info Scope metadata\n" - + "otel_scope_info{otel_scope_name=\"http\",otel_scope_version=\"version\"} 1\n" + "# TYPE grpc_name_total counter\n" + "# HELP grpc_name_total long_description\n" + "grpc_name_total{otel_scope_name=\"grpc\",otel_scope_version=\"version\",kp=\"vp\"} 5.0 0\n" @@ -152,12 +146,6 @@ void fetchOpenMetrics(String endpoint) { "# TYPE target info\n" + "# HELP target Target metadata\n" + "target_info{kr=\"vr\"} 1\n" - + "# TYPE otel_scope_info info\n" - + "# HELP otel_scope_info Scope metadata\n" - + "otel_scope_info{otel_scope_name=\"grpc\",otel_scope_version=\"version\"} 1\n" - + "# TYPE otel_scope_info info\n" - + "# HELP otel_scope_info Scope metadata\n" - + "otel_scope_info{otel_scope_name=\"http\",otel_scope_version=\"version\"} 1\n" + "# TYPE grpc_name counter\n" + "# HELP grpc_name long_description\n" + "grpc_name_total{otel_scope_name=\"grpc\",otel_scope_version=\"version\",kp=\"vp\"} 5.0 0.000\n" @@ -179,9 +167,6 @@ void fetchFiltered() { "# TYPE target info\n" + "# HELP target Target metadata\n" + "target_info{kr=\"vr\"} 1\n" - + "# TYPE otel_scope_info info\n" - + "# HELP otel_scope_info Scope metadata\n" - + "otel_scope_info{otel_scope_name=\"grpc\",otel_scope_version=\"version\"} 1\n" + "# TYPE grpc_name_total counter\n" + "# HELP grpc_name_total long_description\n" + "grpc_name_total{otel_scope_name=\"grpc\",otel_scope_version=\"version\",kp=\"vp\"} 5.0 0\n"); @@ -206,12 +191,6 @@ void fetchPrometheusCompressed() throws IOException { "# TYPE target info\n" + "# HELP target Target metadata\n" + "target_info{kr=\"vr\"} 1\n" - + "# TYPE otel_scope_info info\n" - + "# HELP otel_scope_info Scope metadata\n" - + "otel_scope_info{otel_scope_name=\"grpc\",otel_scope_version=\"version\"} 1\n" - + "# TYPE otel_scope_info info\n" - + "# HELP otel_scope_info Scope metadata\n" - + "otel_scope_info{otel_scope_name=\"http\",otel_scope_version=\"version\"} 1\n" + "# TYPE grpc_name_total counter\n" + "# HELP grpc_name_total long_description\n" + "grpc_name_total{otel_scope_name=\"grpc\",otel_scope_version=\"version\",kp=\"vp\"} 5.0 0\n" @@ -287,12 +266,6 @@ void fetch_DuplicateMetrics() { "# TYPE target info\n" + "# HELP target Target metadata\n" + "target_info{kr=\"vr\"} 1\n" - + "# TYPE otel_scope_info info\n" - + "# HELP otel_scope_info Scope metadata\n" - + "otel_scope_info{otel_scope_name=\"scope1\"} 1\n" - + "# TYPE otel_scope_info info\n" - + "# HELP otel_scope_info Scope metadata\n" - + "otel_scope_info{otel_scope_name=\"scope2\"} 1\n" + "# TYPE foo_unit_total counter\n" + "# HELP foo_unit_total description1\n" + "foo_unit_total{otel_scope_name=\"scope1\"} 1.0 0\n" diff --git a/exporters/prometheus/src/test/java/io/opentelemetry/exporter/prometheus/SerializerTest.java b/exporters/prometheus/src/test/java/io/opentelemetry/exporter/prometheus/SerializerTest.java index 210e399ac0f..b76c390eab7 100644 --- a/exporters/prometheus/src/test/java/io/opentelemetry/exporter/prometheus/SerializerTest.java +++ b/exporters/prometheus/src/test/java/io/opentelemetry/exporter/prometheus/SerializerTest.java @@ -241,9 +241,6 @@ void outOfOrderedAttributes() { "# TYPE target info\n" + "# HELP target Target metadata\n" + "target_info{kr=\"vr\"} 1\n" - + "# TYPE otel_scope_info info\n" - + "# HELP otel_scope_info Scope metadata\n" - + "otel_scope_info{otel_scope_name=\"scope\",otel_scope_version=\"1.0.0\"} 1\n" + "# TYPE sum_seconds_total counter\n" + "# HELP sum_seconds_total description\n" + "sum_seconds_total{otel_scope_name=\"scope\",otel_scope_version=\"1.0.0\",b_key=\"val1\",a_key=\"val2\",b_key=\"val3\"} 5.0 1633950672000\n"); @@ -251,6 +248,29 @@ void outOfOrderedAttributes() { "Dropping out-of-order attribute a_key=val2, which occurred after b_key. This can occur when an alternative Attribute implementation is used."); } + @Test + void emptyResource() { + MetricData metricData = + ImmutableMetricData.createDoubleSum( + Resource.empty(), + InstrumentationScopeInfo.builder("scope").setVersion("1.0.0").build(), + "monotonic.cumulative.double.sum", + "description", + "s", + ImmutableSumData.create( + /* isMonotonic= */ true, + AggregationTemporality.CUMULATIVE, + Collections.singletonList( + ImmutableDoublePointData.create( + 1633947011000000000L, 1633950672000000000L, Attributes.empty(), 5)))); + + assertThat(serialize004(metricData)) + .isEqualTo( + "# TYPE monotonic_cumulative_double_sum_seconds_total counter\n" + + "# HELP monotonic_cumulative_double_sum_seconds_total description\n" + + "monotonic_cumulative_double_sum_seconds_total{otel_scope_name=\"scope\",otel_scope_version=\"1.0.0\"} 5.0 1633950672000\n"); + } + private static String serialize004(MetricData... metrics) { ByteArrayOutputStream bos = new ByteArrayOutputStream(); try { From 3827ee1e5b9dd34db715a0f1675f59e40382f611 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 11 Oct 2023 14:05:39 -0500 Subject: [PATCH 052/901] Update dependency com.google.api.grpc:proto-google-common-protos to v2.26.0 (#5894) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- dependencyManagement/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index 2a66466b910..7e1f6a96a30 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -55,7 +55,7 @@ val DEPENDENCIES = listOf( "io.prometheus:simpleclient_httpserver:${prometheusClientVersion}", "javax.annotation:javax.annotation-api:1.3.2", "com.github.stefanbirkner:system-rules:1.19.0", - "com.google.api.grpc:proto-google-common-protos:2.25.1", + "com.google.api.grpc:proto-google-common-protos:2.26.0", "com.google.code.findbugs:jsr305:3.0.2", "com.google.guava:guava-beta-checker:1.0", "com.sun.net.httpserver:http:20070405", From 8b7780b7c464f640e48818a5bf3c25bd5abb610e Mon Sep 17 00:00:00 2001 From: Lauri Tulmin Date: Thu, 12 Oct 2023 17:50:32 +0300 Subject: [PATCH 053/901] Remove obsolete comment (#5909) --- buildSrc/build.gradle.kts | 1 - 1 file changed, 1 deletion(-) diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts index 34a1a20cd1c..aaa1db21f13 100644 --- a/buildSrc/build.gradle.kts +++ b/buildSrc/build.gradle.kts @@ -57,7 +57,6 @@ dependencies { implementation("me.champeau.jmh:jmh-gradle-plugin:0.7.1") implementation("net.ltgt.gradle:gradle-errorprone-plugin:3.1.0") implementation("net.ltgt.gradle:gradle-nullaway-plugin:1.6.0") - // at the moment 1.9.0 is the latest version supported by codeql implementation("org.jetbrains.kotlin:kotlin-gradle-plugin:1.9.10") implementation("org.owasp:dependency-check-gradle:8.4.0") implementation("ru.vyarus:gradle-animalsniffer-plugin:1.7.1") From ae770ec442cf861733d23a8c869530fc8693c3b4 Mon Sep 17 00:00:00 2001 From: Lauri Tulmin Date: Thu, 12 Oct 2023 17:50:46 +0300 Subject: [PATCH 054/901] Enable checking javadoc.io links (#5908) --- .github/config/markdown-link-check-config.json | 5 ----- 1 file changed, 5 deletions(-) diff --git a/.github/config/markdown-link-check-config.json b/.github/config/markdown-link-check-config.json index 0f74f443f52..a458029d5d9 100644 --- a/.github/config/markdown-link-check-config.json +++ b/.github/config/markdown-link-check-config.json @@ -3,10 +3,5 @@ "aliveStatusCodes": [ 200, 403 - ], - "ignorePatterns": [ - { - "pattern": "^https://(www\\.)?javadoc\\.io" - } ] } From 6bc24f4263811979249a94e6f5ca1ec5fe300b39 Mon Sep 17 00:00:00 2001 From: jack-berg <34418638+jack-berg@users.noreply.github.com> Date: Fri, 13 Oct 2023 10:36:29 -0500 Subject: [PATCH 055/901] Stop setting Resource schemaUrl in autoconfigure (#5911) --- .../opentelemetry/sdk/autoconfigure/ResourceConfiguration.java | 3 +-- .../sdk/autoconfigure/ResourceConfigurationTest.java | 1 - 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/ResourceConfiguration.java b/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/ResourceConfiguration.java index b431ad6c8d7..010d219acba 100644 --- a/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/ResourceConfiguration.java +++ b/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/ResourceConfiguration.java @@ -33,7 +33,6 @@ public final class ResourceConfiguration { private static final AttributeKey SERVICE_NAME = AttributeKey.stringKey("service.name"); - private static final String SCHEMA_URL = "https://opentelemetry.io/schemas/1.21.0"; // Visible for testing static final String ATTRIBUTE_PROPERTY = "otel.resource.attributes"; @@ -79,7 +78,7 @@ public static Resource createEnvironmentResource(ConfigProperties config) { resourceAttributes.put(SERVICE_NAME, serviceName); } - return Resource.create(resourceAttributes.build(), SCHEMA_URL); + return Resource.create(resourceAttributes.build()); } static Resource configureResource( diff --git a/sdk-extensions/autoconfigure/src/test/java/io/opentelemetry/sdk/autoconfigure/ResourceConfigurationTest.java b/sdk-extensions/autoconfigure/src/test/java/io/opentelemetry/sdk/autoconfigure/ResourceConfigurationTest.java index e5f34035c69..33cc9740639 100644 --- a/sdk-extensions/autoconfigure/src/test/java/io/opentelemetry/sdk/autoconfigure/ResourceConfigurationTest.java +++ b/sdk-extensions/autoconfigure/src/test/java/io/opentelemetry/sdk/autoconfigure/ResourceConfigurationTest.java @@ -43,7 +43,6 @@ void customConfigResource() { .put(stringKey("service.name"), "test-service") .put("food", "cheesecake") .put("shape", "square") - .setSchemaUrl("https://opentelemetry.io/schemas/1.21.0") .build()); } From 1453f3f1814a56c2719a089b4c96cb173f486e22 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 13 Oct 2023 10:36:49 -0500 Subject: [PATCH 056/901] Update dependency com.fasterxml.jackson:jackson-bom to v2.15.3 (#5913) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- dependencyManagement/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index 7e1f6a96a30..2888acddfae 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -8,7 +8,7 @@ val dependencyVersions = hashMapOf() rootProject.extra["versions"] = dependencyVersions val DEPENDENCY_BOMS = listOf( - "com.fasterxml.jackson:jackson-bom:2.15.2", + "com.fasterxml.jackson:jackson-bom:2.15.3", "com.google.guava:guava-bom:32.1.3-jre", "com.google.protobuf:protobuf-bom:3.24.4", "com.linecorp.armeria:armeria-bom:1.25.2", From a9da20f831d215f6653c567946d405d2e0f90971 Mon Sep 17 00:00:00 2001 From: jack-berg <34418638+jack-berg@users.noreply.github.com> Date: Fri, 13 Oct 2023 10:50:12 -0500 Subject: [PATCH 057/901] Cleanup opencensus shim (#5858) --- .../{internal/metrics => }/MetricAdapter.java | 13 +- .../OpenCensusMetricProducer.java | 3 +- .../OpenTelemetryContextManager.java | 1 + .../opencensusshim/OpenTelemetryCtx.java | 2 +- .../OpenTelemetryMetricsExporter.java | 83 --------- .../OpenTelemetryNoRecordEventsSpanImpl.java | 3 +- ...OpenTelemetryPropagationComponentImpl.java | 2 +- .../OpenTelemetrySpanBuilderImpl.java | 48 ++--- .../OpenTelemetryTextFormatImpl.java | 2 +- .../OpenTelemetryTraceComponentImpl.java | 4 +- .../OpenTelemetryTracerImpl.java | 4 +- .../ThreadLocalRandomHandler.java | 4 +- .../metrics => }/MetricAdapterTest.java | 2 +- .../OpenCensusMetricProducerTest.java | 3 +- .../{metrics => }/OpenCensusMetricsTest.java | 3 +- .../OpenTelemetryMetricExporterTest.java | 174 ------------------ 16 files changed, 44 insertions(+), 307 deletions(-) rename opencensus-shim/src/main/java/io/opentelemetry/opencensusshim/{internal/metrics => }/MetricAdapter.java (97%) delete mode 100644 opencensus-shim/src/main/java/io/opentelemetry/opencensusshim/OpenTelemetryMetricsExporter.java rename opencensus-shim/src/test/java/io/opentelemetry/opencensusshim/{internal/metrics => }/MetricAdapterTest.java (99%) rename opencensus-shim/src/test/java/io/opentelemetry/opencensusshim/{metrics => }/OpenCensusMetricProducerTest.java (97%) rename opencensus-shim/src/test/java/io/opentelemetry/opencensusshim/{metrics => }/OpenCensusMetricsTest.java (94%) delete mode 100644 opencensus-shim/src/test/java/io/opentelemetry/opencensusshim/OpenTelemetryMetricExporterTest.java diff --git a/opencensus-shim/src/main/java/io/opentelemetry/opencensusshim/internal/metrics/MetricAdapter.java b/opencensus-shim/src/main/java/io/opentelemetry/opencensusshim/MetricAdapter.java similarity index 97% rename from opencensus-shim/src/main/java/io/opentelemetry/opencensusshim/internal/metrics/MetricAdapter.java rename to opencensus-shim/src/main/java/io/opentelemetry/opencensusshim/MetricAdapter.java index 7ea80936d74..366f6786a4d 100644 --- a/opencensus-shim/src/main/java/io/opentelemetry/opencensusshim/internal/metrics/MetricAdapter.java +++ b/opencensus-shim/src/main/java/io/opentelemetry/opencensusshim/MetricAdapter.java @@ -3,7 +3,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -package io.opentelemetry.opencensusshim.internal.metrics; +package io.opentelemetry.opencensusshim; import io.opencensus.common.Timestamp; import io.opencensus.metrics.LabelKey; @@ -55,13 +55,8 @@ import java.util.regex.Pattern; import javax.annotation.Nullable; -/** - * Adapts an OpenCensus metric into the OpenTelemetry metric data API. - * - *

    This class is internal and is hence not for public use. Its APIs are unstable and can change - * at any time. - */ -public final class MetricAdapter { +/** Adapts an OpenCensus metric into the OpenTelemetry metric data API. */ +final class MetricAdapter { private MetricAdapter() {} // All OpenCensus metrics come from this shim. @@ -81,7 +76,7 @@ private MetricAdapter() {} * @param otelResource The resource associated with the opentelemetry SDK. * @param censusMetric The OpenCensus metric to convert. */ - public static MetricData convert(Resource otelResource, Metric censusMetric) { + static MetricData convert(Resource otelResource, Metric censusMetric) { // Note: we can't just adapt interfaces, we need to do full copy because OTel data API uses // auto-value vs. pure interfaces. switch (censusMetric.getMetricDescriptor().getType()) { diff --git a/opencensus-shim/src/main/java/io/opentelemetry/opencensusshim/OpenCensusMetricProducer.java b/opencensus-shim/src/main/java/io/opentelemetry/opencensusshim/OpenCensusMetricProducer.java index 9a2e29a2bc2..121c61360f1 100644 --- a/opencensus-shim/src/main/java/io/opentelemetry/opencensusshim/OpenCensusMetricProducer.java +++ b/opencensus-shim/src/main/java/io/opentelemetry/opencensusshim/OpenCensusMetricProducer.java @@ -7,7 +7,6 @@ import io.opencensus.metrics.Metrics; import io.opencensus.metrics.export.MetricProducerManager; -import io.opentelemetry.opencensusshim.internal.metrics.MetricAdapter; import io.opentelemetry.sdk.metrics.SdkMeterProviderBuilder; import io.opentelemetry.sdk.metrics.data.MetricData; import io.opentelemetry.sdk.metrics.export.MetricProducer; @@ -26,7 +25,7 @@ public final class OpenCensusMetricProducer implements MetricProducer { private final MetricProducerManager openCensusMetricStorage; - OpenCensusMetricProducer(MetricProducerManager openCensusMetricStorage) { + private OpenCensusMetricProducer(MetricProducerManager openCensusMetricStorage) { this.openCensusMetricStorage = openCensusMetricStorage; } diff --git a/opencensus-shim/src/main/java/io/opentelemetry/opencensusshim/OpenTelemetryContextManager.java b/opencensus-shim/src/main/java/io/opentelemetry/opencensusshim/OpenTelemetryContextManager.java index d73e41ab5dd..24d9818645c 100644 --- a/opencensus-shim/src/main/java/io/opentelemetry/opencensusshim/OpenTelemetryContextManager.java +++ b/opencensus-shim/src/main/java/io/opentelemetry/opencensusshim/OpenTelemetryContextManager.java @@ -22,6 +22,7 @@ public final class OpenTelemetryContextManager implements ContextManager { private static final Logger LOGGER = Logger.getLogger(OpenTelemetryContextManager.class.getName()); + @SuppressWarnings("unused") // Loaded via reflection public OpenTelemetryContextManager() {} @Override diff --git a/opencensus-shim/src/main/java/io/opentelemetry/opencensusshim/OpenTelemetryCtx.java b/opencensus-shim/src/main/java/io/opentelemetry/opencensusshim/OpenTelemetryCtx.java index ae94f630713..a551597186f 100644 --- a/opencensus-shim/src/main/java/io/opentelemetry/opencensusshim/OpenTelemetryCtx.java +++ b/opencensus-shim/src/main/java/io/opentelemetry/opencensusshim/OpenTelemetryCtx.java @@ -10,7 +10,7 @@ import io.opentelemetry.context.Scope; import javax.annotation.Nullable; -class OpenTelemetryCtx implements ContextHandle { +final class OpenTelemetryCtx implements ContextHandle { private final Context context; diff --git a/opencensus-shim/src/main/java/io/opentelemetry/opencensusshim/OpenTelemetryMetricsExporter.java b/opencensus-shim/src/main/java/io/opentelemetry/opencensusshim/OpenTelemetryMetricsExporter.java deleted file mode 100644 index 32783892204..00000000000 --- a/opencensus-shim/src/main/java/io/opentelemetry/opencensusshim/OpenTelemetryMetricsExporter.java +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package io.opentelemetry.opencensusshim; - -import com.google.common.base.Joiner; -import io.opencensus.common.Duration; -import io.opencensus.exporter.metrics.util.IntervalMetricReader; -import io.opencensus.exporter.metrics.util.MetricExporter; -import io.opencensus.exporter.metrics.util.MetricReader; -import io.opencensus.metrics.Metrics; -import io.opencensus.metrics.export.Metric; -import io.opencensus.metrics.export.MetricDescriptor; -import io.opentelemetry.opencensusshim.internal.metrics.MetricAdapter; -import io.opentelemetry.sdk.metrics.data.MetricData; -import io.opentelemetry.sdk.resources.Resource; -import java.util.ArrayList; -import java.util.Collection; -import java.util.HashSet; -import java.util.List; -import java.util.Set; -import java.util.logging.Logger; - -@Deprecated -public final class OpenTelemetryMetricsExporter extends MetricExporter { - private static final Logger LOGGER = - Logger.getLogger(OpenTelemetryMetricsExporter.class.getName()); - - private static final String EXPORTER_NAME = "OpenTelemetryMetricExporter"; - - private final IntervalMetricReader intervalMetricReader; - private final io.opentelemetry.sdk.metrics.export.MetricExporter otelExporter; - // TODO - find this from OTel SDK. - private final Resource resource = Resource.getDefault(); - - public static OpenTelemetryMetricsExporter createAndRegister( - io.opentelemetry.sdk.metrics.export.MetricExporter otelExporter) { - return new OpenTelemetryMetricsExporter(otelExporter, Duration.create(60, 0)); - } - - public static OpenTelemetryMetricsExporter createAndRegister( - io.opentelemetry.sdk.metrics.export.MetricExporter otelExporter, Duration exportInterval) { - return new OpenTelemetryMetricsExporter(otelExporter, exportInterval); - } - - private OpenTelemetryMetricsExporter( - io.opentelemetry.sdk.metrics.export.MetricExporter otelExporter, Duration exportInterval) { - this.otelExporter = otelExporter; - IntervalMetricReader.Options.Builder options = IntervalMetricReader.Options.builder(); - MetricReader reader = - MetricReader.create( - MetricReader.Options.builder() - .setMetricProducerManager(Metrics.getExportComponent().getMetricProducerManager()) - .setSpanName(EXPORTER_NAME) - .build()); - intervalMetricReader = - IntervalMetricReader.create( - this, reader, options.setExportInterval(exportInterval).build()); - } - - @Override - public void export(Collection metrics) { - List metricData = new ArrayList<>(); - Set unsupportedTypes = new HashSet<>(); - for (Metric metric : metrics) { - metricData.add(MetricAdapter.convert(resource, metric)); - } - if (!unsupportedTypes.isEmpty()) { - LOGGER.warning( - Joiner.on(",").join(unsupportedTypes) - + " not supported by OpenCensus to OpenTelemetry migrator."); - } - if (!metricData.isEmpty()) { - otelExporter.export(metricData); - } - } - - public void stop() { - intervalMetricReader.stop(); - } -} diff --git a/opencensus-shim/src/main/java/io/opentelemetry/opencensusshim/OpenTelemetryNoRecordEventsSpanImpl.java b/opencensus-shim/src/main/java/io/opentelemetry/opencensusshim/OpenTelemetryNoRecordEventsSpanImpl.java index b6f3e8eec11..1e18beb8ce4 100644 --- a/opencensus-shim/src/main/java/io/opentelemetry/opencensusshim/OpenTelemetryNoRecordEventsSpanImpl.java +++ b/opencensus-shim/src/main/java/io/opentelemetry/opencensusshim/OpenTelemetryNoRecordEventsSpanImpl.java @@ -39,7 +39,8 @@ import java.util.concurrent.TimeUnit; import javax.annotation.Nonnull; -class OpenTelemetryNoRecordEventsSpanImpl extends Span implements io.opentelemetry.api.trace.Span { +final class OpenTelemetryNoRecordEventsSpanImpl extends Span + implements io.opentelemetry.api.trace.Span { private static final EnumSet NOT_RECORD_EVENTS_SPAN_OPTIONS = EnumSet.noneOf(Options.class); diff --git a/opencensus-shim/src/main/java/io/opentelemetry/opencensusshim/OpenTelemetryPropagationComponentImpl.java b/opencensus-shim/src/main/java/io/opentelemetry/opencensusshim/OpenTelemetryPropagationComponentImpl.java index 6898345ebd0..a4d77541675 100644 --- a/opencensus-shim/src/main/java/io/opentelemetry/opencensusshim/OpenTelemetryPropagationComponentImpl.java +++ b/opencensus-shim/src/main/java/io/opentelemetry/opencensusshim/OpenTelemetryPropagationComponentImpl.java @@ -10,7 +10,7 @@ import io.opentelemetry.api.trace.propagation.W3CTraceContextPropagator; import io.opentelemetry.extension.trace.propagation.B3Propagator; -class OpenTelemetryPropagationComponentImpl extends PropagationComponentImpl { +final class OpenTelemetryPropagationComponentImpl extends PropagationComponentImpl { private final TextFormat b3Format = new OpenTelemetryTextFormatImpl(B3Propagator.injectingMultiHeaders()); diff --git a/opencensus-shim/src/main/java/io/opentelemetry/opencensusshim/OpenTelemetrySpanBuilderImpl.java b/opencensus-shim/src/main/java/io/opentelemetry/opencensusshim/OpenTelemetrySpanBuilderImpl.java index bd09e9b66f1..ede66642e06 100644 --- a/opencensus-shim/src/main/java/io/opentelemetry/opencensusshim/OpenTelemetrySpanBuilderImpl.java +++ b/opencensus-shim/src/main/java/io/opentelemetry/opencensusshim/OpenTelemetrySpanBuilderImpl.java @@ -48,7 +48,7 @@ import java.util.Random; import javax.annotation.Nullable; -class OpenTelemetrySpanBuilderImpl extends SpanBuilder { +final class OpenTelemetrySpanBuilderImpl extends SpanBuilder { private static final Tracer OTEL_TRACER = GlobalOpenTelemetry.getTracer("io.opentelemetry.opencensusshim", OtelVersion.VERSION); @@ -68,6 +68,29 @@ class OpenTelemetrySpanBuilderImpl extends SpanBuilder { @Nullable private Sampler ocSampler; @Nullable private SpanKind otelKind; + private OpenTelemetrySpanBuilderImpl( + String name, + @Nullable SpanContext ocRemoteParentSpanContext, + @Nullable Span ocParent, + OpenTelemetrySpanBuilderImpl.Options options) { + this.name = checkNotNull(name, "name"); + this.ocParent = ocParent; + this.ocRemoteParentSpanContext = ocRemoteParentSpanContext; + this.options = options; + } + + static OpenTelemetrySpanBuilderImpl createWithParent( + String spanName, @Nullable Span parent, OpenTelemetrySpanBuilderImpl.Options options) { + return new OpenTelemetrySpanBuilderImpl(spanName, null, parent, options); + } + + static OpenTelemetrySpanBuilderImpl createWithRemoteParent( + String spanName, + @Nullable SpanContext remoteParentSpanContext, + OpenTelemetrySpanBuilderImpl.Options options) { + return new OpenTelemetrySpanBuilderImpl(spanName, remoteParentSpanContext, null, options); + } + @Override public SpanBuilder setSampler(Sampler sampler) { this.ocSampler = checkNotNull(sampler, "sampler"); @@ -155,29 +178,6 @@ public Span startSpan() { return new OpenTelemetrySpanImpl(otSpan); } - private OpenTelemetrySpanBuilderImpl( - String name, - @Nullable SpanContext ocRemoteParentSpanContext, - @Nullable Span ocParent, - OpenTelemetrySpanBuilderImpl.Options options) { - this.name = checkNotNull(name, "name"); - this.ocParent = ocParent; - this.ocRemoteParentSpanContext = ocRemoteParentSpanContext; - this.options = options; - } - - static OpenTelemetrySpanBuilderImpl createWithParent( - String spanName, @Nullable Span parent, OpenTelemetrySpanBuilderImpl.Options options) { - return new OpenTelemetrySpanBuilderImpl(spanName, null, parent, options); - } - - static OpenTelemetrySpanBuilderImpl createWithRemoteParent( - String spanName, - @Nullable SpanContext remoteParentSpanContext, - OpenTelemetrySpanBuilderImpl.Options options) { - return new OpenTelemetrySpanBuilderImpl(spanName, remoteParentSpanContext, null, options); - } - private static boolean makeSamplingDecision( @Nullable SpanContext parent, @Nullable Boolean hasRemoteParent, diff --git a/opencensus-shim/src/main/java/io/opentelemetry/opencensusshim/OpenTelemetryTextFormatImpl.java b/opencensus-shim/src/main/java/io/opentelemetry/opencensusshim/OpenTelemetryTextFormatImpl.java index c8c2c3d4009..ac4d76f429d 100644 --- a/opencensus-shim/src/main/java/io/opentelemetry/opencensusshim/OpenTelemetryTextFormatImpl.java +++ b/opencensus-shim/src/main/java/io/opentelemetry/opencensusshim/OpenTelemetryTextFormatImpl.java @@ -18,7 +18,7 @@ import java.util.List; import javax.annotation.Nullable; -class OpenTelemetryTextFormatImpl extends TextFormat { +final class OpenTelemetryTextFormatImpl extends TextFormat { private final TextMapPropagator propagator; diff --git a/opencensus-shim/src/main/java/io/opentelemetry/opencensusshim/OpenTelemetryTraceComponentImpl.java b/opencensus-shim/src/main/java/io/opentelemetry/opencensusshim/OpenTelemetryTraceComponentImpl.java index 4859dd9ca1f..503220353b4 100644 --- a/opencensus-shim/src/main/java/io/opentelemetry/opencensusshim/OpenTelemetryTraceComponentImpl.java +++ b/opencensus-shim/src/main/java/io/opentelemetry/opencensusshim/OpenTelemetryTraceComponentImpl.java @@ -30,7 +30,7 @@ public final class OpenTelemetryTraceComponentImpl extends TraceComponent { private final TraceConfig traceConfig = makeTraceConfig(); private final Tracer tracer; - /** Public constructor to be used with reflection loading. */ + @SuppressWarnings("unused") // Loaded via reflection public OpenTelemetryTraceComponentImpl() { clock = MillisClock.getInstance(); RandomHandler randomHandler = new ThreadLocalRandomHandler(); @@ -48,7 +48,7 @@ public PropagationComponent getPropagationComponent() { } @Override - public final Clock getClock() { + public Clock getClock() { return clock; } diff --git a/opencensus-shim/src/main/java/io/opentelemetry/opencensusshim/OpenTelemetryTracerImpl.java b/opencensus-shim/src/main/java/io/opentelemetry/opencensusshim/OpenTelemetryTracerImpl.java index c3ba98b67fd..4bffa46fc26 100644 --- a/opencensus-shim/src/main/java/io/opentelemetry/opencensusshim/OpenTelemetryTracerImpl.java +++ b/opencensus-shim/src/main/java/io/opentelemetry/opencensusshim/OpenTelemetryTracerImpl.java @@ -30,10 +30,10 @@ import io.opencensus.trace.config.TraceConfig; import javax.annotation.Nullable; -class OpenTelemetryTracerImpl extends Tracer { +final class OpenTelemetryTracerImpl extends Tracer { private final OpenTelemetrySpanBuilderImpl.Options spanBuilderOptions; - public OpenTelemetryTracerImpl(RandomHandler randomHandler, TraceConfig traceConfig) { + OpenTelemetryTracerImpl(RandomHandler randomHandler, TraceConfig traceConfig) { spanBuilderOptions = new OpenTelemetrySpanBuilderImpl.Options(randomHandler, traceConfig); } diff --git a/opencensus-shim/src/main/java/io/opentelemetry/opencensusshim/ThreadLocalRandomHandler.java b/opencensus-shim/src/main/java/io/opentelemetry/opencensusshim/ThreadLocalRandomHandler.java index 76b1567d2bf..942a06c8856 100644 --- a/opencensus-shim/src/main/java/io/opentelemetry/opencensusshim/ThreadLocalRandomHandler.java +++ b/opencensus-shim/src/main/java/io/opentelemetry/opencensusshim/ThreadLocalRandomHandler.java @@ -15,10 +15,10 @@ * implementation in opencensus-impl, however we do not want to depend on opencensus-impl here. */ @ThreadSafe -public final class ThreadLocalRandomHandler extends RandomHandler { +final class ThreadLocalRandomHandler extends RandomHandler { /** Constructs a new {@code ThreadLocalRandomHandler}. */ - public ThreadLocalRandomHandler() {} + ThreadLocalRandomHandler() {} @Override public Random current() { diff --git a/opencensus-shim/src/test/java/io/opentelemetry/opencensusshim/internal/metrics/MetricAdapterTest.java b/opencensus-shim/src/test/java/io/opentelemetry/opencensusshim/MetricAdapterTest.java similarity index 99% rename from opencensus-shim/src/test/java/io/opentelemetry/opencensusshim/internal/metrics/MetricAdapterTest.java rename to opencensus-shim/src/test/java/io/opentelemetry/opencensusshim/MetricAdapterTest.java index 9d1a582aa44..7022477dce6 100644 --- a/opencensus-shim/src/test/java/io/opentelemetry/opencensusshim/internal/metrics/MetricAdapterTest.java +++ b/opencensus-shim/src/test/java/io/opentelemetry/opencensusshim/MetricAdapterTest.java @@ -3,7 +3,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -package io.opentelemetry.opencensusshim.internal.metrics; +package io.opentelemetry.opencensusshim; import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.assertThat; import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.attributeEntry; diff --git a/opencensus-shim/src/test/java/io/opentelemetry/opencensusshim/metrics/OpenCensusMetricProducerTest.java b/opencensus-shim/src/test/java/io/opentelemetry/opencensusshim/OpenCensusMetricProducerTest.java similarity index 97% rename from opencensus-shim/src/test/java/io/opentelemetry/opencensusshim/metrics/OpenCensusMetricProducerTest.java rename to opencensus-shim/src/test/java/io/opentelemetry/opencensusshim/OpenCensusMetricProducerTest.java index c2465522296..67996be5e06 100644 --- a/opencensus-shim/src/test/java/io/opentelemetry/opencensusshim/metrics/OpenCensusMetricProducerTest.java +++ b/opencensus-shim/src/test/java/io/opentelemetry/opencensusshim/OpenCensusMetricProducerTest.java @@ -3,7 +3,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -package io.opentelemetry.opencensusshim.metrics; +package io.opentelemetry.opencensusshim; import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.assertThat; @@ -21,7 +21,6 @@ import io.opencensus.trace.TraceOptions; import io.opencensus.trace.Tracestate; import io.opentelemetry.api.common.Attributes; -import io.opentelemetry.opencensusshim.OpenCensusMetricProducer; import io.opentelemetry.sdk.metrics.export.MetricProducer; import io.opentelemetry.sdk.resources.Resource; import java.time.Duration; diff --git a/opencensus-shim/src/test/java/io/opentelemetry/opencensusshim/metrics/OpenCensusMetricsTest.java b/opencensus-shim/src/test/java/io/opentelemetry/opencensusshim/OpenCensusMetricsTest.java similarity index 94% rename from opencensus-shim/src/test/java/io/opentelemetry/opencensusshim/metrics/OpenCensusMetricsTest.java rename to opencensus-shim/src/test/java/io/opentelemetry/opencensusshim/OpenCensusMetricsTest.java index 368e08ccb2f..4539045c435 100644 --- a/opencensus-shim/src/test/java/io/opentelemetry/opencensusshim/metrics/OpenCensusMetricsTest.java +++ b/opencensus-shim/src/test/java/io/opentelemetry/opencensusshim/OpenCensusMetricsTest.java @@ -3,7 +3,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -package io.opentelemetry.opencensusshim.metrics; +package io.opentelemetry.opencensusshim; import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.assertThat; @@ -12,7 +12,6 @@ import io.opencensus.stats.Stats; import io.opencensus.stats.StatsRecorder; import io.opencensus.stats.View; -import io.opentelemetry.opencensusshim.OpenCensusMetricProducer; import io.opentelemetry.sdk.metrics.SdkMeterProvider; import io.opentelemetry.sdk.testing.exporter.InMemoryMetricReader; import java.time.Duration; diff --git a/opencensus-shim/src/test/java/io/opentelemetry/opencensusshim/OpenTelemetryMetricExporterTest.java b/opencensus-shim/src/test/java/io/opentelemetry/opencensusshim/OpenTelemetryMetricExporterTest.java deleted file mode 100644 index c0bce937a18..00000000000 --- a/opencensus-shim/src/test/java/io/opentelemetry/opencensusshim/OpenTelemetryMetricExporterTest.java +++ /dev/null @@ -1,174 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package io.opentelemetry.opencensusshim; - -import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.assertThat; -import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.attributeEntry; -import static java.util.stream.Collectors.groupingBy; - -import com.google.common.collect.ImmutableList; -import io.opencensus.common.Duration; -import io.opencensus.stats.Aggregation; -import io.opencensus.stats.Measure; -import io.opencensus.stats.Stats; -import io.opencensus.stats.StatsRecorder; -import io.opencensus.stats.View; -import io.opencensus.stats.ViewManager; -import io.opencensus.tags.TagContext; -import io.opencensus.tags.TagKey; -import io.opencensus.tags.TagMetadata; -import io.opencensus.tags.TagValue; -import io.opencensus.tags.Tagger; -import io.opencensus.tags.Tags; -import io.opentelemetry.api.common.Attributes; -import io.opentelemetry.sdk.metrics.data.MetricData; -import io.opentelemetry.sdk.testing.exporter.InMemoryMetricExporter; -import java.util.HashSet; -import java.util.Set; -import java.util.stream.Collectors; -import org.awaitility.Awaitility; -import org.junit.jupiter.api.Test; - -class OpenTelemetryMetricExporterTest { - - @Test - @SuppressWarnings({"deprecation"}) // Summary is deprecated in census - void testSupportedMetricsExportedCorrectly() { - Tagger tagger = Tags.getTagger(); - Measure.MeasureLong latency = - Measure.MeasureLong.create("task_latency", "The task latency in milliseconds", "ms"); - Measure.MeasureDouble latency2 = - Measure.MeasureDouble.create("task_latency_2", "The task latency in milliseconds 2", "ms"); - StatsRecorder statsRecorder = Stats.getStatsRecorder(); - TagKey tagKey = TagKey.create("tagKey"); - TagValue tagValue = TagValue.create("tagValue"); - View longSumView = - View.create( - View.Name.create("long_sum"), - "long sum", - latency, - Aggregation.Sum.create(), - ImmutableList.of(tagKey)); - View longGaugeView = - View.create( - View.Name.create("long_gauge"), - "long gauge", - latency, - Aggregation.LastValue.create(), - ImmutableList.of(tagKey)); - View doubleSumView = - View.create( - View.Name.create("double_sum"), - "double sum", - latency2, - Aggregation.Sum.create(), - ImmutableList.of()); - View doubleGaugeView = - View.create( - View.Name.create("double_gauge"), - "double gauge", - latency2, - Aggregation.LastValue.create(), - ImmutableList.of()); - ViewManager viewManager = Stats.getViewManager(); - viewManager.registerView(longSumView); - viewManager.registerView(longGaugeView); - viewManager.registerView(doubleSumView); - viewManager.registerView(doubleGaugeView); - // Create OpenCensus -> OpenTelemetry Exporter bridge - InMemoryMetricExporter exporter = InMemoryMetricExporter.create(); - OpenTelemetryMetricsExporter otelExporter = - OpenTelemetryMetricsExporter.createAndRegister(exporter, Duration.create(1, 0)); - try { - TagContext tagContext = - tagger - .emptyBuilder() - .put(tagKey, tagValue, TagMetadata.create(TagMetadata.TagTtl.UNLIMITED_PROPAGATION)) - .build(); - try (io.opencensus.common.Scope ss = tagger.withTagContext(tagContext)) { - statsRecorder.newMeasureMap().put(latency, 50).record(); - statsRecorder.newMeasureMap().put(latency2, 60).record(); - } - Set allowedMetrics = new HashSet<>(); - allowedMetrics.add("double_gauge"); - allowedMetrics.add("double_sum"); - allowedMetrics.add("long_gauge"); - allowedMetrics.add("long_sum"); - // Slow down for OpenCensus to catch up. - Awaitility.await() - .atMost(java.time.Duration.ofSeconds(10)) - .untilAsserted( - () -> - assertThat( - // Filter for metrics with name in allowedMetrics, and dedupe to only one - // metric per unique metric name - exporter.getFinishedMetricItems().stream() - .filter(metric -> allowedMetrics.contains(metric.getName())) - .collect(groupingBy(MetricData::getName)) - .values() - .stream() - .map(metricData -> metricData.get(0)) - .collect(Collectors.toList())) - .satisfiesExactlyInAnyOrder( - metric -> - assertThat(metric) - .hasName("double_gauge") - .hasDescription("double gauge") - .hasUnit("ms") - .hasDoubleGaugeSatisfying( - gauge -> - gauge.hasPointsSatisfying( - point -> - point - .hasValue(60) - .hasAttributes(Attributes.empty()))), - metric -> - assertThat(metric) - .hasName("double_sum") - .hasDescription("double sum") - .hasUnit("ms") - .hasDoubleSumSatisfying( - sum -> - sum.hasPointsSatisfying( - point -> - point - .hasValue(60) - .hasAttributes(Attributes.empty()))), - metric -> - assertThat(metric) - .hasName("long_gauge") - .hasDescription("long gauge") - .hasUnit("ms") - .hasLongGaugeSatisfying( - gauge -> - gauge.hasPointsSatisfying( - point -> - point - .hasValue(50) - .hasAttributes( - attributeEntry( - tagKey.getName(), - tagValue.asString())))), - metric -> - assertThat(metric) - .hasName("long_sum") - .hasDescription("long sum") - .hasUnit("ms") - .hasLongSumSatisfying( - sum -> - sum.hasPointsSatisfying( - point -> - point - .hasValue(50) - .hasAttributes( - attributeEntry( - tagKey.getName(), - tagValue.asString())))))); - } finally { - otelExporter.stop(); - } - } -} From 57d83344178f578eb5d2f043b0ffc5c42b6719a5 Mon Sep 17 00:00:00 2001 From: jason plumb <75337021+breedx-splk@users.noreply.github.com> Date: Fri, 13 Oct 2023 12:24:05 -0700 Subject: [PATCH 058/901] Dismantle AbstractInstrumentBuilder inheritance hierarchy (#5820) --- ...entBuilder.java => InstrumentBuilder.java} | 116 ++++++++---------- .../sdk/metrics/SdkDoubleCounter.java | 50 +++++--- .../sdk/metrics/SdkDoubleGauge.java | 47 ++++--- .../sdk/metrics/SdkDoubleHistogram.java | 44 ++++--- .../sdk/metrics/SdkDoubleUpDownCounter.java | 48 +++++--- .../sdk/metrics/SdkLongCounter.java | 45 ++++--- .../sdk/metrics/SdkLongGauge.java | 50 +++++--- .../sdk/metrics/SdkLongHistogram.java | 46 ++++--- .../sdk/metrics/SdkLongUpDownCounter.java | 46 ++++--- .../AbstractInstrumentBuilderTest.java | 67 ---------- .../sdk/metrics/InstrumentBuilderTest.java | 81 ++++++++++++ 11 files changed, 372 insertions(+), 268 deletions(-) rename sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/{AbstractInstrumentBuilder.java => InstrumentBuilder.java} (59%) delete mode 100644 sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/AbstractInstrumentBuilderTest.java create mode 100644 sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/InstrumentBuilderTest.java diff --git a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/AbstractInstrumentBuilder.java b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/InstrumentBuilder.java similarity index 59% rename from sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/AbstractInstrumentBuilder.java rename to sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/InstrumentBuilder.java index db6a552bad2..f1da522e15b 100644 --- a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/AbstractInstrumentBuilder.java +++ b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/InstrumentBuilder.java @@ -5,6 +5,7 @@ package io.opentelemetry.sdk.metrics; +import io.opentelemetry.api.common.AttributeKey; import io.opentelemetry.api.metrics.ObservableDoubleMeasurement; import io.opentelemetry.api.metrics.ObservableLongMeasurement; import io.opentelemetry.sdk.metrics.internal.descriptor.Advice; @@ -15,95 +16,64 @@ import io.opentelemetry.sdk.metrics.internal.state.SdkObservableMeasurement; import io.opentelemetry.sdk.metrics.internal.state.WriteableMetricStorage; import java.util.Collections; +import java.util.List; import java.util.function.BiFunction; import java.util.function.Consumer; /** Helper to make implementing builders easier. */ -abstract class AbstractInstrumentBuilder> { - - static final String DEFAULT_UNIT = ""; +final class InstrumentBuilder { + private final String name; private final MeterProviderSharedState meterProviderSharedState; - private final InstrumentType type; + private final MeterSharedState meterSharedState; private final InstrumentValueType valueType; - private String description; - private String unit; - - protected final MeterSharedState meterSharedState; - protected final String instrumentName; - protected final Advice.AdviceBuilder adviceBuilder; + private InstrumentType type; + private Advice.AdviceBuilder adviceBuilder = Advice.builder(); + private String description = ""; + private String unit = ""; - AbstractInstrumentBuilder( - MeterProviderSharedState meterProviderSharedState, - MeterSharedState meterSharedState, - InstrumentType type, - InstrumentValueType valueType, + InstrumentBuilder( String name, - String description, - String unit) { - this( - meterProviderSharedState, - meterSharedState, - type, - valueType, - name, - description, - unit, - Advice.builder()); - } - - AbstractInstrumentBuilder( - MeterProviderSharedState meterProviderSharedState, - MeterSharedState meterSharedState, InstrumentType type, InstrumentValueType valueType, - String name, - String description, - String unit, - Advice.AdviceBuilder adviceBuilder) { + MeterProviderSharedState meterProviderSharedState, + MeterSharedState meterSharedState) { + this.name = name; this.type = type; this.valueType = valueType; - this.instrumentName = name; - this.description = description; - this.unit = unit; this.meterProviderSharedState = meterProviderSharedState; this.meterSharedState = meterSharedState; - this.adviceBuilder = adviceBuilder; } - protected abstract BuilderT getThis(); - - public BuilderT setUnit(String unit) { + InstrumentBuilder setUnit(String unit) { this.unit = unit; - return getThis(); + return this; + } + + InstrumentBuilder setAdviceBuilder(Advice.AdviceBuilder adviceBuilder) { + this.adviceBuilder = adviceBuilder; + return this; } - public BuilderT setDescription(String description) { + InstrumentBuilder setDescription(String description) { this.description = description; - return getThis(); + return this; } - protected T swapBuilder(SwapBuilder swapper) { + T swapBuilder(SwapBuilder swapper) { return swapper.newBuilder( - meterProviderSharedState, - meterSharedState, - instrumentName, - description, - unit, - adviceBuilder); + meterProviderSharedState, meterSharedState, name, description, unit, adviceBuilder); } - final I buildSynchronousInstrument( + I buildSynchronousInstrument( BiFunction instrumentFactory) { - InstrumentDescriptor descriptor = - InstrumentDescriptor.create( - instrumentName, description, unit, type, valueType, adviceBuilder.build()); + InstrumentDescriptor descriptor = newDescriptor(); WriteableMetricStorage storage = meterSharedState.registerSynchronousMetricStorage(descriptor, meterProviderSharedState); return instrumentFactory.apply(descriptor, storage); } - final SdkObservableInstrument registerDoubleAsynchronousInstrument( + SdkObservableInstrument buildDoubleAsynchronousInstrument( InstrumentType type, Consumer updater) { SdkObservableMeasurement sdkObservableMeasurement = buildObservableMeasurement(type); Runnable runnable = () -> updater.accept(sdkObservableMeasurement); @@ -113,7 +83,7 @@ final SdkObservableInstrument registerDoubleAsynchronousInstrument( return new SdkObservableInstrument(meterSharedState, callbackRegistration); } - final SdkObservableInstrument registerLongAsynchronousInstrument( + SdkObservableInstrument buildLongAsynchronousInstrument( InstrumentType type, Consumer updater) { SdkObservableMeasurement sdkObservableMeasurement = buildObservableMeasurement(type); Runnable runnable = () -> updater.accept(sdkObservableMeasurement); @@ -123,20 +93,24 @@ final SdkObservableInstrument registerLongAsynchronousInstrument( return new SdkObservableInstrument(meterSharedState, callbackRegistration); } - final SdkObservableMeasurement buildObservableMeasurement(InstrumentType type) { - InstrumentDescriptor descriptor = - InstrumentDescriptor.create( - instrumentName, description, unit, type, valueType, adviceBuilder.build()); + SdkObservableMeasurement buildObservableMeasurement(InstrumentType type) { + this.type = type; + InstrumentDescriptor descriptor = newDescriptor(); return meterSharedState.registerObservableMeasurement(descriptor); } + private InstrumentDescriptor newDescriptor() { + return InstrumentDescriptor.create( + name, description, unit, type, valueType, adviceBuilder.build()); + } + @Override public String toString() { - return this.getClass().getSimpleName() - + "{descriptor=" - + InstrumentDescriptor.create( - instrumentName, description, unit, type, valueType, adviceBuilder.build()) - + "}"; + return toStringHelper(getClass().getSimpleName()); + } + + String toStringHelper(String className) { + return className + "{descriptor=" + newDescriptor() + "}"; } @FunctionalInterface @@ -149,4 +123,12 @@ T newBuilder( String unit, Advice.AdviceBuilder adviceBuilder); } + + void setAdviceAttributes(List> attributes) { + adviceBuilder.setAttributes(attributes); + } + + void setExplicitBucketBoundaries(List bucketBoundaries) { + adviceBuilder.setExplicitBucketBoundaries(bucketBoundaries); + } } diff --git a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkDoubleCounter.java b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkDoubleCounter.java index 1b54f8a623d..d92cd29076c 100644 --- a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkDoubleCounter.java +++ b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkDoubleCounter.java @@ -8,6 +8,7 @@ import io.opentelemetry.api.common.AttributeKey; import io.opentelemetry.api.common.Attributes; import io.opentelemetry.api.metrics.DoubleCounter; +import io.opentelemetry.api.metrics.DoubleCounterBuilder; import io.opentelemetry.api.metrics.ObservableDoubleCounter; import io.opentelemetry.api.metrics.ObservableDoubleMeasurement; import io.opentelemetry.context.Context; @@ -57,9 +58,9 @@ public void add(double increment) { add(increment, Attributes.empty()); } - static final class SdkDoubleCounterBuilder - extends AbstractInstrumentBuilder - implements ExtendedDoubleCounterBuilder { + static final class SdkDoubleCounterBuilder implements ExtendedDoubleCounterBuilder { + + private final InstrumentBuilder builder; SdkDoubleCounterBuilder( MeterProviderSharedState meterProviderSharedState, @@ -68,42 +69,55 @@ static final class SdkDoubleCounterBuilder String description, String unit, Advice.AdviceBuilder adviceBuilder) { - super( - meterProviderSharedState, - sharedState, - InstrumentType.COUNTER, - InstrumentValueType.DOUBLE, - name, - description, - unit, - adviceBuilder); + this.builder = + new InstrumentBuilder( + name, + InstrumentType.COUNTER, + InstrumentValueType.DOUBLE, + meterProviderSharedState, + sharedState) + .setUnit(unit) + .setDescription(description) + .setAdviceBuilder(adviceBuilder); + } + + @Override + public SdkDoubleCounter build() { + return builder.buildSynchronousInstrument(SdkDoubleCounter::new); } @Override - protected SdkDoubleCounterBuilder getThis() { + public DoubleCounterBuilder setDescription(String description) { + builder.setDescription(description); return this; } @Override - public SdkDoubleCounter build() { - return buildSynchronousInstrument(SdkDoubleCounter::new); + public DoubleCounterBuilder setUnit(String unit) { + builder.setUnit(unit); + return this; } @Override public ObservableDoubleCounter buildWithCallback( Consumer callback) { - return registerDoubleAsynchronousInstrument(InstrumentType.OBSERVABLE_COUNTER, callback); + return builder.buildDoubleAsynchronousInstrument(InstrumentType.OBSERVABLE_COUNTER, callback); } @Override public ObservableDoubleMeasurement buildObserver() { - return buildObservableMeasurement(InstrumentType.OBSERVABLE_COUNTER); + return builder.buildObservableMeasurement(InstrumentType.OBSERVABLE_COUNTER); } @Override public ExtendedDoubleCounterBuilder setAttributesAdvice(List> attributes) { - adviceBuilder.setAttributes(attributes); + builder.setAdviceAttributes(attributes); return this; } + + @Override + public String toString() { + return builder.toStringHelper(getClass().getSimpleName()); + } } } diff --git a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkDoubleGauge.java b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkDoubleGauge.java index 008745b2652..e9f852510b5 100644 --- a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkDoubleGauge.java +++ b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkDoubleGauge.java @@ -7,6 +7,7 @@ import io.opentelemetry.api.common.AttributeKey; import io.opentelemetry.api.common.Attributes; +import io.opentelemetry.api.metrics.DoubleGaugeBuilder; import io.opentelemetry.api.metrics.LongGaugeBuilder; import io.opentelemetry.api.metrics.ObservableDoubleGauge; import io.opentelemetry.api.metrics.ObservableDoubleMeasurement; @@ -39,55 +40,67 @@ public void set(double increment) { set(increment, Attributes.empty()); } - static final class SdkDoubleGaugeBuilder extends AbstractInstrumentBuilder - implements ExtendedDoubleGaugeBuilder { + static final class SdkDoubleGaugeBuilder implements ExtendedDoubleGaugeBuilder { + private final InstrumentBuilder builder; SdkDoubleGaugeBuilder( MeterProviderSharedState meterProviderSharedState, MeterSharedState meterSharedState, String name) { - super( - meterProviderSharedState, - meterSharedState, - // TODO: use InstrumentType.GAUGE when available - InstrumentType.OBSERVABLE_GAUGE, - InstrumentValueType.DOUBLE, - name, - "", - DEFAULT_UNIT); + + // TODO: use InstrumentType.GAUGE when available + builder = + new InstrumentBuilder( + name, + InstrumentType.OBSERVABLE_GAUGE, + InstrumentValueType.DOUBLE, + meterProviderSharedState, + meterSharedState); } @Override - protected SdkDoubleGaugeBuilder getThis() { + public DoubleGaugeBuilder setDescription(String description) { + builder.setDescription(description); + return this; + } + + @Override + public DoubleGaugeBuilder setUnit(String unit) { + builder.setUnit(unit); return this; } @Override public SdkDoubleGauge build() { - return buildSynchronousInstrument(SdkDoubleGauge::new); + return builder.buildSynchronousInstrument(SdkDoubleGauge::new); } @Override public ExtendedDoubleGaugeBuilder setAttributesAdvice(List> attributes) { - adviceBuilder.setAttributes(attributes); + builder.setAdviceAttributes(attributes); return this; } @Override public LongGaugeBuilder ofLongs() { - return swapBuilder(SdkLongGauge.SdkLongGaugeBuilder::new); + return builder.swapBuilder(SdkLongGauge.SdkLongGaugeBuilder::new); } @Override public ObservableDoubleGauge buildWithCallback(Consumer callback) { // TODO: use InstrumentType.GAUGE when available - return registerDoubleAsynchronousInstrument(InstrumentType.OBSERVABLE_GAUGE, callback); + return builder.buildDoubleAsynchronousInstrument(InstrumentType.OBSERVABLE_GAUGE, callback); } @Override public ObservableDoubleMeasurement buildObserver() { // TODO: use InstrumentType.GAUGE when available - return buildObservableMeasurement(InstrumentType.OBSERVABLE_GAUGE); + return builder.buildObservableMeasurement(InstrumentType.OBSERVABLE_GAUGE); + } + + @Override + public String toString() { + return builder.toStringHelper(getClass().getSimpleName()); } } } diff --git a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkDoubleHistogram.java b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkDoubleHistogram.java index c2e8d9b4126..64a0daac68e 100644 --- a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkDoubleHistogram.java +++ b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkDoubleHistogram.java @@ -8,6 +8,7 @@ import io.opentelemetry.api.common.AttributeKey; import io.opentelemetry.api.common.Attributes; import io.opentelemetry.api.metrics.DoubleHistogram; +import io.opentelemetry.api.metrics.DoubleHistogramBuilder; import io.opentelemetry.api.metrics.LongHistogramBuilder; import io.opentelemetry.context.Context; import io.opentelemetry.extension.incubator.metrics.ExtendedDoubleHistogramBuilder; @@ -54,50 +55,61 @@ public void record(double value) { record(value, Attributes.empty()); } - static final class SdkDoubleHistogramBuilder - extends AbstractInstrumentBuilder - implements ExtendedDoubleHistogramBuilder { + static final class SdkDoubleHistogramBuilder implements ExtendedDoubleHistogramBuilder { + + private final InstrumentBuilder builder; SdkDoubleHistogramBuilder( MeterProviderSharedState meterProviderSharedState, MeterSharedState meterSharedState, String name) { - super( - meterProviderSharedState, - meterSharedState, - InstrumentType.HISTOGRAM, - InstrumentValueType.DOUBLE, - name, - "", - DEFAULT_UNIT); + builder = + new InstrumentBuilder( + name, + InstrumentType.HISTOGRAM, + InstrumentValueType.DOUBLE, + meterProviderSharedState, + meterSharedState); + } + + @Override + public DoubleHistogramBuilder setDescription(String description) { + builder.setDescription(description); + return this; } @Override - protected SdkDoubleHistogramBuilder getThis() { + public DoubleHistogramBuilder setUnit(String unit) { + builder.setUnit(unit); return this; } @Override public SdkDoubleHistogram build() { - return buildSynchronousInstrument(SdkDoubleHistogram::new); + return builder.buildSynchronousInstrument(SdkDoubleHistogram::new); } @Override public LongHistogramBuilder ofLongs() { - return swapBuilder(SdkLongHistogram.SdkLongHistogramBuilder::new); + return builder.swapBuilder(SdkLongHistogram.SdkLongHistogramBuilder::new); } @Override public ExtendedDoubleHistogramBuilder setExplicitBucketBoundariesAdvice( List bucketBoundaries) { - adviceBuilder.setExplicitBucketBoundaries(bucketBoundaries); + builder.setExplicitBucketBoundaries(bucketBoundaries); return this; } @Override public ExtendedDoubleHistogramBuilder setAttributesAdvice(List> attributes) { - adviceBuilder.setAttributes(attributes); + builder.setAdviceAttributes(attributes); return this; } + + @Override + public String toString() { + return builder.toStringHelper(getClass().getSimpleName()); + } } } diff --git a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkDoubleUpDownCounter.java b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkDoubleUpDownCounter.java index a11fd3f2f61..6521aeef871 100644 --- a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkDoubleUpDownCounter.java +++ b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkDoubleUpDownCounter.java @@ -8,6 +8,7 @@ import io.opentelemetry.api.common.AttributeKey; import io.opentelemetry.api.common.Attributes; import io.opentelemetry.api.metrics.DoubleUpDownCounter; +import io.opentelemetry.api.metrics.DoubleUpDownCounterBuilder; import io.opentelemetry.api.metrics.ObservableDoubleMeasurement; import io.opentelemetry.api.metrics.ObservableDoubleUpDownCounter; import io.opentelemetry.context.Context; @@ -44,9 +45,9 @@ public void add(double increment) { add(increment, Attributes.empty()); } - static final class SdkDoubleUpDownCounterBuilder - extends AbstractInstrumentBuilder - implements ExtendedDoubleUpDownCounterBuilder { + static final class SdkDoubleUpDownCounterBuilder implements ExtendedDoubleUpDownCounterBuilder { + + private final InstrumentBuilder builder; SdkDoubleUpDownCounterBuilder( MeterProviderSharedState meterProviderSharedState, @@ -55,44 +56,57 @@ static final class SdkDoubleUpDownCounterBuilder String description, String unit, Advice.AdviceBuilder adviceBuilder) { - super( - meterProviderSharedState, - sharedState, - InstrumentType.UP_DOWN_COUNTER, - InstrumentValueType.DOUBLE, - name, - description, - unit, - adviceBuilder); + this.builder = + new InstrumentBuilder( + name, + InstrumentType.UP_DOWN_COUNTER, + InstrumentValueType.DOUBLE, + meterProviderSharedState, + sharedState) + .setDescription(description) + .setUnit(unit) + .setAdviceBuilder(adviceBuilder); + } + + @Override + public DoubleUpDownCounterBuilder setDescription(String description) { + builder.setDescription(description); + return this; } @Override - protected SdkDoubleUpDownCounterBuilder getThis() { + public DoubleUpDownCounterBuilder setUnit(String unit) { + builder.setUnit(unit); return this; } @Override public DoubleUpDownCounter build() { - return buildSynchronousInstrument(SdkDoubleUpDownCounter::new); + return builder.buildSynchronousInstrument(SdkDoubleUpDownCounter::new); } @Override public ObservableDoubleUpDownCounter buildWithCallback( Consumer callback) { - return registerDoubleAsynchronousInstrument( + return builder.buildDoubleAsynchronousInstrument( InstrumentType.OBSERVABLE_UP_DOWN_COUNTER, callback); } @Override public ObservableDoubleMeasurement buildObserver() { - return buildObservableMeasurement(InstrumentType.OBSERVABLE_UP_DOWN_COUNTER); + return builder.buildObservableMeasurement(InstrumentType.OBSERVABLE_UP_DOWN_COUNTER); } @Override public ExtendedDoubleUpDownCounterBuilder setAttributesAdvice( List> attributes) { - adviceBuilder.setAttributes(attributes); + builder.setAdviceAttributes(attributes); return this; } + + @Override + public String toString() { + return builder.toStringHelper(getClass().getSimpleName()); + } } } diff --git a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkLongCounter.java b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkLongCounter.java index 58383d9e783..98f806165af 100644 --- a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkLongCounter.java +++ b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkLongCounter.java @@ -9,6 +9,7 @@ import io.opentelemetry.api.common.Attributes; import io.opentelemetry.api.metrics.DoubleCounterBuilder; import io.opentelemetry.api.metrics.LongCounter; +import io.opentelemetry.api.metrics.LongCounterBuilder; import io.opentelemetry.api.metrics.ObservableLongCounter; import io.opentelemetry.api.metrics.ObservableLongMeasurement; import io.opentelemetry.context.Context; @@ -58,52 +59,64 @@ public void add(long increment) { add(increment, Attributes.empty()); } - static final class SdkLongCounterBuilder extends AbstractInstrumentBuilder - implements ExtendedLongCounterBuilder { + static final class SdkLongCounterBuilder implements ExtendedLongCounterBuilder { + + private final InstrumentBuilder builder; SdkLongCounterBuilder( MeterProviderSharedState meterProviderSharedState, MeterSharedState meterSharedState, String name) { - super( - meterProviderSharedState, - meterSharedState, - InstrumentType.COUNTER, - InstrumentValueType.LONG, - name, - "", - DEFAULT_UNIT); + this.builder = + new InstrumentBuilder( + name, + InstrumentType.COUNTER, + InstrumentValueType.LONG, + meterProviderSharedState, + meterSharedState); + } + + @Override + public LongCounterBuilder setDescription(String description) { + builder.setDescription(description); + return this; } @Override - protected SdkLongCounterBuilder getThis() { + public LongCounterBuilder setUnit(String unit) { + builder.setUnit(unit); return this; } @Override public SdkLongCounter build() { - return buildSynchronousInstrument(SdkLongCounter::new); + return builder.buildSynchronousInstrument(SdkLongCounter::new); } @Override public DoubleCounterBuilder ofDoubles() { - return swapBuilder(SdkDoubleCounter.SdkDoubleCounterBuilder::new); + return builder.swapBuilder(SdkDoubleCounter.SdkDoubleCounterBuilder::new); } @Override public ObservableLongCounter buildWithCallback(Consumer callback) { - return registerLongAsynchronousInstrument(InstrumentType.OBSERVABLE_COUNTER, callback); + return builder.buildLongAsynchronousInstrument(InstrumentType.OBSERVABLE_COUNTER, callback); } @Override public ObservableLongMeasurement buildObserver() { - return buildObservableMeasurement(InstrumentType.OBSERVABLE_COUNTER); + return builder.buildObservableMeasurement(InstrumentType.OBSERVABLE_COUNTER); } @Override public ExtendedLongCounterBuilder setAttributesAdvice(List> attributes) { - adviceBuilder.setAttributes(attributes); + builder.setAdviceAttributes(attributes); return this; } + + @Override + public String toString() { + return builder.toStringHelper(getClass().getSimpleName()); + } } } diff --git a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkLongGauge.java b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkLongGauge.java index 24e6be8e6a5..73492eb9849 100644 --- a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkLongGauge.java +++ b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkLongGauge.java @@ -7,6 +7,7 @@ import io.opentelemetry.api.common.AttributeKey; import io.opentelemetry.api.common.Attributes; +import io.opentelemetry.api.metrics.LongGaugeBuilder; import io.opentelemetry.api.metrics.ObservableLongGauge; import io.opentelemetry.api.metrics.ObservableLongMeasurement; import io.opentelemetry.context.Context; @@ -39,8 +40,9 @@ public void set(long increment) { set(increment, Attributes.empty()); } - static final class SdkLongGaugeBuilder extends AbstractInstrumentBuilder - implements ExtendedLongGaugeBuilder { + static final class SdkLongGaugeBuilder implements ExtendedLongGaugeBuilder { + + private final InstrumentBuilder builder; SdkLongGaugeBuilder( MeterProviderSharedState meterProviderSharedState, @@ -49,44 +51,58 @@ static final class SdkLongGaugeBuilder extends AbstractInstrumentBuilder> attributes) { - adviceBuilder.setAttributes(attributes); + builder.setAdviceAttributes(attributes); return this; } @Override public ObservableLongGauge buildWithCallback(Consumer callback) { // TODO: use InstrumentType.GAUGE when available - return registerLongAsynchronousInstrument(InstrumentType.OBSERVABLE_GAUGE, callback); + return builder.buildLongAsynchronousInstrument(InstrumentType.OBSERVABLE_GAUGE, callback); } @Override public ObservableLongMeasurement buildObserver() { // TODO: use InstrumentType.GAUGE when available - return buildObservableMeasurement(InstrumentType.OBSERVABLE_GAUGE); + return builder.buildObservableMeasurement(InstrumentType.OBSERVABLE_GAUGE); + } + + @Override + public String toString() { + return builder.toStringHelper(getClass().getSimpleName()); } } } diff --git a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkLongHistogram.java b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkLongHistogram.java index c087a0c282e..4e2e223fa90 100644 --- a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkLongHistogram.java +++ b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkLongHistogram.java @@ -8,6 +8,7 @@ import io.opentelemetry.api.common.AttributeKey; import io.opentelemetry.api.common.Attributes; import io.opentelemetry.api.metrics.LongHistogram; +import io.opentelemetry.api.metrics.LongHistogramBuilder; import io.opentelemetry.context.Context; import io.opentelemetry.extension.incubator.metrics.ExtendedLongHistogramBuilder; import io.opentelemetry.sdk.internal.ThrottlingLogger; @@ -55,9 +56,9 @@ public void record(long value) { record(value, Attributes.empty()); } - static final class SdkLongHistogramBuilder - extends AbstractInstrumentBuilder - implements ExtendedLongHistogramBuilder { + static final class SdkLongHistogramBuilder implements ExtendedLongHistogramBuilder { + + private final InstrumentBuilder builder; SdkLongHistogramBuilder( MeterProviderSharedState meterProviderSharedState, @@ -66,25 +67,33 @@ static final class SdkLongHistogramBuilder String description, String unit, Advice.AdviceBuilder adviceBuilder) { - super( - meterProviderSharedState, - sharedState, - InstrumentType.HISTOGRAM, - InstrumentValueType.LONG, - name, - description, - unit, - adviceBuilder); + builder = + new InstrumentBuilder( + name, + InstrumentType.HISTOGRAM, + InstrumentValueType.LONG, + meterProviderSharedState, + sharedState) + .setDescription(description) + .setUnit(unit) + .setAdviceBuilder(adviceBuilder); + } + + @Override + public LongHistogramBuilder setDescription(String description) { + builder.setDescription(description); + return this; } @Override - protected SdkLongHistogramBuilder getThis() { + public LongHistogramBuilder setUnit(String unit) { + builder.setUnit(unit); return this; } @Override public SdkLongHistogram build() { - return buildSynchronousInstrument(SdkLongHistogram::new); + return builder.buildSynchronousInstrument(SdkLongHistogram::new); } @Override @@ -92,14 +101,19 @@ public ExtendedLongHistogramBuilder setExplicitBucketBoundariesAdvice( List bucketBoundaries) { List doubleBoundaries = bucketBoundaries.stream().map(Long::doubleValue).collect(Collectors.toList()); - adviceBuilder.setExplicitBucketBoundaries(doubleBoundaries); + builder.setExplicitBucketBoundaries(doubleBoundaries); return this; } @Override public ExtendedLongHistogramBuilder setAttributesAdvice(List> attributes) { - adviceBuilder.setAttributes(attributes); + builder.setAdviceAttributes(attributes); return this; } + + @Override + public String toString() { + return builder.toStringHelper(getClass().getSimpleName()); + } } } diff --git a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkLongUpDownCounter.java b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkLongUpDownCounter.java index 4351b28e5ce..9c0aff76c43 100644 --- a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkLongUpDownCounter.java +++ b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkLongUpDownCounter.java @@ -9,6 +9,7 @@ import io.opentelemetry.api.common.Attributes; import io.opentelemetry.api.metrics.DoubleUpDownCounterBuilder; import io.opentelemetry.api.metrics.LongUpDownCounter; +import io.opentelemetry.api.metrics.LongUpDownCounterBuilder; import io.opentelemetry.api.metrics.ObservableLongMeasurement; import io.opentelemetry.api.metrics.ObservableLongUpDownCounter; import io.opentelemetry.context.Context; @@ -44,55 +45,66 @@ public void add(long increment) { add(increment, Attributes.empty()); } - static final class SdkLongUpDownCounterBuilder - extends AbstractInstrumentBuilder - implements ExtendedLongUpDownCounterBuilder { + static final class SdkLongUpDownCounterBuilder implements ExtendedLongUpDownCounterBuilder { + + private final InstrumentBuilder builder; SdkLongUpDownCounterBuilder( MeterProviderSharedState meterProviderSharedState, MeterSharedState meterSharedState, String name) { - super( - meterProviderSharedState, - meterSharedState, - InstrumentType.UP_DOWN_COUNTER, - InstrumentValueType.LONG, - name, - "", - DEFAULT_UNIT); + this.builder = + new InstrumentBuilder( + name, + InstrumentType.UP_DOWN_COUNTER, + InstrumentValueType.LONG, + meterProviderSharedState, + meterSharedState); + } + + @Override + public LongUpDownCounterBuilder setDescription(String description) { + builder.setDescription(description); + return this; } @Override - protected SdkLongUpDownCounterBuilder getThis() { + public LongUpDownCounterBuilder setUnit(String unit) { + builder.setUnit(unit); return this; } @Override public LongUpDownCounter build() { - return buildSynchronousInstrument(SdkLongUpDownCounter::new); + return builder.buildSynchronousInstrument(SdkLongUpDownCounter::new); } @Override public DoubleUpDownCounterBuilder ofDoubles() { - return swapBuilder(SdkDoubleUpDownCounter.SdkDoubleUpDownCounterBuilder::new); + return builder.swapBuilder(SdkDoubleUpDownCounter.SdkDoubleUpDownCounterBuilder::new); } @Override public ObservableLongUpDownCounter buildWithCallback( Consumer callback) { - return registerLongAsynchronousInstrument( + return builder.buildLongAsynchronousInstrument( InstrumentType.OBSERVABLE_UP_DOWN_COUNTER, callback); } @Override public ObservableLongMeasurement buildObserver() { - return buildObservableMeasurement(InstrumentType.OBSERVABLE_UP_DOWN_COUNTER); + return builder.buildObservableMeasurement(InstrumentType.OBSERVABLE_UP_DOWN_COUNTER); } @Override public ExtendedLongUpDownCounterBuilder setAttributesAdvice(List> attributes) { - adviceBuilder.setAttributes(attributes); + builder.setAdviceAttributes(attributes); return this; } + + @Override + public String toString() { + return builder.toStringHelper(getClass().getSimpleName()); + } } } diff --git a/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/AbstractInstrumentBuilderTest.java b/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/AbstractInstrumentBuilderTest.java deleted file mode 100644 index 15f6ba3030f..00000000000 --- a/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/AbstractInstrumentBuilderTest.java +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package io.opentelemetry.sdk.metrics; - -import static org.assertj.core.api.Assertions.assertThat; - -import io.opentelemetry.sdk.common.InstrumentationScopeInfo; -import io.opentelemetry.sdk.metrics.internal.exemplar.ExemplarFilter; -import io.opentelemetry.sdk.metrics.internal.state.MeterProviderSharedState; -import io.opentelemetry.sdk.metrics.internal.state.MeterSharedState; -import io.opentelemetry.sdk.resources.Resource; -import io.opentelemetry.sdk.testing.time.TestClock; -import java.util.Collections; -import org.junit.jupiter.api.Test; - -class AbstractInstrumentBuilderTest { - - @Test - void stringRepresentation() { - InstrumentationScopeInfo scope = InstrumentationScopeInfo.create("scope-name"); - TestInstrumentBuilder builder = - new TestInstrumentBuilder( - MeterProviderSharedState.create( - TestClock.create(), Resource.getDefault(), ExemplarFilter.alwaysOff(), 0), - MeterSharedState.create(scope, Collections.emptyList()), - InstrumentType.COUNTER, - InstrumentValueType.LONG, - "instrument-name", - "instrument-description", - "instrument-unit"); - assertThat(builder.toString()) - .isEqualTo( - "TestInstrumentBuilder{" - + "descriptor=" - + "InstrumentDescriptor{" - + "name=instrument-name, " - + "description=instrument-description, " - + "unit=instrument-unit, " - + "type=COUNTER, " - + "valueType=LONG, " - + "advice=Advice{explicitBucketBoundaries=null, attributes=null}" - + "}}"); - } - - private static class TestInstrumentBuilder - extends AbstractInstrumentBuilder { - - TestInstrumentBuilder( - MeterProviderSharedState meterProviderSharedState, - MeterSharedState meterSharedState, - InstrumentType type, - InstrumentValueType valueType, - String name, - String description, - String unit) { - super(meterProviderSharedState, meterSharedState, type, valueType, name, description, unit); - } - - @Override - protected TestInstrumentBuilder getThis() { - return this; - } - } -} diff --git a/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/InstrumentBuilderTest.java b/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/InstrumentBuilderTest.java new file mode 100644 index 00000000000..a351c95d0e6 --- /dev/null +++ b/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/InstrumentBuilderTest.java @@ -0,0 +1,81 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.sdk.metrics; + +import static org.assertj.core.api.Assertions.assertThat; + +import io.opentelemetry.sdk.common.InstrumentationScopeInfo; +import io.opentelemetry.sdk.metrics.internal.descriptor.Advice; +import io.opentelemetry.sdk.metrics.internal.exemplar.ExemplarFilter; +import io.opentelemetry.sdk.metrics.internal.state.MeterProviderSharedState; +import io.opentelemetry.sdk.metrics.internal.state.MeterSharedState; +import io.opentelemetry.sdk.resources.Resource; +import io.opentelemetry.sdk.testing.time.TestClock; +import java.util.Collections; +import org.junit.jupiter.api.Test; + +class InstrumentBuilderTest { + + public static final MeterProviderSharedState PROVIDER_SHARED_STATE = + MeterProviderSharedState.create( + TestClock.create(), Resource.getDefault(), ExemplarFilter.alwaysOff(), 0); + static final InstrumentationScopeInfo SCOPE = InstrumentationScopeInfo.create("scope-name"); + public static final MeterSharedState METER_SHARED_STATE = + MeterSharedState.create(SCOPE, Collections.emptyList()); + + @Test + void stringRepresentation() { + InstrumentBuilder builder = + new InstrumentBuilder( + "instrument-name", + InstrumentType.COUNTER, + InstrumentValueType.LONG, + PROVIDER_SHARED_STATE, + METER_SHARED_STATE) + .setDescription("instrument-description") + .setUnit("instrument-unit") + .setAdviceBuilder(Advice.builder()); + assertThat(builder.toString()) + .isEqualTo( + "InstrumentBuilder{" + + "descriptor=" + + "InstrumentDescriptor{" + + "name=instrument-name, " + + "description=instrument-description, " + + "unit=instrument-unit, " + + "type=COUNTER, " + + "valueType=LONG, " + + "advice=Advice{explicitBucketBoundaries=null, attributes=null}" + + "}}"); + } + + @Test + void toStringHelper() { + InstrumentBuilder builder = + new InstrumentBuilder( + "instrument-name", + InstrumentType.HISTOGRAM, + InstrumentValueType.DOUBLE, + PROVIDER_SHARED_STATE, + METER_SHARED_STATE) + .setDescription("instrument-description") + .setUnit("instrument-unit") + .setAdviceBuilder(Advice.builder()); + + assertThat(builder.toStringHelper("FooBuilder")) + .isEqualTo( + "FooBuilder{" + + "descriptor=" + + "InstrumentDescriptor{" + + "name=instrument-name, " + + "description=instrument-description, " + + "unit=instrument-unit, " + + "type=HISTOGRAM, " + + "valueType=DOUBLE, " + + "advice=Advice{explicitBucketBoundaries=null, attributes=null}" + + "}}"); + } +} From 1bff69a663289f74a3fbc45c2e76d54bcceaed80 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 19 Oct 2023 09:22:44 -0500 Subject: [PATCH 059/901] Update dependency jacoco to v0.8.11 (#5919) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- buildSrc/src/main/kotlin/otel.jacoco-conventions.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/buildSrc/src/main/kotlin/otel.jacoco-conventions.gradle.kts b/buildSrc/src/main/kotlin/otel.jacoco-conventions.gradle.kts index f672ef2dcad..fa6360129fd 100644 --- a/buildSrc/src/main/kotlin/otel.jacoco-conventions.gradle.kts +++ b/buildSrc/src/main/kotlin/otel.jacoco-conventions.gradle.kts @@ -5,7 +5,7 @@ plugins { } jacoco { - toolVersion = "0.8.10" + toolVersion = "0.8.11" } // https://docs.gradle.org/current/samples/sample_jvm_multi_project_with_code_coverage.html From a77e1f9af39e301554f97523abd7414e7f373f55 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 19 Oct 2023 09:26:55 -0500 Subject: [PATCH 060/901] Update dependency com.uber.nullaway:nullaway to v0.10.15 (#5929) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- dependencyManagement/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index 2888acddfae..2e440ef8523 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -60,7 +60,7 @@ val DEPENDENCIES = listOf( "com.google.guava:guava-beta-checker:1.0", "com.sun.net.httpserver:http:20070405", "com.tngtech.archunit:archunit-junit5:1.1.0", - "com.uber.nullaway:nullaway:0.10.14", + "com.uber.nullaway:nullaway:0.10.15", "edu.berkeley.cs.jqf:jqf-fuzz:1.7", // jqf-fuzz version 1.8+ requires Java 11+ "eu.rekawek.toxiproxy:toxiproxy-java:2.1.7", "io.github.netmikey.logunit:logunit-jul:2.0.0", From 5740c3ceaf115dd5f19f0bc7e781952fb2d7ad63 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 19 Oct 2023 10:06:04 -0500 Subject: [PATCH 061/901] Update dependency com.squareup.okhttp3:okhttp-bom to v4.12.0 (#5921) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- dependencyManagement/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index 2e440ef8523..8d3610fc359 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -12,7 +12,7 @@ val DEPENDENCY_BOMS = listOf( "com.google.guava:guava-bom:32.1.3-jre", "com.google.protobuf:protobuf-bom:3.24.4", "com.linecorp.armeria:armeria-bom:1.25.2", - "com.squareup.okhttp3:okhttp-bom:4.11.0", + "com.squareup.okhttp3:okhttp-bom:4.12.0", "com.squareup.okio:okio-bom:3.6.0", // applies to transitive dependencies of okhttp "io.grpc:grpc-bom:1.58.0", "io.netty:netty-bom:4.1.100.Final", From e592d5dbfded93010c871c858c6eac6eff345831 Mon Sep 17 00:00:00 2001 From: jack-berg <34418638+jack-berg@users.noreply.github.com> Date: Mon, 23 Oct 2023 10:29:01 -0500 Subject: [PATCH 062/901] Add env var substitution support to file configuration (#5914) --- .../fileconfig/ConfigurationFactory.java | 3 + .../fileconfig/ConfigurationReader.java | 113 +++++++++++++- .../fileconfig/ConfigurationReaderTest.java | 146 +++++++++++++++++- 3 files changed, 252 insertions(+), 10 deletions(-) diff --git a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/ConfigurationFactory.java b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/ConfigurationFactory.java index 1e0dddf3074..9c51f00af9a 100644 --- a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/ConfigurationFactory.java +++ b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/ConfigurationFactory.java @@ -34,6 +34,9 @@ private ConfigurationFactory() {} * Parse the {@code inputStream} YAML to {@link OpenTelemetryConfiguration} and interpret the * model to create {@link OpenTelemetrySdk} instance corresponding to the configuration. * + *

    Before parsing, environment variable substitution is performed as described in {@link + * ConfigurationReader.EnvSubstitutionConstructor}. + * * @param inputStream the configuration YAML * @return the {@link OpenTelemetrySdk} */ diff --git a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/ConfigurationReader.java b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/ConfigurationReader.java index 4fe765ee344..731bfee1770 100644 --- a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/ConfigurationReader.java +++ b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/ConfigurationReader.java @@ -10,23 +10,120 @@ import com.fasterxml.jackson.databind.ObjectMapper; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.OpenTelemetryConfiguration; import java.io.InputStream; +import java.util.Map; +import java.util.regex.MatchResult; +import java.util.regex.Matcher; +import java.util.regex.Pattern; import org.snakeyaml.engine.v2.api.Load; import org.snakeyaml.engine.v2.api.LoadSettings; +import org.snakeyaml.engine.v2.constructor.StandardConstructor; +import org.snakeyaml.engine.v2.nodes.MappingNode; +import org.yaml.snakeyaml.Yaml; final class ConfigurationReader { - private static final ObjectMapper MAPPER = - new ObjectMapper() - // Create empty object instances for keys which are present but have null values - .setDefaultSetterInfo(JsonSetter.Value.forValueNulls(Nulls.AS_EMPTY)); + private static final Pattern ENV_VARIABLE_REFERENCE = + Pattern.compile("\\$\\{env:([a-zA-Z_]+[a-zA-Z0-9_]*)}"); + + private static final ObjectMapper MAPPER; + + static { + MAPPER = + new ObjectMapper() + // Create empty object instances for keys which are present but have null values + .setDefaultSetterInfo(JsonSetter.Value.forValueNulls(Nulls.AS_EMPTY)); + // Boxed primitives which are present but have null values should be set to null, rather than + // empty instances + MAPPER.configOverride(String.class).setSetterInfo(JsonSetter.Value.forValueNulls(Nulls.SET)); + MAPPER.configOverride(Integer.class).setSetterInfo(JsonSetter.Value.forValueNulls(Nulls.SET)); + MAPPER.configOverride(Double.class).setSetterInfo(JsonSetter.Value.forValueNulls(Nulls.SET)); + MAPPER.configOverride(Boolean.class).setSetterInfo(JsonSetter.Value.forValueNulls(Nulls.SET)); + } private ConfigurationReader() {} - /** Parse the {@code configuration} YAML and return the {@link OpenTelemetryConfiguration}. */ + /** + * Parse the {@code configuration} YAML and return the {@link OpenTelemetryConfiguration}. + * + *

    Before parsing, environment variable substitution is performed as described in {@link + * EnvSubstitutionConstructor}. + */ static OpenTelemetryConfiguration parse(InputStream configuration) { - LoadSettings settings = LoadSettings.builder().build(); - Load yaml = new Load(settings); - Object yamlObj = yaml.loadFromInputStream(configuration); + return parse(configuration, System.getenv()); + } + + // Visible for testing + static OpenTelemetryConfiguration parse( + InputStream configuration, Map environmentVariables) { + Object yamlObj = loadYaml(configuration, environmentVariables); return MAPPER.convertValue(yamlObj, OpenTelemetryConfiguration.class); } + + static Object loadYaml(InputStream inputStream, Map environmentVariables) { + LoadSettings settings = LoadSettings.builder().build(); + Load yaml = new Load(settings, new EnvSubstitutionConstructor(settings, environmentVariables)); + return yaml.loadFromInputStream(inputStream); + } + + /** + * {@link StandardConstructor} which substitutes environment variables. + * + *

    Environment variables follow the syntax {@code ${env:VARIABLE}}, where {@code VARIABLE} is + * an environment variable matching the regular expression {@code [a-zA-Z_]+[a-zA-Z0-9_]*}. + * + *

    Environment variable substitution only takes place on scalar values of maps. References to + * environment variables in keys or sets are ignored. + * + *

    If a referenced environment variable is not defined, it is replaced with {@code ""}. + */ + static final class EnvSubstitutionConstructor extends StandardConstructor { + + // Yaml is not thread safe but this instance is always used on the same thread + private final Yaml yaml = new Yaml(); + private final Map environmentVariables; + + private EnvSubstitutionConstructor( + LoadSettings loadSettings, Map environmentVariables) { + super(loadSettings); + this.environmentVariables = environmentVariables; + } + + @Override + protected Map constructMapping(MappingNode node) { + // First call the super to construct mapping from MappingNode as usual + Map result = super.constructMapping(node); + + // Iterate through the map entries, and: + // 1. Identify entries which are scalar strings eligible for environment variable substitution + // 2. Apply environment variable substitution + // 3. Re-parse substituted value so it has correct type (i.e. yaml.load(newVal)) + for (Map.Entry entry : result.entrySet()) { + Object value = entry.getValue(); + if (!(value instanceof String)) { + continue; + } + + String val = (String) value; + Matcher matcher = ENV_VARIABLE_REFERENCE.matcher(val); + if (!matcher.find()) { + continue; + } + + int offset = 0; + StringBuilder newVal = new StringBuilder(); + do { + MatchResult matchResult = matcher.toMatchResult(); + String replacement = environmentVariables.getOrDefault(matcher.group(1), ""); + newVal.append(val, offset, matchResult.start()).append(replacement); + offset = matchResult.end(); + } while (matcher.find()); + if (offset != val.length()) { + newVal.append(val, offset, val.length()); + } + entry.setValue(yaml.load(newVal.toString())); + } + + return result; + } + } } diff --git a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/ConfigurationReaderTest.java b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/ConfigurationReaderTest.java index afdb4cac33e..3a1e81c4073 100644 --- a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/ConfigurationReaderTest.java +++ b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/ConfigurationReaderTest.java @@ -49,14 +49,21 @@ import java.io.FileInputStream; import java.io.IOException; import java.nio.charset.StandardCharsets; +import java.util.AbstractMap; import java.util.Arrays; import java.util.Collections; +import java.util.HashMap; +import java.util.Map; +import javax.annotation.Nullable; import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; class ConfigurationReaderTest { @Test - void read_KitchenSinkExampleFile() throws IOException { + void parse_KitchenSinkExampleFile() throws IOException { OpenTelemetryConfiguration expected = new OpenTelemetryConfiguration(); expected.withFileFormat("0.1"); @@ -283,7 +290,7 @@ void read_KitchenSinkExampleFile() throws IOException { } @Test - void nullValuesParsedToEmptyObjects() { + void parse_nullValuesParsedToEmptyObjects() { String objectPlaceholderString = "file_format: \"0.1\"\n" + "tracer_provider:\n" @@ -337,4 +344,139 @@ void nullValuesParsedToEmptyObjects() { assertThat(objectPlaceholderModel).isEqualTo(noObjectPlaceholderModel); } + + @Test + void parse_nullBoxedPrimitivesParsedToNull() { + String yaml = + "file_format:\n" // String + + "disabled:\n" // Boolean + + "attribute_limits:\n" + + " attribute_value_length_limit:\n" // Integer + + "tracer_provider:\n" + + " sampler:\n" + + " trace_id_ratio_based:\n" + + " ratio:\n"; // Double + + OpenTelemetryConfiguration model = + ConfigurationReader.parse(new ByteArrayInputStream(yaml.getBytes(StandardCharsets.UTF_8))); + + assertThat(model.getFileFormat()).isNull(); + assertThat(model.getDisabled()).isNull(); + assertThat(model.getAttributeLimits().getAttributeValueLengthLimit()).isNull(); + assertThat(model.getTracerProvider().getSampler().getTraceIdRatioBased().getRatio()).isNull(); + + assertThat(model) + .isEqualTo( + new OpenTelemetryConfiguration() + .withAttributeLimits(new AttributeLimits()) + .withTracerProvider( + new TracerProvider() + .withSampler( + new Sampler().withTraceIdRatioBased(new TraceIdRatioBased())))); + } + + @ParameterizedTest + @MethodSource("envVarSubstitutionArgs") + void envSubstituteAndLoadYaml(String rawYaml, Object expectedYamlResult) { + Map environmentVariables = new HashMap<>(); + environmentVariables.put("STR_1", "value1"); + environmentVariables.put("STR_2", "value2"); + environmentVariables.put("BOOL", "true"); + environmentVariables.put("INT", "1"); + environmentVariables.put("FLOAT", "1.1"); + + Object yaml = + ConfigurationReader.loadYaml( + new ByteArrayInputStream(rawYaml.getBytes(StandardCharsets.UTF_8)), + environmentVariables); + assertThat(yaml).isEqualTo(expectedYamlResult); + } + + @SuppressWarnings("unchecked") + private static java.util.stream.Stream envVarSubstitutionArgs() { + return java.util.stream.Stream.of( + // Simple cases + Arguments.of("key1: ${env:STR_1}\n", mapOf(entry("key1", "value1"))), + Arguments.of("key1: ${env:BOOL}\n", mapOf(entry("key1", true))), + Arguments.of("key1: ${env:INT}\n", mapOf(entry("key1", 1))), + Arguments.of("key1: ${env:FLOAT}\n", mapOf(entry("key1", 1.1))), + Arguments.of( + "key1: ${env:STR_1}\n" + "key2: value2\n", + mapOf(entry("key1", "value1"), entry("key2", "value2"))), + Arguments.of( + "key1: ${env:STR_1} value1\n" + "key2: value2\n", + mapOf(entry("key1", "value1 value1"), entry("key2", "value2"))), + // Multiple environment variables referenced + Arguments.of("key1: ${env:STR_1}${env:STR_2}\n", mapOf(entry("key1", "value1value2"))), + Arguments.of("key1: ${env:STR_1} ${env:STR_2}\n", mapOf(entry("key1", "value1 value2"))), + // Undefined environment variable + Arguments.of("key1: ${env:STR_3}\n", mapOf(entry("key1", null))), + Arguments.of("key1: ${env:STR_1} ${env:STR_3}\n", mapOf(entry("key1", "value1"))), + // Environment variable keys must match pattern: [a-zA-Z_]+[a-zA-Z0-9_]* + Arguments.of("key1: ${env:VAR&}\n", mapOf(entry("key1", "${env:VAR&}"))), + // Environment variable substitution only takes place in scalar values of maps + Arguments.of("${env:STR_1}: value1\n", mapOf(entry("${env:STR_1}", "value1"))), + Arguments.of( + "key1:\n ${env:STR_1}: value1\n", + mapOf(entry("key1", mapOf(entry("${env:STR_1}", "value1"))))), + Arguments.of( + "key1:\n - ${env:STR_1}\n", + mapOf(entry("key1", Collections.singletonList("${env:STR_1}"))))); + } + + private static Map.Entry entry(K key, @Nullable V value) { + return new AbstractMap.SimpleEntry<>(key, value); + } + + @SuppressWarnings("unchecked") + private static Map mapOf(Map.Entry... entries) { + Map result = new HashMap<>(); + for (Map.Entry entry : entries) { + result.put(entry.getKey(), entry.getValue()); + } + return result; + } + + @Test + void read_WithEnvironmentVariables() { + String yaml = + "file_format: \"0.1\"\n" + + "tracer_provider:\n" + + " processors:\n" + + " - batch:\n" + + " exporter:\n" + + " otlp:\n" + + " endpoint: ${env:OTEL_EXPORTER_OTLP_ENDPOINT}\n" + + " - batch:\n" + + " exporter:\n" + + " otlp:\n" + + " endpoint: \"${env:UNSET_ENV_VAR}\"\n"; + Map envVars = new HashMap<>(); + envVars.put("OTEL_EXPORTER_OTLP_ENDPOINT", "http://collector:4317"); + OpenTelemetryConfiguration model = + ConfigurationReader.parse( + new ByteArrayInputStream(yaml.getBytes(StandardCharsets.UTF_8)), envVars); + assertThat(model) + .isEqualTo( + new OpenTelemetryConfiguration() + .withFileFormat("0.1") + .withTracerProvider( + new TracerProvider() + .withProcessors( + Arrays.asList( + new SpanProcessor() + .withBatch( + new BatchSpanProcessor() + .withExporter( + new SpanExporter() + .withOtlp( + new Otlp() + .withEndpoint( + "http://collector:4317")))), + new SpanProcessor() + .withBatch( + new BatchSpanProcessor() + .withExporter( + new SpanExporter().withOtlp(new Otlp()))))))); + } } From 70cb2c9235430fd8c9d88e4875444b1c11dc3cf9 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 23 Oct 2023 10:29:37 -0500 Subject: [PATCH 063/901] Update dependency org.owasp:dependency-check-gradle to v8.4.2 (#5935) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- buildSrc/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts index aaa1db21f13..ca79346af23 100644 --- a/buildSrc/build.gradle.kts +++ b/buildSrc/build.gradle.kts @@ -58,7 +58,7 @@ dependencies { implementation("net.ltgt.gradle:gradle-errorprone-plugin:3.1.0") implementation("net.ltgt.gradle:gradle-nullaway-plugin:1.6.0") implementation("org.jetbrains.kotlin:kotlin-gradle-plugin:1.9.10") - implementation("org.owasp:dependency-check-gradle:8.4.0") + implementation("org.owasp:dependency-check-gradle:8.4.2") implementation("ru.vyarus:gradle-animalsniffer-plugin:1.7.1") } From c3a2e94579caaf6b35cf5902cd8a79f58d9a9e15 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 23 Oct 2023 10:29:49 -0500 Subject: [PATCH 064/901] Update dependency io.grpc:grpc-bom to v1.59.0 (#5934) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- dependencyManagement/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index 8d3610fc359..380ab0a3e22 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -14,7 +14,7 @@ val DEPENDENCY_BOMS = listOf( "com.linecorp.armeria:armeria-bom:1.25.2", "com.squareup.okhttp3:okhttp-bom:4.12.0", "com.squareup.okio:okio-bom:3.6.0", // applies to transitive dependencies of okhttp - "io.grpc:grpc-bom:1.58.0", + "io.grpc:grpc-bom:1.59.0", "io.netty:netty-bom:4.1.100.Final", "io.zipkin.brave:brave-bom:5.16.0", "io.zipkin.reporter2:zipkin-reporter-bom:2.16.4", From cb44b2b18c474f80478184ff1665bc3fa5d2ced3 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 23 Oct 2023 10:31:09 -0500 Subject: [PATCH 065/901] Update errorProneVersion to v2.23.0 (#5927) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Co-authored-by: Jack Berg --- .../api/GlobalOpenTelemetry.java | 5 ++++- .../events/GlobalEventEmitterProvider.java | 4 +++- .../context/BraveInOtelTest.java | 1 + .../opentelemetry/context/GrpcInOtelTest.java | 1 + .../context/ContextStorageWrappers.java | 1 + .../context/OtelAsBraveTest.java | 1 + .../context/OtelInBraveTest.java | 1 + .../opentelemetry/context/OtelInGrpcTest.java | 1 + dependencyManagement/build.gradle.kts | 2 +- .../thrift/JaegerThriftIntegrationTest.java | 2 +- .../jaeger/JaegerGrpcSpanExporterTest.java | 19 ++++++---------- .../jaeger/JaegerIntegrationTest.java | 2 +- .../otlp/trace/OltpExporterBenchmark.java | 1 + .../otlp/trace/SpanPipelineOtlpBenchmark.java | 22 +++++++++---------- .../prometheus/CollectorIntegrationTest.java | 1 + .../prometheus/PrometheusHttpServerTest.java | 3 +++ .../prometheus/PrometheusIntegrationTest.java | 3 +++ .../ZipkinSpanExporterEndToEndHttpTest.java | 2 +- .../OtlpExporterIntegrationTest.java | 3 +++ .../B3PropagationIntegrationTest.java | 3 +++ .../opentracingshim/TracerShimTest.java | 3 ++- .../perf/OtlpPipelineStressTest.java | 8 +++---- .../JaegerRemoteSamplerIntegrationTest.java | 2 +- .../metrics/internal/debug/DebugConfig.java | 2 ++ .../SettableContextStorageProvider.java | 1 + .../sdk/trace/ExceptionBenchmark.java | 1 + .../sdk/trace/SpanBenchmark.java | 2 ++ 27 files changed, 62 insertions(+), 35 deletions(-) diff --git a/api/all/src/main/java/io/opentelemetry/api/GlobalOpenTelemetry.java b/api/all/src/main/java/io/opentelemetry/api/GlobalOpenTelemetry.java index 3e2244a95bb..230a85e06a9 100644 --- a/api/all/src/main/java/io/opentelemetry/api/GlobalOpenTelemetry.java +++ b/api/all/src/main/java/io/opentelemetry/api/GlobalOpenTelemetry.java @@ -53,8 +53,11 @@ public final class GlobalOpenTelemetry { private static final Object mutex = new Object(); - @Nullable private static volatile ObfuscatedOpenTelemetry globalOpenTelemetry; + @SuppressWarnings("NonFinalStaticField") + @Nullable + private static volatile ObfuscatedOpenTelemetry globalOpenTelemetry; + @SuppressWarnings("NonFinalStaticField") @GuardedBy("mutex") @Nullable private static Throwable setGlobalCaller; diff --git a/api/events/src/main/java/io/opentelemetry/api/events/GlobalEventEmitterProvider.java b/api/events/src/main/java/io/opentelemetry/api/events/GlobalEventEmitterProvider.java index ddf62a6d5a0..b6b1685bbfa 100644 --- a/api/events/src/main/java/io/opentelemetry/api/events/GlobalEventEmitterProvider.java +++ b/api/events/src/main/java/io/opentelemetry/api/events/GlobalEventEmitterProvider.java @@ -20,7 +20,9 @@ public final class GlobalEventEmitterProvider { private static final AtomicReference instance = new AtomicReference<>(EventEmitterProvider.noop()); - @Nullable private static volatile Throwable setInstanceCaller; + @SuppressWarnings("NonFinalStaticField") + @Nullable + private static volatile Throwable setInstanceCaller; private GlobalEventEmitterProvider() {} diff --git a/context/src/braveInOtelTest/java/io/opentelemetry/context/BraveInOtelTest.java b/context/src/braveInOtelTest/java/io/opentelemetry/context/BraveInOtelTest.java index efaf20562d0..13298a341e2 100644 --- a/context/src/braveInOtelTest/java/io/opentelemetry/context/BraveInOtelTest.java +++ b/context/src/braveInOtelTest/java/io/opentelemetry/context/BraveInOtelTest.java @@ -27,6 +27,7 @@ class BraveInOtelTest { private static final TraceContext TRACE_CONTEXT = TraceContext.newBuilder().traceId(1).spanId(1).addExtra("japan").build(); + @SuppressWarnings("NonFinalStaticField") private static ExecutorService otherThread; @BeforeAll diff --git a/context/src/grpcInOtelTest/java/io/opentelemetry/context/GrpcInOtelTest.java b/context/src/grpcInOtelTest/java/io/opentelemetry/context/GrpcInOtelTest.java index 265c623ed4f..4d22ed765ee 100644 --- a/context/src/grpcInOtelTest/java/io/opentelemetry/context/GrpcInOtelTest.java +++ b/context/src/grpcInOtelTest/java/io/opentelemetry/context/GrpcInOtelTest.java @@ -21,6 +21,7 @@ class GrpcInOtelTest { private static final io.grpc.Context.Key FOOD = io.grpc.Context.key("food"); private static final io.grpc.Context.Key COUNTRY = io.grpc.Context.key("country"); + @SuppressWarnings("NonFinalStaticField") private static ExecutorService otherThread; @BeforeAll diff --git a/context/src/main/java/io/opentelemetry/context/ContextStorageWrappers.java b/context/src/main/java/io/opentelemetry/context/ContextStorageWrappers.java index 9f8eb3276a1..faa05a66c0b 100644 --- a/context/src/main/java/io/opentelemetry/context/ContextStorageWrappers.java +++ b/context/src/main/java/io/opentelemetry/context/ContextStorageWrappers.java @@ -19,6 +19,7 @@ final class ContextStorageWrappers { private static final Logger log = Logger.getLogger(ContextStorageWrappers.class.getName()); + @SuppressWarnings("NonFinalStaticField") private static boolean storageInitialized; private static final List> wrappers = diff --git a/context/src/otelAsBraveTest/java/io/opentelemetry/context/OtelAsBraveTest.java b/context/src/otelAsBraveTest/java/io/opentelemetry/context/OtelAsBraveTest.java index 6acad3d0e7b..f3498727995 100644 --- a/context/src/otelAsBraveTest/java/io/opentelemetry/context/OtelAsBraveTest.java +++ b/context/src/otelAsBraveTest/java/io/opentelemetry/context/OtelAsBraveTest.java @@ -27,6 +27,7 @@ class OtelAsBraveTest { private static final TraceContext TRACE_CONTEXT = TraceContext.newBuilder().traceId(1).spanId(1).addExtra("japan").build(); + @SuppressWarnings("NonFinalStaticField") private static ExecutorService otherThread; @BeforeAll diff --git a/context/src/otelInBraveTest/java/io/opentelemetry/context/OtelInBraveTest.java b/context/src/otelInBraveTest/java/io/opentelemetry/context/OtelInBraveTest.java index 72a8b402acf..232cb0c4755 100644 --- a/context/src/otelInBraveTest/java/io/opentelemetry/context/OtelInBraveTest.java +++ b/context/src/otelInBraveTest/java/io/opentelemetry/context/OtelInBraveTest.java @@ -28,6 +28,7 @@ class OtelInBraveTest { BraveContextStorageProvider.toBraveContext( TraceContext.newBuilder().traceId(1).spanId(1).build(), CONTEXT_WITH_ANIMAL); + @SuppressWarnings("NonFinalStaticField") private static ExecutorService otherThread; @BeforeAll diff --git a/context/src/otelInGrpcTest/java/io/opentelemetry/context/OtelInGrpcTest.java b/context/src/otelInGrpcTest/java/io/opentelemetry/context/OtelInGrpcTest.java index 6b5cf16dabb..6024100b986 100644 --- a/context/src/otelInGrpcTest/java/io/opentelemetry/context/OtelInGrpcTest.java +++ b/context/src/otelInGrpcTest/java/io/opentelemetry/context/OtelInGrpcTest.java @@ -21,6 +21,7 @@ class OtelInGrpcTest { private static final io.grpc.Context.Key FOOD = io.grpc.Context.key("food"); private static final io.grpc.Context.Key COUNTRY = io.grpc.Context.key("country"); + @SuppressWarnings("NonFinalStaticField") private static ExecutorService otherThread; @BeforeAll diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index 380ab0a3e22..89c1624878d 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -25,7 +25,7 @@ val DEPENDENCY_BOMS = listOf( ) val autoValueVersion = "1.10.4" -val errorProneVersion = "2.22.0" +val errorProneVersion = "2.23.0" val jmhVersion = "1.37" // Mockito 5.x.x requires Java 11 https://github.com/mockito/mockito/releases/tag/v5.0.0 val mockitoVersion = "4.11.0" diff --git a/exporters/jaeger-thrift/src/test/java/io/opentelemetry/exporter/jaeger/thrift/JaegerThriftIntegrationTest.java b/exporters/jaeger-thrift/src/test/java/io/opentelemetry/exporter/jaeger/thrift/JaegerThriftIntegrationTest.java index 6aa33e2efc1..fe95b30894b 100644 --- a/exporters/jaeger-thrift/src/test/java/io/opentelemetry/exporter/jaeger/thrift/JaegerThriftIntegrationTest.java +++ b/exporters/jaeger-thrift/src/test/java/io/opentelemetry/exporter/jaeger/thrift/JaegerThriftIntegrationTest.java @@ -47,7 +47,7 @@ class JaegerThriftIntegrationTest { private static final String JAEGER_URL = "http://localhost"; @Container - public static GenericContainer jaegerContainer = + public static final GenericContainer jaegerContainer = new GenericContainer<>("ghcr.io/open-telemetry/opentelemetry-java/jaeger:1.32") .withImagePullPolicy(PullPolicy.alwaysPull()) .withExposedPorts(THRIFT_HTTP_PORT, THRIFT_UDP_PORT, QUERY_PORT, HEALTH_PORT) diff --git a/exporters/jaeger/src/test/java/io/opentelemetry/exporter/jaeger/JaegerGrpcSpanExporterTest.java b/exporters/jaeger/src/test/java/io/opentelemetry/exporter/jaeger/JaegerGrpcSpanExporterTest.java index 2889f9ab972..994998d6176 100644 --- a/exporters/jaeger/src/test/java/io/opentelemetry/exporter/jaeger/JaegerGrpcSpanExporterTest.java +++ b/exporters/jaeger/src/test/java/io/opentelemetry/exporter/jaeger/JaegerGrpcSpanExporterTest.java @@ -55,9 +55,8 @@ import javax.net.ssl.TrustManager; import javax.net.ssl.X509KeyManager; import javax.net.ssl.X509TrustManager; -import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.RegisterExtension; @@ -99,10 +98,10 @@ protected CompletionStage handleMessage( @RegisterExtension static final SelfSignedCertificateExtension clientTls = new SelfSignedCertificateExtension(); - private static JaegerGrpcSpanExporter exporter; + private JaegerGrpcSpanExporter exporter; - @BeforeAll - static void setUp() { + @BeforeEach + void setUp() { exporter = JaegerGrpcSpanExporter.builder() .setEndpoint(server.httpUri().toString()) @@ -110,13 +109,9 @@ static void setUp() { .build(); } - @AfterAll - static void tearDown() { - exporter.shutdown(); - } - @AfterEach - void reset() { + void tearDown() { + exporter.shutdown(); postedRequests.clear(); } @@ -213,7 +208,7 @@ void testExportMultipleResources() throws Exception { } } - private static void verifyBatch(Model.Batch batch) throws Exception { + private void verifyBatch(Model.Batch batch) throws Exception { assertThat(batch.getSpansCount()).isEqualTo(1); assertThat(TraceId.fromBytes(batch.getSpans(0).getTraceId().toByteArray())).isNotNull(); assertThat(batch.getProcess().getTagsCount()).isEqualTo(5); diff --git a/exporters/jaeger/src/test/java/io/opentelemetry/exporter/jaeger/JaegerIntegrationTest.java b/exporters/jaeger/src/test/java/io/opentelemetry/exporter/jaeger/JaegerIntegrationTest.java index b0e32ba636e..bfd7db8046f 100644 --- a/exporters/jaeger/src/test/java/io/opentelemetry/exporter/jaeger/JaegerIntegrationTest.java +++ b/exporters/jaeger/src/test/java/io/opentelemetry/exporter/jaeger/JaegerIntegrationTest.java @@ -41,7 +41,7 @@ class JaegerIntegrationTest { private static final String JAEGER_URL = "http://localhost"; @Container - public static GenericContainer jaegerContainer = + public static final GenericContainer jaegerContainer = new GenericContainer<>("ghcr.io/open-telemetry/opentelemetry-java/jaeger:1.32") .withImagePullPolicy(PullPolicy.alwaysPull()) .withExposedPorts(COLLECTOR_PORT, QUERY_PORT, HEALTH_PORT) diff --git a/exporters/otlp/all/src/jmh/java/io/opentelemetry/exporter/otlp/trace/OltpExporterBenchmark.java b/exporters/otlp/all/src/jmh/java/io/opentelemetry/exporter/otlp/trace/OltpExporterBenchmark.java index 9271ad9fc7e..8e70ad7a73f 100644 --- a/exporters/otlp/all/src/jmh/java/io/opentelemetry/exporter/otlp/trace/OltpExporterBenchmark.java +++ b/exporters/otlp/all/src/jmh/java/io/opentelemetry/exporter/otlp/trace/OltpExporterBenchmark.java @@ -44,6 +44,7 @@ @Measurement(iterations = 20, time = 1) @Fork(1) @State(Scope.Benchmark) +@SuppressWarnings("NonFinalStaticField") public class OltpExporterBenchmark { private static final Server server = Server.builder() diff --git a/exporters/otlp/all/src/testSpanPipeline/java/io/opentelemetry/exporter/otlp/trace/SpanPipelineOtlpBenchmark.java b/exporters/otlp/all/src/testSpanPipeline/java/io/opentelemetry/exporter/otlp/trace/SpanPipelineOtlpBenchmark.java index 3fc1f5f9a5a..a5536b31c3b 100644 --- a/exporters/otlp/all/src/testSpanPipeline/java/io/opentelemetry/exporter/otlp/trace/SpanPipelineOtlpBenchmark.java +++ b/exporters/otlp/all/src/testSpanPipeline/java/io/opentelemetry/exporter/otlp/trace/SpanPipelineOtlpBenchmark.java @@ -23,8 +23,8 @@ import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletionStage; import java.util.concurrent.TimeUnit; -import org.junit.jupiter.api.AfterAll; -import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.RegisterExtension; @@ -70,11 +70,11 @@ protected CompletionStage handleMessage( } }; - private static SdkTracerProvider tracerProvider; - private static Tracer tracer; + private SdkTracerProvider tracerProvider; + private Tracer tracer; - @BeforeAll - public static void setUp() { + @BeforeEach + public void setUp() { tracerProvider = SdkTracerProvider.builder() .setResource(RESOURCE) @@ -89,12 +89,12 @@ public static void setUp() { tracer = tracerProvider.get("benchmark"); } - @AfterAll - public static void tearDown() { + @AfterEach + public void tearDown() { tracerProvider.close(); } - private static void createSpan() { + private void createSpan() { Span span = tracer.spanBuilder("POST /search").startSpan(); try (Scope ignored = span.makeCurrent()) { span.setAllAttributes(SPAN_ATTRIBUTES); @@ -109,10 +109,10 @@ void runPipeline() { long endTimeNanos = startTimeNanos + TimeUnit.SECONDS.toNanos(60); try { while (System.nanoTime() < endTimeNanos) { - SpanPipelineOtlpBenchmark.createSpan(); + createSpan(); } } finally { - SpanPipelineOtlpBenchmark.tearDown(); + tearDown(); } } } diff --git a/exporters/prometheus/src/test/java/io/opentelemetry/exporter/prometheus/CollectorIntegrationTest.java b/exporters/prometheus/src/test/java/io/opentelemetry/exporter/prometheus/CollectorIntegrationTest.java index 07cee01a801..c062f61bcc6 100644 --- a/exporters/prometheus/src/test/java/io/opentelemetry/exporter/prometheus/CollectorIntegrationTest.java +++ b/exporters/prometheus/src/test/java/io/opentelemetry/exporter/prometheus/CollectorIntegrationTest.java @@ -56,6 +56,7 @@ * running in process, allowing assertions to be made against the data. */ @Testcontainers(disabledWithoutDocker = true) +@SuppressWarnings("NonFinalStaticField") class CollectorIntegrationTest { private static final String COLLECTOR_IMAGE = diff --git a/exporters/prometheus/src/test/java/io/opentelemetry/exporter/prometheus/PrometheusHttpServerTest.java b/exporters/prometheus/src/test/java/io/opentelemetry/exporter/prometheus/PrometheusHttpServerTest.java index 2c6245fd1d4..7f65cf1e0c2 100644 --- a/exporters/prometheus/src/test/java/io/opentelemetry/exporter/prometheus/PrometheusHttpServerTest.java +++ b/exporters/prometheus/src/test/java/io/opentelemetry/exporter/prometheus/PrometheusHttpServerTest.java @@ -58,7 +58,10 @@ class PrometheusHttpServerTest { private static final AtomicReference> metricData = new AtomicReference<>(); + @SuppressWarnings("NonFinalStaticField") static PrometheusHttpServer prometheusServer; + + @SuppressWarnings("NonFinalStaticField") static WebClient client; @RegisterExtension diff --git a/exporters/prometheus/src/test/java/io/opentelemetry/exporter/prometheus/PrometheusIntegrationTest.java b/exporters/prometheus/src/test/java/io/opentelemetry/exporter/prometheus/PrometheusIntegrationTest.java index f98b06c7da6..cff688c129d 100644 --- a/exporters/prometheus/src/test/java/io/opentelemetry/exporter/prometheus/PrometheusIntegrationTest.java +++ b/exporters/prometheus/src/test/java/io/opentelemetry/exporter/prometheus/PrometheusIntegrationTest.java @@ -35,7 +35,10 @@ @Testcontainers(disabledWithoutDocker = true) class PrometheusIntegrationTest { + @SuppressWarnings("NonFinalStaticField") private static SdkMeterProvider meterProvider; + + @SuppressWarnings("NonFinalStaticField") private static GenericContainer prometheus; @BeforeAll diff --git a/exporters/zipkin/src/test/java/io/opentelemetry/exporter/zipkin/ZipkinSpanExporterEndToEndHttpTest.java b/exporters/zipkin/src/test/java/io/opentelemetry/exporter/zipkin/ZipkinSpanExporterEndToEndHttpTest.java index d12a6b060e3..c7d23af452f 100644 --- a/exporters/zipkin/src/test/java/io/opentelemetry/exporter/zipkin/ZipkinSpanExporterEndToEndHttpTest.java +++ b/exporters/zipkin/src/test/java/io/opentelemetry/exporter/zipkin/ZipkinSpanExporterEndToEndHttpTest.java @@ -81,7 +81,7 @@ class ZipkinSpanExporterEndToEndHttpTest { SEEN_ATTRIBUTES.toBuilder().put(AttributeKey.booleanKey("success"), false).build(); @Container - public static GenericContainer zipkinContainer = + public static final GenericContainer zipkinContainer = new GenericContainer<>("ghcr.io/openzipkin/zipkin:2.23") .withExposedPorts(ZIPKIN_API_PORT) .waitingFor(Wait.forHttp("/health").forPort(ZIPKIN_API_PORT)); diff --git a/integration-tests/otlp/src/main/java/io/opentelemetry/integrationtest/OtlpExporterIntegrationTest.java b/integration-tests/otlp/src/main/java/io/opentelemetry/integrationtest/OtlpExporterIntegrationTest.java index 379aeb5112c..7bfa82a3876 100644 --- a/integration-tests/otlp/src/main/java/io/opentelemetry/integrationtest/OtlpExporterIntegrationTest.java +++ b/integration-tests/otlp/src/main/java/io/opentelemetry/integrationtest/OtlpExporterIntegrationTest.java @@ -124,7 +124,10 @@ abstract class OtlpExporterIntegrationTest { @RegisterExtension static final SelfSignedCertificateExtension clientTls = new SelfSignedCertificateExtension(); + @SuppressWarnings("NonFinalStaticField") private static OtlpGrpcServer grpcServer; + + @SuppressWarnings("NonFinalStaticField") private static GenericContainer collector; @BeforeAll diff --git a/integration-tests/src/test/java/io/opentelemetry/B3PropagationIntegrationTest.java b/integration-tests/src/test/java/io/opentelemetry/B3PropagationIntegrationTest.java index b87db824a26..66eaa8e6cef 100644 --- a/integration-tests/src/test/java/io/opentelemetry/B3PropagationIntegrationTest.java +++ b/integration-tests/src/test/java/io/opentelemetry/B3PropagationIntegrationTest.java @@ -50,7 +50,10 @@ class B3PropagationIntegrationTest { private static final InMemorySpanExporter spanExporter = InMemorySpanExporter.create(); + @SuppressWarnings("NonFinalStaticField") static WebClient b3MultiClient; + + @SuppressWarnings("NonFinalStaticField") static WebClient b3SingleClient; private static class FrontendService implements HttpService { diff --git a/opentracing-shim/src/test/java/io/opentelemetry/opentracingshim/TracerShimTest.java b/opentracing-shim/src/test/java/io/opentelemetry/opentracingshim/TracerShimTest.java index d15d7d98d6b..8a961288c23 100644 --- a/opentracing-shim/src/test/java/io/opentelemetry/opentracingshim/TracerShimTest.java +++ b/opentracing-shim/src/test/java/io/opentelemetry/opentracingshim/TracerShimTest.java @@ -45,7 +45,8 @@ class TracerShimTest { static final io.opentelemetry.api.baggage.Baggage EMPTY_BAGGAGE = io.opentelemetry.api.baggage.Baggage.empty(); - @RegisterExtension static OpenTelemetryExtension otelTesting = OpenTelemetryExtension.create(); + @RegisterExtension + static final OpenTelemetryExtension otelTesting = OpenTelemetryExtension.create(); TracerShim tracerShim; TracerProvider provider; diff --git a/perf-harness/src/test/java/io/opentelemetry/perf/OtlpPipelineStressTest.java b/perf-harness/src/test/java/io/opentelemetry/perf/OtlpPipelineStressTest.java index 2e175fd4873..0538d8f011f 100644 --- a/perf-harness/src/test/java/io/opentelemetry/perf/OtlpPipelineStressTest.java +++ b/perf-harness/src/test/java/io/opentelemetry/perf/OtlpPipelineStressTest.java @@ -61,13 +61,13 @@ public class OtlpPipelineStressTest { public static final int OTLP_RECEIVER_PORT = 4317; public static final int COLLECTOR_PROXY_PORT = 44444; public static final int TOXIPROXY_CONTROL_PORT = 8474; - public static Network network = Network.newNetwork(); - public static AtomicLong totalSpansReceivedByCollector = new AtomicLong(); + public static final Network network = Network.newNetwork(); + public static final AtomicLong totalSpansReceivedByCollector = new AtomicLong(); private static final Logger logger = LoggerFactory.getLogger(OtlpPipelineStressTest.class); @Container - public static GenericContainer collectorContainer = + public static final GenericContainer collectorContainer = new GenericContainer<>( DockerImageName.parse("ghcr.io/open-telemetry/opentelemetry-java/otel-collector")) .withImagePullPolicy(PullPolicy.alwaysPull()) @@ -93,7 +93,7 @@ public class OtlpPipelineStressTest { .waitingFor(new LogMessageWaitStrategy().withRegEx(".*Everything is ready.*")); @Container - public static GenericContainer toxiproxyContainer = + public static final GenericContainer toxiproxyContainer = new GenericContainer<>( DockerImageName.parse("ghcr.io/open-telemetry/opentelemetry-java/toxiproxy")) .withImagePullPolicy(PullPolicy.alwaysPull()) diff --git a/sdk-extensions/jaeger-remote-sampler/src/test/java/io/opentelemetry/sdk/extension/trace/jaeger/sampler/JaegerRemoteSamplerIntegrationTest.java b/sdk-extensions/jaeger-remote-sampler/src/test/java/io/opentelemetry/sdk/extension/trace/jaeger/sampler/JaegerRemoteSamplerIntegrationTest.java index fd36ee29ca4..c873808c332 100644 --- a/sdk-extensions/jaeger-remote-sampler/src/test/java/io/opentelemetry/sdk/extension/trace/jaeger/sampler/JaegerRemoteSamplerIntegrationTest.java +++ b/sdk-extensions/jaeger-remote-sampler/src/test/java/io/opentelemetry/sdk/extension/trace/jaeger/sampler/JaegerRemoteSamplerIntegrationTest.java @@ -35,7 +35,7 @@ class JaegerRemoteSamplerIntegrationTest { private static final String SERVICE_NAME_DEFAULT_STRATEGY = "foobar"; @Container - public static GenericContainer jaegerContainer = + public static final GenericContainer jaegerContainer = new GenericContainer<>("ghcr.io/open-telemetry/opentelemetry-java/jaeger:1.32") .withImagePullPolicy(PullPolicy.alwaysPull()) .withCommand("--sampling.strategies-file=/sampling.json") diff --git a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/debug/DebugConfig.java b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/debug/DebugConfig.java index db5b82081d4..7228aa2be4e 100644 --- a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/debug/DebugConfig.java +++ b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/debug/DebugConfig.java @@ -15,6 +15,8 @@ */ public final class DebugConfig { private static final String ENABLE_METRICS_DEBUG_PROPERTY = "otel.experimental.sdk.metrics.debug"; + + @SuppressWarnings("NonFinalStaticField") private static boolean enabled; private DebugConfig() {} diff --git a/sdk/testing/src/main/java/io/opentelemetry/sdk/testing/context/SettableContextStorageProvider.java b/sdk/testing/src/main/java/io/opentelemetry/sdk/testing/context/SettableContextStorageProvider.java index 1a34c3eade4..22b4fc6ec87 100644 --- a/sdk/testing/src/main/java/io/opentelemetry/sdk/testing/context/SettableContextStorageProvider.java +++ b/sdk/testing/src/main/java/io/opentelemetry/sdk/testing/context/SettableContextStorageProvider.java @@ -34,6 +34,7 @@ public static ContextStorage getContextStorage() { private enum SettableContextStorage implements ContextStorage { INSTANCE; + @SuppressWarnings("NonFinalStaticField") private static volatile ContextStorage delegate = createStorage(); @Override diff --git a/sdk/trace/src/jmh/java/io/opentelemetry/sdk/trace/ExceptionBenchmark.java b/sdk/trace/src/jmh/java/io/opentelemetry/sdk/trace/ExceptionBenchmark.java index 438deb7b69d..7dd1298345b 100644 --- a/sdk/trace/src/jmh/java/io/opentelemetry/sdk/trace/ExceptionBenchmark.java +++ b/sdk/trace/src/jmh/java/io/opentelemetry/sdk/trace/ExceptionBenchmark.java @@ -25,6 +25,7 @@ @State(Scope.Benchmark) public class ExceptionBenchmark { + @SuppressWarnings("NonFinalStaticField") private static SpanBuilder spanBuilder; @Setup(Level.Trial) diff --git a/sdk/trace/src/jmh/java/io/opentelemetry/sdk/trace/SpanBenchmark.java b/sdk/trace/src/jmh/java/io/opentelemetry/sdk/trace/SpanBenchmark.java index c8063e1bb07..cf0cf3737c8 100644 --- a/sdk/trace/src/jmh/java/io/opentelemetry/sdk/trace/SpanBenchmark.java +++ b/sdk/trace/src/jmh/java/io/opentelemetry/sdk/trace/SpanBenchmark.java @@ -24,7 +24,9 @@ @State(Scope.Benchmark) public class SpanBenchmark { + @SuppressWarnings("NonFinalStaticField") private static SdkSpanBuilder sdkSpanBuilder; + private final Resource serviceResource = Resource.create( Attributes.builder() From 82a0e03add880ecfe1b6ad8b72bccbd393a585cb Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 23 Oct 2023 11:03:10 -0500 Subject: [PATCH 066/901] Update dependency com.google.api.grpc:proto-google-common-protos to v2.27.0 (#5933) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- dependencyManagement/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index 89c1624878d..a56615e81bc 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -55,7 +55,7 @@ val DEPENDENCIES = listOf( "io.prometheus:simpleclient_httpserver:${prometheusClientVersion}", "javax.annotation:javax.annotation-api:1.3.2", "com.github.stefanbirkner:system-rules:1.19.0", - "com.google.api.grpc:proto-google-common-protos:2.26.0", + "com.google.api.grpc:proto-google-common-protos:2.27.0", "com.google.code.findbugs:jsr305:3.0.2", "com.google.guava:guava-beta-checker:1.0", "com.sun.net.httpserver:http:20070405", From e06d35add577fd702104b5b2836201e76f72d88b Mon Sep 17 00:00:00 2001 From: jack-berg <34418638+jack-berg@users.noreply.github.com> Date: Mon, 23 Oct 2023 11:03:50 -0500 Subject: [PATCH 067/901] JdkHttpSender should retry on connect exceptions (#5867) --- exporters/sender/jdk/build.gradle.kts | 5 + .../sender/jdk/internal/JdkHttpSender.java | 117 +++++++++++++----- .../jdk/internal/JdkHttpSenderTest.java | 95 ++++++++++++++ 3 files changed, 186 insertions(+), 31 deletions(-) create mode 100644 exporters/sender/jdk/src/test/java/io/opentelemetry/exporter/sender/jdk/internal/JdkHttpSenderTest.java diff --git a/exporters/sender/jdk/build.gradle.kts b/exporters/sender/jdk/build.gradle.kts index 2784bc66cb1..80fb0f870d3 100644 --- a/exporters/sender/jdk/build.gradle.kts +++ b/exporters/sender/jdk/build.gradle.kts @@ -18,3 +18,8 @@ tasks { options.release.set(11) } } + +tasks.test { + val testJavaVersion: String? by project + enabled = !testJavaVersion.equals("8") +} diff --git a/exporters/sender/jdk/src/main/java/io/opentelemetry/exporter/sender/jdk/internal/JdkHttpSender.java b/exporters/sender/jdk/src/main/java/io/opentelemetry/exporter/sender/jdk/internal/JdkHttpSender.java index 5739ffb5596..fda90c6a8c7 100644 --- a/exporters/sender/jdk/src/main/java/io/opentelemetry/exporter/sender/jdk/internal/JdkHttpSender.java +++ b/exporters/sender/jdk/src/main/java/io/opentelemetry/exporter/sender/jdk/internal/JdkHttpSender.java @@ -16,6 +16,7 @@ import java.net.http.HttpClient; import java.net.http.HttpRequest; import java.net.http.HttpResponse; +import java.net.http.HttpTimeoutException; import java.nio.ByteBuffer; import java.time.Duration; import java.util.Map; @@ -56,19 +57,16 @@ public final class JdkHttpSender implements HttpSender { private final Supplier> headerSupplier; @Nullable private final RetryPolicy retryPolicy; + // Visible for testing JdkHttpSender( + HttpClient client, String endpoint, boolean compressionEnabled, String contentType, long timeoutNanos, Supplier> headerSupplier, - @Nullable RetryPolicy retryPolicy, - @Nullable SSLContext sslContext) { - HttpClient.Builder builder = HttpClient.newBuilder().executor(executorService); - if (sslContext != null) { - builder.sslContext(sslContext); - } - this.client = builder.build(); + @Nullable RetryPolicy retryPolicy) { + this.client = client; try { this.uri = new URI(endpoint); } catch (URISyntaxException e) { @@ -81,6 +79,36 @@ public final class JdkHttpSender implements HttpSender { this.retryPolicy = retryPolicy; } + JdkHttpSender( + String endpoint, + boolean compressionEnabled, + String contentType, + long timeoutNanos, + Supplier> headerSupplier, + @Nullable RetryPolicy retryPolicy, + @Nullable SSLContext sslContext) { + this( + configureClient(sslContext), + endpoint, + compressionEnabled, + contentType, + timeoutNanos, + headerSupplier, + retryPolicy); + } + + private static HttpClient configureClient(@Nullable SSLContext sslContext) { + HttpClient.Builder builder = + HttpClient.newBuilder() + // Aligned with OkHttpClient default connect timeout + // TODO (jack-berg): Consider making connect timeout configurable + .connectTimeout(Duration.ofSeconds(10)); + if (sslContext != null) { + builder.sslContext(sslContext); + } + return builder.build(); + } + @Override public void send( Consumer marshaler, @@ -88,7 +116,15 @@ public void send( Consumer onResponse, Consumer onError) { CompletableFuture> unused = - CompletableFuture.supplyAsync(() -> sendInternal(marshaler), executorService) + CompletableFuture.supplyAsync( + () -> { + try { + return sendInternal(marshaler); + } catch (IOException e) { + throw new IllegalStateException(e); + } + }, + executorService) .whenComplete( (httpResponse, throwable) -> { if (throwable != null) { @@ -99,7 +135,8 @@ public void send( }); } - private HttpResponse sendInternal(Consumer marshaler) { + // Visible for testing + HttpResponse sendInternal(Consumer marshaler) throws IOException { long startTimeNanos = System.nanoTime(); HttpRequest.Builder requestBuilder = HttpRequest.newBuilder().uri(uri).timeout(Duration.ofNanos(timeoutNanos)); @@ -129,46 +166,64 @@ private HttpResponse sendInternal(Consumer marshaler) { long attempt = 0; long nextBackoffNanos = retryPolicy.getInitialBackoff().toNanos(); + HttpResponse httpResponse = null; + IOException exception = null; do { - requestBuilder.timeout(Duration.ofNanos(timeoutNanos - (System.nanoTime() - startTimeNanos))); - HttpResponse httpResponse = sendRequest(requestBuilder, byteBufferPool); - attempt++; - if (attempt >= retryPolicy.getMaxAttempts() - || !retryableStatusCodes.contains(httpResponse.statusCode())) { - return httpResponse; + if (attempt > 0) { + // Compute and sleep for backoff + long upperBoundNanos = Math.min(nextBackoffNanos, retryPolicy.getMaxBackoff().toNanos()); + long backoffNanos = ThreadLocalRandom.current().nextLong(upperBoundNanos); + nextBackoffNanos = (long) (nextBackoffNanos * retryPolicy.getBackoffMultiplier()); + try { + TimeUnit.NANOSECONDS.sleep(backoffNanos); + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + break; // Break out and return response or throw + } + // If after sleeping we've exceeded timeoutNanos, break out and return response or throw + if ((System.nanoTime() - startTimeNanos) >= timeoutNanos) { + break; + } } - // Compute and sleep for backoff - long upperBoundNanos = Math.min(nextBackoffNanos, retryPolicy.getMaxBackoff().toNanos()); - long backoffNanos = ThreadLocalRandom.current().nextLong(upperBoundNanos); - nextBackoffNanos = (long) (nextBackoffNanos * retryPolicy.getBackoffMultiplier()); + attempt++; + requestBuilder.timeout(Duration.ofNanos(timeoutNanos - (System.nanoTime() - startTimeNanos))); try { - TimeUnit.NANOSECONDS.sleep(backoffNanos); - } catch (InterruptedException e) { - Thread.currentThread().interrupt(); - throw new IllegalStateException(e); + httpResponse = sendRequest(requestBuilder, byteBufferPool); + } catch (IOException e) { + exception = e; } - if ((System.nanoTime() - startTimeNanos) >= timeoutNanos) { + + if (httpResponse != null && !retryableStatusCodes.contains(httpResponse.statusCode())) { return httpResponse; } - } while (true); + if (exception != null && !isRetryableException(exception)) { + throw exception; + } + } while (attempt < retryPolicy.getMaxAttempts()); + + if (httpResponse != null) { + return httpResponse; + } + throw exception; } private HttpResponse sendRequest( - HttpRequest.Builder requestBuilder, ByteBufferPool byteBufferPool) { + HttpRequest.Builder requestBuilder, ByteBufferPool byteBufferPool) throws IOException { try { return client.send(requestBuilder.build(), HttpResponse.BodyHandlers.ofByteArray()); - } catch (IOException | InterruptedException e) { - if (e instanceof InterruptedException) { - Thread.currentThread().interrupt(); - } - // TODO: is throwable retryable? + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); throw new IllegalStateException(e); } finally { byteBufferPool.resetPool(); } } + private static boolean isRetryableException(IOException throwable) { + return throwable instanceof HttpTimeoutException; + } + private static class NoCopyByteArrayOutputStream extends ByteArrayOutputStream { NoCopyByteArrayOutputStream() { super(retryableStatusCodes.size()); diff --git a/exporters/sender/jdk/src/test/java/io/opentelemetry/exporter/sender/jdk/internal/JdkHttpSenderTest.java b/exporters/sender/jdk/src/test/java/io/opentelemetry/exporter/sender/jdk/internal/JdkHttpSenderTest.java new file mode 100644 index 00000000000..2691bb1ca3f --- /dev/null +++ b/exporters/sender/jdk/src/test/java/io/opentelemetry/exporter/sender/jdk/internal/JdkHttpSenderTest.java @@ -0,0 +1,95 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.exporter.sender.jdk.internal; + +import static org.assertj.core.api.Assertions.as; +import static org.assertj.core.api.AssertionsForClassTypes.assertThat; +import static org.assertj.core.api.AssertionsForClassTypes.assertThatThrownBy; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.doThrow; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import io.opentelemetry.sdk.common.export.RetryPolicy; +import java.io.IOException; +import java.net.http.HttpClient; +import java.net.http.HttpConnectTimeoutException; +import java.time.Duration; +import java.util.Collections; +import org.assertj.core.api.InstanceOfAssertFactories; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; +import org.mockito.junit.jupiter.MockitoSettings; +import org.mockito.quality.Strictness; + +@ExtendWith(MockitoExtension.class) +@MockitoSettings(strictness = Strictness.LENIENT) +class JdkHttpSenderTest { + + private final HttpClient realHttpClient = + HttpClient.newBuilder().connectTimeout(Duration.ofMillis(10)).build(); + @Mock private HttpClient mockHttpClient; + private JdkHttpSender sender; + + @BeforeEach + void setup() throws IOException, InterruptedException { + // Can't directly spy on HttpClient for some reason, so create a real instance and a mock that + // delegates to the real thing + when(mockHttpClient.send(any(), any())) + .thenAnswer( + invocation -> + realHttpClient.send(invocation.getArgument(0), invocation.getArgument(1))); + sender = + new JdkHttpSender( + mockHttpClient, + "http://10.255.255.1", // Connecting to a non-routable IP address to trigger connection + // timeout + false, + "text/plain", + Duration.ofSeconds(10).toNanos(), + Collections::emptyMap, + RetryPolicy.builder() + .setMaxAttempts(2) + .setInitialBackoff(Duration.ofMillis(1)) + .build()); + } + + @Test + void sendInternal_RetryableConnectTimeoutException() throws IOException, InterruptedException { + assertThatThrownBy(() -> sender.sendInternal(marshaler -> {})) + .isInstanceOf(HttpConnectTimeoutException.class); + + verify(mockHttpClient, times(2)).send(any(), any()); + } + + @Test + void sendInternal_NonRetryableException() throws IOException, InterruptedException { + doThrow(new IOException("unknown error")).when(mockHttpClient).send(any(), any()); + + assertThatThrownBy(() -> sender.sendInternal(marshaler -> {})) + .isInstanceOf(IOException.class) + .hasMessage("unknown error"); + + verify(mockHttpClient, times(1)).send(any(), any()); + } + + @Test + void defaultConnectTimeout() { + sender = + new JdkHttpSender( + "http://localhost", true, "text/plain", 1, Collections::emptyMap, null, null); + + assertThat(sender) + .extracting("client", as(InstanceOfAssertFactories.type(HttpClient.class))) + .satisfies( + httpClient -> + assertThat(httpClient.connectTimeout().get()).isEqualTo(Duration.ofSeconds(10))); + } +} From 6c931951b3a8e7a4d7250e793f72372e330c2550 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 27 Oct 2023 14:45:28 -0500 Subject: [PATCH 068/901] Update dependency me.champeau.jmh:jmh-gradle-plugin to v0.7.2 (#5946) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- buildSrc/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts index ca79346af23..3bc47d01f0e 100644 --- a/buildSrc/build.gradle.kts +++ b/buildSrc/build.gradle.kts @@ -54,7 +54,7 @@ dependencies { implementation("gradle.plugin.com.google.protobuf:protobuf-gradle-plugin:0.8.18") implementation("gradle.plugin.io.morethan.jmhreport:gradle-jmh-report:0.9.0") implementation("me.champeau.gradle:japicmp-gradle-plugin:0.4.2") - implementation("me.champeau.jmh:jmh-gradle-plugin:0.7.1") + implementation("me.champeau.jmh:jmh-gradle-plugin:0.7.2") implementation("net.ltgt.gradle:gradle-errorprone-plugin:3.1.0") implementation("net.ltgt.gradle:gradle-nullaway-plugin:1.6.0") implementation("org.jetbrains.kotlin:kotlin-gradle-plugin:1.9.10") From 976edfde504193f84d19936b97e2eb8d8cf060e2 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 27 Oct 2023 14:45:48 -0500 Subject: [PATCH 069/901] Update dependency com.linecorp.armeria:armeria-bom to v1.26.0 (#5943) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- dependencyManagement/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index a56615e81bc..1bc0630d1df 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -11,7 +11,7 @@ val DEPENDENCY_BOMS = listOf( "com.fasterxml.jackson:jackson-bom:2.15.3", "com.google.guava:guava-bom:32.1.3-jre", "com.google.protobuf:protobuf-bom:3.24.4", - "com.linecorp.armeria:armeria-bom:1.25.2", + "com.linecorp.armeria:armeria-bom:1.26.0", "com.squareup.okhttp3:okhttp-bom:4.12.0", "com.squareup.okio:okio-bom:3.6.0", // applies to transitive dependencies of okhttp "io.grpc:grpc-bom:1.59.0", From 33d3a9213c38feaa8e44e07e52087a23c2b327c2 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 30 Oct 2023 16:52:19 -0500 Subject: [PATCH 070/901] Update dependency com.linecorp.armeria:armeria-bom to v1.26.1 (#5947) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- dependencyManagement/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index 1bc0630d1df..b59ffeba1dd 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -11,7 +11,7 @@ val DEPENDENCY_BOMS = listOf( "com.fasterxml.jackson:jackson-bom:2.15.3", "com.google.guava:guava-bom:32.1.3-jre", "com.google.protobuf:protobuf-bom:3.24.4", - "com.linecorp.armeria:armeria-bom:1.26.0", + "com.linecorp.armeria:armeria-bom:1.26.1", "com.squareup.okhttp3:okhttp-bom:4.12.0", "com.squareup.okio:okio-bom:3.6.0", // applies to transitive dependencies of okhttp "io.grpc:grpc-bom:1.59.0", From ccb2e04237242b44e368524a41954941e2a8fe28 Mon Sep 17 00:00:00 2001 From: Abdolsamad Montazeri Shahtoori Date: Tue, 31 Oct 2023 20:30:34 +0200 Subject: [PATCH 071/901] Fix opentracing header name issue (#5840) --- .../trace/propagation/OtTracePropagator.java | 8 +++-- .../propagation/OtTracePropagatorTest.java | 29 +++++++++++++++++++ 2 files changed, 35 insertions(+), 2 deletions(-) diff --git a/extensions/trace-propagators/src/main/java/io/opentelemetry/extension/trace/propagation/OtTracePropagator.java b/extensions/trace-propagators/src/main/java/io/opentelemetry/extension/trace/propagation/OtTracePropagator.java index 3bd0ed771fe..105c3830c7e 100644 --- a/extensions/trace-propagators/src/main/java/io/opentelemetry/extension/trace/propagation/OtTracePropagator.java +++ b/extensions/trace-propagators/src/main/java/io/opentelemetry/extension/trace/propagation/OtTracePropagator.java @@ -20,6 +20,7 @@ import java.util.Arrays; import java.util.Collection; import java.util.Collections; +import java.util.Locale; import javax.annotation.Nullable; import javax.annotation.concurrent.Immutable; @@ -108,14 +109,17 @@ public Context extract(Context context, @Nullable C carrier, TextMapGetter carrier = new LinkedHashMap<>(); @@ -313,6 +326,22 @@ void extract_Baggage() { assertThat(Baggage.fromContext(context)).isEqualTo(expectedBaggage); } + @Test + void extract_Baggage_CapitalizedHeaders() { + String capitalizedBaggageHeader = + capitalizeFirstLetter(OtTracePropagator.PREFIX_BAGGAGE_HEADER + "some-key", "-"); + Map carrier = new LinkedHashMap<>(); + carrier.put(OtTracePropagator.TRACE_ID_HEADER, TRACE_ID); + carrier.put(OtTracePropagator.SPAN_ID_HEADER, SPAN_ID); + carrier.put(OtTracePropagator.SAMPLED_HEADER, Common.TRUE_INT); + carrier.put(capitalizedBaggageHeader, "value"); + + Context context = propagator.extract(Context.current(), carrier, getter); + + Baggage expectedBaggage = Baggage.builder().put("some-key", "value").build(); + assertThat(Baggage.fromContext(context)).isEqualTo(expectedBaggage); + } + @Test void extract_Baggage_InvalidContext() { Map carrier = new LinkedHashMap<>(); From efa46a5dccb962b50943a0b4905c1800282d6be6 Mon Sep 17 00:00:00 2001 From: jack-berg <34418638+jack-berg@users.noreply.github.com> Date: Tue, 31 Oct 2023 15:05:36 -0500 Subject: [PATCH 072/901] Experimental support for Log AnyValue body (#5880) --- .../internal/otlp/logs/LogMarshaler.java | 2 +- extensions/incubator/build.gradle.kts | 2 + .../extension/incubator/logs/AnyValue.java | 106 +++++++++ .../incubator/logs/AnyValueArray.java | 63 +++++ .../incubator/logs/AnyValueBoolean.java | 54 +++++ .../incubator/logs/AnyValueBytes.java | 62 +++++ .../incubator/logs/AnyValueDouble.java | 54 +++++ .../incubator/logs/AnyValueLong.java | 54 +++++ .../incubator/logs/AnyValueString.java | 55 +++++ .../incubator/logs/AnyValueType.java | 21 ++ .../logs/ExtendedLogRecordBuilder.java | 15 ++ .../extension/incubator/logs/KeyAnyValue.java | 25 ++ .../incubator/logs/KeyAnyValueImpl.java | 18 ++ .../incubator/logs/KeyAnyValueList.java | 75 ++++++ .../incubator/logs/AnyValueTest.java | 223 ++++++++++++++++++ sdk/logs/build.gradle.kts | 2 + .../sdk/logs/SdkLogRecordBuilder.java | 11 +- .../io/opentelemetry/sdk/logs/data/Body.java | 2 + .../sdk/logs/internal/AnyValueBody.java | 43 ++++ .../sdk/logs/AnyValueBodyTest.java | 156 ++++++++++++ 20 files changed, 1041 insertions(+), 2 deletions(-) create mode 100644 extensions/incubator/src/main/java/io/opentelemetry/extension/incubator/logs/AnyValue.java create mode 100644 extensions/incubator/src/main/java/io/opentelemetry/extension/incubator/logs/AnyValueArray.java create mode 100644 extensions/incubator/src/main/java/io/opentelemetry/extension/incubator/logs/AnyValueBoolean.java create mode 100644 extensions/incubator/src/main/java/io/opentelemetry/extension/incubator/logs/AnyValueBytes.java create mode 100644 extensions/incubator/src/main/java/io/opentelemetry/extension/incubator/logs/AnyValueDouble.java create mode 100644 extensions/incubator/src/main/java/io/opentelemetry/extension/incubator/logs/AnyValueLong.java create mode 100644 extensions/incubator/src/main/java/io/opentelemetry/extension/incubator/logs/AnyValueString.java create mode 100644 extensions/incubator/src/main/java/io/opentelemetry/extension/incubator/logs/AnyValueType.java create mode 100644 extensions/incubator/src/main/java/io/opentelemetry/extension/incubator/logs/ExtendedLogRecordBuilder.java create mode 100644 extensions/incubator/src/main/java/io/opentelemetry/extension/incubator/logs/KeyAnyValue.java create mode 100644 extensions/incubator/src/main/java/io/opentelemetry/extension/incubator/logs/KeyAnyValueImpl.java create mode 100644 extensions/incubator/src/main/java/io/opentelemetry/extension/incubator/logs/KeyAnyValueList.java create mode 100644 extensions/incubator/src/test/java/io/opentelemetry/extension/incubator/logs/AnyValueTest.java create mode 100644 sdk/logs/src/main/java/io/opentelemetry/sdk/logs/internal/AnyValueBody.java create mode 100644 sdk/logs/src/test/java/io/opentelemetry/sdk/logs/AnyValueBodyTest.java diff --git a/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/logs/LogMarshaler.java b/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/logs/LogMarshaler.java index bd2c6b3b8a2..7a68041e5d1 100644 --- a/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/logs/LogMarshaler.java +++ b/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/logs/LogMarshaler.java @@ -41,7 +41,7 @@ static LogMarshaler create(LogRecordData logRecordData) { KeyValueMarshaler[] attributeMarshalers = KeyValueMarshaler.createRepeated(logRecordData.getAttributes()); - // For now, map all the bodies to String AnyValue. + // TODO(jack-berg): handle AnyValue log body StringAnyValueMarshaler anyValueMarshaler = new StringAnyValueMarshaler(MarshalerUtil.toBytes(logRecordData.getBody().asString())); diff --git a/extensions/incubator/build.gradle.kts b/extensions/incubator/build.gradle.kts index 6acaf6cddb2..6e79f9361fd 100644 --- a/extensions/incubator/build.gradle.kts +++ b/extensions/incubator/build.gradle.kts @@ -12,5 +12,7 @@ otelJava.moduleName.set("io.opentelemetry.extension.incubator") dependencies { api(project(":api:all")) + annotationProcessor("com.google.auto.value:auto-value") + testImplementation(project(":sdk:testing")) } diff --git a/extensions/incubator/src/main/java/io/opentelemetry/extension/incubator/logs/AnyValue.java b/extensions/incubator/src/main/java/io/opentelemetry/extension/incubator/logs/AnyValue.java new file mode 100644 index 00000000000..6f250e10da7 --- /dev/null +++ b/extensions/incubator/src/main/java/io/opentelemetry/extension/incubator/logs/AnyValue.java @@ -0,0 +1,106 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.extension.incubator.logs; + +import java.nio.ByteBuffer; +import java.util.List; +import java.util.Map; + +/** + * AnyValue mirrors the proto AnyValue + * message type, and is used to model any type. + * + *

    It can be used to represent: + * + *

      + *
    • Primitive values via {@link #of(long)}, {@link #of(String)}, {@link #of(boolean)}, {@link + * #of(double)}. + *
    • String-keyed maps (i.e. associative arrays, dictionaries) via {@link #of(KeyAnyValue...)}, + * {@link #of(Map)}. Note, because map values are type {@link AnyValue}, maps can be nested + * within other maps. + *
    • Arrays (heterogeneous or homogenous) via {@link #of(AnyValue[])}. Note, because array + * values are type {@link AnyValue}, arrays can contain primitives, complex types like maps or + * arrays, or any combination. + *
    • Raw bytes via {@link #of(byte[])} + *
    + * + * @param the type. See {@link #getValue()} for description of types. + */ +public interface AnyValue { + + /** Returns an {@link AnyValue} for the {@link String} value. */ + static AnyValue of(String value) { + return AnyValueString.create(value); + } + + /** Returns an {@link AnyValue} for the {@code boolean} value. */ + static AnyValue of(boolean value) { + return AnyValueBoolean.create(value); + } + + /** Returns an {@link AnyValue} for the {@code long} value. */ + static AnyValue of(long value) { + return AnyValueLong.create(value); + } + + /** Returns an {@link AnyValue} for the {@code double} value. */ + static AnyValue of(double value) { + return AnyValueDouble.create(value); + } + + /** Returns an {@link AnyValue} for the {@code byte[]} value. */ + static AnyValue of(byte[] value) { + return AnyValueBytes.create(value); + } + + /** Returns an {@link AnyValue} for the array of {@link AnyValue} values. */ + static AnyValue>> of(AnyValue... value) { + return AnyValueArray.create(value); + } + + /** + * Returns an {@link AnyValue} for the array of {@link KeyAnyValue} values. {@link + * KeyAnyValue#getKey()} values should not repeat - duplicates may be dropped. + */ + static AnyValue> of(KeyAnyValue... value) { + return KeyAnyValueList.create(value); + } + + /** Returns an {@link AnyValue} for the {@link Map} of key, {@link AnyValue}. */ + static AnyValue> of(Map> value) { + return KeyAnyValueList.createFromMap(value); + } + + /** Returns the type of this {@link AnyValue}. Useful for building switch statements. */ + AnyValueType getType(); + + /** + * Returns the value for this {@link AnyValue}. + * + *

    The return type varies by {@link #getType()} as described below: + * + *

      + *
    • {@link AnyValueType#STRING} returns {@link String} + *
    • {@link AnyValueType#BOOLEAN} returns {@code boolean} + *
    • {@link AnyValueType#LONG} returns {@code long} + *
    • {@link AnyValueType#DOUBLE} returns {@code double} + *
    • {@link AnyValueType#ARRAY} returns {@link List} of {@link AnyValue} + *
    • {@link AnyValueType#KEY_VALUE_LIST} returns {@link List} of {@link KeyAnyValue} + *
    • {@link AnyValueType#BYTES} returns read only {@link ByteBuffer}. See {@link + * ByteBuffer#asReadOnlyBuffer()}. + *
    + */ + T getValue(); + + /** + * Return a string encoding of this {@link AnyValue}. This is intended to be a fallback serialized + * representation in case there is no suitable encoding that can utilize {@link #getType()} / + * {@link #getValue()} to serialize specific types. + */ + // TODO(jack-berg): Should this be a JSON encoding? + String asString(); +} diff --git a/extensions/incubator/src/main/java/io/opentelemetry/extension/incubator/logs/AnyValueArray.java b/extensions/incubator/src/main/java/io/opentelemetry/extension/incubator/logs/AnyValueArray.java new file mode 100644 index 00000000000..dd96a60793d --- /dev/null +++ b/extensions/incubator/src/main/java/io/opentelemetry/extension/incubator/logs/AnyValueArray.java @@ -0,0 +1,63 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.extension.incubator.logs; + +import static java.util.stream.Collectors.joining; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import java.util.Objects; + +final class AnyValueArray implements AnyValue>> { + + private final List> value; + + private AnyValueArray(List> value) { + this.value = value; + } + + static AnyValue>> create(AnyValue... value) { + Objects.requireNonNull(value, "value must not be null"); + List> list = new ArrayList<>(value.length); + list.addAll(Arrays.asList(value)); + return new AnyValueArray(Collections.unmodifiableList(list)); + } + + @Override + public AnyValueType getType() { + return AnyValueType.ARRAY; + } + + @Override + public List> getValue() { + return value; + } + + @Override + public String asString() { + return value.stream().map(AnyValue::asString).collect(joining(", ", "[", "]")); + } + + @Override + public String toString() { + return "AnyValueArray{" + asString() + "}"; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + return (o instanceof AnyValue) && Objects.equals(this.value, ((AnyValue) o).getValue()); + } + + @Override + public int hashCode() { + return value.hashCode(); + } +} diff --git a/extensions/incubator/src/main/java/io/opentelemetry/extension/incubator/logs/AnyValueBoolean.java b/extensions/incubator/src/main/java/io/opentelemetry/extension/incubator/logs/AnyValueBoolean.java new file mode 100644 index 00000000000..5fa862b777f --- /dev/null +++ b/extensions/incubator/src/main/java/io/opentelemetry/extension/incubator/logs/AnyValueBoolean.java @@ -0,0 +1,54 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.extension.incubator.logs; + +import java.util.Objects; + +final class AnyValueBoolean implements AnyValue { + + private final boolean value; + + private AnyValueBoolean(boolean value) { + this.value = value; + } + + static AnyValue create(boolean value) { + return new AnyValueBoolean(value); + } + + @Override + public AnyValueType getType() { + return AnyValueType.BOOLEAN; + } + + @Override + public Boolean getValue() { + return value; + } + + @Override + public String asString() { + return String.valueOf(value); + } + + @Override + public String toString() { + return "AnyValueBoolean{" + asString() + "}"; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + return (o instanceof AnyValue) && Objects.equals(this.value, ((AnyValue) o).getValue()); + } + + @Override + public int hashCode() { + return Boolean.hashCode(value); + } +} diff --git a/extensions/incubator/src/main/java/io/opentelemetry/extension/incubator/logs/AnyValueBytes.java b/extensions/incubator/src/main/java/io/opentelemetry/extension/incubator/logs/AnyValueBytes.java new file mode 100644 index 00000000000..1677a3313e8 --- /dev/null +++ b/extensions/incubator/src/main/java/io/opentelemetry/extension/incubator/logs/AnyValueBytes.java @@ -0,0 +1,62 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.extension.incubator.logs; + +import io.opentelemetry.api.internal.OtelEncodingUtils; +import java.nio.ByteBuffer; +import java.util.Arrays; +import java.util.Objects; + +final class AnyValueBytes implements AnyValue { + + private final byte[] raw; + + private AnyValueBytes(byte[] value) { + this.raw = value; + } + + static AnyValue create(byte[] value) { + Objects.requireNonNull(value, "value must not be null"); + return new AnyValueBytes(Arrays.copyOf(value, value.length)); + } + + @Override + public AnyValueType getType() { + return AnyValueType.BYTES; + } + + @Override + public ByteBuffer getValue() { + return ByteBuffer.wrap(raw).asReadOnlyBuffer(); + } + + @Override + public String asString() { + // TODO: base64 would be better, but isn't available in android and java. Can we vendor in a + // base64 implementation? + char[] arr = new char[raw.length * 2]; + OtelEncodingUtils.bytesToBase16(raw, arr, raw.length); + return new String(arr); + } + + @Override + public String toString() { + return "AnyValueBytes{" + asString() + "}"; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + return (o instanceof AnyValueBytes) && Arrays.equals(this.raw, ((AnyValueBytes) o).raw); + } + + @Override + public int hashCode() { + return Arrays.hashCode(raw); + } +} diff --git a/extensions/incubator/src/main/java/io/opentelemetry/extension/incubator/logs/AnyValueDouble.java b/extensions/incubator/src/main/java/io/opentelemetry/extension/incubator/logs/AnyValueDouble.java new file mode 100644 index 00000000000..4e2cdccf33b --- /dev/null +++ b/extensions/incubator/src/main/java/io/opentelemetry/extension/incubator/logs/AnyValueDouble.java @@ -0,0 +1,54 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.extension.incubator.logs; + +import java.util.Objects; + +final class AnyValueDouble implements AnyValue { + + private final double value; + + private AnyValueDouble(double value) { + this.value = value; + } + + static AnyValue create(double value) { + return new AnyValueDouble(value); + } + + @Override + public AnyValueType getType() { + return AnyValueType.DOUBLE; + } + + @Override + public Double getValue() { + return value; + } + + @Override + public String asString() { + return String.valueOf(value); + } + + @Override + public String toString() { + return "AnyValueDouble{" + asString() + "}"; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + return (o instanceof AnyValue) && Objects.equals(this.value, ((AnyValue) o).getValue()); + } + + @Override + public int hashCode() { + return Double.hashCode(value); + } +} diff --git a/extensions/incubator/src/main/java/io/opentelemetry/extension/incubator/logs/AnyValueLong.java b/extensions/incubator/src/main/java/io/opentelemetry/extension/incubator/logs/AnyValueLong.java new file mode 100644 index 00000000000..558a08376ee --- /dev/null +++ b/extensions/incubator/src/main/java/io/opentelemetry/extension/incubator/logs/AnyValueLong.java @@ -0,0 +1,54 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.extension.incubator.logs; + +import java.util.Objects; + +final class AnyValueLong implements AnyValue { + + private final long value; + + private AnyValueLong(long value) { + this.value = value; + } + + static AnyValue create(long value) { + return new AnyValueLong(value); + } + + @Override + public AnyValueType getType() { + return AnyValueType.LONG; + } + + @Override + public Long getValue() { + return value; + } + + @Override + public String asString() { + return String.valueOf(value); + } + + @Override + public String toString() { + return "AnyValueLong{" + asString() + "}"; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + return (o instanceof AnyValue) && Objects.equals(this.value, ((AnyValue) o).getValue()); + } + + @Override + public int hashCode() { + return Long.hashCode(value); + } +} diff --git a/extensions/incubator/src/main/java/io/opentelemetry/extension/incubator/logs/AnyValueString.java b/extensions/incubator/src/main/java/io/opentelemetry/extension/incubator/logs/AnyValueString.java new file mode 100644 index 00000000000..6a7b0a1c8e2 --- /dev/null +++ b/extensions/incubator/src/main/java/io/opentelemetry/extension/incubator/logs/AnyValueString.java @@ -0,0 +1,55 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.extension.incubator.logs; + +import java.util.Objects; + +final class AnyValueString implements AnyValue { + + private final String value; + + private AnyValueString(String value) { + this.value = value; + } + + static AnyValue create(String value) { + Objects.requireNonNull(value, "value must not be null"); + return new AnyValueString(value); + } + + @Override + public AnyValueType getType() { + return AnyValueType.STRING; + } + + @Override + public String getValue() { + return value; + } + + @Override + public String asString() { + return value; + } + + @Override + public String toString() { + return "AnyValueString{" + value + "}"; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + return (o instanceof AnyValue) && Objects.equals(this.value, ((AnyValue) o).getValue()); + } + + @Override + public int hashCode() { + return value.hashCode(); + } +} diff --git a/extensions/incubator/src/main/java/io/opentelemetry/extension/incubator/logs/AnyValueType.java b/extensions/incubator/src/main/java/io/opentelemetry/extension/incubator/logs/AnyValueType.java new file mode 100644 index 00000000000..f683cc61ea5 --- /dev/null +++ b/extensions/incubator/src/main/java/io/opentelemetry/extension/incubator/logs/AnyValueType.java @@ -0,0 +1,21 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.extension.incubator.logs; + +/** + * AnyValue type options, mirroring AnyValue#value + * options. + */ +public enum AnyValueType { + STRING, + BOOLEAN, + LONG, + DOUBLE, + ARRAY, + KEY_VALUE_LIST, + BYTES +} diff --git a/extensions/incubator/src/main/java/io/opentelemetry/extension/incubator/logs/ExtendedLogRecordBuilder.java b/extensions/incubator/src/main/java/io/opentelemetry/extension/incubator/logs/ExtendedLogRecordBuilder.java new file mode 100644 index 00000000000..b1ca789c1f6 --- /dev/null +++ b/extensions/incubator/src/main/java/io/opentelemetry/extension/incubator/logs/ExtendedLogRecordBuilder.java @@ -0,0 +1,15 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.extension.incubator.logs; + +import io.opentelemetry.api.logs.LogRecordBuilder; + +/** Extended {@link LogRecordBuilder} with experimental APIs. */ +public interface ExtendedLogRecordBuilder extends LogRecordBuilder { + + /** Set the body {@link AnyValue}. */ + LogRecordBuilder setBody(AnyValue body); +} diff --git a/extensions/incubator/src/main/java/io/opentelemetry/extension/incubator/logs/KeyAnyValue.java b/extensions/incubator/src/main/java/io/opentelemetry/extension/incubator/logs/KeyAnyValue.java new file mode 100644 index 00000000000..6aeb5eab6ab --- /dev/null +++ b/extensions/incubator/src/main/java/io/opentelemetry/extension/incubator/logs/KeyAnyValue.java @@ -0,0 +1,25 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.extension.incubator.logs; + +/** + * Key-value pair of {@link String} key and {@link AnyValue} value. + * + * @see AnyValue#of(KeyAnyValue...) + */ +public interface KeyAnyValue { + + /** Returns a {@link KeyAnyValue} for the given {@code key} and {@code value}. */ + static KeyAnyValue of(String key, AnyValue value) { + return KeyAnyValueImpl.create(key, value); + } + + /** Returns the key. */ + String getKey(); + + /** Returns the value. */ + AnyValue getAnyValue(); +} diff --git a/extensions/incubator/src/main/java/io/opentelemetry/extension/incubator/logs/KeyAnyValueImpl.java b/extensions/incubator/src/main/java/io/opentelemetry/extension/incubator/logs/KeyAnyValueImpl.java new file mode 100644 index 00000000000..516f46e0840 --- /dev/null +++ b/extensions/incubator/src/main/java/io/opentelemetry/extension/incubator/logs/KeyAnyValueImpl.java @@ -0,0 +1,18 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.extension.incubator.logs; + +import com.google.auto.value.AutoValue; + +@AutoValue +abstract class KeyAnyValueImpl implements KeyAnyValue { + + KeyAnyValueImpl() {} + + static KeyAnyValueImpl create(String key, AnyValue value) { + return new AutoValue_KeyAnyValueImpl(key, value); + } +} diff --git a/extensions/incubator/src/main/java/io/opentelemetry/extension/incubator/logs/KeyAnyValueList.java b/extensions/incubator/src/main/java/io/opentelemetry/extension/incubator/logs/KeyAnyValueList.java new file mode 100644 index 00000000000..427ed4cb13a --- /dev/null +++ b/extensions/incubator/src/main/java/io/opentelemetry/extension/incubator/logs/KeyAnyValueList.java @@ -0,0 +1,75 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.extension.incubator.logs; + +import static java.util.stream.Collectors.joining; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.Objects; + +final class KeyAnyValueList implements AnyValue> { + + private final List value; + + private KeyAnyValueList(List value) { + this.value = value; + } + + static AnyValue> create(KeyAnyValue... value) { + Objects.requireNonNull(value, "value must not be null"); + List list = new ArrayList<>(value.length); + list.addAll(Arrays.asList(value)); + return new KeyAnyValueList(Collections.unmodifiableList(list)); + } + + static AnyValue> createFromMap(Map> value) { + Objects.requireNonNull(value, "value must not be null"); + KeyAnyValue[] array = + value.entrySet().stream() + .map(entry -> KeyAnyValue.of(entry.getKey(), entry.getValue())) + .toArray(KeyAnyValue[]::new); + return create(array); + } + + @Override + public AnyValueType getType() { + return AnyValueType.KEY_VALUE_LIST; + } + + @Override + public List getValue() { + return value; + } + + @Override + public String asString() { + return value.stream() + .map(item -> item.getKey() + "=" + item.getAnyValue().asString()) + .collect(joining(", ", "[", "]")); + } + + @Override + public String toString() { + return "KeyAnyValueList{" + asString() + "}"; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + return (o instanceof AnyValue) && Objects.equals(this.value, ((AnyValue) o).getValue()); + } + + @Override + public int hashCode() { + return value.hashCode(); + } +} diff --git a/extensions/incubator/src/test/java/io/opentelemetry/extension/incubator/logs/AnyValueTest.java b/extensions/incubator/src/test/java/io/opentelemetry/extension/incubator/logs/AnyValueTest.java new file mode 100644 index 00000000000..842cd505c61 --- /dev/null +++ b/extensions/incubator/src/test/java/io/opentelemetry/extension/incubator/logs/AnyValueTest.java @@ -0,0 +1,223 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.extension.incubator.logs; + +import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.junit.jupiter.params.provider.Arguments.arguments; + +import io.opentelemetry.api.internal.OtelEncodingUtils; +import java.nio.ByteBuffer; +import java.nio.ReadOnlyBufferException; +import java.nio.charset.StandardCharsets; +import java.util.Arrays; +import java.util.Collections; +import java.util.LinkedHashMap; +import java.util.Map; +import java.util.stream.Stream; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; + +class AnyValueTest { + + @Test + void anyValue_OfString() { + assertThat(AnyValue.of("foo")) + .satisfies( + anyValue -> { + assertThat(anyValue.getType()).isEqualTo(AnyValueType.STRING); + assertThat(anyValue.getValue()).isEqualTo("foo"); + assertThat(anyValue).hasSameHashCodeAs(AnyValue.of("foo")); + }); + } + + @Test + void anyValue_OfBoolean() { + assertThat(AnyValue.of(true)) + .satisfies( + anyValue -> { + assertThat(anyValue.getType()).isEqualTo(AnyValueType.BOOLEAN); + assertThat(anyValue.getValue()).isEqualTo(true); + assertThat(anyValue).hasSameHashCodeAs(AnyValue.of(true)); + }); + } + + @Test + void anyValue_OfLong() { + assertThat(AnyValue.of(1L)) + .satisfies( + anyValue -> { + assertThat(anyValue.getType()).isEqualTo(AnyValueType.LONG); + assertThat(anyValue.getValue()).isEqualTo(1L); + assertThat(anyValue).hasSameHashCodeAs(AnyValue.of(1L)); + }); + } + + @Test + void anyValue_OfDouble() { + assertThat(AnyValue.of(1.1)) + .satisfies( + anyValue -> { + assertThat(anyValue.getType()).isEqualTo(AnyValueType.DOUBLE); + assertThat(anyValue.getValue()).isEqualTo(1.1); + assertThat(anyValue).hasSameHashCodeAs(AnyValue.of(1.1)); + }); + } + + @Test + void anyValue_OfByteArray() { + assertThat(AnyValue.of(new byte[] {'a', 'b'})) + .satisfies( + anyValue -> { + assertThat(anyValue.getType()).isEqualTo(AnyValueType.BYTES); + ByteBuffer value = anyValue.getValue(); + // AnyValueBytes returns read only view of ByteBuffer + assertThatThrownBy(value::array).isInstanceOf(ReadOnlyBufferException.class); + byte[] bytes = new byte[value.remaining()]; + value.get(bytes); + assertThat(bytes).isEqualTo(new byte[] {'a', 'b'}); + assertThat(anyValue).hasSameHashCodeAs(AnyValue.of(new byte[] {'a', 'b'})); + }); + } + + @Test + void anyValue_OfAnyValueArray() { + assertThat(AnyValue.of(AnyValue.of(true), AnyValue.of(1L))) + .satisfies( + anyValue -> { + assertThat(anyValue.getType()).isEqualTo(AnyValueType.ARRAY); + assertThat(anyValue.getValue()) + .isEqualTo(Arrays.asList(AnyValue.of(true), AnyValue.of(1L))); + assertThat(anyValue) + .hasSameHashCodeAs(AnyValue.of(AnyValue.of(true), AnyValue.of(1L))); + }); + } + + @Test + @SuppressWarnings("DoubleBraceInitialization") + void anyValue_OfKeyValueList() { + assertThat( + AnyValue.of( + KeyAnyValue.of("bool", AnyValue.of(true)), KeyAnyValue.of("long", AnyValue.of(1L)))) + .satisfies( + anyValue -> { + assertThat(anyValue.getType()).isEqualTo(AnyValueType.KEY_VALUE_LIST); + assertThat(anyValue.getValue()) + .isEqualTo( + Arrays.asList( + KeyAnyValue.of("bool", AnyValue.of(true)), + KeyAnyValue.of("long", AnyValue.of(1L)))); + assertThat(anyValue) + .hasSameHashCodeAs( + AnyValue.of( + KeyAnyValue.of("bool", AnyValue.of(true)), + KeyAnyValue.of("long", AnyValue.of(1L)))); + }); + + assertThat( + AnyValue.of( + new LinkedHashMap>() { + { + put("bool", AnyValue.of(true)); + put("long", AnyValue.of(1L)); + } + })) + .satisfies( + anyValue -> { + assertThat(anyValue.getType()).isEqualTo(AnyValueType.KEY_VALUE_LIST); + assertThat(anyValue.getValue()) + .isEqualTo( + Arrays.asList( + KeyAnyValue.of("bool", AnyValue.of(true)), + KeyAnyValue.of("long", AnyValue.of(1L)))); + assertThat(anyValue) + .hasSameHashCodeAs( + AnyValue.of( + new LinkedHashMap>() { + { + put("bool", AnyValue.of(true)); + put("long", AnyValue.of(1L)); + } + })); + }); + } + + @Test + void anyValue_NullsNotAllowed() { + assertThatThrownBy(() -> AnyValue.of((String) null)) + .isInstanceOf(NullPointerException.class) + .hasMessageContaining("value must not be null"); + assertThatThrownBy(() -> AnyValue.of((byte[]) null)) + .isInstanceOf(NullPointerException.class) + .hasMessageContaining("value must not be null"); + assertThatThrownBy(() -> AnyValue.of((AnyValue[]) null)) + .isInstanceOf(NullPointerException.class) + .hasMessageContaining("value must not be null"); + assertThatThrownBy(() -> AnyValue.of((KeyAnyValue[]) null)) + .isInstanceOf(NullPointerException.class) + .hasMessageContaining("value must not be null"); + assertThatThrownBy(() -> AnyValue.of((Map>) null)) + .isInstanceOf(NullPointerException.class) + .hasMessageContaining("value must not be null"); + } + + @ParameterizedTest + @MethodSource("asStringArgs") + void asString(AnyValue value, String expectedAsString) { + assertThat(value.asString()).isEqualTo(expectedAsString); + } + + @SuppressWarnings("DoubleBraceInitialization") + private static Stream asStringArgs() { + return Stream.of( + // primitives + arguments(AnyValue.of("str"), "str"), + arguments(AnyValue.of(true), "true"), + arguments(AnyValue.of(1), "1"), + arguments(AnyValue.of(1.1), "1.1"), + // heterogeneous array + arguments( + AnyValue.of(AnyValue.of("str"), AnyValue.of(true), AnyValue.of(1), AnyValue.of(1.1)), + "[str, true, 1, 1.1]"), + // key value list from KeyAnyValue array + arguments( + AnyValue.of( + KeyAnyValue.of("key1", AnyValue.of("val1")), + KeyAnyValue.of("key2", AnyValue.of(2))), + "[key1=val1, key2=2]"), + // key value list from map + arguments( + AnyValue.of( + new LinkedHashMap>() { + { + put("key1", AnyValue.of("val1")); + put("key2", AnyValue.of(2)); + } + }), + "[key1=val1, key2=2]"), + // map of map + arguments( + AnyValue.of( + Collections.singletonMap( + "child", + AnyValue.of(Collections.singletonMap("grandchild", AnyValue.of("str"))))), + "[child=[grandchild=str]]"), + // bytes + arguments( + AnyValue.of("hello world".getBytes(StandardCharsets.UTF_8)), "68656c6c6f20776f726c64")); + } + + @Test + void anyValueByteAsString() { + // TODO: add more test cases + String str = "hello world"; + String base16Encoded = AnyValue.of(str.getBytes(StandardCharsets.UTF_8)).asString(); + byte[] decodedBytes = OtelEncodingUtils.bytesFromBase16(base16Encoded, base16Encoded.length()); + assertThat(new String(decodedBytes, StandardCharsets.UTF_8)).isEqualTo(str); + } +} diff --git a/sdk/logs/build.gradle.kts b/sdk/logs/build.gradle.kts index 8ffe760b86f..6640c4ed0ee 100644 --- a/sdk/logs/build.gradle.kts +++ b/sdk/logs/build.gradle.kts @@ -12,6 +12,7 @@ otelJava.moduleName.set("io.opentelemetry.sdk.logs") dependencies { api(project(":api:all")) api(project(":sdk:common")) + implementation(project(":extensions:incubator")) implementation(project(":api:events")) @@ -20,4 +21,5 @@ dependencies { testImplementation(project(":sdk:testing")) testImplementation("org.awaitility:awaitility") + testImplementation("com.google.guava:guava") } diff --git a/sdk/logs/src/main/java/io/opentelemetry/sdk/logs/SdkLogRecordBuilder.java b/sdk/logs/src/main/java/io/opentelemetry/sdk/logs/SdkLogRecordBuilder.java index 8ef8b2ae4b2..6bdd0407aa5 100644 --- a/sdk/logs/src/main/java/io/opentelemetry/sdk/logs/SdkLogRecordBuilder.java +++ b/sdk/logs/src/main/java/io/opentelemetry/sdk/logs/SdkLogRecordBuilder.java @@ -10,15 +10,18 @@ import io.opentelemetry.api.logs.Severity; import io.opentelemetry.api.trace.Span; import io.opentelemetry.context.Context; +import io.opentelemetry.extension.incubator.logs.AnyValue; +import io.opentelemetry.extension.incubator.logs.ExtendedLogRecordBuilder; import io.opentelemetry.sdk.common.InstrumentationScopeInfo; import io.opentelemetry.sdk.internal.AttributesMap; import io.opentelemetry.sdk.logs.data.Body; +import io.opentelemetry.sdk.logs.internal.AnyValueBody; import java.time.Instant; import java.util.concurrent.TimeUnit; import javax.annotation.Nullable; /** SDK implementation of {@link LogRecordBuilder}. */ -final class SdkLogRecordBuilder implements LogRecordBuilder { +final class SdkLogRecordBuilder implements ExtendedLogRecordBuilder { private final LoggerSharedState loggerSharedState; private final LogLimits logLimits; @@ -89,6 +92,12 @@ public SdkLogRecordBuilder setBody(String body) { return this; } + @Override + public LogRecordBuilder setBody(AnyValue value) { + this.body = AnyValueBody.create(value); + return this; + } + @Override public SdkLogRecordBuilder setAttribute(AttributeKey key, T value) { if (key == null || key.getKey().isEmpty() || value == null) { diff --git a/sdk/logs/src/main/java/io/opentelemetry/sdk/logs/data/Body.java b/sdk/logs/src/main/java/io/opentelemetry/sdk/logs/data/Body.java index a13ecc003fe..2dc7957de91 100644 --- a/sdk/logs/src/main/java/io/opentelemetry/sdk/logs/data/Body.java +++ b/sdk/logs/src/main/java/io/opentelemetry/sdk/logs/data/Body.java @@ -22,6 +22,8 @@ public interface Body { enum Type { EMPTY, STRING + // TODO (jack-berg): Add ANY_VALUE type when API for setting body to AnyValue is stable + // ANY_VALUE } /** diff --git a/sdk/logs/src/main/java/io/opentelemetry/sdk/logs/internal/AnyValueBody.java b/sdk/logs/src/main/java/io/opentelemetry/sdk/logs/internal/AnyValueBody.java new file mode 100644 index 00000000000..7a1a9f2138f --- /dev/null +++ b/sdk/logs/src/main/java/io/opentelemetry/sdk/logs/internal/AnyValueBody.java @@ -0,0 +1,43 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.sdk.logs.internal; + +import io.opentelemetry.extension.incubator.logs.AnyValue; +import io.opentelemetry.sdk.logs.data.Body; +import javax.annotation.concurrent.Immutable; + +@Immutable +public final class AnyValueBody implements Body { + + private final AnyValue value; + + private AnyValueBody(AnyValue value) { + this.value = value; + } + + public static Body create(AnyValue value) { + return new AnyValueBody(value); + } + + @Override + public Type getType() { + return Type.STRING; + } + + @Override + public String asString() { + return value.asString(); + } + + public AnyValue asAnyValue() { + return value; + } + + @Override + public String toString() { + return "AnyValueBody{" + asString() + "}"; + } +} diff --git a/sdk/logs/src/test/java/io/opentelemetry/sdk/logs/AnyValueBodyTest.java b/sdk/logs/src/test/java/io/opentelemetry/sdk/logs/AnyValueBodyTest.java new file mode 100644 index 00000000000..e793dc513d0 --- /dev/null +++ b/sdk/logs/src/test/java/io/opentelemetry/sdk/logs/AnyValueBodyTest.java @@ -0,0 +1,156 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.sdk.logs; + +import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.assertThat; + +import io.opentelemetry.api.logs.Logger; +import io.opentelemetry.extension.incubator.logs.AnyValue; +import io.opentelemetry.extension.incubator.logs.ExtendedLogRecordBuilder; +import io.opentelemetry.extension.incubator.logs.KeyAnyValue; +import io.opentelemetry.sdk.logs.export.SimpleLogRecordProcessor; +import io.opentelemetry.sdk.logs.internal.AnyValueBody; +import io.opentelemetry.sdk.testing.exporter.InMemoryLogRecordExporter; +import java.nio.charset.StandardCharsets; +import java.util.LinkedHashMap; +import org.junit.jupiter.api.Test; + +class AnyValueBodyTest { + + @Test + @SuppressWarnings("DoubleBraceInitialization") + void anyValueBody() { + InMemoryLogRecordExporter exporter = InMemoryLogRecordExporter.create(); + SdkLoggerProvider provider = + SdkLoggerProvider.builder() + .addLogRecordProcessor(SimpleLogRecordProcessor.create(exporter)) + .build(); + Logger logger = provider.get(AnyValueBodyTest.class.getName()); + + // AnyValue can be a primitive type, like a string, long, double, boolean + extendedLogRecordBuilder(logger).setBody(AnyValue.of(1)).emit(); + assertThat(exporter.getFinishedLogRecordItems()) + .hasSize(1) + .satisfiesExactly( + logRecordData -> { + // TODO (jack-berg): add assertion when ANY_VALUE is added to Body.Type + // assertThat(logRecordData.getBody().getType()).isEqualTo(Body.Type.ANY_VALUE); + assertThat(logRecordData.getBody().asString()).isEqualTo("1"); + assertThat(((AnyValueBody) logRecordData.getBody()).asAnyValue()) + .isEqualTo(AnyValue.of(1)); + }); + exporter.reset(); + + // ...or a byte array of raw data + extendedLogRecordBuilder(logger) + .setBody(AnyValue.of("hello world".getBytes(StandardCharsets.UTF_8))) + .emit(); + assertThat(exporter.getFinishedLogRecordItems()) + .hasSize(1) + .satisfiesExactly( + logRecordData -> { + // TODO (jack-berg): add assertion when ANY_VALUE is added to Body.Type + // assertThat(logRecordData.getBody().getType()).isEqualTo(Body.Type.ANY_VALUE); + assertThat(logRecordData.getBody().asString()).isEqualTo("68656c6c6f20776f726c64"); + assertThat(((AnyValueBody) logRecordData.getBody()).asAnyValue()) + .isEqualTo(AnyValue.of("hello world".getBytes(StandardCharsets.UTF_8))); + }); + exporter.reset(); + + // But most commonly it will be used to represent complex structured like a map + extendedLogRecordBuilder(logger) + .setBody( + // The protocol data structure uses a repeated KeyValue to represent a map: + // https://github.com/open-telemetry/opentelemetry-proto/blob/ac3242b03157295e4ee9e616af53b81517b06559/opentelemetry/proto/common/v1/common.proto#L59 + // The comment says that keys aren't allowed to repeat themselves, and because its + // represented as a repeated KeyValue, we need to at least offer the ability to preserve + // order. + // Accepting a Map> makes for a cleaner API, but ordering of the + // entries is lost. To accommodate use cases where ordering should be preserved we + // accept an array of key value pairs, but also a map based alternative (see the + // key_value_list_key entry). + AnyValue.of( + KeyAnyValue.of("str_key", AnyValue.of("value")), + KeyAnyValue.of("bool_key", AnyValue.of(true)), + KeyAnyValue.of("long_key", AnyValue.of(1L)), + KeyAnyValue.of("double_key", AnyValue.of(1.1)), + KeyAnyValue.of("bytes_key", AnyValue.of("bytes".getBytes(StandardCharsets.UTF_8))), + KeyAnyValue.of( + "arr_key", + AnyValue.of(AnyValue.of("entry1"), AnyValue.of(2), AnyValue.of(3.3))), + KeyAnyValue.of( + "key_value_list_key", + AnyValue.of( + new LinkedHashMap>() { + { + put("child_str_key1", AnyValue.of("child_value1")); + put("child_str_key2", AnyValue.of("child_value2")); + } + })))) + .emit(); + assertThat(exporter.getFinishedLogRecordItems()) + .hasSize(1) + .satisfiesExactly( + logRecordData -> { + // TODO (jack-berg): add assertion when ANY_VALUE is added to Body.Type + // assertThat(logRecordData.getBody().getType()).isEqualTo(Body.Type.ANY_VALUE); + assertThat(logRecordData.getBody().asString()) + .isEqualTo( + "[" + + "str_key=value, " + + "bool_key=true, " + + "long_key=1, " + + "double_key=1.1, " + + "bytes_key=6279746573, " + + "arr_key=[entry1, 2, 3.3], " + + "key_value_list_key=[child_str_key1=child_value1, child_str_key2=child_value2]" + + "]"); + assertThat(((AnyValueBody) logRecordData.getBody()).asAnyValue()) + .isEqualTo( + AnyValue.of( + KeyAnyValue.of("str_key", AnyValue.of("value")), + KeyAnyValue.of("bool_key", AnyValue.of(true)), + KeyAnyValue.of("long_key", AnyValue.of(1L)), + KeyAnyValue.of("double_key", AnyValue.of(1.1)), + KeyAnyValue.of( + "bytes_key", AnyValue.of("bytes".getBytes(StandardCharsets.UTF_8))), + KeyAnyValue.of( + "arr_key", + AnyValue.of(AnyValue.of("entry1"), AnyValue.of(2), AnyValue.of(3.3))), + KeyAnyValue.of( + "key_value_list_key", + AnyValue.of( + new LinkedHashMap>() { + { + put("child_str_key1", AnyValue.of("child_value1")); + put("child_str_key2", AnyValue.of("child_value2")); + } + })))); + }); + exporter.reset(); + + // ..or an array (optionally with heterogeneous types) + extendedLogRecordBuilder(logger) + .setBody(AnyValue.of(AnyValue.of("entry1"), AnyValue.of("entry2"), AnyValue.of(3))) + .emit(); + assertThat(exporter.getFinishedLogRecordItems()) + .hasSize(1) + .satisfiesExactly( + logRecordData -> { + // TODO (jack-berg): add assertion when ANY_VALUE is added to Body.Type + // assertThat(logRecordData.getBody().getType()).isEqualTo(Body.Type.ANY_VALUE); + assertThat(logRecordData.getBody().asString()).isEqualTo("[entry1, entry2, 3]"); + assertThat(((AnyValueBody) logRecordData.getBody()).asAnyValue()) + .isEqualTo( + AnyValue.of(AnyValue.of("entry1"), AnyValue.of("entry2"), AnyValue.of(3))); + }); + exporter.reset(); + } + + ExtendedLogRecordBuilder extendedLogRecordBuilder(Logger logger) { + return (ExtendedLogRecordBuilder) logger.logRecordBuilder(); + } +} From 9d55f25386c2186a30efe8f0054b8dcb5eb0a0bd Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 3 Nov 2023 16:19:01 -0500 Subject: [PATCH 073/901] Update dependency com.google.protobuf:protobuf-bom to v3.25.0 (#5957) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- dependencyManagement/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index b59ffeba1dd..ef2eb2caa2b 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -10,7 +10,7 @@ rootProject.extra["versions"] = dependencyVersions val DEPENDENCY_BOMS = listOf( "com.fasterxml.jackson:jackson-bom:2.15.3", "com.google.guava:guava-bom:32.1.3-jre", - "com.google.protobuf:protobuf-bom:3.24.4", + "com.google.protobuf:protobuf-bom:3.25.0", "com.linecorp.armeria:armeria-bom:1.26.1", "com.squareup.okhttp3:okhttp-bom:4.12.0", "com.squareup.okio:okio-bom:3.6.0", // applies to transitive dependencies of okhttp From 35ecf7a46128257c7d6106ea22d78b0207612245 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 3 Nov 2023 16:19:21 -0500 Subject: [PATCH 074/901] Update dependency com.uber.nullaway:nullaway to v0.10.16 (#5956) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- dependencyManagement/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index ef2eb2caa2b..90dae2bfeb3 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -60,7 +60,7 @@ val DEPENDENCIES = listOf( "com.google.guava:guava-beta-checker:1.0", "com.sun.net.httpserver:http:20070405", "com.tngtech.archunit:archunit-junit5:1.1.0", - "com.uber.nullaway:nullaway:0.10.15", + "com.uber.nullaway:nullaway:0.10.16", "edu.berkeley.cs.jqf:jqf-fuzz:1.7", // jqf-fuzz version 1.8+ requires Java 11+ "eu.rekawek.toxiproxy:toxiproxy-java:2.1.7", "io.github.netmikey.logunit:logunit-jul:2.0.0", From 0263e62b4226762d3beb4e4a4d529d023f8359cc Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 3 Nov 2023 16:19:41 -0500 Subject: [PATCH 075/901] Update dependency nl.jqno.equalsverifier:equalsverifier to v3.15.3 (#5953) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- dependencyManagement/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index 90dae2bfeb3..a7110006974 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -70,7 +70,7 @@ val DEPENDENCIES = listOf( "io.opentracing:opentracing-api:0.33.0", "io.opentracing:opentracing-noop:0.33.0", "junit:junit:4.13.2", - "nl.jqno.equalsverifier:equalsverifier:3.15.2", + "nl.jqno.equalsverifier:equalsverifier:3.15.3", "org.awaitility:awaitility:4.2.0", "org.bouncycastle:bcpkix-jdk15on:1.70", "org.codehaus.mojo:animal-sniffer-annotations:1.23", From c0cf5dd95fa417040819dd9509a26bb18e37f022 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 3 Nov 2023 16:20:43 -0500 Subject: [PATCH 076/901] Update dependency com.google.api.grpc:proto-google-common-protos to v2.28.0 (#5951) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- dependencyManagement/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index a7110006974..6eb363f025f 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -55,7 +55,7 @@ val DEPENDENCIES = listOf( "io.prometheus:simpleclient_httpserver:${prometheusClientVersion}", "javax.annotation:javax.annotation-api:1.3.2", "com.github.stefanbirkner:system-rules:1.19.0", - "com.google.api.grpc:proto-google-common-protos:2.27.0", + "com.google.api.grpc:proto-google-common-protos:2.28.0", "com.google.code.findbugs:jsr305:3.0.2", "com.google.guava:guava-beta-checker:1.0", "com.sun.net.httpserver:http:20070405", From e2c76320ed05b628c74e94493b7312817e92647a Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 3 Nov 2023 16:21:01 -0500 Subject: [PATCH 077/901] Update dependency org.jetbrains.kotlin:kotlin-gradle-plugin to v1.9.20 (#5949) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- buildSrc/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts index 3bc47d01f0e..f5385ed9008 100644 --- a/buildSrc/build.gradle.kts +++ b/buildSrc/build.gradle.kts @@ -57,7 +57,7 @@ dependencies { implementation("me.champeau.jmh:jmh-gradle-plugin:0.7.2") implementation("net.ltgt.gradle:gradle-errorprone-plugin:3.1.0") implementation("net.ltgt.gradle:gradle-nullaway-plugin:1.6.0") - implementation("org.jetbrains.kotlin:kotlin-gradle-plugin:1.9.10") + implementation("org.jetbrains.kotlin:kotlin-gradle-plugin:1.9.20") implementation("org.owasp:dependency-check-gradle:8.4.2") implementation("ru.vyarus:gradle-animalsniffer-plugin:1.7.1") } From 7fd46f058350f35cb222eec1f76153b3751121b8 Mon Sep 17 00:00:00 2001 From: Lauri Tulmin Date: Fri, 3 Nov 2023 23:26:01 +0200 Subject: [PATCH 078/901] Fix flaky jaeger remote sampler test (#5955) --- .../trace/jaeger/sampler/JaegerRemoteSamplerGrpcNettyTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sdk-extensions/jaeger-remote-sampler/src/testGrpcNetty/java/io/opentelemetry/sdk/extension/trace/jaeger/sampler/JaegerRemoteSamplerGrpcNettyTest.java b/sdk-extensions/jaeger-remote-sampler/src/testGrpcNetty/java/io/opentelemetry/sdk/extension/trace/jaeger/sampler/JaegerRemoteSamplerGrpcNettyTest.java index 5eb5db44bec..257ddf3b139 100644 --- a/sdk-extensions/jaeger-remote-sampler/src/testGrpcNetty/java/io/opentelemetry/sdk/extension/trace/jaeger/sampler/JaegerRemoteSamplerGrpcNettyTest.java +++ b/sdk-extensions/jaeger-remote-sampler/src/testGrpcNetty/java/io/opentelemetry/sdk/extension/trace/jaeger/sampler/JaegerRemoteSamplerGrpcNettyTest.java @@ -148,7 +148,7 @@ void description() { void initialSampler() { try (JaegerRemoteSampler sampler = JaegerRemoteSampler.builder() - .setChannel(managedChannel()) + .setChannel(ManagedChannelBuilder.forTarget("example.com").build()) .setServiceName(SERVICE_NAME) .setInitialSampler(Sampler.alwaysOn()) .build()) { From 19196a02519cf83ee0867f58c7e9532d3ed29c55 Mon Sep 17 00:00:00 2001 From: jack-berg <34418638+jack-berg@users.noreply.github.com> Date: Mon, 6 Nov 2023 10:58:34 -0600 Subject: [PATCH 079/901] Stabilize explicit bucket boundaries advice API (#5897) --- .../api/metrics/DoubleHistogramBuilder.java | 16 +++ .../api/metrics/LongHistogramBuilder.java | 16 +++ .../current_vs_latest/opentelemetry-api.txt | 7 +- .../ExtendedDoubleHistogramBuilder.java | 9 -- .../metrics/ExtendedLongHistogramBuilder.java | 9 -- .../sdk/metrics/SdkDoubleHistogram.java | 9 ++ .../sdk/metrics/SdkLongHistogram.java | 15 ++- .../ExplicitBucketHistogramUtils.java | 21 ++- .../ExplicitBucketBoundariesAdviceTest.java | 121 ++++++++++++++++-- 9 files changed, 176 insertions(+), 47 deletions(-) diff --git a/api/all/src/main/java/io/opentelemetry/api/metrics/DoubleHistogramBuilder.java b/api/all/src/main/java/io/opentelemetry/api/metrics/DoubleHistogramBuilder.java index 68d89a3302b..bc93b3c9e3f 100644 --- a/api/all/src/main/java/io/opentelemetry/api/metrics/DoubleHistogramBuilder.java +++ b/api/all/src/main/java/io/opentelemetry/api/metrics/DoubleHistogramBuilder.java @@ -5,6 +5,8 @@ package io.opentelemetry.api.metrics; +import java.util.List; + /** * Builder class for {@link DoubleHistogram}. * @@ -32,6 +34,20 @@ public interface DoubleHistogramBuilder { */ DoubleHistogramBuilder setUnit(String unit); + /** + * Set the explicit bucket buckets boundaries advice, which suggests the recommended set of + * explicit bucket boundaries for this histogram. + * + * @param bucketBoundaries The explicit bucket boundaries advice. + * @see Explicit + * bucket boundaries advisory parameter + * @since 1.32.0 + */ + default DoubleHistogramBuilder setExplicitBucketBoundariesAdvice(List bucketBoundaries) { + return this; + } + /** Sets the Counter for recording {@code long} values. */ LongHistogramBuilder ofLongs(); diff --git a/api/all/src/main/java/io/opentelemetry/api/metrics/LongHistogramBuilder.java b/api/all/src/main/java/io/opentelemetry/api/metrics/LongHistogramBuilder.java index 80f59753457..baad3928346 100644 --- a/api/all/src/main/java/io/opentelemetry/api/metrics/LongHistogramBuilder.java +++ b/api/all/src/main/java/io/opentelemetry/api/metrics/LongHistogramBuilder.java @@ -5,6 +5,8 @@ package io.opentelemetry.api.metrics; +import java.util.List; + /** * Builder class for {@link LongHistogram}. * @@ -31,6 +33,20 @@ public interface LongHistogramBuilder { */ LongHistogramBuilder setUnit(String unit); + /** + * Set the explicit bucket buckets boundaries advice, which suggests the recommended set of + * explicit bucket boundaries for this histogram. + * + * @param bucketBoundaries The explicit bucket boundaries advice. + * @see Explicit + * bucket boundaries advisory parameter + * @since 1.32.0 + */ + default LongHistogramBuilder setExplicitBucketBoundariesAdvice(List bucketBoundaries) { + return this; + } + /** * Builds and returns a Histogram instrument with the configuration. * diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-api.txt b/docs/apidiffs/current_vs_latest/opentelemetry-api.txt index df26146497b..faa8d3cf893 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-api.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-api.txt @@ -1,2 +1,7 @@ Comparing source compatibility of against -No changes. \ No newline at end of file +*** MODIFIED INTERFACE: PUBLIC ABSTRACT io.opentelemetry.api.metrics.DoubleHistogramBuilder (not serializable) + === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 + +++ NEW METHOD: PUBLIC(+) io.opentelemetry.api.metrics.DoubleHistogramBuilder setExplicitBucketBoundariesAdvice(java.util.List) +*** MODIFIED INTERFACE: PUBLIC ABSTRACT io.opentelemetry.api.metrics.LongHistogramBuilder (not serializable) + === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 + +++ NEW METHOD: PUBLIC(+) io.opentelemetry.api.metrics.LongHistogramBuilder setExplicitBucketBoundariesAdvice(java.util.List) diff --git a/extensions/incubator/src/main/java/io/opentelemetry/extension/incubator/metrics/ExtendedDoubleHistogramBuilder.java b/extensions/incubator/src/main/java/io/opentelemetry/extension/incubator/metrics/ExtendedDoubleHistogramBuilder.java index 881727538c2..dc515448f52 100644 --- a/extensions/incubator/src/main/java/io/opentelemetry/extension/incubator/metrics/ExtendedDoubleHistogramBuilder.java +++ b/extensions/incubator/src/main/java/io/opentelemetry/extension/incubator/metrics/ExtendedDoubleHistogramBuilder.java @@ -12,15 +12,6 @@ /** Extended {@link DoubleHistogramBuilder} with experimental APIs. */ public interface ExtendedDoubleHistogramBuilder extends DoubleHistogramBuilder { - /** - * Specify the explicit bucket buckets boundaries advice, which suggests the recommended set of - * explicit bucket boundaries for this histogram. - */ - default ExtendedDoubleHistogramBuilder setExplicitBucketBoundariesAdvice( - List bucketBoundaries) { - return this; - } - /** * Specify the attribute advice, which suggests the recommended set of attribute keys to be used * for this histogram. diff --git a/extensions/incubator/src/main/java/io/opentelemetry/extension/incubator/metrics/ExtendedLongHistogramBuilder.java b/extensions/incubator/src/main/java/io/opentelemetry/extension/incubator/metrics/ExtendedLongHistogramBuilder.java index 665e4e3555e..3afb35b7e4c 100644 --- a/extensions/incubator/src/main/java/io/opentelemetry/extension/incubator/metrics/ExtendedLongHistogramBuilder.java +++ b/extensions/incubator/src/main/java/io/opentelemetry/extension/incubator/metrics/ExtendedLongHistogramBuilder.java @@ -12,15 +12,6 @@ /** Extended {@link LongHistogramBuilder} with experimental APIs. */ public interface ExtendedLongHistogramBuilder extends LongHistogramBuilder { - /** - * Specify the explicit bucket buckets boundaries advice, which suggests the recommended set of - * explicit bucket boundaries for this histogram. - */ - default ExtendedLongHistogramBuilder setExplicitBucketBoundariesAdvice( - List bucketBoundaries) { - return this; - } - /** * Specify the attribute advice, which suggests the recommended set of attribute keys to be used * for this histogram. diff --git a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkDoubleHistogram.java b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkDoubleHistogram.java index 64a0daac68e..9d9c1535f0b 100644 --- a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkDoubleHistogram.java +++ b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkDoubleHistogram.java @@ -13,11 +13,13 @@ import io.opentelemetry.context.Context; import io.opentelemetry.extension.incubator.metrics.ExtendedDoubleHistogramBuilder; import io.opentelemetry.sdk.internal.ThrottlingLogger; +import io.opentelemetry.sdk.metrics.internal.aggregator.ExplicitBucketHistogramUtils; import io.opentelemetry.sdk.metrics.internal.descriptor.InstrumentDescriptor; import io.opentelemetry.sdk.metrics.internal.state.MeterProviderSharedState; import io.opentelemetry.sdk.metrics.internal.state.MeterSharedState; import io.opentelemetry.sdk.metrics.internal.state.WriteableMetricStorage; import java.util.List; +import java.util.Objects; import java.util.logging.Level; import java.util.logging.Logger; @@ -97,6 +99,13 @@ public LongHistogramBuilder ofLongs() { @Override public ExtendedDoubleHistogramBuilder setExplicitBucketBoundariesAdvice( List bucketBoundaries) { + try { + Objects.requireNonNull(bucketBoundaries, "bucketBoundaries must not be null"); + ExplicitBucketHistogramUtils.validateBucketBoundaries(bucketBoundaries); + } catch (IllegalArgumentException | NullPointerException e) { + logger.warning("Error setting explicit bucket boundaries advice: " + e.getMessage()); + return this; + } builder.setExplicitBucketBoundaries(bucketBoundaries); return this; } diff --git a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkLongHistogram.java b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkLongHistogram.java index 4e2e223fa90..38a7e52293e 100644 --- a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkLongHistogram.java +++ b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkLongHistogram.java @@ -12,12 +12,14 @@ import io.opentelemetry.context.Context; import io.opentelemetry.extension.incubator.metrics.ExtendedLongHistogramBuilder; import io.opentelemetry.sdk.internal.ThrottlingLogger; +import io.opentelemetry.sdk.metrics.internal.aggregator.ExplicitBucketHistogramUtils; import io.opentelemetry.sdk.metrics.internal.descriptor.Advice; import io.opentelemetry.sdk.metrics.internal.descriptor.InstrumentDescriptor; import io.opentelemetry.sdk.metrics.internal.state.MeterProviderSharedState; import io.opentelemetry.sdk.metrics.internal.state.MeterSharedState; import io.opentelemetry.sdk.metrics.internal.state.WriteableMetricStorage; import java.util.List; +import java.util.Objects; import java.util.logging.Level; import java.util.logging.Logger; import java.util.stream.Collectors; @@ -99,9 +101,16 @@ public SdkLongHistogram build() { @Override public ExtendedLongHistogramBuilder setExplicitBucketBoundariesAdvice( List bucketBoundaries) { - List doubleBoundaries = - bucketBoundaries.stream().map(Long::doubleValue).collect(Collectors.toList()); - builder.setExplicitBucketBoundaries(doubleBoundaries); + List boundaries; + try { + Objects.requireNonNull(bucketBoundaries, "bucketBoundaries must not be null"); + boundaries = bucketBoundaries.stream().map(Long::doubleValue).collect(Collectors.toList()); + ExplicitBucketHistogramUtils.validateBucketBoundaries(boundaries); + } catch (IllegalArgumentException | NullPointerException e) { + logger.warning("Error setting explicit bucket boundaries advice: " + e.getMessage()); + return this; + } + builder.setExplicitBucketBoundaries(boundaries); return this; } diff --git a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/aggregator/ExplicitBucketHistogramUtils.java b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/aggregator/ExplicitBucketHistogramUtils.java index fd11247c57c..4d25b873f5a 100644 --- a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/aggregator/ExplicitBucketHistogramUtils.java +++ b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/aggregator/ExplicitBucketHistogramUtils.java @@ -26,7 +26,8 @@ private ExplicitBucketHistogramUtils() {} /** Converts bucket boundary "convenient" configuration into the "more efficient" array. */ public static double[] createBoundaryArray(List boundaries) { - return validateBucketBoundaries(boundaries.stream().mapToDouble(i -> i).toArray()); + validateBucketBoundaries(boundaries); + return boundaries.stream().mapToDouble(i -> i).toArray(); } /** @@ -51,32 +52,30 @@ public static int findBucketIndex(double[] boundaries, double value) { * Validates errors in boundary configuration. * * @param boundaries The array of bucket boundaries. - * @return The original boundaries. * @throws IllegalArgumentException if boundaries are not specified correctly. */ - public static double[] validateBucketBoundaries(double[] boundaries) { + public static void validateBucketBoundaries(List boundaries) { for (double v : boundaries) { if (Double.isNaN(v)) { throw new IllegalArgumentException("invalid bucket boundary: NaN"); } } - for (int i = 1; i < boundaries.length; ++i) { - if (boundaries[i - 1] >= boundaries[i]) { + for (int i = 1; i < boundaries.size(); ++i) { + if (boundaries.get(i - 1) >= boundaries.get(i)) { throw new IllegalArgumentException( "Bucket boundaries must be in increasing order: " - + boundaries[i - 1] + + boundaries.get(i - 1) + " >= " - + boundaries[i]); + + boundaries.get(i)); } } - if (boundaries.length > 0) { - if (boundaries[0] == Double.NEGATIVE_INFINITY) { + if (!boundaries.isEmpty()) { + if (boundaries.get(0) == Double.NEGATIVE_INFINITY) { throw new IllegalArgumentException("invalid bucket boundary: -Inf"); } - if (boundaries[boundaries.length - 1] == Double.POSITIVE_INFINITY) { + if (boundaries.get(boundaries.size() - 1) == Double.POSITIVE_INFINITY) { throw new IllegalArgumentException("invalid bucket boundary: +Inf"); } } - return boundaries; } } diff --git a/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/ExplicitBucketBoundariesAdviceTest.java b/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/ExplicitBucketBoundariesAdviceTest.java index 555f852df1d..16d4d05cac0 100644 --- a/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/ExplicitBucketBoundariesAdviceTest.java +++ b/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/ExplicitBucketBoundariesAdviceTest.java @@ -8,10 +8,10 @@ import static io.opentelemetry.sdk.metrics.Aggregation.explicitBucketHistogram; import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.assertThat; +import io.github.netmikey.logunit.api.LogCapturer; import io.opentelemetry.api.metrics.DoubleHistogram; import io.opentelemetry.api.metrics.LongHistogram; -import io.opentelemetry.extension.incubator.metrics.ExtendedDoubleHistogramBuilder; -import io.opentelemetry.extension.incubator.metrics.ExtendedLongHistogramBuilder; +import io.opentelemetry.internal.testing.slf4j.SuppressLogger; import io.opentelemetry.sdk.metrics.export.AggregationTemporalitySelector; import io.opentelemetry.sdk.metrics.export.DefaultAggregationSelector; import io.opentelemetry.sdk.testing.exporter.InMemoryMetricReader; @@ -21,6 +21,7 @@ import java.util.function.Function; import java.util.stream.Stream; import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.extension.RegisterExtension; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.MethodSource; @@ -29,6 +30,12 @@ class ExplicitBucketBoundariesAdviceTest { private SdkMeterProvider meterProvider = SdkMeterProvider.builder().build(); + @RegisterExtension + LogCapturer logCapturer = + LogCapturer.create() + .captureForLogger(SdkLongHistogram.class.getName()) + .captureForLogger(SdkDoubleHistogram.class.getName()); + @AfterEach void cleanup() { meterProvider.close(); @@ -61,6 +68,8 @@ void histogramWithoutAdvice(Function> histogram .hasBucketBoundaries( 0d, 5d, 10d, 25d, 50d, 75d, 100d, 250d, 500d, 750d, 1_000d, 2_500d, 5_000d, 7_500d, 10_000d)))); + + assertThat(logCapturer.getEvents()).isEmpty(); } @ParameterizedTest @@ -88,6 +97,8 @@ void histogramWithAdvice(Function> histogramBui point .hasBucketCounts(1, 1, 1, 1) .hasBucketBoundaries(10.0, 20.0, 30.0)))); + + assertThat(logCapturer.getEvents()).isEmpty(); } @ParameterizedTest @@ -120,6 +131,8 @@ void histogramWithAdviceAndViews(Function> hist histogram -> histogram.hasPointsSatisfying( point -> point.hasBucketCounts(4, 0).hasBucketBoundaries(50.0)))); + + assertThat(logCapturer.getEvents()).isEmpty(); } @ParameterizedTest @@ -151,6 +164,42 @@ void histogramWithAdviceAndReaderAggregationPreference( histogram -> histogram.hasPointsSatisfying( point -> point.hasBucketCounts(4, 0).hasBucketBoundaries(50.0)))); + + assertThat(logCapturer.getEvents()).isEmpty(); + } + + @ParameterizedTest + @MethodSource("histogramsWithInvalidAdvice") + @SuppressLogger(SdkDoubleHistogram.class) + @SuppressLogger(SdkLongHistogram.class) + void histogramWithInvalidAdvice( + Function> histogramBuilder, String expectedErrorMessage) { + InMemoryMetricReader reader = InMemoryMetricReader.create(); + meterProvider = SdkMeterProvider.builder().registerMetricReader(reader).build(); + + Consumer histogramRecorder = histogramBuilder.apply(meterProvider); + histogramRecorder.accept(5L); + histogramRecorder.accept(15L); + histogramRecorder.accept(25L); + histogramRecorder.accept(35L); + + // Should use default bucket bounds + assertThat(reader.collectAllMetrics()) + .satisfiesExactly( + metric -> + assertThat(metric) + .hasHistogramSatisfying( + histogram -> + histogram.hasPointsSatisfying( + point -> + point + .hasBucketCounts( + 0, 1, 0, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) + .hasBucketBoundaries( + 0d, 5d, 10d, 25d, 50d, 75d, 100d, 250d, 500d, 750d, + 1_000d, 2_500d, 5_000d, 7_500d, 10_000d)))); + + logCapturer.assertContains(expectedErrorMessage); } private static Stream histogramsWithoutAdvice() { @@ -158,16 +207,16 @@ private static Stream histogramsWithoutAdvice() { Arguments.of( (Function>) meterProvider -> { - DoubleHistogram build = + DoubleHistogram histogram = meterProvider.get("meter").histogramBuilder("histogram").build(); - return build::record; + return histogram::record; }), Arguments.of( (Function>) meterProvider -> { - LongHistogram build = + LongHistogram histogram = meterProvider.get("meter").histogramBuilder("histogram").ofLongs().build(); - return build::record; + return histogram::record; })); } @@ -176,22 +225,66 @@ private static Stream histogramsWithAdvice() { Arguments.of( (Function>) meterProvider -> { - DoubleHistogram build = - ((ExtendedDoubleHistogramBuilder) - meterProvider.get("meter").histogramBuilder("histogram")) + DoubleHistogram histogram = + meterProvider + .get("meter") + .histogramBuilder("histogram") .setExplicitBucketBoundariesAdvice(Arrays.asList(10.0, 20.0, 30.0)) .build(); - return build::record; + return histogram::record; }), Arguments.of( (Function>) meterProvider -> { - LongHistogram build = - ((ExtendedLongHistogramBuilder) - meterProvider.get("meter").histogramBuilder("histogram").ofLongs()) + LongHistogram histogram = + meterProvider + .get("meter") + .histogramBuilder("histogram") + .ofLongs() .setExplicitBucketBoundariesAdvice(Arrays.asList(10L, 20L, 30L)) .build(); - return build::record; + return histogram::record; })); } + + private static Stream histogramsWithInvalidAdvice() { + return Stream.of( + Arguments.of( + (Function>) + meterProvider -> { + DoubleHistogram histogram = + meterProvider + .get("meter") + .histogramBuilder("histogram") + .setExplicitBucketBoundariesAdvice(Arrays.asList(10.0, 9.0, 8.0)) + .build(); + return histogram::record; + }, + "Error setting explicit bucket boundaries advice: Bucket boundaries must be in increasing order: 10.0 >= 9.0"), + Arguments.of( + (Function>) + meterProvider -> { + LongHistogram histogram = + meterProvider + .get("meter") + .histogramBuilder("histogram") + .ofLongs() + .setExplicitBucketBoundariesAdvice(Arrays.asList(10L, 9L, 8L)) + .build(); + return histogram::record; + }, + "Error setting explicit bucket boundaries advice: Bucket boundaries must be in increasing order: 10.0 >= 9.0"), + Arguments.of( + (Function>) + meterProvider -> { + DoubleHistogram histogram = + meterProvider + .get("meter") + .histogramBuilder("histogram") + .setExplicitBucketBoundariesAdvice(null) + .build(); + return histogram::record; + }, + "Error setting explicit bucket boundaries advice: bucketBoundaries must not be null")); + } } From 1ecc9197bea8a566bf4ec6e3afa6b70f55d593ef Mon Sep 17 00:00:00 2001 From: Lauri Tulmin Date: Mon, 6 Nov 2023 19:12:29 +0200 Subject: [PATCH 080/901] Add null check to StrictContextStorage (#5954) --- .../java/io/opentelemetry/context/StrictContextStorage.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/context/src/main/java/io/opentelemetry/context/StrictContextStorage.java b/context/src/main/java/io/opentelemetry/context/StrictContextStorage.java index b02d33b4aea..aeed325c364 100644 --- a/context/src/main/java/io/opentelemetry/context/StrictContextStorage.java +++ b/context/src/main/java/io/opentelemetry/context/StrictContextStorage.java @@ -23,6 +23,7 @@ import static java.lang.Thread.currentThread; import io.opentelemetry.context.internal.shaded.WeakConcurrentMap; +import java.lang.ref.Reference; import java.util.Arrays; import java.util.List; import java.util.concurrent.ConcurrentHashMap; @@ -266,7 +267,9 @@ List drainPendingCallers() { public void run() { try { while (!Thread.interrupted()) { - CallerStackTrace caller = map.remove(remove()); + Reference reference = remove(); + // on openj9 ReferenceQueue.remove can return null + CallerStackTrace caller = reference != null ? map.remove(reference) : null; if (caller != null && !caller.closed) { logger.log( Level.SEVERE, "Scope garbage collected before being closed.", callerError(caller)); From f9be6821a53d51797d73b16975fe405232a39c6f Mon Sep 17 00:00:00 2001 From: Lauri Tulmin Date: Tue, 7 Nov 2023 18:01:41 +0200 Subject: [PATCH 081/901] Use a custom output stream in marshaling jmh benchmarks (#5964) --- .../internal/otlp/GrpcGzipBenchmark.java | 8 ++--- .../MetricsRequestMarshalerBenchmark.java | 5 ++-- .../otlp/RequestMarshalBenchmarks.java | 15 +++++----- .../internal/otlp/TestOutputStream.java | 29 +++++++++++++++++++ 4 files changed, 42 insertions(+), 15 deletions(-) create mode 100644 exporters/otlp/common/src/jmh/java/io/opentelemetry/exporter/internal/otlp/TestOutputStream.java diff --git a/exporters/otlp/common/src/jmh/java/io/opentelemetry/exporter/internal/otlp/GrpcGzipBenchmark.java b/exporters/otlp/common/src/jmh/java/io/opentelemetry/exporter/internal/otlp/GrpcGzipBenchmark.java index 5bbc501700c..21a98f5546c 100644 --- a/exporters/otlp/common/src/jmh/java/io/opentelemetry/exporter/internal/otlp/GrpcGzipBenchmark.java +++ b/exporters/otlp/common/src/jmh/java/io/opentelemetry/exporter/internal/otlp/GrpcGzipBenchmark.java @@ -141,8 +141,8 @@ public class GrpcGzipBenchmark { } @Benchmark - public ByteArrayOutputStream gzipCompressor() throws IOException { - ByteArrayOutputStream baos = new ByteArrayOutputStream(); + public TestOutputStream gzipCompressor() throws IOException { + TestOutputStream baos = new TestOutputStream(); OutputStream gzos = GZIP_CODEC.compress(baos); METRICS_REQUEST.writeTo(gzos); gzos.close(); @@ -150,8 +150,8 @@ public ByteArrayOutputStream gzipCompressor() throws IOException { } @Benchmark - public ByteArrayOutputStream identityCompressor() throws IOException { - ByteArrayOutputStream baos = new ByteArrayOutputStream(); + public TestOutputStream identityCompressor() throws IOException { + TestOutputStream baos = new TestOutputStream(); OutputStream gzos = IDENTITY_CODEC.compress(baos); METRICS_REQUEST.writeTo(gzos); gzos.close(); diff --git a/exporters/otlp/common/src/jmh/java/io/opentelemetry/exporter/internal/otlp/MetricsRequestMarshalerBenchmark.java b/exporters/otlp/common/src/jmh/java/io/opentelemetry/exporter/internal/otlp/MetricsRequestMarshalerBenchmark.java index c15a789809f..e284357e401 100644 --- a/exporters/otlp/common/src/jmh/java/io/opentelemetry/exporter/internal/otlp/MetricsRequestMarshalerBenchmark.java +++ b/exporters/otlp/common/src/jmh/java/io/opentelemetry/exporter/internal/otlp/MetricsRequestMarshalerBenchmark.java @@ -18,7 +18,6 @@ import io.opentelemetry.sdk.metrics.data.MetricData; import io.opentelemetry.sdk.resources.Resource; import io.opentelemetry.sdk.testing.exporter.InMemoryMetricReader; -import java.io.ByteArrayOutputStream; import java.io.IOException; import java.util.Arrays; import java.util.Collection; @@ -117,9 +116,9 @@ public class MetricsRequestMarshalerBenchmark { } @Benchmark - public ByteArrayOutputStream marshaler() throws IOException { + public TestOutputStream marshaler() throws IOException { MetricsRequestMarshaler marshaler = MetricsRequestMarshaler.create(METRICS); - ByteArrayOutputStream bos = new ByteArrayOutputStream(); + TestOutputStream bos = new TestOutputStream(); marshaler.writeBinaryTo(bos); return bos; } diff --git a/exporters/otlp/common/src/jmh/java/io/opentelemetry/exporter/internal/otlp/RequestMarshalBenchmarks.java b/exporters/otlp/common/src/jmh/java/io/opentelemetry/exporter/internal/otlp/RequestMarshalBenchmarks.java index b84b5ccca0e..87cce61bfc2 100644 --- a/exporters/otlp/common/src/jmh/java/io/opentelemetry/exporter/internal/otlp/RequestMarshalBenchmarks.java +++ b/exporters/otlp/common/src/jmh/java/io/opentelemetry/exporter/internal/otlp/RequestMarshalBenchmarks.java @@ -6,7 +6,6 @@ package io.opentelemetry.exporter.internal.otlp; import io.opentelemetry.exporter.internal.otlp.traces.TraceRequestMarshaler; -import java.io.ByteArrayOutputStream; import java.io.IOException; import java.util.concurrent.TimeUnit; import org.openjdk.jmh.annotations.Benchmark; @@ -27,26 +26,26 @@ public class RequestMarshalBenchmarks { @Benchmark @Threads(1) - public ByteArrayOutputStream createCustomMarshal(RequestMarshalState state) { + public TestOutputStream createCustomMarshal(RequestMarshalState state) { TraceRequestMarshaler requestMarshaler = TraceRequestMarshaler.create(state.spanDataList); - return new ByteArrayOutputStream(requestMarshaler.getBinarySerializedSize()); + return new TestOutputStream(requestMarshaler.getBinarySerializedSize()); } @Benchmark @Threads(1) - public ByteArrayOutputStream marshalCustom(RequestMarshalState state) throws IOException { + public TestOutputStream marshalCustom(RequestMarshalState state) throws IOException { TraceRequestMarshaler requestMarshaler = TraceRequestMarshaler.create(state.spanDataList); - ByteArrayOutputStream customOutput = - new ByteArrayOutputStream(requestMarshaler.getBinarySerializedSize()); + TestOutputStream customOutput = + new TestOutputStream(requestMarshaler.getBinarySerializedSize()); requestMarshaler.writeBinaryTo(customOutput); return customOutput; } @Benchmark @Threads(1) - public ByteArrayOutputStream marshalJson(RequestMarshalState state) throws IOException { + public TestOutputStream marshalJson(RequestMarshalState state) throws IOException { TraceRequestMarshaler requestMarshaler = TraceRequestMarshaler.create(state.spanDataList); - ByteArrayOutputStream customOutput = new ByteArrayOutputStream(); + TestOutputStream customOutput = new TestOutputStream(); requestMarshaler.writeJsonTo(customOutput); return customOutput; } diff --git a/exporters/otlp/common/src/jmh/java/io/opentelemetry/exporter/internal/otlp/TestOutputStream.java b/exporters/otlp/common/src/jmh/java/io/opentelemetry/exporter/internal/otlp/TestOutputStream.java new file mode 100644 index 00000000000..160853e89fe --- /dev/null +++ b/exporters/otlp/common/src/jmh/java/io/opentelemetry/exporter/internal/otlp/TestOutputStream.java @@ -0,0 +1,29 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.exporter.internal.otlp; + +import java.io.OutputStream; + +class TestOutputStream extends OutputStream { + private final int size; + private int count; + + TestOutputStream() { + this(-1); + } + + TestOutputStream(int size) { + this.size = size; + } + + @Override + public void write(int b) { + count++; + if (size > 0 && count > size) { + throw new IllegalStateException("max size exceeded"); + } + } +} From f99e4961cb91447f242f3cd044acf0531b4c8bd3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9sar?= <56847527+LikeTheSalad@users.noreply.github.com> Date: Thu, 9 Nov 2023 15:49:06 +0100 Subject: [PATCH 082/901] Identifying otel http calls (#5918) Co-authored-by: jack-berg <34418638+jack-berg@users.noreply.github.com> --- .../internal/InstrumentationUtil.java | 40 ++++++++ .../internal/InstrumentationUtilTest.java | 27 ++++++ .../okhttp/internal/OkHttpGrpcSender.java | 93 ++++++++++--------- .../okhttp/internal/OkHttpHttpSender.java | 65 ++++++------- .../sender/okhttp/internal/OkHttpUtil.java | 9 +- .../AbstractOkHttpSuppressionTest.java | 58 ++++++++++++ .../internal/OkHttpGrpcSuppressionTest.java | 36 +++++++ .../internal/OkHttpHttpSuppressionTest.java | 39 ++++++++ .../sdk/internal/DaemonThreadFactory.java | 19 +++- 9 files changed, 308 insertions(+), 78 deletions(-) create mode 100644 exporters/common/src/main/java/io/opentelemetry/exporter/internal/InstrumentationUtil.java create mode 100644 exporters/common/src/test/java/io/opentelemetry/exporter/internal/InstrumentationUtilTest.java create mode 100644 exporters/sender/okhttp/src/test/java/io/opentelemetry/exporter/sender/okhttp/internal/AbstractOkHttpSuppressionTest.java create mode 100644 exporters/sender/okhttp/src/test/java/io/opentelemetry/exporter/sender/okhttp/internal/OkHttpGrpcSuppressionTest.java create mode 100644 exporters/sender/okhttp/src/test/java/io/opentelemetry/exporter/sender/okhttp/internal/OkHttpHttpSuppressionTest.java diff --git a/exporters/common/src/main/java/io/opentelemetry/exporter/internal/InstrumentationUtil.java b/exporters/common/src/main/java/io/opentelemetry/exporter/internal/InstrumentationUtil.java new file mode 100644 index 00000000000..4ce9622fe4c --- /dev/null +++ b/exporters/common/src/main/java/io/opentelemetry/exporter/internal/InstrumentationUtil.java @@ -0,0 +1,40 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.exporter.internal; + +import io.opentelemetry.context.Context; +import io.opentelemetry.context.ContextKey; +import java.util.Objects; + +/** + * This class is internal and is hence not for public use. Its APIs are unstable and can change at + * any time. + */ +public final class InstrumentationUtil { + private static final ContextKey SUPPRESS_INSTRUMENTATION_KEY = + ContextKey.named("suppress_internal_exporter_instrumentation"); + + private InstrumentationUtil() {} + + /** + * Adds a Context boolean key that will allow to identify HTTP calls coming from OTel exporters. + * The key later be checked by an automatic instrumentation to avoid tracing OTel exporter's + * calls. + */ + public static void suppressInstrumentation(Runnable runnable) { + Context.current().with(SUPPRESS_INSTRUMENTATION_KEY, true).wrap(runnable).run(); + } + + /** + * Checks if an automatic instrumentation should be suppressed with the provided Context. + * + * @return TRUE to suppress the automatic instrumentation, FALSE to continue with the + * instrumentation. + */ + public static boolean shouldSuppressInstrumentation(Context context) { + return Objects.equals(context.get(SUPPRESS_INSTRUMENTATION_KEY), true); + } +} diff --git a/exporters/common/src/test/java/io/opentelemetry/exporter/internal/InstrumentationUtilTest.java b/exporters/common/src/test/java/io/opentelemetry/exporter/internal/InstrumentationUtilTest.java new file mode 100644 index 00000000000..2c7e9f540c7 --- /dev/null +++ b/exporters/common/src/test/java/io/opentelemetry/exporter/internal/InstrumentationUtilTest.java @@ -0,0 +1,27 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.exporter.internal; + +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import io.opentelemetry.context.Context; +import org.junit.jupiter.api.Test; + +class InstrumentationUtilTest { + @Test + void verifySuppressInstrumentation() { + // Should be false by default. + assertFalse(InstrumentationUtil.shouldSuppressInstrumentation(Context.current())); + + // Should be true inside the Runnable passed to InstrumentationUtil.suppressInstrumentation. + InstrumentationUtil.suppressInstrumentation( + () -> assertTrue(InstrumentationUtil.shouldSuppressInstrumentation(Context.current()))); + + // Should be false after the runnable finishes. + assertFalse(InstrumentationUtil.shouldSuppressInstrumentation(Context.current())); + } +} diff --git a/exporters/sender/okhttp/src/main/java/io/opentelemetry/exporter/sender/okhttp/internal/OkHttpGrpcSender.java b/exporters/sender/okhttp/src/main/java/io/opentelemetry/exporter/sender/okhttp/internal/OkHttpGrpcSender.java index 5da750edead..9ed05b003b5 100644 --- a/exporters/sender/okhttp/src/main/java/io/opentelemetry/exporter/sender/okhttp/internal/OkHttpGrpcSender.java +++ b/exporters/sender/okhttp/src/main/java/io/opentelemetry/exporter/sender/okhttp/internal/OkHttpGrpcSender.java @@ -23,6 +23,7 @@ package io.opentelemetry.exporter.sender.okhttp.internal; +import io.opentelemetry.exporter.internal.InstrumentationUtil; import io.opentelemetry.exporter.internal.RetryUtil; import io.opentelemetry.exporter.internal.grpc.GrpcExporterUtil; import io.opentelemetry.exporter.internal.grpc.GrpcResponse; @@ -112,51 +113,53 @@ public void send(T request, Runnable onSuccess, BiConsumer + client + .newCall(requestBuilder.build()) + .enqueue( + new Callback() { + @Override + public void onFailure(Call call, IOException e) { + String description = e.getMessage(); + if (description == null) { + description = ""; + } + onError.accept(GrpcResponse.create(2 /* UNKNOWN */, description), e); + } + + @Override + public void onResponse(Call call, Response response) { + // Response body is empty but must be consumed to access trailers. + try { + response.body().bytes(); + } catch (IOException e) { + onError.accept( + GrpcResponse.create( + GrpcExporterUtil.GRPC_STATUS_UNKNOWN, + "Could not consume server response."), + e); + return; + } + + String status = grpcStatus(response); + if ("0".equals(status)) { + onSuccess.run(); + return; + } + + String errorMessage = grpcMessage(response); + int statusCode; + try { + statusCode = Integer.parseInt(status); + } catch (NumberFormatException ex) { + statusCode = GrpcExporterUtil.GRPC_STATUS_UNKNOWN; + } + onError.accept( + GrpcResponse.create(statusCode, errorMessage), + new IllegalStateException(errorMessage)); + } + })); } @Nullable diff --git a/exporters/sender/okhttp/src/main/java/io/opentelemetry/exporter/sender/okhttp/internal/OkHttpHttpSender.java b/exporters/sender/okhttp/src/main/java/io/opentelemetry/exporter/sender/okhttp/internal/OkHttpHttpSender.java index 306c7b97163..2355a94ba60 100644 --- a/exporters/sender/okhttp/src/main/java/io/opentelemetry/exporter/sender/okhttp/internal/OkHttpHttpSender.java +++ b/exporters/sender/okhttp/src/main/java/io/opentelemetry/exporter/sender/okhttp/internal/OkHttpHttpSender.java @@ -5,6 +5,7 @@ package io.opentelemetry.exporter.sender.okhttp.internal; +import io.opentelemetry.exporter.internal.InstrumentationUtil; import io.opentelemetry.exporter.internal.RetryUtil; import io.opentelemetry.exporter.internal.auth.Authenticator; import io.opentelemetry.exporter.internal.http.HttpSender; @@ -101,38 +102,40 @@ public void send( requestBuilder.post(body); } - client - .newCall(requestBuilder.build()) - .enqueue( - new Callback() { - @Override - public void onFailure(Call call, IOException e) { - onError.accept(e); - } - - @Override - public void onResponse(Call call, okhttp3.Response response) { - try (ResponseBody body = response.body()) { - onResponse.accept( - new Response() { - @Override - public int statusCode() { - return response.code(); + InstrumentationUtil.suppressInstrumentation( + () -> + client + .newCall(requestBuilder.build()) + .enqueue( + new Callback() { + @Override + public void onFailure(Call call, IOException e) { + onError.accept(e); + } + + @Override + public void onResponse(Call call, okhttp3.Response response) { + try (ResponseBody body = response.body()) { + onResponse.accept( + new Response() { + @Override + public int statusCode() { + return response.code(); + } + + @Override + public String statusMessage() { + return response.message(); + } + + @Override + public byte[] responseBody() throws IOException { + return body.bytes(); + } + }); } - - @Override - public String statusMessage() { - return response.message(); - } - - @Override - public byte[] responseBody() throws IOException { - return body.bytes(); - } - }); - } - } - }); + } + })); } @Override diff --git a/exporters/sender/okhttp/src/main/java/io/opentelemetry/exporter/sender/okhttp/internal/OkHttpUtil.java b/exporters/sender/okhttp/src/main/java/io/opentelemetry/exporter/sender/okhttp/internal/OkHttpUtil.java index 8aef6b7c21a..b641d1bad05 100644 --- a/exporters/sender/okhttp/src/main/java/io/opentelemetry/exporter/sender/okhttp/internal/OkHttpUtil.java +++ b/exporters/sender/okhttp/src/main/java/io/opentelemetry/exporter/sender/okhttp/internal/OkHttpUtil.java @@ -18,6 +18,13 @@ * at any time. */ public final class OkHttpUtil { + @SuppressWarnings("NonFinalStaticField") + private static boolean propagateContextForTestingInDispatcher = false; + + public static void setPropagateContextForTestingInDispatcher( + boolean propagateContextForTestingInDispatcher) { + OkHttpUtil.propagateContextForTestingInDispatcher = propagateContextForTestingInDispatcher; + } /** Returns a {@link Dispatcher} using daemon threads, otherwise matching the OkHttp default. */ public static Dispatcher newDispatcher() { @@ -28,7 +35,7 @@ public static Dispatcher newDispatcher() { 60, TimeUnit.SECONDS, new SynchronousQueue<>(), - new DaemonThreadFactory("okhttp-dispatch"))); + new DaemonThreadFactory("okhttp-dispatch", propagateContextForTestingInDispatcher))); } private OkHttpUtil() {} diff --git a/exporters/sender/okhttp/src/test/java/io/opentelemetry/exporter/sender/okhttp/internal/AbstractOkHttpSuppressionTest.java b/exporters/sender/okhttp/src/test/java/io/opentelemetry/exporter/sender/okhttp/internal/AbstractOkHttpSuppressionTest.java new file mode 100644 index 00000000000..d1a84a7491d --- /dev/null +++ b/exporters/sender/okhttp/src/test/java/io/opentelemetry/exporter/sender/okhttp/internal/AbstractOkHttpSuppressionTest.java @@ -0,0 +1,58 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.exporter.sender.okhttp.internal; + +import static org.junit.jupiter.api.Assertions.assertTrue; + +import io.opentelemetry.context.Context; +import io.opentelemetry.exporter.internal.InstrumentationUtil; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.atomic.AtomicBoolean; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +abstract class AbstractOkHttpSuppressionTest { + + @BeforeEach + void setUp() { + OkHttpUtil.setPropagateContextForTestingInDispatcher(true); + } + + @AfterEach + void tearDown() { + OkHttpUtil.setPropagateContextForTestingInDispatcher(false); + } + + @Test + void testSuppressInstrumentation() throws InterruptedException { + CountDownLatch latch = new CountDownLatch(1); + AtomicBoolean suppressInstrumentation = new AtomicBoolean(false); + + Runnable onSuccess = Assertions::fail; + Runnable onFailure = + () -> { + suppressInstrumentation.set( + InstrumentationUtil.shouldSuppressInstrumentation(Context.current())); + latch.countDown(); + }; + + send(getSender(), onSuccess, onFailure); + + latch.await(); + + assertTrue(suppressInstrumentation.get()); + } + + abstract void send(T sender, Runnable onSuccess, Runnable onFailure); + + private T getSender() { + return createSender("https://none"); + } + + abstract T createSender(String endpoint); +} diff --git a/exporters/sender/okhttp/src/test/java/io/opentelemetry/exporter/sender/okhttp/internal/OkHttpGrpcSuppressionTest.java b/exporters/sender/okhttp/src/test/java/io/opentelemetry/exporter/sender/okhttp/internal/OkHttpGrpcSuppressionTest.java new file mode 100644 index 00000000000..df52ff0f891 --- /dev/null +++ b/exporters/sender/okhttp/src/test/java/io/opentelemetry/exporter/sender/okhttp/internal/OkHttpGrpcSuppressionTest.java @@ -0,0 +1,36 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.exporter.sender.okhttp.internal; + +import io.opentelemetry.exporter.internal.marshal.MarshalerWithSize; +import io.opentelemetry.exporter.internal.marshal.Serializer; +import java.util.Collections; + +class OkHttpGrpcSuppressionTest + extends AbstractOkHttpSuppressionTest< + OkHttpGrpcSender> { + + @Override + void send(OkHttpGrpcSender sender, Runnable onSuccess, Runnable onFailure) { + sender.send(new DummyMarshaler(), onSuccess, (grpcResponse, throwable) -> onFailure.run()); + } + + @Override + OkHttpGrpcSender createSender(String endpoint) { + return new OkHttpGrpcSender<>( + "https://localhost", false, 10L, Collections.emptyMap(), null, null, null); + } + + protected static class DummyMarshaler extends MarshalerWithSize { + + protected DummyMarshaler() { + super(0); + } + + @Override + protected void writeTo(Serializer output) {} + } +} diff --git a/exporters/sender/okhttp/src/test/java/io/opentelemetry/exporter/sender/okhttp/internal/OkHttpHttpSuppressionTest.java b/exporters/sender/okhttp/src/test/java/io/opentelemetry/exporter/sender/okhttp/internal/OkHttpHttpSuppressionTest.java new file mode 100644 index 00000000000..22c2c4a0dd0 --- /dev/null +++ b/exporters/sender/okhttp/src/test/java/io/opentelemetry/exporter/sender/okhttp/internal/OkHttpHttpSuppressionTest.java @@ -0,0 +1,39 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.exporter.sender.okhttp.internal; + +import java.io.IOException; +import java.io.OutputStream; +import java.nio.charset.StandardCharsets; +import java.util.Collections; +import java.util.function.Consumer; + +class OkHttpHttpSuppressionTest extends AbstractOkHttpSuppressionTest { + + @Override + void send(OkHttpHttpSender sender, Runnable onSuccess, Runnable onFailure) { + byte[] content = "A".getBytes(StandardCharsets.UTF_8); + Consumer outputStreamConsumer = + outputStream -> { + try { + outputStream.write(content); + } catch (IOException e) { + throw new RuntimeException(e); + } + }; + sender.send( + outputStreamConsumer, + content.length, + (response) -> onSuccess.run(), + (error) -> onFailure.run()); + } + + @Override + OkHttpHttpSender createSender(String endpoint) { + return new OkHttpHttpSender( + endpoint, false, "text/plain", 10L, Collections::emptyMap, null, null, null, null); + } +} diff --git a/sdk/common/src/main/java/io/opentelemetry/sdk/internal/DaemonThreadFactory.java b/sdk/common/src/main/java/io/opentelemetry/sdk/internal/DaemonThreadFactory.java index 9e319d8f735..e8f75abe40f 100644 --- a/sdk/common/src/main/java/io/opentelemetry/sdk/internal/DaemonThreadFactory.java +++ b/sdk/common/src/main/java/io/opentelemetry/sdk/internal/DaemonThreadFactory.java @@ -5,6 +5,7 @@ package io.opentelemetry.sdk.internal; +import io.opentelemetry.context.Context; import java.util.concurrent.Executors; import java.util.concurrent.ThreadFactory; import java.util.concurrent.atomic.AtomicInteger; @@ -20,14 +21,30 @@ public final class DaemonThreadFactory implements ThreadFactory { private final String namePrefix; private final AtomicInteger counter = new AtomicInteger(); private final ThreadFactory delegate = Executors.defaultThreadFactory(); + private final boolean propagateContextForTesting; public DaemonThreadFactory(String namePrefix) { + this(namePrefix, /* propagateContextForTesting= */ false); + } + + /** + * {@link DaemonThreadFactory}'s constructor. + * + * @param namePrefix Used when setting the new thread's name. + * @param propagateContextForTesting For tests only. When enabled, the current thread's {@link + * Context} will be passed over to the new threads, this is useful for validating scenarios + * where context propagation is available through bytecode instrumentation. + */ + public DaemonThreadFactory(String namePrefix, boolean propagateContextForTesting) { this.namePrefix = namePrefix; + this.propagateContextForTesting = propagateContextForTesting; } @Override public Thread newThread(Runnable runnable) { - Thread t = delegate.newThread(runnable); + Thread t = + delegate.newThread( + propagateContextForTesting ? Context.current().wrap(runnable) : runnable); try { t.setDaemon(true); t.setName(namePrefix + "-" + counter.incrementAndGet()); From f2f3ab33b764733b9c70519967b8eabeb4c90063 Mon Sep 17 00:00:00 2001 From: jack-berg <34418638+jack-berg@users.noreply.github.com> Date: Thu, 9 Nov 2023 08:49:21 -0600 Subject: [PATCH 083/901] Autoconfigure listener (#5931) --- .../opentelemetry-exporter-otlp.txt | 13 ++- .../internal/grpc/GrpcExporterBuilder.java | 4 +- .../internal/http/HttpExporterBuilder.java | 4 +- .../jaeger/JaegerGrpcSpanExporterBuilder.java | 2 +- .../OtlpHttpLogRecordExporterBuilder.java | 14 ++- .../OtlpHttpMetricExporterBuilder.java | 2 +- .../trace/OtlpHttpSpanExporterBuilder.java | 14 ++- .../OtlpLogRecordExporterProvider.java | 18 +++- .../internal/OtlpMetricExporterProvider.java | 1 + .../internal/OtlpSpanExporterProvider.java | 18 +++- .../OtlpGrpcLogRecordExporterBuilder.java | 14 ++- .../OtlpGrpcMetricExporterBuilder.java | 2 +- .../trace/OtlpGrpcSpanExporterBuilder.java | 14 ++- .../perf/OtlpPipelineStressTest.java | 2 +- .../spi/internal/AutoConfigureListener.java | 20 +++++ ...AutoConfiguredOpenTelemetrySdkBuilder.java | 14 +++ .../sdk/autoconfigure/internal/SpiHelper.java | 26 +++++- .../AutoConfiguredOpenTelemetrySdkTest.java | 24 +++++ .../ConfigurableLogRecordExporterTest.java | 19 ++-- .../ConfigurableMetricExporterTest.java | 5 ++ .../ConfigurableSpanExporterTest.java | 7 ++ .../sdk/autoconfigure/FullConfigTest.java | 89 ++++++++++++------- .../provider/MetricCustomizer.java | 8 +- ...ConfigurableLogRecordExporterProvider.java | 7 +- ...estConfigurableMetricExporterProvider.java | 8 +- .../TestConfigurableSpanExporterProvider.java | 8 +- 26 files changed, 295 insertions(+), 62 deletions(-) create mode 100644 sdk-extensions/autoconfigure-spi/src/main/java/io/opentelemetry/sdk/autoconfigure/spi/internal/AutoConfigureListener.java diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-otlp.txt b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-otlp.txt index df26146497b..afee563c67e 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-otlp.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-otlp.txt @@ -1,2 +1,13 @@ Comparing source compatibility of against -No changes. \ No newline at end of file +*** MODIFIED CLASS: PUBLIC FINAL io.opentelemetry.exporter.otlp.http.logs.OtlpHttpLogRecordExporterBuilder (not serializable) + === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 + +++ NEW METHOD: PUBLIC(+) io.opentelemetry.exporter.otlp.http.logs.OtlpHttpLogRecordExporterBuilder setMeterProvider(java.util.function.Supplier) +*** MODIFIED CLASS: PUBLIC FINAL io.opentelemetry.exporter.otlp.http.trace.OtlpHttpSpanExporterBuilder (not serializable) + === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 + +++ NEW METHOD: PUBLIC(+) io.opentelemetry.exporter.otlp.http.trace.OtlpHttpSpanExporterBuilder setMeterProvider(java.util.function.Supplier) +*** MODIFIED CLASS: PUBLIC FINAL io.opentelemetry.exporter.otlp.logs.OtlpGrpcLogRecordExporterBuilder (not serializable) + === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 + +++ NEW METHOD: PUBLIC(+) io.opentelemetry.exporter.otlp.logs.OtlpGrpcLogRecordExporterBuilder setMeterProvider(java.util.function.Supplier) +*** MODIFIED CLASS: PUBLIC FINAL io.opentelemetry.exporter.otlp.trace.OtlpGrpcSpanExporterBuilder (not serializable) + === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 + +++ NEW METHOD: PUBLIC(+) io.opentelemetry.exporter.otlp.trace.OtlpGrpcSpanExporterBuilder setMeterProvider(java.util.function.Supplier) diff --git a/exporters/common/src/main/java/io/opentelemetry/exporter/internal/grpc/GrpcExporterBuilder.java b/exporters/common/src/main/java/io/opentelemetry/exporter/internal/grpc/GrpcExporterBuilder.java index 31eb7745d54..6260db41c73 100644 --- a/exporters/common/src/main/java/io/opentelemetry/exporter/internal/grpc/GrpcExporterBuilder.java +++ b/exporters/common/src/main/java/io/opentelemetry/exporter/internal/grpc/GrpcExporterBuilder.java @@ -123,8 +123,8 @@ public GrpcExporterBuilder setRetryPolicy(RetryPolicy retryPolicy) { return this; } - public GrpcExporterBuilder setMeterProvider(MeterProvider meterProvider) { - this.meterProviderSupplier = () -> meterProvider; + public GrpcExporterBuilder setMeterProvider(Supplier meterProviderSupplier) { + this.meterProviderSupplier = meterProviderSupplier; return this; } diff --git a/exporters/common/src/main/java/io/opentelemetry/exporter/internal/http/HttpExporterBuilder.java b/exporters/common/src/main/java/io/opentelemetry/exporter/internal/http/HttpExporterBuilder.java index 5227a760eb5..fc4473b034c 100644 --- a/exporters/common/src/main/java/io/opentelemetry/exporter/internal/http/HttpExporterBuilder.java +++ b/exporters/common/src/main/java/io/opentelemetry/exporter/internal/http/HttpExporterBuilder.java @@ -112,8 +112,8 @@ public HttpExporterBuilder setSslContext( return this; } - public HttpExporterBuilder setMeterProvider(MeterProvider meterProvider) { - this.meterProviderSupplier = () -> meterProvider; + public HttpExporterBuilder setMeterProvider(Supplier meterProviderSupplier) { + this.meterProviderSupplier = meterProviderSupplier; return this; } diff --git a/exporters/jaeger/src/main/java/io/opentelemetry/exporter/jaeger/JaegerGrpcSpanExporterBuilder.java b/exporters/jaeger/src/main/java/io/opentelemetry/exporter/jaeger/JaegerGrpcSpanExporterBuilder.java index e67311dc7e5..4255401ae00 100644 --- a/exporters/jaeger/src/main/java/io/opentelemetry/exporter/jaeger/JaegerGrpcSpanExporterBuilder.java +++ b/exporters/jaeger/src/main/java/io/opentelemetry/exporter/jaeger/JaegerGrpcSpanExporterBuilder.java @@ -145,7 +145,7 @@ public JaegerGrpcSpanExporterBuilder setSslContext( */ public JaegerGrpcSpanExporterBuilder setMeterProvider(MeterProvider meterProvider) { requireNonNull(meterProvider, "meterProvider"); - delegate.setMeterProvider(meterProvider); + delegate.setMeterProvider(() -> meterProvider); return this; } diff --git a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/logs/OtlpHttpLogRecordExporterBuilder.java b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/logs/OtlpHttpLogRecordExporterBuilder.java index cb74e9859a8..0a9c9733917 100644 --- a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/logs/OtlpHttpLogRecordExporterBuilder.java +++ b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/logs/OtlpHttpLogRecordExporterBuilder.java @@ -16,6 +16,7 @@ import io.opentelemetry.sdk.common.export.RetryPolicy; import java.time.Duration; import java.util.concurrent.TimeUnit; +import java.util.function.Supplier; import javax.net.ssl.SSLContext; import javax.net.ssl.X509TrustManager; @@ -135,7 +136,18 @@ public OtlpHttpLogRecordExporterBuilder setRetryPolicy(RetryPolicy retryPolicy) */ public OtlpHttpLogRecordExporterBuilder setMeterProvider(MeterProvider meterProvider) { requireNonNull(meterProvider, "meterProvider"); - delegate.setMeterProvider(meterProvider); + setMeterProvider(() -> meterProvider); + return this; + } + + /** + * Sets the {@link MeterProvider} supplier used to collect metrics related to export. If not set, + * uses {@link GlobalOpenTelemetry#getMeterProvider()}. + */ + public OtlpHttpLogRecordExporterBuilder setMeterProvider( + Supplier meterProviderSupplier) { + requireNonNull(meterProviderSupplier, "meterProviderSupplier"); + delegate.setMeterProvider(meterProviderSupplier); return this; } diff --git a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/metrics/OtlpHttpMetricExporterBuilder.java b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/metrics/OtlpHttpMetricExporterBuilder.java index c9466d51819..57cca1c8f9b 100644 --- a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/metrics/OtlpHttpMetricExporterBuilder.java +++ b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/metrics/OtlpHttpMetricExporterBuilder.java @@ -43,7 +43,7 @@ public final class OtlpHttpMetricExporterBuilder { OtlpHttpMetricExporterBuilder(HttpExporterBuilder delegate) { this.delegate = delegate; - delegate.setMeterProvider(MeterProvider.noop()); + delegate.setMeterProvider(MeterProvider::noop); OtlpUserAgent.addUserAgentHeader(delegate::addHeader); } diff --git a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/trace/OtlpHttpSpanExporterBuilder.java b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/trace/OtlpHttpSpanExporterBuilder.java index 3cf5b85b1cf..890ec87ace7 100644 --- a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/trace/OtlpHttpSpanExporterBuilder.java +++ b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/trace/OtlpHttpSpanExporterBuilder.java @@ -16,6 +16,7 @@ import io.opentelemetry.sdk.common.export.RetryPolicy; import java.time.Duration; import java.util.concurrent.TimeUnit; +import java.util.function.Supplier; import javax.net.ssl.SSLContext; import javax.net.ssl.X509TrustManager; @@ -136,7 +137,18 @@ public OtlpHttpSpanExporterBuilder setRetryPolicy(RetryPolicy retryPolicy) { */ public OtlpHttpSpanExporterBuilder setMeterProvider(MeterProvider meterProvider) { requireNonNull(meterProvider, "meterProvider"); - delegate.setMeterProvider(meterProvider); + setMeterProvider(() -> meterProvider); + return this; + } + + /** + * Sets the {@link MeterProvider} supplier to use to collect metrics related to export. If not + * set, uses {@link GlobalOpenTelemetry#getMeterProvider()}. + */ + public OtlpHttpSpanExporterBuilder setMeterProvider( + Supplier meterProviderSupplier) { + requireNonNull(meterProviderSupplier, "meterProviderSupplier"); + delegate.setMeterProvider(meterProviderSupplier); return this; } diff --git a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/OtlpLogRecordExporterProvider.java b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/OtlpLogRecordExporterProvider.java index ebc2c25eb44..1694189d69b 100644 --- a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/OtlpLogRecordExporterProvider.java +++ b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/OtlpLogRecordExporterProvider.java @@ -9,14 +9,18 @@ import static io.opentelemetry.exporter.otlp.internal.OtlpConfigUtil.PROTOCOL_GRPC; import static io.opentelemetry.exporter.otlp.internal.OtlpConfigUtil.PROTOCOL_HTTP_PROTOBUF; +import io.opentelemetry.api.metrics.MeterProvider; import io.opentelemetry.exporter.otlp.http.logs.OtlpHttpLogRecordExporter; import io.opentelemetry.exporter.otlp.http.logs.OtlpHttpLogRecordExporterBuilder; import io.opentelemetry.exporter.otlp.logs.OtlpGrpcLogRecordExporter; import io.opentelemetry.exporter.otlp.logs.OtlpGrpcLogRecordExporterBuilder; +import io.opentelemetry.sdk.OpenTelemetrySdk; import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties; import io.opentelemetry.sdk.autoconfigure.spi.ConfigurationException; +import io.opentelemetry.sdk.autoconfigure.spi.internal.AutoConfigureListener; import io.opentelemetry.sdk.autoconfigure.spi.logs.ConfigurableLogRecordExporterProvider; import io.opentelemetry.sdk.logs.export.LogRecordExporter; +import java.util.concurrent.atomic.AtomicReference; /** * {@link LogRecordExporter} SPI implementation for {@link OtlpGrpcLogRecordExporter} and {@link @@ -25,7 +29,12 @@ *

    This class is internal and is hence not for public use. Its APIs are unstable and can change * at any time. */ -public class OtlpLogRecordExporterProvider implements ConfigurableLogRecordExporterProvider { +public class OtlpLogRecordExporterProvider + implements ConfigurableLogRecordExporterProvider, AutoConfigureListener { + + private final AtomicReference meterProviderRef = + new AtomicReference<>(MeterProvider.noop()); + @Override public LogRecordExporter createExporter(ConfigProperties config) { String protocol = OtlpConfigUtil.getOtlpProtocol(DATA_TYPE_LOGS, config); @@ -43,6 +52,7 @@ public LogRecordExporter createExporter(ConfigProperties config) { builder::setTrustedCertificates, builder::setClientTls, builder::setRetryPolicy); + builder.setMeterProvider(meterProviderRef::get); return builder.build(); } else if (protocol.equals(PROTOCOL_GRPC)) { @@ -58,6 +68,7 @@ public LogRecordExporter createExporter(ConfigProperties config) { builder::setTrustedCertificates, builder::setClientTls, builder::setRetryPolicy); + builder.setMeterProvider(meterProviderRef::get); return builder.build(); } @@ -78,4 +89,9 @@ OtlpHttpLogRecordExporterBuilder httpBuilder() { OtlpGrpcLogRecordExporterBuilder grpcBuilder() { return OtlpGrpcLogRecordExporter.builder(); } + + @Override + public void afterAutoConfigure(OpenTelemetrySdk sdk) { + meterProviderRef.set(sdk.getMeterProvider()); + } } diff --git a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/OtlpMetricExporterProvider.java b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/OtlpMetricExporterProvider.java index 48111b8d84a..3d424b498f0 100644 --- a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/OtlpMetricExporterProvider.java +++ b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/OtlpMetricExporterProvider.java @@ -26,6 +26,7 @@ * at any time. */ public class OtlpMetricExporterProvider implements ConfigurableMetricExporterProvider { + @Override public MetricExporter createExporter(ConfigProperties config) { String protocol = OtlpConfigUtil.getOtlpProtocol(DATA_TYPE_METRICS, config); diff --git a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/OtlpSpanExporterProvider.java b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/OtlpSpanExporterProvider.java index 4c43dd2a82a..b4b8731b1bd 100644 --- a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/OtlpSpanExporterProvider.java +++ b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/OtlpSpanExporterProvider.java @@ -9,14 +9,18 @@ import static io.opentelemetry.exporter.otlp.internal.OtlpConfigUtil.PROTOCOL_GRPC; import static io.opentelemetry.exporter.otlp.internal.OtlpConfigUtil.PROTOCOL_HTTP_PROTOBUF; +import io.opentelemetry.api.metrics.MeterProvider; import io.opentelemetry.exporter.otlp.http.trace.OtlpHttpSpanExporter; import io.opentelemetry.exporter.otlp.http.trace.OtlpHttpSpanExporterBuilder; import io.opentelemetry.exporter.otlp.trace.OtlpGrpcSpanExporter; import io.opentelemetry.exporter.otlp.trace.OtlpGrpcSpanExporterBuilder; +import io.opentelemetry.sdk.OpenTelemetrySdk; import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties; import io.opentelemetry.sdk.autoconfigure.spi.ConfigurationException; +import io.opentelemetry.sdk.autoconfigure.spi.internal.AutoConfigureListener; import io.opentelemetry.sdk.autoconfigure.spi.traces.ConfigurableSpanExporterProvider; import io.opentelemetry.sdk.trace.export.SpanExporter; +import java.util.concurrent.atomic.AtomicReference; /** * {@link SpanExporter} SPI implementation for {@link OtlpGrpcSpanExporter} and {@link @@ -25,7 +29,12 @@ *

    This class is internal and is hence not for public use. Its APIs are unstable and can change * at any time. */ -public class OtlpSpanExporterProvider implements ConfigurableSpanExporterProvider { +public class OtlpSpanExporterProvider + implements ConfigurableSpanExporterProvider, AutoConfigureListener { + + private final AtomicReference meterProviderRef = + new AtomicReference<>(MeterProvider.noop()); + @Override public SpanExporter createExporter(ConfigProperties config) { String protocol = OtlpConfigUtil.getOtlpProtocol(DATA_TYPE_TRACES, config); @@ -42,6 +51,7 @@ public SpanExporter createExporter(ConfigProperties config) { builder::setTrustedCertificates, builder::setClientTls, builder::setRetryPolicy); + builder.setMeterProvider(meterProviderRef::get); return builder.build(); } else if (protocol.equals(PROTOCOL_GRPC)) { @@ -57,6 +67,7 @@ public SpanExporter createExporter(ConfigProperties config) { builder::setTrustedCertificates, builder::setClientTls, builder::setRetryPolicy); + builder.setMeterProvider(meterProviderRef::get); return builder.build(); } @@ -77,4 +88,9 @@ OtlpHttpSpanExporterBuilder httpBuilder() { OtlpGrpcSpanExporterBuilder grpcBuilder() { return OtlpGrpcSpanExporter.builder(); } + + @Override + public void afterAutoConfigure(OpenTelemetrySdk sdk) { + meterProviderRef.set(sdk.getMeterProvider()); + } } diff --git a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/logs/OtlpGrpcLogRecordExporterBuilder.java b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/logs/OtlpGrpcLogRecordExporterBuilder.java index 97b193bab3f..c825f93d023 100644 --- a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/logs/OtlpGrpcLogRecordExporterBuilder.java +++ b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/logs/OtlpGrpcLogRecordExporterBuilder.java @@ -18,6 +18,7 @@ import java.net.URI; import java.time.Duration; import java.util.concurrent.TimeUnit; +import java.util.function.Supplier; import javax.net.ssl.SSLContext; import javax.net.ssl.X509TrustManager; @@ -179,7 +180,18 @@ public OtlpGrpcLogRecordExporterBuilder setRetryPolicy(RetryPolicy retryPolicy) */ public OtlpGrpcLogRecordExporterBuilder setMeterProvider(MeterProvider meterProvider) { requireNonNull(meterProvider, "meterProvider"); - delegate.setMeterProvider(meterProvider); + setMeterProvider(() -> meterProvider); + return this; + } + + /** + * Sets the {@link MeterProvider} supplier used to collect metrics related to export. If not set, + * uses {@link GlobalOpenTelemetry#getMeterProvider()}. + */ + public OtlpGrpcLogRecordExporterBuilder setMeterProvider( + Supplier meterProviderSupplier) { + requireNonNull(meterProviderSupplier, "meterProviderSupplier"); + delegate.setMeterProvider(meterProviderSupplier); return this; } diff --git a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/metrics/OtlpGrpcMetricExporterBuilder.java b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/metrics/OtlpGrpcMetricExporterBuilder.java index 5059d111987..11ba7460868 100644 --- a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/metrics/OtlpGrpcMetricExporterBuilder.java +++ b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/metrics/OtlpGrpcMetricExporterBuilder.java @@ -53,7 +53,7 @@ public final class OtlpGrpcMetricExporterBuilder { OtlpGrpcMetricExporterBuilder(GrpcExporterBuilder delegate) { this.delegate = delegate; - delegate.setMeterProvider(MeterProvider.noop()); + delegate.setMeterProvider(MeterProvider::noop); OtlpUserAgent.addUserAgentHeader(delegate::addHeader); } diff --git a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/trace/OtlpGrpcSpanExporterBuilder.java b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/trace/OtlpGrpcSpanExporterBuilder.java index 9a27f97fc8b..9aa119c2f1f 100644 --- a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/trace/OtlpGrpcSpanExporterBuilder.java +++ b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/trace/OtlpGrpcSpanExporterBuilder.java @@ -18,6 +18,7 @@ import java.net.URI; import java.time.Duration; import java.util.concurrent.TimeUnit; +import java.util.function.Supplier; import javax.net.ssl.SSLContext; import javax.net.ssl.X509TrustManager; @@ -176,7 +177,18 @@ public OtlpGrpcSpanExporterBuilder setRetryPolicy(RetryPolicy retryPolicy) { */ public OtlpGrpcSpanExporterBuilder setMeterProvider(MeterProvider meterProvider) { requireNonNull(meterProvider, "meterProvider"); - delegate.setMeterProvider(meterProvider); + setMeterProvider(() -> meterProvider); + return this; + } + + /** + * Sets the {@link MeterProvider} supplier used to collect metrics related to export. If not set, + * uses {@link GlobalOpenTelemetry#getMeterProvider()}. + */ + public OtlpGrpcSpanExporterBuilder setMeterProvider( + Supplier meterProviderSupplier) { + requireNonNull(meterProviderSupplier, "meterProviderSupplier"); + delegate.setMeterProvider(meterProviderSupplier); return this; } diff --git a/perf-harness/src/test/java/io/opentelemetry/perf/OtlpPipelineStressTest.java b/perf-harness/src/test/java/io/opentelemetry/perf/OtlpPipelineStressTest.java index 0538d8f011f..5ab5db7214c 100644 --- a/perf-harness/src/test/java/io/opentelemetry/perf/OtlpPipelineStressTest.java +++ b/perf-harness/src/test/java/io/opentelemetry/perf/OtlpPipelineStressTest.java @@ -259,7 +259,7 @@ private void setupSdk() { // set up the span exporter and wire it into the SDK OtlpGrpcSpanExporter spanExporter = OtlpGrpcSpanExporter.builder() - .setMeterProvider(meterProvider) + .setMeterProvider(() -> meterProvider) .setEndpoint( "http://" + toxiproxyContainer.getHost() diff --git a/sdk-extensions/autoconfigure-spi/src/main/java/io/opentelemetry/sdk/autoconfigure/spi/internal/AutoConfigureListener.java b/sdk-extensions/autoconfigure-spi/src/main/java/io/opentelemetry/sdk/autoconfigure/spi/internal/AutoConfigureListener.java new file mode 100644 index 00000000000..af27105cb4f --- /dev/null +++ b/sdk-extensions/autoconfigure-spi/src/main/java/io/opentelemetry/sdk/autoconfigure/spi/internal/AutoConfigureListener.java @@ -0,0 +1,20 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.sdk.autoconfigure.spi.internal; + +import io.opentelemetry.sdk.OpenTelemetrySdk; + +/** + * Interface to be extended by SPIs that require access to the autoconfigured {@link + * OpenTelemetrySdk} instance. + * + *

    This is not a standalone SPI. Instead, implementations of other SPIs can also implement this + * interface to receive a callback with the configured SDK. + */ +public interface AutoConfigureListener { + + void afterAutoConfigure(OpenTelemetrySdk sdk); +} diff --git a/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/AutoConfiguredOpenTelemetrySdkBuilder.java b/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/AutoConfiguredOpenTelemetrySdkBuilder.java index 7a89123ef65..1761108081b 100644 --- a/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/AutoConfiguredOpenTelemetrySdkBuilder.java +++ b/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/AutoConfiguredOpenTelemetrySdkBuilder.java @@ -18,6 +18,7 @@ import io.opentelemetry.sdk.autoconfigure.spi.AutoConfigurationCustomizerProvider; import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties; import io.opentelemetry.sdk.autoconfigure.spi.ConfigurationException; +import io.opentelemetry.sdk.autoconfigure.spi.internal.AutoConfigureListener; import io.opentelemetry.sdk.autoconfigure.spi.internal.DefaultConfigProperties; import io.opentelemetry.sdk.logs.SdkLoggerProvider; import io.opentelemetry.sdk.logs.SdkLoggerProviderBuilder; @@ -405,6 +406,7 @@ public AutoConfiguredOpenTelemetrySdk build() { maybeRegisterShutdownHook(openTelemetrySdk); maybeSetAsGlobal(openTelemetrySdk); + callAutoConfigureListeners(spiHelper, openTelemetrySdk); return AutoConfiguredOpenTelemetrySdk.create(openTelemetrySdk, resource, config); } catch (RuntimeException e) { @@ -478,6 +480,18 @@ private void maybeSetAsGlobal(OpenTelemetrySdk openTelemetrySdk) { Level.FINE, "Global OpenTelemetry set to {0} by autoconfiguration", openTelemetrySdk); } + // Visible for testing + void callAutoConfigureListeners(SpiHelper spiHelper, OpenTelemetrySdk openTelemetrySdk) { + for (AutoConfigureListener listener : spiHelper.getListeners()) { + try { + listener.afterAutoConfigure(openTelemetrySdk); + } catch (Throwable throwable) { + logger.log( + Level.WARNING, "Error invoking listener " + listener.getClass().getName(), throwable); + } + } + } + @SuppressWarnings("deprecation") // Support deprecated SdkTracerProviderConfigurer private void mergeSdkTracerProviderConfigurer() { for (io.opentelemetry.sdk.autoconfigure.spi.traces.SdkTracerProviderConfigurer configurer : diff --git a/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/internal/SpiHelper.java b/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/internal/SpiHelper.java index c1d9e7eab84..4002ce65329 100644 --- a/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/internal/SpiHelper.java +++ b/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/internal/SpiHelper.java @@ -7,12 +7,16 @@ import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties; import io.opentelemetry.sdk.autoconfigure.spi.Ordered; +import io.opentelemetry.sdk.autoconfigure.spi.internal.AutoConfigureListener; import java.util.ArrayList; +import java.util.Collections; import java.util.Comparator; import java.util.HashMap; +import java.util.IdentityHashMap; import java.util.List; import java.util.Map; import java.util.ServiceLoader; +import java.util.Set; import java.util.function.BiFunction; import java.util.function.Function; import java.util.function.Supplier; @@ -25,6 +29,8 @@ public final class SpiHelper { private final ClassLoader classLoader; private final SpiFinder spiFinder; + private final Set listeners = + Collections.newSetFromMap(new IdentityHashMap<>()); // Visible for testing SpiHelper(ClassLoader classLoader, SpiFinder spiFinder) { @@ -57,7 +63,13 @@ public NamedSpiManager loadConfigurable( Map> nameToProvider = new HashMap<>(); for (S provider : load(spiClass)) { String name = getName.apply(provider); - nameToProvider.put(name, () -> getConfigurable.apply(provider, config)); + nameToProvider.put( + name, + () -> { + T result = getConfigurable.apply(provider, config); + maybeAddListener(result); + return result; + }); } return NamedSpiManager.create(nameToProvider); } @@ -85,11 +97,23 @@ public List loadOrdered(Class spiClass) { public List load(Class spiClass) { List result = new ArrayList<>(); for (T service : spiFinder.load(spiClass, classLoader)) { + maybeAddListener(service); result.add(service); } return result; } + private void maybeAddListener(Object object) { + if (object instanceof AutoConfigureListener) { + listeners.add((AutoConfigureListener) object); + } + } + + /** Return the set of SPIs loaded which implement {@link AutoConfigureListener}. */ + public Set getListeners() { + return Collections.unmodifiableSet(listeners); + } + // Visible for testing interface SpiFinder { Iterable load(Class spiClass, ClassLoader classLoader); diff --git a/sdk-extensions/autoconfigure/src/test/java/io/opentelemetry/sdk/autoconfigure/AutoConfiguredOpenTelemetrySdkTest.java b/sdk-extensions/autoconfigure/src/test/java/io/opentelemetry/sdk/autoconfigure/AutoConfiguredOpenTelemetrySdkTest.java index da0451a7144..649ad70406b 100644 --- a/sdk-extensions/autoconfigure/src/test/java/io/opentelemetry/sdk/autoconfigure/AutoConfiguredOpenTelemetrySdkTest.java +++ b/sdk-extensions/autoconfigure/src/test/java/io/opentelemetry/sdk/autoconfigure/AutoConfiguredOpenTelemetrySdkTest.java @@ -8,6 +8,7 @@ import static io.opentelemetry.api.common.AttributeKey.stringKey; import static java.util.Collections.singletonMap; import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatCode; import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.doReturn; @@ -33,8 +34,10 @@ import io.opentelemetry.context.propagation.TextMapPropagator; import io.opentelemetry.internal.testing.slf4j.SuppressLogger; import io.opentelemetry.sdk.OpenTelemetrySdk; +import io.opentelemetry.sdk.autoconfigure.internal.SpiHelper; import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties; import io.opentelemetry.sdk.autoconfigure.spi.ConfigurationException; +import io.opentelemetry.sdk.autoconfigure.spi.internal.AutoConfigureListener; import io.opentelemetry.sdk.common.CompletableResultCode; import io.opentelemetry.sdk.logs.LogRecordProcessor; import io.opentelemetry.sdk.logs.SdkLoggerProvider; @@ -393,6 +396,27 @@ void shutdownHook() throws InterruptedException { verify(sdk).close(); } + @Test + void builder_CallAutoConfigureListeners() { + builder = spy(builder); + + assertThatCode(() -> builder.build()).doesNotThrowAnyException(); + + verify(builder, times(1)).callAutoConfigureListeners(any(), any()); + } + + @Test + void callAutoConfigureListeners() { + AutoConfigureListener listener = mock(AutoConfigureListener.class); + SpiHelper spiHelper = mock(SpiHelper.class); + when(spiHelper.getListeners()).thenReturn(Collections.singleton(listener)); + OpenTelemetrySdk sdk = mock(OpenTelemetrySdk.class); + + builder.callAutoConfigureListeners(spiHelper, sdk); + + verify(listener).afterAutoConfigure(sdk); + } + private static Supplier> disableExportPropertySupplier() { Map props = new HashMap<>(); props.put("otel.metrics.exporter", "none"); diff --git a/sdk-extensions/autoconfigure/src/testFullConfig/java/io/opentelemetry/sdk/autoconfigure/ConfigurableLogRecordExporterTest.java b/sdk-extensions/autoconfigure/src/testFullConfig/java/io/opentelemetry/sdk/autoconfigure/ConfigurableLogRecordExporterTest.java index 315925be7f0..7025de0084e 100644 --- a/sdk-extensions/autoconfigure/src/testFullConfig/java/io/opentelemetry/sdk/autoconfigure/ConfigurableLogRecordExporterTest.java +++ b/sdk-extensions/autoconfigure/src/testFullConfig/java/io/opentelemetry/sdk/autoconfigure/ConfigurableLogRecordExporterTest.java @@ -9,6 +9,7 @@ import static org.assertj.core.api.Assertions.assertThatThrownBy; import com.google.common.collect.ImmutableMap; +import io.opentelemetry.exporter.otlp.internal.OtlpLogRecordExporterProvider; import io.opentelemetry.internal.testing.CleanupExtension; import io.opentelemetry.sdk.autoconfigure.internal.NamedSpiManager; import io.opentelemetry.sdk.autoconfigure.internal.SpiHelper; @@ -37,12 +38,10 @@ void configureLogRecordExporters_spiExporter() { ImmutableMap.of("test.option", "true", "otel.logs.exporter", "testExporter")); List closeables = new ArrayList<>(); + SpiHelper spiHelper = SpiHelper.create(LogRecordExporterConfiguration.class.getClassLoader()); Map exportersByName = LogRecordExporterConfiguration.configureLogRecordExporters( - config, - SpiHelper.create(LogRecordExporterConfiguration.class.getClassLoader()), - (a, unused) -> a, - closeables); + config, spiHelper, (a, unused) -> a, closeables); cleanup.addCloseables(closeables); assertThat(exportersByName) @@ -55,6 +54,11 @@ void configureLogRecordExporters_spiExporter() { assertThat(closeables) .hasExactlyElementsOfTypes( TestConfigurableLogRecordExporterProvider.TestLogRecordExporter.class); + assertThat(spiHelper.getListeners()) + .satisfiesExactlyInAnyOrder( + listener -> + assertThat(listener).isInstanceOf(TestConfigurableLogRecordExporterProvider.class), + listener -> assertThat(listener).isInstanceOf(OtlpLogRecordExporterProvider.class)); } @Test @@ -64,17 +68,16 @@ void configureLogRecordExporters_emptyClassLoader() { ImmutableMap.of("test.option", "true", "otel.logs.exporter", "testExporter")); List closeables = new ArrayList<>(); + SpiHelper spiHelper = SpiHelper.create(new URLClassLoader(new URL[0], null)); assertThatThrownBy( () -> LogRecordExporterConfiguration.configureLogRecordExporters( - config, - SpiHelper.create(new URLClassLoader(new URL[0], null)), - (a, unused) -> a, - closeables)) + config, spiHelper, (a, unused) -> a, closeables)) .isInstanceOf(ConfigurationException.class) .hasMessageContaining("testExporter"); cleanup.addCloseables(closeables); assertThat(closeables).isEmpty(); + assertThat(spiHelper.getListeners()).isEmpty(); } @Test diff --git a/sdk-extensions/autoconfigure/src/testFullConfig/java/io/opentelemetry/sdk/autoconfigure/ConfigurableMetricExporterTest.java b/sdk-extensions/autoconfigure/src/testFullConfig/java/io/opentelemetry/sdk/autoconfigure/ConfigurableMetricExporterTest.java index ba18d0c89c3..18797f0058b 100644 --- a/sdk-extensions/autoconfigure/src/testFullConfig/java/io/opentelemetry/sdk/autoconfigure/ConfigurableMetricExporterTest.java +++ b/sdk-extensions/autoconfigure/src/testFullConfig/java/io/opentelemetry/sdk/autoconfigure/ConfigurableMetricExporterTest.java @@ -49,6 +49,10 @@ void configureExporter_spiExporter() { .isInstanceOf(TestConfigurableMetricExporterProvider.TestMetricExporter.class) .extracting("config") .isSameAs(config); + assertThat(spiHelper.getListeners()) + .satisfiesExactlyInAnyOrder( + listener -> + assertThat(listener).isInstanceOf(TestConfigurableMetricExporterProvider.class)); } } @@ -88,6 +92,7 @@ void configureMetricReaders_multipleWithNone() { .hasMessageContaining("otel.metrics.exporter contains none along with other exporters"); cleanup.addCloseables(closeables); assertThat(closeables).isEmpty(); + assertThat(spiHelper.getListeners()).isEmpty(); } @Test diff --git a/sdk-extensions/autoconfigure/src/testFullConfig/java/io/opentelemetry/sdk/autoconfigure/ConfigurableSpanExporterTest.java b/sdk-extensions/autoconfigure/src/testFullConfig/java/io/opentelemetry/sdk/autoconfigure/ConfigurableSpanExporterTest.java index 89f23078da3..ef533b82ac3 100644 --- a/sdk-extensions/autoconfigure/src/testFullConfig/java/io/opentelemetry/sdk/autoconfigure/ConfigurableSpanExporterTest.java +++ b/sdk-extensions/autoconfigure/src/testFullConfig/java/io/opentelemetry/sdk/autoconfigure/ConfigurableSpanExporterTest.java @@ -11,6 +11,7 @@ import com.google.common.collect.ImmutableMap; import io.opentelemetry.api.metrics.MeterProvider; import io.opentelemetry.exporter.logging.LoggingSpanExporter; +import io.opentelemetry.exporter.otlp.internal.OtlpSpanExporterProvider; import io.opentelemetry.exporter.otlp.trace.OtlpGrpcSpanExporter; import io.opentelemetry.exporter.zipkin.ZipkinSpanExporter; import io.opentelemetry.internal.testing.CleanupExtension; @@ -63,6 +64,11 @@ void configureSpanExporters_spiExporter() { .isSameAs(config); assertThat(closeables) .hasExactlyElementsOfTypes(TestConfigurableSpanExporterProvider.TestSpanExporter.class); + assertThat(spiHelper.getListeners()) + .satisfiesExactlyInAnyOrder( + listener -> + assertThat(listener).isInstanceOf(TestConfigurableSpanExporterProvider.class), + listener -> assertThat(listener).isInstanceOf(OtlpSpanExporterProvider.class)); } @Test @@ -83,6 +89,7 @@ void configureSpanExporters_emptyClassLoader() { .hasMessageContaining("testExporter"); cleanup.addCloseables(closeables); assertThat(closeables).isEmpty(); + assertThat(spiHelper.getListeners()).isEmpty(); } @Test diff --git a/sdk-extensions/autoconfigure/src/testFullConfig/java/io/opentelemetry/sdk/autoconfigure/FullConfigTest.java b/sdk-extensions/autoconfigure/src/testFullConfig/java/io/opentelemetry/sdk/autoconfigure/FullConfigTest.java index 7a1a1f705f5..affe5d4fd63 100644 --- a/sdk-extensions/autoconfigure/src/testFullConfig/java/io/opentelemetry/sdk/autoconfigure/FullConfigTest.java +++ b/sdk-extensions/autoconfigure/src/testFullConfig/java/io/opentelemetry/sdk/autoconfigure/FullConfigTest.java @@ -39,8 +39,6 @@ import io.opentelemetry.proto.common.v1.AnyValue; import io.opentelemetry.proto.common.v1.KeyValue; import io.opentelemetry.proto.metrics.v1.Metric; -import io.opentelemetry.proto.metrics.v1.ResourceMetrics; -import io.opentelemetry.proto.metrics.v1.ScopeMetrics; import io.opentelemetry.sdk.OpenTelemetrySdk; import java.util.ArrayList; import java.util.Collection; @@ -216,8 +214,8 @@ void configures() throws Exception { eventEmitter.emit("test-name", Attributes.builder().put("cow", "moo").build()); openTelemetrySdk.getSdkTracerProvider().forceFlush().join(10, TimeUnit.SECONDS); - openTelemetrySdk.getSdkMeterProvider().forceFlush().join(10, TimeUnit.SECONDS); openTelemetrySdk.getSdkLoggerProvider().forceFlush().join(10, TimeUnit.SECONDS); + openTelemetrySdk.getSdkMeterProvider().forceFlush().join(10, TimeUnit.SECONDS); await().untilAsserted(() -> assertThat(otlpTraceRequests).hasSize(1)); @@ -257,38 +255,61 @@ void configures() throws Exception { .untilAsserted( () -> { ExportMetricsServiceRequest metricRequest = otlpMetricsRequests.take(); - assertThat(metricRequest.getResourceMetrics(0).getResource().getAttributesList()) - .contains( - KeyValue.newBuilder() - .setKey("service.name") - .setValue(AnyValue.newBuilder().setStringValue("test").build()) - .build(), - KeyValue.newBuilder() - .setKey("cat") - .setValue(AnyValue.newBuilder().setStringValue("meow").build()) - .build()); - for (ResourceMetrics resourceMetrics : metricRequest.getResourceMetricsList()) { - assertThat(resourceMetrics.getScopeMetricsList()) - .anySatisfy(ilm -> assertThat(ilm.getScope().getName()).isEqualTo("test")); - for (ScopeMetrics instrumentationLibraryMetrics : - resourceMetrics.getScopeMetricsList()) { - for (Metric metric : instrumentationLibraryMetrics.getMetricsList()) { - // SPI was loaded - // MetricExporterCustomizer filters metrics not named my-metric - assertThat(metric.getName()).isEqualTo("my-metric"); - // TestMeterProviderConfigurer configures a view that only passes on attribute - // named allowed - // configured-test - assertThat(getFirstDataPointLabels(metric)) - .contains( - KeyValue.newBuilder() - .setKey("allowed") - .setValue(AnyValue.newBuilder().setStringValue("bear").build()) - .build()); - } - } - } + assertThat(metricRequest.getResourceMetricsList()) + .satisfiesExactly( + resourceMetrics -> { + assertThat(resourceMetrics.getResource().getAttributesList()) + .contains( + KeyValue.newBuilder() + .setKey("service.name") + .setValue(AnyValue.newBuilder().setStringValue("test").build()) + .build(), + KeyValue.newBuilder() + .setKey("cat") + .setValue(AnyValue.newBuilder().setStringValue("meow").build()) + .build()); + assertThat(resourceMetrics.getScopeMetricsList()) + .anySatisfy( + scopeMetrics -> { + assertThat(scopeMetrics.getScope().getName()).isEqualTo("test"); + assertThat(scopeMetrics.getMetricsList()) + .satisfiesExactly( + metric -> { + // SPI was loaded + assertThat(metric.getName()).isEqualTo("my-metric"); + // TestMeterProviderConfigurer configures a view that + // only passes on attribute + // named allowed + // configured-test + assertThat(getFirstDataPointLabels(metric)) + .contains( + KeyValue.newBuilder() + .setKey("allowed") + .setValue( + AnyValue.newBuilder() + .setStringValue("bear") + .build()) + .build()); + }); + }) + // This verifies that AutoConfigureListener was invoked and the OTLP + // span / log exporters received the autoconfigured OpenTelemetrySdk + // instance + .anySatisfy( + scopeMetrics -> { + assertThat(scopeMetrics.getScope().getName()) + .isEqualTo("io.opentelemetry.exporters.otlp-grpc"); + assertThat(scopeMetrics.getMetricsList()) + .satisfiesExactlyInAnyOrder( + metric -> + assertThat(metric.getName()) + .isEqualTo("otlp.exporter.seen"), + metric -> + assertThat(metric.getName()) + .isEqualTo("otlp.exporter.exported")); + }); + }); }); await().untilAsserted(() -> assertThat(otlpLogsRequests).hasSize(1)); diff --git a/sdk-extensions/autoconfigure/src/testFullConfig/java/io/opentelemetry/sdk/autoconfigure/provider/MetricCustomizer.java b/sdk-extensions/autoconfigure/src/testFullConfig/java/io/opentelemetry/sdk/autoconfigure/provider/MetricCustomizer.java index 979071f23d8..d4a34a57d82 100644 --- a/sdk-extensions/autoconfigure/src/testFullConfig/java/io/opentelemetry/sdk/autoconfigure/provider/MetricCustomizer.java +++ b/sdk-extensions/autoconfigure/src/testFullConfig/java/io/opentelemetry/sdk/autoconfigure/provider/MetricCustomizer.java @@ -48,7 +48,13 @@ public CompletableResultCode export(Collection metrics) { // please configure the SdkMeterProvider with the appropriate view. Collection filtered = metrics.stream() - .filter(metricData -> metricData.getName().equals("my-metric")) + .filter( + metricData -> + metricData.getName().equals("my-metric") + || metricData + .getInstrumentationScopeInfo() + .getName() + .startsWith("io.opentelemetry.exporters")) .collect(Collectors.toList()); return delegate.export(filtered); } diff --git a/sdk-extensions/autoconfigure/src/testFullConfig/java/io/opentelemetry/sdk/autoconfigure/provider/TestConfigurableLogRecordExporterProvider.java b/sdk-extensions/autoconfigure/src/testFullConfig/java/io/opentelemetry/sdk/autoconfigure/provider/TestConfigurableLogRecordExporterProvider.java index c1e0f37cadf..2b94eda22ff 100644 --- a/sdk-extensions/autoconfigure/src/testFullConfig/java/io/opentelemetry/sdk/autoconfigure/provider/TestConfigurableLogRecordExporterProvider.java +++ b/sdk-extensions/autoconfigure/src/testFullConfig/java/io/opentelemetry/sdk/autoconfigure/provider/TestConfigurableLogRecordExporterProvider.java @@ -5,7 +5,9 @@ package io.opentelemetry.sdk.autoconfigure.provider; +import io.opentelemetry.sdk.OpenTelemetrySdk; import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties; +import io.opentelemetry.sdk.autoconfigure.spi.internal.AutoConfigureListener; import io.opentelemetry.sdk.autoconfigure.spi.logs.ConfigurableLogRecordExporterProvider; import io.opentelemetry.sdk.common.CompletableResultCode; import io.opentelemetry.sdk.logs.data.LogRecordData; @@ -13,7 +15,7 @@ import java.util.Collection; public class TestConfigurableLogRecordExporterProvider - implements ConfigurableLogRecordExporterProvider { + implements ConfigurableLogRecordExporterProvider, AutoConfigureListener { @Override public LogRecordExporter createExporter(ConfigProperties config) { @@ -25,6 +27,9 @@ public String getName() { return "testExporter"; } + @Override + public void afterAutoConfigure(OpenTelemetrySdk sdk) {} + public static class TestLogRecordExporter implements LogRecordExporter { private final ConfigProperties config; diff --git a/sdk-extensions/autoconfigure/src/testFullConfig/java/io/opentelemetry/sdk/autoconfigure/provider/TestConfigurableMetricExporterProvider.java b/sdk-extensions/autoconfigure/src/testFullConfig/java/io/opentelemetry/sdk/autoconfigure/provider/TestConfigurableMetricExporterProvider.java index 59eaf065573..49ed7986477 100644 --- a/sdk-extensions/autoconfigure/src/testFullConfig/java/io/opentelemetry/sdk/autoconfigure/provider/TestConfigurableMetricExporterProvider.java +++ b/sdk-extensions/autoconfigure/src/testFullConfig/java/io/opentelemetry/sdk/autoconfigure/provider/TestConfigurableMetricExporterProvider.java @@ -5,7 +5,9 @@ package io.opentelemetry.sdk.autoconfigure.provider; +import io.opentelemetry.sdk.OpenTelemetrySdk; import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties; +import io.opentelemetry.sdk.autoconfigure.spi.internal.AutoConfigureListener; import io.opentelemetry.sdk.autoconfigure.spi.metrics.ConfigurableMetricExporterProvider; import io.opentelemetry.sdk.common.CompletableResultCode; import io.opentelemetry.sdk.metrics.InstrumentType; @@ -14,7 +16,8 @@ import io.opentelemetry.sdk.metrics.export.MetricExporter; import java.util.Collection; -public class TestConfigurableMetricExporterProvider implements ConfigurableMetricExporterProvider { +public class TestConfigurableMetricExporterProvider + implements ConfigurableMetricExporterProvider, AutoConfigureListener { @Override public MetricExporter createExporter(ConfigProperties config) { @@ -26,6 +29,9 @@ public String getName() { return "testExporter"; } + @Override + public void afterAutoConfigure(OpenTelemetrySdk sdk) {} + public static class TestMetricExporter implements MetricExporter { private final ConfigProperties config; diff --git a/sdk-extensions/autoconfigure/src/testFullConfig/java/io/opentelemetry/sdk/autoconfigure/provider/TestConfigurableSpanExporterProvider.java b/sdk-extensions/autoconfigure/src/testFullConfig/java/io/opentelemetry/sdk/autoconfigure/provider/TestConfigurableSpanExporterProvider.java index 8f62bbddd23..a4c7fef26ab 100644 --- a/sdk-extensions/autoconfigure/src/testFullConfig/java/io/opentelemetry/sdk/autoconfigure/provider/TestConfigurableSpanExporterProvider.java +++ b/sdk-extensions/autoconfigure/src/testFullConfig/java/io/opentelemetry/sdk/autoconfigure/provider/TestConfigurableSpanExporterProvider.java @@ -5,14 +5,17 @@ package io.opentelemetry.sdk.autoconfigure.provider; +import io.opentelemetry.sdk.OpenTelemetrySdk; import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties; +import io.opentelemetry.sdk.autoconfigure.spi.internal.AutoConfigureListener; import io.opentelemetry.sdk.autoconfigure.spi.traces.ConfigurableSpanExporterProvider; import io.opentelemetry.sdk.common.CompletableResultCode; import io.opentelemetry.sdk.trace.data.SpanData; import io.opentelemetry.sdk.trace.export.SpanExporter; import java.util.Collection; -public class TestConfigurableSpanExporterProvider implements ConfigurableSpanExporterProvider { +public class TestConfigurableSpanExporterProvider + implements ConfigurableSpanExporterProvider, AutoConfigureListener { @Override public SpanExporter createExporter(ConfigProperties config) { return new TestSpanExporter(config); @@ -23,6 +26,9 @@ public String getName() { return "testExporter"; } + @Override + public void afterAutoConfigure(OpenTelemetrySdk sdk) {} + public static class TestSpanExporter implements SpanExporter { private final ConfigProperties config; From 59f3eb8eef3f348ef089d5dbdcb07374ddce9267 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 9 Nov 2023 09:19:24 -0600 Subject: [PATCH 084/901] Update dependency com.linecorp.armeria:armeria-bom to v1.26.2 (#5968) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- dependencyManagement/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index 6eb363f025f..115e29e2d6b 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -11,7 +11,7 @@ val DEPENDENCY_BOMS = listOf( "com.fasterxml.jackson:jackson-bom:2.15.3", "com.google.guava:guava-bom:32.1.3-jre", "com.google.protobuf:protobuf-bom:3.25.0", - "com.linecorp.armeria:armeria-bom:1.26.1", + "com.linecorp.armeria:armeria-bom:1.26.2", "com.squareup.okhttp3:okhttp-bom:4.12.0", "com.squareup.okio:okio-bom:3.6.0", // applies to transitive dependencies of okhttp "io.grpc:grpc-bom:1.59.0", From a9dfcd0cf055c4ea284fa401da34b9aba94256c0 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 9 Nov 2023 09:19:45 -0600 Subject: [PATCH 085/901] Update dependency com.tngtech.archunit:archunit-junit5 to v1.2.0 (#5963) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- dependencyManagement/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index 115e29e2d6b..05c0137265a 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -59,7 +59,7 @@ val DEPENDENCIES = listOf( "com.google.code.findbugs:jsr305:3.0.2", "com.google.guava:guava-beta-checker:1.0", "com.sun.net.httpserver:http:20070405", - "com.tngtech.archunit:archunit-junit5:1.1.0", + "com.tngtech.archunit:archunit-junit5:1.2.0", "com.uber.nullaway:nullaway:0.10.16", "edu.berkeley.cs.jqf:jqf-fuzz:1.7", // jqf-fuzz version 1.8+ requires Java 11+ "eu.rekawek.toxiproxy:toxiproxy-java:2.1.7", From efcce14ba98dd23b99b65b60c067e120f44ca79e Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 9 Nov 2023 09:20:15 -0600 Subject: [PATCH 086/901] Update dependency org.junit:junit-bom to v5.10.1 (#5962) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- dependencyManagement/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index 05c0137265a..c7a8aa61f5a 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -19,7 +19,7 @@ val DEPENDENCY_BOMS = listOf( "io.zipkin.brave:brave-bom:5.16.0", "io.zipkin.reporter2:zipkin-reporter-bom:2.16.4", "org.assertj:assertj-bom:3.24.2", - "org.junit:junit-bom:5.10.0", + "org.junit:junit-bom:5.10.1", "org.testcontainers:testcontainers-bom:1.19.1", "org.snakeyaml:snakeyaml-engine:2.7" ) From b03ec3aa62d8823e2eb3bcd19be6082d53e209b6 Mon Sep 17 00:00:00 2001 From: jack-berg <34418638+jack-berg@users.noreply.github.com> Date: Thu, 9 Nov 2023 10:03:36 -0600 Subject: [PATCH 087/901] Add log support to junit extensions (#5966) --- .../opentelemetry-sdk-testing.txt | 9 ++++- .../sdk/testing/junit4/OpenTelemetryRule.java | 39 ++++++++++++++++++- .../junit5/OpenTelemetryExtension.java | 39 ++++++++++++++++++- .../testing/junit4/OpenTelemetryRuleTest.java | 34 ++++++++++++++++ .../junit5/OpenTelemetryExtensionTest.java | 33 ++++++++++++++++ 5 files changed, 149 insertions(+), 5 deletions(-) diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-testing.txt b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-testing.txt index df26146497b..e8f3d45d4f7 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-testing.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-testing.txt @@ -1,2 +1,9 @@ Comparing source compatibility of against -No changes. \ No newline at end of file +*** MODIFIED CLASS: PUBLIC FINAL io.opentelemetry.sdk.testing.junit4.OpenTelemetryRule (not serializable) + === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 + +++ NEW METHOD: PUBLIC(+) void clearLogRecords() + +++ NEW METHOD: PUBLIC(+) java.util.List getLogRecords() +*** MODIFIED CLASS: PUBLIC FINAL io.opentelemetry.sdk.testing.junit5.OpenTelemetryExtension (not serializable) + === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 + +++ NEW METHOD: PUBLIC(+) void clearLogRecords() + +++ NEW METHOD: PUBLIC(+) java.util.List getLogRecords() diff --git a/sdk/testing/src/main/java/io/opentelemetry/sdk/testing/junit4/OpenTelemetryRule.java b/sdk/testing/src/main/java/io/opentelemetry/sdk/testing/junit4/OpenTelemetryRule.java index b0b15782a12..7cf3a873cba 100644 --- a/sdk/testing/src/main/java/io/opentelemetry/sdk/testing/junit4/OpenTelemetryRule.java +++ b/sdk/testing/src/main/java/io/opentelemetry/sdk/testing/junit4/OpenTelemetryRule.java @@ -10,10 +10,14 @@ import io.opentelemetry.api.trace.propagation.W3CTraceContextPropagator; import io.opentelemetry.context.propagation.ContextPropagators; import io.opentelemetry.sdk.OpenTelemetrySdk; +import io.opentelemetry.sdk.logs.SdkLoggerProvider; +import io.opentelemetry.sdk.logs.data.LogRecordData; +import io.opentelemetry.sdk.logs.export.SimpleLogRecordProcessor; import io.opentelemetry.sdk.metrics.SdkMeterProvider; import io.opentelemetry.sdk.metrics.data.AggregationTemporality; import io.opentelemetry.sdk.metrics.data.MetricData; import io.opentelemetry.sdk.metrics.internal.SdkMeterProviderUtil; +import io.opentelemetry.sdk.testing.exporter.InMemoryLogRecordExporter; import io.opentelemetry.sdk.testing.exporter.InMemoryMetricReader; import io.opentelemetry.sdk.testing.exporter.InMemorySpanExporter; import io.opentelemetry.sdk.trace.SdkTracerProvider; @@ -71,27 +75,38 @@ public static OpenTelemetryRule create() { SdkMeterProvider meterProvider = SdkMeterProvider.builder().registerMetricReader(metricReader).build(); + InMemoryLogRecordExporter logRecordExporter = InMemoryLogRecordExporter.create(); + + SdkLoggerProvider loggerProvider = + SdkLoggerProvider.builder() + .addLogRecordProcessor(SimpleLogRecordProcessor.create(logRecordExporter)) + .build(); + OpenTelemetrySdk openTelemetry = OpenTelemetrySdk.builder() .setPropagators(ContextPropagators.create(W3CTraceContextPropagator.getInstance())) .setTracerProvider(tracerProvider) .setMeterProvider(meterProvider) + .setLoggerProvider(loggerProvider) .build(); - return new OpenTelemetryRule(openTelemetry, spanExporter, metricReader); + return new OpenTelemetryRule(openTelemetry, spanExporter, metricReader, logRecordExporter); } private final OpenTelemetrySdk openTelemetry; private final InMemorySpanExporter spanExporter; private final InMemoryMetricReader metricReader; + private final InMemoryLogRecordExporter logRecordExporter; private OpenTelemetryRule( OpenTelemetrySdk openTelemetry, InMemorySpanExporter spanExporter, - InMemoryMetricReader metricReader) { + InMemoryMetricReader metricReader, + InMemoryLogRecordExporter logRecordExporter) { this.openTelemetry = openTelemetry; this.spanExporter = spanExporter; this.metricReader = metricReader; + this.logRecordExporter = logRecordExporter; } /** Returns the {@link OpenTelemetrySdk} created by this extension. */ @@ -113,6 +128,15 @@ public List getMetrics() { return new ArrayList<>(metricReader.collectAllMetrics()); } + /** + * Returns all the exported {@link LogRecordData} so far. + * + * @since 1.32.0 + */ + public List getLogRecords() { + return new ArrayList<>(logRecordExporter.getFinishedLogRecordItems()); + } + /** * Clears the collected exported {@link SpanData}. Consider making your test smaller instead of * manually clearing state using this method. @@ -130,12 +154,23 @@ public void clearMetrics() { SdkMeterProviderUtil.resetForTest(openTelemetry.getSdkMeterProvider()); } + /** + * Clears the collected exported {@link LogRecordData}. Consider making your test smaller instead + * of manually clearing state using this method. + * + * @since 1.32.0 + */ + public void clearLogRecords() { + logRecordExporter.reset(); + } + @Override protected void before() { GlobalOpenTelemetry.resetForTest(); GlobalOpenTelemetry.set(openTelemetry); clearSpans(); clearMetrics(); + clearLogRecords(); } @Override diff --git a/sdk/testing/src/main/java/io/opentelemetry/sdk/testing/junit5/OpenTelemetryExtension.java b/sdk/testing/src/main/java/io/opentelemetry/sdk/testing/junit5/OpenTelemetryExtension.java index 35ed9f4a637..3aedad968c7 100644 --- a/sdk/testing/src/main/java/io/opentelemetry/sdk/testing/junit5/OpenTelemetryExtension.java +++ b/sdk/testing/src/main/java/io/opentelemetry/sdk/testing/junit5/OpenTelemetryExtension.java @@ -12,11 +12,15 @@ import io.opentelemetry.api.trace.propagation.W3CTraceContextPropagator; import io.opentelemetry.context.propagation.ContextPropagators; import io.opentelemetry.sdk.OpenTelemetrySdk; +import io.opentelemetry.sdk.logs.SdkLoggerProvider; +import io.opentelemetry.sdk.logs.data.LogRecordData; +import io.opentelemetry.sdk.logs.export.SimpleLogRecordProcessor; import io.opentelemetry.sdk.metrics.SdkMeterProvider; import io.opentelemetry.sdk.metrics.data.AggregationTemporality; import io.opentelemetry.sdk.metrics.data.MetricData; import io.opentelemetry.sdk.metrics.internal.SdkMeterProviderUtil; import io.opentelemetry.sdk.testing.assertj.TracesAssert; +import io.opentelemetry.sdk.testing.exporter.InMemoryLogRecordExporter; import io.opentelemetry.sdk.testing.exporter.InMemoryMetricReader; import io.opentelemetry.sdk.testing.exporter.InMemorySpanExporter; import io.opentelemetry.sdk.trace.SdkTracerProvider; @@ -73,27 +77,38 @@ public static OpenTelemetryExtension create() { SdkMeterProvider meterProvider = SdkMeterProvider.builder().registerMetricReader(metricReader).build(); + InMemoryLogRecordExporter logRecordExporter = InMemoryLogRecordExporter.create(); + + SdkLoggerProvider loggerProvider = + SdkLoggerProvider.builder() + .addLogRecordProcessor(SimpleLogRecordProcessor.create(logRecordExporter)) + .build(); + OpenTelemetrySdk openTelemetry = OpenTelemetrySdk.builder() .setPropagators(ContextPropagators.create(W3CTraceContextPropagator.getInstance())) .setTracerProvider(tracerProvider) .setMeterProvider(meterProvider) + .setLoggerProvider(loggerProvider) .build(); - return new OpenTelemetryExtension(openTelemetry, spanExporter, metricReader); + return new OpenTelemetryExtension(openTelemetry, spanExporter, metricReader, logRecordExporter); } private final OpenTelemetrySdk openTelemetry; private final InMemorySpanExporter spanExporter; private final InMemoryMetricReader metricReader; + private final InMemoryLogRecordExporter logRecordExporter; private OpenTelemetryExtension( OpenTelemetrySdk openTelemetry, InMemorySpanExporter spanExporter, - InMemoryMetricReader metricReader) { + InMemoryMetricReader metricReader, + InMemoryLogRecordExporter logRecordExporter) { this.openTelemetry = openTelemetry; this.spanExporter = spanExporter; this.metricReader = metricReader; + this.logRecordExporter = logRecordExporter; } /** Returns the {@link OpenTelemetrySdk} created by this extension. */ @@ -115,6 +130,15 @@ public List getMetrics() { return new ArrayList<>(metricReader.collectAllMetrics()); } + /** + * Returns all the exported {@link LogRecordData} so far. + * + * @since 1.32.0 + */ + public List getLogRecords() { + return new ArrayList<>(logRecordExporter.getFinishedLogRecordItems()); + } + /** * Returns a {@link TracesAssert} for asserting on the currently exported traces. This method * requires AssertJ to be on the classpath. @@ -140,10 +164,21 @@ public void clearMetrics() { SdkMeterProviderUtil.resetForTest(openTelemetry.getSdkMeterProvider()); } + /** + * Clears the collected exported {@link LogRecordData}. Consider making your test smaller instead + * of manually clearing state using this method. + * + * @since 1.32.0 + */ + public void clearLogRecords() { + logRecordExporter.reset(); + } + @Override public void beforeEach(ExtensionContext context) { clearSpans(); clearMetrics(); + clearLogRecords(); } @Override diff --git a/sdk/testing/src/test/java/io/opentelemetry/sdk/testing/junit4/OpenTelemetryRuleTest.java b/sdk/testing/src/test/java/io/opentelemetry/sdk/testing/junit4/OpenTelemetryRuleTest.java index a9450c471fb..b8a14c5975d 100644 --- a/sdk/testing/src/test/java/io/opentelemetry/sdk/testing/junit4/OpenTelemetryRuleTest.java +++ b/sdk/testing/src/test/java/io/opentelemetry/sdk/testing/junit4/OpenTelemetryRuleTest.java @@ -7,6 +7,7 @@ import static org.assertj.core.api.Assertions.assertThat; +import io.opentelemetry.api.logs.Logger; import io.opentelemetry.api.metrics.LongCounter; import io.opentelemetry.api.metrics.Meter; import io.opentelemetry.api.trace.Tracer; @@ -21,11 +22,13 @@ public class OpenTelemetryRuleTest { private Tracer tracer; private Meter meter; + private Logger logger; @Before public void setup() { tracer = otelTesting.getOpenTelemetry().getTracer("test"); meter = otelTesting.getOpenTelemetry().getMeter("test"); + logger = otelTesting.getOpenTelemetry().getLogsBridge().get("test"); } @Test @@ -83,4 +86,35 @@ public void getMetricsAgain() { .hasLongSumSatisfying( sum -> sum.hasPointsSatisfying(point -> point.hasValue(1)))); } + + @Test + public void getLogRecords() { + logger.logRecordBuilder().setBody("body").emit(); + + assertThat(otelTesting.getLogRecords()) + .singleElement() + .satisfies( + logRecordData -> assertThat(logRecordData.getBody().asString()).isEqualTo("body")); + // Logs cleared between tests, not when retrieving + assertThat(otelTesting.getLogRecords()) + .singleElement() + .satisfies( + logRecordData -> assertThat(logRecordData.getBody().asString()).isEqualTo("body")); + } + + // We have two tests to verify logs get cleared up between tests. + @Test + public void getLogRecordsAgain() { + logger.logRecordBuilder().setBody("body").emit(); + + assertThat(otelTesting.getLogRecords()) + .singleElement() + .satisfies( + logRecordData -> assertThat(logRecordData.getBody().asString()).isEqualTo("body")); + // Logs cleared between tests, not when retrieving + assertThat(otelTesting.getLogRecords()) + .singleElement() + .satisfies( + logRecordData -> assertThat(logRecordData.getBody().asString()).isEqualTo("body")); + } } diff --git a/sdk/testing/src/test/java/io/opentelemetry/sdk/testing/junit5/OpenTelemetryExtensionTest.java b/sdk/testing/src/test/java/io/opentelemetry/sdk/testing/junit5/OpenTelemetryExtensionTest.java index 3f658bf0724..f2e7257b2bd 100644 --- a/sdk/testing/src/test/java/io/opentelemetry/sdk/testing/junit5/OpenTelemetryExtensionTest.java +++ b/sdk/testing/src/test/java/io/opentelemetry/sdk/testing/junit5/OpenTelemetryExtensionTest.java @@ -10,6 +10,7 @@ import io.opentelemetry.api.GlobalOpenTelemetry; import io.opentelemetry.api.OpenTelemetry; +import io.opentelemetry.api.logs.Logger; import io.opentelemetry.api.metrics.LongCounter; import io.opentelemetry.api.metrics.Meter; import io.opentelemetry.api.trace.Span; @@ -30,6 +31,7 @@ class OpenTelemetryExtensionTest { private final Tracer tracer = otelTesting.getOpenTelemetry().getTracer("test"); private final Meter meter = otelTesting.getOpenTelemetry().getMeter("test"); + private final Logger logger = otelTesting.getOpenTelemetry().getLogsBridge().get("test"); @Test public void getSpans() { @@ -175,6 +177,37 @@ void getMetricsAgain() { sum -> sum.hasPointsSatisfying(point -> point.hasValue(1)))); } + @Test + public void getLogRecords() { + logger.logRecordBuilder().setBody("body").emit(); + + assertThat(otelTesting.getLogRecords()) + .singleElement() + .satisfies( + logRecordData -> assertThat(logRecordData.getBody().asString()).isEqualTo("body")); + // Logs cleared between tests, not when retrieving + assertThat(otelTesting.getLogRecords()) + .singleElement() + .satisfies( + logRecordData -> assertThat(logRecordData.getBody().asString()).isEqualTo("body")); + } + + // We have two tests to verify spans get cleared up between tests. + @Test + public void getLogRecordsAgain() { + logger.logRecordBuilder().setBody("body").emit(); + + assertThat(otelTesting.getLogRecords()) + .singleElement() + .satisfies( + logRecordData -> assertThat(logRecordData.getBody().asString()).isEqualTo("body")); + // Logs cleared between tests, not when retrieving + assertThat(otelTesting.getLogRecords()) + .singleElement() + .satisfies( + logRecordData -> assertThat(logRecordData.getBody().asString()).isEqualTo("body")); + } + @Test void afterAll() { // Use a different instance of OpenTelemetryExtension to avoid interfering with other tests From 83993e03d342726bd67870752c96be9af3fd5cc3 Mon Sep 17 00:00:00 2001 From: jason plumb <75337021+breedx-splk@users.noreply.github.com> Date: Thu, 9 Nov 2023 13:58:58 -0800 Subject: [PATCH 088/901] Allow events to be emitted with timestamp (#5928) Co-authored-by: Jack Berg --- .../api/events/DefaultEventEmitter.java | 25 +++++++++++ .../api/events/EventBuilder.java | 32 ++++++++++++++ .../api/events/EventEmitter.java | 9 ++++ .../api/events/DefaultEventEmitterTest.java | 16 +++++++ .../sdk/logs/internal/SdkEventBuilder.java | 41 ++++++++++++++++++ .../internal/SdkEventEmitterProvider.java | 40 +++++++++++++----- .../logs/internal/SdkEventBuilderTest.java | 42 +++++++++++++++++++ .../internal/SdkEventEmitterProviderTest.java | 26 ++++++++++++ 8 files changed, 220 insertions(+), 11 deletions(-) create mode 100644 api/events/src/main/java/io/opentelemetry/api/events/EventBuilder.java create mode 100644 sdk/logs/src/main/java/io/opentelemetry/sdk/logs/internal/SdkEventBuilder.java create mode 100644 sdk/logs/src/test/java/io/opentelemetry/sdk/logs/internal/SdkEventBuilderTest.java diff --git a/api/events/src/main/java/io/opentelemetry/api/events/DefaultEventEmitter.java b/api/events/src/main/java/io/opentelemetry/api/events/DefaultEventEmitter.java index 2be4164d010..8d9a81f8e7f 100644 --- a/api/events/src/main/java/io/opentelemetry/api/events/DefaultEventEmitter.java +++ b/api/events/src/main/java/io/opentelemetry/api/events/DefaultEventEmitter.java @@ -6,6 +6,8 @@ package io.opentelemetry.api.events; import io.opentelemetry.api.common.Attributes; +import java.time.Instant; +import java.util.concurrent.TimeUnit; class DefaultEventEmitter implements EventEmitter { @@ -19,4 +21,27 @@ static EventEmitter getInstance() { @Override public void emit(String eventName, Attributes attributes) {} + + @Override + public EventBuilder builder(String eventName, Attributes attributes) { + return NoOpEventBuilder.INSTANCE; + } + + private static class NoOpEventBuilder implements EventBuilder { + + public static final EventBuilder INSTANCE = new NoOpEventBuilder(); + + @Override + public EventBuilder setTimestamp(long timestamp, TimeUnit unit) { + return this; + } + + @Override + public EventBuilder setTimestamp(Instant instant) { + return this; + } + + @Override + public void emit() {} + } } diff --git a/api/events/src/main/java/io/opentelemetry/api/events/EventBuilder.java b/api/events/src/main/java/io/opentelemetry/api/events/EventBuilder.java new file mode 100644 index 00000000000..a9acabbca6c --- /dev/null +++ b/api/events/src/main/java/io/opentelemetry/api/events/EventBuilder.java @@ -0,0 +1,32 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.api.events; + +import java.time.Instant; +import java.util.concurrent.TimeUnit; + +/** The EventBuilder is used to {@link #emit()} events. */ +public interface EventBuilder { + + /** + * Set the epoch {@code timestamp} for the event, using the timestamp and unit. + * + *

    The {@code timestamp} is the time at which the event occurred. If unset, it will be set to + * the current time when {@link #emit()} is called. + */ + EventBuilder setTimestamp(long timestamp, TimeUnit unit); + + /** + * Set the epoch {@code timestamp} for the event, using the instant. + * + *

    The {@code timestamp} is the time at which the event occurred. If unset, it will be set to + * the current time when {@link #emit()} is called. + */ + EventBuilder setTimestamp(Instant instant); + + /** Emit an event. */ + void emit(); +} diff --git a/api/events/src/main/java/io/opentelemetry/api/events/EventEmitter.java b/api/events/src/main/java/io/opentelemetry/api/events/EventEmitter.java index 69df8407f43..a8dc47c83d7 100644 --- a/api/events/src/main/java/io/opentelemetry/api/events/EventEmitter.java +++ b/api/events/src/main/java/io/opentelemetry/api/events/EventEmitter.java @@ -40,4 +40,13 @@ public interface EventEmitter { * @param attributes attributes associated with the event */ void emit(String eventName, Attributes attributes); + + /** + * Return a {@link EventBuilder} to emit an event. + * + * @param eventName the event name, which acts as a classifier for events. Within a particular + * event domain, event name defines a particular class or type of event. + * @param attributes attributes associated with the event + */ + EventBuilder builder(String eventName, Attributes attributes); } diff --git a/api/events/src/test/java/io/opentelemetry/api/events/DefaultEventEmitterTest.java b/api/events/src/test/java/io/opentelemetry/api/events/DefaultEventEmitterTest.java index fb6bcabfc91..460cb1583ac 100644 --- a/api/events/src/test/java/io/opentelemetry/api/events/DefaultEventEmitterTest.java +++ b/api/events/src/test/java/io/opentelemetry/api/events/DefaultEventEmitterTest.java @@ -8,6 +8,8 @@ import static org.assertj.core.api.Assertions.assertThatCode; import io.opentelemetry.api.common.Attributes; +import java.time.Instant; +import java.util.concurrent.TimeUnit; import org.junit.jupiter.api.Test; class DefaultEventEmitterTest { @@ -22,4 +24,18 @@ void emit() { .emit("event-name", Attributes.builder().put("key1", "value1").build())) .doesNotThrowAnyException(); } + + @Test + void builder() { + Attributes attributes = Attributes.builder().put("key1", "value1").build(); + EventEmitter emitter = DefaultEventEmitter.getInstance(); + assertThatCode( + () -> + emitter + .builder("myEvent", attributes) + .setTimestamp(123456L, TimeUnit.NANOSECONDS) + .setTimestamp(Instant.now()) + .emit()) + .doesNotThrowAnyException(); + } } diff --git a/sdk/logs/src/main/java/io/opentelemetry/sdk/logs/internal/SdkEventBuilder.java b/sdk/logs/src/main/java/io/opentelemetry/sdk/logs/internal/SdkEventBuilder.java new file mode 100644 index 00000000000..a79b09babc3 --- /dev/null +++ b/sdk/logs/src/main/java/io/opentelemetry/sdk/logs/internal/SdkEventBuilder.java @@ -0,0 +1,41 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.sdk.logs.internal; + +import io.opentelemetry.api.events.EventBuilder; +import io.opentelemetry.api.logs.LogRecordBuilder; +import java.time.Instant; +import java.util.concurrent.TimeUnit; + +class SdkEventBuilder implements EventBuilder { + private final LogRecordBuilder logRecordBuilder; + private final String eventDomain; + private final String eventName; + + SdkEventBuilder(LogRecordBuilder logRecordBuilder, String eventDomain, String eventName) { + this.logRecordBuilder = logRecordBuilder; + this.eventDomain = eventDomain; + this.eventName = eventName; + } + + @Override + public EventBuilder setTimestamp(long timestamp, TimeUnit unit) { + this.logRecordBuilder.setTimestamp(timestamp, unit); + return this; + } + + @Override + public EventBuilder setTimestamp(Instant instant) { + this.logRecordBuilder.setTimestamp(instant); + return this; + } + + @Override + public void emit() { + SdkEventEmitterProvider.addEventNameAndDomain(logRecordBuilder, eventDomain, eventName); + logRecordBuilder.emit(); + } +} diff --git a/sdk/logs/src/main/java/io/opentelemetry/sdk/logs/internal/SdkEventEmitterProvider.java b/sdk/logs/src/main/java/io/opentelemetry/sdk/logs/internal/SdkEventEmitterProvider.java index 18d1e434824..1cc6768667e 100644 --- a/sdk/logs/src/main/java/io/opentelemetry/sdk/logs/internal/SdkEventEmitterProvider.java +++ b/sdk/logs/src/main/java/io/opentelemetry/sdk/logs/internal/SdkEventEmitterProvider.java @@ -7,9 +7,11 @@ import io.opentelemetry.api.common.AttributeKey; import io.opentelemetry.api.common.Attributes; +import io.opentelemetry.api.events.EventBuilder; import io.opentelemetry.api.events.EventEmitter; import io.opentelemetry.api.events.EventEmitterBuilder; import io.opentelemetry.api.events.EventEmitterProvider; +import io.opentelemetry.api.logs.LogRecordBuilder; import io.opentelemetry.api.logs.Logger; import io.opentelemetry.api.logs.LoggerBuilder; import io.opentelemetry.api.logs.LoggerProvider; @@ -24,7 +26,10 @@ */ public final class SdkEventEmitterProvider implements EventEmitterProvider { - private static final String DEFAULT_EVENT_DOMAIN = "unknown"; + static final AttributeKey EVENT_DOMAIN = AttributeKey.stringKey("event.domain"); + static final AttributeKey EVENT_NAME = AttributeKey.stringKey("event.name"); + + static final String DEFAULT_EVENT_DOMAIN = "unknown"; private final LoggerProvider delegateLoggerProvider; private final Clock clock; @@ -98,9 +103,6 @@ public EventEmitter build() { private static class SdkEventEmitter implements EventEmitter { - private static final AttributeKey EVENT_DOMAIN = AttributeKey.stringKey("event.domain"); - private static final AttributeKey EVENT_NAME = AttributeKey.stringKey("event.name"); - private final Clock clock; private final Logger delegateLogger; private final String eventDomain; @@ -111,15 +113,31 @@ private SdkEventEmitter(Clock clock, Logger delegateLogger, String eventDomain) this.eventDomain = eventDomain; } + @Override + public EventBuilder builder(String eventName, Attributes attributes) { + return new SdkEventBuilder( + delegateLogger + .logRecordBuilder() + .setTimestamp(clock.now(), TimeUnit.NANOSECONDS) + .setAllAttributes(attributes), + eventDomain, + eventName); + } + @Override public void emit(String eventName, Attributes attributes) { - delegateLogger - .logRecordBuilder() - .setTimestamp(clock.now(), TimeUnit.NANOSECONDS) - .setAllAttributes(attributes) - .setAttribute(EVENT_DOMAIN, eventDomain) - .setAttribute(EVENT_NAME, eventName) - .emit(); + LogRecordBuilder logRecordBuilder = + delegateLogger + .logRecordBuilder() + .setTimestamp(clock.now(), TimeUnit.NANOSECONDS) + .setAllAttributes(attributes); + addEventNameAndDomain(logRecordBuilder, eventDomain, eventName); + logRecordBuilder.emit(); } } + + static void addEventNameAndDomain( + LogRecordBuilder logRecordBuilder, String eventDomain, String eventName) { + logRecordBuilder.setAttribute(EVENT_DOMAIN, eventDomain).setAttribute(EVENT_NAME, eventName); + } } diff --git a/sdk/logs/src/test/java/io/opentelemetry/sdk/logs/internal/SdkEventBuilderTest.java b/sdk/logs/src/test/java/io/opentelemetry/sdk/logs/internal/SdkEventBuilderTest.java new file mode 100644 index 00000000000..2115463a771 --- /dev/null +++ b/sdk/logs/src/test/java/io/opentelemetry/sdk/logs/internal/SdkEventBuilderTest.java @@ -0,0 +1,42 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.sdk.logs.internal; + +import static io.opentelemetry.api.common.AttributeKey.stringKey; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyLong; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import io.opentelemetry.api.logs.LogRecordBuilder; +import java.time.Instant; +import java.util.concurrent.TimeUnit; +import org.junit.jupiter.api.Test; + +class SdkEventBuilderTest { + + @Test + void emit() { + String eventDomain = "mydomain"; + String eventName = "banana"; + + LogRecordBuilder logRecordBuilder = mock(LogRecordBuilder.class); + when(logRecordBuilder.setTimestamp(anyLong(), any())).thenReturn(logRecordBuilder); + when(logRecordBuilder.setAttribute(any(), any())).thenReturn(logRecordBuilder); + + Instant instant = Instant.now(); + new SdkEventBuilder(logRecordBuilder, eventDomain, eventName) + .setTimestamp(123456L, TimeUnit.NANOSECONDS) + .setTimestamp(instant) + .emit(); + verify(logRecordBuilder).setAttribute(stringKey("event.domain"), eventDomain); + verify(logRecordBuilder).setAttribute(stringKey("event.name"), eventName); + verify(logRecordBuilder).setTimestamp(123456L, TimeUnit.NANOSECONDS); + verify(logRecordBuilder).setTimestamp(instant); + verify(logRecordBuilder).emit(); + } +} diff --git a/sdk/logs/src/test/java/io/opentelemetry/sdk/logs/internal/SdkEventEmitterProviderTest.java b/sdk/logs/src/test/java/io/opentelemetry/sdk/logs/internal/SdkEventEmitterProviderTest.java index 964c67e64c1..7f22b1376a8 100644 --- a/sdk/logs/src/test/java/io/opentelemetry/sdk/logs/internal/SdkEventEmitterProviderTest.java +++ b/sdk/logs/src/test/java/io/opentelemetry/sdk/logs/internal/SdkEventEmitterProviderTest.java @@ -5,16 +5,19 @@ package io.opentelemetry.sdk.logs.internal; +import static io.opentelemetry.api.common.AttributeKey.stringKey; import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.assertThat; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; import io.opentelemetry.api.common.Attributes; +import io.opentelemetry.api.events.EventEmitter; import io.opentelemetry.sdk.common.Clock; import io.opentelemetry.sdk.common.InstrumentationScopeInfo; import io.opentelemetry.sdk.logs.ReadWriteLogRecord; import io.opentelemetry.sdk.logs.SdkLoggerProvider; import io.opentelemetry.sdk.resources.Resource; +import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicReference; import org.junit.jupiter.api.Test; @@ -91,4 +94,27 @@ void emit_NoDomain() { .put("event.name", "event-name") .build()); } + + @Test + void builder() { + long yesterday = System.nanoTime() - TimeUnit.DAYS.toNanos(1); + Attributes attributes = Attributes.of(stringKey("foo"), "bar"); + + EventEmitter emitter = eventEmitterProvider.eventEmitterBuilder("test-scope").build(); + + emitter.builder("testing", attributes).setTimestamp(yesterday, TimeUnit.NANOSECONDS).emit(); + verifySeen(yesterday, attributes); + } + + private void verifySeen(long timestamp, Attributes attributes) { + assertThat(seenLog.get().toLogRecordData()) + .hasResource(RESOURCE) + .hasInstrumentationScope(InstrumentationScopeInfo.create("test-scope")) + .hasTimestamp(timestamp) + .hasAttributes( + attributes.toBuilder() + .put("event.domain", "unknown") + .put("event.name", "testing") + .build()); + } } From 04f6d9cc4600596de75e8dee12991d6cb5e49735 Mon Sep 17 00:00:00 2001 From: jack-berg <34418638+jack-berg@users.noreply.github.com> Date: Fri, 10 Nov 2023 09:00:56 -0600 Subject: [PATCH 089/901] Fix delta metric storage concurrency bug (#5932) --- .../io/opentelemetry/sdk/metrics/TestSdk.java | 15 +++- .../DefaultSynchronousMetricStorage.java | 55 ++++++++++-- .../state/SynchronousMetricStorageTest.java | 88 +++++++++++++++++++ 3 files changed, 149 insertions(+), 9 deletions(-) diff --git a/sdk/metrics/src/jmh/java/io/opentelemetry/sdk/metrics/TestSdk.java b/sdk/metrics/src/jmh/java/io/opentelemetry/sdk/metrics/TestSdk.java index 4f461d6fa63..1c8e760425d 100644 --- a/sdk/metrics/src/jmh/java/io/opentelemetry/sdk/metrics/TestSdk.java +++ b/sdk/metrics/src/jmh/java/io/opentelemetry/sdk/metrics/TestSdk.java @@ -38,7 +38,7 @@ Meter build() { .get("io.opentelemetry.sdk.metrics"); } }), - SDK( + SDK_CUMULATIVE( new SdkBuilder() { @Override Meter build() { @@ -50,6 +50,19 @@ Meter build() { .build() .get("io.opentelemetry.sdk.metrics"); } + }), + SDK_DELTA( + new SdkBuilder() { + @Override + Meter build() { + return SdkMeterProvider.builder() + .setClock(Clock.getDefault()) + .setResource(Resource.empty()) + // Must register reader for real SDK. + .registerMetricReader(InMemoryMetricReader.createDelta()) + .build() + .get("io.opentelemetry.sdk.metrics"); + } }); private final SdkBuilder sdkBuilder; diff --git a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/state/DefaultSynchronousMetricStorage.java b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/state/DefaultSynchronousMetricStorage.java index 3a359d75d23..0a837018483 100644 --- a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/state/DefaultSynchronousMetricStorage.java +++ b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/state/DefaultSynchronousMetricStorage.java @@ -26,6 +26,9 @@ import java.util.Queue; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentLinkedQueue; +import java.util.concurrent.locks.Lock; +import java.util.concurrent.locks.ReadWriteLock; +import java.util.concurrent.locks.ReentrantReadWriteLock; import java.util.logging.Level; import java.util.logging.Logger; @@ -46,8 +49,7 @@ public final class DefaultSynchronousMetricStorage aggregator; - private final ConcurrentHashMap> aggregatorHandles = - new ConcurrentHashMap<>(); + private volatile AggregatorHolder aggregatorHolder = new AggregatorHolder<>(); private final AttributesProcessor attributesProcessor; /** @@ -83,8 +85,15 @@ Queue> getAggregatorHandlePool() { @Override public void recordLong(long value, Attributes attributes, Context context) { - AggregatorHandle handle = getAggregatorHandle(attributes, context); - handle.recordLong(value, attributes, context); + Lock readLock = aggregatorHolder.lock.readLock(); + readLock.lock(); + try { + AggregatorHandle handle = + getAggregatorHandle(aggregatorHolder.aggregatorHandles, attributes, context); + handle.recordLong(value, attributes, context); + } finally { + readLock.unlock(); + } } @Override @@ -99,11 +108,21 @@ public void recordDouble(double value, Attributes attributes, Context context) { + ". Dropping measurement."); return; } - AggregatorHandle handle = getAggregatorHandle(attributes, context); - handle.recordDouble(value, attributes, context); + Lock readLock = aggregatorHolder.lock.readLock(); + readLock.lock(); + try { + AggregatorHandle handle = + getAggregatorHandle(aggregatorHolder.aggregatorHandles, attributes, context); + handle.recordDouble(value, attributes, context); + } finally { + readLock.unlock(); + } } - private AggregatorHandle getAggregatorHandle(Attributes attributes, Context context) { + private AggregatorHandle getAggregatorHandle( + ConcurrentHashMap> aggregatorHandles, + Attributes attributes, + Context context) { Objects.requireNonNull(attributes, "attributes"); attributes = attributesProcessor.process(attributes, context); AggregatorHandle handle = aggregatorHandles.get(attributes); @@ -146,13 +165,27 @@ public MetricData collect( ? registeredReader.getLastCollectEpochNanos() : startEpochNanos; + ConcurrentHashMap> aggregatorHandles; + if (reset) { + AggregatorHolder holder = this.aggregatorHolder; + this.aggregatorHolder = new AggregatorHolder<>(); + Lock writeLock = holder.lock.writeLock(); + writeLock.lock(); + try { + aggregatorHandles = holder.aggregatorHandles; + } finally { + writeLock.unlock(); + } + } else { + aggregatorHandles = this.aggregatorHolder.aggregatorHandles; + } + // Grab aggregated points. List points = new ArrayList<>(aggregatorHandles.size()); aggregatorHandles.forEach( (attributes, handle) -> { T point = handle.aggregateThenMaybeReset(start, epochNanos, attributes, reset); if (reset) { - aggregatorHandles.remove(attributes, handle); // Return the aggregator to the pool. aggregatorHandlePool.offer(handle); } @@ -180,4 +213,10 @@ public MetricData collect( public MetricDescriptor getMetricDescriptor() { return metricDescriptor; } + + private static class AggregatorHolder { + private final ConcurrentHashMap> aggregatorHandles = + new ConcurrentHashMap<>(); + private final ReadWriteLock lock = new ReentrantReadWriteLock(); + } } diff --git a/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/internal/state/SynchronousMetricStorageTest.java b/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/internal/state/SynchronousMetricStorageTest.java index aa6fe1d3999..2d301eb6d88 100644 --- a/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/internal/state/SynchronousMetricStorageTest.java +++ b/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/internal/state/SynchronousMetricStorageTest.java @@ -12,6 +12,8 @@ import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; +import com.google.common.util.concurrent.AtomicDouble; +import com.google.common.util.concurrent.Uninterruptibles; import io.github.netmikey.logunit.api.LogCapturer; import io.opentelemetry.api.common.AttributeKey; import io.opentelemetry.api.common.Attributes; @@ -21,9 +23,11 @@ import io.opentelemetry.sdk.metrics.Aggregation; import io.opentelemetry.sdk.metrics.InstrumentType; import io.opentelemetry.sdk.metrics.InstrumentValueType; +import io.opentelemetry.sdk.metrics.data.ExemplarData; import io.opentelemetry.sdk.metrics.data.LongExemplarData; import io.opentelemetry.sdk.metrics.data.LongPointData; import io.opentelemetry.sdk.metrics.data.MetricData; +import io.opentelemetry.sdk.metrics.data.PointData; import io.opentelemetry.sdk.metrics.internal.aggregator.Aggregator; import io.opentelemetry.sdk.metrics.internal.aggregator.AggregatorFactory; import io.opentelemetry.sdk.metrics.internal.aggregator.EmptyMetricData; @@ -37,8 +41,17 @@ import io.opentelemetry.sdk.resources.Resource; import io.opentelemetry.sdk.testing.exporter.InMemoryMetricReader; import io.opentelemetry.sdk.testing.time.TestClock; +import java.time.Duration; +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.CountDownLatch; +import java.util.function.BiConsumer; +import java.util.stream.Stream; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.RegisterExtension; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; import org.slf4j.event.Level; @SuppressLogger(DefaultSynchronousMetricStorage.class) @@ -370,4 +383,79 @@ void recordAndCollect_DeltaAtLimit() { assertThat(storage.getAggregatorHandlePool()).hasSize(CARDINALITY_LIMIT); logs.assertContains("Instrument name has exceeded the maximum allowed cardinality"); } + + @ParameterizedTest + @MethodSource("concurrentStressTestArguments") + void recordAndCollect_concurrentStressTest( + DefaultSynchronousMetricStorage storage, BiConsumer collect) { + // Define record threads. Each records a value of 1.0, 2000 times + List threads = new ArrayList<>(); + CountDownLatch latch = new CountDownLatch(4); + for (int i = 0; i < 4; i++) { + Thread thread = + new Thread( + () -> { + for (int j = 0; j < 2000; j++) { + storage.recordDouble(1.0, Attributes.empty(), Context.current()); + Uninterruptibles.sleepUninterruptibly(Duration.ofMillis(1)); + } + latch.countDown(); + }); + threads.add(thread); + } + + // Define collect thread. Collect thread collects and aggregates the + AtomicDouble cumulativeSum = new AtomicDouble(); + Thread collectThread = + new Thread( + () -> { + do { + Uninterruptibles.sleepUninterruptibly(Duration.ofMillis(1)); + MetricData metricData = + storage.collect(Resource.empty(), InstrumentationScopeInfo.empty(), 0, 1); + if (metricData.isEmpty()) { + continue; + } + metricData.getDoubleSumData().getPoints().stream() + .findFirst() + .ifPresent(pointData -> collect.accept(pointData.getValue(), cumulativeSum)); + } while (latch.getCount() != 0); + }); + + // Start all the threads + collectThread.start(); + threads.forEach(Thread::start); + + // Wait for the collect thread to end, which collects until the record threads are done + Uninterruptibles.joinUninterruptibly(collectThread); + + assertThat(cumulativeSum.get()).isEqualTo(8000.0); + } + + private static Stream concurrentStressTestArguments() { + Aggregator aggregator = + ((AggregatorFactory) Aggregation.sum()) + .createAggregator(DESCRIPTOR, ExemplarFilter.alwaysOff()); + return Stream.of( + Arguments.of( + // Delta + new DefaultSynchronousMetricStorage<>( + RegisteredReader.create(InMemoryMetricReader.createDelta(), ViewRegistry.create()), + METRIC_DESCRIPTOR, + aggregator, + AttributesProcessor.noop(), + CARDINALITY_LIMIT), + (BiConsumer) + (value, cumulativeCount) -> cumulativeCount.addAndGet(value)), + Arguments.of( + // Cumulative + new DefaultSynchronousMetricStorage<>( + RegisteredReader.create(InMemoryMetricReader.create(), ViewRegistry.create()), + METRIC_DESCRIPTOR, + aggregator, + AttributesProcessor.noop(), + CARDINALITY_LIMIT), + (BiConsumer) + (value, cumulativeCount) -> cumulativeCount.set(value))); + } } From f44d99108d3c3c0b692f31a30d96cb98eb8e8b69 Mon Sep 17 00:00:00 2001 From: jack-berg <34418638+jack-berg@users.noreply.github.com> Date: Fri, 10 Nov 2023 09:30:03 -0600 Subject: [PATCH 090/901] Expand the set of retryable exceptions in JdkHttpSender (#5942) --- .../sender/jdk/internal/JdkHttpSender.java | 10 ++++++++-- .../sender/jdk/internal/JdkHttpSenderTest.java | 14 +++++++++++++- 2 files changed, 21 insertions(+), 3 deletions(-) diff --git a/exporters/sender/jdk/src/main/java/io/opentelemetry/exporter/sender/jdk/internal/JdkHttpSender.java b/exporters/sender/jdk/src/main/java/io/opentelemetry/exporter/sender/jdk/internal/JdkHttpSender.java index fda90c6a8c7..25866a162fc 100644 --- a/exporters/sender/jdk/src/main/java/io/opentelemetry/exporter/sender/jdk/internal/JdkHttpSender.java +++ b/exporters/sender/jdk/src/main/java/io/opentelemetry/exporter/sender/jdk/internal/JdkHttpSender.java @@ -16,7 +16,6 @@ import java.net.http.HttpClient; import java.net.http.HttpRequest; import java.net.http.HttpResponse; -import java.net.http.HttpTimeoutException; import java.nio.ByteBuffer; import java.time.Duration; import java.util.Map; @@ -32,6 +31,7 @@ import java.util.zip.GZIPOutputStream; import javax.annotation.Nullable; import javax.net.ssl.SSLContext; +import javax.net.ssl.SSLException; /** * {@link HttpSender} which is backed by JDK {@link HttpClient}. @@ -221,7 +221,13 @@ private HttpResponse sendRequest( } private static boolean isRetryableException(IOException throwable) { - return throwable instanceof HttpTimeoutException; + // Almost all IOExceptions we've encountered are transient retryable, so we opt out of specific + // IOExceptions that are unlikely to resolve rather than opting in. + // Known retryable IOException messages: "Connection reset", "/{remote ip}:{remote port} GOAWAY + // received" + // Known retryable HttpTimeoutException messages: "request timed out" + // Known retryable HttpConnectTimeoutException messages: "HTTP connect timed out" + return !(throwable instanceof SSLException); } private static class NoCopyByteArrayOutputStream extends ByteArrayOutputStream { diff --git a/exporters/sender/jdk/src/test/java/io/opentelemetry/exporter/sender/jdk/internal/JdkHttpSenderTest.java b/exporters/sender/jdk/src/test/java/io/opentelemetry/exporter/sender/jdk/internal/JdkHttpSenderTest.java index 2691bb1ca3f..19cb3f997ac 100644 --- a/exporters/sender/jdk/src/test/java/io/opentelemetry/exporter/sender/jdk/internal/JdkHttpSenderTest.java +++ b/exporters/sender/jdk/src/test/java/io/opentelemetry/exporter/sender/jdk/internal/JdkHttpSenderTest.java @@ -20,6 +20,7 @@ import java.net.http.HttpConnectTimeoutException; import java.time.Duration; import java.util.Collections; +import javax.net.ssl.SSLException; import org.assertj.core.api.InstanceOfAssertFactories; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -69,9 +70,20 @@ void sendInternal_RetryableConnectTimeoutException() throws IOException, Interru verify(mockHttpClient, times(2)).send(any(), any()); } + @Test + void sendInternal_RetryableIoException() throws IOException, InterruptedException { + doThrow(new IOException("error!")).when(mockHttpClient).send(any(), any()); + + assertThatThrownBy(() -> sender.sendInternal(marshaler -> {})) + .isInstanceOf(IOException.class) + .hasMessage("error!"); + + verify(mockHttpClient, times(2)).send(any(), any()); + } + @Test void sendInternal_NonRetryableException() throws IOException, InterruptedException { - doThrow(new IOException("unknown error")).when(mockHttpClient).send(any(), any()); + doThrow(new SSLException("unknown error")).when(mockHttpClient).send(any(), any()); assertThatThrownBy(() -> sender.sendInternal(marshaler -> {})) .isInstanceOf(IOException.class) From aca4157d8f2cc39f5b120975c5e352e82284b2e5 Mon Sep 17 00:00:00 2001 From: jack-berg <34418638+jack-berg@users.noreply.github.com> Date: Fri, 10 Nov 2023 11:55:58 -0600 Subject: [PATCH 091/901] Stop publishing announcement on release (#5971) --- .github/workflows/release.yml | 1 - README.md | 3 +++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 2b9b785a277..ba4f236c4c1 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -120,7 +120,6 @@ jobs: gh release create --target $GITHUB_REF_NAME \ --title "Version $VERSION" \ --notes-file /tmp/release-notes.txt \ - --discussion-category announcements \ v$VERSION echo "version=$VERSION" >> $GITHUB_OUTPUT diff --git a/README.md b/README.md index 7a1efa3374f..4359cb50d0c 100644 --- a/README.md +++ b/README.md @@ -36,6 +36,9 @@ for support or general questions. Feel free to drop us a line. We are also present in the [`#otel-java`](https://cloud-native.slack.com/archives/C014L2KCTE3) channel in the [CNCF slack](https://slack.cncf.io/). Please join us for more informal discussions. +To report a bug, or request a new feature, +please [open an issue](https://github.com/open-telemetry/opentelemetry-java/issues/new/choose). + ## Overview OpenTelemetry is the merging of OpenCensus and OpenTracing into a single project. From 72a5bb151bd18e86defacd1588f98ac9d26b9975 Mon Sep 17 00:00:00 2001 From: jack-berg <34418638+jack-berg@users.noreply.github.com> Date: Mon, 13 Nov 2023 09:43:27 -0600 Subject: [PATCH 092/901] CAS and voltile approach to fix delta concurrency bug (#5976) --- .../DefaultSynchronousMetricStorage.java | 74 +++++++++++++++---- .../state/SynchronousMetricStorageTest.java | 11 ++- 2 files changed, 67 insertions(+), 18 deletions(-) diff --git a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/state/DefaultSynchronousMetricStorage.java b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/state/DefaultSynchronousMetricStorage.java index 0a837018483..cf31f90cb24 100644 --- a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/state/DefaultSynchronousMetricStorage.java +++ b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/state/DefaultSynchronousMetricStorage.java @@ -26,9 +26,7 @@ import java.util.Queue; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentLinkedQueue; -import java.util.concurrent.locks.Lock; -import java.util.concurrent.locks.ReadWriteLock; -import java.util.concurrent.locks.ReentrantReadWriteLock; +import java.util.concurrent.atomic.AtomicInteger; import java.util.logging.Level; import java.util.logging.Logger; @@ -85,14 +83,13 @@ Queue> getAggregatorHandlePool() { @Override public void recordLong(long value, Attributes attributes, Context context) { - Lock readLock = aggregatorHolder.lock.readLock(); - readLock.lock(); + AggregatorHolder aggregatorHolder = getHolderForRecord(); try { AggregatorHandle handle = getAggregatorHandle(aggregatorHolder.aggregatorHandles, attributes, context); handle.recordLong(value, attributes, context); } finally { - readLock.unlock(); + releaseHolderForRecord(aggregatorHolder); } } @@ -108,17 +105,46 @@ public void recordDouble(double value, Attributes attributes, Context context) { + ". Dropping measurement."); return; } - Lock readLock = aggregatorHolder.lock.readLock(); - readLock.lock(); + AggregatorHolder aggregatorHolder = getHolderForRecord(); try { AggregatorHandle handle = getAggregatorHandle(aggregatorHolder.aggregatorHandles, attributes, context); handle.recordDouble(value, attributes, context); } finally { - readLock.unlock(); + releaseHolderForRecord(aggregatorHolder); } } + /** + * Obtain the AggregatorHolder for recording measurements, re-reading the volatile + * this.aggregatorHolder until we access one where recordsInProgress is even. Collect sets + * recordsInProgress to odd as a signal that AggregatorHolder is stale and is being replaced. + * Record operations increment recordInProgress by 2. Callers MUST call {@link + * #releaseHolderForRecord(AggregatorHolder)} when record operation completes to signal to that + * its safe to proceed with Collect operations. + */ + private AggregatorHolder getHolderForRecord() { + do { + AggregatorHolder aggregatorHolder = this.aggregatorHolder; + int recordsInProgress = aggregatorHolder.activeRecordingThreads.addAndGet(2); + if (recordsInProgress % 2 == 0) { + return aggregatorHolder; + } else { + // Collect is in progress, decrement recordsInProgress to allow collect to proceed and + // re-read aggregatorHolder + aggregatorHolder.activeRecordingThreads.addAndGet(-2); + } + } while (true); + } + + /** + * Called on the {@link AggregatorHolder} obtained from {@link #getHolderForRecord()} to indicate + * that recording is complete and it is safe to collect. + */ + private void releaseHolderForRecord(AggregatorHolder aggregatorHolder) { + aggregatorHolder.activeRecordingThreads.addAndGet(-2); + } + private AggregatorHandle getAggregatorHandle( ConcurrentHashMap> aggregatorHandles, Attributes attributes, @@ -169,13 +195,15 @@ public MetricData collect( if (reset) { AggregatorHolder holder = this.aggregatorHolder; this.aggregatorHolder = new AggregatorHolder<>(); - Lock writeLock = holder.lock.writeLock(); - writeLock.lock(); - try { - aggregatorHandles = holder.aggregatorHandles; - } finally { - writeLock.unlock(); + // Increment recordsInProgress by 1, which produces an odd number acting as a signal that + // record operations should re-read the volatile this.aggregatorHolder. + // Repeatedly grab recordsInProgress until it is <= 1, which signals all active record + // operations are complete. + int recordsInProgress = holder.activeRecordingThreads.addAndGet(1); + while (recordsInProgress > 1) { + recordsInProgress = holder.activeRecordingThreads.get(); } + aggregatorHandles = holder.aggregatorHandles; } else { aggregatorHandles = this.aggregatorHolder.aggregatorHandles; } @@ -217,6 +245,20 @@ public MetricDescriptor getMetricDescriptor() { private static class AggregatorHolder { private final ConcurrentHashMap> aggregatorHandles = new ConcurrentHashMap<>(); - private final ReadWriteLock lock = new ReentrantReadWriteLock(); + // Recording threads grab the current interval (AggregatorHolder) and atomically increment + // this by 2 before recording against it (and then decrement by two when done). + // + // The collection thread grabs the current interval (AggregatorHolder) and atomically + // increments this by 1 to "lock" this interval (and then waits for any active recording + // threads to complete before collecting it). + // + // Recording threads check the return value of their atomic increment, and if it's odd + // that means the collector thread has "locked" this interval for collection. + // + // But before the collector "locks" the interval it sets up a new current interval + // (AggregatorHolder), and so if a recording thread encounters an odd value, + // all it needs to do is release the "read lock" it just obtained (decrementing by 2), + // and then grab and record against the new current interval (AggregatorHolder). + private final AtomicInteger activeRecordingThreads = new AtomicInteger(0); } } diff --git a/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/internal/state/SynchronousMetricStorageTest.java b/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/internal/state/SynchronousMetricStorageTest.java index 2d301eb6d88..cbaa2aa303b 100644 --- a/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/internal/state/SynchronousMetricStorageTest.java +++ b/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/internal/state/SynchronousMetricStorageTest.java @@ -409,7 +409,11 @@ void recordAndCollect_concurrentStressTest( Thread collectThread = new Thread( () -> { - do { + int extraCollects = 0; + // If we terminate when latch.count() == 0, the last collect may have occurred before + // the last recorded measurement. To ensure we collect all measurements, we collect + // one extra time after latch.count() == 0. + while (latch.getCount() != 0 && extraCollects <= 1) { Uninterruptibles.sleepUninterruptibly(Duration.ofMillis(1)); MetricData metricData = storage.collect(Resource.empty(), InstrumentationScopeInfo.empty(), 0, 1); @@ -419,7 +423,10 @@ void recordAndCollect_concurrentStressTest( metricData.getDoubleSumData().getPoints().stream() .findFirst() .ifPresent(pointData -> collect.accept(pointData.getValue(), cumulativeSum)); - } while (latch.getCount() != 0); + if (latch.getCount() == 0) { + extraCollects++; + } + } }); // Start all the threads From ab4379da25d1264114e5a278c3b1c7fce3220b2a Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 13 Nov 2023 11:33:49 -0600 Subject: [PATCH 093/901] Update dependency com.squareup.wire:wire-bom to v4.9.2 (#5978) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- buildSrc/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts index f5385ed9008..d603d71b69b 100644 --- a/buildSrc/build.gradle.kts +++ b/buildSrc/build.gradle.kts @@ -42,7 +42,7 @@ repositories { } dependencies { - implementation(enforcedPlatform("com.squareup.wire:wire-bom:4.9.1")) + implementation(enforcedPlatform("com.squareup.wire:wire-bom:4.9.2")) implementation("com.google.auto.value:auto-value-annotations:1.10.4") // When updating, update above in plugins too implementation("com.diffplug.spotless:spotless-plugin-gradle:6.22.0") From cc5b70c737a96dc71b4984817deb3a1b390884b8 Mon Sep 17 00:00:00 2001 From: jack-berg <34418638+jack-berg@users.noreply.github.com> Date: Mon, 13 Nov 2023 11:34:01 -0600 Subject: [PATCH 094/901] Prepare 1.32.0 (#5977) Co-authored-by: Trask Stalnaker --- CHANGELOG.md | 70 +++++++++++++++++++ .../OtlpHttpLogRecordExporterBuilder.java | 2 + .../trace/OtlpHttpSpanExporterBuilder.java | 2 + .../OtlpGrpcLogRecordExporterBuilder.java | 2 + .../trace/OtlpGrpcSpanExporterBuilder.java | 2 + 5 files changed, 78 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5d9004b6e62..729b0687ad8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,76 @@ ## Unreleased +### API + +* Stabilize explicit bucket boundaries advice API + ([#5897](https://github.com/open-telemetry/opentelemetry-java/pull/5897)) +* Allow events to be emitted with timestamp + ([#5928](https://github.com/open-telemetry/opentelemetry-java/pull/5928)) + +#### Context + +* Add null check to StrictContextStorage + ([#5954](https://github.com/open-telemetry/opentelemetry-java/pull/5954)) + +#### Incubator + +* Experimental support for Log AnyValue body + ([#5880](https://github.com/open-telemetry/opentelemetry-java/pull/5880)) + +### SDK + +#### Metrics + +* Dismantle AbstractInstrumentBuilder inheritance hierarchy + ([#5820](https://github.com/open-telemetry/opentelemetry-java/pull/5820)) +* Fix delta metric storage concurrency bug that allows for lost writes when record operations occur + during collection. The fix introduces additional work on record threads to ensure correctness. The + additional overhead is non-blocking and should be small according to performance testing. Still, + there may be an opportunity for further optimization. + ([#5932](https://github.com/open-telemetry/opentelemetry-java/pull/5932), + [#5976](https://github.com/open-telemetry/opentelemetry-java/pull/5976)) + + +#### Exporters + +* Prometheus exporter: omit empty otel_scope_info and otel_target_info metrics + ([#5887](https://github.com/open-telemetry/opentelemetry-java/pull/5887)) +* JdkHttpSender should retry on connect exceptions + ([#5867](https://github.com/open-telemetry/opentelemetry-java/pull/5867)) +* Expand the set of retryable exceptions in JdkHttpSender + ([#5942](https://github.com/open-telemetry/opentelemetry-java/pull/5942)) +* Identify OTLP export calls with context key used for instrumentation suppression + ([#5918](https://github.com/open-telemetry/opentelemetry-java/pull/5918)) + +#### Testing + +* Add log support to junit extensions + ([#5966](https://github.com/open-telemetry/opentelemetry-java/pull/5966)) + +#### SDK Extensions + +* Add file configuration to autoconfigure + ([#5831](https://github.com/open-telemetry/opentelemetry-java/pull/5831)) +* Update to file configuration to use opentelemetry-configuration v0.1.0 + ([#5899](https://github.com/open-telemetry/opentelemetry-java/pull/5899)) +* Add env var substitution support to file configuration + ([#5914](https://github.com/open-telemetry/opentelemetry-java/pull/5914)) +* Stop setting Resource schemaUrl in autoconfigure + ([#5911](https://github.com/open-telemetry/opentelemetry-java/pull/5911)) +* Add AutoConfigureListener to provide components with autoconfigured SDK + ([#5931](https://github.com/open-telemetry/opentelemetry-java/pull/5931)) + +### OpenCensus Shim + +* Clean up OpenCensus shim + ([#5858](https://github.com/open-telemetry/opentelemetry-java/pull/5858)) + +### OpenTracing Shim + +* Fix OpenTracing header name issue + ([#5840](https://github.com/open-telemetry/opentelemetry-java/pull/5840)) + ## Version 1.31.0 (2023-10-06) ### API diff --git a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/logs/OtlpHttpLogRecordExporterBuilder.java b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/logs/OtlpHttpLogRecordExporterBuilder.java index 0a9c9733917..024d6b8b10e 100644 --- a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/logs/OtlpHttpLogRecordExporterBuilder.java +++ b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/logs/OtlpHttpLogRecordExporterBuilder.java @@ -143,6 +143,8 @@ public OtlpHttpLogRecordExporterBuilder setMeterProvider(MeterProvider meterProv /** * Sets the {@link MeterProvider} supplier used to collect metrics related to export. If not set, * uses {@link GlobalOpenTelemetry#getMeterProvider()}. + * + * @since 1.32.0 */ public OtlpHttpLogRecordExporterBuilder setMeterProvider( Supplier meterProviderSupplier) { diff --git a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/trace/OtlpHttpSpanExporterBuilder.java b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/trace/OtlpHttpSpanExporterBuilder.java index 890ec87ace7..91645cafba5 100644 --- a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/trace/OtlpHttpSpanExporterBuilder.java +++ b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/trace/OtlpHttpSpanExporterBuilder.java @@ -144,6 +144,8 @@ public OtlpHttpSpanExporterBuilder setMeterProvider(MeterProvider meterProvider) /** * Sets the {@link MeterProvider} supplier to use to collect metrics related to export. If not * set, uses {@link GlobalOpenTelemetry#getMeterProvider()}. + * + * @since 1.32.0 */ public OtlpHttpSpanExporterBuilder setMeterProvider( Supplier meterProviderSupplier) { diff --git a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/logs/OtlpGrpcLogRecordExporterBuilder.java b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/logs/OtlpGrpcLogRecordExporterBuilder.java index c825f93d023..cbdf26886c1 100644 --- a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/logs/OtlpGrpcLogRecordExporterBuilder.java +++ b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/logs/OtlpGrpcLogRecordExporterBuilder.java @@ -187,6 +187,8 @@ public OtlpGrpcLogRecordExporterBuilder setMeterProvider(MeterProvider meterProv /** * Sets the {@link MeterProvider} supplier used to collect metrics related to export. If not set, * uses {@link GlobalOpenTelemetry#getMeterProvider()}. + * + * @since 1.32.0 */ public OtlpGrpcLogRecordExporterBuilder setMeterProvider( Supplier meterProviderSupplier) { diff --git a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/trace/OtlpGrpcSpanExporterBuilder.java b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/trace/OtlpGrpcSpanExporterBuilder.java index 9aa119c2f1f..77e0f3ae01a 100644 --- a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/trace/OtlpGrpcSpanExporterBuilder.java +++ b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/trace/OtlpGrpcSpanExporterBuilder.java @@ -184,6 +184,8 @@ public OtlpGrpcSpanExporterBuilder setMeterProvider(MeterProvider meterProvider) /** * Sets the {@link MeterProvider} supplier used to collect metrics related to export. If not set, * uses {@link GlobalOpenTelemetry#getMeterProvider()}. + * + * @since 1.32.0 */ public OtlpGrpcSpanExporterBuilder setMeterProvider( Supplier meterProviderSupplier) { From 320a4d32d83b417d3801380a54285ad9ad01c838 Mon Sep 17 00:00:00 2001 From: OpenTelemetry Bot <107717825+opentelemetrybot@users.noreply.github.com> Date: Mon, 13 Nov 2023 15:04:20 -0300 Subject: [PATCH 095/901] Update version to 1.33.0 (#5979) --- CHANGELOG.md | 2 ++ version.gradle.kts | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 729b0687ad8..c0039e5f114 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,8 @@ ## Unreleased +## Version 1.32.0 (2023-11-13) + ### API * Stabilize explicit bucket boundaries advice API diff --git a/version.gradle.kts b/version.gradle.kts index 6778cc99912..3c385255433 100644 --- a/version.gradle.kts +++ b/version.gradle.kts @@ -1,7 +1,7 @@ val snapshot = true allprojects { - var ver = "1.32.0" + var ver = "1.33.0" val release = findProperty("otel.release") if (release != null) { ver += "-" + release From 89014162077706c649c061ace9f53f4158e26107 Mon Sep 17 00:00:00 2001 From: jack-berg <34418638+jack-berg@users.noreply.github.com> Date: Mon, 13 Nov 2023 17:29:11 -0600 Subject: [PATCH 096/901] Post release 1.32.0 (#5982) --- README.md | 76 +++++++++---------- .../1.32.0_vs_1.31.0/opentelemetry-api.txt | 7 ++ .../opentelemetry-context.txt | 2 + .../opentelemetry-exporter-common.txt | 2 + .../opentelemetry-exporter-jaeger-thrift.txt | 2 + .../opentelemetry-exporter-jaeger.txt | 2 + .../opentelemetry-exporter-logging-otlp.txt | 2 + .../opentelemetry-exporter-logging.txt | 2 + .../opentelemetry-exporter-otlp-common.txt | 2 + .../opentelemetry-exporter-otlp.txt | 13 ++++ ...y-exporter-sender-grpc-managed-channel.txt | 2 + .../opentelemetry-exporter-sender-okhttp.txt | 2 + .../opentelemetry-exporter-zipkin.txt | 2 + .../opentelemetry-extension-kotlin.txt | 2 + ...ntelemetry-extension-trace-propagators.txt | 2 + .../opentelemetry-opentracing-shim.txt | 2 + .../opentelemetry-sdk-common.txt | 2 + ...emetry-sdk-extension-autoconfigure-spi.txt | 2 + ...ntelemetry-sdk-extension-autoconfigure.txt | 2 + ...ry-sdk-extension-jaeger-remote-sampler.txt | 2 + .../opentelemetry-sdk-logs.txt | 2 + .../opentelemetry-sdk-metrics.txt | 2 + .../opentelemetry-sdk-testing.txt | 9 +++ .../opentelemetry-sdk-trace.txt | 2 + .../1.32.0_vs_1.31.0/opentelemetry-sdk.txt | 2 + .../current_vs_latest/opentelemetry-api.txt | 7 +- .../opentelemetry-exporter-otlp.txt | 13 +--- .../opentelemetry-sdk-testing.txt | 9 +-- 28 files changed, 112 insertions(+), 64 deletions(-) create mode 100644 docs/apidiffs/1.32.0_vs_1.31.0/opentelemetry-api.txt create mode 100644 docs/apidiffs/1.32.0_vs_1.31.0/opentelemetry-context.txt create mode 100644 docs/apidiffs/1.32.0_vs_1.31.0/opentelemetry-exporter-common.txt create mode 100644 docs/apidiffs/1.32.0_vs_1.31.0/opentelemetry-exporter-jaeger-thrift.txt create mode 100644 docs/apidiffs/1.32.0_vs_1.31.0/opentelemetry-exporter-jaeger.txt create mode 100644 docs/apidiffs/1.32.0_vs_1.31.0/opentelemetry-exporter-logging-otlp.txt create mode 100644 docs/apidiffs/1.32.0_vs_1.31.0/opentelemetry-exporter-logging.txt create mode 100644 docs/apidiffs/1.32.0_vs_1.31.0/opentelemetry-exporter-otlp-common.txt create mode 100644 docs/apidiffs/1.32.0_vs_1.31.0/opentelemetry-exporter-otlp.txt create mode 100644 docs/apidiffs/1.32.0_vs_1.31.0/opentelemetry-exporter-sender-grpc-managed-channel.txt create mode 100644 docs/apidiffs/1.32.0_vs_1.31.0/opentelemetry-exporter-sender-okhttp.txt create mode 100644 docs/apidiffs/1.32.0_vs_1.31.0/opentelemetry-exporter-zipkin.txt create mode 100644 docs/apidiffs/1.32.0_vs_1.31.0/opentelemetry-extension-kotlin.txt create mode 100644 docs/apidiffs/1.32.0_vs_1.31.0/opentelemetry-extension-trace-propagators.txt create mode 100644 docs/apidiffs/1.32.0_vs_1.31.0/opentelemetry-opentracing-shim.txt create mode 100644 docs/apidiffs/1.32.0_vs_1.31.0/opentelemetry-sdk-common.txt create mode 100644 docs/apidiffs/1.32.0_vs_1.31.0/opentelemetry-sdk-extension-autoconfigure-spi.txt create mode 100644 docs/apidiffs/1.32.0_vs_1.31.0/opentelemetry-sdk-extension-autoconfigure.txt create mode 100644 docs/apidiffs/1.32.0_vs_1.31.0/opentelemetry-sdk-extension-jaeger-remote-sampler.txt create mode 100644 docs/apidiffs/1.32.0_vs_1.31.0/opentelemetry-sdk-logs.txt create mode 100644 docs/apidiffs/1.32.0_vs_1.31.0/opentelemetry-sdk-metrics.txt create mode 100644 docs/apidiffs/1.32.0_vs_1.31.0/opentelemetry-sdk-testing.txt create mode 100644 docs/apidiffs/1.32.0_vs_1.31.0/opentelemetry-sdk-trace.txt create mode 100644 docs/apidiffs/1.32.0_vs_1.31.0/opentelemetry-sdk.txt diff --git a/README.md b/README.md index 4359cb50d0c..4b9b12f2540 100644 --- a/README.md +++ b/README.md @@ -97,7 +97,7 @@ dependency versions in sync. io.opentelemetry opentelemetry-bom - 1.31.0 + 1.32.0 pom import @@ -116,7 +116,7 @@ dependency versions in sync. ```groovy dependencies { - implementation platform("io.opentelemetry:opentelemetry-bom:1.31.0") + implementation platform("io.opentelemetry:opentelemetry-bom:1.32.0") implementation('io.opentelemetry:opentelemetry-api') } ``` @@ -125,8 +125,8 @@ Note that if you want to use any artifacts that have not fully stabilized yet (s ```groovy dependencies { - implementation platform("io.opentelemetry:opentelemetry-bom:1.31.0") - implementation platform('io.opentelemetry:opentelemetry-bom-alpha:1.31.0-alpha') + implementation platform("io.opentelemetry:opentelemetry-bom:1.32.0") + implementation platform('io.opentelemetry:opentelemetry-bom-alpha:1.32.0-alpha') implementation('io.opentelemetry:opentelemetry-api') implementation('io.opentelemetry:opentelemetry-exporter-prometheus') @@ -154,7 +154,7 @@ We strongly recommend using our published BOM to keep all dependency versions in io.opentelemetry opentelemetry-bom - 1.32.0-SNAPSHOT + 1.33.0-SNAPSHOT pom import @@ -177,7 +177,7 @@ repositories { } dependencies { - implementation platform("io.opentelemetry:opentelemetry-bom:1.32.0-SNAPSHOT") + implementation platform("io.opentelemetry:opentelemetry-bom:1.33.0-SNAPSHOT") implementation('io.opentelemetry:opentelemetry-api') } ``` @@ -222,53 +222,53 @@ dependency as follows, replacing `{{artifact-id}}` with the value from the "Arti | Component | Description | Artifact ID | Version | Javadoc | |----------------------------------------------|----------------------------------------|---------------------------|-------------------------------------------------------------|---------| -| [Bill of Materials (BOM)](./bom) | Bill of materials for stable artifacts | `opentelemetry-bom` | 1.31.0 | N/A | -| [Alpha Bill of Materials (BOM)](./bom-alpha) | Bill of materials for alpha artifacts | `opentelemetry-bom-alpha` | 1.31.0-alpha | N/A | +| [Bill of Materials (BOM)](./bom) | Bill of materials for stable artifacts | `opentelemetry-bom` | 1.32.0 | N/A | +| [Alpha Bill of Materials (BOM)](./bom-alpha) | Bill of materials for alpha artifacts | `opentelemetry-bom-alpha` | 1.32.0-alpha | N/A | ### API | Component | Description | Artifact ID | Version | Javadoc | |-----------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|----------------------------|-------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------| -| [API](./api/all) | OpenTelemetry API, including metrics, traces, baggage, context | `opentelemetry-api` | 1.31.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-api.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-api) | -| [Events API](./api/events) | OpenTelemetry Event API for emitting events. | `opentelemetry-api-events` | 1.31.0-alpha | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-api-events.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-api-events) | -| [Context API](./context) | OpenTelemetry context API | `opentelemetry-context` | 1.31.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-context.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-context) | +| [API](./api/all) | OpenTelemetry API, including metrics, traces, baggage, context | `opentelemetry-api` | 1.32.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-api.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-api) | +| [Events API](./api/events) | OpenTelemetry Event API for emitting events. | `opentelemetry-api-events` | 1.32.0-alpha | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-api-events.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-api-events) | +| [Context API](./context) | OpenTelemetry context API | `opentelemetry-context` | 1.32.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-context.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-context) | ### API Extensions | Component | Description | Artifact ID | Version | Javadoc | |---------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|---------------------------------------------|-------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| [Kotlin Extension](./extensions/kotlin) | Context extension for coroutines | `opentelemetry-extension-kotlin` | 1.31.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-extension-kotlin.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-extension-kotlin) | -| [Trace Propagators Extension](./extensions/trace-propagators) | Trace propagators, including B3, Jaeger, OT Trace | `opentelemetry-extension-trace-propagators` | 1.31.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-extension-trace-propagators.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-extension-trace-propagators) | -| [Incubator Extension](./extensions/incubator) | API incubator, including pass through propagator, and extended tracer | `opentelemetry-extension-incubator` | 1.31.0-alpha | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-extension-incubator.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-extension-incubator) | +| [Kotlin Extension](./extensions/kotlin) | Context extension for coroutines | `opentelemetry-extension-kotlin` | 1.32.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-extension-kotlin.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-extension-kotlin) | +| [Trace Propagators Extension](./extensions/trace-propagators) | Trace propagators, including B3, Jaeger, OT Trace | `opentelemetry-extension-trace-propagators` | 1.32.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-extension-trace-propagators.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-extension-trace-propagators) | +| [Incubator Extension](./extensions/incubator) | API incubator, including pass through propagator, and extended tracer | `opentelemetry-extension-incubator` | 1.32.0-alpha | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-extension-incubator.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-extension-incubator) | ### SDK | Component | Description | Artifact ID | Version | Javadoc | |------------------------------|--------------------------------------------------------|-----------------------------|---------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| [SDK](./sdk/all) | OpenTelemetry SDK, including metrics, traces, and logs | `opentelemetry-sdk` | 1.31.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk) | -| [Metrics SDK](./sdk/metrics) | OpenTelemetry metrics SDK | `opentelemetry-sdk-metrics` | 1.31.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-metrics.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-metrics) | -| [Trace SDK](./sdk/trace) | OpenTelemetry trace SDK | `opentelemetry-sdk-trace` | 1.31.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-trace.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-trace) | -| [Log SDK](./sdk/logs) | OpenTelemetry log SDK | `opentelemetry-sdk-logs` | 1.31.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-logs.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-logs) | -| [SDK Common](./sdk/common) | Shared SDK components | `opentelemetry-sdk-common` | 1.31.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-common.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-common) | -| [SDK Testing](./sdk/testing) | Components for testing OpenTelemetry instrumentation | `opentelemetry-sdk-testing` | 1.31.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-testing.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-testing) | +| [SDK](./sdk/all) | OpenTelemetry SDK, including metrics, traces, and logs | `opentelemetry-sdk` | 1.32.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk) | +| [Metrics SDK](./sdk/metrics) | OpenTelemetry metrics SDK | `opentelemetry-sdk-metrics` | 1.32.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-metrics.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-metrics) | +| [Trace SDK](./sdk/trace) | OpenTelemetry trace SDK | `opentelemetry-sdk-trace` | 1.32.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-trace.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-trace) | +| [Log SDK](./sdk/logs) | OpenTelemetry log SDK | `opentelemetry-sdk-logs` | 1.32.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-logs.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-logs) | +| [SDK Common](./sdk/common) | Shared SDK components | `opentelemetry-sdk-common` | 1.32.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-common.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-common) | +| [SDK Testing](./sdk/testing) | Components for testing OpenTelemetry instrumentation | `opentelemetry-sdk-testing` | 1.32.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-testing.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-testing) | ### SDK Exporters | Component | Description | Artifact ID | Version | Javadoc | |-----------------------------------------------------------------------|------------------------------------------------------------------------------|------------------------------------------------------|-------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| [OTLP Exporters](./exporters/otlp/all) | OTLP gRPC & HTTP exporters, including traces, metrics, and logs | `opentelemetry-exporter-otlp` | 1.31.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-otlp.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-otlp) | -| [OTLP Logging Exporters](./exporters/logging-otlp) | Logging exporters in OTLP JSON encoding, including traces, metrics, and logs | `opentelemetry-exporter-logging-otlp` | 1.31.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-logging-otlp.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-logging-otlp) | -| [OTLP Common](./exporters/otlp/common) | Shared OTLP components (internal) | `opentelemetry-exporter-otlp-common` | 1.31.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-otlp-common.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-otlp-common) | -| [Jaeger gRPC Exporter](./exporters/jaeger) | Jaeger gRPC trace exporter (deprecated [1]) | `opentelemetry-exporter-jaeger` | 1.31.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-jaeger.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-jaeger) | -| [Jaeger Thrift Exporter](./exporters/jaeger-thrift) | Jaeger thrift trace exporter (deprecated [1]) | `opentelemetry-exporter-jaeger-thift` | 1.31.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-jaeger-thrift.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-jaeger-thrift) | -| [Logging Exporter](./exporters/logging) | Logging exporters, including metrics, traces, and logs | `opentelemetry-exporter-logging` | 1.31.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-logging.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-logging) | -| [Zipkin Exporter](./exporters/zipkin) | Zipkin trace exporter | `opentelemetry-exporter-zipkin` | 1.31.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-zipkin.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-zipkin) | -| [Prometheus Exporter](./exporters/prometheus) | Prometheus metric exporter | `opentelemetry-exporter-prometheus` | 1.31.0-alpha | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-prometheus.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-prometheus) | -| [Exporter Common](./exporters/common) | Shared exporter components (internal) | `opentelemetry-exporter-common` | 1.31.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-common.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-common) | -| [OkHttp Sender](./exporters/sender/okhttp) | OkHttp implementation of HttpSender (internal) | `opentelemetry-exporter-sender-okhttp` | 1.31.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-sender-okhttp.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-sender-okhttp) | -| [JDK Sender](./exporters/sender/okhttp) | Java 11+ native HttpClient implementation of HttpSender (internal) | `opentelemetry-exporter-sender-jdk` | 1.31.0-alpha | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-sender-jdk.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-sender-jdk) | | -| [gRPC ManagedChannel Sender](./exporters/sender/grpc-managed-channel) | gRPC ManagedChannel implementation of GrpcSender (internal) | `opentelemetry-exporter-sender-grpc-managed-channel` | 1.31.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-sender-grpc-managed-channel.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-sender-grpc-managed-channel) | | +| [OTLP Exporters](./exporters/otlp/all) | OTLP gRPC & HTTP exporters, including traces, metrics, and logs | `opentelemetry-exporter-otlp` | 1.32.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-otlp.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-otlp) | +| [OTLP Logging Exporters](./exporters/logging-otlp) | Logging exporters in OTLP JSON encoding, including traces, metrics, and logs | `opentelemetry-exporter-logging-otlp` | 1.32.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-logging-otlp.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-logging-otlp) | +| [OTLP Common](./exporters/otlp/common) | Shared OTLP components (internal) | `opentelemetry-exporter-otlp-common` | 1.32.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-otlp-common.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-otlp-common) | +| [Jaeger gRPC Exporter](./exporters/jaeger) | Jaeger gRPC trace exporter (deprecated [1]) | `opentelemetry-exporter-jaeger` | 1.32.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-jaeger.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-jaeger) | +| [Jaeger Thrift Exporter](./exporters/jaeger-thrift) | Jaeger thrift trace exporter (deprecated [1]) | `opentelemetry-exporter-jaeger-thift` | 1.32.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-jaeger-thrift.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-jaeger-thrift) | +| [Logging Exporter](./exporters/logging) | Logging exporters, including metrics, traces, and logs | `opentelemetry-exporter-logging` | 1.32.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-logging.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-logging) | +| [Zipkin Exporter](./exporters/zipkin) | Zipkin trace exporter | `opentelemetry-exporter-zipkin` | 1.32.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-zipkin.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-zipkin) | +| [Prometheus Exporter](./exporters/prometheus) | Prometheus metric exporter | `opentelemetry-exporter-prometheus` | 1.32.0-alpha | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-prometheus.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-prometheus) | +| [Exporter Common](./exporters/common) | Shared exporter components (internal) | `opentelemetry-exporter-common` | 1.32.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-common.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-common) | +| [OkHttp Sender](./exporters/sender/okhttp) | OkHttp implementation of HttpSender (internal) | `opentelemetry-exporter-sender-okhttp` | 1.32.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-sender-okhttp.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-sender-okhttp) | +| [JDK Sender](./exporters/sender/okhttp) | Java 11+ native HttpClient implementation of HttpSender (internal) | `opentelemetry-exporter-sender-jdk` | 1.32.0-alpha | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-sender-jdk.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-sender-jdk) | | +| [gRPC ManagedChannel Sender](./exporters/sender/grpc-managed-channel) | gRPC ManagedChannel implementation of GrpcSender (internal) | `opentelemetry-exporter-sender-grpc-managed-channel` | 1.32.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-sender-grpc-managed-channel.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-sender-grpc-managed-channel) | | **[1]**: Jaeger now has [native support for OTLP](https://opentelemetry.io/blog/2022/jaeger-native-otlp/) and jaeger @@ -281,17 +281,17 @@ additional versions will be published. | Component | Description | Artifact ID | Version | Javadoc | |-------------------------------------------------------------------------------|------------------------------------------------------------------------------------|-----------------------------------------------------|-------------------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| [SDK Autoconfigure](./sdk-extensions/autoconfigure) | Autoconfigure OpenTelemetry SDK from env vars, system properties, and SPI | `opentelemetry-sdk-extension-autoconfigure` | 1.31.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-extension-autoconfigure.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-extension-autoconfigure) | -| [SDK Autoconfigure SPI](./sdk-extensions/autoconfigure-spi) | Service Provider Interface (SPI) definitions for autoconfigure | `opentelemetry-sdk-extension-autoconfigure-spi` | 1.31.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-extension-autoconfigure-spi.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-extension-autoconfigure-spi) | -| [SDK Jaeger Remote Sampler Extension](./sdk-extensions/jaeger-remote-sampler) | Sampler which obtains sampling configuration from remote Jaeger server | `opentelemetry-sdk-extension-jaeger-remote-sampler` | 1.31.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-extension-jaeger-remote-sampler.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-extension-jaeger-remote-sampler) | -| [SDK Incubator](./sdk-extensions/incubator) | SDK incubator, including YAML based view configuration, LeakDetectingSpanProcessor | `opentelemetry-sdk-extension-incubator` | 1.31.0-alpha | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-extension-incubator.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-extension-incubator) | +| [SDK Autoconfigure](./sdk-extensions/autoconfigure) | Autoconfigure OpenTelemetry SDK from env vars, system properties, and SPI | `opentelemetry-sdk-extension-autoconfigure` | 1.32.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-extension-autoconfigure.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-extension-autoconfigure) | +| [SDK Autoconfigure SPI](./sdk-extensions/autoconfigure-spi) | Service Provider Interface (SPI) definitions for autoconfigure | `opentelemetry-sdk-extension-autoconfigure-spi` | 1.32.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-extension-autoconfigure-spi.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-extension-autoconfigure-spi) | +| [SDK Jaeger Remote Sampler Extension](./sdk-extensions/jaeger-remote-sampler) | Sampler which obtains sampling configuration from remote Jaeger server | `opentelemetry-sdk-extension-jaeger-remote-sampler` | 1.32.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-extension-jaeger-remote-sampler.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-extension-jaeger-remote-sampler) | +| [SDK Incubator](./sdk-extensions/incubator) | SDK incubator, including YAML based view configuration, LeakDetectingSpanProcessor | `opentelemetry-sdk-extension-incubator` | 1.32.0-alpha | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-extension-incubator.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-extension-incubator) | ### Shims | Component | Description | Artifact ID | Version | Javadoc | |----------------------------------------|--------------------------------------------------------------|----------------------------------|-------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| [OpenCensus Shim](./opencensus-shim) | Bridge opencensus metrics into the OpenTelemetry metrics SDK | `opentelemetry-opencensus-shim` | 1.31.0-alpha | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-opencensus-shim.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-opencensus-shim) | -| [OpenTracing Shim](./opentracing-shim) | Bridge opentracing spans into the OpenTelemetry trace API | `opentelemetry-opentracing-shim` | 1.31.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-opentracing-shim.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-opentracing-shim) | +| [OpenCensus Shim](./opencensus-shim) | Bridge opencensus metrics into the OpenTelemetry metrics SDK | `opentelemetry-opencensus-shim` | 1.32.0-alpha | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-opencensus-shim.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-opencensus-shim) | +| [OpenTracing Shim](./opentracing-shim) | Bridge opentracing spans into the OpenTelemetry trace API | `opentelemetry-opentracing-shim` | 1.32.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-opentracing-shim.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-opentracing-shim) | ## Contributing diff --git a/docs/apidiffs/1.32.0_vs_1.31.0/opentelemetry-api.txt b/docs/apidiffs/1.32.0_vs_1.31.0/opentelemetry-api.txt new file mode 100644 index 00000000000..faa8d3cf893 --- /dev/null +++ b/docs/apidiffs/1.32.0_vs_1.31.0/opentelemetry-api.txt @@ -0,0 +1,7 @@ +Comparing source compatibility of against +*** MODIFIED INTERFACE: PUBLIC ABSTRACT io.opentelemetry.api.metrics.DoubleHistogramBuilder (not serializable) + === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 + +++ NEW METHOD: PUBLIC(+) io.opentelemetry.api.metrics.DoubleHistogramBuilder setExplicitBucketBoundariesAdvice(java.util.List) +*** MODIFIED INTERFACE: PUBLIC ABSTRACT io.opentelemetry.api.metrics.LongHistogramBuilder (not serializable) + === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 + +++ NEW METHOD: PUBLIC(+) io.opentelemetry.api.metrics.LongHistogramBuilder setExplicitBucketBoundariesAdvice(java.util.List) diff --git a/docs/apidiffs/1.32.0_vs_1.31.0/opentelemetry-context.txt b/docs/apidiffs/1.32.0_vs_1.31.0/opentelemetry-context.txt new file mode 100644 index 00000000000..df26146497b --- /dev/null +++ b/docs/apidiffs/1.32.0_vs_1.31.0/opentelemetry-context.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of against +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.32.0_vs_1.31.0/opentelemetry-exporter-common.txt b/docs/apidiffs/1.32.0_vs_1.31.0/opentelemetry-exporter-common.txt new file mode 100644 index 00000000000..df26146497b --- /dev/null +++ b/docs/apidiffs/1.32.0_vs_1.31.0/opentelemetry-exporter-common.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of against +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.32.0_vs_1.31.0/opentelemetry-exporter-jaeger-thrift.txt b/docs/apidiffs/1.32.0_vs_1.31.0/opentelemetry-exporter-jaeger-thrift.txt new file mode 100644 index 00000000000..df26146497b --- /dev/null +++ b/docs/apidiffs/1.32.0_vs_1.31.0/opentelemetry-exporter-jaeger-thrift.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of against +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.32.0_vs_1.31.0/opentelemetry-exporter-jaeger.txt b/docs/apidiffs/1.32.0_vs_1.31.0/opentelemetry-exporter-jaeger.txt new file mode 100644 index 00000000000..df26146497b --- /dev/null +++ b/docs/apidiffs/1.32.0_vs_1.31.0/opentelemetry-exporter-jaeger.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of against +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.32.0_vs_1.31.0/opentelemetry-exporter-logging-otlp.txt b/docs/apidiffs/1.32.0_vs_1.31.0/opentelemetry-exporter-logging-otlp.txt new file mode 100644 index 00000000000..df26146497b --- /dev/null +++ b/docs/apidiffs/1.32.0_vs_1.31.0/opentelemetry-exporter-logging-otlp.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of against +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.32.0_vs_1.31.0/opentelemetry-exporter-logging.txt b/docs/apidiffs/1.32.0_vs_1.31.0/opentelemetry-exporter-logging.txt new file mode 100644 index 00000000000..df26146497b --- /dev/null +++ b/docs/apidiffs/1.32.0_vs_1.31.0/opentelemetry-exporter-logging.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of against +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.32.0_vs_1.31.0/opentelemetry-exporter-otlp-common.txt b/docs/apidiffs/1.32.0_vs_1.31.0/opentelemetry-exporter-otlp-common.txt new file mode 100644 index 00000000000..df26146497b --- /dev/null +++ b/docs/apidiffs/1.32.0_vs_1.31.0/opentelemetry-exporter-otlp-common.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of against +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.32.0_vs_1.31.0/opentelemetry-exporter-otlp.txt b/docs/apidiffs/1.32.0_vs_1.31.0/opentelemetry-exporter-otlp.txt new file mode 100644 index 00000000000..afee563c67e --- /dev/null +++ b/docs/apidiffs/1.32.0_vs_1.31.0/opentelemetry-exporter-otlp.txt @@ -0,0 +1,13 @@ +Comparing source compatibility of against +*** MODIFIED CLASS: PUBLIC FINAL io.opentelemetry.exporter.otlp.http.logs.OtlpHttpLogRecordExporterBuilder (not serializable) + === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 + +++ NEW METHOD: PUBLIC(+) io.opentelemetry.exporter.otlp.http.logs.OtlpHttpLogRecordExporterBuilder setMeterProvider(java.util.function.Supplier) +*** MODIFIED CLASS: PUBLIC FINAL io.opentelemetry.exporter.otlp.http.trace.OtlpHttpSpanExporterBuilder (not serializable) + === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 + +++ NEW METHOD: PUBLIC(+) io.opentelemetry.exporter.otlp.http.trace.OtlpHttpSpanExporterBuilder setMeterProvider(java.util.function.Supplier) +*** MODIFIED CLASS: PUBLIC FINAL io.opentelemetry.exporter.otlp.logs.OtlpGrpcLogRecordExporterBuilder (not serializable) + === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 + +++ NEW METHOD: PUBLIC(+) io.opentelemetry.exporter.otlp.logs.OtlpGrpcLogRecordExporterBuilder setMeterProvider(java.util.function.Supplier) +*** MODIFIED CLASS: PUBLIC FINAL io.opentelemetry.exporter.otlp.trace.OtlpGrpcSpanExporterBuilder (not serializable) + === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 + +++ NEW METHOD: PUBLIC(+) io.opentelemetry.exporter.otlp.trace.OtlpGrpcSpanExporterBuilder setMeterProvider(java.util.function.Supplier) diff --git a/docs/apidiffs/1.32.0_vs_1.31.0/opentelemetry-exporter-sender-grpc-managed-channel.txt b/docs/apidiffs/1.32.0_vs_1.31.0/opentelemetry-exporter-sender-grpc-managed-channel.txt new file mode 100644 index 00000000000..df26146497b --- /dev/null +++ b/docs/apidiffs/1.32.0_vs_1.31.0/opentelemetry-exporter-sender-grpc-managed-channel.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of against +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.32.0_vs_1.31.0/opentelemetry-exporter-sender-okhttp.txt b/docs/apidiffs/1.32.0_vs_1.31.0/opentelemetry-exporter-sender-okhttp.txt new file mode 100644 index 00000000000..df26146497b --- /dev/null +++ b/docs/apidiffs/1.32.0_vs_1.31.0/opentelemetry-exporter-sender-okhttp.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of against +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.32.0_vs_1.31.0/opentelemetry-exporter-zipkin.txt b/docs/apidiffs/1.32.0_vs_1.31.0/opentelemetry-exporter-zipkin.txt new file mode 100644 index 00000000000..df26146497b --- /dev/null +++ b/docs/apidiffs/1.32.0_vs_1.31.0/opentelemetry-exporter-zipkin.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of against +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.32.0_vs_1.31.0/opentelemetry-extension-kotlin.txt b/docs/apidiffs/1.32.0_vs_1.31.0/opentelemetry-extension-kotlin.txt new file mode 100644 index 00000000000..df26146497b --- /dev/null +++ b/docs/apidiffs/1.32.0_vs_1.31.0/opentelemetry-extension-kotlin.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of against +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.32.0_vs_1.31.0/opentelemetry-extension-trace-propagators.txt b/docs/apidiffs/1.32.0_vs_1.31.0/opentelemetry-extension-trace-propagators.txt new file mode 100644 index 00000000000..df26146497b --- /dev/null +++ b/docs/apidiffs/1.32.0_vs_1.31.0/opentelemetry-extension-trace-propagators.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of against +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.32.0_vs_1.31.0/opentelemetry-opentracing-shim.txt b/docs/apidiffs/1.32.0_vs_1.31.0/opentelemetry-opentracing-shim.txt new file mode 100644 index 00000000000..df26146497b --- /dev/null +++ b/docs/apidiffs/1.32.0_vs_1.31.0/opentelemetry-opentracing-shim.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of against +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.32.0_vs_1.31.0/opentelemetry-sdk-common.txt b/docs/apidiffs/1.32.0_vs_1.31.0/opentelemetry-sdk-common.txt new file mode 100644 index 00000000000..df26146497b --- /dev/null +++ b/docs/apidiffs/1.32.0_vs_1.31.0/opentelemetry-sdk-common.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of against +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.32.0_vs_1.31.0/opentelemetry-sdk-extension-autoconfigure-spi.txt b/docs/apidiffs/1.32.0_vs_1.31.0/opentelemetry-sdk-extension-autoconfigure-spi.txt new file mode 100644 index 00000000000..df26146497b --- /dev/null +++ b/docs/apidiffs/1.32.0_vs_1.31.0/opentelemetry-sdk-extension-autoconfigure-spi.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of against +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.32.0_vs_1.31.0/opentelemetry-sdk-extension-autoconfigure.txt b/docs/apidiffs/1.32.0_vs_1.31.0/opentelemetry-sdk-extension-autoconfigure.txt new file mode 100644 index 00000000000..df26146497b --- /dev/null +++ b/docs/apidiffs/1.32.0_vs_1.31.0/opentelemetry-sdk-extension-autoconfigure.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of against +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.32.0_vs_1.31.0/opentelemetry-sdk-extension-jaeger-remote-sampler.txt b/docs/apidiffs/1.32.0_vs_1.31.0/opentelemetry-sdk-extension-jaeger-remote-sampler.txt new file mode 100644 index 00000000000..df26146497b --- /dev/null +++ b/docs/apidiffs/1.32.0_vs_1.31.0/opentelemetry-sdk-extension-jaeger-remote-sampler.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of against +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.32.0_vs_1.31.0/opentelemetry-sdk-logs.txt b/docs/apidiffs/1.32.0_vs_1.31.0/opentelemetry-sdk-logs.txt new file mode 100644 index 00000000000..df26146497b --- /dev/null +++ b/docs/apidiffs/1.32.0_vs_1.31.0/opentelemetry-sdk-logs.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of against +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.32.0_vs_1.31.0/opentelemetry-sdk-metrics.txt b/docs/apidiffs/1.32.0_vs_1.31.0/opentelemetry-sdk-metrics.txt new file mode 100644 index 00000000000..df26146497b --- /dev/null +++ b/docs/apidiffs/1.32.0_vs_1.31.0/opentelemetry-sdk-metrics.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of against +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.32.0_vs_1.31.0/opentelemetry-sdk-testing.txt b/docs/apidiffs/1.32.0_vs_1.31.0/opentelemetry-sdk-testing.txt new file mode 100644 index 00000000000..e8f3d45d4f7 --- /dev/null +++ b/docs/apidiffs/1.32.0_vs_1.31.0/opentelemetry-sdk-testing.txt @@ -0,0 +1,9 @@ +Comparing source compatibility of against +*** MODIFIED CLASS: PUBLIC FINAL io.opentelemetry.sdk.testing.junit4.OpenTelemetryRule (not serializable) + === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 + +++ NEW METHOD: PUBLIC(+) void clearLogRecords() + +++ NEW METHOD: PUBLIC(+) java.util.List getLogRecords() +*** MODIFIED CLASS: PUBLIC FINAL io.opentelemetry.sdk.testing.junit5.OpenTelemetryExtension (not serializable) + === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 + +++ NEW METHOD: PUBLIC(+) void clearLogRecords() + +++ NEW METHOD: PUBLIC(+) java.util.List getLogRecords() diff --git a/docs/apidiffs/1.32.0_vs_1.31.0/opentelemetry-sdk-trace.txt b/docs/apidiffs/1.32.0_vs_1.31.0/opentelemetry-sdk-trace.txt new file mode 100644 index 00000000000..df26146497b --- /dev/null +++ b/docs/apidiffs/1.32.0_vs_1.31.0/opentelemetry-sdk-trace.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of against +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.32.0_vs_1.31.0/opentelemetry-sdk.txt b/docs/apidiffs/1.32.0_vs_1.31.0/opentelemetry-sdk.txt new file mode 100644 index 00000000000..df26146497b --- /dev/null +++ b/docs/apidiffs/1.32.0_vs_1.31.0/opentelemetry-sdk.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of against +No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-api.txt b/docs/apidiffs/current_vs_latest/opentelemetry-api.txt index faa8d3cf893..df26146497b 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-api.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-api.txt @@ -1,7 +1,2 @@ Comparing source compatibility of against -*** MODIFIED INTERFACE: PUBLIC ABSTRACT io.opentelemetry.api.metrics.DoubleHistogramBuilder (not serializable) - === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 - +++ NEW METHOD: PUBLIC(+) io.opentelemetry.api.metrics.DoubleHistogramBuilder setExplicitBucketBoundariesAdvice(java.util.List) -*** MODIFIED INTERFACE: PUBLIC ABSTRACT io.opentelemetry.api.metrics.LongHistogramBuilder (not serializable) - === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 - +++ NEW METHOD: PUBLIC(+) io.opentelemetry.api.metrics.LongHistogramBuilder setExplicitBucketBoundariesAdvice(java.util.List) +No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-otlp.txt b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-otlp.txt index afee563c67e..df26146497b 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-otlp.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-otlp.txt @@ -1,13 +1,2 @@ Comparing source compatibility of against -*** MODIFIED CLASS: PUBLIC FINAL io.opentelemetry.exporter.otlp.http.logs.OtlpHttpLogRecordExporterBuilder (not serializable) - === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 - +++ NEW METHOD: PUBLIC(+) io.opentelemetry.exporter.otlp.http.logs.OtlpHttpLogRecordExporterBuilder setMeterProvider(java.util.function.Supplier) -*** MODIFIED CLASS: PUBLIC FINAL io.opentelemetry.exporter.otlp.http.trace.OtlpHttpSpanExporterBuilder (not serializable) - === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 - +++ NEW METHOD: PUBLIC(+) io.opentelemetry.exporter.otlp.http.trace.OtlpHttpSpanExporterBuilder setMeterProvider(java.util.function.Supplier) -*** MODIFIED CLASS: PUBLIC FINAL io.opentelemetry.exporter.otlp.logs.OtlpGrpcLogRecordExporterBuilder (not serializable) - === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 - +++ NEW METHOD: PUBLIC(+) io.opentelemetry.exporter.otlp.logs.OtlpGrpcLogRecordExporterBuilder setMeterProvider(java.util.function.Supplier) -*** MODIFIED CLASS: PUBLIC FINAL io.opentelemetry.exporter.otlp.trace.OtlpGrpcSpanExporterBuilder (not serializable) - === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 - +++ NEW METHOD: PUBLIC(+) io.opentelemetry.exporter.otlp.trace.OtlpGrpcSpanExporterBuilder setMeterProvider(java.util.function.Supplier) +No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-testing.txt b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-testing.txt index e8f3d45d4f7..df26146497b 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-testing.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-testing.txt @@ -1,9 +1,2 @@ Comparing source compatibility of against -*** MODIFIED CLASS: PUBLIC FINAL io.opentelemetry.sdk.testing.junit4.OpenTelemetryRule (not serializable) - === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 - +++ NEW METHOD: PUBLIC(+) void clearLogRecords() - +++ NEW METHOD: PUBLIC(+) java.util.List getLogRecords() -*** MODIFIED CLASS: PUBLIC FINAL io.opentelemetry.sdk.testing.junit5.OpenTelemetryExtension (not serializable) - === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 - +++ NEW METHOD: PUBLIC(+) void clearLogRecords() - +++ NEW METHOD: PUBLIC(+) java.util.List getLogRecords() +No changes. \ No newline at end of file From 9ac678e81bce7c12820acdb846d22d7957b8b15f Mon Sep 17 00:00:00 2001 From: jack-berg <34418638+jack-berg@users.noreply.github.com> Date: Tue, 14 Nov 2023 10:23:42 -0600 Subject: [PATCH 097/901] Fix SynchronousMetricStorageTest flake (#5981) --- .../internal/state/SynchronousMetricStorageTest.java | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/internal/state/SynchronousMetricStorageTest.java b/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/internal/state/SynchronousMetricStorageTest.java index cbaa2aa303b..f808a0e85f1 100644 --- a/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/internal/state/SynchronousMetricStorageTest.java +++ b/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/internal/state/SynchronousMetricStorageTest.java @@ -413,16 +413,15 @@ void recordAndCollect_concurrentStressTest( // If we terminate when latch.count() == 0, the last collect may have occurred before // the last recorded measurement. To ensure we collect all measurements, we collect // one extra time after latch.count() == 0. - while (latch.getCount() != 0 && extraCollects <= 1) { + while (latch.getCount() != 0 || extraCollects <= 1) { Uninterruptibles.sleepUninterruptibly(Duration.ofMillis(1)); MetricData metricData = storage.collect(Resource.empty(), InstrumentationScopeInfo.empty(), 0, 1); - if (metricData.isEmpty()) { - continue; + if (!metricData.isEmpty()) { + metricData.getDoubleSumData().getPoints().stream() + .findFirst() + .ifPresent(pointData -> collect.accept(pointData.getValue(), cumulativeSum)); } - metricData.getDoubleSumData().getPoints().stream() - .findFirst() - .ifPresent(pointData -> collect.accept(pointData.getValue(), cumulativeSum)); if (latch.getCount() == 0) { extraCollects++; } From 514d0820b2828f82b89fd7aae7f42387cd9fc81a Mon Sep 17 00:00:00 2001 From: Asaf Mesika Date: Fri, 17 Nov 2023 00:53:54 +0200 Subject: [PATCH 098/901] MetricsBenchmarks should share state between threads (#5984) --- buildSrc/src/main/kotlin/otel.jmh-conventions.gradle.kts | 5 +++++ .../exporter/otlp/trace/OltpExporterBenchmark.java | 2 +- .../java/io/opentelemetry/sdk/metrics/MetricsBenchmarks.java | 4 ++-- 3 files changed, 8 insertions(+), 3 deletions(-) diff --git a/buildSrc/src/main/kotlin/otel.jmh-conventions.gradle.kts b/buildSrc/src/main/kotlin/otel.jmh-conventions.gradle.kts index 5434e9f9181..3e4ad43195c 100644 --- a/buildSrc/src/main/kotlin/otel.jmh-conventions.gradle.kts +++ b/buildSrc/src/main/kotlin/otel.jmh-conventions.gradle.kts @@ -7,6 +7,11 @@ dependencies { jmh(platform(project(":dependencyManagement"))) jmh("org.openjdk.jmh:jmh-core") jmh("org.openjdk.jmh:jmh-generator-bytecode") + + // This enables running JMH benchmark classes within IntelliJ using + // JMH plugins + jmh("org.openjdk.jmh:jmh-generator-annprocess") + jmhAnnotationProcessor("org.openjdk.jmh:jmh-generator-annprocess") } // invoke jmh on a single benchmark class like so: diff --git a/exporters/otlp/all/src/jmh/java/io/opentelemetry/exporter/otlp/trace/OltpExporterBenchmark.java b/exporters/otlp/all/src/jmh/java/io/opentelemetry/exporter/otlp/trace/OltpExporterBenchmark.java index 8e70ad7a73f..942f66573d3 100644 --- a/exporters/otlp/all/src/jmh/java/io/opentelemetry/exporter/otlp/trace/OltpExporterBenchmark.java +++ b/exporters/otlp/all/src/jmh/java/io/opentelemetry/exporter/otlp/trace/OltpExporterBenchmark.java @@ -95,7 +95,7 @@ public void setUp() { URI.create("http://localhost:" + server.activeLocalPort()) .resolve(OtlpGrpcSpanExporterBuilder.GRPC_ENDPOINT_PATH) .toString(), - false, + /* compressionEnabled= */ false, 10, Collections.emptyMap(), null, diff --git a/sdk/metrics/src/jmh/java/io/opentelemetry/sdk/metrics/MetricsBenchmarks.java b/sdk/metrics/src/jmh/java/io/opentelemetry/sdk/metrics/MetricsBenchmarks.java index a77c3200d28..c181f5dd1ba 100644 --- a/sdk/metrics/src/jmh/java/io/opentelemetry/sdk/metrics/MetricsBenchmarks.java +++ b/sdk/metrics/src/jmh/java/io/opentelemetry/sdk/metrics/MetricsBenchmarks.java @@ -51,7 +51,7 @@ public class MetricsBenchmarks { } } - @State(Scope.Thread) + @State(Scope.Benchmark) public static class ThreadState { @Param TestSdk sdk; @@ -78,7 +78,7 @@ public void setup(ThreadParams threadParams) { } @TearDown - public void tearDown(ThreadParams threadParams) { + public void tearDown() { contextScope.close(); span.end(); } From 531898cd6b906a2273291f7683e15e04212d8161 Mon Sep 17 00:00:00 2001 From: jack-berg <34418638+jack-berg@users.noreply.github.com> Date: Thu, 16 Nov 2023 17:01:23 -0600 Subject: [PATCH 099/901] Define language version compatibility requirements (#5983) --- README.md | 9 +++++++-- VERSIONING.md | 15 +++++++++++++++ 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 4b9b12f2540..e14f66c7fc6 100644 --- a/README.md +++ b/README.md @@ -66,10 +66,15 @@ We would love to hear from the larger community: please provide feedback proacti ## Requirements Unless otherwise noted, all published artifacts support Java 8 or higher. +See [language version compatibility](VERSIONING.md#language-version-compatibility) for complete +details. -**Android Disclaimer:** For compatibility reasons, [library desugaring](https://developer.android.com/studio/write/java8-support#library-desugaring) must be enabled. +**Android Disclaimer:** For compatibility +reasons, [library desugaring](https://developer.android.com/studio/write/java8-support#library-desugaring) +must be enabled. -See [CONTRIBUTING.md](./CONTRIBUTING.md) for additional instructions for building this project for development. +See [CONTRIBUTING.md](./CONTRIBUTING.md) for additional instructions for building this project for +development. ### Note about extensions diff --git a/VERSIONING.md b/VERSIONING.md index 9d2ad3af3cf..d0bf9a79148 100644 --- a/VERSIONING.md +++ b/VERSIONING.md @@ -61,6 +61,21 @@ you do not use classes in the `internal` package (which you MUST NOT do), you ca your app will always function and have access to the latest features of OpenTelemetry without needing any changes to code. +## Language Version Compatibility + +The artifacts published by this codebase are compatible with certain language levels of tooling in +the Java ecosystem. For example, all artifacts (except where otherwise noted) support Java language +level 8 or higher, and the many artifacts intended to be used in Android environments adhere to a +particular [Android API level](https://developer.android.com/tools/releases/build-tools). The +following table defines the minimum language levels we adhere to, and how each is considered with +respect to semantic versioning. + +| Language | Minimum Version | Applicability | Semconv Notes | +|----------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|---------------------------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| Java | 8+ | All artifacts, unless otherwise noted | Changing requires major version bump. | +| Android | 21+ (NOTE: [desugaring](https://developer.android.com/studio/write/java8-support#library-desugaring) is required. We stay up to date with the latest version of [desugar_jdk_libs](https://github.com/google/desugar_jdk_libs).) | Artifacts using `otel.animalsniffer-conventions` plugin | Kept in sync with minimum requirements for [Google Play services](https://developers.google.com/android/guides/setup). Subject to change in minor version. | +| Kotlin | 1.6+ | Only applies to `opentelemetry-extension-kotlin` | Kept in sync with [minimum non-deprecated](https://kotlinlang.org/docs/gradle-compiler-options.html#attributes-common-to-jvm-and-js) version. Subject to change in minor versions. | + ## API vs SDK This codebase is broadly split into two large pieces, the OpenTelemetry API and the OpenTelemetry SDK, From c87852c3d135bd670ab8ad5762809420c5f2dbf7 Mon Sep 17 00:00:00 2001 From: Lauri Tulmin Date: Fri, 17 Nov 2023 21:54:13 +0200 Subject: [PATCH 100/901] Target kotlin 1.4 in kotlin extension (#5910) --- .../current_vs_latest/opentelemetry-extension-kotlin.txt | 9 ++++++++- extensions/kotlin/build.gradle.kts | 1 + 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-extension-kotlin.txt b/docs/apidiffs/current_vs_latest/opentelemetry-extension-kotlin.txt index df26146497b..1945e8c996d 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-extension-kotlin.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-extension-kotlin.txt @@ -1,2 +1,9 @@ Comparing source compatibility of against -No changes. \ No newline at end of file +=== UNCHANGED CLASS: PUBLIC FINAL io.opentelemetry.extension.kotlin.ContextExtensionsKt (not serializable) + === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 + *** MODIFIED ANNOTATION: kotlin.Metadata + === UNCHANGED ELEMENT: xi=48 + *** MODIFIED ELEMENT: mv=1,6,0 (<- 1,9,0) + === UNCHANGED ELEMENT: k=2 + === UNCHANGED ELEMENT: d1=�� � ��� ��� ��� ���� ����0�*�0�� ����0�*�0�� ����0�*�0�¨�� + === UNCHANGED ELEMENT: d2=asContextElement,Lkotlin/coroutines/CoroutineContext;,Lio/opentelemetry/context/Context;,Lio/opentelemetry/context/ImplicitContextKeyed;,getOpenTelemetryContext,opentelemetry-extension-kotlin diff --git a/extensions/kotlin/build.gradle.kts b/extensions/kotlin/build.gradle.kts index 14a43ef1499..7409cb49f29 100644 --- a/extensions/kotlin/build.gradle.kts +++ b/extensions/kotlin/build.gradle.kts @@ -48,6 +48,7 @@ tasks { withType(KotlinCompile::class) { kotlinOptions { jvmTarget = "1.8" + languageVersion = "1.6" } } From f58a209e9acd8edf064c979af7f43d5d005be633 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9sar?= <56847527+LikeTheSalad@users.noreply.github.com> Date: Mon, 20 Nov 2023 19:12:55 +0100 Subject: [PATCH 101/901] Building animal sniffer signatures directly from android corelib (#5973) --- animal-sniffer-signature/build.gradle.kts | 52 +++++++++++++++++++ .../otel.animalsniffer-conventions.gradle.kts | 2 +- dependencyManagement/build.gradle.kts | 1 + settings.gradle.kts | 2 + 4 files changed, 56 insertions(+), 1 deletion(-) create mode 100644 animal-sniffer-signature/build.gradle.kts diff --git a/animal-sniffer-signature/build.gradle.kts b/animal-sniffer-signature/build.gradle.kts new file mode 100644 index 00000000000..2f835c559aa --- /dev/null +++ b/animal-sniffer-signature/build.gradle.kts @@ -0,0 +1,52 @@ +import ru.vyarus.gradle.plugin.animalsniffer.info.SignatureInfoTask +import ru.vyarus.gradle.plugin.animalsniffer.signature.BuildSignatureTask + +plugins { + id("otel.java-conventions") + id("ru.vyarus.animalsniffer") +} + +description = "Build tool to generate the Animal Sniffer Android signature" +otelJava.moduleName.set("io.opentelemetry.internal.animalsniffer") + +val signatureJar = configurations.create("signatureJar") { + isCanBeConsumed = false + isCanBeResolved = false +} +val signatureJarClasspath = configurations.create("signatureJarClasspath") { + isCanBeConsumed = false + isCanBeResolved = true + extendsFrom(signatureJar) +} +val generatedSignature = configurations.create("generatedSignature") { + isCanBeConsumed = true + isCanBeResolved = false +} +configurations.add(signatureJar) +configurations.add(signatureJarClasspath) +configurations.add(generatedSignature) + +dependencies { + signature("com.toasttab.android:gummy-bears-api-21:0.6.1@signature") + signatureJar("com.android.tools:desugar_jdk_libs") +} + +val signatureSimpleName = "android.signature" +val signatureBuilderTask = tasks.register("buildSignature", BuildSignatureTask::class.java) { + files(signatureJarClasspath) // All the jar files here will be added to the signature file. + signatures(configurations.signature) // We'll extend from the existing signatures added to this config. + outputName = signatureSimpleName // Name for the generated signature file. +} + +// Exposing the "generatedSignature" consumable config to be used in other subprojects +artifacts { + add("generatedSignature", project.provider { File(signatureBuilderTask.get().outputs.files.singleFile, signatureSimpleName) }) { + builtBy(signatureBuilderTask) + } +} + +// Utility task to show what's in the signature file +tasks.register("printSignature", SignatureInfoTask::class.java) { + signature = signatureBuilderTask.get().outputFiles + depth = 1 +} diff --git a/buildSrc/src/main/kotlin/otel.animalsniffer-conventions.gradle.kts b/buildSrc/src/main/kotlin/otel.animalsniffer-conventions.gradle.kts index 9680996fcc8..73bbf0dd2d7 100644 --- a/buildSrc/src/main/kotlin/otel.animalsniffer-conventions.gradle.kts +++ b/buildSrc/src/main/kotlin/otel.animalsniffer-conventions.gradle.kts @@ -7,7 +7,7 @@ plugins { } dependencies { - add("signature", "com.toasttab.android:gummy-bears-api-21:0.3.0:coreLib@signature") + signature(project(path = ":animal-sniffer-signature", configuration = "generatedSignature")) } animalsniffer { diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index c7a8aa61f5a..03b62a6e2a7 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -77,6 +77,7 @@ val DEPENDENCIES = listOf( "org.jctools:jctools-core:4.0.1", "org.junit-pioneer:junit-pioneer:1.9.1", "org.skyscreamer:jsonassert:1.5.1", + "com.android.tools:desugar_jdk_libs:2.0.4", ) javaPlatform { diff --git a/settings.gradle.kts b/settings.gradle.kts index 735cc2f5ccf..5599100fcd8 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -16,6 +16,7 @@ plugins { dependencyResolutionManagement { repositories { mavenCentral() + google() mavenLocal() } } @@ -64,6 +65,7 @@ include(":sdk-extensions:autoconfigure-spi") include(":sdk-extensions:incubator") include(":sdk-extensions:jaeger-remote-sampler") include(":testing-internal") +include(":animal-sniffer-signature") val gradleEnterpriseServer = "https://ge.opentelemetry.io" val isCI = System.getenv("CI") != null From 0f60bd421518c1d84fdf545c80a9024c5072aaa8 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 20 Nov 2023 14:17:44 -0600 Subject: [PATCH 102/901] Update dependency com.uber.nullaway:nullaway to v0.10.17 (#6000) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- dependencyManagement/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index 03b62a6e2a7..366cefd0d56 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -60,7 +60,7 @@ val DEPENDENCIES = listOf( "com.google.guava:guava-beta-checker:1.0", "com.sun.net.httpserver:http:20070405", "com.tngtech.archunit:archunit-junit5:1.2.0", - "com.uber.nullaway:nullaway:0.10.16", + "com.uber.nullaway:nullaway:0.10.17", "edu.berkeley.cs.jqf:jqf-fuzz:1.7", // jqf-fuzz version 1.8+ requires Java 11+ "eu.rekawek.toxiproxy:toxiproxy-java:2.1.7", "io.github.netmikey.logunit:logunit-jul:2.0.0", From c7b2c8b00beb9588f17662fb5f4c1d1c9c6529df Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 20 Nov 2023 14:18:05 -0600 Subject: [PATCH 103/901] Update dependency com.fasterxml.jackson:jackson-bom to v2.16.0 (#5992) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- dependencyManagement/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index 366cefd0d56..6191b4388d3 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -8,7 +8,7 @@ val dependencyVersions = hashMapOf() rootProject.extra["versions"] = dependencyVersions val DEPENDENCY_BOMS = listOf( - "com.fasterxml.jackson:jackson-bom:2.15.3", + "com.fasterxml.jackson:jackson-bom:2.16.0", "com.google.guava:guava-bom:32.1.3-jre", "com.google.protobuf:protobuf-bom:3.25.0", "com.linecorp.armeria:armeria-bom:1.26.2", From 8e0f6124cf80681dd428e9587785fe7719dbb8ed Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 20 Nov 2023 14:19:03 -0600 Subject: [PATCH 104/901] Update dependency com.linecorp.armeria:armeria-bom to v1.26.3 (#5996) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- dependencyManagement/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index 6191b4388d3..ca9ec1b4c0e 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -11,7 +11,7 @@ val DEPENDENCY_BOMS = listOf( "com.fasterxml.jackson:jackson-bom:2.16.0", "com.google.guava:guava-bom:32.1.3-jre", "com.google.protobuf:protobuf-bom:3.25.0", - "com.linecorp.armeria:armeria-bom:1.26.2", + "com.linecorp.armeria:armeria-bom:1.26.3", "com.squareup.okhttp3:okhttp-bom:4.12.0", "com.squareup.okio:okio-bom:3.6.0", // applies to transitive dependencies of okhttp "io.grpc:grpc-bom:1.59.0", From 9a01f2e5927012e9a3ed21b7e82593c9de585208 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 20 Nov 2023 14:19:39 -0600 Subject: [PATCH 105/901] Update dependency org.owasp:dependency-check-gradle to v8.4.3 (#5988) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- buildSrc/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts index d603d71b69b..b6dcd8f3062 100644 --- a/buildSrc/build.gradle.kts +++ b/buildSrc/build.gradle.kts @@ -58,7 +58,7 @@ dependencies { implementation("net.ltgt.gradle:gradle-errorprone-plugin:3.1.0") implementation("net.ltgt.gradle:gradle-nullaway-plugin:1.6.0") implementation("org.jetbrains.kotlin:kotlin-gradle-plugin:1.9.20") - implementation("org.owasp:dependency-check-gradle:8.4.2") + implementation("org.owasp:dependency-check-gradle:8.4.3") implementation("ru.vyarus:gradle-animalsniffer-plugin:1.7.1") } From a33de86cb63a68b9ccc7e332ca21fea54731d89e Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 20 Nov 2023 14:19:58 -0600 Subject: [PATCH 106/901] Update dependency org.testcontainers:testcontainers-bom to v1.19.2 (#5989) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- dependencyManagement/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index ca9ec1b4c0e..baac712d27d 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -20,7 +20,7 @@ val DEPENDENCY_BOMS = listOf( "io.zipkin.reporter2:zipkin-reporter-bom:2.16.4", "org.assertj:assertj-bom:3.24.2", "org.junit:junit-bom:5.10.1", - "org.testcontainers:testcontainers-bom:1.19.1", + "org.testcontainers:testcontainers-bom:1.19.2", "org.snakeyaml:snakeyaml-engine:2.7" ) From 34cd3f9342ece98090d72d99b4ee4994ee2f33c0 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 20 Nov 2023 14:20:11 -0600 Subject: [PATCH 107/901] Update dependency checkstyle to v10.12.5 (#5985) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- buildSrc/src/main/kotlin/otel.java-conventions.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/buildSrc/src/main/kotlin/otel.java-conventions.gradle.kts b/buildSrc/src/main/kotlin/otel.java-conventions.gradle.kts index 43791644017..910702266cf 100644 --- a/buildSrc/src/main/kotlin/otel.java-conventions.gradle.kts +++ b/buildSrc/src/main/kotlin/otel.java-conventions.gradle.kts @@ -35,7 +35,7 @@ java { checkstyle { configDirectory.set(file("$rootDir/buildscripts/")) - toolVersion = "10.12.4" + toolVersion = "10.12.5" isIgnoreFailures = false configProperties["rootDir"] = rootDir } From e2dd3e4404681d17cdde48a240ac363547c049c6 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 20 Nov 2023 15:35:48 -0600 Subject: [PATCH 108/901] Update dependency com.google.protobuf:protobuf-bom to v3.25.1 (#5991) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- dependencyManagement/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index baac712d27d..8e7a8d1b140 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -10,7 +10,7 @@ rootProject.extra["versions"] = dependencyVersions val DEPENDENCY_BOMS = listOf( "com.fasterxml.jackson:jackson-bom:2.16.0", "com.google.guava:guava-bom:32.1.3-jre", - "com.google.protobuf:protobuf-bom:3.25.0", + "com.google.protobuf:protobuf-bom:3.25.1", "com.linecorp.armeria:armeria-bom:1.26.3", "com.squareup.okhttp3:okhttp-bom:4.12.0", "com.squareup.okio:okio-bom:3.6.0", // applies to transitive dependencies of okhttp From e6c7a0f264569a514df3caba0b7f59f80c4ba3d2 Mon Sep 17 00:00:00 2001 From: jack-berg <34418638+jack-berg@users.noreply.github.com> Date: Tue, 21 Nov 2023 10:02:53 -0600 Subject: [PATCH 109/901] Base64 encode AnyValue bytes in string representation (#6003) --- .../extension/incubator/logs/AnyValueBytes.java | 8 ++------ .../extension/incubator/logs/AnyValueTest.java | 9 ++++----- .../java/io/opentelemetry/sdk/logs/AnyValueBodyTest.java | 4 ++-- 3 files changed, 8 insertions(+), 13 deletions(-) diff --git a/extensions/incubator/src/main/java/io/opentelemetry/extension/incubator/logs/AnyValueBytes.java b/extensions/incubator/src/main/java/io/opentelemetry/extension/incubator/logs/AnyValueBytes.java index 1677a3313e8..65697978dec 100644 --- a/extensions/incubator/src/main/java/io/opentelemetry/extension/incubator/logs/AnyValueBytes.java +++ b/extensions/incubator/src/main/java/io/opentelemetry/extension/incubator/logs/AnyValueBytes.java @@ -5,9 +5,9 @@ package io.opentelemetry.extension.incubator.logs; -import io.opentelemetry.api.internal.OtelEncodingUtils; import java.nio.ByteBuffer; import java.util.Arrays; +import java.util.Base64; import java.util.Objects; final class AnyValueBytes implements AnyValue { @@ -35,11 +35,7 @@ public ByteBuffer getValue() { @Override public String asString() { - // TODO: base64 would be better, but isn't available in android and java. Can we vendor in a - // base64 implementation? - char[] arr = new char[raw.length * 2]; - OtelEncodingUtils.bytesToBase16(raw, arr, raw.length); - return new String(arr); + return Base64.getEncoder().encodeToString(raw); } @Override diff --git a/extensions/incubator/src/test/java/io/opentelemetry/extension/incubator/logs/AnyValueTest.java b/extensions/incubator/src/test/java/io/opentelemetry/extension/incubator/logs/AnyValueTest.java index 842cd505c61..900cdd24c93 100644 --- a/extensions/incubator/src/test/java/io/opentelemetry/extension/incubator/logs/AnyValueTest.java +++ b/extensions/incubator/src/test/java/io/opentelemetry/extension/incubator/logs/AnyValueTest.java @@ -9,11 +9,11 @@ import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.junit.jupiter.params.provider.Arguments.arguments; -import io.opentelemetry.api.internal.OtelEncodingUtils; import java.nio.ByteBuffer; import java.nio.ReadOnlyBufferException; import java.nio.charset.StandardCharsets; import java.util.Arrays; +import java.util.Base64; import java.util.Collections; import java.util.LinkedHashMap; import java.util.Map; @@ -208,16 +208,15 @@ private static Stream asStringArgs() { AnyValue.of(Collections.singletonMap("grandchild", AnyValue.of("str"))))), "[child=[grandchild=str]]"), // bytes - arguments( - AnyValue.of("hello world".getBytes(StandardCharsets.UTF_8)), "68656c6c6f20776f726c64")); + arguments(AnyValue.of("hello world".getBytes(StandardCharsets.UTF_8)), "aGVsbG8gd29ybGQ=")); } @Test void anyValueByteAsString() { // TODO: add more test cases String str = "hello world"; - String base16Encoded = AnyValue.of(str.getBytes(StandardCharsets.UTF_8)).asString(); - byte[] decodedBytes = OtelEncodingUtils.bytesFromBase16(base16Encoded, base16Encoded.length()); + String base64Encoded = AnyValue.of(str.getBytes(StandardCharsets.UTF_8)).asString(); + byte[] decodedBytes = Base64.getDecoder().decode(base64Encoded); assertThat(new String(decodedBytes, StandardCharsets.UTF_8)).isEqualTo(str); } } diff --git a/sdk/logs/src/test/java/io/opentelemetry/sdk/logs/AnyValueBodyTest.java b/sdk/logs/src/test/java/io/opentelemetry/sdk/logs/AnyValueBodyTest.java index e793dc513d0..0345ecbd2fa 100644 --- a/sdk/logs/src/test/java/io/opentelemetry/sdk/logs/AnyValueBodyTest.java +++ b/sdk/logs/src/test/java/io/opentelemetry/sdk/logs/AnyValueBodyTest.java @@ -54,7 +54,7 @@ void anyValueBody() { logRecordData -> { // TODO (jack-berg): add assertion when ANY_VALUE is added to Body.Type // assertThat(logRecordData.getBody().getType()).isEqualTo(Body.Type.ANY_VALUE); - assertThat(logRecordData.getBody().asString()).isEqualTo("68656c6c6f20776f726c64"); + assertThat(logRecordData.getBody().asString()).isEqualTo("aGVsbG8gd29ybGQ="); assertThat(((AnyValueBody) logRecordData.getBody()).asAnyValue()) .isEqualTo(AnyValue.of("hello world".getBytes(StandardCharsets.UTF_8))); }); @@ -104,7 +104,7 @@ void anyValueBody() { + "bool_key=true, " + "long_key=1, " + "double_key=1.1, " - + "bytes_key=6279746573, " + + "bytes_key=Ynl0ZXM=, " + "arr_key=[entry1, 2, 3.3], " + "key_value_list_key=[child_str_key1=child_value1, child_str_key2=child_value2]" + "]"); From 1e82b72f36d847e743a525ae8767a6badd8deb81 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 21 Nov 2023 13:15:23 -0600 Subject: [PATCH 110/901] Update dependency org.testcontainers:testcontainers-bom to v1.19.3 (#6005) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- dependencyManagement/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index 8e7a8d1b140..9ffb3b0ba8c 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -20,7 +20,7 @@ val DEPENDENCY_BOMS = listOf( "io.zipkin.reporter2:zipkin-reporter-bom:2.16.4", "org.assertj:assertj-bom:3.24.2", "org.junit:junit-bom:5.10.1", - "org.testcontainers:testcontainers-bom:1.19.2", + "org.testcontainers:testcontainers-bom:1.19.3", "org.snakeyaml:snakeyaml-engine:2.7" ) From ad7fc9e75366747c3984e4480fce02a087bf6b48 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 22 Nov 2023 14:19:35 -0600 Subject: [PATCH 111/901] Update dependency org.owasp:dependency-check-gradle to v9 (#6007) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- buildSrc/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts index b6dcd8f3062..23fb30ddd79 100644 --- a/buildSrc/build.gradle.kts +++ b/buildSrc/build.gradle.kts @@ -58,7 +58,7 @@ dependencies { implementation("net.ltgt.gradle:gradle-errorprone-plugin:3.1.0") implementation("net.ltgt.gradle:gradle-nullaway-plugin:1.6.0") implementation("org.jetbrains.kotlin:kotlin-gradle-plugin:1.9.20") - implementation("org.owasp:dependency-check-gradle:8.4.3") + implementation("org.owasp:dependency-check-gradle:9.0.0") implementation("ru.vyarus:gradle-animalsniffer-plugin:1.7.1") } From 28ff59de414774a078d0072418c61f4f6d6fd5c2 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 23 Nov 2023 08:36:18 -0600 Subject: [PATCH 112/901] Update plugin org.graalvm.buildtools.native to v0.9.28 (#5793) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Co-authored-by: Jack Berg --- integration-tests/graal/build.gradle.kts | 14 ++++++++++++++ settings.gradle.kts | 2 +- 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/integration-tests/graal/build.gradle.kts b/integration-tests/graal/build.gradle.kts index 41404ddfc8d..cb39297a76a 100644 --- a/integration-tests/graal/build.gradle.kts +++ b/integration-tests/graal/build.gradle.kts @@ -19,6 +19,20 @@ dependencies { implementation(project(path = ":sdk:trace-shaded-deps")) } +// org.graalvm.buildtools.native pluging requires java 11+ as of version 0.9.26 +// https://github.com/graalvm/native-build-tools/blob/master/docs/src/docs/asciidoc/index.adoc +tasks { + withType().configureEach { + sourceCompatibility = "11" + targetCompatibility = "11" + options.release.set(11) + } + withType().configureEach { + val testJavaVersion: String? by project + enabled = !testJavaVersion.equals("8") + } +} + graalvmNative { binaries { named("test") { diff --git a/settings.gradle.kts b/settings.gradle.kts index 5599100fcd8..8e4fc690d1b 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -5,7 +5,7 @@ pluginManagement { id("de.undercouch.download") version "5.5.0" id("org.jsonschema2pojo") version "1.2.1" id("io.github.gradle-nexus.publish-plugin") version "1.3.0" - id("org.graalvm.buildtools.native") version "0.9.25" + id("org.graalvm.buildtools.native") version "0.9.28" } } From 675101a4eaf32c585e5af98c53dd2801009ed783 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 27 Nov 2023 12:35:02 -0600 Subject: [PATCH 113/901] Update dependency com.squareup.wire:wire-bom to v4.9.3 (#6009) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- buildSrc/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts index 23fb30ddd79..4b444e9f97c 100644 --- a/buildSrc/build.gradle.kts +++ b/buildSrc/build.gradle.kts @@ -42,7 +42,7 @@ repositories { } dependencies { - implementation(enforcedPlatform("com.squareup.wire:wire-bom:4.9.2")) + implementation(enforcedPlatform("com.squareup.wire:wire-bom:4.9.3")) implementation("com.google.auto.value:auto-value-annotations:1.10.4") // When updating, update above in plugins too implementation("com.diffplug.spotless:spotless-plugin-gradle:6.22.0") From 3382073239d4a070568f2483766ac22f842326ef Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 27 Nov 2023 12:35:23 -0600 Subject: [PATCH 114/901] Update dependency org.owasp:dependency-check-gradle to v9.0.1 (#6012) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- buildSrc/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts index 4b444e9f97c..158cb9dcf85 100644 --- a/buildSrc/build.gradle.kts +++ b/buildSrc/build.gradle.kts @@ -58,7 +58,7 @@ dependencies { implementation("net.ltgt.gradle:gradle-errorprone-plugin:3.1.0") implementation("net.ltgt.gradle:gradle-nullaway-plugin:1.6.0") implementation("org.jetbrains.kotlin:kotlin-gradle-plugin:1.9.20") - implementation("org.owasp:dependency-check-gradle:9.0.0") + implementation("org.owasp:dependency-check-gradle:9.0.1") implementation("ru.vyarus:gradle-animalsniffer-plugin:1.7.1") } From 1dcea73ea894591e8ec58e883b4860ca9bc34b88 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 27 Nov 2023 12:36:40 -0600 Subject: [PATCH 115/901] Update dependency org.jctools:jctools-core to v4.0.2 (#6006) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- dependencyManagement/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index 9ffb3b0ba8c..bd272d830aa 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -74,7 +74,7 @@ val DEPENDENCIES = listOf( "org.awaitility:awaitility:4.2.0", "org.bouncycastle:bcpkix-jdk15on:1.70", "org.codehaus.mojo:animal-sniffer-annotations:1.23", - "org.jctools:jctools-core:4.0.1", + "org.jctools:jctools-core:4.0.2", "org.junit-pioneer:junit-pioneer:1.9.1", "org.skyscreamer:jsonassert:1.5.1", "com.android.tools:desugar_jdk_libs:2.0.4", From c57ca65f7f1455e2f9d72f3d2d626aaf2f2f9a81 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 27 Nov 2023 12:37:25 -0600 Subject: [PATCH 116/901] Update dependency com.toasttab.android:gummy-bears-api-21 to v0.7.0 (#6002) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- animal-sniffer-signature/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/animal-sniffer-signature/build.gradle.kts b/animal-sniffer-signature/build.gradle.kts index 2f835c559aa..fd5d486ff20 100644 --- a/animal-sniffer-signature/build.gradle.kts +++ b/animal-sniffer-signature/build.gradle.kts @@ -27,7 +27,7 @@ configurations.add(signatureJarClasspath) configurations.add(generatedSignature) dependencies { - signature("com.toasttab.android:gummy-bears-api-21:0.6.1@signature") + signature("com.toasttab.android:gummy-bears-api-21:0.7.0@signature") signatureJar("com.android.tools:desugar_jdk_libs") } From f9e0acba15ccbd494b228d69496ebb612ed6db21 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 27 Nov 2023 20:14:37 -0600 Subject: [PATCH 117/901] Update dependency org.jetbrains.kotlin:kotlin-gradle-plugin to v1.9.21 (#6008) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- buildSrc/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts index 158cb9dcf85..bcbd8fb1a70 100644 --- a/buildSrc/build.gradle.kts +++ b/buildSrc/build.gradle.kts @@ -57,7 +57,7 @@ dependencies { implementation("me.champeau.jmh:jmh-gradle-plugin:0.7.2") implementation("net.ltgt.gradle:gradle-errorprone-plugin:3.1.0") implementation("net.ltgt.gradle:gradle-nullaway-plugin:1.6.0") - implementation("org.jetbrains.kotlin:kotlin-gradle-plugin:1.9.20") + implementation("org.jetbrains.kotlin:kotlin-gradle-plugin:1.9.21") implementation("org.owasp:dependency-check-gradle:9.0.1") implementation("ru.vyarus:gradle-animalsniffer-plugin:1.7.1") } From da2cc9f0479fbc26f0ccbc317cd07c41787698f9 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 28 Nov 2023 09:41:54 -0600 Subject: [PATCH 118/901] Update dependency io.grpc:grpc-bom to v1.59.1 (#6021) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- dependencyManagement/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index bd272d830aa..fc328d0f1ae 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -14,7 +14,7 @@ val DEPENDENCY_BOMS = listOf( "com.linecorp.armeria:armeria-bom:1.26.3", "com.squareup.okhttp3:okhttp-bom:4.12.0", "com.squareup.okio:okio-bom:3.6.0", // applies to transitive dependencies of okhttp - "io.grpc:grpc-bom:1.59.0", + "io.grpc:grpc-bom:1.59.1", "io.netty:netty-bom:4.1.100.Final", "io.zipkin.brave:brave-bom:5.16.0", "io.zipkin.reporter2:zipkin-reporter-bom:2.16.4", From a7b2cc04fcfb14c670d090f5bb8f28e518580025 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 28 Nov 2023 10:23:41 -0600 Subject: [PATCH 119/901] Update dependency io.netty:netty-bom to v4.1.101.Final (#5970) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- dependencyManagement/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index fc328d0f1ae..1f097d61588 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -15,7 +15,7 @@ val DEPENDENCY_BOMS = listOf( "com.squareup.okhttp3:okhttp-bom:4.12.0", "com.squareup.okio:okio-bom:3.6.0", // applies to transitive dependencies of okhttp "io.grpc:grpc-bom:1.59.1", - "io.netty:netty-bom:4.1.100.Final", + "io.netty:netty-bom:4.1.101.Final", "io.zipkin.brave:brave-bom:5.16.0", "io.zipkin.reporter2:zipkin-reporter-bom:2.16.4", "org.assertj:assertj-bom:3.24.2", From 433ad9462d12132d3d74c4d1832cca946ffdd769 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 30 Nov 2023 10:07:46 -0600 Subject: [PATCH 120/901] Update plugin com.diffplug.spotless to v6.23.2 (#6014) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- buildSrc/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts index bcbd8fb1a70..542aba04e4e 100644 --- a/buildSrc/build.gradle.kts +++ b/buildSrc/build.gradle.kts @@ -2,7 +2,7 @@ plugins { `kotlin-dsl` // When updating, update below in dependencies too - id("com.diffplug.spotless") version "6.22.0" + id("com.diffplug.spotless") version "6.23.2" } if (!JavaVersion.current().isCompatibleWith(JavaVersion.VERSION_17)) { From 52958c8e91cc85e3b59e4c4fafe97170c5ba48e6 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 30 Nov 2023 10:09:35 -0600 Subject: [PATCH 121/901] Update dependency gradle to v8.5 (#6029) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- gradle/wrapper/gradle-wrapper.jar | Bin 63721 -> 43462 bytes gradle/wrapper/gradle-wrapper.properties | 4 ++-- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index 7f93135c49b765f8051ef9d0a6055ff8e46073d8..d64cd4917707c1f8861d8cb53dd15194d4248596 100644 GIT binary patch literal 43462 zcma&NWl&^owk(X(xVyW%ySuwf;qI=D6|RlDJ2cR^yEKh!@I- zp9QeisK*rlxC>+~7Dk4IxIRsKBHqdR9b3+fyL=ynHmIDe&|>O*VlvO+%z5;9Z$|DJ zb4dO}-R=MKr^6EKJiOrJdLnCJn>np?~vU-1sSFgPu;pthGwf}bG z(1db%xwr#x)r+`4AGu$j7~u2MpVs3VpLp|mx&;>`0p0vH6kF+D2CY0fVdQOZ@h;A` z{infNyvmFUiu*XG}RNMNwXrbec_*a3N=2zJ|Wh5z* z5rAX$JJR{#zP>KY**>xHTuw?|-Rg|o24V)74HcfVT;WtQHXlE+_4iPE8QE#DUm%x0 zEKr75ur~W%w#-My3Tj`hH6EuEW+8K-^5P62$7Sc5OK+22qj&Pd1;)1#4tKihi=~8C zHiQSst0cpri6%OeaR`PY>HH_;CPaRNty%WTm4{wDK8V6gCZlG@U3$~JQZ;HPvDJcT1V{ z?>H@13MJcCNe#5z+MecYNi@VT5|&UiN1D4ATT+%M+h4c$t;C#UAs3O_q=GxK0}8%8 z8J(_M9bayxN}69ex4dzM_P3oh@ZGREjVvn%%r7=xjkqxJP4kj}5tlf;QosR=%4L5y zWhgejO=vao5oX%mOHbhJ8V+SG&K5dABn6!WiKl{|oPkq(9z8l&Mm%(=qGcFzI=eLu zWc_oCLyf;hVlB@dnwY98?75B20=n$>u3b|NB28H0u-6Rpl((%KWEBOfElVWJx+5yg z#SGqwza7f}$z;n~g%4HDU{;V{gXIhft*q2=4zSezGK~nBgu9-Q*rZ#2f=Q}i2|qOp z!!y4p)4o=LVUNhlkp#JL{tfkhXNbB=Ox>M=n6soptJw-IDI|_$is2w}(XY>a=H52d z3zE$tjPUhWWS+5h=KVH&uqQS=$v3nRs&p$%11b%5qtF}S2#Pc`IiyBIF4%A!;AVoI zXU8-Rpv!DQNcF~(qQnyyMy=-AN~U>#&X1j5BLDP{?K!%h!;hfJI>$mdLSvktEr*89 zdJHvby^$xEX0^l9g$xW-d?J;L0#(`UT~zpL&*cEh$L|HPAu=P8`OQZV!-}l`noSp_ zQ-1$q$R-gDL)?6YaM!=8H=QGW$NT2SeZlb8PKJdc=F-cT@j7Xags+Pr*jPtlHFnf- zh?q<6;)27IdPc^Wdy-mX%2s84C1xZq9Xms+==F4);O`VUASmu3(RlgE#0+#giLh-& zcxm3_e}n4{%|X zJp{G_j+%`j_q5}k{eW&TlP}J2wtZ2^<^E(O)4OQX8FDp6RJq!F{(6eHWSD3=f~(h} zJXCf7=r<16X{pHkm%yzYI_=VDP&9bmI1*)YXZeB}F? z(%QsB5fo*FUZxK$oX~X^69;x~j7ms8xlzpt-T15e9}$4T-pC z6PFg@;B-j|Ywajpe4~bk#S6(fO^|mm1hKOPfA%8-_iGCfICE|=P_~e;Wz6my&)h_~ zkv&_xSAw7AZ%ThYF(4jADW4vg=oEdJGVOs>FqamoL3Np8>?!W#!R-0%2Bg4h?kz5I zKV-rKN2n(vUL%D<4oj@|`eJ>0i#TmYBtYmfla;c!ATW%;xGQ0*TW@PTlGG><@dxUI zg>+3SiGdZ%?5N=8uoLA|$4isK$aJ%i{hECP$bK{J#0W2gQ3YEa zZQ50Stn6hqdfxJ*9#NuSLwKFCUGk@c=(igyVL;;2^wi4o30YXSIb2g_ud$ zgpCr@H0qWtk2hK8Q|&wx)}4+hTYlf;$a4#oUM=V@Cw#!$(nOFFpZ;0lc!qd=c$S}Z zGGI-0jg~S~cgVT=4Vo)b)|4phjStD49*EqC)IPwyeKBLcN;Wu@Aeph;emROAwJ-0< z_#>wVm$)ygH|qyxZaet&(Vf%pVdnvKWJn9`%DAxj3ot;v>S$I}jJ$FLBF*~iZ!ZXE zkvui&p}fI0Y=IDX)mm0@tAd|fEHl~J&K}ZX(Mm3cm1UAuwJ42+AO5@HwYfDH7ipIc zmI;1J;J@+aCNG1M`Btf>YT>~c&3j~Qi@Py5JT6;zjx$cvOQW@3oQ>|}GH?TW-E z1R;q^QFjm5W~7f}c3Ww|awg1BAJ^slEV~Pk`Kd`PS$7;SqJZNj->it4DW2l15}xP6 zoCl$kyEF%yJni0(L!Z&14m!1urXh6Btj_5JYt1{#+H8w?5QI%% zo-$KYWNMJVH?Hh@1n7OSu~QhSswL8x0=$<8QG_zepi_`y_79=nK=_ZP_`Em2UI*tyQoB+r{1QYZCpb?2OrgUw#oRH$?^Tj!Req>XiE#~B|~ z+%HB;=ic+R@px4Ld8mwpY;W^A%8%l8$@B@1m5n`TlKI6bz2mp*^^^1mK$COW$HOfp zUGTz-cN9?BGEp}5A!mDFjaiWa2_J2Iq8qj0mXzk; z66JBKRP{p%wN7XobR0YjhAuW9T1Gw3FDvR5dWJ8ElNYF94eF3ebu+QwKjtvVu4L zI9ip#mQ@4uqVdkl-TUQMb^XBJVLW(-$s;Nq;@5gr4`UfLgF$adIhd?rHOa%D);whv z=;krPp~@I+-Z|r#s3yCH+c1US?dnm+C*)r{m+86sTJusLdNu^sqLrfWed^ndHXH`m zd3#cOe3>w-ga(Dus_^ppG9AC>Iq{y%%CK+Cro_sqLCs{VLuK=dev>OL1dis4(PQ5R zcz)>DjEkfV+MO;~>VUlYF00SgfUo~@(&9$Iy2|G0T9BSP?&T22>K46D zL*~j#yJ?)^*%J3!16f)@Y2Z^kS*BzwfAQ7K96rFRIh>#$*$_Io;z>ux@}G98!fWR@ zGTFxv4r~v)Gsd|pF91*-eaZ3Qw1MH$K^7JhWIdX%o$2kCbvGDXy)a?@8T&1dY4`;L z4Kn+f%SSFWE_rpEpL9bnlmYq`D!6F%di<&Hh=+!VI~j)2mfil03T#jJ_s?}VV0_hp z7T9bWxc>Jm2Z0WMU?`Z$xE74Gu~%s{mW!d4uvKCx@WD+gPUQ zV0vQS(Ig++z=EHN)BR44*EDSWIyT~R4$FcF*VEY*8@l=218Q05D2$|fXKFhRgBIEE zdDFB}1dKkoO^7}{5crKX!p?dZWNz$m>1icsXG2N+((x0OIST9Zo^DW_tytvlwXGpn zs8?pJXjEG;T@qrZi%#h93?FP$!&P4JA(&H61tqQi=opRzNpm zkrG}$^t9&XduK*Qa1?355wd8G2CI6QEh@Ua>AsD;7oRUNLPb76m4HG3K?)wF~IyS3`fXuNM>${?wmB zpVz;?6_(Fiadfd{vUCBM*_kt$+F3J+IojI;9L(gc9n3{sEZyzR9o!_mOwFC#tQ{Q~ zP3-`#uK#tP3Q7~Q;4H|wjZHO8h7e4IuBxl&vz2w~D8)w=Wtg31zpZhz%+kzSzL*dV zwp@{WU4i;hJ7c2f1O;7Mz6qRKeASoIv0_bV=i@NMG*l<#+;INk-^`5w@}Dj~;k=|}qM1vq_P z|GpBGe_IKq|LNy9SJhKOQ$c=5L{Dv|Q_lZl=-ky*BFBJLW9&y_C|!vyM~rQx=!vun z?rZJQB5t}Dctmui5i31C_;_}CEn}_W%>oSXtt>@kE1=JW*4*v4tPp;O6 zmAk{)m!)}34pTWg8{i>($%NQ(Tl;QC@J@FfBoc%Gr&m560^kgSfodAFrIjF}aIw)X zoXZ`@IsMkc8_=w%-7`D6Y4e*CG8k%Ud=GXhsTR50jUnm+R*0A(O3UKFg0`K;qp1bl z7``HN=?39ic_kR|^R^~w-*pa?Vj#7|e9F1iRx{GN2?wK!xR1GW!qa=~pjJb-#u1K8 zeR?Y2i-pt}yJq;SCiVHODIvQJX|ZJaT8nO+(?HXbLefulKKgM^B(UIO1r+S=7;kLJ zcH}1J=Px2jsh3Tec&v8Jcbng8;V-`#*UHt?hB(pmOipKwf3Lz8rG$heEB30Sg*2rx zV<|KN86$soN(I!BwO`1n^^uF2*x&vJ$2d$>+`(romzHP|)K_KkO6Hc>_dwMW-M(#S zK(~SiXT1@fvc#U+?|?PniDRm01)f^#55;nhM|wi?oG>yBsa?~?^xTU|fX-R(sTA+5 zaq}-8Tx7zrOy#3*JLIIVsBmHYLdD}!0NP!+ITW+Thn0)8SS!$@)HXwB3tY!fMxc#1 zMp3H?q3eD?u&Njx4;KQ5G>32+GRp1Ee5qMO0lZjaRRu&{W<&~DoJNGkcYF<5(Ab+J zgO>VhBl{okDPn78<%&e2mR{jwVCz5Og;*Z;;3%VvoGo_;HaGLWYF7q#jDX=Z#Ml`H z858YVV$%J|e<1n`%6Vsvq7GmnAV0wW4$5qQ3uR@1i>tW{xrl|ExywIc?fNgYlA?C5 zh$ezAFb5{rQu6i7BSS5*J-|9DQ{6^BVQ{b*lq`xS@RyrsJN?-t=MTMPY;WYeKBCNg z^2|pN!Q^WPJuuO4!|P@jzt&tY1Y8d%FNK5xK(!@`jO2aEA*4 zkO6b|UVBipci?){-Ke=+1;mGlND8)6+P;8sq}UXw2hn;fc7nM>g}GSMWu&v&fqh

    iViYT=fZ(|3Ox^$aWPp4a8h24tD<|8-!aK0lHgL$N7Efw}J zVIB!7=T$U`ao1?upi5V4Et*-lTG0XvExbf!ya{cua==$WJyVG(CmA6Of*8E@DSE%L z`V^$qz&RU$7G5mg;8;=#`@rRG`-uS18$0WPN@!v2d{H2sOqP|!(cQ@ zUHo!d>>yFArLPf1q`uBvY32miqShLT1B@gDL4XoVTK&@owOoD)OIHXrYK-a1d$B{v zF^}8D3Y^g%^cnvScOSJR5QNH+BI%d|;J;wWM3~l>${fb8DNPg)wrf|GBP8p%LNGN# z3EaIiItgwtGgT&iYCFy9-LG}bMI|4LdmmJt@V@% zb6B)1kc=T)(|L@0;wr<>=?r04N;E&ef+7C^`wPWtyQe(*pD1pI_&XHy|0gIGHMekd zF_*M4yi6J&Z4LQj65)S zXwdM{SwUo%3SbPwFsHgqF@V|6afT|R6?&S;lw=8% z3}@9B=#JI3@B*#4s!O))~z zc>2_4Q_#&+5V`GFd?88^;c1i7;Vv_I*qt!_Yx*n=;rj!82rrR2rQ8u5(Ejlo{15P% zs~!{%XJ>FmJ})H^I9bn^Re&38H{xA!0l3^89k(oU;bZWXM@kn$#aoS&Y4l^-WEn-fH39Jb9lA%s*WsKJQl?n9B7_~P z-XM&WL7Z!PcoF6_D>V@$CvUIEy=+Z&0kt{szMk=f1|M+r*a43^$$B^MidrT0J;RI` z(?f!O<8UZkm$_Ny$Hth1J#^4ni+im8M9mr&k|3cIgwvjAgjH z8`N&h25xV#v*d$qBX5jkI|xOhQn!>IYZK7l5#^P4M&twe9&Ey@@GxYMxBZq2e7?`q z$~Szs0!g{2fGcp9PZEt|rdQ6bhAgpcLHPz?f-vB?$dc*!9OL?Q8mn7->bFD2Si60* z!O%y)fCdMSV|lkF9w%x~J*A&srMyYY3{=&$}H zGQ4VG_?$2X(0|vT0{=;W$~icCI{b6W{B!Q8xdGhF|D{25G_5_+%s(46lhvNLkik~R z>nr(&C#5wwOzJZQo9m|U<;&Wk!_#q|V>fsmj1g<6%hB{jGoNUPjgJslld>xmODzGjYc?7JSuA?A_QzjDw5AsRgi@Y|Z0{F{!1=!NES-#*f^s4l0Hu zz468))2IY5dmD9pa*(yT5{EyP^G>@ZWumealS-*WeRcZ}B%gxq{MiJ|RyX-^C1V=0 z@iKdrGi1jTe8Ya^x7yyH$kBNvM4R~`fbPq$BzHum-3Zo8C6=KW@||>zsA8-Y9uV5V z#oq-f5L5}V<&wF4@X@<3^C%ptp6+Ce)~hGl`kwj)bsAjmo_GU^r940Z-|`<)oGnh7 zFF0Tde3>ui?8Yj{sF-Z@)yQd~CGZ*w-6p2U<8}JO-sRsVI5dBji`01W8A&3$?}lxBaC&vn0E$c5tW* zX>5(zzZ=qn&!J~KdsPl;P@bmA-Pr8T*)eh_+Dv5=Ma|XSle6t(k8qcgNyar{*ReQ8 zTXwi=8vr>!3Ywr+BhggHDw8ke==NTQVMCK`$69fhzEFB*4+H9LIvdt-#IbhZvpS}} zO3lz;P?zr0*0$%-Rq_y^k(?I{Mk}h@w}cZpMUp|ucs55bcloL2)($u%mXQw({Wzc~ z;6nu5MkjP)0C(@%6Q_I_vsWrfhl7Zpoxw#WoE~r&GOSCz;_ro6i(^hM>I$8y>`!wW z*U^@?B!MMmb89I}2(hcE4zN2G^kwyWCZp5JG>$Ez7zP~D=J^LMjSM)27_0B_X^C(M z`fFT+%DcKlu?^)FCK>QzSnV%IsXVcUFhFdBP!6~se&xxrIxsvySAWu++IrH;FbcY$ z2DWTvSBRfLwdhr0nMx+URA$j3i7_*6BWv#DXfym?ZRDcX9C?cY9sD3q)uBDR3uWg= z(lUIzB)G$Hr!){>E{s4Dew+tb9kvToZp-1&c?y2wn@Z~(VBhqz`cB;{E4(P3N2*nJ z_>~g@;UF2iG{Kt(<1PyePTKahF8<)pozZ*xH~U-kfoAayCwJViIrnqwqO}7{0pHw$ zs2Kx?s#vQr7XZ264>5RNKSL8|Ty^=PsIx^}QqOOcfpGUU4tRkUc|kc7-!Ae6!+B{o~7nFpm3|G5^=0#Bnm6`V}oSQlrX(u%OWnC zoLPy&Q;1Jui&7ST0~#+}I^&?vcE*t47~Xq#YwvA^6^} z`WkC)$AkNub|t@S!$8CBlwbV~?yp&@9h{D|3z-vJXgzRC5^nYm+PyPcgRzAnEi6Q^gslXYRv4nycsy-SJu?lMps-? zV`U*#WnFsdPLL)Q$AmD|0`UaC4ND07+&UmOu!eHruzV|OUox<+Jl|Mr@6~C`T@P%s zW7sgXLF2SSe9Fl^O(I*{9wsFSYb2l%-;&Pi^dpv!{)C3d0AlNY6!4fgmSgj_wQ*7Am7&$z;Jg&wgR-Ih;lUvWS|KTSg!&s_E9_bXBkZvGiC6bFKDWZxsD$*NZ#_8bl zG1P-#@?OQzED7@jlMJTH@V!6k;W>auvft)}g zhoV{7$q=*;=l{O>Q4a@ ziMjf_u*o^PsO)#BjC%0^h>Xp@;5$p{JSYDt)zbb}s{Kbt!T*I@Pk@X0zds6wsefuU zW$XY%yyRGC94=6mf?x+bbA5CDQ2AgW1T-jVAJbm7K(gp+;v6E0WI#kuACgV$r}6L? zd|Tj?^%^*N&b>Dd{Wr$FS2qI#Ucs1yd4N+RBUQiSZGujH`#I)mG&VKoDh=KKFl4=G z&MagXl6*<)$6P}*Tiebpz5L=oMaPrN+caUXRJ`D?=K9!e0f{@D&cZLKN?iNP@X0aF zE(^pl+;*T5qt?1jRC=5PMgV!XNITRLS_=9{CJExaQj;lt!&pdzpK?8p>%Mb+D z?yO*uSung=-`QQ@yX@Hyd4@CI^r{2oiu`%^bNkz+Nkk!IunjwNC|WcqvX~k=><-I3 zDQdbdb|!v+Iz01$w@aMl!R)koD77Xp;eZwzSl-AT zr@Vu{=xvgfq9akRrrM)}=!=xcs+U1JO}{t(avgz`6RqiiX<|hGG1pmop8k6Q+G_mv zJv|RfDheUp2L3=^C=4aCBMBn0aRCU(DQwX-W(RkRwmLeuJYF<0urcaf(=7)JPg<3P zQs!~G)9CT18o!J4{zX{_e}4eS)U-E)0FAt}wEI(c0%HkxgggW;(1E=>J17_hsH^sP z%lT0LGgbUXHx-K*CI-MCrP66UP0PvGqM$MkeLyqHdbgP|_Cm!7te~b8p+e6sQ_3k| zVcwTh6d83ltdnR>D^)BYQpDKlLk3g0Hdcgz2}%qUs9~~Rie)A-BV1mS&naYai#xcZ z(d{8=-LVpTp}2*y)|gR~;qc7fp26}lPcLZ#=JpYcn3AT9(UIdOyg+d(P5T7D&*P}# zQCYplZO5|7+r19%9e`v^vfSS1sbX1c%=w1;oyruXB%Kl$ACgKQ6=qNWLsc=28xJjg zwvsI5-%SGU|3p>&zXVl^vVtQT3o-#$UT9LI@Npz~6=4!>mc431VRNN8od&Ul^+G_kHC`G=6WVWM z%9eWNyy(FTO|A+@x}Ou3CH)oi;t#7rAxdIXfNFwOj_@Y&TGz6P_sqiB`Q6Lxy|Q{`|fgmRG(k+!#b*M+Z9zFce)f-7;?Km5O=LHV9f9_87; zF7%R2B+$?@sH&&-$@tzaPYkw0;=i|;vWdI|Wl3q_Zu>l;XdIw2FjV=;Mq5t1Q0|f< zs08j54Bp`3RzqE=2enlkZxmX6OF+@|2<)A^RNQpBd6o@OXl+i)zO%D4iGiQNuXd+zIR{_lb96{lc~bxsBveIw6umhShTX+3@ZJ=YHh@ zWY3(d0azg;7oHn>H<>?4@*RQbi>SmM=JrHvIG(~BrvI)#W(EAeO6fS+}mxxcc+X~W6&YVl86W9WFSS}Vz-f9vS?XUDBk)3TcF z8V?$4Q)`uKFq>xT=)Y9mMFVTUk*NIA!0$?RP6Ig0TBmUFrq*Q-Agq~DzxjStQyJ({ zBeZ;o5qUUKg=4Hypm|}>>L=XKsZ!F$yNTDO)jt4H0gdQ5$f|d&bnVCMMXhNh)~mN z@_UV6D7MVlsWz+zM+inZZp&P4fj=tm6fX)SG5H>OsQf_I8c~uGCig$GzuwViK54bcgL;VN|FnyQl>Ed7(@>=8$a_UKIz|V6CeVSd2(P z0Uu>A8A+muM%HLFJQ9UZ5c)BSAv_zH#1f02x?h9C}@pN@6{>UiAp>({Fn(T9Q8B z^`zB;kJ5b`>%dLm+Ol}ty!3;8f1XDSVX0AUe5P#@I+FQ-`$(a;zNgz)4x5hz$Hfbg z!Q(z26wHLXko(1`;(BAOg_wShpX0ixfWq3ponndY+u%1gyX)_h=v1zR#V}#q{au6; z!3K=7fQwnRfg6FXtNQmP>`<;!N137paFS%y?;lb1@BEdbvQHYC{976l`cLqn;b8lp zIDY>~m{gDj(wfnK!lpW6pli)HyLEiUrNc%eXTil|F2s(AY+LW5hkKb>TQ3|Q4S9rr zpDs4uK_co6XPsn_z$LeS{K4jFF`2>U`tbgKdyDne`xmR<@6AA+_hPNKCOR-Zqv;xk zu5!HsBUb^!4uJ7v0RuH-7?l?}b=w5lzzXJ~gZcxRKOovSk@|#V+MuX%Y+=;14i*%{)_gSW9(#4%)AV#3__kac1|qUy!uyP{>?U#5wYNq}y$S9pCc zFc~4mgSC*G~j0u#qqp9 z${>3HV~@->GqEhr_Xwoxq?Hjn#=s2;i~g^&Hn|aDKpA>Oc%HlW(KA1?BXqpxB;Ydx)w;2z^MpjJ(Qi(X!$5RC z*P{~%JGDQqojV>2JbEeCE*OEu!$XJ>bWA9Oa_Hd;y)F%MhBRi*LPcdqR8X`NQ&1L# z5#9L*@qxrx8n}LfeB^J{%-?SU{FCwiWyHp682F+|pa+CQa3ZLzBqN1{)h4d6+vBbV zC#NEbQLC;}me3eeYnOG*nXOJZEU$xLZ1<1Y=7r0(-U0P6-AqwMAM`a(Ed#7vJkn6plb4eI4?2y3yOTGmmDQ!z9`wzbf z_OY#0@5=bnep;MV0X_;;SJJWEf^E6Bd^tVJ9znWx&Ks8t*B>AM@?;D4oWUGc z!H*`6d7Cxo6VuyS4Eye&L1ZRhrRmN6Lr`{NL(wDbif|y&z)JN>Fl5#Wi&mMIr5i;x zBx}3YfF>>8EC(fYnmpu~)CYHuHCyr5*`ECap%t@y=jD>!_%3iiE|LN$mK9>- zHdtpy8fGZtkZF?%TW~29JIAfi2jZT8>OA7=h;8T{{k?c2`nCEx9$r zS+*&vt~2o^^J+}RDG@+9&M^K*z4p{5#IEVbz`1%`m5c2};aGt=V?~vIM}ZdPECDI)47|CWBCfDWUbxBCnmYivQ*0Nu_xb*C>~C9(VjHM zxe<*D<#dQ8TlpMX2c@M<9$w!RP$hpG4cs%AI){jp*Sj|*`m)5(Bw*A0$*i-(CA5#%>a)$+jI2C9r6|(>J8InryENI z$NohnxDUB;wAYDwrb*!N3noBTKPpPN}~09SEL18tkG zxgz(RYU_;DPT{l?Q$+eaZaxnsWCA^ds^0PVRkIM%bOd|G2IEBBiz{&^JtNsODs;5z zICt_Zj8wo^KT$7Bg4H+y!Df#3mbl%%?|EXe!&(Vmac1DJ*y~3+kRKAD=Ovde4^^%~ zw<9av18HLyrf*_>Slp;^i`Uy~`mvBjZ|?Ad63yQa#YK`4+c6;pW4?XIY9G1(Xh9WO8{F-Aju+nS9Vmv=$Ac0ienZ+p9*O%NG zMZKy5?%Z6TAJTE?o5vEr0r>f>hb#2w2U3DL64*au_@P!J!TL`oH2r*{>ffu6|A7tv zL4juf$DZ1MW5ZPsG!5)`k8d8c$J$o;%EIL0va9&GzWvkS%ZsGb#S(?{!UFOZ9<$a| zY|a+5kmD5N&{vRqkgY>aHsBT&`rg|&kezoD)gP0fsNYHsO#TRc_$n6Lf1Z{?+DLziXlHrq4sf(!>O{?Tj;Eh@%)+nRE_2VxbN&&%%caU#JDU%vL3}Cb zsb4AazPI{>8H&d=jUaZDS$-0^AxE@utGs;-Ez_F(qC9T=UZX=>ok2k2 ziTn{K?y~a5reD2A)P${NoI^>JXn>`IeArow(41c-Wm~)wiryEP(OS{YXWi7;%dG9v zI?mwu1MxD{yp_rrk!j^cKM)dc4@p4Ezyo%lRN|XyD}}>v=Xoib0gOcdXrQ^*61HNj z=NP|pd>@yfvr-=m{8$3A8TQGMTE7g=z!%yt`8`Bk-0MMwW~h^++;qyUP!J~ykh1GO z(FZ59xuFR$(WE;F@UUyE@Sp>`aVNjyj=Ty>_Vo}xf`e7`F;j-IgL5`1~-#70$9_=uBMq!2&1l zomRgpD58@)YYfvLtPW}{C5B35R;ZVvB<<#)x%srmc_S=A7F@DW8>QOEGwD6suhwCg z>Pa+YyULhmw%BA*4yjDp|2{!T98~<6Yfd(wo1mQ!KWwq0eg+6)o1>W~f~kL<-S+P@$wx*zeI|1t7z#Sxr5 zt6w+;YblPQNplq4Z#T$GLX#j6yldXAqj>4gAnnWtBICUnA&-dtnlh=t0Ho_vEKwV` z)DlJi#!@nkYV#$!)@>udAU*hF?V`2$Hf=V&6PP_|r#Iv*J$9)pF@X3`k;5})9^o4y z&)~?EjX5yX12O(BsFy-l6}nYeuKkiq`u9145&3Ssg^y{5G3Pse z9w(YVa0)N-fLaBq1`P!_#>SS(8fh_5!f{UrgZ~uEdeMJIz7DzI5!NHHqQtm~#CPij z?=N|J>nPR6_sL7!f4hD_|KH`vf8(Wpnj-(gPWH+ZvID}%?~68SwhPTC3u1_cB`otq z)U?6qo!ZLi5b>*KnYHWW=3F!p%h1;h{L&(Q&{qY6)_qxNfbP6E3yYpW!EO+IW3?@J z);4>g4gnl^8klu7uA>eGF6rIGSynacogr)KUwE_R4E5Xzi*Qir@b-jy55-JPC8c~( zo!W8y9OGZ&`xmc8;=4-U9=h{vCqfCNzYirONmGbRQlR`WWlgnY+1wCXbMz&NT~9*| z6@FrzP!LX&{no2!Ln_3|I==_4`@}V?4a;YZKTdw;vT<+K+z=uWbW(&bXEaWJ^W8Td z-3&1bY^Z*oM<=M}LVt>_j+p=2Iu7pZmbXrhQ_k)ysE9yXKygFNw$5hwDn(M>H+e1&9BM5!|81vd%r%vEm zqxY3?F@fb6O#5UunwgAHR9jp_W2zZ}NGp2%mTW@(hz7$^+a`A?mb8|_G*GNMJ) zjqegXQio=i@AINre&%ofexAr95aop5C+0MZ0m-l=MeO8m3epm7U%vZB8+I+C*iNFM z#T3l`gknX;D$-`2XT^Cg*vrv=RH+P;_dfF++cP?B_msQI4j+lt&rX2)3GaJx%W*Nn zkML%D{z5tpHH=dksQ*gzc|}gzW;lwAbxoR07VNgS*-c3d&8J|;@3t^ zVUz*J*&r7DFRuFVDCJDK8V9NN5hvpgGjwx+5n)qa;YCKe8TKtdnh{I7NU9BCN!0dq zczrBk8pE{{@vJa9ywR@mq*J=v+PG;?fwqlJVhijG!3VmIKs>9T6r7MJpC)m!Tc#>g zMtVsU>wbwFJEfwZ{vB|ZlttNe83)$iz`~#8UJ^r)lJ@HA&G#}W&ZH*;k{=TavpjWE z7hdyLZPf*X%Gm}i`Y{OGeeu^~nB8=`{r#TUrM-`;1cBvEd#d!kPqIgYySYhN-*1;L z^byj%Yi}Gx)Wnkosi337BKs}+5H5dth1JA{Ir-JKN$7zC)*}hqeoD(WfaUDPT>0`- z(6sa0AoIqASwF`>hP}^|)a_j2s^PQn*qVC{Q}htR z5-)duBFXT_V56-+UohKXlq~^6uf!6sA#ttk1o~*QEy_Y-S$gAvq47J9Vtk$5oA$Ct zYhYJ@8{hsC^98${!#Ho?4y5MCa7iGnfz}b9jE~h%EAAv~Qxu)_rAV;^cygV~5r_~?l=B`zObj7S=H=~$W zPtI_m%g$`kL_fVUk9J@>EiBH zOO&jtn~&`hIFMS5S`g8w94R4H40mdNUH4W@@XQk1sr17b{@y|JB*G9z1|CrQjd+GX z6+KyURG3;!*BQrentw{B2R&@2&`2}n(z-2&X7#r!{yg@Soy}cRD~j zj9@UBW+N|4HW4AWapy4wfUI- zZ`gSL6DUlgj*f1hSOGXG0IVH8HxK?o2|3HZ;KW{K+yPAlxtb)NV_2AwJm|E)FRs&& z=c^e7bvUsztY|+f^k7NXs$o1EUq>cR7C0$UKi6IooHWlK_#?IWDkvywnzg&ThWo^? z2O_N{5X39#?eV9l)xI(>@!vSB{DLt*oY!K1R8}_?%+0^C{d9a%N4 zoxHVT1&Lm|uDX%$QrBun5e-F`HJ^T$ zmzv)p@4ZHd_w9!%Hf9UYNvGCw2TTTbrj9pl+T9%-_-}L(tES>Or-}Z4F*{##n3~L~TuxjirGuIY#H7{%$E${?p{Q01 zi6T`n;rbK1yIB9jmQNycD~yZq&mbIsFWHo|ZAChSFPQa<(%d8mGw*V3fh|yFoxOOiWJd(qvVb!Z$b88cg->N=qO*4k~6;R==|9ihg&riu#P~s4Oap9O7f%crSr^rljeIfXDEg>wi)&v*a%7zpz<9w z*r!3q9J|390x`Zk;g$&OeN&ctp)VKRpDSV@kU2Q>jtok($Y-*x8_$2piTxun81@vt z!Vj?COa0fg2RPXMSIo26T=~0d`{oGP*eV+$!0I<(4azk&Vj3SiG=Q!6mX0p$z7I}; z9BJUFgT-K9MQQ-0@Z=^7R<{bn2Fm48endsSs`V7_@%8?Bxkqv>BDoVcj?K#dV#uUP zL1ND~?D-|VGKe3Rw_7-Idpht>H6XRLh*U7epS6byiGvJpr%d}XwfusjH9g;Z98H`x zyde%%5mhGOiL4wljCaWCk-&uE4_OOccb9c!ZaWt4B(wYl!?vyzl%7n~QepN&eFUrw zFIOl9c({``6~QD+43*_tzP{f2x41h(?b43^y6=iwyB)2os5hBE!@YUS5?N_tXd=h( z)WE286Fbd>R4M^P{!G)f;h<3Q>Fipuy+d2q-)!RyTgt;wr$(?9ox3;q+{E*ZQHhOn;lM`cjnu9 zXa48ks-v(~b*;MAI<>YZH(^NV8vjb34beE<_cwKlJoR;k6lJNSP6v}uiyRD?|0w+X@o1ONrH8a$fCxXpf? z?$DL0)7|X}Oc%h^zrMKWc-NS9I0Utu@>*j}b@tJ=ixQSJ={4@854wzW@E>VSL+Y{i z#0b=WpbCZS>kUCO_iQz)LoE>P5LIG-hv9E+oG}DtlIDF>$tJ1aw9^LuhLEHt?BCj& z(O4I8v1s#HUi5A>nIS-JK{v!7dJx)^Yg%XjNmlkWAq2*cv#tHgz`Y(bETc6CuO1VkN^L-L3j_x<4NqYb5rzrLC-7uOv z!5e`GZt%B782C5-fGnn*GhDF$%(qP<74Z}3xx+{$4cYKy2ikxI7B2N+2r07DN;|-T->nU&!=Cm#rZt%O_5c&1Z%nlWq3TKAW0w zQqemZw_ue--2uKQsx+niCUou?HjD`xhEjjQd3%rrBi82crq*~#uA4+>vR<_S{~5ce z-2EIl?~s z1=GVL{NxP1N3%=AOaC}j_Fv=ur&THz zyO!d9kHq|c73kpq`$+t+8Bw7MgeR5~`d7ChYyGCBWSteTB>8WAU(NPYt2Dk`@#+}= zI4SvLlyk#pBgVigEe`?NG*vl7V6m+<}%FwPV=~PvvA)=#ths==DRTDEYh4V5}Cf$z@#;< zyWfLY_5sP$gc3LLl2x+Ii)#b2nhNXJ{R~vk`s5U7Nyu^3yFg&D%Txwj6QezMX`V(x z=C`{76*mNb!qHHs)#GgGZ_7|vkt9izl_&PBrsu@}L`X{95-2jf99K)0=*N)VxBX2q z((vkpP2RneSIiIUEnGb?VqbMb=Zia+rF~+iqslydE34cSLJ&BJW^3knX@M;t*b=EA zNvGzv41Ld_T+WT#XjDB840vovUU^FtN_)G}7v)1lPetgpEK9YS^OWFkPoE{ovj^=@ zO9N$S=G$1ecndT_=5ehth2Lmd1II-PuT~C9`XVePw$y8J#dpZ?Tss<6wtVglm(Ok7 z3?^oi@pPio6l&!z8JY(pJvG=*pI?GIOu}e^EB6QYk$#FJQ%^AIK$I4epJ+9t?KjqA+bkj&PQ*|vLttme+`9G=L% ziadyMw_7-M)hS(3E$QGNCu|o23|%O+VN7;Qggp?PB3K-iSeBa2b}V4_wY`G1Jsfz4 z9|SdB^;|I8E8gWqHKx!vj_@SMY^hLEIbSMCuE?WKq=c2mJK z8LoG-pnY!uhqFv&L?yEuxo{dpMTsmCn)95xanqBrNPTgXP((H$9N${Ow~Is-FBg%h z53;|Y5$MUN)9W2HBe2TD`ct^LHI<(xWrw}$qSoei?}s)&w$;&!14w6B6>Yr6Y8b)S z0r71`WmAvJJ`1h&poLftLUS6Ir zC$bG9!Im_4Zjse)#K=oJM9mHW1{%l8sz$1o?ltdKlLTxWWPB>Vk22czVt|1%^wnN@*!l)}?EgtvhC>vlHm^t+ogpgHI1_$1ox9e;>0!+b(tBrmXRB`PY1vp-R**8N7 zGP|QqI$m(Rdu#=(?!(N}G9QhQ%o!aXE=aN{&wtGP8|_qh+7a_j_sU5|J^)vxq;# zjvzLn%_QPHZZIWu1&mRAj;Sa_97p_lLq_{~j!M9N^1yp3U_SxRqK&JnR%6VI#^E12 z>CdOVI^_9aPK2eZ4h&^{pQs}xsijXgFYRIxJ~N7&BB9jUR1fm!(xl)mvy|3e6-B3j zJn#ajL;bFTYJ2+Q)tDjx=3IklO@Q+FFM}6UJr6km7hj7th9n_&JR7fnqC!hTZoM~T zBeaVFp%)0cbPhejX<8pf5HyRUj2>aXnXBqDJe73~J%P(2C?-RT{c3NjE`)om! zl$uewSgWkE66$Kb34+QZZvRn`fob~Cl9=cRk@Es}KQm=?E~CE%spXaMO6YmrMl%9Q zlA3Q$3|L1QJ4?->UjT&CBd!~ru{Ih^in&JXO=|<6J!&qp zRe*OZ*cj5bHYlz!!~iEKcuE|;U4vN1rk$xq6>bUWD*u(V@8sG^7>kVuo(QL@Ki;yL zWC!FT(q{E8#on>%1iAS0HMZDJg{Z{^!De(vSIq&;1$+b)oRMwA3nc3mdTSG#3uYO_ z>+x;7p4I;uHz?ZB>dA-BKl+t-3IB!jBRgdvAbW!aJ(Q{aT>+iz?91`C-xbe)IBoND z9_Xth{6?(y3rddwY$GD65IT#f3<(0o#`di{sh2gm{dw*#-Vnc3r=4==&PU^hCv$qd zjw;>i&?L*Wq#TxG$mFIUf>eK+170KG;~+o&1;Tom9}}mKo23KwdEM6UonXgc z!6N(@k8q@HPw{O8O!lAyi{rZv|DpgfU{py+j(X_cwpKqcalcqKIr0kM^%Br3SdeD> zHSKV94Yxw;pjzDHo!Q?8^0bb%L|wC;4U^9I#pd5O&eexX+Im{ z?jKnCcsE|H?{uGMqVie_C~w7GX)kYGWAg%-?8|N_1#W-|4F)3YTDC+QSq1s!DnOML3@d`mG%o2YbYd#jww|jD$gotpa)kntakp#K;+yo-_ZF9qrNZw<%#C zuPE@#3RocLgPyiBZ+R_-FJ_$xP!RzWm|aN)S+{$LY9vvN+IW~Kf3TsEIvP+B9Mtm! zpfNNxObWQpLoaO&cJh5>%slZnHl_Q~(-Tfh!DMz(dTWld@LG1VRF`9`DYKhyNv z2pU|UZ$#_yUx_B_|MxUq^glT}O5Xt(Vm4Mr02><%C)@v;vPb@pT$*yzJ4aPc_FZ3z z3}PLoMBIM>q_9U2rl^sGhk1VUJ89=*?7|v`{!Z{6bqFMq(mYiA?%KbsI~JwuqVA9$H5vDE+VocjX+G^%bieqx->s;XWlKcuv(s%y%D5Xbc9+ zc(_2nYS1&^yL*ey664&4`IoOeDIig}y-E~_GS?m;D!xv5-xwz+G`5l6V+}CpeJDi^ z%4ed$qowm88=iYG+(`ld5Uh&>Dgs4uPHSJ^TngXP_V6fPyl~>2bhi20QB%lSd#yYn zO05?KT1z@?^-bqO8Cg`;ft>ilejsw@2%RR7;`$Vs;FmO(Yr3Fp`pHGr@P2hC%QcA|X&N2Dn zYf`MqXdHi%cGR@%y7Rg7?d3?an){s$zA{!H;Ie5exE#c~@NhQUFG8V=SQh%UxUeiV zd7#UcYqD=lk-}sEwlpu&H^T_V0{#G?lZMxL7ih_&{(g)MWBnCZxtXg znr#}>U^6!jA%e}@Gj49LWG@*&t0V>Cxc3?oO7LSG%~)Y5}f7vqUUnQ;STjdDU}P9IF9d9<$;=QaXc zL1^X7>fa^jHBu_}9}J~#-oz3Oq^JmGR#?GO7b9a(=R@fw@}Q{{@`Wy1vIQ#Bw?>@X z-_RGG@wt|%u`XUc%W{J z>iSeiz8C3H7@St3mOr_mU+&bL#Uif;+Xw-aZdNYUpdf>Rvu0i0t6k*}vwU`XNO2he z%miH|1tQ8~ZK!zmL&wa3E;l?!!XzgV#%PMVU!0xrDsNNZUWKlbiOjzH-1Uoxm8E#r`#2Sz;-o&qcqB zC-O_R{QGuynW14@)7&@yw1U}uP(1cov)twxeLus0s|7ayrtT8c#`&2~Fiu2=R;1_4bCaD=*E@cYI>7YSnt)nQc zohw5CsK%m?8Ack)qNx`W0_v$5S}nO|(V|RZKBD+btO?JXe|~^Qqur%@eO~<8-L^9d z=GA3-V14ng9L29~XJ>a5k~xT2152zLhM*@zlp2P5Eu}bywkcqR;ISbas&#T#;HZSf z2m69qTV(V@EkY(1Dk3`}j)JMo%ZVJ*5eB zYOjIisi+igK0#yW*gBGj?@I{~mUOvRFQR^pJbEbzFxTubnrw(Muk%}jI+vXmJ;{Q6 zrSobKD>T%}jV4Ub?L1+MGOD~0Ir%-`iTnWZN^~YPrcP5y3VMAzQ+&en^VzKEb$K!Q z<7Dbg&DNXuow*eD5yMr+#08nF!;%4vGrJI++5HdCFcGLfMW!KS*Oi@=7hFwDG!h2< zPunUEAF+HncQkbfFj&pbzp|MU*~60Z(|Ik%Tn{BXMN!hZOosNIseT?R;A`W?=d?5X zK(FB=9mZusYahp|K-wyb={rOpdn=@;4YI2W0EcbMKyo~-#^?h`BA9~o285%oY zfifCh5Lk$SY@|2A@a!T2V+{^!psQkx4?x0HSV`(w9{l75QxMk!)U52Lbhn{8ol?S) zCKo*7R(z!uk<6*qO=wh!Pul{(qq6g6xW;X68GI_CXp`XwO zxuSgPRAtM8K7}5E#-GM!*ydOOG_{A{)hkCII<|2=ma*71ci_-}VPARm3crFQjLYV! z9zbz82$|l01mv`$WahE2$=fAGWkd^X2kY(J7iz}WGS z@%MyBEO=A?HB9=^?nX`@nh;7;laAjs+fbo!|K^mE!tOB>$2a_O0y-*uaIn8k^6Y zSbuv;5~##*4Y~+y7Z5O*3w4qgI5V^17u*ZeupVGH^nM&$qmAk|anf*>r zWc5CV;-JY-Z@Uq1Irpb^O`L_7AGiqd*YpGUShb==os$uN3yYvb`wm6d=?T*it&pDk zo`vhw)RZX|91^^Wa_ti2zBFyWy4cJu#g)_S6~jT}CC{DJ_kKpT`$oAL%b^!2M;JgT zM3ZNbUB?}kP(*YYvXDIH8^7LUxz5oE%kMhF!rnPqv!GiY0o}NR$OD=ITDo9r%4E>E0Y^R(rS^~XjWyVI6 zMOR5rPXhTp*G*M&X#NTL`Hu*R+u*QNoiOKg4CtNPrjgH>c?Hi4MUG#I917fx**+pJfOo!zFM&*da&G_x)L(`k&TPI*t3e^{crd zX<4I$5nBQ8Ax_lmNRa~E*zS-R0sxkz`|>7q_?*e%7bxqNm3_eRG#1ae3gtV9!fQpY z+!^a38o4ZGy9!J5sylDxZTx$JmG!wg7;>&5H1)>f4dXj;B+@6tMlL=)cLl={jLMxY zbbf1ax3S4>bwB9-$;SN2?+GULu;UA-35;VY*^9Blx)Jwyb$=U!D>HhB&=jSsd^6yw zL)?a|>GxU!W}ocTC(?-%z3!IUhw^uzc`Vz_g>-tv)(XA#JK^)ZnC|l1`@CdX1@|!| z_9gQ)7uOf?cR@KDp97*>6X|;t@Y`k_N@)aH7gY27)COv^P3ya9I{4z~vUjLR9~z1Z z5=G{mVtKH*&$*t0@}-i_v|3B$AHHYale7>E+jP`ClqG%L{u;*ff_h@)al?RuL7tOO z->;I}>%WI{;vbLP3VIQ^iA$4wl6@0sDj|~112Y4OFjMs`13!$JGkp%b&E8QzJw_L5 zOnw9joc0^;O%OpF$Qp)W1HI!$4BaXX84`%@#^dk^hFp^pQ@rx4g(8Xjy#!X%+X5Jd@fs3amGT`}mhq#L97R>OwT5-m|h#yT_-v@(k$q7P*9X~T*3)LTdzP!*B} z+SldbVWrrwQo9wX*%FyK+sRXTa@O?WM^FGWOE?S`R(0P{<6p#f?0NJvnBia?k^fX2 zNQs7K-?EijgHJY}&zsr;qJ<*PCZUd*x|dD=IQPUK_nn)@X4KWtqoJNHkT?ZWL_hF? zS8lp2(q>;RXR|F;1O}EE#}gCrY~#n^O`_I&?&z5~7N;zL0)3Tup`%)oHMK-^r$NT% zbFg|o?b9w(q@)6w5V%si<$!U<#}s#x@0aX-hP>zwS#9*75VXA4K*%gUc>+yzupTDBOKH8WR4V0pM(HrfbQ&eJ79>HdCvE=F z|J>s;;iDLB^3(9}?biKbxf1$lI!*Z%*0&8UUq}wMyPs_hclyQQi4;NUY+x2qy|0J; zhn8;5)4ED1oHwg+VZF|80<4MrL97tGGXc5Sw$wAI#|2*cvQ=jB5+{AjMiDHmhUC*a zlmiZ`LAuAn_}hftXh;`Kq0zblDk8?O-`tnilIh|;3lZp@F_osJUV9`*R29M?7H{Fy z`nfVEIDIWXmU&YW;NjU8)EJpXhxe5t+scf|VXM!^bBlwNh)~7|3?fWwo_~ZFk(22% zTMesYw+LNx3J-_|DM~`v93yXe=jPD{q;li;5PD?Dyk+b? zo21|XpT@)$BM$%F=P9J19Vi&1#{jM3!^Y&fr&_`toi`XB1!n>sbL%U9I5<7!@?t)~ z;&H%z>bAaQ4f$wIzkjH70;<8tpUoxzKrPhn#IQfS%9l5=Iu))^XC<58D!-O z{B+o5R^Z21H0T9JQ5gNJnqh#qH^na|z92=hONIM~@_iuOi|F>jBh-?aA20}Qx~EpDGElELNn~|7WRXRFnw+Wdo`|# zBpU=Cz3z%cUJ0mx_1($X<40XEIYz(`noWeO+x#yb_pwj6)R(__%@_Cf>txOQ74wSJ z0#F3(zWWaR-jMEY$7C*3HJrohc79>MCUu26mfYN)f4M~4gD`}EX4e}A!U}QV8!S47 z6y-U-%+h`1n`*pQuKE%Av0@)+wBZr9mH}@vH@i{v(m-6QK7Ncf17x_D=)32`FOjjo zg|^VPf5c6-!FxN{25dvVh#fog=NNpXz zfB$o+0jbRkHH{!TKhE709f+jI^$3#v1Nmf80w`@7-5$1Iv_`)W^px8P-({xwb;D0y z7LKDAHgX<84?l!I*Dvi2#D@oAE^J|g$3!)x1Ua;_;<@#l1fD}lqU2_tS^6Ht$1Wl} zBESo7o^)9-Tjuz$8YQSGhfs{BQV6zW7dA?0b(Dbt=UnQs&4zHfe_sj{RJ4uS-vQpC zX;Bbsuju4%!o8?&m4UZU@~ZZjeFF6ex2ss5_60_JS_|iNc+R0GIjH1@Z z=rLT9%B|WWgOrR7IiIwr2=T;Ne?30M!@{%Qf8o`!>=s<2CBpCK_TWc(DX51>e^xh8 z&@$^b6CgOd7KXQV&Y4%}_#uN*mbanXq(2=Nj`L7H7*k(6F8s6{FOw@(DzU`4-*77{ zF+dxpv}%mFpYK?>N_2*#Y?oB*qEKB}VoQ@bzm>ptmVS_EC(#}Lxxx730trt0G)#$b zE=wVvtqOct1%*9}U{q<)2?{+0TzZzP0jgf9*)arV)*e!f`|jgT{7_9iS@e)recI#z zbzolURQ+TOzE!ymqvBY7+5NnAbWxvMLsLTwEbFqW=CPyCsmJ}P1^V30|D5E|p3BC5 z)3|qgw@ra7aXb-wsa|l^in~1_fm{7bS9jhVRkYVO#U{qMp z)Wce+|DJ}4<2gp8r0_xfZpMo#{Hl2MfjLcZdRB9(B(A(f;+4s*FxV{1F|4d`*sRNd zp4#@sEY|?^FIJ;tmH{@keZ$P(sLh5IdOk@k^0uB^BWr@pk6mHy$qf&~rI>P*a;h0C{%oA*i!VjWn&D~O#MxN&f@1Po# zKN+ zrGrkSjcr?^R#nGl<#Q722^wbYcgW@{+6CBS<1@%dPA8HC!~a`jTz<`g_l5N1M@9wn9GOAZ>nqNgq!yOCbZ@1z`U_N`Z>}+1HIZxk*5RDc&rd5{3qjRh8QmT$VyS;jK z;AF+r6XnnCp=wQYoG|rT2@8&IvKq*IB_WvS%nt%e{MCFm`&W*#LXc|HrD?nVBo=(8*=Aq?u$sDA_sC_RPDUiQ+wnIJET8vx$&fxkW~kP9qXKt zozR)@xGC!P)CTkjeWvXW5&@2?)qt)jiYWWBU?AUtzAN}{JE1I)dfz~7$;}~BmQF`k zpn11qmObXwRB8&rnEG*#4Xax3XBkKlw(;tb?Np^i+H8m(Wyz9k{~ogba@laiEk;2! zV*QV^6g6(QG%vX5Um#^sT&_e`B1pBW5yVth~xUs#0}nv?~C#l?W+9Lsb_5)!71rirGvY zTIJ$OPOY516Y|_014sNv+Z8cc5t_V=i>lWV=vNu#!58y9Zl&GsMEW#pPYPYGHQ|;vFvd*9eM==$_=vc7xnyz0~ zY}r??$<`wAO?JQk@?RGvkWVJlq2dk9vB(yV^vm{=NVI8dhsX<)O(#nr9YD?I?(VmQ z^r7VfUBn<~p3()8yOBjm$#KWx!5hRW)5Jl7wY@ky9lNM^jaT##8QGVsYeaVywmpv>X|Xj7gWE1Ezai&wVLt3p)k4w~yrskT-!PR!kiyQlaxl(( zXhF%Q9x}1TMt3~u@|#wWm-Vq?ZerK={8@~&@9r5JW}r#45#rWii};t`{5#&3$W)|@ zbAf2yDNe0q}NEUvq_Quq3cTjcw z@H_;$hu&xllCI9CFDLuScEMg|x{S7GdV8<&Mq=ezDnRZAyX-8gv97YTm0bg=d)(>N z+B2FcqvI9>jGtnK%eO%y zoBPkJTk%y`8TLf4)IXPBn`U|9>O~WL2C~C$z~9|0m*YH<-vg2CD^SX#&)B4ngOSG$ zV^wmy_iQk>dfN@Pv(ckfy&#ak@MLC7&Q6Ro#!ezM*VEh`+b3Jt%m(^T&p&WJ2Oqvj zs-4nq0TW6cv~(YI$n0UkfwN}kg3_fp?(ijSV#tR9L0}l2qjc7W?i*q01=St0eZ=4h zyGQbEw`9OEH>NMuIe)hVwYHsGERWOD;JxEiO7cQv%pFCeR+IyhwQ|y@&^24k+|8fD zLiOWFNJ2&vu2&`Jv96_z-Cd5RLgmeY3*4rDOQo?Jm`;I_(+ejsPM03!ly!*Cu}Cco zrQSrEDHNyzT(D5s1rZq!8#?f6@v6dB7a-aWs(Qk>N?UGAo{gytlh$%_IhyL7h?DLXDGx zgxGEBQoCAWo-$LRvM=F5MTle`M})t3vVv;2j0HZY&G z22^iGhV@uaJh(XyyY%} zd4iH_UfdV#T=3n}(Lj^|n;O4|$;xhu*8T3hR1mc_A}fK}jfZ7LX~*n5+`8N2q#rI$ z@<_2VANlYF$vIH$ zl<)+*tIWW78IIINA7Rr7i{<;#^yzxoLNkXL)eSs=%|P>$YQIh+ea_3k z_s7r4%j7%&*NHSl?R4k%1>Z=M9o#zxY!n8sL5>BO-ZP;T3Gut>iLS@U%IBrX6BA3k z)&@q}V8a{X<5B}K5s(c(LQ=%v1ocr`t$EqqY0EqVjr65usa=0bkf|O#ky{j3)WBR(((L^wmyHRzoWuL2~WTC=`yZ zn%VX`L=|Ok0v7?s>IHg?yArBcync5rG#^+u)>a%qjES%dRZoIyA8gQ;StH z1Ao7{<&}6U=5}4v<)1T7t!J_CL%U}CKNs-0xWoTTeqj{5{?Be$L0_tk>M9o8 zo371}S#30rKZFM{`H_(L`EM9DGp+Mifk&IP|C2Zu_)Ghr4Qtpmkm1osCf@%Z$%t+7 zYH$Cr)Ro@3-QDeQJ8m+x6%;?YYT;k6Z0E-?kr>x33`H%*ueBD7Zx~3&HtWn0?2Wt} zTG}*|v?{$ajzt}xPzV%lL1t-URi8*Zn)YljXNGDb>;!905Td|mpa@mHjIH%VIiGx- zd@MqhpYFu4_?y5N4xiHn3vX&|e6r~Xt> zZG`aGq|yTNjv;9E+Txuoa@A(9V7g?1_T5FzRI;!=NP1Kqou1z5?%X~Wwb{trRfd>i z8&y^H)8YnKyA_Fyx>}RNmQIczT?w2J4SNvI{5J&}Wto|8FR(W;Qw#b1G<1%#tmYzQ zQ2mZA-PAdi%RQOhkHy9Ea#TPSw?WxwL@H@cbkZwIq0B!@ns}niALidmn&W?!Vd4Gj zO7FiuV4*6Mr^2xlFSvM;Cp_#r8UaqIzHJQg_z^rEJw&OMm_8NGAY2)rKvki|o1bH~ z$2IbfVeY2L(^*rMRU1lM5Y_sgrDS`Z??nR2lX;zyR=c%UyGb*%TC-Dil?SihkjrQy~TMv6;BMs7P8il`H7DmpVm@rJ;b)hW)BL)GjS154b*xq-NXq2cwE z^;VP7ua2pxvCmxrnqUYQMH%a%nHmwmI33nJM(>4LznvY*k&C0{8f*%?zggpDgkuz&JBx{9mfb@wegEl2v!=}Sq2Gaty0<)UrOT0{MZtZ~j5y&w zXlYa_jY)I_+VA-^#mEox#+G>UgvM!Ac8zI<%JRXM_73Q!#i3O|)lOP*qBeJG#BST0 zqohi)O!|$|2SeJQo(w6w7%*92S})XfnhrH_Z8qe!G5>CglP=nI7JAOW?(Z29;pXJ9 zR9`KzQ=WEhy*)WH>$;7Cdz|>*i>=##0bB)oU0OR>>N<21e4rMCHDemNi2LD>Nc$;& zQRFthpWniC1J6@Zh~iJCoLOxN`oCKD5Q4r%ynwgUKPlIEd#?QViIqovY|czyK8>6B zSP%{2-<;%;1`#0mG^B(8KbtXF;Nf>K#Di72UWE4gQ%(_26Koiad)q$xRL~?pN71ZZ zujaaCx~jXjygw;rI!WB=xrOJO6HJ!!w}7eiivtCg5K|F6$EXa)=xUC za^JXSX98W`7g-tm@uo|BKj39Dl;sg5ta;4qjo^pCh~{-HdLl6qI9Ix6f$+qiZ$}s= zNguKrU;u+T@ko(Vr1>)Q%h$?UKXCY>3se%&;h2osl2D zE4A9bd7_|^njDd)6cI*FupHpE3){4NQ*$k*cOWZ_?CZ>Z4_fl@n(mMnYK62Q1d@+I zr&O))G4hMihgBqRIAJkLdk(p(D~X{-oBUA+If@B}j& zsHbeJ3RzTq96lB7d($h$xTeZ^gP0c{t!Y0c)aQE;$FY2!mACg!GDEMKXFOPI^)nHZ z`aSPJpvV0|bbrzhWWkuPURlDeN%VT8tndV8?d)eN*i4I@u zVKl^6{?}A?P)Fsy?3oi#clf}L18t;TjNI2>eI&(ezDK7RyqFxcv%>?oxUlonv(px) z$vnPzRH`y5A(x!yOIfL0bmgeMQB$H5wenx~!ujQK*nUBW;@Em&6Xv2%s(~H5WcU2R z;%Nw<$tI)a`Ve!>x+qegJnQsN2N7HaKzrFqM>`6R*gvh%O*-%THt zrB$Nk;lE;z{s{r^PPm5qz(&lM{sO*g+W{sK+m3M_z=4=&CC>T`{X}1Vg2PEfSj2x_ zmT*(x;ov%3F?qoEeeM>dUn$a*?SIGyO8m806J1W1o+4HRhc2`9$s6hM#qAm zChQ87b~GEw{ADfs+5}FJ8+|bIlIv(jT$Ap#hSHoXdd9#w<#cA<1Rkq^*EEkknUd4& zoIWIY)sAswy6fSERVm&!SO~#iN$OgOX*{9@_BWFyJTvC%S++ilSfCrO(?u=Dc?CXZ zzCG&0yVR{Z`|ZF0eEApWEo#s9osV>F{uK{QA@BES#&;#KsScf>y zvs?vIbI>VrT<*!;XmQS=bhq%46-aambZ(8KU-wOO2=en~D}MCToB_u;Yz{)1ySrPZ z@=$}EvjTdzTWU7c0ZI6L8=yP+YRD_eMMos}b5vY^S*~VZysrkq<`cK3>>v%uy7jgq z0ilW9KjVDHLv0b<1K_`1IkbTOINs0=m-22c%M~l=^S}%hbli-3?BnNq?b`hx^HX2J zIe6ECljRL0uBWb`%{EA=%!i^4sMcj+U_TaTZRb+~GOk z^ZW!nky0n*Wb*r+Q|9H@ml@Z5gU&W`(z4-j!OzC1wOke`TRAYGZVl$PmQ16{3196( zO*?`--I}Qf(2HIwb2&1FB^!faPA2=sLg(@6P4mN)>Dc3i(B0;@O-y2;lM4akD>@^v z=u>*|!s&9zem70g7zfw9FXl1bpJW(C#5w#uy5!V?Q(U35A~$dR%LDVnq@}kQm13{} zd53q3N(s$Eu{R}k2esbftfjfOITCL;jWa$}(mmm}d(&7JZ6d3%IABCapFFYjdEjdK z&4Edqf$G^MNAtL=uCDRs&Fu@FXRgX{*0<(@c3|PNHa>L%zvxWS={L8%qw`STm+=Rd zA}FLspESSIpE_^41~#5yI2bJ=9`oc;GIL!JuW&7YetZ?0H}$$%8rW@*J37L-~Rsx!)8($nI4 zZhcZ2^=Y+p4YPl%j!nFJA|*M^gc(0o$i3nlphe+~-_m}jVkRN{spFs(o0ajW@f3K{ zDV!#BwL322CET$}Y}^0ixYj2w>&Xh12|R8&yEw|wLDvF!lZ#dOTHM9pK6@Nm-@9Lnng4ZHBgBSrr7KI8YCC9DX5Kg|`HsiwJHg2(7#nS;A{b3tVO?Z% za{m5b3rFV6EpX;=;n#wltDv1LE*|g5pQ+OY&*6qCJZc5oDS6Z6JD#6F)bWxZSF@q% z+1WV;m!lRB!n^PC>RgQCI#D1br_o^#iPk>;K2hB~0^<~)?p}LG%kigm@moD#q3PE+ zA^Qca)(xnqw6x>XFhV6ku9r$E>bWNrVH9fum0?4s?Rn2LG{Vm_+QJHse6xa%nzQ?k zKug4PW~#Gtb;#5+9!QBgyB@q=sk9=$S{4T>wjFICStOM?__fr+Kei1 z3j~xPqW;W@YkiUM;HngG!;>@AITg}vAE`M2Pj9Irl4w1fo4w<|Bu!%rh%a(Ai^Zhi zs92>v5;@Y(Zi#RI*ua*h`d_7;byQSa*v9E{2x$<-_=5Z<7{%)}4XExANcz@rK69T0x3%H<@frW>RA8^swA+^a(FxK| zFl3LD*ImHN=XDUkrRhp6RY5$rQ{bRgSO*(vEHYV)3Mo6Jy3puiLmU&g82p{qr0F?ohmbz)f2r{X2|T2 z$4fdQ=>0BeKbiVM!e-lIIs8wVTuC_m7}y4A_%ikI;Wm5$9j(^Y z(cD%U%k)X>_>9~t8;pGzL6L-fmQO@K; zo&vQzMlgY95;1BSkngY)e{`n0!NfVgf}2mB3t}D9@*N;FQ{HZ3Pb%BK6;5#-O|WI( zb6h@qTLU~AbVW#_6?c!?Dj65Now7*pU{h!1+eCV^KCuPAGs28~3k@ueL5+u|Z-7}t z9|lskE`4B7W8wMs@xJa{#bsCGDFoRSNSnmNYB&U7 zVGKWe%+kFB6kb)e;TyHfqtU6~fRg)f|>=5(N36)0+C z`hv65J<$B}WUc!wFAb^QtY31yNleq4dzmG`1wHTj=c*=hay9iD071Hc?oYoUk|M*_ zU1GihAMBsM@5rUJ(qS?9ZYJ6@{bNqJ`2Mr+5#hKf?doa?F|+^IR!8lq9)wS3tF_9n zW_?hm)G(M+MYb?V9YoX^_mu5h-LP^TL^!Q9Z7|@sO(rg_4+@=PdI)WL(B7`!K^ND- z-uIuVDCVEdH_C@c71YGYT^_Scf_dhB8Z2Xy6vGtBSlYud9vggOqv^L~F{BraSE_t} zIkP+Hp2&nH^-MNEs}^`oMLy11`PQW$T|K(`Bu*(f@)mv1-qY(_YG&J2M2<7k;;RK~ zL{Fqj9yCz8(S{}@c)S!65aF<=&eLI{hAMErCx&>i7OeDN>okvegO87OaG{Jmi<|}D zaT@b|0X{d@OIJ7zvT>r+eTzgLq~|Dpu)Z&db-P4z*`M$UL51lf>FLlq6rfG)%doyp z)3kk_YIM!03eQ8Vu_2fg{+osaEJPtJ-s36R+5_AEG12`NG)IQ#TF9c@$99%0iye+ zUzZ57=m2)$D(5Nx!n)=5Au&O0BBgwxIBaeI(mro$#&UGCr<;C{UjJVAbVi%|+WP(a zL$U@TYCxJ=1{Z~}rnW;7UVb7+ZnzgmrogDxhjLGo>c~MiJAWs&&;AGg@%U?Y^0JhL ze(x6Z74JG6FlOFK(T}SXQfhr}RIFl@QXKnIcXYF)5|V~e-}suHILKT-k|<*~Ij|VF zC;t@=uj=hot~*!C68G8hTA%8SzOfETOXQ|3FSaIEjvBJp(A)7SWUi5!Eu#yWgY+;n zlm<$+UDou*V+246_o#V4kMdto8hF%%Lki#zPh}KYXmMf?hrN0;>Mv%`@{0Qn`Ujp) z=lZe+13>^Q!9zT);H<(#bIeRWz%#*}sgUX9P|9($kexOyKIOc`dLux}c$7It4u|Rl z6SSkY*V~g_B-hMPo_ak>>z@AVQ(_N)VY2kB3IZ0G(iDUYw+2d7W^~(Jq}KY=JnWS( z#rzEa&0uNhJ>QE8iiyz;n2H|SV#Og+wEZv=f2%1ELX!SX-(d3tEj$5$1}70Mp<&eI zCkfbByL7af=qQE@5vDVxx1}FSGt_a1DoE3SDI+G)mBAna)KBG4p8Epxl9QZ4BfdAN zFnF|Y(umr;gRgG6NLQ$?ZWgllEeeq~z^ZS7L?<(~O&$5|y)Al^iMKy}&W+eMm1W z7EMU)u^ke(A1#XCV>CZ71}P}0x)4wtHO8#JRG3MA-6g=`ZM!FcICCZ{IEw8Dm2&LQ z1|r)BUG^0GzI6f946RrBlfB1Vs)~8toZf~7)+G;pv&XiUO(%5bm)pl=p>nV^o*;&T z;}@oZSibzto$arQgfkp|z4Z($P>dTXE{4O=vY0!)kDO* zGF8a4wq#VaFpLfK!iELy@?-SeRrdz%F*}hjKcA*y@mj~VD3!it9lhRhX}5YOaR9$} z3mS%$2Be7{l(+MVx3 z(4?h;P!jnRmX9J9sYN#7i=iyj_5q7n#X(!cdqI2lnr8T$IfOW<_v`eB!d9xY1P=2q&WtOXY=D9QYteP)De?S4}FK6#6Ma z=E*V+#s8>L;8aVroK^6iKo=MH{4yEZ_>N-N z`(|;aOATba1^asjxlILk<4}f~`39dBFlxj>Dw(hMYKPO3EEt1@S`1lxFNM+J@uB7T zZ8WKjz7HF1-5&2=l=fqF-*@>n5J}jIxdDwpT?oKM3s8Nr`x8JnN-kCE?~aM1H!hAE z%%w(3kHfGwMnMmNj(SU(w42OrC-euI>Dsjk&jz3ts}WHqmMpzQ3vZrsXrZ|}+MHA7 z068obeXZTsO*6RS@o3x80E4ok``rV^Y3hr&C1;|ZZ0|*EKO`$lECUYG2gVFtUTw)R z4Um<0ZzlON`zTdvVdL#KFoMFQX*a5wM0Czp%wTtfK4Sjs)P**RW&?lP$(<}q%r68Z zS53Y!d@&~ne9O)A^tNrXHhXBkj~$8j%pT1%%mypa9AW5E&s9)rjF4@O3ytH{0z6riz|@< zB~UPh*wRFg2^7EbQrHf0y?E~dHlkOxof_a?M{LqQ^C!i2dawHTPYUE=X@2(3<=OOxs8qn_(y>pU>u^}3y&df{JarR0@VJn0f+U%UiF=$Wyq zQvnVHESil@d|8&R<%}uidGh7@u^(%?$#|&J$pvFC-n8&A>utA=n3#)yMkz+qnG3wd zP7xCnF|$9Dif@N~L)Vde3hW8W!UY0BgT2v(wzp;tlLmyk2%N|0jfG$%<;A&IVrOI< z!L)o>j>;dFaqA3pL}b-Je(bB@VJ4%!JeX@3x!i{yIeIso^=n?fDX`3bU=eG7sTc%g%ye8$v8P@yKE^XD=NYxTb zbf!Mk=h|otpqjFaA-vs5YOF-*GwWPc7VbaOW&stlANnCN8iftFMMrUdYNJ_Bnn5Vt zxfz@Ah|+4&P;reZxp;MmEI7C|FOv8NKUm8njF7Wb6Gi7DeODLl&G~}G4be&*Hi0Qw z5}77vL0P+7-B%UL@3n1&JPxW^d@vVwp?u#gVcJqY9#@-3X{ok#UfW3<1fb%FT`|)V~ggq z(3AUoUS-;7)^hCjdT0Kf{i}h)mBg4qhtHHBti=~h^n^OTH5U*XMgDLIR@sre`AaB$ zg)IGBET_4??m@cx&c~bA80O7B8CHR7(LX7%HThkeC*@vi{-pL%e)yXp!B2InafbDF zjPXf1mko3h59{lT6EEbxKO1Z5GF71)WwowO6kY|6tjSVSWdQ}NsK2x{>i|MKZK8%Q zfu&_0D;CO-Jg0#YmyfctyJ!mRJp)e#@O0mYdp|8x;G1%OZQ3Q847YWTyy|%^cpA;m zze0(5p{tMu^lDkpe?HynyO?a1$_LJl2L&mpeKu%8YvgRNr=%2z${%WThHG=vrWY@4 zsA`OP#O&)TetZ>s%h!=+CE15lOOls&nvC~$Qz0Ph7tHiP;O$i|eDwpT{cp>+)0-|; zY$|bB+Gbel>5aRN3>c0x)4U=|X+z+{ zn*_p*EQoquRL+=+p;=lm`d71&1NqBz&_ph)MXu(Nv6&XE7(RsS)^MGj5Q?Fwude-(sq zjJ>aOq!7!EN>@(fK7EE#;i_BGvli`5U;r!YA{JRodLBc6-`n8K+Fjgwb%sX;j=qHQ z7&Tr!)!{HXoO<2BQrV9Sw?JRaLXV8HrsNevvnf>Y-6|{T!pYLl7jp$-nEE z#X!4G4L#K0qG_4Z;Cj6=;b|Be$hi4JvMH!-voxqx^@8cXp`B??eFBz2lLD8RRaRGh zn7kUfy!YV~p(R|p7iC1Rdgt$_24i0cd-S8HpG|`@my70g^y`gu%#Tf_L21-k?sRRZHK&at(*ED0P8iw{7?R$9~OF$Ko;Iu5)ur5<->x!m93Eb zFYpIx60s=Wxxw=`$aS-O&dCO_9?b1yKiPCQmSQb>T)963`*U+Ydj5kI(B(B?HNP8r z*bfSBpSu)w(Z3j7HQoRjUG(+d=IaE~tv}y14zHHs|0UcN52fT8V_<@2ep_ee{QgZG zmgp8iv4V{k;~8@I%M3<#B;2R>Ef(Gg_cQM7%}0s*^)SK6!Ym+~P^58*wnwV1BW@eG z4sZLqsUvBbFsr#8u7S1r4teQ;t)Y@jnn_m5jS$CsW1um!p&PqAcc8!zyiXHVta9QC zY~wCwCF0U%xiQPD_INKtTb;A|Zf29(mu9NI;E zc-e>*1%(LSXB`g}kd`#}O;veb<(sk~RWL|f3ljxCnEZDdNSTDV6#Td({6l&y4IjKF z^}lIUq*ZUqgTPumD)RrCN{M^jhY>E~1pn|KOZ5((%F)G|*ZQ|r4zIbrEiV%42hJV8 z3xS)=!X1+=olbdGJ=yZil?oXLct8FM{(6ikLL3E%=q#O6(H$p~gQu6T8N!plf!96| z&Q3=`L~>U0zZh;z(pGR2^S^{#PrPxTRHD1RQOON&f)Siaf`GLj#UOk&(|@0?zm;Sx ztsGt8=29-MZs5CSf1l1jNFtNt5rFNZxJPvkNu~2}7*9468TWm>nN9TP&^!;J{-h)_ z7WsHH9|F%I`Pb!>KAS3jQWKfGivTVkMJLO-HUGM_a4UQ_%RgL6WZvrW+Z4ujZn;y@ zz9$=oO!7qVTaQAA^BhX&ZxS*|5dj803M=k&2%QrXda`-Q#IoZL6E(g+tN!6CA!CP* zCpWtCujIea)ENl0liwVfj)Nc<9mV%+e@=d`haoZ*`B7+PNjEbXBkv=B+Pi^~L#EO$D$ZqTiD8f<5$eyb54-(=3 zh)6i8i|jp(@OnRrY5B8t|LFXFQVQ895n*P16cEKTrT*~yLH6Z4e*bZ5otpRDri&+A zfNbK1D5@O=sm`fN=WzWyse!za5n%^+6dHPGX#8DyIK>?9qyX}2XvBWVqbP%%D)7$= z=#$WulZlZR<{m#gU7lwqK4WS1Ne$#_P{b17qe$~UOXCl>5b|6WVh;5vVnR<%d+Lnp z$uEmML38}U4vaW8>shm6CzB(Wei3s#NAWE3)a2)z@i{4jTn;;aQS)O@l{rUM`J@K& l00vQ5JBs~;vo!vr%%-k{2_Fq1Mn4QF81S)AQ99zk{{c4yR+0b! literal 63721 zcmb5Wb9gP!wgnp7wrv|bwr$&XvSZt}Z6`anZSUAlc9NHKf9JdJ;NJVr`=eI(_pMp0 zy1VAAG3FfAOI`{X1O)&90s;U4K;XLp008~hCjbEC_fbYfS%6kTR+JtXK>nW$ZR+`W ze|#J8f4A@M|F5BpfUJb5h>|j$jOe}0oE!`Zf6fM>CR?!y@zU(cL8NsKk`a z6tx5mAkdjD;J=LcJ;;Aw8p!v#ouk>mUDZF@ zK>yvw%+bKu+T{Nk@LZ;zkYy0HBKw06_IWcMHo*0HKpTsEFZhn5qCHH9j z)|XpN&{`!0a>Vl+PmdQc)Yg4A(AG-z!+@Q#eHr&g<9D?7E)_aEB?s_rx>UE9TUq|? z;(ggJt>9l?C|zoO@5)tu?EV0x_7T17q4fF-q3{yZ^ipUbKcRZ4Qftd!xO(#UGhb2y>?*@{xq%`(-`2T^vc=#< zx!+@4pRdk&*1ht2OWk^Z5IAQ0YTAXLkL{(D*$gENaD)7A%^XXrCchN&z2x+*>o2FwPFjWpeaL=!tzv#JOW#( z$B)Nel<+$bkH1KZv3&-}=SiG~w2sbDbAWarg%5>YbC|}*d9hBjBkR(@tyM0T)FO$# zPtRXukGPnOd)~z=?avu+4Co@wF}1T)-uh5jI<1$HLtyDrVak{gw`mcH@Q-@wg{v^c zRzu}hMKFHV<8w}o*yg6p@Sq%=gkd~;`_VGTS?L@yVu`xuGy+dH6YOwcP6ZE`_0rK% zAx5!FjDuss`FQ3eF|mhrWkjux(Pny^k$u_)dyCSEbAsecHsq#8B3n3kDU(zW5yE|( zgc>sFQywFj5}U*qtF9Y(bi*;>B7WJykcAXF86@)z|0-Vm@jt!EPoLA6>r)?@DIobIZ5Sx zsc@OC{b|3%vaMbyeM|O^UxEYlEMHK4r)V-{r)_yz`w1*xV0|lh-LQOP`OP`Pk1aW( z8DSlGN>Ts|n*xj+%If~+E_BxK)~5T#w6Q1WEKt{!Xtbd`J;`2a>8boRo;7u2M&iOop4qcy<)z023=oghSFV zST;?S;ye+dRQe>ygiJ6HCv4;~3DHtJ({fWeE~$H@mKn@Oh6Z(_sO>01JwH5oA4nvK zr5Sr^g+LC zLt(i&ecdmqsIJGNOSUyUpglvhhrY8lGkzO=0USEKNL%8zHshS>Qziu|`eyWP^5xL4 zRP122_dCJl>hZc~?58w~>`P_s18VoU|7(|Eit0-lZRgLTZKNq5{k zE?V=`7=R&ro(X%LTS*f+#H-mGo_j3dm@F_krAYegDLk6UV{`UKE;{YSsn$ z(yz{v1@p|p!0>g04!eRSrSVb>MQYPr8_MA|MpoGzqyd*$@4j|)cD_%^Hrd>SorF>@ zBX+V<@vEB5PRLGR(uP9&U&5=(HVc?6B58NJT_igiAH*q~Wb`dDZpJSKfy5#Aag4IX zj~uv74EQ_Q_1qaXWI!7Vf@ZrdUhZFE;L&P_Xr8l@GMkhc#=plV0+g(ki>+7fO%?Jb zl+bTy7q{w^pTb{>(Xf2q1BVdq?#f=!geqssXp z4pMu*q;iiHmA*IjOj4`4S&|8@gSw*^{|PT}Aw~}ZXU`6=vZB=GGeMm}V6W46|pU&58~P+?LUs%n@J}CSrICkeng6YJ^M? zS(W?K4nOtoBe4tvBXs@@`i?4G$S2W&;$z8VBSM;Mn9 zxcaEiQ9=vS|bIJ>*tf9AH~m&U%2+Dim<)E=}KORp+cZ^!@wI`h1NVBXu{@%hB2Cq(dXx_aQ9x3mr*fwL5!ZryQqi|KFJuzvP zK1)nrKZ7U+B{1ZmJub?4)Ln^J6k!i0t~VO#=q1{?T)%OV?MN}k5M{}vjyZu#M0_*u z8jwZKJ#Df~1jcLXZL7bnCEhB6IzQZ-GcoQJ!16I*39iazoVGugcKA{lhiHg4Ta2fD zk1Utyc5%QzZ$s3;p0N+N8VX{sd!~l*Ta3|t>lhI&G`sr6L~G5Lul`>m z{!^INm?J|&7X=;{XveF!(b*=?9NAp4y&r&N3(GKcW4rS(Ejk|Lzs1PrxPI_owB-`H zg3(Rruh^&)`TKA6+_!n>RdI6pw>Vt1_j&+bKIaMTYLiqhZ#y_=J8`TK{Jd<7l9&sY z^^`hmi7^14s16B6)1O;vJWOF$=$B5ONW;;2&|pUvJlmeUS&F;DbSHCrEb0QBDR|my zIs+pE0Y^`qJTyH-_mP=)Y+u^LHcuZhsM3+P||?+W#V!_6E-8boP#R-*na4!o-Q1 zVthtYhK{mDhF(&7Okzo9dTi03X(AE{8cH$JIg%MEQca`S zy@8{Fjft~~BdzWC(di#X{ny;!yYGK9b@=b|zcKZ{vv4D8i+`ilOPl;PJl{!&5-0!w z^fOl#|}vVg%=n)@_e1BrP)`A zKPgs`O0EO}Y2KWLuo`iGaKu1k#YR6BMySxQf2V++Wo{6EHmK>A~Q5o73yM z-RbxC7Qdh0Cz!nG+7BRZE>~FLI-?&W_rJUl-8FDIaXoNBL)@1hwKa^wOr1($*5h~T zF;%f^%<$p8Y_yu(JEg=c_O!aZ#)Gjh$n(hfJAp$C2he555W5zdrBqjFmo|VY+el;o z=*D_w|GXG|p0**hQ7~9-n|y5k%B}TAF0iarDM!q-jYbR^us(>&y;n^2l0C%@2B}KM zyeRT9)oMt97Agvc4sEKUEy%MpXr2vz*lb zh*L}}iG>-pqDRw7ud{=FvTD?}xjD)w{`KzjNom-$jS^;iw0+7nXSnt1R@G|VqoRhE%12nm+PH?9`(4rM0kfrZzIK9JU=^$YNyLvAIoxl#Q)xxDz!^0@zZ zSCs$nfcxK_vRYM34O<1}QHZ|hp4`ioX3x8(UV(FU$J@o%tw3t4k1QPmlEpZa2IujG&(roX_q*%e`Hq|);0;@k z0z=fZiFckp#JzW0p+2A+D$PC~IsakhJJkG(c;CqAgFfU0Z`u$PzG~-9I1oPHrCw&)@s^Dc~^)#HPW0Ra}J^=|h7Fs*<8|b13ZzG6MP*Q1dkoZ6&A^!}|hbjM{2HpqlSXv_UUg1U4gn z3Q)2VjU^ti1myodv+tjhSZp%D978m~p& z43uZUrraHs80Mq&vcetqfQpQP?m!CFj)44t8Z}k`E798wxg&~aCm+DBoI+nKq}&j^ zlPY3W$)K;KtEajks1`G?-@me7C>{PiiBu+41#yU_c(dITaqE?IQ(DBu+c^Ux!>pCj zLC|HJGU*v+!it1(;3e`6igkH(VA)-S+k(*yqxMgUah3$@C zz`7hEM47xr>j8^g`%*f=6S5n>z%Bt_Fg{Tvmr+MIsCx=0gsu_sF`q2hlkEmisz#Fy zj_0;zUWr;Gz}$BS%Y`meb(=$d%@Crs(OoJ|}m#<7=-A~PQbyN$x%2iXP2@e*nO0b7AwfH8cCUa*Wfu@b)D_>I*%uE4O3 z(lfnB`-Xf*LfC)E}e?%X2kK7DItK6Tf<+M^mX0Ijf_!IP>7c8IZX%8_#0060P{QMuV^B9i<^E`_Qf0pv9(P%_s8D`qvDE9LK9u-jB}J2S`(mCO&XHTS04Z5Ez*vl^T%!^$~EH8M-UdwhegL>3IQ*)(MtuH2Xt1p!fS4o~*rR?WLxlA!sjc2(O znjJn~wQ!Fp9s2e^IWP1C<4%sFF}T4omr}7+4asciyo3DntTgWIzhQpQirM$9{EbQd z3jz9vS@{aOqTQHI|l#aUV@2Q^Wko4T0T04Me4!2nsdrA8QY1%fnAYb~d2GDz@lAtfcHq(P7 zaMBAGo}+NcE-K*@9y;Vt3*(aCaMKXBB*BJcD_Qnxpt75r?GeAQ}*|>pYJE=uZb73 zC>sv)18)q#EGrTG6io*}JLuB_jP3AU1Uiu$D7r|2_zlIGb9 zjhst#ni)Y`$)!fc#reM*$~iaYoz~_Cy7J3ZTiPm)E?%`fbk`3Tu-F#`{i!l5pNEn5 zO-Tw-=TojYhzT{J=?SZj=Z8#|eoF>434b-DXiUsignxXNaR3 zm_}4iWU$gt2Mw5NvZ5(VpF`?X*f2UZDs1TEa1oZCif?Jdgr{>O~7}-$|BZ7I(IKW`{f;@|IZFX*R8&iT= zoWstN8&R;}@2Ka%d3vrLtR|O??ben;k8QbS-WB0VgiCz;<$pBmIZdN!aalyCSEm)crpS9dcD^Y@XT1a3+zpi-`D}e#HV<} z$Y(G&o~PvL-xSVD5D?JqF3?B9rxGWeb=oEGJ3vRp5xfBPlngh1O$yI95EL+T8{GC@ z98i1H9KhZGFl|;`)_=QpM6H?eDPpw~^(aFQWwyXZ8_EEE4#@QeT_URray*mEOGsGc z6|sdXtq!hVZo=d#+9^@lm&L5|q&-GDCyUx#YQiccq;spOBe3V+VKdjJA=IL=Zn%P} zNk=_8u}VhzFf{UYZV0`lUwcD&)9AFx0@Fc6LD9A6Rd1=ga>Mi0)_QxM2ddCVRmZ0d z+J=uXc(?5JLX3=)e)Jm$HS2yF`44IKhwRnm2*669_J=2LlwuF5$1tAo@ROSU@-y+;Foy2IEl2^V1N;fk~YR z?&EP8#t&m0B=?aJeuz~lHjAzRBX>&x=A;gIvb>MD{XEV zV%l-+9N-)i;YH%nKP?>f`=?#`>B(`*t`aiPLoQM(a6(qs4p5KFjDBN?8JGrf3z8>= zi7sD)c)Nm~x{e<^jy4nTx${P~cwz_*a>%0_;ULou3kHCAD7EYkw@l$8TN#LO9jC( z1BeFW`k+bu5e8Ns^a8dPcjEVHM;r6UX+cN=Uy7HU)j-myRU0wHd$A1fNI~`4;I~`zC)3ul#8#^rXVSO*m}Ag>c%_;nj=Nv$rCZ z*~L@C@OZg%Q^m)lc-kcX&a*a5`y&DaRxh6O*dfhLfF+fU5wKs(1v*!TkZidw*)YBP za@r`3+^IHRFeO%!ai%rxy;R;;V^Fr=OJlpBX;(b*3+SIw}7= zIq$*Thr(Zft-RlY)D3e8V;BmD&HOfX+E$H#Y@B3?UL5L~_fA-@*IB-!gItK7PIgG9 zgWuGZK_nuZjHVT_Fv(XxtU%)58;W39vzTI2n&)&4Dmq7&JX6G>XFaAR{7_3QB6zsT z?$L8c*WdN~nZGiscY%5KljQARN;`w$gho=p006z;n(qIQ*Zu<``TMO3n0{ARL@gYh zoRwS*|Niw~cR!?hE{m*y@F`1)vx-JRfqET=dJ5_(076st(=lFfjtKHoYg`k3oNmo_ zNbQEw8&sO5jAYmkD|Zaz_yUb0rC})U!rCHOl}JhbYIDLzLvrZVw0~JO`d*6f;X&?V=#T@ND*cv^I;`sFeq4 z##H5;gpZTb^0Hz@3C*~u0AqqNZ-r%rN3KD~%Gw`0XsIq$(^MEb<~H(2*5G^<2(*aI z%7}WB+TRlMIrEK#s0 z93xn*Ohb=kWFc)BNHG4I(~RPn-R8#0lqyBBz5OM6o5|>x9LK@%HaM}}Y5goCQRt2C z{j*2TtT4ne!Z}vh89mjwiSXG=%DURar~=kGNNaO_+Nkb+tRi~Rkf!7a$*QlavziD( z83s4GmQ^Wf*0Bd04f#0HX@ua_d8 z23~z*53ePD6@xwZ(vdl0DLc=>cPIOPOdca&MyR^jhhKrdQO?_jJh`xV3GKz&2lvP8 zEOwW6L*ufvK;TN{=S&R@pzV^U=QNk^Ec}5H z+2~JvEVA{`uMAr)?Kf|aW>33`)UL@bnfIUQc~L;TsTQ6>r-<^rB8uoNOJ>HWgqMI8 zSW}pZmp_;z_2O5_RD|fGyTxaxk53Hg_3Khc<8AUzV|ZeK{fp|Ne933=1&_^Dbv5^u zB9n=*)k*tjHDRJ@$bp9mrh}qFn*s}npMl5BMDC%Hs0M0g-hW~P*3CNG06G!MOPEQ_ zi}Qs-6M8aMt;sL$vlmVBR^+Ry<64jrm1EI1%#j?c?4b*7>)a{aDw#TfTYKq+SjEFA z(aJ&z_0?0JB83D-i3Vh+o|XV4UP+YJ$9Boid2^M2en@APw&wx7vU~t$r2V`F|7Qfo z>WKgI@eNBZ-+Og<{u2ZiG%>YvH2L3fNpV9J;WLJoBZda)01Rn;o@){01{7E#ke(7U zHK>S#qZ(N=aoae*4X!0A{)nu0R_sKpi1{)u>GVjC+b5Jyl6#AoQ-1_3UDovNSo`T> z?c-@7XX*2GMy?k?{g)7?Sv;SJkmxYPJPs!&QqB12ejq`Lee^-cDveVWL^CTUldb(G zjDGe(O4P=S{4fF=#~oAu>LG>wrU^z_?3yt24FOx>}{^lCGh8?vtvY$^hbZ)9I0E3r3NOlb9I?F-Yc=r$*~l`4N^xzlV~N zl~#oc>U)Yjl0BxV>O*Kr@lKT{Z09OXt2GlvE38nfs+DD7exl|&vT;)>VFXJVZp9Np zDK}aO;R3~ag$X*|hRVY3OPax|PG`@_ESc8E!mHRByJbZQRS38V2F__7MW~sgh!a>98Q2%lUNFO=^xU52|?D=IK#QjwBky-C>zOWlsiiM&1n z;!&1((Xn1$9K}xabq~222gYvx3hnZPg}VMF_GV~5ocE=-v>V=T&RsLBo&`)DOyIj* zLV{h)JU_y*7SdRtDajP_Y+rBkNN*1_TXiKwHH2&p51d(#zv~s#HwbNy?<+(=9WBvo zw2hkk2Dj%kTFhY+$T+W-b7@qD!bkfN#Z2ng@Pd=i3-i?xYfs5Z*1hO?kd7Sp^9`;Y zM2jeGg<-nJD1er@Pc_cSY7wo5dzQX44=%6rn}P_SRbpzsA{6B+!$3B0#;}qwO37G^ zL(V_5JK`XT?OHVk|{_$vQ|oNEpab*BO4F zUTNQ7RUhnRsU`TK#~`)$icsvKh~(pl=3p6m98@k3P#~upd=k*u20SNcb{l^1rUa)>qO997)pYRWMncC8A&&MHlbW?7i^7M`+B$hH~Y|J zd>FYOGQ;j>Zc2e7R{KK7)0>>nn_jYJy&o@sK!4G>-rLKM8Hv)f;hi1D2fAc$+six2 zyVZ@wZ6x|fJ!4KrpCJY=!Mq0;)X)OoS~{Lkh6u8J`eK%u0WtKh6B>GW_)PVc zl}-k`p09qwGtZ@VbYJC!>29V?Dr>>vk?)o(x?!z*9DJ||9qG-&G~#kXxbw{KKYy}J zQKa-dPt~M~E}V?PhW0R26xdA%1T*%ra6SguGu50YHngOTIv)@N|YttEXo#OZfgtP7;H?EeZZxo<}3YlYxtBq znJ!WFR^tmGf0Py}N?kZ(#=VtpC@%xJkDmfcCoBTxq zr_|5gP?u1@vJZbxPZ|G0AW4=tpb84gM2DpJU||(b8kMOV1S3|(yuwZJ&rIiFW(U;5 zUtAW`O6F6Zy+eZ1EDuP~AAHlSY-+A_eI5Gx)%*uro5tljy}kCZU*_d7)oJ>oQSZ3* zneTn`{gnNC&uJd)0aMBzAg021?YJ~b(fmkwZAd696a=0NzBAqBN54KuNDwa*no(^O z6p05bioXUR^uXjpTol*ppHp%1v9e)vkoUAUJyBx3lw0UO39b0?^{}yb!$yca(@DUn zCquRF?t=Zb9`Ed3AI6|L{eX~ijVH`VzSMheKoP7LSSf4g>md>`yi!TkoG5P>Ofp+n z(v~rW+(5L96L{vBb^g51B=(o)?%%xhvT*A5btOpw(TKh^g^4c zw>0%X!_0`{iN%RbVk+A^f{w-4-SSf*fu@FhruNL##F~sF24O~u zyYF<3el2b$$wZ_|uW#@Ak+VAGk#e|kS8nL1g>2B-SNMjMp^8;-FfeofY2fphFHO!{ z*!o4oTb{4e;S<|JEs<1_hPsmAlVNk?_5-Fp5KKU&d#FiNW~Y+pVFk@Cua1I{T+1|+ zHx6rFMor)7L)krbilqsWwy@T+g3DiH5MyVf8Wy}XbEaoFIDr~y;@r&I>FMW{ z?Q+(IgyebZ)-i4jNoXQhq4Muy9Fv+OxU;9_Jmn+<`mEC#%2Q_2bpcgzcinygNI!&^ z=V$)o2&Yz04~+&pPWWn`rrWxJ&}8khR)6B(--!9Q zubo}h+1T)>a@c)H^i``@<^j?|r4*{;tQf78(xn0g39IoZw0(CwY1f<%F>kEaJ zp9u|IeMY5mRdAlw*+gSN^5$Q)ShM<~E=(c8QM+T-Qk)FyKz#Sw0EJ*edYcuOtO#~Cx^(M7w5 z3)rl#L)rF|(Vun2LkFr!rg8Q@=r>9p>(t3Gf_auiJ2Xx9HmxYTa|=MH_SUlYL`mz9 zTTS$`%;D-|Jt}AP1&k7PcnfFNTH0A-*FmxstjBDiZX?}%u%Yq94$fUT&z6od+(Uk> zuqsld#G(b$G8tus=M!N#oPd|PVFX)?M?tCD0tS%2IGTfh}3YA3f&UM)W$_GNV8 zQo+a(ml2Km4o6O%gKTCSDNq+#zCTIQ1*`TIJh~k6Gp;htHBFnne))rlFdGqwC6dx2+La1&Mnko*352k0y z+tQcwndQlX`nc6nb$A9?<-o|r*%aWXV#=6PQic0Ok_D;q>wbv&j7cKc!w4~KF#-{6 z(S%6Za)WpGIWf7jZ3svNG5OLs0>vCL9{V7cgO%zevIVMH{WgP*^D9ws&OqA{yr|m| zKD4*07dGXshJHd#e%x%J+qmS^lS|0Bp?{drv;{@{l9ArPO&?Q5=?OO9=}h$oVe#3b z3Yofj&Cb}WC$PxmRRS)H%&$1-)z7jELS}!u!zQ?A^Y{Tv4QVt*vd@uj-^t2fYRzQj zfxGR>-q|o$3sGn^#VzZ!QQx?h9`njeJry}@x?|k0-GTTA4y3t2E`3DZ!A~D?GiJup z)8%PK2^9OVRlP(24P^4_<|D=H^7}WlWu#LgsdHzB%cPy|f8dD3|A^mh4WXxhLTVu_ z@abE{6Saz|Y{rXYPd4$tfPYo}ef(oQWZ=4Bct-=_9`#Qgp4ma$n$`tOwq#&E18$B; z@Bp)bn3&rEi0>fWWZ@7k5WazfoX`SCO4jQWwVuo+$PmSZn^Hz?O(-tW@*DGxuf)V1 zO_xm&;NVCaHD4dqt(-MlszI3F-p?0!-e$fbiCeuaw66h^TTDLWuaV<@C-`=Xe5WL) zwooG7h>4&*)p3pKMS3O!4>-4jQUN}iAMQ)2*70?hP~)TzzR?-f@?Aqy$$1Iy8VGG$ zMM?8;j!pUX7QQD$gRc_#+=raAS577ga-w?jd`vCiN5lu)dEUkkUPl9!?{$IJNxQys z*E4e$eF&n&+AMRQR2gcaFEjAy*r)G!s(P6D&TfoApMFC_*Ftx0|D0@E-=B7tezU@d zZ{hGiN;YLIoSeRS;9o%dEua4b%4R3;$SugDjP$x;Z!M!@QibuSBb)HY!3zJ7M;^jw zlx6AD50FD&p3JyP*>o+t9YWW8(7P2t!VQQ21pHJOcG_SXQD;(5aX#M6x##5H_Re>6lPyDCjxr*R(+HE%c&QN+b^tbT zXBJk?p)zhJj#I?&Y2n&~XiytG9!1ox;bw5Rbj~)7c(MFBb4>IiRATdhg zmiEFlj@S_hwYYI(ki{}&<;_7(Z0Qkfq>am z&LtL=2qc7rWguk3BtE4zL41@#S;NN*-jWw|7Kx7H7~_%7fPt;TIX}Ubo>;Rmj94V> zNB1=;-9AR7s`Pxn}t_6^3ahlq53e&!Lh85uG zec0vJY_6e`tg7LgfrJ3k!DjR)Bi#L@DHIrZ`sK=<5O0Ip!fxGf*OgGSpP@Hbbe&$9 z;ZI}8lEoC2_7;%L2=w?tb%1oL0V+=Z`7b=P&lNGY;yVBazXRYu;+cQDKvm*7NCxu&i;zub zAJh#11%?w>E2rf2e~C4+rAb-&$^vsdACs7 z@|Ra!OfVM(ke{vyiqh7puf&Yp6cd6{DptUteYfIRWG3pI+5< zBVBI_xkBAc<(pcb$!Y%dTW(b;B;2pOI-(QCsLv@U-D1XJ z(Gk8Q3l7Ws46Aktuj>|s{$6zA&xCPuXL-kB`CgYMs}4IeyG*P51IDwW?8UNQd+$i~ zlxOPtSi5L|gJcF@DwmJA5Ju8HEJ>o{{upwIpb!f{2(vLNBw`7xMbvcw<^{Fj@E~1( z?w`iIMieunS#>nXlmUcSMU+D3rX28f?s7z;X=se6bo8;5vM|O^(D6{A9*ChnGH!RG zP##3>LDC3jZPE4PH32AxrqPk|yIIrq~`aL-=}`okhNu9aT%q z1b)7iJ)CN=V#Ly84N_r7U^SH2FGdE5FpTO2 z630TF$P>GNMu8`rOytb(lB2};`;P4YNwW1<5d3Q~AX#P0aX}R2b2)`rgkp#zTxcGj zAV^cvFbhP|JgWrq_e`~exr~sIR$6p5V?o4Wym3kQ3HA+;Pr$bQ0(PmADVO%MKL!^q z?zAM8j1l4jrq|5X+V!8S*2Wl@=7*pPgciTVK6kS1Ge zMsd_u6DFK$jTnvVtE;qa+8(1sGBu~n&F%dh(&c(Zs4Fc#A=gG^^%^AyH}1^?|8quj zl@Z47h$){PlELJgYZCIHHL= z{U8O>Tw4x3<1{?$8>k-P<}1y9DmAZP_;(3Y*{Sk^H^A=_iSJ@+s5ktgwTXz_2$~W9>VVZsfwCm@s0sQ zeB50_yu@uS+e7QoPvdCwDz{prjo(AFwR%C?z`EL{1`|coJHQTk^nX=tvs1<0arUOJ z!^`*x&&BvTYmemyZ)2p~{%eYX=JVR?DYr(rNgqRMA5E1PR1Iw=prk=L2ldy3r3Vg@27IZx43+ywyzr-X*p*d@tZV+!U#~$-q=8c zgdSuh#r?b4GhEGNai)ayHQpk>5(%j5c@C1K3(W1pb~HeHpaqijJZa-e6vq_8t-^M^ zBJxq|MqZc?pjXPIH}70a5vt!IUh;l}<>VX<-Qcv^u@5(@@M2CHSe_hD$VG-eiV^V( zj7*9T0?di?P$FaD6oo?)<)QT>Npf6Og!GO^GmPV(Km0!=+dE&bk#SNI+C9RGQ|{~O*VC+tXK3!n`5 zHfl6>lwf_aEVV3`0T!aHNZLsj$paS$=LL(?b!Czaa5bbSuZ6#$_@LK<(7yrrl+80| z{tOFd=|ta2Z`^ssozD9BINn45NxUeCQis?-BKmU*Kt=FY-NJ+)8S1ecuFtN-M?&42 zl2$G>u!iNhAk*HoJ^4v^9#ORYp5t^wDj6|lx~5w45#E5wVqI1JQ~9l?nPp1YINf++ zMAdSif~_ETv@Er(EFBI^@L4BULFW>)NI+ejHFP*T}UhWNN`I)RRS8za? z*@`1>9ZB}An%aT5K=_2iQmfE;GcBVHLF!$`I99o5GO`O%O_zLr9AG18>&^HkG(;=V z%}c!OBQ~?MX(9h~tajX{=x)+!cbM7$YzTlmsPOdp2L-?GoW`@{lY9U3f;OUo*BwRB z8A+nv(br0-SH#VxGy#ZrgnGD(=@;HME;yd46EgWJ`EL%oXc&lFpc@Y}^>G(W>h_v_ zlN!`idhX+OjL+~T?19sroAFVGfa5tX-D49w$1g2g_-T|EpHL6}K_aX4$K=LTvwtlF zL*z}j{f+Uoe7{-px3_5iKPA<_7W=>Izkk)!l9ez2w%vi(?Y;i8AxRNLSOGDzNoqoI zP!1uAl}r=_871(G?y`i&)-7{u=%nxk7CZ_Qh#!|ITec zwQn`33GTUM`;D2POWnkqngqJhJRlM>CTONzTG}>^Q0wUunQyn|TAiHzyX2_%ATx%P z%7gW)%4rA9^)M<_%k@`Y?RbC<29sWU&5;@|9thf2#zf8z12$hRcZ!CSb>kUp=4N#y zl3hE#y6>kkA8VY2`W`g5Ip?2qC_BY$>R`iGQLhz2-S>x(RuWv)SPaGdl^)gGw7tjR zH@;jwk!jIaCgSg_*9iF|a);sRUTq30(8I(obh^|}S~}P4U^BIGYqcz;MPpC~Y@k_m zaw4WG1_vz2GdCAX!$_a%GHK**@IrHSkGoN>)e}>yzUTm52on`hYot7cB=oA-h1u|R ztH$11t?54Qg2L+i33FPFKKRm1aOjKST{l1*(nps`>sv%VqeVMWjl5+Gh+9);hIP8? zA@$?}Sc z3qIRpba+y5yf{R6G(u8Z^vkg0Fu&D-7?1s=QZU`Ub{-!Y`I?AGf1VNuc^L3v>)>i# z{DV9W$)>34wnzAXUiV^ZpYKw>UElrN_5Xj6{r_3| z$X5PK`e5$7>~9Dj7gK5ash(dvs`vwfk}&RD`>04;j62zoXESkFBklYaKm5seyiX(P zqQ-;XxlV*yg?Dhlx%xt!b0N3GHp@(p$A;8|%# zZ5m2KL|{on4nr>2_s9Yh=r5ScQ0;aMF)G$-9-Ca6%wA`Pa)i?NGFA|#Yi?{X-4ZO_ z^}%7%vkzvUHa$-^Y#aA+aiR5sa%S|Ebyn`EV<3Pc?ax_f>@sBZF1S;7y$CXd5t5=WGsTKBk8$OfH4v|0?0I=Yp}7c=WBSCg!{0n)XmiU;lfx)**zZaYqmDJelxk$)nZyx5`x$6R|fz(;u zEje5Dtm|a%zK!!tk3{i9$I2b{vXNFy%Bf{50X!x{98+BsDr_u9i>G5%*sqEX|06J0 z^IY{UcEbj6LDwuMh7cH`H@9sVt1l1#8kEQ(LyT@&+K}(ReE`ux8gb0r6L_#bDUo^P z3Ka2lRo52Hdtl_%+pwVs14=q`{d^L58PsU@AMf(hENumaxM{7iAT5sYmWh@hQCO^ zK&}ijo=`VqZ#a3vE?`7QW0ZREL17ZvDfdqKGD?0D4fg{7v%|Yj&_jcKJAB)>=*RS* zto8p6@k%;&^ZF>hvXm&$PCuEp{uqw3VPG$9VMdW5$w-fy2CNNT>E;>ejBgy-m_6`& z97L1p{%srn@O_JQgFpa_#f(_)eb#YS>o>q3(*uB;uZb605(iqM$=NK{nHY=+X2*G) zO3-_Xh%aG}fHWe*==58zBwp%&`mge<8uq8;xIxOd=P%9EK!34^E9sk|(Zq1QSz-JVeP12Fp)-`F|KY$LPwUE?rku zY@OJ)Z9A!ojfzfeyJ9;zv2EM7ZQB)AR5xGa-tMn^bl)FmoIiVyJ@!~@%{}qXXD&Ns zPnfe5U+&ohKefILu_1mPfLGuapX@btta5C#gPB2cjk5m4T}Nfi+Vfka!Yd(L?-c~5 z#ZK4VeQEXNPc4r$K00Fg>g#_W!YZ)cJ?JTS<&68_$#cZT-ME`}tcwqg3#``3M3UPvn+pi}(VNNx6y zFIMVb6OwYU(2`at$gHba*qrMVUl8xk5z-z~fb@Q3Y_+aXuEKH}L+>eW__!IAd@V}L zkw#s%H0v2k5-=vh$^vPCuAi22Luu3uKTf6fPo?*nvj$9(u)4$6tvF-%IM+3pt*cgs z_?wW}J7VAA{_~!?))?s6{M=KPpVhg4fNuU*|3THp@_(q!b*hdl{fjRVFWtu^1dV(f z6iOux9hi&+UK=|%M*~|aqFK{Urfl!TA}UWY#`w(0P!KMe1Si{8|o))Gy6d7;!JQYhgMYmXl?3FfOM2nQGN@~Ap6(G z3+d_5y@=nkpKAhRqf{qQ~k7Z$v&l&@m7Ppt#FSNzKPZM z8LhihcE6i=<(#87E|Wr~HKvVWhkll4iSK$^mUHaxgy8*K$_Zj;zJ`L$naPj+^3zTi z-3NTaaKnD5FPY-~?Tq6QHnmDDRxu0mh0D|zD~Y=vv_qig5r-cIbCpxlju&8Sya)@{ zsmv6XUSi)@(?PvItkiZEeN*)AE~I_?#+Ja-r8$(XiXei2d@Hi7Rx8+rZZb?ZLa{;@*EHeRQ-YDadz~M*YCM4&F-r;E#M+@CSJMJ0oU|PQ^ z=E!HBJDMQ2TN*Y(Ag(ynAL8%^v;=~q?s4plA_hig&5Z0x_^Oab!T)@6kRN$)qEJ6E zNuQjg|G7iwU(N8pI@_6==0CL;lRh1dQF#wePhmu@hADFd3B5KIH#dx(2A zp~K&;Xw}F_N6CU~0)QpQk7s$a+LcTOj1%=WXI(U=Dv!6 z{#<#-)2+gCyyv=Jw?Ab#PVkxPDeH|sAxyG`|Ys}A$PW4TdBv%zDz z^?lwrxWR<%Vzc8Sgt|?FL6ej_*e&rhqJZ3Y>k=X(^dytycR;XDU16}Pc9Vn0>_@H+ zQ;a`GSMEG64=JRAOg%~L)x*w{2re6DVprNp+FcNra4VdNjiaF0M^*>CdPkt(m150rCue?FVdL0nFL$V%5y6N z%eLr5%YN7D06k5ji5*p4v$UMM)G??Q%RB27IvH7vYr_^3>1D-M66#MN8tWGw>WED} z5AhlsanO=STFYFs)Il_0i)l)f<8qn|$DW7ZXhf5xI;m+7M5-%P63XFQrG9>DMqHc} zsgNU9nR`b}E^mL5=@7<1_R~j@q_2U^3h|+`7YH-?C=vme1C3m`Fe0HC>pjt6f_XMh zy~-i-8R46QNYneL4t@)<0VU7({aUO?aH`z4V2+kxgH5pYD5)wCh75JqQY)jIPN=U6 z+qi8cGiOtXG2tXm;_CfpH9ESCz#i5B(42}rBJJF$jh<1sbpj^8&L;gzGHb8M{of+} zzF^8VgML2O9nxBW7AvdEt90vp+#kZxWf@A)o9f9}vKJy9NDBjBW zSt=Hcs=YWCwnfY1UYx*+msp{g!w0HC<_SM!VL1(I2PE?CS}r(eh?{I)mQixmo5^p# zV?2R!R@3GV6hwTCrfHiK#3Orj>I!GS2kYhk1S;aFBD_}u2v;0HYFq}Iz1Z(I4oca4 zxquja8$+8JW_EagDHf$a1OTk5S97umGSDaj)gH=fLs9>_=XvVj^Xj9a#gLdk=&3tl zfmK9MNnIX9v{?%xdw7568 zNrZ|roYs(vC4pHB5RJ8>)^*OuyNC>x7ad)tB_}3SgQ96+-JT^Qi<`xi=)_=$Skwv~ zdqeT9Pa`LYvCAn&rMa2aCDV(TMI#PA5g#RtV|CWpgDYRA^|55LLN^uNh*gOU>Z=a06qJ;$C9z8;n-Pq=qZnc1zUwJ@t)L;&NN+E5m zRkQ(SeM8=l-aoAKGKD>!@?mWTW&~)uF2PYUJ;tB^my`r9n|Ly~0c%diYzqs9W#FTjy?h&X3TnH zXqA{QI82sdjPO->f=^K^f>N`+B`q9&rN0bOXO79S&a9XX8zund(kW7O76f4dcWhIu zER`XSMSFbSL>b;Rp#`CuGJ&p$s~G|76){d?xSA5wVg##_O0DrmyEYppyBr%fyWbbv zp`K84JwRNP$d-pJ!Qk|(RMr?*!wi1if-9G#0p>>1QXKXWFy)eB3ai)l3601q8!9JC zvU#ZWWDNKq9g6fYs?JQ)Q4C_cgTy3FhgKb8s&m)DdmL5zhNK#8wWg!J*7G7Qhe9VU zha?^AQTDpYcuN!B+#1dE*X{<#!M%zfUQbj=zLE{dW0XeQ7-oIsGY6RbkP2re@Q{}r_$iiH0xU%iN*ST`A)-EH6eaZB$GA#v)cLi z*MpA(3bYk$oBDKAzu^kJoSUsDd|856DApz={3u8sbQV@JnRkp2nC|)m;#T=DvIL-O zI4vh;g7824l}*`_p@MT4+d`JZ2%6NQh=N9bmgJ#q!hK@_<`HQq3}Z8Ij>3%~<*= zcv=!oT#5xmeGI92lqm9sGVE%#X$ls;St|F#u!?5Y7syhx6q#MVRa&lBmmn%$C0QzU z);*ldgwwCmzM3uglr}!Z2G+?& zf%Dpo&mD%2ZcNFiN-Z0f;c_Q;A%f@>26f?{d1kxIJD}LxsQkB47SAdwinfMILZdN3 zfj^HmTzS3Ku5BxY>ANutS8WPQ-G>v4^_Qndy==P3pDm+Xc?>rUHl-4+^%Sp5atOja z2oP}ftw-rqnb}+khR3CrRg^ibi6?QYk1*i^;kQGirQ=uB9Sd1NTfT-Rbv;hqnY4neE5H1YUrjS2m+2&@uXiAo- zrKUX|Ohg7(6F(AoP~tj;NZlV#xsfo-5reuQHB$&EIAhyZk;bL;k9ouDmJNBAun;H& zn;Of1z_Qj`x&M;5X;{s~iGzBQTY^kv-k{ksbE*Dl%Qf%N@hQCfY~iUw!=F-*$cpf2 z3wix|aLBV0b;W@z^%7S{>9Z^T^fLOI68_;l@+Qzaxo`nAI8emTV@rRhEKZ z?*z_{oGdI~R*#<2{bkz$G~^Qef}$*4OYTgtL$e9q!FY7EqxJ2`zk6SQc}M(k(_MaV zSLJnTXw&@djco1~a(vhBl^&w=$fa9{Sru>7g8SHahv$&Bl(D@(Zwxo_3r=;VH|uc5 zi1Ny)J!<(KN-EcQ(xlw%PNwK8U>4$9nVOhj(y0l9X^vP1TA>r_7WtSExIOsz`nDOP zs}d>Vxb2Vo2e5x8p(n~Y5ggAyvib>d)6?)|E@{FIz?G3PVGLf7-;BxaP;c?7ddH$z zA+{~k^V=bZuXafOv!RPsE1GrR3J2TH9uB=Z67gok+u`V#}BR86hB1xl}H4v`F+mRfr zYhortD%@IGfh!JB(NUNSDh+qDz?4ztEgCz&bIG-Wg7w-ua4ChgQR_c+z8dT3<1?uX z*G(DKy_LTl*Ea!%v!RhpCXW1WJO6F`bgS-SB;Xw9#! z<*K}=#wVu9$`Yo|e!z-CPYH!nj7s9dEPr-E`DXUBu0n!xX~&|%#G=BeM?X@shQQMf zMvr2!y7p_gD5-!Lnm|a@z8Of^EKboZsTMk%5VsJEm>VsJ4W7Kv{<|#4f-qDE$D-W>gWT%z-!qXnDHhOvLk=?^a1*|0j z{pW{M0{#1VcR5;F!!fIlLVNh_Gj zbnW(_j?0c2q$EHIi@fSMR{OUKBcLr{Y&$hrM8XhPByyZaXy|dd&{hYQRJ9@Fn%h3p7*VQolBIV@Eq`=y%5BU~3RPa^$a?ixp^cCg z+}Q*X+CW9~TL29@OOng(#OAOd!)e$d%sr}^KBJ-?-X&|4HTmtemxmp?cT3uA?md4% zT8yZ0U;6Rg6JHy3fJae{6TMGS?ZUX6+gGTT{Q{)SI85$5FD{g-eR%O0KMpWPY`4@O zx!hen1*8^E(*}{m^V_?}(b5k3hYo=T+$&M32+B`}81~KKZhY;2H{7O-M@vbCzuX0n zW-&HXeyr1%I3$@ns-V1~Lb@wIpkmx|8I~ob1Of7i6BTNysEwI}=!nU%q7(V_^+d*G z7G;07m(CRTJup!`cdYi93r^+LY+`M*>aMuHJm(A8_O8C#A*$!Xvddgpjx5)?_EB*q zgE8o5O>e~9IiSC@WtZpF{4Bj2J5eZ>uUzY%TgWF7wdDE!fSQIAWCP)V{;HsU3ap?4 znRsiiDbtN7i9hapO;(|Ew>Ip2TZSvK9Z^N21%J?OiA_&eP1{(Pu_=%JjKy|HOardq ze?zK^K zA%sjF64*Wufad%H<) z^|t>e*h+Z1#l=5wHexzt9HNDNXgM=-OPWKd^5p!~%SIl>Fo&7BvNpbf8{NXmH)o{r zO=aBJ;meX1^{O%q;kqdw*5k!Y7%t_30 zy{nGRVc&5qt?dBwLs+^Sfp;f`YVMSB#C>z^a9@fpZ!xb|b-JEz1LBX7ci)V@W+kvQ89KWA0T~Lj$aCcfW#nD5bt&Y_< z-q{4ZXDqVg?|0o)j1%l0^_it0WF*LCn-+)c!2y5yS7aZIN$>0LqNnkujV*YVes(v$ zY@_-!Q;!ZyJ}Bg|G-~w@or&u0RO?vlt5*9~yeoPV_UWrO2J54b4#{D(D>jF(R88u2 zo#B^@iF_%S>{iXSol8jpmsZuJ?+;epg>k=$d`?GSegAVp3n$`GVDvK${N*#L_1`44 z{w0fL{2%)0|E+qgZtjX}itZz^KJt4Y;*8uSK}Ft38+3>j|K(PxIXXR-t4VopXo#9# zt|F{LWr-?34y`$nLBVV_*UEgA6AUI65dYIbqpNq9cl&uLJ0~L}<=ESlOm?Y-S@L*d z<7vt}`)TW#f%Rp$Q}6@3=j$7Tze@_uZO@aMn<|si{?S}~maII`VTjs&?}jQ4_cut9$)PEqMukwoXobzaKx^MV z2fQwl+;LSZ$qy%Tys0oo^K=jOw$!YwCv^ei4NBVauL)tN%=wz9M{uf{IB(BxK|lT*pFkmNK_1tV`nb%jH=a0~VNq2RCKY(rG7jz!-D^k)Ec)yS%17pE#o6&eY+ z^qN(hQT$}5F(=4lgNQhlxj?nB4N6ntUY6(?+R#B?W3hY_a*)hnr4PA|vJ<6p`K3Z5Hy z{{8(|ux~NLUW=!?9Qe&WXMTAkQnLXg(g=I@(VG3{HE13OaUT|DljyWXPs2FE@?`iU z4GQlM&Q=T<4&v@Fe<+TuXiZQT3G~vZ&^POfmI1K2h6t4eD}Gk5XFGpbj1n_g*{qmD6Xy z`6Vv|lLZtLmrnv*{Q%xxtcWVj3K4M%$bdBk_a&ar{{GWyu#ljM;dII;*jP;QH z#+^o-A4np{@|Mz+LphTD0`FTyxYq#wY)*&Ls5o{0z9yg2K+K7ZN>j1>N&;r+Z`vI| zDzG1LJZ+sE?m?>x{5LJx^)g&pGEpY=fQ-4}{x=ru;}FL$inHemOg%|R*ZXPodU}Kh zFEd5#+8rGq$Y<_?k-}r5zgQ3jRV=ooHiF|@z_#D4pKVEmn5CGV(9VKCyG|sT9nc=U zEoT67R`C->KY8Wp-fEcjjFm^;Cg(ls|*ABVHq8clBE(;~K^b+S>6uj70g? z&{XQ5U&!Z$SO7zfP+y^8XBbiu*Cv-yJG|l-oe*!s5$@Lh_KpxYL2sx`B|V=dETN>5K+C+CU~a_3cI8{vbu$TNVdGf15*>D zz@f{zIlorkY>TRh7mKuAlN9A0>N>SV`X)+bEHms=mfYTMWt_AJtz_h+JMmrgH?mZt zm=lfdF`t^J*XLg7v+iS)XZROygK=CS@CvUaJo&w2W!Wb@aa?~Drtf`JV^cCMjngVZ zv&xaIBEo8EYWuML+vxCpjjY^s1-ahXJzAV6hTw%ZIy!FjI}aJ+{rE&u#>rs)vzuxz z+$5z=7W?zH2>Eb32dvgHYZtCAf!=OLY-pb4>Ae79rd68E2LkVPj-|jFeyqtBCCwiW zkB@kO_(3wFq)7qwV}bA=zD!*@UhT`geq}ITo%@O(Z5Y80nEX~;0-8kO{oB6|(4fQh z);73T!>3@{ZobPwRv*W?7m0Ml9GmJBCJd&6E?hdj9lV= z4flNfsc(J*DyPv?RCOx!MSvk(M952PJ-G|JeVxWVjN~SNS6n-_Ge3Q;TGE;EQvZg86%wZ`MB zSMQua(i*R8a75!6$QRO^(o7sGoomb+Y{OMy;m~Oa`;P9Yqo>?bJAhqXxLr7_3g_n>f#UVtxG!^F#1+y@os6x(sg z^28bsQ@8rw%Gxk-stAEPRbv^}5sLe=VMbkc@Jjimqjvmd!3E7+QnL>|(^3!R} zD-l1l7*Amu@j+PWLGHXXaFG0Ct2Q=}5YNUxEQHCAU7gA$sSC<5OGylNnQUa>>l%sM zyu}z6i&({U@x^hln**o6r2s-(C-L50tQvz|zHTqW!ir?w&V23tuYEDJVV#5pE|OJu z7^R!A$iM$YCe?8n67l*J-okwfZ+ZTkGvZ)tVPfR;|3gyFjF)8V zyXXN=!*bpyRg9#~Bg1+UDYCt0 ztp4&?t1X0q>uz;ann$OrZs{5*r`(oNvw=$7O#rD|Wuv*wIi)4b zGtq4%BX+kkagv3F9Id6~-c+1&?zny%w5j&nk9SQfo0k4LhdSU_kWGW7axkfpgR`8* z!?UTG*Zi_baA1^0eda8S|@&F z{)Rad0kiLjB|=}XFJhD(S3ssKlveFFmkN{Vl^_nb!o5M!RC=m)V&v2%e?ZoRC@h3> zJ(?pvToFd`*Zc@HFPL#=otWKwtuuQ_dT-Hr{S%pQX<6dqVJ8;f(o)4~VM_kEQkMR+ zs1SCVi~k>M`u1u2xc}>#D!V&6nOOh-E$O&SzYrjJdZpaDv1!R-QGA141WjQe2s0J~ zQ;AXG)F+K#K8_5HVqRoRM%^EduqOnS(j2)|ctA6Q^=|s_WJYU;Z%5bHp08HPL`YF2 zR)Ad1z{zh`=sDs^&V}J z%$Z$!jd7BY5AkT?j`eqMs%!Gm@T8)4w3GYEX~IwgE~`d|@T{WYHkudy(47brgHXx& zBL1yFG6!!!VOSmDxBpefy2{L_u5yTwja&HA!mYA#wg#bc-m%~8aRR|~AvMnind@zs zy>wkShe5&*un^zvSOdlVu%kHsEo>@puMQ`b1}(|)l~E{5)f7gC=E$fP(FC2=F<^|A zxeIm?{EE!3sO!Gr7e{w)Dx(uU#3WrFZ>ibmKSQ1tY?*-Nh1TDHLe+k*;{Rp!Bmd_m zb#^kh`Y*8l|9Cz2e{;RL%_lg{#^Ar+NH|3z*Zye>!alpt{z;4dFAw^^H!6ING*EFc z_yqhr8d!;%nHX9AKhFQZBGrSzfzYCi%C!(Q5*~hX>)0N`vbhZ@N|i;_972WSx*>LH z87?en(;2_`{_JHF`Sv6Wlps;dCcj+8IJ8ca6`DsOQCMb3n# z3)_w%FuJ3>fjeOOtWyq)ag|PmgQbC-s}KRHG~enBcIwqIiGW8R8jFeBNY9|YswRY5 zjGUxdGgUD26wOpwM#8a!Nuqg68*dG@VM~SbOroL_On0N6QdT9?)NeB3@0FCC?Z|E0 z6TPZj(AsPtwCw>*{eDEE}Gby>0q{*lI+g2e&(YQrsY&uGM{O~}(oM@YWmb*F zA0^rr5~UD^qmNljq$F#ARXRZ1igP`MQx4aS6*MS;Ot(1L5jF2NJ;de!NujUYg$dr# z=TEL_zTj2@>ZZN(NYCeVX2==~=aT)R30gETO{G&GM4XN<+!&W&(WcDP%oL8PyIVUC zs5AvMgh6qr-2?^unB@mXK*Dbil^y-GTC+>&N5HkzXtozVf93m~xOUHn8`HpX=$_v2 z61H;Z1qK9o;>->tb8y%#4H)765W4E>TQ1o0PFj)uTOPEvv&}%(_mG0ISmyhnQV33Z$#&yd{ zc{>8V8XK$3u8}04CmAQ#I@XvtmB*s4t8va?-IY4@CN>;)mLb_4!&P3XSw4pA_NzDb zORn!blT-aHk1%Jpi>T~oGLuh{DB)JIGZ9KOsciWs2N7mM1JWM+lna4vkDL?Q)z_Ct z`!mi0jtr+4*L&N7jk&LodVO#6?_qRGVaucqVB8*us6i3BTa^^EI0x%EREQSXV@f!lak6Wf1cNZ8>*artIJ(ADO*=<-an`3zB4d*oO*8D1K!f z*A@P1bZCNtU=p!742MrAj%&5v%Xp_dSX@4YCw%F|%Dk=u|1BOmo)HsVz)nD5USa zR~??e61sO(;PR)iaxK{M%QM_rIua9C^4ppVS$qCT9j2%?*em?`4Z;4@>I(c%M&#cH z>4}*;ej<4cKkbCAjjDsyKS8rIm90O)Jjgyxj5^venBx&7B!xLmzxW3jhj7sR(^3Fz z84EY|p1NauwXUr;FfZjdaAfh%ivyp+^!jBjJuAaKa!yCq=?T_)R!>16?{~p)FQ3LDoMyG%hL#pR!f@P%*;#90rs_y z@9}@r1BmM-SJ#DeuqCQk=J?ixDSwL*wh|G#us;dd{H}3*-Y7Tv5m=bQJMcH+_S`zVtf;!0kt*(zwJ zs+kedTm!A}cMiM!qv(c$o5K%}Yd0|nOd0iLjus&;s0Acvoi-PFrWm?+q9f^FslxGi z6ywB`QpL$rJzWDg(4)C4+!2cLE}UPCTBLa*_=c#*$b2PWrRN46$y~yST3a2$7hEH= zNjux+wna^AzQ=KEa_5#9Ph=G1{S0#hh1L3hQ`@HrVnCx{!fw_a0N5xV(iPdKZ-HOM za)LdgK}1ww*C_>V7hbQnTzjURJL`S%`6nTHcgS+dB6b_;PY1FsrdE8(2K6FN>37!62j_cBlui{jO^$dPkGHV>pXvW0EiOA zqW`YaSUBWg_v^Y5tPJfWLcLpsA8T zG)!x>pKMpt!lv3&KV!-um= zKCir6`bEL_LCFx4Z5bAFXW$g3Cq`?Q%)3q0r852XI*Der*JNuKUZ`C{cCuu8R8nkt z%pnF>R$uY8L+D!V{s^9>IC+bmt<05h**>49R*#vpM*4i0qRB2uPbg8{{s#9yC;Z18 zD7|4m<9qneQ84uX|J&f-g8a|nFKFt34@Bt{CU`v(SYbbn95Q67*)_Esl_;v291s=9 z+#2F2apZU4Tq=x+?V}CjwD(P=U~d<=mfEFuyPB`Ey82V9G#Sk8H_Ob_RnP3s?)S_3 zr%}Pb?;lt_)Nf>@zX~D~TBr;-LS<1I##8z`;0ZCvI_QbXNh8Iv)$LS=*gHr;}dgb=w5$3k2la1keIm|=7<-JD>)U%=Avl0Vj@+&vxn zt-)`vJxJr88D&!}2^{GPXc^nmRf#}nb$4MMkBA21GzB`-Or`-3lq^O^svO7Vs~FdM zv`NvzyG+0T!P8l_&8gH|pzE{N(gv_tgDU7SWeiI-iHC#0Ai%Ixn4&nt{5y3(GQs)i z&uA;~_0shP$0Wh0VooIeyC|lak__#KVJfxa7*mYmZ22@(<^W}FdKjd*U1CqSjNKW% z*z$5$=t^+;Ui=MoDW~A7;)Mj%ibX1_p4gu>RC}Z_pl`U*{_z@+HN?AF{_W z?M_X@o%w8fgFIJ$fIzBeK=v#*`mtY$HC3tqw7q^GCT!P$I%=2N4FY7j9nG8aIm$c9 zeKTxVKN!UJ{#W)zxW|Q^K!3s;(*7Gbn;e@pQBCDS(I|Y0euK#dSQ_W^)sv5pa%<^o zyu}3d?Lx`)3-n5Sy9r#`I{+t6x%I%G(iewGbvor&I^{lhu-!#}*Q3^itvY(^UWXgvthH52zLy&T+B)Pw;5>4D6>74 zO_EBS)>l!zLTVkX@NDqyN2cXTwsUVao7$HcqV2%t$YzdAC&T)dwzExa3*kt9d(}al zA~M}=%2NVNUjZiO7c>04YH)sRelXJYpWSn^aC$|Ji|E13a^-v2MB!Nc*b+=KY7MCm zqIteKfNkONq}uM;PB?vvgQvfKLPMB8u5+Am=d#>g+o&Ysb>dX9EC8q?D$pJH!MTAqa=DS5$cb+;hEvjwVfF{4;M{5U&^_+r zvZdu_rildI!*|*A$TzJ&apQWV@p{!W`=?t(o0{?9y&vM)V)ycGSlI3`;ps(vf2PUq zX745#`cmT*ra7XECC0gKkpu2eyhFEUb?;4@X7weEnLjXj_F~?OzL1U1L0|s6M+kIhmi%`n5vvDALMagi4`wMc=JV{XiO+^ z?s9i7;GgrRW{Mx)d7rj)?(;|b-`iBNPqdwtt%32se@?w4<^KU&585_kZ=`Wy^oLu9 z?DQAh5z%q;UkP48jgMFHTf#mj?#z|=w= z(q6~17Vn}P)J3M?O)x))%a5+>TFW3No~TgP;f}K$#icBh;rSS+R|}l鯊%1Et zwk~hMkhq;MOw^Q5`7oC{CUUyTw9x>^%*FHx^qJw(LB+E0WBX@{Ghw;)6aA-KyYg8p z7XDveQOpEr;B4je@2~usI5BlFadedX^ma{b{ypd|RNYqo#~d*mj&y`^iojR}s%~vF z(H!u`yx68D1Tj(3(m;Q+Ma}s2n#;O~bcB1`lYk%Irx60&-nWIUBr2x&@}@76+*zJ5 ze&4?q8?m%L9c6h=J$WBzbiTf1Z-0Eb5$IZs>lvm$>1n_Mezp*qw_pr8<8$6f)5f<@ zyV#tzMCs51nTv_5ca`x`yfE5YA^*%O_H?;tWYdM_kHPubA%vy47i=9>Bq) zRQ&0UwLQHeswmB1yP)+BiR;S+Vc-5TX84KUA;8VY9}yEj0eESSO`7HQ4lO z4(CyA8y1G7_C;6kd4U3K-aNOK!sHE}KL_-^EDl(vB42P$2Km7$WGqNy=%fqB+ zSLdrlcbEH=T@W8V4(TgoXZ*G1_aq$K^@ek=TVhoKRjw;HyI&coln|uRr5mMOy2GXP zwr*F^Y|!Sjr2YQXX(Fp^*`Wk905K%$bd03R4(igl0&7IIm*#f`A!DCarW9$h$z`kYk9MjjqN&5-DsH@8xh63!fTNPxWsFQhNv z#|3RjnP$Thdb#Ys7M+v|>AHm0BVTw)EH}>x@_f4zca&3tXJhTZ8pO}aN?(dHo)44Z z_5j+YP=jMlFqwvf3lq!57-SAuRV2_gJ*wsR_!Y4Z(trO}0wmB9%f#jNDHPdQGHFR; zZXzS-$`;7DQ5vF~oSgP3bNV$6Z(rwo6W(U07b1n3UHqml>{=6&-4PALATsH@Bh^W? z)ob%oAPaiw{?9HfMzpGb)@Kys^J$CN{uf*HX?)z=g`J(uK1YO^8~s1(ZIbG%Et(|q z$D@_QqltVZu9Py4R0Ld8!U|#`5~^M=b>fnHthzKBRr=i+w@0Vr^l|W;=zFT#PJ?*a zbC}G#It}rQP^Ait^W&aa6B;+0gNvz4cWUMzpv(1gvfw-X4xJ2Sv;mt;zb2Tsn|kSS zo*U9N?I{=-;a-OybL4r;PolCfiaL=y@o9{%`>+&FI#D^uy#>)R@b^1ue&AKKwuI*` zx%+6r48EIX6nF4o;>)zhV_8(IEX})NGU6Vs(yslrx{5fII}o3SMHW7wGtK9oIO4OM&@@ECtXSICLcPXoS|{;=_yj>hh*%hP27yZwOmj4&Lh z*Nd@OMkd!aKReoqNOkp5cW*lC)&C$P?+H3*%8)6HcpBg&IhGP^77XPZpc%WKYLX$T zsSQ$|ntaVVOoRat$6lvZO(G-QM5s#N4j*|N_;8cc2v_k4n6zx9c1L4JL*83F-C1Cn zaJhd;>rHXB%%ZN=3_o3&Qd2YOxrK~&?1=UuN9QhL$~OY-Qyg&})#ez*8NpQW_*a&kD&ANjedxT0Ar z<6r{eaVz3`d~+N~vkMaV8{F?RBVemN(jD@S8qO~L{rUw#=2a$V(7rLE+kGUZ<%pdr z?$DP|Vg#gZ9S}w((O2NbxzQ^zTot=89!0^~hE{|c9q1hVzv0?YC5s42Yx($;hAp*E zyoGuRyphQY{Q2ee0Xx`1&lv(l-SeC$NEyS~8iil3_aNlnqF_G|;zt#F%1;J)jnPT& z@iU0S;wHJ2$f!juqEzPZeZkjcQ+Pa@eERSLKsWf=`{R@yv7AuRh&ALRTAy z8=g&nxsSJCe!QLchJ=}6|LshnXIK)SNd zRkJNiqHwKK{SO;N5m5wdL&qK`v|d?5<4!(FAsDxR>Ky#0#t$8XCMptvNo?|SY?d8b z`*8dVBlXTUanlh6n)!EHf2&PDG8sXNAt6~u-_1EjPI1|<=33T8 zEnA00E!`4Ave0d&VVh0e>)Dc}=FfAFxpsC1u9ATfQ`-Cu;mhc8Z>2;uyXtqpLb7(P zd2F9<3cXS} znMg?{&8_YFTGRQZEPU-XPq55%51}RJpw@LO_|)CFAt62-_!u_Uq$csc+7|3+TV_!h z+2a7Yh^5AA{q^m|=KSJL+w-EWDBc&I_I1vOr^}P8i?cKMhGy$CP0XKrQzCheG$}G# zuglf8*PAFO8%xop7KSwI8||liTaQ9NCAFarr~psQt)g*pC@9bORZ>m`_GA`_K@~&% zijH0z;T$fd;-Liw8%EKZas>BH8nYTqsK7F;>>@YsE=Rqo?_8}UO-S#|6~CAW0Oz1} z3F(1=+#wrBJh4H)9jTQ_$~@#9|Bc1Pd3rAIA_&vOpvvbgDJOM(yNPhJJq2%PCcMaI zrbe~toYzvkZYQ{ea(Wiyu#4WB#RRN%bMe=SOk!CbJZv^m?Flo5p{W8|0i3`hI3Np# zvCZqY%o258CI=SGb+A3yJe~JH^i{uU`#U#fvSC~rWTq+K`E%J@ zasU07&pB6A4w3b?d?q}2=0rA#SA7D`X+zg@&zm^iA*HVi z009#PUH<%lk4z~p^l0S{lCJk1Uxi=F4e_DwlfHA`X`rv(|JqWKAA5nH+u4Da+E_p+ zVmH@lg^n4ixs~*@gm_dgQ&eDmE1mnw5wBz9Yg?QdZwF|an67Xd*x!He)Gc8&2!urh z4_uXzbYz-aX)X1>&iUjGp;P1u8&7TID0bTH-jCL&Xk8b&;;6p2op_=y^m@Nq*0{#o!!A;wNAFG@0%Z9rHo zcJs?Th>Ny6+hI`+1XoU*ED$Yf@9f91m9Y=#N(HJP^Y@ZEYR6I?oM{>&Wq4|v0IB(p zqX#Z<_3X(&{H+{3Tr|sFy}~=bv+l=P;|sBz$wk-n^R`G3p0(p>p=5ahpaD7>r|>pm zv;V`_IR@tvZreIuv2EM7ZQHhO+qUgw#kOs%*ekY^n|=1#x9&c;Ro&I~{rG-#_3ZB1 z?|9}IFdbP}^DneP*T-JaoYHt~r@EfvnPE5EKUwIxjPbsr$% zfWW83pgWST7*B(o=kmo)74$8UU)v0{@4DI+ci&%=#90}!CZz|rnH+Mz=HN~97G3~@ z;v5(9_2%eca(9iu@J@aqaMS6*$TMw!S>H(b z4(*B!|H|8&EuB%mITr~O?vVEf%(Gr)6E=>H~1VR z&1YOXluJSG1!?TnT)_*YmJ*o_Q@om~(GdrhI{$Fsx_zrkupc#y{DK1WOUR>tk>ZE) ziOLoBkhZZ?0Uf}cm>GsA>Rd6V8@JF)J*EQlQ<=JD@m<)hyElXR0`pTku*3MU`HJn| zIf7$)RlK^pW-$87U;431;Ye4Ie+l~_B3*bH1>*yKzn23cH0u(i5pXV! z4K?{3oF7ZavmmtTq((wtml)m6i)8X6ot_mrE-QJCW}Yn!(3~aUHYG=^fA<^~`e3yc z-NWTb{gR;DOUcK#zPbN^D*e=2eR^_!(!RKkiwMW@@yYtEoOp4XjOGgzi`;=8 zi3`Ccw1%L*y(FDj=C7Ro-V?q)-%p?Ob2ZElu`eZ99n14-ZkEV#y5C+{Pq87Gu3&>g zFy~Wk7^6v*)4pF3@F@rE__k3ikx(hzN3@e*^0=KNA6|jC^B5nf(XaoQaZN?Xi}Rn3 z$8&m*KmWvPaUQ(V<#J+S&zO|8P-#!f%7G+n_%sXp9=J%Z4&9OkWXeuZN}ssgQ#Tcj z8p6ErJQJWZ+fXLCco=RN8D{W%+*kko*2-LEb))xcHwNl~Xmir>kmAxW?eW50Osw3# zki8Fl$#fvw*7rqd?%E?}ZX4`c5-R&w!Y0#EBbelVXSng+kUfeUiqofPehl}$ormli zg%r)}?%=?_pHb9`Cq9Z|B`L8b>(!+8HSX?`5+5mm81AFXfnAt1*R3F z%b2RPIacKAddx%JfQ8l{3U|vK@W7KB$CdLqn@wP^?azRks@x8z59#$Q*7q!KilY-P zHUbs(IFYRGG1{~@RF;Lqyho$~7^hNC`NL3kn^Td%A7dRgr_&`2k=t+}D-o9&C!y^? z6MsQ=tc3g0xkK(O%DzR9nbNB(r@L;1zQrs8mzx&4dz}?3KNYozOW5;=w18U6$G4U2 z#2^qRLT*Mo4bV1Oeo1PKQ2WQS2Y-hv&S|C7`xh6=Pj7MNLC5K-zokZ67S)C;(F0Dd zloDK2_o1$Fmza>EMj3X9je7e%Q`$39Dk~GoOj89-6q9|_WJlSl!!+*{R=tGp z8u|MuSwm^t7K^nUe+^0G3dkGZr3@(X+TL5eah)K^Tn zXEtHmR9UIaEYgD5Nhh(s*fcG_lh-mfy5iUF3xxpRZ0q3nZ=1qAtUa?(LnT9I&~uxX z`pV?+=|-Gl(kz?w!zIieXT}o}7@`QO>;u$Z!QB${a08_bW0_o@&9cjJUXzVyNGCm8 zm=W+$H!;_Kzp6WQqxUI;JlPY&`V}9C$8HZ^m?NvI*JT@~BM=()T()Ii#+*$y@lTZBkmMMda>7s#O(1YZR+zTG@&}!EXFG{ zEWPSDI5bFi;NT>Yj*FjH((=oe%t%xYmE~AGaOc4#9K_XsVpl<4SP@E!TgC0qpe1oi zNpxU2b0(lEMcoibQ-G^cxO?ySVW26HoBNa;n0}CWL*{k)oBu1>F18X061$SP{Gu67 z-v-Fa=Fl^u3lnGY^o5v)Bux}bNZ~ z5pL+7F_Esoun8^5>z8NFoIdb$sNS&xT8_|`GTe8zSXQzs4r^g0kZjg(b0bJvz`g<70u9Z3fQILX1Lj@;@+##bP|FAOl)U^9U>0rx zGi)M1(Hce)LAvQO-pW!MN$;#ZMX?VE(22lTlJrk#pB0FJNqVwC+*%${Gt#r_tH9I_ z;+#)#8cWAl?d@R+O+}@1A^hAR1s3UcW{G+>;X4utD2d9X(jF555}!TVN-hByV6t+A zdFR^aE@GNNgSxxixS2p=on4(+*+f<8xrwAObC)D5)4!z7)}mTpb7&ofF3u&9&wPS< zB62WHLGMhmrmOAgmJ+|c>qEWTD#jd~lHNgT0?t-p{T=~#EMcB| z=AoDKOL+qXCfk~F)-Rv**V}}gWFl>liXOl7Uec_8v)(S#av99PX1sQIVZ9eNLkhq$ zt|qu0b?GW_uo}TbU8!jYn8iJeIP)r@;!Ze_7mj{AUV$GEz6bDSDO=D!&C9!M@*S2! zfGyA|EPlXGMjkH6x7OMF?gKL7{GvGfED=Jte^p=91FpCu)#{whAMw`vSLa`K#atdN zThnL+7!ZNmP{rc=Z>%$meH;Qi1=m1E3Lq2D_O1-X5C;!I0L>zur@tPAC9*7Jeh)`;eec}1`nkRP(%iv-`N zZ@ip-g|7l6Hz%j%gcAM}6-nrC8oA$BkOTz^?dakvX?`^=ZkYh%vUE z9+&)K1UTK=ahYiaNn&G5nHUY5niLGus@p5E2@RwZufRvF{@$hW{;{3QhjvEHMvduO z#Wf-@oYU4ht?#uP{N3utVzV49mEc9>*TV_W2TVC`6+oI)zAjy$KJrr=*q##&kobiQ z1vNbya&OVjK`2pdRrM?LuK6BgrLN7H_3m z!qpNKg~87XgCwb#I=Q&0rI*l$wM!qTkXrx1ko5q-f;=R2fImRMwt5Qs{P*p^z@9ex z`2#v(qE&F%MXlHpdO#QEZyZftn4f05ab^f2vjxuFaat2}jke{j?5GrF=WYBR?gS(^ z9SBiNi}anzBDBRc+QqizTTQuJrzm^bNA~A{j%ugXP7McZqJ}65l10({wk++$=e8O{ zxWjG!Qp#5OmI#XRQQM?n6?1ztl6^D40hDJr?4$Wc&O_{*OfMfxe)V0=e{|N?J#fgE>j9jAajze$iN!*yeF%jJU#G1c@@rm zolGW!j?W6Q8pP=lkctNFdfgUMg92wlM4E$aks1??M$~WQfzzzXtS)wKrr2sJeCN4X zY(X^H_c^PzfcO8Bq(Q*p4c_v@F$Y8cHLrH$`pJ2}=#*8%JYdqsqnGqEdBQMpl!Ot04tUGSXTQdsX&GDtjbWD=prcCT9(+ z&UM%lW%Q3yrl1yiYs;LxzIy>2G}EPY6|sBhL&X&RAQrSAV4Tlh2nITR?{6xO9ujGu zr*)^E`>o!c=gT*_@6S&>0POxcXYNQd&HMw6<|#{eSute2C3{&h?Ah|cw56-AP^f8l zT^kvZY$YiH8j)sk7_=;gx)vx-PW`hbSBXJGCTkpt;ap(}G2GY=2bbjABU5)ty%G#x zAi07{Bjhv}>OD#5zh#$0w;-vvC@^}F! z#X$@)zIs1L^E;2xDAwEjaXhTBw2<{&JkF*`;c3<1U@A4MaLPe{M5DGGkL}#{cHL%* zYMG+-Fm0#qzPL#V)TvQVI|?_M>=zVJr9>(6ib*#z8q@mYKXDP`k&A4A};xMK0h=yrMp~JW{L?mE~ph&1Y1a#4%SO)@{ zK2juwynUOC)U*hVlJU17%llUxAJFuKZh3K0gU`aP)pc~bE~mM!i1mi!~LTf>1Wp< zuG+ahp^gH8g8-M$u{HUWh0m^9Rg@cQ{&DAO{PTMudV6c?ka7+AO& z746QylZ&Oj`1aqfu?l&zGtJnpEQOt;OAFq19MXTcI~`ZcoZmyMrIKDFRIDi`FH)w; z8+*8tdevMDv*VtQi|e}CnB_JWs>fhLOH-+Os2Lh!&)Oh2utl{*AwR)QVLS49iTp{6 z;|172Jl!Ml17unF+pd+Ff@jIE-{Oxv)5|pOm@CkHW?{l}b@1>Pe!l}VccX#xp@xgJ zyE<&ep$=*vT=}7vtvif0B?9xw_3Gej7mN*dOHdQPtW5kA5_zGD zpA4tV2*0E^OUimSsV#?Tg#oiQ>%4D@1F5@AHwT8Kgen$bSMHD3sXCkq8^(uo7CWk`mT zuslYq`6Yz;L%wJh$3l1%SZv#QnG3=NZ=BK4yzk#HAPbqXa92;3K5?0kn4TQ`%E%X} z&>Lbt!!QclYKd6+J7Nl@xv!uD%)*bY-;p`y^ZCC<%LEHUi$l5biu!sT3TGGSTPA21 zT8@B&a0lJHVn1I$I3I1I{W9fJAYc+8 zVj8>HvD}&O`TqU2AAb={?eT;0hyL(R{|h23=4fDSZKC32;wWxsVj`P z3J3{M$PwdH!ro*Cn!D&=jnFR>BNGR<<|I8CI@+@658Dy(lhqbhXfPTVecY@L8%`3Q z1Fux2w?2C3th60jI~%OC9BtpNF$QPqcG+Pz96qZJ71_`0o0w_q7|h&O>`6U+^BA&5 zXd5Zp1Xkw~>M%RixTm&OqpNl8Q+ue=92Op_>T~_9UON?ZM2c0aGm=^A4ejrXj3dV9 zhh_bCt-b9`uOX#cFLj!vhZ#lS8Tc47OH>*)y#{O9?AT~KR9LntM|#l#Dlm^8{nZdk zjMl#>ZM%#^nK2TPzLcKxqx24P7R1FPlBy7LSBrRvx>fE$9AJ;7{PQm~^LBX^k#6Zq zw*Z(zJC|`!6_)EFR}8|n8&&Rbj8y028~P~sFXBFRt+tmqH-S3<%N;C&WGH!f3{7cm zy_fCAb9@HqaXa1Y5vFbxWf%#zg6SI$C+Uz5=CTO}e|2fjWkZ;Dx|84Ow~bkI=LW+U zuq;KSv9VMboRvs9)}2PAO|b(JCEC_A0wq{uEj|3x@}*=bOd zwr{TgeCGG>HT<@Zeq8y}vTpwDg#UBvD)BEs@1KP$^3$sh&_joQPn{hjBXmLPJ{tC) z*HS`*2+VtJO{|e$mM^|qv1R*8i(m1`%)}g=SU#T#0KlTM2RSvYUc1fP+va|4;5}Bfz98UvDCpq7}+SMV&;nX zQw~N6qOX{P55{#LQkrZk(e5YGzr|(B;Q;ju;2a`q+S9bsEH@i1{_Y0;hWYn1-79jl z5c&bytD*k)GqrVcHn6t-7kinadiD>B{Tl`ZY@`g|b~pvHh5!gKP4({rp?D0aFd_cN zhHRo4dd5^S6ViN(>(28qZT6E>??aRhc($kP`>@<+lIKS5HdhjVU;>f7<4))E*5|g{ z&d1}D|vpuV^eRj5j|xx9nwaCxXFG?Qbjn~_WSy=N}P0W>MP zG-F%70lX5Xr$a)2i6?i|iMyM|;Jtf*hO?=Jxj12oz&>P=1#h~lf%#fc73M2_(SUM- zf&qnjS80|_Y0lDgl&I?*eMumUklLe_=Td!9G@eR*tcPOgIShJipp3{A10u(4eT~DY zHezEj8V+7m!knn7)W!-5QI3=IvC^as5+TW1@Ern@yX| z7Nn~xVx&fGSr+L%4iohtS3w^{-H1A_5=r&x8}R!YZvp<2T^YFvj8G_vm}5q;^UOJf ztl=X3iL;;^^a#`t{Ae-%5Oq{?M#s6Npj+L(n-*LMI-yMR{)qki!~{5z{&`-iL}lgW zxo+tnvICK=lImjV$Z|O_cYj_PlEYCzu-XBz&XC-JVxUh9;6*z4fuBG+H{voCC;`~GYV|hj%j_&I zDZCj>Q_0RCwFauYoVMiUSB+*Mx`tg)bWmM^SwMA+?lBg12QUF_x2b)b?qb88K-YUd z0dO}3k#QirBV<5%jL$#wlf!60dizu;tsp(7XLdI=eQs?P`tOZYMjVq&jE)qK*6B^$ zBe>VvH5TO>s>izhwJJ$<`a8fakTL!yM^Zfr2hV9`f}}VVUXK39p@G|xYRz{fTI+Yq z20d=)iwjuG9RB$%$^&8#(c0_j0t_C~^|n+c`Apu|x7~;#cS-s=X1|C*YxX3ailhg_|0`g!E&GZJEr?bh#Tpb8siR=JxWKc{#w7g zWznLwi;zLFmM1g8V5-P#RsM@iX>TK$xsWuujcsVR^7TQ@!+vCD<>Bk9tdCo7Mzgq5 zv8d>dK9x8C@Qoh01u@3h0X_`SZluTb@5o;{4{{eF!-4405x8X7hewZWpz z2qEi4UTiXTvsa(0X7kQH{3VMF>W|6;6iTrrYD2fMggFA&-CBEfSqPlQDxqsa>{e2M z(R5PJ7uOooFc|9GU0ELA%m4&4Ja#cQpNw8i8ACAoK6?-px+oBl_yKmenZut#Xumjz zk8p^OV2KY&?5MUwGrBOo?ki`Sxo#?-Q4gw*Sh0k`@ zFTaYK2;}%Zk-68`#5DXU$2#=%YL#S&MTN8bF+!J2VT6x^XBci6O)Q#JfW{YMz) zOBM>t2rSj)n#0a3cjvu}r|k3od6W(SN}V-cL?bi*Iz-8uOcCcsX0L>ZXjLqk zZu2uHq5B|Kt>e+=pPKu=1P@1r9WLgYFq_TNV1p9pu0erHGd!+bBp!qGi+~4A(RsYN@CyXNrC&hxGmW)u5m35OmWwX`I+0yByglO`}HC4nGE^_HUs^&A(uaM zKPj^=qI{&ayOq#z=p&pnx@@k&I1JI>cttJcu@Ihljt?6p^6{|ds`0MoQwp+I{3l6` zB<9S((RpLG^>=Kic`1LnhpW2=Gu!x`m~=y;A`Qk!-w`IN;S8S930#vBVMv2vCKi}u z6<-VPrU0AnE&vzwV(CFC0gnZYcpa-l5T0ZS$P6(?9AM;`Aj~XDvt;Jua=jIgF=Fm? zdp=M$>`phx%+Gu};;-&7T|B1AcC#L4@mW5SV_^1BRbo6;2PWe$r+npRV`yc;T1mo& z+~_?7rA+(Um&o@Tddl zL_hxvWk~a)yY}%j`Y+200D%9$bWHy&;(yj{jpi?Rtz{J66ANw)UyPOm;t6FzY3$hx zcn)Ir79nhFvNa7^a{SHN7XH*|Vlsx`CddPnA&Qvh8aNhEA;mPVv;Ah=k<*u!Zq^7 z<=xs*iQTQOMMcg|(NA_auh@x`3#_LFt=)}%SQppP{E>mu_LgquAWvh<>L7tf9+~rO znwUDS52u)OtY<~!d$;m9+87aO+&`#2ICl@Y>&F{jI=H(K+@3M1$rr=*H^dye#~TyD z!){#Pyfn+|ugUu}G;a~!&&0aqQ59U@UT3|_JuBlYUpT$2+11;}JBJ`{+lQN9T@QFY z5+`t;6(TS0F?OlBTE!@7D`8#URDNqx2t6`GZ{ZgXeS@v%-eJzZOHz18aS|svxII$a zZeFjrJ*$IwX$f-Rzr_G>xbu@euGl)B7pC&S+CmDJBg$BoV~jxSO#>y z33`bupN#LDoW0feZe0%q8un0rYN|eRAnwDHQ6e_)xBTbtoZtTA=Fvk){q}9Os~6mQ zKB80VI_&6iSq`LnK7*kfHZoeX6?WE}8yjuDn=2#JG$+;-TOA1%^=DnXx%w{b=w}tS zQbU3XxtOI8E(!%`64r2`zog;5<0b4i)xBmGP^jiDZ2%HNSxIf3@wKs~uk4%3Mxz;~ zts_S~E4>W+YwI<-*-$U8*^HKDEa8oLbmqGg?3vewnaNg%Mm)W=)lcC_J+1ov^u*N3 zXJ?!BrH-+wGYziJq2Y#vyry6Z>NPgkEk+Ke`^DvNRdb>Q2Nlr#v%O@<5hbflI6EKE z9dWc0-ORk^T}jP!nkJ1imyjdVX@GrjOs%cpgA8-c&FH&$(4od#x6Y&=LiJZPINVyW z0snY$8JW@>tc2}DlrD3StQmA0Twck~@>8dSix9CyQOALcREdxoM$Sw*l!}bXKq9&r zysMWR@%OY24@e`?+#xV2bk{T^C_xSo8v2ZI=lBI*l{RciPwuE>L5@uhz@{!l)rtVlWC>)6(G)1~n=Q|S!{E9~6*fdpa*n z!()-8EpTdj=zr_Lswi;#{TxbtH$8*G=UM`I+icz7sr_SdnHXrv=?iEOF1UL+*6O;% zPw>t^kbW9X@oEXx<97%lBm-9?O_7L!DeD)Me#rwE54t~UBu9VZ zl_I1tBB~>jm@bw0Aljz8! zXBB6ATG6iByKIxs!qr%pz%wgqbg(l{65DP4#v(vqhhL{0b#0C8mq`bnqZ1OwFV z7mlZZJFMACm>h9v^2J9+^_zc1=JjL#qM5ZHaThH&n zXPTsR8(+)cj&>Un{6v*z?@VTLr{TmZ@-fY%*o2G}*G}#!bmqpoo*Ay@U!JI^Q@7gj;Kg-HIrLj4}#ec4~D2~X6vo;ghep-@&yOivYP zC19L0D`jjKy1Yi-SGPAn94(768Tcf$urAf{)1)9W58P`6MA{YG%O?|07!g9(b`8PXG1B1Sh0?HQmeJtP0M$O$hI z{5G`&9XzYhh|y@qsF1GnHN|~^ru~HVf#)lOTSrv=S@DyR$UKQk zjdEPFDz{uHM&UM;=mG!xKvp;xAGHOBo~>_=WFTmh$chpC7c`~7?36h)7$fF~Ii}8q zF|YXxH-Z?d+Q+27Rs3X9S&K3N+)OBxMHn1u(vlrUC6ckBY@@jl+mgr#KQUKo#VeFm zFwNYgv0<%~Wn}KeLeD9e1$S>jhOq&(e*I@L<=I5b(?G(zpqI*WBqf|Zge0&aoDUsC zngMRA_Kt0>La+Erl=Uv_J^p(z=!?XHpenzn$%EA`JIq#yYF?JLDMYiPfM(&Csr#f{ zdd+LJL1by?xz|D8+(fgzRs~(N1k9DSyK@LJygwaYX8dZl0W!I&c^K?7)z{2is;OkE zd$VK-(uH#AUaZrp=1z;O*n=b?QJkxu`Xsw&7yrX0?(CX=I-C#T;yi8a<{E~?vr3W> zQrpPqOW2M+AnZ&p{hqmHZU-;Q(7?- zP8L|Q0RM~sB0w1w53f&Kd*y}ofx@c z5Y6B8qGel+uT1JMot$nT1!Tim6{>oZzJXdyA+4euOLME?5Fd_85Uk%#E*ln%y{u8Q z$|?|R@Hpb~yTVK-Yr_S#%NUy7EBfYGAg>b({J|5b+j-PBpPy$Ns`PaJin4JdRfOaS zE|<HjH%NuJgsd2wOlv>~y=np%=2)$M9LS|>P)zJ+Fei5vYo_N~B0XCn+GM76 z)Xz3tg*FRVFgIl9zpESgdpWAavvVViGlU8|UFY{{gVJskg*I!ZjWyk~OW-Td4(mZ6 zB&SQreAAMqwp}rjy`HsG({l2&q5Y52<@AULVAu~rWI$UbFuZs>Sc*x+XI<+ez%$U)|a^unjpiW0l0 zj1!K0(b6$8LOjzRqQ~K&dfbMIE=TF}XFAi)$+h}5SD3lo z%%Qd>p9se=VtQG{kQ;N`sI)G^u|DN#7{aoEd zkksYP%_X$Rq08);-s6o>CGJ<}v`qs%eYf+J%DQ^2k68C%nvikRsN?$ap--f+vCS`K z#&~)f7!N^;sdUXu54gl3L=LN>FB^tuK=y2e#|hWiWUls__n@L|>xH{%8lIJTd5`w? zSwZbnS;W~DawT4OwSJVdAylbY+u5S+ZH{4hAi2&}Iv~W(UvHg(1GTZRPz`@{SOqzy z(8g&Dz=$PfRV=6FgxN~zo+G8OoPI&d-thcGVR*_^(R8COTM@bq?fDwY{}WhsQS1AK zF6R1t8!RdFmfocpJ6?9Yv~;WYi~XPgs(|>{5})j!AR!voO7y9&cMPo#80A(`za@t>cx<0;qxM@S*m(jYP)dMXr*?q0E`oL;12}VAep179uEr8c<=D zr5?A*C{eJ`z9Ee;E$8)MECqatHkbHH z&Y+ho0B$31MIB-xm&;xyaFCtg<{m~M-QDbY)fQ>Q*Xibb~8ytxZQ?QMf9!%cV zU0_X1@b4d+Pg#R!`OJ~DOrQz3@cpiGy~XSKjZQQ|^4J1puvwKeScrH8o{bscBsowomu z^f12kTvje`yEI3eEXDHJ6L+O{Jv$HVj%IKb|J{IvD*l6IG8WUgDJ*UGz z3!C%>?=dlfSJ>4U88)V+`U-!9r^@AxJBx8R;)J4Fn@`~k>8>v0M9xp90OJElWP&R5 zM#v*vtT}*Gm1^)Bv!s72T3PB0yVIjJW)H7a)ilkAvoaH?)jjb`MP>2z{%Y?}83 zUIwBKn`-MSg)=?R)1Q0z3b>dHE^)D8LFs}6ASG1|daDly_^lOSy&zIIhm*HXm1?VS=_iacG);_I9c zUQH1>i#*?oPIwBMJkzi_*>HoUe}_4o>2(SHWzqQ=;TyhAHS;Enr7!#8;sdlty&(>d zl%5cjri8`2X^Ds`jnw7>A`X|bl=U8n+3LKLy(1dAu8`g@9=5iw$R0qk)w8Vh_Dt^U zIglK}sn^)W7aB(Q>HvrX=rxB z+*L)3DiqpQ_%~|m=44LcD4-bxO3OO*LPjsh%p(k?&jvLp0py57oMH|*IMa(<|{m1(0S|x)?R-mqJ=I;_YUZA>J z62v*eSK;5w!h8J+6Z2~oyGdZ68waWfy09?4fU&m7%u~zi?YPHPgK6LDwphgaYu%0j zurtw)AYOpYKgHBrkX189mlJ`q)w-f|6>IER{5Lk97%P~a-JyCRFjejW@L>n4vt6#hq;!|m;hNE||LK3nw1{bJOy+eBJjK=QqNjI;Q6;Rp5 z&035pZDUZ#%Oa;&_7x0T<7!RW`#YBOj}F380Bq?MjjEhrvlCATPdkCTTl+2efTX$k zH&0zR1n^`C3ef~^sXzJK-)52(T}uTG%OF8yDhT76L~|^+hZ2hiSM*QA9*D5odI1>& z9kV9jC~twA5MwyOx(lsGD_ggYmztXPD`2=_V|ks_FOx!_J8!zM zTzh^cc+=VNZ&(OdN=y4Juw)@8-85lwf_#VMN!Ed(eQiRiLB2^2e`4dp286h@v@`O%_b)Y~A; zv}r6U?zs&@uD_+(_4bwoy7*uozNvp?bXFoB8?l8yG0qsm1JYzIvB_OH4_2G*IIOwT zVl%HX1562vLVcxM_RG*~w_`FbIc!(T=3>r528#%mwwMK}uEhJ()3MEby zQQjzqjWkwfI~;Fuj(Lj=Ug0y`>~C7`w&wzjK(rPw+Hpd~EvQ-ufQOiB4OMpyUKJhw zqEt~jle9d7S~LI~$6Z->J~QJ{Vdn3!c}g9}*KG^Kzr^(7VI5Gk(mHLL{itj_hG?&K4Ws0+T4gLfi3eu$N=`s36geNC?c zm!~}vG6lx9Uf^5M;bWntF<-{p^bruy~f?sk9 zcETAPQZLoJ8JzMMg<-=ju4keY@SY%Wo?u9Gx=j&dfa6LIAB|IrbORLV1-H==Z1zCM zeZcOYpm5>U2fU7V*h;%n`8 zN95QhfD994={1*<2vKLCNF)feKOGk`R#K~G=;rfq}|)s20&MCa65 zUM?xF5!&e0lF%|U!#rD@I{~OsS_?=;s_MQ_b_s=PuWdC)q|UQ&ea)DMRh5>fpQjXe z%9#*x=7{iRCtBKT#H>#v%>77|{4_slZ)XCY{s3j_r{tdpvb#|r|sbS^dU1x70$eJMU!h{Y7Kd{dl}9&vxQl6Jt1a` zHQZrWyY0?!vqf@u-fxU_@+}u(%Wm>0I#KP48tiAPYY!TdW(o|KtVI|EUB9V`CBBNaBLVih7+yMVF|GSoIQD0Jfb{ z!OXq;(>Z?O`1gap(L~bUcp>Lc@Jl-})^=6P%<~~9ywY=$iu8pJ0m*hOPzr~q`23eX zgbs;VOxxENe0UMVeN*>uCn9Gk!4siN-e>x)pIKAbQz!G)TcqIJ0`JBBaX>1-4_XO_-HCS^vr2vjv#7KltDZdyQ{tlWh4$Gm zB>|O1cBDC)yG(sbnc*@w6e%e}r*|IhpXckx&;sQCwGdKH+3oSG-2)Bf#x`@<4ETAr z0My%7RFh6ZLiZ_;X6Mu1YmXx7C$lSZ^}1h;j`EZd6@%JNUe=btBE z%s=Xmo1Ps?8G`}9+6>iaB8bgjUdXT?=trMu|4yLX^m0Dg{m7rpKNJey|EwHI+nN1e zL^>qN%5Fg)dGs4DO~uwIdXImN)QJ*Jhpj7$fq_^`{3fwpztL@WBB}OwQ#Epo-mqMO zsM$UgpFiG&d#)lzEQ{3Q;)&zTw;SzGOah-Dpm{!q7<8*)Ti_;xvV2TYXa}=faXZy? z3y?~GY@kl)>G&EvEijk9y1S`*=zBJSB1iet>0;x1Ai)*`^{pj0JMs)KAM=@UyOGtO z3y0BouW$N&TnwU6!%zS%nIrnANvZF&vB1~P5_d`x-giHuG zPJ;>XkVoghm#kZXRf>qxxEix;2;D1CC~NrbO6NBX!`&_$iXwP~P*c($EVV|669kDO zKoTLZNF4Cskh!Jz5ga9uZ`3o%7Pv`d^;a=cXI|>y;zC3rYPFLQkF*nv(r>SQvD*## z(Vo%^9g`%XwS0t#94zPq;mYGLKu4LU3;txF26?V~A0xZbU4Lmy`)>SoQX^m7fd^*E z+%{R4eN!rIk~K)M&UEzxp9dbY;_I^c} zOc{wlIrN_P(PPqi51k_$>Lt|X6A^|CGYgKAmoI#Li?;Wq%q~q*L7ehZkUrMxW67Jl zhsb~+U?33QS>eqyN{(odAkbopo=Q$Az?L+NZW>j;#~@wCDX?=L5SI|OxI~7!Pli;e zELMFcZtJY3!|=Gr2L4>z8yQ-{To>(f80*#;6`4IAiqUw`=Pg$%C?#1 z_g@hIGerILSU>=P>z{gM|DS91A4cT@PEIB^hSop!uhMo#2G;+tQSpDO_6nOnPWSLU zS;a9m^DFMXR4?*X=}d7l;nXuHk&0|m`NQn%d?8|Ab3A9l9Jh5s120ibWBdB z$5YwsK3;wvp!Kn@)Qae{ef`0#NwlRpQ}k^r>yos_Ne1;xyKLO?4)t_G4eK~wkUS2A&@_;)K0-03XGBzU+5f+uMDxC z(s8!8!RvdC#@`~fx$r)TKdLD6fWEVdEYtV#{ncT-ZMX~eI#UeQ-+H(Z43vVn%Yj9X zLdu9>o%wnWdvzA-#d6Z~vzj-}V3FQ5;axDIZ;i(95IIU=GQ4WuU{tl-{gk!5{l4_d zvvb&uE{%!iFwpymz{wh?bKr1*qzeZb5f6e6m_ozRF&zux2mlK=v_(_s^R6b5lu?_W4W3#<$zeG~Pd)^!4tzhs}-Sx$FJP>)ZGF(hVTH|C3(U zs0PO&*h_ zNA-&qZpTP$$LtIgfiCn07}XDbK#HIXdmv8zdz4TY;ifNIH-0jy(gMSByG2EF~Th#eb_TueZC` zE?3I>UTMpKQ})=C;6p!?G)M6w^u*A57bD?2X`m3X^6;&4%i_m(uGJ3Z5h`nwxM<)H z$I5m?wN>O~8`BGnZ=y^p6;0+%_0K}Dcg|K;+fEi|qoBqvHj(M&aHGqNF48~XqhtU? z^ogwBzRlOfpAJ+Rw7IED8lRbTdBdyEK$gPUpUG}j-M42xDj_&qEAQEtbs>D#dRd7Y z<&TpSZ(quQDHiCFn&0xsrz~4`4tz!CdL8m~HxZM_agu@IrBpyeL1Ft}V$HX_ZqDPm z-f89)pjuEzGdq-PRu`b1m+qBGY{zr_>{6Ss>F|xHZlJj9dt5HD$u`1*WZe)qEIuDSR)%z+|n zatVlhQ?$w#XRS7xUrFE;Y8vMGhQS5*T{ZnY=q1P?w5g$OKJ#M&e??tAmPWHMj3xhS ziGxapy?kn@$~2%ZY;M8Bc@%$pkl%Rvj!?o%agBvpQ-Q61n9kznC4ttrRNQ4%GFR5u zyv%Yo9~yxQJWJSfj z?#HY$y=O~F|2pZs22pu|_&Ajd+D(Mt!nPUG{|1nlvP`=R#kKH zO*s$r_%ss5h1YO7k0bHJ2CXN)Yd6CHn~W!R=SqkWe=&nAZu(Q1G!xgcUilM@YVei@2@a`8he z9@pM`)VB*=e7-MWgLlXlc)t;fF&-AwM{E-EX}pViFn0I0CNw2bNEnN2dj!^4(^zS3 zobUm1uQnpqk_4q{pl*n06=TfK_C>UgurKFjRXsK_LEn};=79`TB12tv6KzwSu*-C8 z;=~ohDLZylHQ|Mpx-?yql>|e=vI1Z!epyUpAcDCp4T|*RV&X`Q$0ogNwy6mFALo^@ z9=&(9txO8V@E!@6^(W0{*~CT>+-MA~vnJULBxCTUW>X5>r7*eXYUT0B6+w@lzw%n> z_VjJ<2qf|(d6jYq2(x$(ZDf!yVkfnbvNmb5c|hhZ^2TV_LBz`9w!e_V*W_(MiA7|= z&EeIIkw*+$Xd!)j8<@_<}A5;~A_>3JT*kX^@}cDoLd>Qj<`Se^wdUa(j0dp+Tl8EptwBm{9OGsdFEq zM`!pjf(Lm(`$e3FLOjqA5LnN5o!}z{ zNf}rJuZh@yUtq&ErjHeGzX4(!luV!jB&;FAP|!R_QHYw#^Z1LwTePAKJ6X&IDNO#; z)#I@Xnnzyij~C@UH~X51JCgQeF0&hTXnuoElz#m{heZRexWc0k4<>0+ClX7%0 zEBqCCld1tD9Zwkr4{?Nor19#E5-YKfB8d?qgR82-Ow2^AuNevly2*tHA|sK!ybYkX zm-sLQH72P&{vEAW6+z~O5d0qd=xW~rua~5a?ymYFSD@8&gV)E5@RNNBAj^C99+Z5Z zR@Pq55mbCQbz+Mn$d_CMW<-+?TU960agEk1J<>d>0K=pF19yN))a~4>m^G&tc*xR+yMD*S=yip-q=H zIlredHpsJV8H(32@Zxc@bX6a21dUV95Th--8pE6C&3F>pk=yv$yd6@Haw;$v4+Fcb zRwn{Qo@0`7aPa2LQOP}j9v>sjOo5Kqvn|`FLizX zB+@-u4Lw|jsvz{p^>n8Vo8H2peIqJJnMN}A)q6%$Tmig7eu^}K2 zrh$X?T|ZMsoh{6pdw1G$_T<`Ds-G=jc;qcGdK4{?dN2-XxjDNbb(7pk|3JUVCU4y; z)?LXR>f+AAu)JEiti_Zy#z5{RgsC}R(@jl%9YZ>zu~hKQ*AxbvhC378-I@{~#%Y`Z zy=a=9YpewPIC+gkEUUwtUL7|RU7=!^Aa}Mk^6uxOgRGA#JXjWLsjFUnix|Mau{hDT z7mn*z1m5g`vP(#tjT0Zy4eAY(br&!RiiXE=ZI!{sE1#^#%x^Z7t1U)b<;%Y}Q9=5v z;wpDCEZ@OE36TWT=|gxigT@VaW9BvHS05;_P(#s z8zI4XFQys}q)<`tkX$WnSarn{3e!s}4(J!=Yf>+Y>cP3f;vr63f2{|S^`_pWc)^5_!R z*(x-fuBxL51@xe!lnDBKi}Br$c$BMZ3%f2Sa6kLabiBS{pq*yj;q|k(86x`PiC{p6 z_bxCW{>Q2BA8~Ggz&0jkrcU+-$ANBsOop*ms>34K9lNYil@}jC;?cYP(m^P}nR6FV zk(M%48Z&%2Rx$A&FhOEirEhY0(dn;-k(qkTU)sFQ`+-ih+s@A8g?r8Pw+}2;35WYf zi}VO`jS`p(tc)$X$a>-#WXoW!phhatC*$}|rk>|wUU71eUJG^$c6_jwX?iSHM@6__ zvV|6%U*$sSXJu9SX?2%M^kK|}a2QJ8AhF{fuXrHZxXsI~O zGKX45!K7p*MCPEQ=gp?eu&#AW*pR{lhQR##P_*{c_DjMGL|3T3-bSJ(o$|M{ytU}> zAV>wq*uE*qFo9KvnA^@juy{x<-u*#2NvkV={Ly}ysKYB-k`K3@K#^S1Bb$8Y#0L0# z`6IkSG&|Z$ODy|VLS+y5pFJx&8tvPmMd8c9FhCyiU8~k6FwkakUd^(_ml8`rnl>JS zZV){9G*)xBqPz^LDqRwyS6w86#D^~xP4($150M)SOZRe9sn=>V#aG0Iy(_^YcPpIz8QYM-#s+n% z@Jd?xQq?Xk6=<3xSY7XYP$$yd&Spu{A#uafiIfy8gRC`o0nk{ezEDjb=q_qRAlR1d zFq^*9Gn)yTG4b}R{!+3hWQ+u3GT~8nwl2S1lpw`s0X_qpxv)g+JIkVKl${sYf_nV~B>Em>M;RlqGb5WVil(89 zs=ld@|#;dq1*vQGz=7--Br-|l) zZ%Xh@v8>B7P?~}?Cg$q9_={59l%m~O&*a6TKsCMAzG&vD>k2WDzJ6!tc!V)+oxF;h zJH;apM=wO?r_+*#;ulohuP=E>^zon}a$NnlcQ{1$SO*i=jnGVcQa^>QOILc)e6;eNTI>os=eaJ{*^DE+~jc zS}TYeOykDmJ=6O%>m`i*>&pO_S;qMySJIyP=}4E&J%#1zju$RpVAkZbEl+p%?ZP^C z*$$2b4t%a(e+%>a>d_f_<JjxI#J1x;=hPd1zFPx=6T$;;X1TD*2(edZ3f46zaAoW>L53vS_J*N8TMB|n+;LD| zC=GkQPpyDY#Am4l49chDv*gojhRj_?63&&8#doW`INATAo(qY#{q}%nf@eTIXmtU< zdB<7YWfyCmBs|c)cK>1)v&M#!yNj#4d$~pVfDWQc_ke1?fw{T1Nce_b`v|Vp5ig(H zJvRD^+ps46^hLX;=e2!2e;w9y1D@!D$c@Jc&%%%IL=+xzw55&2?darw=9g~>P z9>?Kdc$r?6c$m%x2S$sdpPl>GQZ{rC9mPS63*qjCVa?OIBj!fW zm|g?>CVfGXNjOfcyqImXR_(tXS(F{FcoNzKvG5R$IgGaxC@)i(e+$ME}vPVIhd|mx2IIE+f zM?9opQHIVgBWu)^A|RzXw!^??S!x)SZOwZaJkGjc<_}2l^eSBm!eAJG9T>EC6I_sy z?bxzDIAn&K5*mX)$RQzDA?s)-no-XF(g*yl4%+GBf`##bDXJ==AQk*xmnatI;SsLp zP9XTHq5mmS=iWu~9ES>b%Q=1aMa|ya^vj$@qz9S!ih{T8_PD%Sf_QrNKwgrXw9ldm zHRVR98*{C?_XNpJn{abA!oix_mowRMu^2lV-LPi;0+?-F(>^5#OHX-fPED zCu^l7u3E%STI}c4{J2!)9SUlGP_@!d?5W^QJXOI-Ea`hFMKjR7TluLvzC-ozCPn1`Tpy z!vlv@_Z58ILX6>nDjTp-1LlFMx~-%GA`aJvG$?8*Ihn;mH37eK**rmOEwqegf-Ccx zrIX4;{c~RK>XuTXxYo5kMiWMy)!IC{*DHG@E$hx?RwP@+wuad(P1{@%tRkyJRqD)3 zMHHHZ4boqDn>-=DgR5VlhQTpfVy182Gk;A_S8A1-;U1RR>+$62>(MUx@Nox$vTjHq z%QR=j!6Gdyb5wu7y(YUktwMuW5<@jl?m4cv4BODiT5o8qVdC0MBqGr@-YBIwnpZAY znX9(_uQjP}JJ=!~Ve9#5I~rUnN|P_3D$LqZcvBnywYhjlMSFHm`;u9GPla{5QD7(7*6Tb3Svr8;(nuAd81q$*uq6HC_&~je*Ca7hP4sJp0av{M8480wF zxASi7Qv+~@2U%Nu1Ud;s-G4CTVWIPyx!sg&8ZG0Wq zG_}i3C(6_1>q3w!EH7$Kwq8uBp2F2N7}l65mk1p*9v0&+;th=_E-W)E;w}P(j⁢ zv5o9#E7!G0XmdzfsS{efPNi`1b44~SZ4Z8fuX!I}#8g+(wxzQwUT#Xb2(tbY1+EUhGKoT@KEU9Ktl>_0 z%bjDJg;#*gtJZv!-Zs`?^}v5eKmnbjqlvnSzE@_SP|LG_PJ6CYU+6zY6>92%E+ z=j@TZf-iW4(%U{lnYxQA;7Q!b;^brF8n0D>)`q5>|WDDXLrqYU_tKN2>=#@~OE7grMnNh?UOz-O~6 z6%rHy{#h9K0AT+lDC7q4{hw^|q6*Ry;;L%Q@)Ga}$60_q%D)rv(CtS$CQbpq9|y1e zRSrN4;$Jyl{m5bZw`$8TGvb}(LpY{-cQ)fcyJv7l3S52TLXVDsphtv&aPuDk1OzCA z4A^QtC(!11`IsNx_HnSy?>EKpHJWT^wmS~hc^p^zIIh@9f6U@I2 zC=Mve{j2^)mS#U$e{@Q?SO6%LDsXz@SY+=cK_QMmXBIU)j!$ajc-zLx3V60EXJ!qC zi<%2x8Q24YN+&8U@CIlN zrZkcT9yh%LrlGS9`G)KdP(@9Eo-AQz@8GEFWcb7U=a0H^ZVbLmz{+&M7W(nXJ4sN8 zJLR7eeK(K8`2-}j(T7JsO`L!+CvbueT%izanm-^A1Dn{`1Nw`9P?cq;7no+XfC`K(GO9?O^5zNIt4M+M8LM0=7Gz8UA@Z0N+lg+cX)NfazRu z5D)~HA^(u%w^cz+@2@_#S|u>GpB+j4KzQ^&Wcl9f z&hG#bCA(Yk0D&t&aJE^xME^&E-&xGHhXn%}psEIj641H+Nl-}boj;)Zt*t(4wZ5DN z@GXF$bL=&pBq-#vkTkh>7hl%K5|3 z{`Vn9b$iR-SoGENp}bn4;fR3>9sA%X2@1L3aE9yTra;Wb#_`xWwLSLdfu+PAu+o3| zGVnpzPr=ch{uuoHjtw7+_!L_2;knQ!DuDl0R`|%jr+}jFzXtrHIKc323?JO{l&;VF z*L1+}JU7%QJOg|5|Tc|D8fN zJORAg=_vsy{ak|o);@)Yh8Lkcg@$FG3k@ep36BRa^>~UmnRPziS>Z=`Jb2x*Q#`%A zU*i3&Vg?TluO@X0O;r2Jl6LKLUOVhSqg1*qOt^|8*c7 zo(298@+r$k_wQNGHv{|$tW(T8L+4_`FQ{kEW5Jgg{yf7ey4ss_(SNKfz(N9lx&a;< je(UuV8hP?p&}TPdm1I$XmG#(RzlD&B2izSj9sl%y5~4qc diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 46671acb6e1..db8c3baafe3 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,7 +1,7 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionSha256Sum=3e1af3ae886920c3ac87f7a91f816c0c7c436f276a6eefdb3da152100fef72ae -distributionUrl=https\://services.gradle.org/distributions/gradle-8.4-bin.zip +distributionSha256Sum=9d926787066a081739e8200858338b4a69e837c3a821a33aca9db09dd4a41026 +distributionUrl=https\://services.gradle.org/distributions/gradle-8.5-bin.zip networkTimeout=10000 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME From 6867bd04bd764bdec6ea13a8dbe00f4030d47bab Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 30 Nov 2023 10:10:03 -0600 Subject: [PATCH 122/901] Update dependency com.google.api.grpc:proto-google-common-protos to v2.29.0 (#6032) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- dependencyManagement/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index 1f097d61588..5656f95954b 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -55,7 +55,7 @@ val DEPENDENCIES = listOf( "io.prometheus:simpleclient_httpserver:${prometheusClientVersion}", "javax.annotation:javax.annotation-api:1.3.2", "com.github.stefanbirkner:system-rules:1.19.0", - "com.google.api.grpc:proto-google-common-protos:2.28.0", + "com.google.api.grpc:proto-google-common-protos:2.29.0", "com.google.code.findbugs:jsr305:3.0.2", "com.google.guava:guava-beta-checker:1.0", "com.sun.net.httpserver:http:20070405", From 0e9ca2b863e18ae6841eca370bfa8ca24a18cce3 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 30 Nov 2023 10:11:02 -0600 Subject: [PATCH 123/901] Update actions/setup-java action to v4 (#6030) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/benchmark-tags.yml | 2 +- .github/workflows/benchmark.yml | 2 +- .github/workflows/build.yml | 6 +++--- .github/workflows/codeql-daily.yml | 2 +- .github/workflows/owasp-dependency-check-daily.yml | 2 +- .github/workflows/release.yml | 2 +- 6 files changed, 8 insertions(+), 8 deletions(-) diff --git a/.github/workflows/benchmark-tags.yml b/.github/workflows/benchmark-tags.yml index 7fb9a182150..d10653a48a6 100644 --- a/.github/workflows/benchmark-tags.yml +++ b/.github/workflows/benchmark-tags.yml @@ -45,7 +45,7 @@ jobs: - id: setup-java name: Set up Java for build - uses: actions/setup-java@v3 + uses: actions/setup-java@v4 with: distribution: temurin java-version: 17 diff --git a/.github/workflows/benchmark.yml b/.github/workflows/benchmark.yml index 493e695909d..bb23f7fea17 100644 --- a/.github/workflows/benchmark.yml +++ b/.github/workflows/benchmark.yml @@ -15,7 +15,7 @@ jobs: - id: setup-java name: Set up Java for build - uses: actions/setup-java@v3 + uses: actions/setup-java@v4 with: distribution: temurin java-version: 17 diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 5c404d4b0b4..0732faec59a 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -37,14 +37,14 @@ jobs: - id: setup-java-test name: Set up Java ${{ matrix.test-java-version }} for tests - uses: actions/setup-java@v3 + uses: actions/setup-java@v4 with: distribution: temurin java-version: ${{ matrix.test-java-version }} - id: setup-java name: Set up Java for build - uses: actions/setup-java@v3 + uses: actions/setup-java@v4 with: distribution: temurin java-version: 17 @@ -113,7 +113,7 @@ jobs: - id: setup-java name: Set up Java - uses: actions/setup-java@v3 + uses: actions/setup-java@v4 with: distribution: temurin java-version: 17 diff --git a/.github/workflows/codeql-daily.yml b/.github/workflows/codeql-daily.yml index b54c40e7cd4..90032c303bc 100644 --- a/.github/workflows/codeql-daily.yml +++ b/.github/workflows/codeql-daily.yml @@ -14,7 +14,7 @@ jobs: - uses: actions/checkout@v4 - name: Set up Java 17 - uses: actions/setup-java@v3 + uses: actions/setup-java@v4 with: distribution: temurin java-version: 17 diff --git a/.github/workflows/owasp-dependency-check-daily.yml b/.github/workflows/owasp-dependency-check-daily.yml index cce51d9e57a..ae86cb64c13 100644 --- a/.github/workflows/owasp-dependency-check-daily.yml +++ b/.github/workflows/owasp-dependency-check-daily.yml @@ -14,7 +14,7 @@ jobs: steps: - uses: actions/checkout@v4 - - uses: actions/setup-java@v3 + - uses: actions/setup-java@v4 with: distribution: temurin java-version: 17 diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index ba4f236c4c1..66e7cf0bd3a 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -16,7 +16,7 @@ jobs: - uses: actions/checkout@v4 - - uses: actions/setup-java@v3 + - uses: actions/setup-java@v4 with: distribution: temurin java-version: 17 From 537a4dfc1b160ddeedd056a806f3f2a2e49e8faf Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 30 Nov 2023 10:11:32 -0600 Subject: [PATCH 124/901] Update dependency nl.jqno.equalsverifier:equalsverifier to v3.15.4 (#6028) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- dependencyManagement/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index 5656f95954b..cdbffcea12f 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -70,7 +70,7 @@ val DEPENDENCIES = listOf( "io.opentracing:opentracing-api:0.33.0", "io.opentracing:opentracing-noop:0.33.0", "junit:junit:4.13.2", - "nl.jqno.equalsverifier:equalsverifier:3.15.3", + "nl.jqno.equalsverifier:equalsverifier:3.15.4", "org.awaitility:awaitility:4.2.0", "org.bouncycastle:bcpkix-jdk15on:1.70", "org.codehaus.mojo:animal-sniffer-annotations:1.23", From 14eaa4cdf893f8f65285264ca72918399628f0ef Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 30 Nov 2023 11:14:59 -0600 Subject: [PATCH 125/901] Update dependency com.diffplug.spotless:spotless-plugin-gradle to v6.23.0 (#6016) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Co-authored-by: Jack Berg --- buildSrc/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts index 542aba04e4e..30cad6351dc 100644 --- a/buildSrc/build.gradle.kts +++ b/buildSrc/build.gradle.kts @@ -45,7 +45,7 @@ dependencies { implementation(enforcedPlatform("com.squareup.wire:wire-bom:4.9.3")) implementation("com.google.auto.value:auto-value-annotations:1.10.4") // When updating, update above in plugins too - implementation("com.diffplug.spotless:spotless-plugin-gradle:6.22.0") + implementation("com.diffplug.spotless:spotless-plugin-gradle:6.23.2") // Needed for japicmp but not automatically brought in for some reason. implementation("com.google.guava:guava:32.1.3-jre") implementation("com.squareup:javapoet:1.13.0") From 40325e56dd0f339978ed015738b32a4d57e924fe Mon Sep 17 00:00:00 2001 From: jack-berg <34418638+jack-berg@users.noreply.github.com> Date: Thu, 30 Nov 2023 17:00:20 -0600 Subject: [PATCH 126/901] Remove exception handling in TlsUtil#decodePem (#6034) --- .../io/opentelemetry/exporter/internal/TlsUtil.java | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/exporters/common/src/main/java/io/opentelemetry/exporter/internal/TlsUtil.java b/exporters/common/src/main/java/io/opentelemetry/exporter/internal/TlsUtil.java index 4d177402241..785291635f1 100644 --- a/exporters/common/src/main/java/io/opentelemetry/exporter/internal/TlsUtil.java +++ b/exporters/common/src/main/java/io/opentelemetry/exporter/internal/TlsUtil.java @@ -33,7 +33,6 @@ import javax.net.ssl.TrustManagerFactory; import javax.net.ssl.X509KeyManager; import javax.net.ssl.X509TrustManager; -import org.codehaus.mojo.animal_sniffer.IgnoreJRERequirement; /** * Utilities for working with TLS. @@ -142,9 +141,6 @@ public static X509TrustManager trustManager(byte[] trustedCertificatesPem) throw } } - // We catch linkage error to provide a better exception message on Android. - // https://github.com/open-telemetry/opentelemetry-java/issues/4533 - @IgnoreJRERequirement // Visible for testing static byte[] decodePem(byte[] pem) { String pemStr = new String(pem, StandardCharsets.UTF_8).trim(); @@ -157,12 +153,6 @@ static byte[] decodePem(byte[] pem) { pemStr.substring(PEM_KEY_HEADER.length(), pemStr.length() - PEM_KEY_FOOTER.length()); String content = contentWithNewLines.replaceAll("\\s", ""); - try { - return Base64.getDecoder().decode(content); - } catch (LinkageError unused) { - throw new IllegalArgumentException( - "PEM private keys are currently not supported on Android. " - + "You may try a key encoded as DER."); - } + return Base64.getDecoder().decode(content); } } From f1deb8ec78cd446bc6310b1528a5d71e1d42989e Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 30 Nov 2023 17:00:42 -0600 Subject: [PATCH 127/901] Update dependency com.uber.nullaway:nullaway to v0.10.18 (#6033) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- dependencyManagement/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index cdbffcea12f..31d3ae274f5 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -60,7 +60,7 @@ val DEPENDENCIES = listOf( "com.google.guava:guava-beta-checker:1.0", "com.sun.net.httpserver:http:20070405", "com.tngtech.archunit:archunit-junit5:1.2.0", - "com.uber.nullaway:nullaway:0.10.17", + "com.uber.nullaway:nullaway:0.10.18", "edu.berkeley.cs.jqf:jqf-fuzz:1.7", // jqf-fuzz version 1.8+ requires Java 11+ "eu.rekawek.toxiproxy:toxiproxy-java:2.1.7", "io.github.netmikey.logunit:logunit-jul:2.0.0", From e447e347e143ebb1838b01c6bb23bd40e3c4f723 Mon Sep 17 00:00:00 2001 From: jason plumb <75337021+breedx-splk@users.noreply.github.com> Date: Mon, 4 Dec 2023 09:40:09 -0800 Subject: [PATCH 128/901] Allow for simpler creation of start-only and end-only SpanProcessors. (#5923) --- .../TestTracerProviderConfigurer.java | 27 ++-------- .../incubator/trace/OnEndSpanProcessor.java | 49 ++++++++++++++++++ .../incubator/trace/OnStartSpanProcessor.java | 50 +++++++++++++++++++ .../trace/OnEndSpanProcessorTest.java | 31 ++++++++++++ .../trace/OnStartSpanProcessorTest.java | 39 +++++++++++++++ 5 files changed, 173 insertions(+), 23 deletions(-) create mode 100644 sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/trace/OnEndSpanProcessor.java create mode 100644 sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/trace/OnStartSpanProcessor.java create mode 100644 sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/trace/OnEndSpanProcessorTest.java create mode 100644 sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/trace/OnStartSpanProcessorTest.java diff --git a/sdk-extensions/autoconfigure/src/testFullConfig/java/io/opentelemetry/sdk/autoconfigure/provider/TestTracerProviderConfigurer.java b/sdk-extensions/autoconfigure/src/testFullConfig/java/io/opentelemetry/sdk/autoconfigure/provider/TestTracerProviderConfigurer.java index 3546b8f8160..31d5e8a2dd7 100644 --- a/sdk-extensions/autoconfigure/src/testFullConfig/java/io/opentelemetry/sdk/autoconfigure/provider/TestTracerProviderConfigurer.java +++ b/sdk-extensions/autoconfigure/src/testFullConfig/java/io/opentelemetry/sdk/autoconfigure/provider/TestTracerProviderConfigurer.java @@ -5,12 +5,9 @@ package io.opentelemetry.sdk.autoconfigure.provider; -import io.opentelemetry.context.Context; import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties; -import io.opentelemetry.sdk.trace.ReadWriteSpan; -import io.opentelemetry.sdk.trace.ReadableSpan; +import io.opentelemetry.sdk.extension.incubator.trace.OnStartSpanProcessor; import io.opentelemetry.sdk.trace.SdkTracerProviderBuilder; -import io.opentelemetry.sdk.trace.SpanProcessor; @SuppressWarnings("deprecation") // Support testing of SdkTracerProviderConfigurer public class TestTracerProviderConfigurer @@ -18,24 +15,8 @@ public class TestTracerProviderConfigurer @Override public void configure(SdkTracerProviderBuilder tracerProvider, ConfigProperties config) { tracerProvider.addSpanProcessor( - new SpanProcessor() { - @Override - public void onStart(Context parentContext, ReadWriteSpan span) { - span.setAttribute("configured", config.getBoolean("otel.test.configured")); - } - - @Override - public boolean isStartRequired() { - return true; - } - - @Override - public void onEnd(ReadableSpan span) {} - - @Override - public boolean isEndRequired() { - return false; - } - }); + OnStartSpanProcessor.create( + (ctx, span) -> + span.setAttribute("configured", config.getBoolean("otel.test.configured")))); } } diff --git a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/trace/OnEndSpanProcessor.java b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/trace/OnEndSpanProcessor.java new file mode 100644 index 00000000000..4a207277201 --- /dev/null +++ b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/trace/OnEndSpanProcessor.java @@ -0,0 +1,49 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.sdk.extension.incubator.trace; + +import io.opentelemetry.context.Context; +import io.opentelemetry.sdk.trace.ReadWriteSpan; +import io.opentelemetry.sdk.trace.ReadableSpan; +import io.opentelemetry.sdk.trace.SpanProcessor; + +/** A SpanProcessor implementation that is only capable of processing spans when they end. */ +public final class OnEndSpanProcessor implements SpanProcessor { + private final OnEnd onEnd; + + private OnEndSpanProcessor(OnEnd onEnd) { + this.onEnd = onEnd; + } + + static SpanProcessor create(OnEnd onEnd) { + return new OnEndSpanProcessor(onEnd); + } + + @Override + public void onEnd(ReadableSpan span) { + onEnd.apply(span); + } + + @Override + public boolean isEndRequired() { + return true; + } + + @Override + public void onStart(Context parentContext, ReadWriteSpan span) { + // nop + } + + @Override + public boolean isStartRequired() { + return false; + } + + @FunctionalInterface + public interface OnEnd { + void apply(ReadableSpan span); + } +} diff --git a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/trace/OnStartSpanProcessor.java b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/trace/OnStartSpanProcessor.java new file mode 100644 index 00000000000..1ef96c2e883 --- /dev/null +++ b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/trace/OnStartSpanProcessor.java @@ -0,0 +1,50 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.sdk.extension.incubator.trace; + +import io.opentelemetry.context.Context; +import io.opentelemetry.sdk.trace.ReadWriteSpan; +import io.opentelemetry.sdk.trace.ReadableSpan; +import io.opentelemetry.sdk.trace.SpanProcessor; + +/** A SpanProcessor that only handles onStart(). */ +public final class OnStartSpanProcessor implements SpanProcessor { + + private final OnStart onStart; + + private OnStartSpanProcessor(OnStart onStart) { + this.onStart = onStart; + } + + public static SpanProcessor create(OnStart onStart) { + return new OnStartSpanProcessor(onStart); + } + + @Override + public void onStart(Context parentContext, ReadWriteSpan span) { + onStart.apply(parentContext, span); + } + + @Override + public boolean isStartRequired() { + return true; + } + + @Override + public void onEnd(ReadableSpan span) { + // nop + } + + @Override + public boolean isEndRequired() { + return false; + } + + @FunctionalInterface + public interface OnStart { + void apply(Context context, ReadWriteSpan span); + } +} diff --git a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/trace/OnEndSpanProcessorTest.java b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/trace/OnEndSpanProcessorTest.java new file mode 100644 index 00000000000..426b68e8131 --- /dev/null +++ b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/trace/OnEndSpanProcessorTest.java @@ -0,0 +1,31 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.sdk.extension.incubator.trace; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.mock; + +import io.opentelemetry.sdk.trace.ReadWriteSpan; +import io.opentelemetry.sdk.trace.ReadableSpan; +import io.opentelemetry.sdk.trace.SpanProcessor; +import java.util.concurrent.atomic.AtomicReference; +import org.junit.jupiter.api.Test; + +class OnEndSpanProcessorTest { + + @Test + void endOnly() { + AtomicReference seenSpan = new AtomicReference<>(); + ReadWriteSpan inputSpan = mock(ReadWriteSpan.class); + + SpanProcessor processor = OnEndSpanProcessor.create(seenSpan::set); + + assertThat(processor.isStartRequired()).isFalse(); + assertThat(processor.isEndRequired()).isTrue(); + processor.onEnd(inputSpan); + assertThat(seenSpan.get()).isSameAs(inputSpan); + } +} diff --git a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/trace/OnStartSpanProcessorTest.java b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/trace/OnStartSpanProcessorTest.java new file mode 100644 index 00000000000..245486ec9e2 --- /dev/null +++ b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/trace/OnStartSpanProcessorTest.java @@ -0,0 +1,39 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.sdk.extension.incubator.trace; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.mock; + +import io.opentelemetry.context.Context; +import io.opentelemetry.sdk.trace.ReadWriteSpan; +import io.opentelemetry.sdk.trace.SpanProcessor; +import java.util.concurrent.atomic.AtomicReference; +import org.junit.jupiter.api.Test; + +class OnStartSpanProcessorTest { + + @Test + void startOnly() { + AtomicReference seenContext = new AtomicReference<>(); + AtomicReference seenSpan = new AtomicReference<>(); + Context context = mock(Context.class); + ReadWriteSpan inputSpan = mock(ReadWriteSpan.class); + + SpanProcessor processor = + OnStartSpanProcessor.create( + (ctx, span) -> { + seenContext.set(ctx); + seenSpan.set(span); + }); + + assertThat(processor.isStartRequired()).isTrue(); + assertThat(processor.isEndRequired()).isFalse(); + processor.onStart(context, inputSpan); + assertThat(seenContext.get()).isSameAs(context); + assertThat(seenSpan.get()).isSameAs(inputSpan); + } +} From 3f1b9ed263f39f8538e9961943ccc0dd1d3f9964 Mon Sep 17 00:00:00 2001 From: jason plumb <75337021+breedx-splk@users.noreply.github.com> Date: Mon, 4 Dec 2023 11:40:56 -0800 Subject: [PATCH 129/901] Group spotless renovate updates (#6042) --- .github/renovate.json5 | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/renovate.json5 b/.github/renovate.json5 index 478b6ca84e8..a22fdfb2e4e 100644 --- a/.github/renovate.json5 +++ b/.github/renovate.json5 @@ -27,6 +27,10 @@ "matchPackageNames": ["org.jetbrains.kotlinx:kotlinx-coroutines-core"], "matchCurrentVersion": "1.5.2", "enabled": false + }, + { + "matchPackagePrefixes": ["com.diffplug.spotless"], + "groupName": "spotless packages" } ] } From 247ef4d26e511fc9aedaf3acca6e956c0358731e Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 4 Dec 2023 15:01:15 -0600 Subject: [PATCH 130/901] Update spotless packages to v6.23.3 (#6043) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- buildSrc/build.gradle.kts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts index 30cad6351dc..e4203690fa5 100644 --- a/buildSrc/build.gradle.kts +++ b/buildSrc/build.gradle.kts @@ -2,7 +2,7 @@ plugins { `kotlin-dsl` // When updating, update below in dependencies too - id("com.diffplug.spotless") version "6.23.2" + id("com.diffplug.spotless") version "6.23.3" } if (!JavaVersion.current().isCompatibleWith(JavaVersion.VERSION_17)) { @@ -45,7 +45,7 @@ dependencies { implementation(enforcedPlatform("com.squareup.wire:wire-bom:4.9.3")) implementation("com.google.auto.value:auto-value-annotations:1.10.4") // When updating, update above in plugins too - implementation("com.diffplug.spotless:spotless-plugin-gradle:6.23.2") + implementation("com.diffplug.spotless:spotless-plugin-gradle:6.23.3") // Needed for japicmp but not automatically brought in for some reason. implementation("com.google.guava:guava:32.1.3-jre") implementation("com.squareup:javapoet:1.13.0") From 9a3391d5e064437b87ddfc06492984d35dc1d1da Mon Sep 17 00:00:00 2001 From: jack-berg <34418638+jack-berg@users.noreply.github.com> Date: Thu, 7 Dec 2023 13:29:41 -0600 Subject: [PATCH 131/901] Serialize log body any value (#5938) --- .../internal/marshal/JsonSerializer.java | 2 +- .../internal/marshal/ProtoSerializer.java | 2 +- .../exporter/internal/marshal/Serializer.java | 2 +- exporters/otlp/common/build.gradle.kts | 1 + .../internal/otlp/AnyValueMarshaler.java | 44 ++++ .../internal/otlp/ArrayAnyValueMarshaler.java | 84 ++++++++ .../internal/otlp/BoolAnyValueMarshaler.java | 37 ++++ .../internal/otlp/BytesAnyValueMarshaler.java | 40 ++++ .../otlp/DoubleAnyValueMarshaler.java | 37 ++++ .../otlp/InstrumentationScopeMarshaler.java | 3 +- .../internal/otlp/IntAnyValueMarshaler.java | 37 ++++ .../otlp/KeyValueListAnyValueMarshaler.java | 63 ++++++ .../internal/otlp/KeyValueMarshaler.java | 198 +++--------------- .../internal/otlp/ResourceMarshaler.java | 3 +- .../otlp/StringAnyValueMarshaler.java | 9 +- .../internal/otlp/logs/LogMarshaler.java | 28 ++- .../otlp/metrics/ExemplarMarshaler.java | 2 +- ...xponentialHistogramDataPointMarshaler.java | 2 +- .../metrics/HistogramDataPointMarshaler.java | 2 +- .../metrics/NumberDataPointMarshaler.java | 2 +- .../metrics/SummaryDataPointMarshaler.java | 10 +- .../otlp/traces/SpanEventMarshaler.java | 2 +- .../otlp/traces/SpanLinkMarshaler.java | 2 +- .../internal/otlp/traces/SpanMarshaler.java | 2 +- .../internal/otlp/AnyValueMarshalerTest.java | 171 +++++++++++++++ integration-tests/otlp/build.gradle.kts | 1 + .../OtlpExporterIntegrationTest.java | 120 ++++++++++- .../sdk/logs/SdkLogRecordBuilder.java | 2 +- 28 files changed, 711 insertions(+), 197 deletions(-) create mode 100644 exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/AnyValueMarshaler.java create mode 100644 exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/ArrayAnyValueMarshaler.java create mode 100644 exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/BoolAnyValueMarshaler.java create mode 100644 exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/BytesAnyValueMarshaler.java create mode 100644 exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/DoubleAnyValueMarshaler.java create mode 100644 exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/IntAnyValueMarshaler.java create mode 100644 exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/KeyValueListAnyValueMarshaler.java create mode 100644 exporters/otlp/common/src/test/java/io/opentelemetry/exporter/internal/otlp/AnyValueMarshalerTest.java diff --git a/exporters/common/src/main/java/io/opentelemetry/exporter/internal/marshal/JsonSerializer.java b/exporters/common/src/main/java/io/opentelemetry/exporter/internal/marshal/JsonSerializer.java index ec805fc1fbf..f4745e68cba 100644 --- a/exporters/common/src/main/java/io/opentelemetry/exporter/internal/marshal/JsonSerializer.java +++ b/exporters/common/src/main/java/io/opentelemetry/exporter/internal/marshal/JsonSerializer.java @@ -109,7 +109,7 @@ public void writeString(ProtoFieldInfo field, byte[] utf8Bytes) throws IOExcepti } @Override - protected void writeBytes(ProtoFieldInfo field, byte[] value) throws IOException { + public void writeBytes(ProtoFieldInfo field, byte[] value) throws IOException { generator.writeBinaryField(field.getJsonName(), value); } diff --git a/exporters/common/src/main/java/io/opentelemetry/exporter/internal/marshal/ProtoSerializer.java b/exporters/common/src/main/java/io/opentelemetry/exporter/internal/marshal/ProtoSerializer.java index f34c5690edd..16015fe6bbf 100644 --- a/exporters/common/src/main/java/io/opentelemetry/exporter/internal/marshal/ProtoSerializer.java +++ b/exporters/common/src/main/java/io/opentelemetry/exporter/internal/marshal/ProtoSerializer.java @@ -123,7 +123,7 @@ public void writeString(ProtoFieldInfo field, byte[] utf8Bytes) throws IOExcepti } @Override - protected void writeBytes(ProtoFieldInfo field, byte[] value) throws IOException { + public void writeBytes(ProtoFieldInfo field, byte[] value) throws IOException { output.writeUInt32NoTag(field.getTag()); output.writeByteArrayNoTag(value); } diff --git a/exporters/common/src/main/java/io/opentelemetry/exporter/internal/marshal/Serializer.java b/exporters/common/src/main/java/io/opentelemetry/exporter/internal/marshal/Serializer.java index e3f36e6f98a..622201579a9 100644 --- a/exporters/common/src/main/java/io/opentelemetry/exporter/internal/marshal/Serializer.java +++ b/exporters/common/src/main/java/io/opentelemetry/exporter/internal/marshal/Serializer.java @@ -177,7 +177,7 @@ public void serializeBytes(ProtoFieldInfo field, byte[] value) throws IOExceptio writeBytes(field, value); } - protected abstract void writeBytes(ProtoFieldInfo field, byte[] value) throws IOException; + public abstract void writeBytes(ProtoFieldInfo field, byte[] value) throws IOException; protected abstract void writeStartMessage(ProtoFieldInfo field, int protoMessageSize) throws IOException; diff --git a/exporters/otlp/common/build.gradle.kts b/exporters/otlp/common/build.gradle.kts index 35b7a1b2eb7..1baf390fc34 100644 --- a/exporters/otlp/common/build.gradle.kts +++ b/exporters/otlp/common/build.gradle.kts @@ -16,6 +16,7 @@ dependencies { protoSource("io.opentelemetry.proto:opentelemetry-proto:${versions["io.opentelemetry.proto"]}") api(project(":exporters:common")) + implementation(project(":extensions:incubator")) compileOnly(project(":sdk:metrics")) compileOnly(project(":sdk:trace")) diff --git a/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/AnyValueMarshaler.java b/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/AnyValueMarshaler.java new file mode 100644 index 00000000000..2bd103a154a --- /dev/null +++ b/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/AnyValueMarshaler.java @@ -0,0 +1,44 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.exporter.internal.otlp; + +import io.opentelemetry.exporter.internal.marshal.MarshalerWithSize; +import io.opentelemetry.extension.incubator.logs.AnyValue; +import io.opentelemetry.extension.incubator.logs.KeyAnyValue; +import java.nio.ByteBuffer; +import java.util.List; + +/** + * Utility methods for obtaining AnyValue marshaler. + * + *

    This class is internal and is hence not for public use. Its APIs are unstable and can change + * at any time. + */ +public final class AnyValueMarshaler { + + private AnyValueMarshaler() {} + + @SuppressWarnings("unchecked") + public static MarshalerWithSize create(AnyValue anyValue) { + switch (anyValue.getType()) { + case STRING: + return StringAnyValueMarshaler.create((String) anyValue.getValue()); + case BOOLEAN: + return BoolAnyValueMarshaler.create((boolean) anyValue.getValue()); + case LONG: + return IntAnyValueMarshaler.create((long) anyValue.getValue()); + case DOUBLE: + return DoubleAnyValueMarshaler.create((double) anyValue.getValue()); + case ARRAY: + return ArrayAnyValueMarshaler.createAnyValue((List>) anyValue.getValue()); + case KEY_VALUE_LIST: + return KeyValueListAnyValueMarshaler.create((List) anyValue.getValue()); + case BYTES: + return BytesAnyValueMarshaler.create((ByteBuffer) anyValue.getValue()); + } + throw new IllegalArgumentException("Unsupported AnyValue type: " + anyValue.getType()); + } +} diff --git a/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/ArrayAnyValueMarshaler.java b/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/ArrayAnyValueMarshaler.java new file mode 100644 index 00000000000..e4184086468 --- /dev/null +++ b/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/ArrayAnyValueMarshaler.java @@ -0,0 +1,84 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.exporter.internal.otlp; + +import io.opentelemetry.exporter.internal.marshal.Marshaler; +import io.opentelemetry.exporter.internal.marshal.MarshalerUtil; +import io.opentelemetry.exporter.internal.marshal.MarshalerWithSize; +import io.opentelemetry.exporter.internal.marshal.Serializer; +import io.opentelemetry.proto.common.v1.internal.AnyValue; +import io.opentelemetry.proto.common.v1.internal.ArrayValue; +import java.io.IOException; +import java.util.List; +import java.util.function.Function; + +final class ArrayAnyValueMarshaler extends MarshalerWithSize { + private final Marshaler value; + + private ArrayAnyValueMarshaler(ArrayValueMarshaler value) { + super(calculateSize(value)); + this.value = value; + } + + static MarshalerWithSize createAnyValue( + List> values) { + return createInternal(values, AnyValueMarshaler::create); + } + + static MarshalerWithSize createString(List values) { + return createInternal(values, StringAnyValueMarshaler::create); + } + + static MarshalerWithSize createBool(List values) { + return createInternal(values, BoolAnyValueMarshaler::create); + } + + static MarshalerWithSize createInt(List values) { + return createInternal(values, IntAnyValueMarshaler::create); + } + + static MarshalerWithSize createDouble(List values) { + return createInternal(values, DoubleAnyValueMarshaler::create); + } + + private static MarshalerWithSize createInternal( + List values, Function initializer) { + int len = values.size(); + Marshaler[] marshalers = new Marshaler[len]; + for (int i = 0; i < len; i++) { + marshalers[i] = initializer.apply(values.get(i)); + } + return new ArrayAnyValueMarshaler(new ArrayValueMarshaler(marshalers)); + } + + @Override + public void writeTo(Serializer output) throws IOException { + output.serializeMessage(AnyValue.ARRAY_VALUE, value); + } + + private static int calculateSize(Marshaler value) { + return MarshalerUtil.sizeMessage(AnyValue.ARRAY_VALUE, value); + } + + private static class ArrayValueMarshaler extends MarshalerWithSize { + + private final Marshaler[] values; + + private ArrayValueMarshaler(Marshaler[] values) { + super(calculateSize(values)); + this.values = values; + } + + @Override + public void writeTo(Serializer output) throws IOException { + output.serializeRepeatedMessage(ArrayValue.VALUES, values); + } + + private static int calculateSize(Marshaler[] values) { + return MarshalerUtil.sizeRepeatedMessage(ArrayValue.VALUES, values); + } + } +} diff --git a/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/BoolAnyValueMarshaler.java b/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/BoolAnyValueMarshaler.java new file mode 100644 index 00000000000..2293c0c0e58 --- /dev/null +++ b/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/BoolAnyValueMarshaler.java @@ -0,0 +1,37 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.exporter.internal.otlp; + +import io.opentelemetry.exporter.internal.marshal.CodedOutputStream; +import io.opentelemetry.exporter.internal.marshal.MarshalerWithSize; +import io.opentelemetry.exporter.internal.marshal.Serializer; +import io.opentelemetry.proto.common.v1.internal.AnyValue; +import java.io.IOException; + +final class BoolAnyValueMarshaler extends MarshalerWithSize { + + private final boolean value; + + private BoolAnyValueMarshaler(boolean value) { + super(calculateSize(value)); + this.value = value; + } + + static MarshalerWithSize create(boolean value) { + return new BoolAnyValueMarshaler(value); + } + + @Override + public void writeTo(Serializer output) throws IOException { + // Do not call serialize* method because we always have to write the message tag even if the + // value is empty since it's a oneof. + output.writeBool(AnyValue.BOOL_VALUE, value); + } + + private static int calculateSize(boolean value) { + return AnyValue.BOOL_VALUE.getTagSize() + CodedOutputStream.computeBoolSizeNoTag(value); + } +} diff --git a/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/BytesAnyValueMarshaler.java b/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/BytesAnyValueMarshaler.java new file mode 100644 index 00000000000..d0a781039be --- /dev/null +++ b/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/BytesAnyValueMarshaler.java @@ -0,0 +1,40 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.exporter.internal.otlp; + +import io.opentelemetry.exporter.internal.marshal.CodedOutputStream; +import io.opentelemetry.exporter.internal.marshal.MarshalerWithSize; +import io.opentelemetry.exporter.internal.marshal.Serializer; +import io.opentelemetry.proto.common.v1.internal.AnyValue; +import java.io.IOException; +import java.nio.ByteBuffer; + +final class BytesAnyValueMarshaler extends MarshalerWithSize { + + private final byte[] value; + + private BytesAnyValueMarshaler(byte[] value) { + super(calculateSize(value)); + this.value = value; + } + + static MarshalerWithSize create(ByteBuffer value) { + byte[] bytes = new byte[value.remaining()]; + value.get(bytes); + return new BytesAnyValueMarshaler(bytes); + } + + @Override + public void writeTo(Serializer output) throws IOException { + // Do not call serialize* method because we always have to write the message tag even if the + // value is empty since it's a oneof. + output.writeBytes(AnyValue.BYTES_VALUE, value); + } + + private static int calculateSize(byte[] value) { + return AnyValue.BYTES_VALUE.getTagSize() + CodedOutputStream.computeByteArraySizeNoTag(value); + } +} diff --git a/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/DoubleAnyValueMarshaler.java b/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/DoubleAnyValueMarshaler.java new file mode 100644 index 00000000000..5837976c92d --- /dev/null +++ b/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/DoubleAnyValueMarshaler.java @@ -0,0 +1,37 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.exporter.internal.otlp; + +import io.opentelemetry.exporter.internal.marshal.CodedOutputStream; +import io.opentelemetry.exporter.internal.marshal.MarshalerWithSize; +import io.opentelemetry.exporter.internal.marshal.Serializer; +import io.opentelemetry.proto.common.v1.internal.AnyValue; +import java.io.IOException; + +final class DoubleAnyValueMarshaler extends MarshalerWithSize { + + private final double value; + + private DoubleAnyValueMarshaler(double value) { + super(calculateSize(value)); + this.value = value; + } + + static MarshalerWithSize create(double value) { + return new DoubleAnyValueMarshaler(value); + } + + @Override + public void writeTo(Serializer output) throws IOException { + // Do not call serialize* method because we always have to write the message tag even if the + // value is empty since it's a oneof. + output.writeDouble(AnyValue.DOUBLE_VALUE, value); + } + + private static int calculateSize(double value) { + return AnyValue.DOUBLE_VALUE.getTagSize() + CodedOutputStream.computeDoubleSizeNoTag(value); + } +} diff --git a/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/InstrumentationScopeMarshaler.java b/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/InstrumentationScopeMarshaler.java index 1d0a1d67349..c5466cad479 100644 --- a/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/InstrumentationScopeMarshaler.java +++ b/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/InstrumentationScopeMarshaler.java @@ -37,7 +37,8 @@ public static InstrumentationScopeMarshaler create(InstrumentationScopeInfo scop // a few times until the cache gets filled which is fine. byte[] name = MarshalerUtil.toBytes(scopeInfo.getName()); byte[] version = MarshalerUtil.toBytes(scopeInfo.getVersion()); - KeyValueMarshaler[] attributes = KeyValueMarshaler.createRepeated(scopeInfo.getAttributes()); + KeyValueMarshaler[] attributes = + KeyValueMarshaler.createForAttributes(scopeInfo.getAttributes()); RealInstrumentationScopeMarshaler realMarshaler = new RealInstrumentationScopeMarshaler(name, version, attributes); diff --git a/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/IntAnyValueMarshaler.java b/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/IntAnyValueMarshaler.java new file mode 100644 index 00000000000..498c60e76bb --- /dev/null +++ b/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/IntAnyValueMarshaler.java @@ -0,0 +1,37 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.exporter.internal.otlp; + +import io.opentelemetry.exporter.internal.marshal.CodedOutputStream; +import io.opentelemetry.exporter.internal.marshal.MarshalerWithSize; +import io.opentelemetry.exporter.internal.marshal.Serializer; +import io.opentelemetry.proto.common.v1.internal.AnyValue; +import java.io.IOException; + +final class IntAnyValueMarshaler extends MarshalerWithSize { + + private final long value; + + private IntAnyValueMarshaler(long value) { + super(calculateSize(value)); + this.value = value; + } + + static MarshalerWithSize create(long value) { + return new IntAnyValueMarshaler(value); + } + + @Override + public void writeTo(Serializer output) throws IOException { + // Do not call serialize* method because we always have to write the message tag even if the + // value is empty since it's a oneof. + output.writeInt64(AnyValue.INT_VALUE, value); + } + + private static int calculateSize(long value) { + return AnyValue.INT_VALUE.getTagSize() + CodedOutputStream.computeInt64SizeNoTag(value); + } +} diff --git a/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/KeyValueListAnyValueMarshaler.java b/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/KeyValueListAnyValueMarshaler.java new file mode 100644 index 00000000000..823c28226c8 --- /dev/null +++ b/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/KeyValueListAnyValueMarshaler.java @@ -0,0 +1,63 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.exporter.internal.otlp; + +import io.opentelemetry.exporter.internal.marshal.Marshaler; +import io.opentelemetry.exporter.internal.marshal.MarshalerUtil; +import io.opentelemetry.exporter.internal.marshal.MarshalerWithSize; +import io.opentelemetry.exporter.internal.marshal.Serializer; +import io.opentelemetry.extension.incubator.logs.KeyAnyValue; +import io.opentelemetry.proto.common.v1.internal.AnyValue; +import io.opentelemetry.proto.common.v1.internal.KeyValueList; +import java.io.IOException; +import java.util.List; + +final class KeyValueListAnyValueMarshaler extends MarshalerWithSize { + + private final Marshaler value; + + private KeyValueListAnyValueMarshaler(KeyValueListMarshaler value) { + super(calculateSize(value)); + this.value = value; + } + + static MarshalerWithSize create(List values) { + int len = values.size(); + KeyValueMarshaler[] marshalers = new KeyValueMarshaler[values.size()]; + for (int i = 0; i < len; i++) { + marshalers[i] = KeyValueMarshaler.createForKeyAnyValue(values.get(i)); + } + return new KeyValueListAnyValueMarshaler(new KeyValueListMarshaler(marshalers)); + } + + @Override + public void writeTo(Serializer output) throws IOException { + output.serializeMessage(AnyValue.KVLIST_VALUE, value); + } + + private static int calculateSize(Marshaler value) { + return MarshalerUtil.sizeMessage(AnyValue.KVLIST_VALUE, value); + } + + private static class KeyValueListMarshaler extends MarshalerWithSize { + + private final Marshaler[] values; + + private KeyValueListMarshaler(KeyValueMarshaler[] values) { + super(calculateSize(values)); + this.values = values; + } + + @Override + public void writeTo(Serializer output) throws IOException { + output.serializeRepeatedMessage(KeyValueList.VALUES, values); + } + + private static int calculateSize(Marshaler[] values) { + return MarshalerUtil.sizeRepeatedMessage(KeyValueList.VALUES, values); + } + } +} diff --git a/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/KeyValueMarshaler.java b/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/KeyValueMarshaler.java index 18f151a8f0c..1db0dc2edd5 100644 --- a/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/KeyValueMarshaler.java +++ b/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/KeyValueMarshaler.java @@ -8,13 +8,11 @@ import io.opentelemetry.api.common.AttributeKey; import io.opentelemetry.api.common.Attributes; import io.opentelemetry.api.internal.InternalAttributeKeyImpl; -import io.opentelemetry.exporter.internal.marshal.CodedOutputStream; import io.opentelemetry.exporter.internal.marshal.Marshaler; import io.opentelemetry.exporter.internal.marshal.MarshalerUtil; import io.opentelemetry.exporter.internal.marshal.MarshalerWithSize; import io.opentelemetry.exporter.internal.marshal.Serializer; -import io.opentelemetry.proto.common.v1.internal.AnyValue; -import io.opentelemetry.proto.common.v1.internal.ArrayValue; +import io.opentelemetry.extension.incubator.logs.KeyAnyValue; import io.opentelemetry.proto.common.v1.internal.KeyValue; import java.io.IOException; import java.nio.charset.StandardCharsets; @@ -22,38 +20,52 @@ import java.util.function.BiConsumer; /** - * A Marshaler of {@link Attributes}. + * A Marshaler of key value pairs. * *

    This class is internal and is hence not for public use. Its APIs are unstable and can change * at any time. */ public final class KeyValueMarshaler extends MarshalerWithSize { + private static final byte[] EMPTY_BYTES = new byte[0]; private static final KeyValueMarshaler[] EMPTY_REPEATED = new KeyValueMarshaler[0]; + private final byte[] keyUtf8; + private final Marshaler value; + + private KeyValueMarshaler(byte[] keyUtf8, Marshaler value) { + super(calculateSize(keyUtf8, value)); + this.keyUtf8 = keyUtf8; + this.value = value; + } + + /** Returns Marshaler for the given KeyAnyValue. */ + public static KeyValueMarshaler createForKeyAnyValue(KeyAnyValue keyAnyValue) { + return new KeyValueMarshaler( + keyAnyValue.getKey().getBytes(StandardCharsets.UTF_8), + AnyValueMarshaler.create(keyAnyValue.getAnyValue())); + } + /** Returns Marshalers for the given Attributes. */ @SuppressWarnings("AvoidObjectArrays") - public static KeyValueMarshaler[] createRepeated(Attributes attributes) { + public static KeyValueMarshaler[] createForAttributes(Attributes attributes) { if (attributes.isEmpty()) { return EMPTY_REPEATED; } - KeyValueMarshaler[] attributeMarshalers = new KeyValueMarshaler[attributes.size()]; + KeyValueMarshaler[] marshalers = new KeyValueMarshaler[attributes.size()]; attributes.forEach( new BiConsumer, Object>() { int index = 0; @Override public void accept(AttributeKey attributeKey, Object o) { - attributeMarshalers[index++] = KeyValueMarshaler.create(attributeKey, o); + marshalers[index++] = create(attributeKey, o); } }); - return attributeMarshalers; + return marshalers; } - private final byte[] keyUtf8; - private final Marshaler value; - @SuppressWarnings("unchecked") private static KeyValueMarshaler create(AttributeKey attributeKey, Object value) { byte[] keyUtf8; @@ -66,42 +78,30 @@ private static KeyValueMarshaler create(AttributeKey attributeKey, Object val } switch (attributeKey.getType()) { case STRING: - return new KeyValueMarshaler( - keyUtf8, new StringAnyValueMarshaler(MarshalerUtil.toBytes((String) value))); + return new KeyValueMarshaler(keyUtf8, StringAnyValueMarshaler.create((String) value)); case LONG: - return new KeyValueMarshaler(keyUtf8, new Int64AnyValueMarshaler((long) value)); + return new KeyValueMarshaler(keyUtf8, IntAnyValueMarshaler.create((long) value)); case BOOLEAN: - return new KeyValueMarshaler(keyUtf8, new BoolAnyValueMarshaler((boolean) value)); + return new KeyValueMarshaler(keyUtf8, BoolAnyValueMarshaler.create((boolean) value)); case DOUBLE: - return new KeyValueMarshaler(keyUtf8, new AnyDoubleFieldMarshaler((double) value)); + return new KeyValueMarshaler(keyUtf8, DoubleAnyValueMarshaler.create((double) value)); case STRING_ARRAY: return new KeyValueMarshaler( - keyUtf8, - new ArrayAnyValueMarshaler(ArrayValueMarshaler.createString((List) value))); + keyUtf8, ArrayAnyValueMarshaler.createString((List) value)); case LONG_ARRAY: - return new KeyValueMarshaler( - keyUtf8, - new ArrayAnyValueMarshaler(ArrayValueMarshaler.createInt64((List) value))); + return new KeyValueMarshaler(keyUtf8, ArrayAnyValueMarshaler.createInt((List) value)); case BOOLEAN_ARRAY: return new KeyValueMarshaler( - keyUtf8, - new ArrayAnyValueMarshaler(ArrayValueMarshaler.createBool((List) value))); + keyUtf8, ArrayAnyValueMarshaler.createBool((List) value)); case DOUBLE_ARRAY: return new KeyValueMarshaler( - keyUtf8, - new ArrayAnyValueMarshaler(ArrayValueMarshaler.createDouble((List) value))); + keyUtf8, ArrayAnyValueMarshaler.createDouble((List) value)); } // Error prone ensures the switch statement is complete, otherwise only can happen with // unaligned versions which are not supported. throw new IllegalArgumentException("Unsupported attribute type."); } - private KeyValueMarshaler(byte[] keyUtf8, Marshaler value) { - super(calculateSize(keyUtf8, value)); - this.keyUtf8 = keyUtf8; - this.value = value; - } - @Override public void writeTo(Serializer output) throws IOException { output.serializeString(KeyValue.KEY, keyUtf8); @@ -114,140 +114,4 @@ private static int calculateSize(byte[] keyUtf8, Marshaler value) { size += MarshalerUtil.sizeMessage(KeyValue.VALUE, value); return size; } - - private static class BoolAnyValueMarshaler extends MarshalerWithSize { - - private final boolean value; - - BoolAnyValueMarshaler(boolean value) { - super(calculateSize(value)); - this.value = value; - } - - @Override - public void writeTo(Serializer output) throws IOException { - // Do not call serialize* method because we always have to write the message tag even if the - // value is empty since it's a oneof. - output.writeBool(AnyValue.BOOL_VALUE, value); - } - - private static int calculateSize(boolean value) { - return AnyValue.BOOL_VALUE.getTagSize() + CodedOutputStream.computeBoolSizeNoTag(value); - } - } - - private static class Int64AnyValueMarshaler extends MarshalerWithSize { - - private final long value; - - Int64AnyValueMarshaler(long value) { - super(calculateSize(value)); - this.value = value; - } - - @Override - public void writeTo(Serializer output) throws IOException { - // Do not call serialize* method because we always have to write the message tag even if the - // value is empty since it's a oneof. - output.writeInt64(AnyValue.INT_VALUE, value); - } - - private static int calculateSize(long value) { - return AnyValue.INT_VALUE.getTagSize() + CodedOutputStream.computeInt64SizeNoTag(value); - } - } - - private static class AnyDoubleFieldMarshaler extends MarshalerWithSize { - - private final double value; - - AnyDoubleFieldMarshaler(double value) { - super(calculateSize(value)); - this.value = value; - } - - @Override - public void writeTo(Serializer output) throws IOException { - // Do not call serialize* method because we always have to write the message tag even if the - // value is empty since it's a oneof. - output.writeDouble(AnyValue.DOUBLE_VALUE, value); - } - - private static int calculateSize(double value) { - return AnyValue.DOUBLE_VALUE.getTagSize() + CodedOutputStream.computeDoubleSizeNoTag(value); - } - } - - private static class ArrayAnyValueMarshaler extends MarshalerWithSize { - private final Marshaler value; - - private ArrayAnyValueMarshaler(Marshaler value) { - super(calculateSize(value)); - this.value = value; - } - - @Override - public void writeTo(Serializer output) throws IOException { - output.serializeMessage(AnyValue.ARRAY_VALUE, value); - } - - private static int calculateSize(Marshaler value) { - return MarshalerUtil.sizeMessage(AnyValue.ARRAY_VALUE, value); - } - } - - private static class ArrayValueMarshaler extends MarshalerWithSize { - - static ArrayValueMarshaler createString(List values) { - int len = values.size(); - Marshaler[] marshalers = new StringAnyValueMarshaler[len]; - for (int i = 0; i < len; i++) { - marshalers[i] = new StringAnyValueMarshaler(values.get(i).getBytes(StandardCharsets.UTF_8)); - } - return new ArrayValueMarshaler(marshalers); - } - - static ArrayValueMarshaler createBool(List values) { - int len = values.size(); - Marshaler[] marshalers = new BoolAnyValueMarshaler[len]; - for (int i = 0; i < len; i++) { - marshalers[i] = new BoolAnyValueMarshaler(values.get(i)); - } - return new ArrayValueMarshaler(marshalers); - } - - static ArrayValueMarshaler createInt64(List values) { - int len = values.size(); - Marshaler[] marshalers = new Int64AnyValueMarshaler[len]; - for (int i = 0; i < len; i++) { - marshalers[i] = new Int64AnyValueMarshaler(values.get(i)); - } - return new ArrayValueMarshaler(marshalers); - } - - static ArrayValueMarshaler createDouble(List values) { - int len = values.size(); - Marshaler[] marshalers = new AnyDoubleFieldMarshaler[len]; - for (int i = 0; i < len; i++) { - marshalers[i] = new AnyDoubleFieldMarshaler(values.get(i)); - } - return new ArrayValueMarshaler(marshalers); - } - - private final Marshaler[] values; - - private ArrayValueMarshaler(Marshaler[] values) { - super(calculateSize(values)); - this.values = values; - } - - @Override - public void writeTo(Serializer output) throws IOException { - output.serializeRepeatedMessage(ArrayValue.VALUES, values); - } - - private static int calculateSize(Marshaler[] values) { - return MarshalerUtil.sizeRepeatedMessage(ArrayValue.VALUES, values); - } - } } diff --git a/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/ResourceMarshaler.java b/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/ResourceMarshaler.java index 259f0070000..b3395448a79 100644 --- a/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/ResourceMarshaler.java +++ b/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/ResourceMarshaler.java @@ -36,7 +36,8 @@ public static ResourceMarshaler create(io.opentelemetry.sdk.resources.Resource r // a few times until the cache gets filled which is fine. RealResourceMarshaler realMarshaler = - new RealResourceMarshaler(KeyValueMarshaler.createRepeated(resource.getAttributes())); + new RealResourceMarshaler( + KeyValueMarshaler.createForAttributes(resource.getAttributes())); ByteArrayOutputStream binaryBos = new ByteArrayOutputStream(realMarshaler.getBinarySerializedSize()); diff --git a/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/StringAnyValueMarshaler.java b/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/StringAnyValueMarshaler.java index 81e1ab2c7be..e62c55d2da1 100644 --- a/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/StringAnyValueMarshaler.java +++ b/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/StringAnyValueMarshaler.java @@ -6,6 +6,7 @@ package io.opentelemetry.exporter.internal.otlp; import io.opentelemetry.exporter.internal.marshal.CodedOutputStream; +import io.opentelemetry.exporter.internal.marshal.MarshalerUtil; import io.opentelemetry.exporter.internal.marshal.MarshalerWithSize; import io.opentelemetry.exporter.internal.marshal.Serializer; import io.opentelemetry.proto.common.v1.internal.AnyValue; @@ -17,15 +18,19 @@ *

    This class is internal and is hence not for public use. Its APIs are unstable and can change * at any time. */ -public final class StringAnyValueMarshaler extends MarshalerWithSize { +final class StringAnyValueMarshaler extends MarshalerWithSize { private final byte[] valueUtf8; - public StringAnyValueMarshaler(byte[] valueUtf8) { + private StringAnyValueMarshaler(byte[] valueUtf8) { super(calculateSize(valueUtf8)); this.valueUtf8 = valueUtf8; } + static MarshalerWithSize create(String value) { + return new StringAnyValueMarshaler(MarshalerUtil.toBytes(value)); + } + @Override public void writeTo(Serializer output) throws IOException { // Do not call serialize* method because we always have to write the message tag even if the diff --git a/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/logs/LogMarshaler.java b/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/logs/LogMarshaler.java index 7a68041e5d1..863b27b6442 100644 --- a/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/logs/LogMarshaler.java +++ b/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/logs/LogMarshaler.java @@ -14,17 +14,22 @@ import io.opentelemetry.exporter.internal.marshal.MarshalerWithSize; import io.opentelemetry.exporter.internal.marshal.ProtoEnumInfo; import io.opentelemetry.exporter.internal.marshal.Serializer; +import io.opentelemetry.exporter.internal.otlp.AnyValueMarshaler; import io.opentelemetry.exporter.internal.otlp.KeyValueMarshaler; -import io.opentelemetry.exporter.internal.otlp.StringAnyValueMarshaler; +import io.opentelemetry.extension.incubator.logs.AnyValue; import io.opentelemetry.proto.logs.v1.internal.LogRecord; import io.opentelemetry.proto.logs.v1.internal.SeverityNumber; +import io.opentelemetry.sdk.logs.data.Body; import io.opentelemetry.sdk.logs.data.LogRecordData; +import io.opentelemetry.sdk.logs.internal.AnyValueBody; import java.io.IOException; import javax.annotation.Nullable; final class LogMarshaler extends MarshalerWithSize { private static final String INVALID_TRACE_ID = TraceId.getInvalid(); private static final String INVALID_SPAN_ID = SpanId.getInvalid(); + private static final MarshalerWithSize EMPTY_BODY_MARSHALER = + AnyValueMarshaler.create(AnyValue.of("")); private final long timeUnixNano; private final long observedTimeUnixNano; @@ -39,11 +44,9 @@ final class LogMarshaler extends MarshalerWithSize { static LogMarshaler create(LogRecordData logRecordData) { KeyValueMarshaler[] attributeMarshalers = - KeyValueMarshaler.createRepeated(logRecordData.getAttributes()); + KeyValueMarshaler.createForAttributes(logRecordData.getAttributes()); - // TODO(jack-berg): handle AnyValue log body - StringAnyValueMarshaler anyValueMarshaler = - new StringAnyValueMarshaler(MarshalerUtil.toBytes(logRecordData.getBody().asString())); + MarshalerWithSize bodyMarshaler = body(logRecordData.getBody()); SpanContext spanContext = logRecordData.getSpanContext(); return new LogMarshaler( @@ -51,7 +54,7 @@ static LogMarshaler create(LogRecordData logRecordData) { logRecordData.getObservedTimestampEpochNanos(), toProtoSeverityNumber(logRecordData.getSeverity()), MarshalerUtil.toBytes(logRecordData.getSeverityText()), - anyValueMarshaler, + bodyMarshaler, attributeMarshalers, logRecordData.getTotalAttributeCount() - logRecordData.getAttributes().size(), spanContext.getTraceFlags(), @@ -59,6 +62,19 @@ static LogMarshaler create(LogRecordData logRecordData) { spanContext.getSpanId().equals(INVALID_SPAN_ID) ? null : spanContext.getSpanId()); } + private static MarshalerWithSize body(Body body) { + if (body instanceof AnyValueBody) { + return AnyValueMarshaler.create(((AnyValueBody) body).asAnyValue()); + } + switch (body.getType()) { + case STRING: + return AnyValueMarshaler.create(AnyValue.of(body.asString())); + case EMPTY: + return EMPTY_BODY_MARSHALER; + } + throw new IllegalStateException("Unsupported Body type: " + body.getType()); + } + private LogMarshaler( long timeUnixNano, long observedTimeUnixNano, diff --git a/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/metrics/ExemplarMarshaler.java b/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/metrics/ExemplarMarshaler.java index ed4956ec9a8..8d16c9e40d7 100644 --- a/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/metrics/ExemplarMarshaler.java +++ b/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/metrics/ExemplarMarshaler.java @@ -39,7 +39,7 @@ static ExemplarMarshaler[] createRepeated(List exemplars private static ExemplarMarshaler create(ExemplarData exemplar) { KeyValueMarshaler[] attributeMarshalers = - KeyValueMarshaler.createRepeated(exemplar.getFilteredAttributes()); + KeyValueMarshaler.createForAttributes(exemplar.getFilteredAttributes()); ProtoFieldInfo valueField; if (exemplar instanceof LongExemplarData) { diff --git a/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/metrics/ExponentialHistogramDataPointMarshaler.java b/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/metrics/ExponentialHistogramDataPointMarshaler.java index e7ac8dcd68b..071833954ad 100644 --- a/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/metrics/ExponentialHistogramDataPointMarshaler.java +++ b/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/metrics/ExponentialHistogramDataPointMarshaler.java @@ -83,7 +83,7 @@ private ExponentialHistogramDataPointMarshaler( } static ExponentialHistogramDataPointMarshaler create(ExponentialHistogramPointData point) { - KeyValueMarshaler[] attributes = KeyValueMarshaler.createRepeated(point.getAttributes()); + KeyValueMarshaler[] attributes = KeyValueMarshaler.createForAttributes(point.getAttributes()); ExemplarMarshaler[] exemplars = ExemplarMarshaler.createRepeated(point.getExemplars()); ExponentialHistogramBucketsMarshaler positiveBuckets = diff --git a/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/metrics/HistogramDataPointMarshaler.java b/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/metrics/HistogramDataPointMarshaler.java index b1a027a3455..8022635e868 100644 --- a/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/metrics/HistogramDataPointMarshaler.java +++ b/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/metrics/HistogramDataPointMarshaler.java @@ -41,7 +41,7 @@ static HistogramDataPointMarshaler[] createRepeated(Collection static NumberDataPointMarshaler create(PointData point) { ExemplarMarshaler[] exemplarMarshalers = ExemplarMarshaler.createRepeated(point.getExemplars()); KeyValueMarshaler[] attributeMarshalers = - KeyValueMarshaler.createRepeated(point.getAttributes()); + KeyValueMarshaler.createForAttributes(point.getAttributes()); ProtoFieldInfo valueField; if (point instanceof LongPointData) { diff --git a/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/metrics/SummaryDataPointMarshaler.java b/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/metrics/SummaryDataPointMarshaler.java index cb38c86ed13..c0b6a1dcded 100644 --- a/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/metrics/SummaryDataPointMarshaler.java +++ b/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/metrics/SummaryDataPointMarshaler.java @@ -20,7 +20,7 @@ final class SummaryDataPointMarshaler extends MarshalerWithSize { private final long count; private final double sum; private final ValueAtQuantileMarshaler[] quantileValues; - private final KeyValueMarshaler[] attributes; + private final MarshalerWithSize[] attributes; static SummaryDataPointMarshaler[] createRepeated(Collection points) { SummaryDataPointMarshaler[] marshalers = new SummaryDataPointMarshaler[points.size()]; @@ -34,8 +34,8 @@ static SummaryDataPointMarshaler[] createRepeated(Collection p static SummaryDataPointMarshaler create(SummaryPointData point) { ValueAtQuantileMarshaler[] quantileMarshalers = ValueAtQuantileMarshaler.createRepeated(point.getValues()); - KeyValueMarshaler[] attributeMarshalers = - KeyValueMarshaler.createRepeated(point.getAttributes()); + MarshalerWithSize[] attributeMarshalers = + KeyValueMarshaler.createForAttributes(point.getAttributes()); return new SummaryDataPointMarshaler( point.getStartEpochNanos(), @@ -52,7 +52,7 @@ private SummaryDataPointMarshaler( long count, double sum, ValueAtQuantileMarshaler[] quantileValues, - KeyValueMarshaler[] attributes) { + MarshalerWithSize[] attributes) { super(calculateSize(startTimeUnixNano, timeUnixNano, count, sum, quantileValues, attributes)); this.startTimeUnixNano = startTimeUnixNano; this.timeUnixNano = timeUnixNano; @@ -78,7 +78,7 @@ private static int calculateSize( long count, double sum, ValueAtQuantileMarshaler[] quantileValues, - KeyValueMarshaler[] attributes) { + MarshalerWithSize[] attributes) { int size = 0; size += MarshalerUtil.sizeFixed64(SummaryDataPoint.START_TIME_UNIX_NANO, startTimeUnixNano); size += MarshalerUtil.sizeFixed64(SummaryDataPoint.TIME_UNIX_NANO, timeUnixNano); diff --git a/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/traces/SpanEventMarshaler.java b/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/traces/SpanEventMarshaler.java index 03b208f3df0..2b2cc1d7775 100644 --- a/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/traces/SpanEventMarshaler.java +++ b/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/traces/SpanEventMarshaler.java @@ -40,7 +40,7 @@ static SpanEventMarshaler create(EventData event) { return new SpanEventMarshaler( event.getEpochNanos(), MarshalerUtil.toBytes(event.getName()), - KeyValueMarshaler.createRepeated(event.getAttributes()), + KeyValueMarshaler.createForAttributes(event.getAttributes()), event.getTotalAttributeCount() - event.getAttributes().size()); } diff --git a/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/traces/SpanLinkMarshaler.java b/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/traces/SpanLinkMarshaler.java index 0579fb56e10..6f08b257dce 100644 --- a/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/traces/SpanLinkMarshaler.java +++ b/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/traces/SpanLinkMarshaler.java @@ -52,7 +52,7 @@ static SpanLinkMarshaler create(LinkData link) { link.getSpanContext().getTraceId(), link.getSpanContext().getSpanId(), traceStateUtf8, - KeyValueMarshaler.createRepeated(link.getAttributes()), + KeyValueMarshaler.createForAttributes(link.getAttributes()), link.getTotalAttributeCount() - link.getAttributes().size()); } diff --git a/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/traces/SpanMarshaler.java b/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/traces/SpanMarshaler.java index b487f262a3c..7eae7c7b25c 100644 --- a/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/traces/SpanMarshaler.java +++ b/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/traces/SpanMarshaler.java @@ -41,7 +41,7 @@ final class SpanMarshaler extends MarshalerWithSize { // Because SpanMarshaler is always part of a repeated field, it cannot return "null". static SpanMarshaler create(SpanData spanData) { KeyValueMarshaler[] attributeMarshalers = - KeyValueMarshaler.createRepeated(spanData.getAttributes()); + KeyValueMarshaler.createForAttributes(spanData.getAttributes()); SpanEventMarshaler[] spanEventMarshalers = SpanEventMarshaler.createRepeated(spanData.getEvents()); SpanLinkMarshaler[] spanLinkMarshalers = SpanLinkMarshaler.createRepeated(spanData.getLinks()); diff --git a/exporters/otlp/common/src/test/java/io/opentelemetry/exporter/internal/otlp/AnyValueMarshalerTest.java b/exporters/otlp/common/src/test/java/io/opentelemetry/exporter/internal/otlp/AnyValueMarshalerTest.java new file mode 100644 index 00000000000..d52d504e9c4 --- /dev/null +++ b/exporters/otlp/common/src/test/java/io/opentelemetry/exporter/internal/otlp/AnyValueMarshalerTest.java @@ -0,0 +1,171 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.exporter.internal.otlp; + +import static io.opentelemetry.extension.incubator.logs.AnyValue.of; +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.jupiter.params.provider.Arguments.arguments; + +import com.google.protobuf.ByteString; +import com.google.protobuf.InvalidProtocolBufferException; +import com.google.protobuf.Message; +import com.google.protobuf.util.JsonFormat; +import io.opentelemetry.exporter.internal.marshal.Marshaler; +import io.opentelemetry.exporter.internal.marshal.MarshalerWithSize; +import io.opentelemetry.extension.incubator.logs.KeyAnyValue; +import io.opentelemetry.proto.common.v1.AnyValue; +import io.opentelemetry.proto.common.v1.ArrayValue; +import io.opentelemetry.proto.common.v1.KeyValue; +import io.opentelemetry.proto.common.v1.KeyValueList; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.UncheckedIOException; +import java.nio.charset.StandardCharsets; +import java.util.Collections; +import java.util.stream.Stream; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; + +@SuppressWarnings("BadImport") +class AnyValueMarshalerTest { + + @ParameterizedTest + @MethodSource("serializeAnyValueArgs") + void anyValueString( + io.opentelemetry.extension.incubator.logs.AnyValue anyValue, + AnyValue expectedSerializedValue) { + MarshalerWithSize marshaler = AnyValueMarshaler.create(anyValue); + AnyValue serializedValue = parse(AnyValue.getDefaultInstance(), marshaler); + assertThat(serializedValue).isEqualTo(expectedSerializedValue); + } + + private static Stream serializeAnyValueArgs() { + return Stream.of( + // primitives + arguments(of("str"), AnyValue.newBuilder().setStringValue("str").build()), + arguments(of(true), AnyValue.newBuilder().setBoolValue(true).build()), + arguments(of(1), AnyValue.newBuilder().setIntValue(1).build()), + arguments(of(1.1), AnyValue.newBuilder().setDoubleValue(1.1).build()), + // heterogeneous array + arguments( + of(of("str"), of(true), of(1), of(1.1)), + AnyValue.newBuilder() + .setArrayValue( + ArrayValue.newBuilder() + .addValues(AnyValue.newBuilder().setStringValue("str").build()) + .addValues(AnyValue.newBuilder().setBoolValue(true).build()) + .addValues(AnyValue.newBuilder().setIntValue(1).build()) + .addValues(AnyValue.newBuilder().setDoubleValue(1.1).build()) + .build()) + .build()), + // map + arguments( + of(KeyAnyValue.of("key1", of("val1")), KeyAnyValue.of("key2", of(2))), + AnyValue.newBuilder() + .setKvlistValue( + KeyValueList.newBuilder() + .addValues( + KeyValue.newBuilder() + .setKey("key1") + .setValue(AnyValue.newBuilder().setStringValue("val1").build()) + .build()) + .addValues( + KeyValue.newBuilder() + .setKey("key2") + .setValue(AnyValue.newBuilder().setIntValue(2).build()) + .build()) + .build()) + .build()), + // map of maps + arguments( + of( + Collections.singletonMap( + "child", of(Collections.singletonMap("grandchild", of("str"))))), + AnyValue.newBuilder() + .setKvlistValue( + KeyValueList.newBuilder() + .addValues( + KeyValue.newBuilder() + .setKey("child") + .setValue( + AnyValue.newBuilder() + .setKvlistValue( + KeyValueList.newBuilder() + .addValues( + KeyValue.newBuilder() + .setKey("grandchild") + .setValue( + AnyValue.newBuilder() + .setStringValue("str") + .build()) + .build()) + .build()) + .build()) + .build()) + .build()) + .build()), + // bytes + arguments( + of("hello world".getBytes(StandardCharsets.UTF_8)), + AnyValue.newBuilder() + .setBytesValue(ByteString.copyFrom("hello world".getBytes(StandardCharsets.UTF_8))) + .build())); + } + + @SuppressWarnings("unchecked") + private static T parse(T prototype, Marshaler marshaler) { + byte[] serialized = toByteArray(marshaler); + T result; + try { + result = (T) prototype.newBuilderForType().mergeFrom(serialized).build(); + } catch (InvalidProtocolBufferException e) { + throw new UncheckedIOException(e); + } + // Our marshaler should produce the exact same length of serialized output (for example, field + // default values are not outputted), so we check that here. The output itself may have slightly + // different ordering, mostly due to the way we don't output oneof values in field order all the + // tieme. If the lengths are equal and the resulting protos are equal, the marshaling is + // guaranteed to be valid. + assertThat(result.getSerializedSize()).isEqualTo(serialized.length); + + // We don't compare JSON strings due to some differences (particularly serializing enums as + // numbers instead of names). This may improve in the future but what matters is what we produce + // can be parsed. + String json = toJson(marshaler); + Message.Builder builder = prototype.newBuilderForType(); + try { + JsonFormat.parser().merge(json, builder); + } catch (InvalidProtocolBufferException e) { + throw new UncheckedIOException(e); + } + + assertThat(builder.build()).isEqualTo(result); + + return result; + } + + private static byte[] toByteArray(Marshaler marshaler) { + ByteArrayOutputStream bos = new ByteArrayOutputStream(); + try { + marshaler.writeBinaryTo(bos); + } catch (IOException e) { + throw new UncheckedIOException(e); + } + return bos.toByteArray(); + } + + private static String toJson(Marshaler marshaler) { + + ByteArrayOutputStream bos = new ByteArrayOutputStream(); + try { + marshaler.writeJsonTo(bos); + } catch (IOException e) { + throw new UncheckedIOException(e); + } + return new String(bos.toByteArray(), StandardCharsets.UTF_8); + } +} diff --git a/integration-tests/otlp/build.gradle.kts b/integration-tests/otlp/build.gradle.kts index 6b01f55ac9e..bbd9bc85c4c 100644 --- a/integration-tests/otlp/build.gradle.kts +++ b/integration-tests/otlp/build.gradle.kts @@ -10,6 +10,7 @@ dependencies { implementation(project(":exporters:otlp:all")) implementation(project(":api:events")) + implementation(project(":extensions:incubator")) compileOnly("com.google.errorprone:error_prone_annotations") diff --git a/integration-tests/otlp/src/main/java/io/opentelemetry/integrationtest/OtlpExporterIntegrationTest.java b/integration-tests/otlp/src/main/java/io/opentelemetry/integrationtest/OtlpExporterIntegrationTest.java index 7bfa82a3876..271409e8ea3 100644 --- a/integration-tests/otlp/src/main/java/io/opentelemetry/integrationtest/OtlpExporterIntegrationTest.java +++ b/integration-tests/otlp/src/main/java/io/opentelemetry/integrationtest/OtlpExporterIntegrationTest.java @@ -5,11 +5,13 @@ package io.opentelemetry.integrationtest; +import static io.opentelemetry.extension.incubator.logs.AnyValue.of; import static java.util.concurrent.CompletableFuture.completedFuture; import static org.assertj.core.api.Assertions.assertThat; import static org.awaitility.Awaitility.await; import static org.testcontainers.Testcontainers.exposeHostPorts; +import com.google.protobuf.ByteString; import com.google.protobuf.InvalidProtocolBufferException; import com.linecorp.armeria.server.ServerBuilder; import com.linecorp.armeria.server.ServiceRequestContext; @@ -38,6 +40,8 @@ import io.opentelemetry.exporter.otlp.logs.OtlpGrpcLogRecordExporter; import io.opentelemetry.exporter.otlp.metrics.OtlpGrpcMetricExporter; import io.opentelemetry.exporter.otlp.trace.OtlpGrpcSpanExporter; +import io.opentelemetry.extension.incubator.logs.ExtendedLogRecordBuilder; +import io.opentelemetry.extension.incubator.logs.KeyAnyValue; import io.opentelemetry.proto.collector.logs.v1.ExportLogsServiceRequest; import io.opentelemetry.proto.collector.logs.v1.ExportLogsServiceResponse; import io.opentelemetry.proto.collector.metrics.v1.ExportMetricsServiceRequest; @@ -45,7 +49,9 @@ import io.opentelemetry.proto.collector.trace.v1.ExportTraceServiceRequest; import io.opentelemetry.proto.collector.trace.v1.ExportTraceServiceResponse; import io.opentelemetry.proto.common.v1.AnyValue; +import io.opentelemetry.proto.common.v1.ArrayValue; import io.opentelemetry.proto.common.v1.KeyValue; +import io.opentelemetry.proto.common.v1.KeyValueList; import io.opentelemetry.proto.logs.v1.ResourceLogs; import io.opentelemetry.proto.logs.v1.ScopeLogs; import io.opentelemetry.proto.metrics.v1.AggregationTemporality; @@ -73,6 +79,7 @@ import io.opentelemetry.sdk.trace.export.SimpleSpanProcessor; import io.opentelemetry.sdk.trace.export.SpanExporter; import java.io.UncheckedIOException; +import java.nio.charset.StandardCharsets; import java.time.Duration; import java.util.ArrayList; import java.util.Collections; @@ -514,6 +521,7 @@ void testOtlpHttpLogExport_mtls() throws Exception { testLogRecordExporter(exporter); } + @SuppressWarnings("BadImport") private static void testLogRecordExporter(LogRecordExporter logRecordExporter) { SdkLoggerProvider loggerProvider = SdkLoggerProvider.builder() @@ -539,10 +547,23 @@ private static void testLogRecordExporter(LogRecordExporter logRecordExporter) { TraceState.getDefault()); try (Scope unused = Span.wrap(spanContext).makeCurrent()) { - logger - .logRecordBuilder() + ((ExtendedLogRecordBuilder) logger.logRecordBuilder()) + .setBody( + of( + KeyAnyValue.of("str_key", of("value")), + KeyAnyValue.of("bool_key", of(true)), + KeyAnyValue.of("int_key", of(1L)), + KeyAnyValue.of("double_key", of(1.1)), + KeyAnyValue.of("bytes_key", of("value".getBytes(StandardCharsets.UTF_8))), + KeyAnyValue.of("arr_key", of(of("value"), of(1L))), + KeyAnyValue.of( + "kv_list", + of( + KeyAnyValue.of("child_str_key", of("value")), + KeyAnyValue.of( + "child_kv_list", + of(KeyAnyValue.of("grandchild_str_key", of("value")))))))) .setTimestamp(100, TimeUnit.NANOSECONDS) - .setBody("log body") .setAllAttributes(Attributes.builder().put("key", "value").build()) .setSeverity(Severity.DEBUG) .setSeverityText("DEBUG") @@ -576,7 +597,98 @@ private static void testLogRecordExporter(LogRecordExporter logRecordExporter) { // LogRecord via Logger.logRecordBuilder()...emit() io.opentelemetry.proto.logs.v1.LogRecord protoLog1 = ilLogs.getLogRecords(0); - assertThat(protoLog1.getBody().getStringValue()).isEqualTo("log body"); + assertThat(protoLog1.getBody()) + .isEqualTo( + AnyValue.newBuilder() + .setKvlistValue( + KeyValueList.newBuilder() + .addValues( + KeyValue.newBuilder() + .setKey("str_key") + .setValue(AnyValue.newBuilder().setStringValue("value").build()) + .build()) + .addValues( + KeyValue.newBuilder() + .setKey("bool_key") + .setValue(AnyValue.newBuilder().setBoolValue(true).build()) + .build()) + .addValues( + KeyValue.newBuilder() + .setKey("int_key") + .setValue(AnyValue.newBuilder().setIntValue(1).build()) + .build()) + .addValues( + KeyValue.newBuilder() + .setKey("double_key") + .setValue(AnyValue.newBuilder().setDoubleValue(1.1).build()) + .build()) + .addValues( + KeyValue.newBuilder() + .setKey("bytes_key") + .setValue( + AnyValue.newBuilder() + .setBytesValue( + ByteString.copyFrom( + "value".getBytes(StandardCharsets.UTF_8))) + .build()) + .build()) + .addValues( + KeyValue.newBuilder() + .setKey("arr_key") + .setValue( + AnyValue.newBuilder() + .setArrayValue( + ArrayValue.newBuilder() + .addValues( + AnyValue.newBuilder() + .setStringValue("value") + .build()) + .addValues( + AnyValue.newBuilder().setIntValue(1).build()) + .build()) + .build()) + .build()) + .addValues( + KeyValue.newBuilder() + .setKey("kv_list") + .setValue( + AnyValue.newBuilder() + .setKvlistValue( + KeyValueList.newBuilder() + .addValues( + KeyValue.newBuilder() + .setKey("child_str_key") + .setValue( + AnyValue.newBuilder() + .setStringValue("value") + .build()) + .build()) + .addValues( + KeyValue.newBuilder() + .setKey("child_kv_list") + .setValue( + AnyValue.newBuilder() + .setKvlistValue( + KeyValueList.newBuilder() + .addValues( + KeyValue.newBuilder() + .setKey( + "grandchild_str_key") + .setValue( + AnyValue + .newBuilder() + .setStringValue( + "value") + .build()) + .build()) + .build()) + .build()) + .build()) + .build()) + .build()) + .build()) + .build()) + .build()); assertThat(protoLog1.getAttributesList()) .isEqualTo( Collections.singletonList( diff --git a/sdk/logs/src/main/java/io/opentelemetry/sdk/logs/SdkLogRecordBuilder.java b/sdk/logs/src/main/java/io/opentelemetry/sdk/logs/SdkLogRecordBuilder.java index 6bdd0407aa5..70683a0d22b 100644 --- a/sdk/logs/src/main/java/io/opentelemetry/sdk/logs/SdkLogRecordBuilder.java +++ b/sdk/logs/src/main/java/io/opentelemetry/sdk/logs/SdkLogRecordBuilder.java @@ -88,7 +88,7 @@ public SdkLogRecordBuilder setSeverityText(String severityText) { @Override public SdkLogRecordBuilder setBody(String body) { - this.body = Body.string(body); + this.body = AnyValueBody.create(AnyValue.of(body)); return this; } From dc8b44f00bb639d264f51d41323d708c0ad554c9 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 7 Dec 2023 14:52:58 -0600 Subject: [PATCH 132/901] Update actions/stale action to v9 (#6056) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/issue-management-stale-action.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/issue-management-stale-action.yml b/.github/workflows/issue-management-stale-action.yml index 18f80c1960e..af57d2e3393 100644 --- a/.github/workflows/issue-management-stale-action.yml +++ b/.github/workflows/issue-management-stale-action.yml @@ -9,7 +9,7 @@ jobs: stale: runs-on: ubuntu-latest steps: - - uses: actions/stale@v8 + - uses: actions/stale@v9 with: repo-token: ${{ secrets.GITHUB_TOKEN }} days-before-stale: 7 From 07413b15a5955d05d1e462dcb043dc0d136162fc Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 7 Dec 2023 14:53:20 -0600 Subject: [PATCH 133/901] Update dependency checkstyle to v10.12.6 (#6055) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- buildSrc/src/main/kotlin/otel.java-conventions.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/buildSrc/src/main/kotlin/otel.java-conventions.gradle.kts b/buildSrc/src/main/kotlin/otel.java-conventions.gradle.kts index 910702266cf..ea77a98b438 100644 --- a/buildSrc/src/main/kotlin/otel.java-conventions.gradle.kts +++ b/buildSrc/src/main/kotlin/otel.java-conventions.gradle.kts @@ -35,7 +35,7 @@ java { checkstyle { configDirectory.set(file("$rootDir/buildscripts/")) - toolVersion = "10.12.5" + toolVersion = "10.12.6" isIgnoreFailures = false configProperties["rootDir"] = rootDir } From cf3b3901d92ad74e0329ca7f6573c03f2e88f6d1 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 7 Dec 2023 14:54:29 -0600 Subject: [PATCH 134/901] Update dependency com.toasttab.android:gummy-bears-api-21 to v0.8.0 (#6041) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- animal-sniffer-signature/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/animal-sniffer-signature/build.gradle.kts b/animal-sniffer-signature/build.gradle.kts index fd5d486ff20..45ccf60f0a3 100644 --- a/animal-sniffer-signature/build.gradle.kts +++ b/animal-sniffer-signature/build.gradle.kts @@ -27,7 +27,7 @@ configurations.add(signatureJarClasspath) configurations.add(generatedSignature) dependencies { - signature("com.toasttab.android:gummy-bears-api-21:0.7.0@signature") + signature("com.toasttab.android:gummy-bears-api-21:0.8.0@signature") signatureJar("com.android.tools:desugar_jdk_libs") } From 4e1771605bfd64699976987196c841996d674411 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 7 Dec 2023 14:54:44 -0600 Subject: [PATCH 135/901] Update dependency io.grpc:grpc-bom to v1.60.0 (#6051) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- dependencyManagement/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index 31d3ae274f5..f5b7b9e16f7 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -14,7 +14,7 @@ val DEPENDENCY_BOMS = listOf( "com.linecorp.armeria:armeria-bom:1.26.3", "com.squareup.okhttp3:okhttp-bom:4.12.0", "com.squareup.okio:okio-bom:3.6.0", // applies to transitive dependencies of okhttp - "io.grpc:grpc-bom:1.59.1", + "io.grpc:grpc-bom:1.60.0", "io.netty:netty-bom:4.1.101.Final", "io.zipkin.brave:brave-bom:5.16.0", "io.zipkin.reporter2:zipkin-reporter-bom:2.16.4", From d491facd83b3e938b83a6f79167db519fa1d3053 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 7 Dec 2023 14:54:59 -0600 Subject: [PATCH 136/901] Update dependency com.tngtech.archunit:archunit-junit5 to v1.2.1 (#6038) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- dependencyManagement/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index f5b7b9e16f7..7c3d709e58d 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -59,7 +59,7 @@ val DEPENDENCIES = listOf( "com.google.code.findbugs:jsr305:3.0.2", "com.google.guava:guava-beta-checker:1.0", "com.sun.net.httpserver:http:20070405", - "com.tngtech.archunit:archunit-junit5:1.2.0", + "com.tngtech.archunit:archunit-junit5:1.2.1", "com.uber.nullaway:nullaway:0.10.18", "edu.berkeley.cs.jqf:jqf-fuzz:1.7", // jqf-fuzz version 1.8+ requires Java 11+ "eu.rekawek.toxiproxy:toxiproxy-java:2.1.7", From 377809536acbf5c2c40cb8525c3a618e08e78297 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 7 Dec 2023 14:55:12 -0600 Subject: [PATCH 137/901] Update dependency org.owasp:dependency-check-gradle to v9.0.3 (#6036) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- buildSrc/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts index e4203690fa5..4e5be662aa1 100644 --- a/buildSrc/build.gradle.kts +++ b/buildSrc/build.gradle.kts @@ -58,7 +58,7 @@ dependencies { implementation("net.ltgt.gradle:gradle-errorprone-plugin:3.1.0") implementation("net.ltgt.gradle:gradle-nullaway-plugin:1.6.0") implementation("org.jetbrains.kotlin:kotlin-gradle-plugin:1.9.21") - implementation("org.owasp:dependency-check-gradle:9.0.1") + implementation("org.owasp:dependency-check-gradle:9.0.3") implementation("ru.vyarus:gradle-animalsniffer-plugin:1.7.1") } From f36cc92b858236c4009fb3794c17c9f760ba6a0c Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 7 Dec 2023 15:15:24 -0600 Subject: [PATCH 138/901] Update plugin com.gradle.enterprise to v3.16 (#6050) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- settings.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/settings.gradle.kts b/settings.gradle.kts index 8e4fc690d1b..4fe708002e2 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -1,7 +1,7 @@ pluginManagement { plugins { id("com.github.johnrengelman.shadow") version "8.1.1" - id("com.gradle.enterprise") version "3.15.1" + id("com.gradle.enterprise") version "3.16" id("de.undercouch.download") version "5.5.0" id("org.jsonschema2pojo") version "1.2.1" id("io.github.gradle-nexus.publish-plugin") version "1.3.0" From c8e1e3619e922981922a1034ce07e2a13e99d819 Mon Sep 17 00:00:00 2001 From: Jonas Kunz Date: Thu, 7 Dec 2023 22:41:03 +0100 Subject: [PATCH 139/901] Improve autoconfiguration capabilities for adding, delaying or dropping spans (#5986) --- ...emetry-sdk-extension-autoconfigure-spi.txt | 5 +- ...ntelemetry-sdk-extension-autoconfigure.txt | 5 +- .../spi/AutoConfigurationCustomizer.java | 34 +++++++++++++ ...AutoConfiguredOpenTelemetrySdkBuilder.java | 49 +++++++++++++++++++ .../LoggerProviderConfiguration.java | 13 ++++- .../TracerProviderConfiguration.java | 13 ++++- .../AutoConfiguredOpenTelemetrySdkTest.java | 49 +++++++++++++++++++ .../LoggerProviderConfigurationTest.java | 1 + .../TracerProviderConfigurationTest.java | 1 + .../LoggerProviderConfigurationTest.java | 1 + 10 files changed, 165 insertions(+), 6 deletions(-) diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-extension-autoconfigure-spi.txt b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-extension-autoconfigure-spi.txt index df26146497b..9f4a3fbb37a 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-extension-autoconfigure-spi.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-extension-autoconfigure-spi.txt @@ -1,2 +1,5 @@ Comparing source compatibility of against -No changes. \ No newline at end of file +*** MODIFIED INTERFACE: PUBLIC ABSTRACT io.opentelemetry.sdk.autoconfigure.spi.AutoConfigurationCustomizer (not serializable) + === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 + +++ NEW METHOD: PUBLIC(+) io.opentelemetry.sdk.autoconfigure.spi.AutoConfigurationCustomizer addLogRecordProcessorCustomizer(java.util.function.BiFunction) + +++ NEW METHOD: PUBLIC(+) io.opentelemetry.sdk.autoconfigure.spi.AutoConfigurationCustomizer addSpanProcessorCustomizer(java.util.function.BiFunction) diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-extension-autoconfigure.txt b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-extension-autoconfigure.txt index df26146497b..c4389093f93 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-extension-autoconfigure.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-extension-autoconfigure.txt @@ -1,2 +1,5 @@ Comparing source compatibility of against -No changes. \ No newline at end of file +*** MODIFIED CLASS: PUBLIC FINAL io.opentelemetry.sdk.autoconfigure.AutoConfiguredOpenTelemetrySdkBuilder (not serializable) + === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 + +++ NEW METHOD: PUBLIC(+) io.opentelemetry.sdk.autoconfigure.spi.AutoConfigurationCustomizer addLogRecordProcessorCustomizer(java.util.function.BiFunction) + +++ NEW METHOD: PUBLIC(+) io.opentelemetry.sdk.autoconfigure.AutoConfiguredOpenTelemetrySdkBuilder addSpanProcessorCustomizer(java.util.function.BiFunction) diff --git a/sdk-extensions/autoconfigure-spi/src/main/java/io/opentelemetry/sdk/autoconfigure/spi/AutoConfigurationCustomizer.java b/sdk-extensions/autoconfigure-spi/src/main/java/io/opentelemetry/sdk/autoconfigure/spi/AutoConfigurationCustomizer.java index e016e6a7424..e49ab220875 100644 --- a/sdk-extensions/autoconfigure-spi/src/main/java/io/opentelemetry/sdk/autoconfigure/spi/AutoConfigurationCustomizer.java +++ b/sdk-extensions/autoconfigure-spi/src/main/java/io/opentelemetry/sdk/autoconfigure/spi/AutoConfigurationCustomizer.java @@ -6,12 +6,14 @@ package io.opentelemetry.sdk.autoconfigure.spi; import io.opentelemetry.context.propagation.TextMapPropagator; +import io.opentelemetry.sdk.logs.LogRecordProcessor; import io.opentelemetry.sdk.logs.SdkLoggerProviderBuilder; import io.opentelemetry.sdk.logs.export.LogRecordExporter; import io.opentelemetry.sdk.metrics.SdkMeterProviderBuilder; import io.opentelemetry.sdk.metrics.export.MetricExporter; import io.opentelemetry.sdk.resources.Resource; import io.opentelemetry.sdk.trace.SdkTracerProviderBuilder; +import io.opentelemetry.sdk.trace.SpanProcessor; import io.opentelemetry.sdk.trace.export.SpanExporter; import io.opentelemetry.sdk.trace.samplers.Sampler; import java.util.Map; @@ -62,6 +64,22 @@ AutoConfigurationCustomizer addSpanExporterCustomizer( BiFunction exporterCustomizer); + /** + * Adds a {@link BiFunction} to invoke for all autoconfigured {@link + * io.opentelemetry.sdk.trace.SpanProcessor}. The return value of the {@link BiFunction} will + * replace the passed-in argument. In contrast to {@link #addSpanExporterCustomizer(BiFunction)} + * this allows modifications to happen before batching occurs. As a result, it is possible to + * efficiently filter spans, add artificial spans or delay spans for enhancing them with external, + * delayed data. + * + *

    Multiple calls will execute the customizers in order. + */ + default AutoConfigurationCustomizer addSpanProcessorCustomizer( + BiFunction + spanProcessorCustomizer) { + return this; + } + /** * Adds a {@link Supplier} of a map of property names and values to use as defaults for the {@link * ConfigProperties} used during auto-configuration. The order of precedence of properties is @@ -164,4 +182,20 @@ default AutoConfigurationCustomizer addLogRecordExporterCustomizer( exporterCustomizer) { return this; } + + /** + * Adds a {@link BiFunction} to invoke for all autoconfigured {@link + * io.opentelemetry.sdk.logs.LogRecordProcessor}s. The return value of the {@link BiFunction} will + * replace the passed-in argument. In contrast to {@link + * #addLogRecordExporterCustomizer(BiFunction)} (BiFunction)} this allows modifications to happen + * before batching occurs. As a result, it is possible to efficiently filter logs, add artificial + * logs or delay logs for enhancing them with external, delayed data. + * + *

    Multiple calls will execute the customizers in order. + */ + default AutoConfigurationCustomizer addLogRecordProcessorCustomizer( + BiFunction + logRecordProcessorCustomizer) { + return this; + } } diff --git a/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/AutoConfiguredOpenTelemetrySdkBuilder.java b/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/AutoConfiguredOpenTelemetrySdkBuilder.java index 1761108081b..2d10524e276 100644 --- a/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/AutoConfiguredOpenTelemetrySdkBuilder.java +++ b/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/AutoConfiguredOpenTelemetrySdkBuilder.java @@ -20,6 +20,7 @@ import io.opentelemetry.sdk.autoconfigure.spi.ConfigurationException; import io.opentelemetry.sdk.autoconfigure.spi.internal.AutoConfigureListener; import io.opentelemetry.sdk.autoconfigure.spi.internal.DefaultConfigProperties; +import io.opentelemetry.sdk.logs.LogRecordProcessor; import io.opentelemetry.sdk.logs.SdkLoggerProvider; import io.opentelemetry.sdk.logs.SdkLoggerProviderBuilder; import io.opentelemetry.sdk.logs.export.LogRecordExporter; @@ -30,6 +31,7 @@ import io.opentelemetry.sdk.resources.Resource; import io.opentelemetry.sdk.trace.SdkTracerProvider; import io.opentelemetry.sdk.trace.SdkTracerProviderBuilder; +import io.opentelemetry.sdk.trace.SpanProcessor; import io.opentelemetry.sdk.trace.export.SpanExporter; import io.opentelemetry.sdk.trace.samplers.Sampler; import java.io.Closeable; @@ -71,6 +73,9 @@ public final class AutoConfiguredOpenTelemetrySdkBuilder implements AutoConfigur propagatorCustomizer = (a, unused) -> a; private BiFunction spanExporterCustomizer = (a, unused) -> a; + + private BiFunction + spanProcessorCustomizer = (a, unused) -> a; private BiFunction samplerCustomizer = (a, unused) -> a; @@ -83,6 +88,8 @@ public final class AutoConfiguredOpenTelemetrySdkBuilder implements AutoConfigur loggerProviderCustomizer = (a, unused) -> a; private BiFunction logRecordExporterCustomizer = (a, unused) -> a; + private BiFunction + logRecordProcessorCustomizer = (a, unused) -> a; private BiFunction resourceCustomizer = (a, unused) -> a; @@ -191,6 +198,26 @@ public AutoConfiguredOpenTelemetrySdkBuilder addSpanExporterCustomizer( return this; } + /** + * Adds a {@link BiFunction} to invoke for all autoconfigured {@link + * io.opentelemetry.sdk.trace.SpanProcessor}. The return value of the {@link BiFunction} will + * replace the passed-in argument. In contrast to {@link #addSpanExporterCustomizer(BiFunction)} + * this allows modifications to happen before batching occurs. As a result, it is possible to + * efficiently filter spans, add artificial spans or delay spans for enhancing them with external, + * delayed data. + * + *

    Multiple calls will execute the customizers in order. + */ + @Override + public AutoConfiguredOpenTelemetrySdkBuilder addSpanProcessorCustomizer( + BiFunction + spanProcessorCustomizer) { + requireNonNull(spanProcessorCustomizer, "spanProcessorCustomizer"); + this.spanProcessorCustomizer = + mergeCustomizer(this.spanProcessorCustomizer, spanProcessorCustomizer); + return this; + } + /** * Adds a {@link Supplier} of a map of property names and values to use as defaults for the {@link * ConfigProperties} used during auto-configuration. The order of precedence of properties is @@ -289,6 +316,26 @@ public AutoConfiguredOpenTelemetrySdkBuilder addLogRecordExporterCustomizer( return this; } + /** + * Adds a {@link BiFunction} to invoke for all autoconfigured {@link + * io.opentelemetry.sdk.logs.LogRecordProcessor}s. The return value of the {@link BiFunction} will + * replace the passed-in argument. In contrast to {@link + * #addLogRecordExporterCustomizer(BiFunction)} (BiFunction)} this allows modifications to happen + * before batching occurs. As a result, it is possible to efficiently filter logs, add artificial + * logs or delay logs for enhancing them with external, delayed data. + * + *

    Multiple calls will execute the customizers in order. + */ + @Override + public AutoConfigurationCustomizer addLogRecordProcessorCustomizer( + BiFunction + logRecordProcessorCustomizer) { + requireNonNull(logRecordProcessorCustomizer, "logRecordProcessorCustomizer"); + this.logRecordProcessorCustomizer = + mergeCustomizer(this.logRecordProcessorCustomizer, logRecordProcessorCustomizer); + return this; + } + /** * Disable the registration of a shutdown hook to shut down the SDK when appropriate. By default, * the shutdown hook is registered. @@ -372,6 +419,7 @@ public AutoConfiguredOpenTelemetrySdk build() { spiHelper, meterProvider, spanExporterCustomizer, + spanProcessorCustomizer, samplerCustomizer, closeables); tracerProviderBuilder = tracerProviderCustomizer.apply(tracerProviderBuilder, config); @@ -386,6 +434,7 @@ public AutoConfiguredOpenTelemetrySdk build() { spiHelper, meterProvider, logRecordExporterCustomizer, + logRecordProcessorCustomizer, closeables); loggerProviderBuilder = loggerProviderCustomizer.apply(loggerProviderBuilder, config); SdkLoggerProvider loggerProvider = loggerProviderBuilder.build(); diff --git a/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/LoggerProviderConfiguration.java b/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/LoggerProviderConfiguration.java index 82ffec2c33e..ff94550ecbb 100644 --- a/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/LoggerProviderConfiguration.java +++ b/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/LoggerProviderConfiguration.java @@ -35,6 +35,8 @@ static void configureLoggerProvider( MeterProvider meterProvider, BiFunction logRecordExporterCustomizer, + BiFunction + logRecordProcessorCustomizer, List closeables) { loggerProviderBuilder.setLogLimits(() -> configureLogLimits(config)); @@ -42,8 +44,15 @@ static void configureLoggerProvider( Map exportersByName = configureLogRecordExporters(config, spiHelper, logRecordExporterCustomizer, closeables); - configureLogRecordProcessors(config, exportersByName, meterProvider, closeables) - .forEach(loggerProviderBuilder::addLogRecordProcessor); + List processors = + configureLogRecordProcessors(config, exportersByName, meterProvider, closeables); + for (LogRecordProcessor processor : processors) { + LogRecordProcessor wrapped = logRecordProcessorCustomizer.apply(processor, config); + if (wrapped != processor) { + closeables.add(wrapped); + } + loggerProviderBuilder.addLogRecordProcessor(wrapped); + } } // Visible for testing diff --git a/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/TracerProviderConfiguration.java b/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/TracerProviderConfiguration.java index 78de1700ed9..1241acccc8d 100644 --- a/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/TracerProviderConfiguration.java +++ b/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/TracerProviderConfiguration.java @@ -40,6 +40,8 @@ static void configureTracerProvider( MeterProvider meterProvider, BiFunction spanExporterCustomizer, + BiFunction + spanProcessorCustomizer, BiFunction samplerCustomizer, List closeables) { @@ -53,8 +55,15 @@ static void configureTracerProvider( SpanExporterConfiguration.configureSpanExporters( config, spiHelper, spanExporterCustomizer, closeables); - configureSpanProcessors(config, exportersByName, meterProvider, closeables) - .forEach(tracerProviderBuilder::addSpanProcessor); + List processors = + configureSpanProcessors(config, exportersByName, meterProvider, closeables); + for (SpanProcessor processor : processors) { + SpanProcessor wrapped = spanProcessorCustomizer.apply(processor, config); + if (wrapped != processor) { + closeables.add(wrapped); + } + tracerProviderBuilder.addSpanProcessor(wrapped); + } } static List configureSpanProcessors( diff --git a/sdk-extensions/autoconfigure/src/test/java/io/opentelemetry/sdk/autoconfigure/AutoConfiguredOpenTelemetrySdkTest.java b/sdk-extensions/autoconfigure/src/test/java/io/opentelemetry/sdk/autoconfigure/AutoConfiguredOpenTelemetrySdkTest.java index 649ad70406b..01047907fca 100644 --- a/sdk-extensions/autoconfigure/src/test/java/io/opentelemetry/sdk/autoconfigure/AutoConfiguredOpenTelemetrySdkTest.java +++ b/sdk-extensions/autoconfigure/src/test/java/io/opentelemetry/sdk/autoconfigure/AutoConfiguredOpenTelemetrySdkTest.java @@ -11,6 +11,7 @@ import static org.assertj.core.api.Assertions.assertThatCode; import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.same; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.doThrow; import static org.mockito.Mockito.mock; @@ -18,6 +19,7 @@ import static org.mockito.Mockito.spy; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.verifyNoInteractions; import static org.mockito.Mockito.when; import io.github.netmikey.logunit.api.LogCapturer; @@ -49,8 +51,11 @@ import io.opentelemetry.sdk.resources.Resource; import io.opentelemetry.sdk.testing.exporter.InMemorySpanExporter; import io.opentelemetry.sdk.trace.IdGenerator; +import io.opentelemetry.sdk.trace.ReadWriteSpan; +import io.opentelemetry.sdk.trace.ReadableSpan; import io.opentelemetry.sdk.trace.SdkTracerProvider; import io.opentelemetry.sdk.trace.SdkTracerProviderBuilder; +import io.opentelemetry.sdk.trace.SpanProcessor; import io.opentelemetry.sdk.trace.data.SpanData; import io.opentelemetry.sdk.trace.export.SimpleSpanProcessor; import io.opentelemetry.sdk.trace.export.SpanExporter; @@ -268,6 +273,48 @@ void builder_addSpanExporterCustomizer() { .isEqualTo(spanExporter2); } + @Test + void builder_addSpanProcessorCustomizer() { + SpanProcessor mockProcessor1 = Mockito.mock(SpanProcessor.class); + SpanProcessor mockProcessor2 = Mockito.mock(SpanProcessor.class); + doReturn(true).when(mockProcessor2).isStartRequired(); + doReturn(true).when(mockProcessor2).isEndRequired(); + Mockito.lenient().doReturn(CompletableResultCode.ofSuccess()).when(mockProcessor2).shutdown(); + Mockito.lenient().when(spanExporter1.shutdown()).thenReturn(CompletableResultCode.ofSuccess()); + + SdkTracerProvider sdkTracerProvider = + builder + .addSpanExporterCustomizer((prev, config) -> spanExporter1) + .addSpanProcessorCustomizer( + (previous, config) -> { + assertThat(previous).isNotSameAs(mockProcessor2); + return mockProcessor1; + }) + .addSpanProcessorCustomizer( + (previous, config) -> { + assertThat(previous).isSameAs(mockProcessor1); + return mockProcessor2; + }) + .build() + .getOpenTelemetrySdk() + .getSdkTracerProvider(); + + assertThat(sdkTracerProvider) + .extracting("sharedState") + .extracting("activeSpanProcessor") + .isSameAs(mockProcessor2); + + Span span = sdkTracerProvider.get("dummy-scope").spanBuilder("dummy-span").startSpan(); + + verify(mockProcessor2).onStart(any(), same((ReadWriteSpan) span)); + + span.end(); + verify(mockProcessor2).onEnd(same((ReadableSpan) span)); + + verifyNoInteractions(mockProcessor1); + verifyNoInteractions(spanExporter1); + } + @Test void builder_addPropertiesSupplier() { AutoConfiguredOpenTelemetrySdk autoConfigured = @@ -352,6 +399,8 @@ void builder_addLoggerProviderCustomizer() { // TODO: add test for addLogRecordExporterCustomizer once OTLP export is enabled by default + // TODO: add test for addLogRecordProcessorCustomizer once OTLP export is enabled by default + @Test void builder_setResultAsGlobalFalse() { GlobalOpenTelemetry.set(OpenTelemetry.noop()); diff --git a/sdk-extensions/autoconfigure/src/test/java/io/opentelemetry/sdk/autoconfigure/LoggerProviderConfigurationTest.java b/sdk-extensions/autoconfigure/src/test/java/io/opentelemetry/sdk/autoconfigure/LoggerProviderConfigurationTest.java index 3bf772665b8..f28bb44f3fd 100644 --- a/sdk-extensions/autoconfigure/src/test/java/io/opentelemetry/sdk/autoconfigure/LoggerProviderConfigurationTest.java +++ b/sdk-extensions/autoconfigure/src/test/java/io/opentelemetry/sdk/autoconfigure/LoggerProviderConfigurationTest.java @@ -48,6 +48,7 @@ void configureLoggerProvider() { SpiHelper.create(LoggerProviderConfiguration.class.getClassLoader()), MeterProvider.noop(), (a, unused) -> a, + (a, unused) -> a, closeables); cleanup.addCloseables(closeables); diff --git a/sdk-extensions/autoconfigure/src/test/java/io/opentelemetry/sdk/autoconfigure/TracerProviderConfigurationTest.java b/sdk-extensions/autoconfigure/src/test/java/io/opentelemetry/sdk/autoconfigure/TracerProviderConfigurationTest.java index 3ce674d37e5..d12ab1744f4 100644 --- a/sdk-extensions/autoconfigure/src/test/java/io/opentelemetry/sdk/autoconfigure/TracerProviderConfigurationTest.java +++ b/sdk-extensions/autoconfigure/src/test/java/io/opentelemetry/sdk/autoconfigure/TracerProviderConfigurationTest.java @@ -79,6 +79,7 @@ void configureTracerProvider() { MeterProvider.noop(), (a, unused) -> a, (a, unused) -> a, + (a, unused) -> a, closeables); try (SdkTracerProvider tracerProvider = tracerProviderBuilder.build()) { diff --git a/sdk-extensions/autoconfigure/src/testFullConfig/java/io/opentelemetry/sdk/autoconfigure/LoggerProviderConfigurationTest.java b/sdk-extensions/autoconfigure/src/testFullConfig/java/io/opentelemetry/sdk/autoconfigure/LoggerProviderConfigurationTest.java index 0e1fc3e8a83..6603abf7497 100644 --- a/sdk-extensions/autoconfigure/src/testFullConfig/java/io/opentelemetry/sdk/autoconfigure/LoggerProviderConfigurationTest.java +++ b/sdk-extensions/autoconfigure/src/testFullConfig/java/io/opentelemetry/sdk/autoconfigure/LoggerProviderConfigurationTest.java @@ -47,6 +47,7 @@ void configureLoggerProvider() { SpiHelper.create(LoggerProviderConfiguration.class.getClassLoader()), MeterProvider.noop(), (a, unused) -> a, + (a, unused) -> a, closeables); cleanup.addCloseables(closeables); From 2b33f9fb070822161206a8a62cfde04b214fc3e6 Mon Sep 17 00:00:00 2001 From: Gregor Zeitlinger Date: Thu, 7 Dec 2023 23:27:57 +0100 Subject: [PATCH 140/901] Extended tracer (#6017) Co-authored-by: jack-berg <34418638+jack-berg@users.noreply.github.com> Co-authored-by: Jack Berg --- extensions/incubator/README.md | 167 ++++++++++++ extensions/incubator/build.gradle.kts | 1 + .../propagation/CaseInsensitiveMap.java | 31 +++ .../ExtendedContextPropagators.java | 81 ++++++ .../incubator/trace/ExtendedSpanBuilder.java | 230 +++++++++++++++++ .../incubator/trace/ExtendedTracer.java | 58 ++--- .../incubator/trace/SpanCallable.java | 17 ++ .../incubator/trace/SpanRunnable.java | 16 ++ .../incubator/trace/ExtendedTracerTest.java | 242 ++++++++++++------ 9 files changed, 734 insertions(+), 109 deletions(-) create mode 100644 extensions/incubator/README.md create mode 100644 extensions/incubator/src/main/java/io/opentelemetry/extension/incubator/propagation/CaseInsensitiveMap.java create mode 100644 extensions/incubator/src/main/java/io/opentelemetry/extension/incubator/propagation/ExtendedContextPropagators.java create mode 100644 extensions/incubator/src/main/java/io/opentelemetry/extension/incubator/trace/ExtendedSpanBuilder.java create mode 100644 extensions/incubator/src/main/java/io/opentelemetry/extension/incubator/trace/SpanCallable.java create mode 100644 extensions/incubator/src/main/java/io/opentelemetry/extension/incubator/trace/SpanRunnable.java diff --git a/extensions/incubator/README.md b/extensions/incubator/README.md new file mode 100644 index 00000000000..64264d01681 --- /dev/null +++ b/extensions/incubator/README.md @@ -0,0 +1,167 @@ +# ExtendedTracer + +Utility methods to make it easier to use the OpenTelemetry tracer. + +## Usage Examples + +Here are some examples how the utility methods can help reduce boilerplate code. + +### Tracing a function + +Before: + + +```java +Span span = tracer.spanBuilder("reset_checkout").startSpan(); +String transactionId; +try (Scope scope = span.makeCurrent()) { + transactionId = resetCheckout(cartId); +} catch (Throwable e) { + span.setStatus(StatusCode.ERROR); + span.recordException(e); + throw e; // or throw new RuntimeException(e) - depending on your error handling strategy +} finally { + span.end(); +} +``` + + +After: + +```java +import io.opentelemetry.extension.incubator.trace.ExtendedTracer; + +ExtendedTracer extendedTracer = ExtendedTracer.create(tracer); +String transactionId = extendedTracer.spanBuilder("reset_checkout").startAndCall(() -> resetCheckout(cartId)); +``` + +If you want to set attributes on the span, you can use the `startAndCall` method on the span builder: + +```java +import io.opentelemetry.extension.incubator.trace.ExtendedTracer; + +ExtendedTracer extendedTracer = ExtendedTracer.create(tracer); +String transactionId = extendedTracer.spanBuilder("reset_checkout") + .setAttribute("foo", "bar") + .startAndCall(() -> resetCheckout(cartId)); +``` + +Note: + +- Use `startAndRun` instead of `startAndCall` if the function returns `void` (both on the tracer and span builder). +- Exceptions are re-thrown without modification - see [Exception handling](#exception-handling) + for more details. + +### Trace context propagation + +Before: + +```java +Map propagationHeaders = new HashMap<>(); +openTelemetry + .getPropagators() + .getTextMapPropagator() + .inject( + Context.current(), + propagationHeaders, + (map, key, value) -> { + if (map != null) { + map.put(key, value); + } + }); + +// add propagationHeaders to request headers and call checkout service +``` + + +```java +// in checkout service: get request headers into a Map requestHeaders +Map requestHeaders = new HashMap<>(); +String cartId = "cartId"; + +SpanBuilder spanBuilder = tracer.spanBuilder("checkout_cart"); + +TextMapGetter> TEXT_MAP_GETTER = + new TextMapGetter>() { + @Override + public Set keys(Map carrier) { + return carrier.keySet(); + } + + @Override + @Nullable + public String get(@Nullable Map carrier, String key) { + return carrier == null ? null : carrier.get(key); + } + }; + +Map normalizedTransport = + requestHeaders.entrySet().stream() + .collect( + Collectors.toMap( + entry -> entry.getKey().toLowerCase(Locale.ROOT), Map.Entry::getValue)); +Context newContext = openTelemetry + .getPropagators() + .getTextMapPropagator() + .extract(Context.current(), normalizedTransport, TEXT_MAP_GETTER); +String transactionId; +try (Scope ignore = newContext.makeCurrent()) { + Span span = spanBuilder.setSpanKind(SERVER).startSpan(); + try (Scope scope = span.makeCurrent()) { + transactionId = processCheckout(cartId); + } catch (Throwable e) { + span.setStatus(StatusCode.ERROR); + span.recordException(e); + throw e; // or throw new RuntimeException(e) - depending on your error handling strategy + } finally { + span.end(); + } +} +``` + + +After: + +```java +import io.opentelemetry.extension.incubator.propagation.ExtendedContextPropagators; + +Map propagationHeaders = + ExtendedContextPropagators.getTextMapPropagationContext(openTelemetry.getPropagators()); +// add propagationHeaders to request headers and call checkout service +``` + +```java +import io.opentelemetry.api.trace.SpanKind; +import io.opentelemetry.extension.incubator.trace.ExtendedTracer; + +// in checkout service: get request headers into a Map requestHeaders +Map requestHeaders = new HashMap<>(); +String cartId = "cartId"; + +ExtendedTracer extendedTracer = ExtendedTracer.create(tracer); +String transactionId = extendedTracer.spanBuilder("checkout_cart") + .setSpanKind(SpanKind.SERVER) + .setParentFrom(openTelemetry.getPropagators(), requestHeaders) + .startAndCall(() -> processCheckout(cartId)); +``` + +## Exception handling + +`ExtendedTracer` re-throws exceptions without modification. This means you can +catch exceptions around `ExtendedTracer` calls and handle them as you would without `ExtendedTracer`. + +When an exception is encountered during an `ExtendedTracer` call, the span is marked as error and +the exception is recorded. + +If you want to customize this behaviour, e.g. to only record the exception, because you are +able to recover from the error, you can call the overloaded method of `startAndCall` or +`startAndRun` that takes an exception handler: + +```java +import io.opentelemetry.api.trace.Span; +import io.opentelemetry.extension.incubator.trace.ExtendedTracer; + +ExtendedTracer extendedTracer = ExtendedTracer.create(tracer); +String transactionId = extendedTracer.spanBuilder("checkout_cart") + .startAndCall(() -> processCheckout(cartId), Span::recordException); +``` diff --git a/extensions/incubator/build.gradle.kts b/extensions/incubator/build.gradle.kts index 6e79f9361fd..5812f6462af 100644 --- a/extensions/incubator/build.gradle.kts +++ b/extensions/incubator/build.gradle.kts @@ -14,5 +14,6 @@ dependencies { annotationProcessor("com.google.auto.value:auto-value") + testImplementation("io.opentelemetry.semconv:opentelemetry-semconv:1.21.0-alpha") testImplementation(project(":sdk:testing")) } diff --git a/extensions/incubator/src/main/java/io/opentelemetry/extension/incubator/propagation/CaseInsensitiveMap.java b/extensions/incubator/src/main/java/io/opentelemetry/extension/incubator/propagation/CaseInsensitiveMap.java new file mode 100644 index 00000000000..5c6d7840a56 --- /dev/null +++ b/extensions/incubator/src/main/java/io/opentelemetry/extension/incubator/propagation/CaseInsensitiveMap.java @@ -0,0 +1,31 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.extension.incubator.propagation; + +import java.util.HashMap; +import java.util.Locale; +import java.util.Map; +import javax.annotation.Nullable; + +class CaseInsensitiveMap extends HashMap { + + private static final long serialVersionUID = -4202518750189126871L; + + CaseInsensitiveMap(Map carrier) { + super(carrier); + } + + @Override + public String put(String key, String value) { + return super.put(key.toLowerCase(Locale.ROOT), value); + } + + @Override + @Nullable + public String get(Object key) { + return super.get(((String) key).toLowerCase(Locale.ROOT)); + } +} diff --git a/extensions/incubator/src/main/java/io/opentelemetry/extension/incubator/propagation/ExtendedContextPropagators.java b/extensions/incubator/src/main/java/io/opentelemetry/extension/incubator/propagation/ExtendedContextPropagators.java new file mode 100644 index 00000000000..8095d81b69f --- /dev/null +++ b/extensions/incubator/src/main/java/io/opentelemetry/extension/incubator/propagation/ExtendedContextPropagators.java @@ -0,0 +1,81 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.extension.incubator.propagation; + +import io.opentelemetry.api.OpenTelemetry; +import io.opentelemetry.context.Context; +import io.opentelemetry.context.propagation.ContextPropagators; +import io.opentelemetry.context.propagation.TextMapGetter; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; +import java.util.Set; +import javax.annotation.Nullable; + +/** + * Utility class to simplify context propagation. + * + *

    The README + * explains the use cases in more detail. + */ +public final class ExtendedContextPropagators { + + private ExtendedContextPropagators() {} + + private static final TextMapGetter> TEXT_MAP_GETTER = + new TextMapGetter>() { + @Override + public Set keys(Map carrier) { + return carrier.keySet(); + } + + @Override + @Nullable + public String get(@Nullable Map carrier, String key) { + return carrier == null ? null : carrier.get(key); + } + }; + + /** + * Injects the current context into a string map, which can then be added to HTTP headers or the + * metadata of a message. + * + * @param propagators provide the propagators from {@link OpenTelemetry#getPropagators()} + */ + public static Map getTextMapPropagationContext(ContextPropagators propagators) { + Map carrier = new HashMap<>(); + propagators + .getTextMapPropagator() + .inject( + Context.current(), + carrier, + (map, key, value) -> { + if (map != null) { + map.put(key, value); + } + }); + + return Collections.unmodifiableMap(carrier); + } + + /** + * Extract the context from a string map, which you get from HTTP headers of the metadata of a + * message you're processing. + * + * @param carrier the string map + * @param propagators provide the propagators from {@link OpenTelemetry#getPropagators()} + */ + public static Context extractTextMapPropagationContext( + Map carrier, ContextPropagators propagators) { + Context current = Context.current(); + if (carrier == null) { + return current; + } + CaseInsensitiveMap caseInsensitiveMap = new CaseInsensitiveMap(carrier); + return propagators.getTextMapPropagator().extract(current, caseInsensitiveMap, TEXT_MAP_GETTER); + } +} diff --git a/extensions/incubator/src/main/java/io/opentelemetry/extension/incubator/trace/ExtendedSpanBuilder.java b/extensions/incubator/src/main/java/io/opentelemetry/extension/incubator/trace/ExtendedSpanBuilder.java new file mode 100644 index 00000000000..f28b75dceb7 --- /dev/null +++ b/extensions/incubator/src/main/java/io/opentelemetry/extension/incubator/trace/ExtendedSpanBuilder.java @@ -0,0 +1,230 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.extension.incubator.trace; + +import io.opentelemetry.api.OpenTelemetry; +import io.opentelemetry.api.common.AttributeKey; +import io.opentelemetry.api.common.Attributes; +import io.opentelemetry.api.trace.Span; +import io.opentelemetry.api.trace.SpanBuilder; +import io.opentelemetry.api.trace.SpanContext; +import io.opentelemetry.api.trace.SpanKind; +import io.opentelemetry.api.trace.StatusCode; +import io.opentelemetry.context.Context; +import io.opentelemetry.context.Scope; +import io.opentelemetry.context.propagation.ContextPropagators; +import io.opentelemetry.extension.incubator.propagation.ExtendedContextPropagators; +import java.time.Instant; +import java.util.Map; +import java.util.concurrent.TimeUnit; +import java.util.function.BiConsumer; + +public final class ExtendedSpanBuilder implements SpanBuilder { + private final SpanBuilder delegate; + + ExtendedSpanBuilder(SpanBuilder delegate) { + this.delegate = delegate; + } + + @Override + public ExtendedSpanBuilder setParent(Context context) { + delegate.setParent(context); + return this; + } + + @Override + public ExtendedSpanBuilder setNoParent() { + delegate.setNoParent(); + return this; + } + + @Override + public ExtendedSpanBuilder addLink(SpanContext spanContext) { + delegate.addLink(spanContext); + return this; + } + + @Override + public ExtendedSpanBuilder addLink(SpanContext spanContext, Attributes attributes) { + delegate.addLink(spanContext, attributes); + return this; + } + + @Override + public ExtendedSpanBuilder setAttribute(String key, String value) { + delegate.setAttribute(key, value); + return this; + } + + @Override + public ExtendedSpanBuilder setAttribute(String key, long value) { + delegate.setAttribute(key, value); + return this; + } + + @Override + public ExtendedSpanBuilder setAttribute(String key, double value) { + delegate.setAttribute(key, value); + return this; + } + + @Override + public ExtendedSpanBuilder setAttribute(String key, boolean value) { + delegate.setAttribute(key, value); + return this; + } + + @Override + public ExtendedSpanBuilder setAttribute(AttributeKey key, T value) { + delegate.setAttribute(key, value); + return this; + } + + @Override + public ExtendedSpanBuilder setAllAttributes(Attributes attributes) { + delegate.setAllAttributes(attributes); + return this; + } + + @Override + public ExtendedSpanBuilder setSpanKind(SpanKind spanKind) { + delegate.setSpanKind(spanKind); + return this; + } + + @Override + public ExtendedSpanBuilder setStartTimestamp(long startTimestamp, TimeUnit unit) { + delegate.setStartTimestamp(startTimestamp, unit); + return this; + } + + @Override + public ExtendedSpanBuilder setStartTimestamp(Instant startTimestamp) { + delegate.setStartTimestamp(startTimestamp); + return this; + } + + /** + * Extract a span context from the given carrier and set it as parent of the span for {@link + * #startAndCall(SpanCallable)} and {@link #startAndRun(SpanRunnable)}. + * + *

    The span context will be extracted from the carrier, which you usually get from + * HTTP headers of the metadata of a message you're processing. + * + *

    A typical usage would be: + * ExtendedTracer.create(tracer) + * .setSpanKind(SpanKind.SERVER) + * .setParentFrom(propagators, carrier) + * .run("my-span", () -> { ... }); + * + * + * @param propagators provide the propagators from {@link OpenTelemetry#getPropagators()} + * @param carrier the string map where to extract the span context from + */ + public ExtendedSpanBuilder setParentFrom( + ContextPropagators propagators, Map carrier) { + setParent(ExtendedContextPropagators.extractTextMapPropagationContext(carrier, propagators)); + return this; + } + + @Override + public Span startSpan() { + return delegate.startSpan(); + } + + /** + * Runs the given {@link SpanCallable} inside of the span created by the given {@link + * SpanBuilder}. The span will be ended at the end of the {@link SpanCallable}. + * + *

    If an exception is thrown by the {@link SpanCallable}, the span will be marked as error, and + * the exception will be recorded. + * + * @param spanCallable the {@link SpanCallable} to call + * @param the type of the result + * @param the type of the exception + * @return the result of the {@link SpanCallable} + */ + public T startAndCall(SpanCallable spanCallable) throws E { + return startAndCall(spanCallable, ExtendedSpanBuilder::setSpanError); + } + + /** + * Runs the given {@link SpanCallable} inside of the span created by the given {@link + * SpanBuilder}. The span will be ended at the end of the {@link SpanCallable}. + * + *

    If an exception is thrown by the {@link SpanCallable}, the handleException + * consumer will be called, giving you the opportunity to handle the exception and span in a + * custom way, e.g. not marking the span as error. + * + * @param spanCallable the {@link SpanCallable} to call + * @param handleException the consumer to call when an exception is thrown + * @param the type of the result + * @param the type of the exception + * @return the result of the {@link SpanCallable} + */ + public T startAndCall( + SpanCallable spanCallable, BiConsumer handleException) throws E { + Span span = startSpan(); + + //noinspection unused + try (Scope unused = span.makeCurrent()) { + return spanCallable.callInSpan(); + } catch (Throwable e) { + handleException.accept(span, e); + throw e; + } finally { + span.end(); + } + } + + /** + * Runs the given {@link SpanRunnable} inside of the span created by the given {@link + * SpanBuilder}. The span will be ended at the end of the {@link SpanRunnable}. + * + *

    If an exception is thrown by the {@link SpanRunnable}, the span will be marked as error, and + * the exception will be recorded. + * + * @param runnable the {@link SpanRunnable} to run + * @param the type of the exception + */ + @SuppressWarnings("NullAway") + public void startAndRun(SpanRunnable runnable) throws E { + startAndRun(runnable, ExtendedSpanBuilder::setSpanError); + } + + /** + * Runs the given {@link SpanRunnable} inside of the span created by the given {@link + * SpanBuilder}. The span will be ended at the end of the {@link SpanRunnable}. + * + *

    If an exception is thrown by the {@link SpanRunnable}, the handleException + * consumer will be called, giving you the opportunity to handle the exception and span in a + * custom way, e.g. not marking the span as error. + * + * @param runnable the {@link SpanRunnable} to run + * @param the type of the exception + */ + @SuppressWarnings("NullAway") + public void startAndRun( + SpanRunnable runnable, BiConsumer handleException) throws E { + startAndCall( + () -> { + runnable.runInSpan(); + return null; + }, + handleException); + } + + /** + * Marks a span as error. This is the default exception handler. + * + * @param span the span + * @param exception the exception that caused the error + */ + private static void setSpanError(Span span, Throwable exception) { + span.setStatus(StatusCode.ERROR); + span.recordException(exception); + } +} diff --git a/extensions/incubator/src/main/java/io/opentelemetry/extension/incubator/trace/ExtendedTracer.java b/extensions/incubator/src/main/java/io/opentelemetry/extension/incubator/trace/ExtendedTracer.java index 1be6bc899fa..a564063e49e 100644 --- a/extensions/incubator/src/main/java/io/opentelemetry/extension/incubator/trace/ExtendedTracer.java +++ b/extensions/incubator/src/main/java/io/opentelemetry/extension/incubator/trace/ExtendedTracer.java @@ -5,54 +5,40 @@ package io.opentelemetry.extension.incubator.trace; -import io.opentelemetry.api.trace.Span; -import io.opentelemetry.api.trace.SpanBuilder; import io.opentelemetry.api.trace.Tracer; -import io.opentelemetry.context.Scope; -import java.util.concurrent.Callable; -/** Provides easy mechanisms for wrapping standard Java constructs with an OpenTelemetry Span. */ +/** + * Utility class to simplify tracing. + * + *

    The README + * explains the use cases in more detail. + */ public final class ExtendedTracer implements Tracer { private final Tracer delegate; - /** Create a new {@link ExtendedTracer} that wraps the provided Tracer. */ - public static ExtendedTracer create(Tracer delegate) { - return new ExtendedTracer(delegate); - } - private ExtendedTracer(Tracer delegate) { this.delegate = delegate; } - /** Run the provided {@link Runnable} and wrap with a {@link Span} with the provided name. */ - public void run(String spanName, Runnable runnable) { - Span span = delegate.spanBuilder(spanName).startSpan(); - try (Scope scope = span.makeCurrent()) { - runnable.run(); - } catch (Throwable e) { - span.recordException(e); - throw e; - } finally { - span.end(); - } - } - - /** Call the provided {@link Callable} and wrap with a {@link Span} with the provided name. */ - public T call(String spanName, Callable callable) throws Exception { - Span span = delegate.spanBuilder(spanName).startSpan(); - try (Scope scope = span.makeCurrent()) { - return callable.call(); - } catch (Throwable e) { - span.recordException(e); - throw e; - } finally { - span.end(); - } + /** + * Creates a new instance of {@link ExtendedTracer}. + * + * @param delegate the {@link Tracer} to use + */ + public static ExtendedTracer create(Tracer delegate) { + return new ExtendedTracer(delegate); } + /** + * Creates a new {@link ExtendedSpanBuilder} with the given span name. + * + * @param spanName the name of the span + * @return the {@link ExtendedSpanBuilder} + */ @Override - public SpanBuilder spanBuilder(String spanName) { - return delegate.spanBuilder(spanName); + public ExtendedSpanBuilder spanBuilder(String spanName) { + return new ExtendedSpanBuilder(delegate.spanBuilder(spanName)); } } diff --git a/extensions/incubator/src/main/java/io/opentelemetry/extension/incubator/trace/SpanCallable.java b/extensions/incubator/src/main/java/io/opentelemetry/extension/incubator/trace/SpanCallable.java new file mode 100644 index 00000000000..eb87683f04d --- /dev/null +++ b/extensions/incubator/src/main/java/io/opentelemetry/extension/incubator/trace/SpanCallable.java @@ -0,0 +1,17 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.extension.incubator.trace; + +/** + * An interface for creating a lambda that is wrapped in a span, returns a value, and that may + * throw. + * + * @param Thrown exception type. + */ +@FunctionalInterface +public interface SpanCallable { + T callInSpan() throws E; +} diff --git a/extensions/incubator/src/main/java/io/opentelemetry/extension/incubator/trace/SpanRunnable.java b/extensions/incubator/src/main/java/io/opentelemetry/extension/incubator/trace/SpanRunnable.java new file mode 100644 index 00000000000..508df5a6c31 --- /dev/null +++ b/extensions/incubator/src/main/java/io/opentelemetry/extension/incubator/trace/SpanRunnable.java @@ -0,0 +1,16 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.extension.incubator.trace; + +/** + * An interface for creating a lambda that is wrapped in a span and that may throw. + * + * @param Thrown exception type. + */ +@FunctionalInterface +public interface SpanRunnable { + void runInSpan() throws E; +} diff --git a/extensions/incubator/src/test/java/io/opentelemetry/extension/incubator/trace/ExtendedTracerTest.java b/extensions/incubator/src/test/java/io/opentelemetry/extension/incubator/trace/ExtendedTracerTest.java index 537fb8aa447..2268d6e59a0 100644 --- a/extensions/incubator/src/test/java/io/opentelemetry/extension/incubator/trace/ExtendedTracerTest.java +++ b/extensions/incubator/src/test/java/io/opentelemetry/extension/incubator/trace/ExtendedTracerTest.java @@ -5,113 +5,209 @@ package io.opentelemetry.extension.incubator.trace; +import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.equalTo; +import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.satisfies; import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.assertj.core.api.Assertions.assertThatException; +import static org.assertj.core.api.Assertions.assertThatIllegalStateException; +import static org.junit.jupiter.api.Named.named; -import io.opentelemetry.api.common.AttributeKey; +import com.google.errorprone.annotations.Keep; import io.opentelemetry.api.common.Attributes; import io.opentelemetry.api.trace.Span; -import io.opentelemetry.api.trace.Tracer; +import io.opentelemetry.api.trace.SpanKind; +import io.opentelemetry.context.Context; +import io.opentelemetry.context.Scope; +import io.opentelemetry.context.propagation.ContextPropagators; +import io.opentelemetry.extension.incubator.propagation.ExtendedContextPropagators; +import io.opentelemetry.sdk.testing.assertj.SpanDataAssert; import io.opentelemetry.sdk.testing.junit5.OpenTelemetryExtension; +import io.opentelemetry.sdk.trace.data.StatusData; +import io.opentelemetry.semconv.SemanticAttributes; +import java.time.Instant; +import java.util.Collections; +import java.util.Map; +import java.util.function.BiConsumer; +import java.util.stream.Stream; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.RegisterExtension; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; class ExtendedTracerTest { + + interface ThrowingBiConsumer { + void accept(T t, U u) throws Throwable; + } + @RegisterExtension static final OpenTelemetryExtension otelTesting = OpenTelemetryExtension.create(); - private final Tracer tracer = otelTesting.getOpenTelemetry().getTracer("test"); + private final ExtendedTracer extendedTracer = + ExtendedTracer.create(otelTesting.getOpenTelemetry().getTracer("test")); @Test - void runRunnable() { - ExtendedTracer.create(tracer).run("testSpan", () -> Span.current().setAttribute("one", 1)); - - otelTesting - .assertTraces() - .hasTracesSatisfyingExactly( - traceAssert -> - traceAssert.hasSpansSatisfyingExactly( - spanDataAssert -> - spanDataAssert - .hasName("testSpan") - .hasAttributes(Attributes.of(AttributeKey.longKey("one"), 1L)))); - } - - @Test - void runRunnable_throws() { - assertThatThrownBy( + void wrapInSpan() { + assertThatIllegalStateException() + .isThrownBy( () -> - ExtendedTracer.create(tracer) - .run( - "throwingRunnable", + extendedTracer + .spanBuilder("test") + .startAndRun( () -> { - Span.current().setAttribute("one", 1); - throw new RuntimeException("failed"); - })) - .isInstanceOf(RuntimeException.class); + // runs in span + throw new IllegalStateException("ex"); + })); + + String result = + extendedTracer + .spanBuilder("another test") + .startAndCall( + () -> { + // runs in span + return "result"; + }); + assertThat(result).isEqualTo("result"); otelTesting .assertTraces() .hasTracesSatisfyingExactly( - traceAssert -> - traceAssert.hasSpansSatisfyingExactly( + trace -> + trace.hasSpansSatisfyingExactly( span -> - span.hasName("throwingRunnable") - .hasAttributes(Attributes.of(AttributeKey.longKey("one"), 1L)) - .hasEventsSatisfying( - (events) -> - assertThat(events) - .singleElement() - .satisfies( - eventData -> - assertThat(eventData.getName()) - .isEqualTo("exception"))))); + span.hasName("test") + .hasStatus(StatusData.error()) + .hasEventsSatisfyingExactly( + event -> + event + .hasName("exception") + .hasAttributesSatisfyingExactly( + equalTo( + SemanticAttributes.EXCEPTION_TYPE, + "java.lang.IllegalStateException"), + satisfies( + SemanticAttributes.EXCEPTION_STACKTRACE, + string -> + string.contains( + "java.lang.IllegalStateException: ex")), + equalTo(SemanticAttributes.EXCEPTION_MESSAGE, "ex")))), + trace -> trace.hasSpansSatisfyingExactly(a -> a.hasName("another test"))); } @Test - void callCallable() throws Exception { - assertThat( - ExtendedTracer.create(tracer) - .call( - "spanCallable", - () -> { - Span.current().setAttribute("one", 1); - return "hello"; - })) - .isEqualTo("hello"); + void propagation() { + extendedTracer + .spanBuilder("parent") + .startAndRun( + () -> { + ContextPropagators propagators = otelTesting.getOpenTelemetry().getPropagators(); + Map propagationHeaders = + ExtendedContextPropagators.getTextMapPropagationContext(propagators); + assertThat(propagationHeaders).hasSize(1).containsKey("traceparent"); + + // make sure the parent span is not stored in a thread local anymore + Span invalid = Span.getInvalid(); + //noinspection unused + try (Scope unused = invalid.makeCurrent()) { + extendedTracer + .spanBuilder("child") + .setSpanKind(SpanKind.SERVER) + .setParent(Context.current()) + .setNoParent() + .setParentFrom(propagators, propagationHeaders) + .setAttribute( + "key", + "value") // any method can be called here on the span (and we increase the + // test coverage) + .setAttribute("key2", 0) + .setAttribute("key3", 0.0) + .setAttribute("key4", false) + .setAttribute(SemanticAttributes.CLIENT_PORT, 1234L) + .addLink(invalid.getSpanContext()) + .addLink(invalid.getSpanContext(), Attributes.empty()) + .setAllAttributes(Attributes.empty()) + .setStartTimestamp(0, java.util.concurrent.TimeUnit.NANOSECONDS) + .setStartTimestamp(Instant.MIN) + .startAndRun(() -> {}); + } + }); otelTesting .assertTraces() .hasTracesSatisfyingExactly( - traceAssert -> - traceAssert.hasSpansSatisfyingExactly( - spanDataAssert -> - spanDataAssert - .hasName("spanCallable") - .hasAttributes(Attributes.of(AttributeKey.longKey("one"), 1L)))); + trace -> + trace.hasSpansSatisfyingExactly( + SpanDataAssert::hasNoParent, span -> span.hasParent(trace.getSpan(0)))); } - @Test - void callCallable_throws() { - assertThatThrownBy( + private static class ExtractAndRunParameter { + private final ThrowingBiConsumer> extractAndRun; + private final SpanKind wantKind; + private final StatusData wantStatus; + + private ExtractAndRunParameter( + ThrowingBiConsumer> extractAndRun, + SpanKind wantKind, + StatusData wantStatus) { + this.extractAndRun = extractAndRun; + this.wantKind = wantKind; + this.wantStatus = wantStatus; + } + } + + @Keep + private static Stream extractAndRun() { + BiConsumer ignoreException = + (span, throwable) -> { + // ignore + }; + return Stream.of( + Arguments.of( + named( + "server", + new ExtractAndRunParameter( + (t, c) -> + t.spanBuilder("span") + .setSpanKind(SpanKind.SERVER) + .setParentFrom( + otelTesting.getOpenTelemetry().getPropagators(), + Collections.emptyMap()) + .startAndCall(c), + SpanKind.SERVER, + StatusData.error()))), + Arguments.of( + named( + "server - ignore exception", + new ExtractAndRunParameter( + (t, c) -> + t.spanBuilder("span") + .setSpanKind(SpanKind.SERVER) + .setParentFrom( + otelTesting.getOpenTelemetry().getPropagators(), + Collections.emptyMap()) + .startAndCall(c, ignoreException), + SpanKind.SERVER, + StatusData.unset())))); + } + + @ParameterizedTest + @MethodSource + void extractAndRun(ExtractAndRunParameter parameter) { + assertThatException() + .isThrownBy( () -> - ExtendedTracer.create(tracer) - .call( - "throwingCallable", - () -> { - Span.current().setAttribute("one", 1); - throw new RuntimeException("failed"); - })) - .isInstanceOf(RuntimeException.class); + parameter.extractAndRun.accept( + extendedTracer, + () -> { + throw new RuntimeException("ex"); + })); otelTesting .assertTraces() .hasTracesSatisfyingExactly( - traceAssert -> - traceAssert.hasSpansSatisfyingExactly( - spanDataAssert -> - spanDataAssert - .hasName("throwingCallable") - .hasAttributes(Attributes.of(AttributeKey.longKey("one"), 1L)))); + trace -> + trace.hasSpansSatisfyingExactly( + span -> span.hasKind(parameter.wantKind).hasStatus(parameter.wantStatus))); } } From 902d68cf2abd081aea8de44898a38cc718e4bd56 Mon Sep 17 00:00:00 2001 From: jack-berg <34418638+jack-berg@users.noreply.github.com> Date: Thu, 7 Dec 2023 16:28:15 -0600 Subject: [PATCH 141/901] Add connectTimeout configuration option OtlpHttp{Signal}Exporters (#5941) --- .../opentelemetry-exporter-otlp.txt | 13 ++++- .../internal/http/HttpExporterBuilder.java | 11 +++-- .../internal/http/HttpSenderProvider.java | 2 + .../OtlpHttpLogRecordExporterBuilder.java | 20 ++++++++ .../OtlpHttpMetricExporterBuilder.java | 20 ++++++++ .../trace/OtlpHttpSpanExporterBuilder.java | 20 ++++++++ .../AbstractHttpTelemetryExporterTest.java | 49 +++++++++++++++++++ .../GrpcLogRecordExporterBuilderWrapper.java | 10 ++++ .../GrpcMetricExporterBuilderWrapper.java | 10 ++++ .../GrpcSpanExporterBuilderWrapper.java | 10 ++++ .../HttpLogRecordExporterBuilderWrapper.java | 12 +++++ .../HttpMetricExporterBuilderWrapper.java | 12 +++++ .../HttpSpanExporterBuilderWrapper.java | 12 +++++ ...anagedChannelTelemetryExporterBuilder.java | 12 +++++ .../internal/TelemetryExporterBuilder.java | 4 ++ .../sender/jdk/internal/JdkHttpSender.java | 11 ++--- .../jdk/internal/JdkHttpSenderProvider.java | 2 + .../jdk/internal/JdkHttpSenderTest.java | 12 ++++- .../okhttp/internal/OkHttpHttpSender.java | 3 ++ .../internal/OkHttpHttpSenderProvider.java | 2 + .../internal/OkHttpHttpSuppressionTest.java | 2 +- 21 files changed, 236 insertions(+), 13 deletions(-) diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-otlp.txt b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-otlp.txt index df26146497b..b889d450445 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-otlp.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-otlp.txt @@ -1,2 +1,13 @@ Comparing source compatibility of against -No changes. \ No newline at end of file +*** MODIFIED CLASS: PUBLIC FINAL io.opentelemetry.exporter.otlp.http.logs.OtlpHttpLogRecordExporterBuilder (not serializable) + === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 + +++ NEW METHOD: PUBLIC(+) io.opentelemetry.exporter.otlp.http.logs.OtlpHttpLogRecordExporterBuilder setConnectTimeout(long, java.util.concurrent.TimeUnit) + +++ NEW METHOD: PUBLIC(+) io.opentelemetry.exporter.otlp.http.logs.OtlpHttpLogRecordExporterBuilder setConnectTimeout(java.time.Duration) +*** MODIFIED CLASS: PUBLIC FINAL io.opentelemetry.exporter.otlp.http.metrics.OtlpHttpMetricExporterBuilder (not serializable) + === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 + +++ NEW METHOD: PUBLIC(+) io.opentelemetry.exporter.otlp.http.metrics.OtlpHttpMetricExporterBuilder setConnectTimeout(long, java.util.concurrent.TimeUnit) + +++ NEW METHOD: PUBLIC(+) io.opentelemetry.exporter.otlp.http.metrics.OtlpHttpMetricExporterBuilder setConnectTimeout(java.time.Duration) +*** MODIFIED CLASS: PUBLIC FINAL io.opentelemetry.exporter.otlp.http.trace.OtlpHttpSpanExporterBuilder (not serializable) + === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 + +++ NEW METHOD: PUBLIC(+) io.opentelemetry.exporter.otlp.http.trace.OtlpHttpSpanExporterBuilder setConnectTimeout(long, java.util.concurrent.TimeUnit) + +++ NEW METHOD: PUBLIC(+) io.opentelemetry.exporter.otlp.http.trace.OtlpHttpSpanExporterBuilder setConnectTimeout(java.time.Duration) diff --git a/exporters/common/src/main/java/io/opentelemetry/exporter/internal/http/HttpExporterBuilder.java b/exporters/common/src/main/java/io/opentelemetry/exporter/internal/http/HttpExporterBuilder.java index fc4473b034c..d39601b48bc 100644 --- a/exporters/common/src/main/java/io/opentelemetry/exporter/internal/http/HttpExporterBuilder.java +++ b/exporters/common/src/main/java/io/opentelemetry/exporter/internal/http/HttpExporterBuilder.java @@ -14,7 +14,6 @@ import io.opentelemetry.exporter.internal.marshal.Marshaler; import io.opentelemetry.sdk.common.export.RetryPolicy; import java.net.URI; -import java.time.Duration; import java.util.Collections; import java.util.HashMap; import java.util.Map; @@ -37,6 +36,7 @@ @SuppressWarnings("checkstyle:JavadocMethod") public final class HttpExporterBuilder { public static final long DEFAULT_TIMEOUT_SECS = 10; + public static final long DEFAULT_CONNECT_TIMEOUT_SECS = 10; private static final Logger LOGGER = Logger.getLogger(HttpExporterBuilder.class.getName()); @@ -46,6 +46,7 @@ public final class HttpExporterBuilder { private String endpoint; private long timeoutNanos = TimeUnit.SECONDS.toNanos(DEFAULT_TIMEOUT_SECS); + private long connectTimeoutNanos = TimeUnit.SECONDS.toNanos(DEFAULT_CONNECT_TIMEOUT_SECS); private boolean compressionEnabled = false; private boolean exportAsJson = false; @Nullable private Map headers; @@ -67,8 +68,9 @@ public HttpExporterBuilder setTimeout(long timeout, TimeUnit unit) { return this; } - public HttpExporterBuilder setTimeout(Duration timeout) { - return setTimeout(timeout.toNanos(), TimeUnit.NANOSECONDS); + public HttpExporterBuilder setConnectTimeout(long timeout, TimeUnit unit) { + connectTimeoutNanos = unit.toNanos(timeout); + return this; } public HttpExporterBuilder setEndpoint(String endpoint) { @@ -132,6 +134,7 @@ public HttpExporterBuilder copy() { HttpExporterBuilder copy = new HttpExporterBuilder<>(exporterName, type, endpoint); copy.endpoint = endpoint; copy.timeoutNanos = timeoutNanos; + copy.connectTimeoutNanos = connectTimeoutNanos; copy.exportAsJson = exportAsJson; copy.compressionEnabled = compressionEnabled; if (headers != null) { @@ -157,6 +160,7 @@ public HttpExporter build() { compressionEnabled, exportAsJson ? "application/json" : "application/x-protobuf", timeoutNanos, + connectTimeoutNanos, headerSupplier, authenticator, retryPolicy, @@ -176,6 +180,7 @@ public String toString(boolean includePrefixAndSuffix) { joiner.add("type=" + type); joiner.add("endpoint=" + endpoint); joiner.add("timeoutNanos=" + timeoutNanos); + joiner.add("connectTimeoutNanos=" + connectTimeoutNanos); joiner.add("compressionEnabled=" + compressionEnabled); joiner.add("exportAsJson=" + exportAsJson); if (headers != null) { diff --git a/exporters/common/src/main/java/io/opentelemetry/exporter/internal/http/HttpSenderProvider.java b/exporters/common/src/main/java/io/opentelemetry/exporter/internal/http/HttpSenderProvider.java index 22050e8e624..fba8f4ebb5e 100644 --- a/exporters/common/src/main/java/io/opentelemetry/exporter/internal/http/HttpSenderProvider.java +++ b/exporters/common/src/main/java/io/opentelemetry/exporter/internal/http/HttpSenderProvider.java @@ -23,11 +23,13 @@ public interface HttpSenderProvider { /** Returns a {@link HttpSender} configured with the provided parameters. */ + @SuppressWarnings("TooManyParameters") HttpSender createSender( String endpoint, boolean compressionEnabled, String contentType, long timeoutNanos, + long connectTimeout, Supplier> headerSupplier, @Nullable Authenticator authenticator, @Nullable RetryPolicy retryPolicy, diff --git a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/logs/OtlpHttpLogRecordExporterBuilder.java b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/logs/OtlpHttpLogRecordExporterBuilder.java index 024d6b8b10e..9780567565a 100644 --- a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/logs/OtlpHttpLogRecordExporterBuilder.java +++ b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/logs/OtlpHttpLogRecordExporterBuilder.java @@ -60,6 +60,26 @@ public OtlpHttpLogRecordExporterBuilder setTimeout(Duration timeout) { return setTimeout(timeout.toNanos(), TimeUnit.NANOSECONDS); } + /** + * Sets the maximum time to wait for new connections to be established. If unset, defaults to + * {@value HttpExporterBuilder#DEFAULT_CONNECT_TIMEOUT_SECS}s. + */ + public OtlpHttpLogRecordExporterBuilder setConnectTimeout(long timeout, TimeUnit unit) { + requireNonNull(unit, "unit"); + checkArgument(timeout >= 0, "timeout must be non-negative"); + delegate.setConnectTimeout(timeout, unit); + return this; + } + + /** + * Sets the maximum time to wait for new connections to be established. If unset, defaults to + * {@value HttpExporterBuilder#DEFAULT_CONNECT_TIMEOUT_SECS}s. + */ + public OtlpHttpLogRecordExporterBuilder setConnectTimeout(Duration timeout) { + requireNonNull(timeout, "timeout"); + return setConnectTimeout(timeout.toNanos(), TimeUnit.NANOSECONDS); + } + /** * Sets the OTLP endpoint to connect to. If unset, defaults to {@value DEFAULT_ENDPOINT}. The * endpoint must start with either http:// or https://, and include the full HTTP path. diff --git a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/metrics/OtlpHttpMetricExporterBuilder.java b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/metrics/OtlpHttpMetricExporterBuilder.java index 57cca1c8f9b..01a29681c32 100644 --- a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/metrics/OtlpHttpMetricExporterBuilder.java +++ b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/metrics/OtlpHttpMetricExporterBuilder.java @@ -71,6 +71,26 @@ public OtlpHttpMetricExporterBuilder setTimeout(Duration timeout) { return setTimeout(timeout.toNanos(), TimeUnit.NANOSECONDS); } + /** + * Sets the maximum time to wait for new connections to be established. If unset, defaults to + * {@value HttpExporterBuilder#DEFAULT_CONNECT_TIMEOUT_SECS}s. + */ + public OtlpHttpMetricExporterBuilder setConnectTimeout(long timeout, TimeUnit unit) { + requireNonNull(unit, "unit"); + checkArgument(timeout >= 0, "timeout must be non-negative"); + delegate.setConnectTimeout(timeout, unit); + return this; + } + + /** + * Sets the maximum time to wait for new connections to be established. If unset, defaults to + * {@value HttpExporterBuilder#DEFAULT_CONNECT_TIMEOUT_SECS}s. + */ + public OtlpHttpMetricExporterBuilder setConnectTimeout(Duration timeout) { + requireNonNull(timeout, "timeout"); + return setConnectTimeout(timeout.toNanos(), TimeUnit.NANOSECONDS); + } + /** * Sets the OTLP endpoint to connect to. If unset, defaults to {@value DEFAULT_ENDPOINT}. The * endpoint must start with either http:// or https://, and include the full HTTP path. diff --git a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/trace/OtlpHttpSpanExporterBuilder.java b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/trace/OtlpHttpSpanExporterBuilder.java index 91645cafba5..eba2ee786a3 100644 --- a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/trace/OtlpHttpSpanExporterBuilder.java +++ b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/trace/OtlpHttpSpanExporterBuilder.java @@ -60,6 +60,26 @@ public OtlpHttpSpanExporterBuilder setTimeout(Duration timeout) { return setTimeout(timeout.toNanos(), TimeUnit.NANOSECONDS); } + /** + * Sets the maximum time to wait for new connections to be established. If unset, defaults to + * {@value HttpExporterBuilder#DEFAULT_CONNECT_TIMEOUT_SECS}s. + */ + public OtlpHttpSpanExporterBuilder setConnectTimeout(long timeout, TimeUnit unit) { + requireNonNull(unit, "unit"); + checkArgument(timeout >= 0, "timeout must be non-negative"); + delegate.setConnectTimeout(timeout, unit); + return this; + } + + /** + * Sets the maximum time to wait for new connections to be established. If unset, defaults to + * {@value HttpExporterBuilder#DEFAULT_CONNECT_TIMEOUT_SECS}s. + */ + public OtlpHttpSpanExporterBuilder setConnectTimeout(Duration timeout) { + requireNonNull(timeout, "timeout"); + return setConnectTimeout(timeout.toNanos(), TimeUnit.NANOSECONDS); + } + /** * Sets the OTLP endpoint to connect to. If unset, defaults to {@value DEFAULT_ENDPOINT}. The * endpoint must start with either http:// or https://, and include the full HTTP path. diff --git a/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/AbstractHttpTelemetryExporterTest.java b/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/AbstractHttpTelemetryExporterTest.java index be8e5e773fc..c306e4fbc2f 100644 --- a/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/AbstractHttpTelemetryExporterTest.java +++ b/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/AbstractHttpTelemetryExporterTest.java @@ -464,6 +464,28 @@ public Stream provideArguments(ExtensionContext context) th } } + @Test + @SuppressLogger(HttpExporter.class) + void connectTimeout() { + TelemetryExporter exporter = + exporterBuilder() + // Connecting to a non-routable IP address to trigger connection error + .setEndpoint("http://10.255.255.1") + .setConnectTimeout(Duration.ofMillis(1)) + .build(); + try { + long startTimeMillis = System.currentTimeMillis(); + CompletableResultCode result = + exporter.export(Collections.singletonList(generateFakeTelemetry())); + assertThat(result.join(10, TimeUnit.SECONDS).isSuccess()).isFalse(); + // Assert that the export request fails well before the default connect timeout of 10s + assertThat(System.currentTimeMillis() - startTimeMillis) + .isLessThan(TimeUnit.SECONDS.toMillis(1)); + } finally { + exporter.shutdown(); + } + } + @Test void deadlineSetPerExport() throws InterruptedException { TelemetryExporter exporter = @@ -602,6 +624,15 @@ void validConfig() { assertThatCode(() -> exporterBuilder().setTimeout(Duration.ofMillis(10))) .doesNotThrowAnyException(); + assertThatCode(() -> exporterBuilder().setConnectTimeout(0, TimeUnit.MILLISECONDS)) + .doesNotThrowAnyException(); + assertThatCode(() -> exporterBuilder().setConnectTimeout(Duration.ofMillis(0))) + .doesNotThrowAnyException(); + assertThatCode(() -> exporterBuilder().setConnectTimeout(10, TimeUnit.MILLISECONDS)) + .doesNotThrowAnyException(); + assertThatCode(() -> exporterBuilder().setConnectTimeout(Duration.ofMillis(10))) + .doesNotThrowAnyException(); + assertThatCode(() -> exporterBuilder().setEndpoint("http://localhost:4318")) .doesNotThrowAnyException(); assertThatCode(() -> exporterBuilder().setEndpoint("http://localhost/")) @@ -635,6 +666,16 @@ void invalidConfig() { .isInstanceOf(NullPointerException.class) .hasMessage("timeout"); + assertThatThrownBy(() -> exporterBuilder().setConnectTimeout(-1, TimeUnit.MILLISECONDS)) + .isInstanceOf(IllegalArgumentException.class) + .hasMessage("timeout must be non-negative"); + assertThatThrownBy(() -> exporterBuilder().setConnectTimeout(1, null)) + .isInstanceOf(NullPointerException.class) + .hasMessage("unit"); + assertThatThrownBy(() -> exporterBuilder().setConnectTimeout(null)) + .isInstanceOf(NullPointerException.class) + .hasMessage("timeout"); + assertThatThrownBy(() -> exporterBuilder().setEndpoint(null)) .isInstanceOf(NullPointerException.class) .hasMessage("endpoint"); @@ -666,6 +707,7 @@ void toBuilderEquality() TelemetryExporter exporter = exporterBuilder() .setTimeout(Duration.ofSeconds(5)) + .setConnectTimeout(Duration.ofSeconds(4)) .setEndpoint("http://localhost:4318") .setCompression("gzip") .addHeader("foo", "bar") @@ -728,6 +770,9 @@ void stringRepresentation() throws IOException, CertificateEncodingException { + "timeoutNanos=" + TimeUnit.SECONDS.toNanos(10) + ", " + + "connectTimeoutNanos=" + + TimeUnit.SECONDS.toNanos(10) + + ", " + "compressionEnabled=false, " + "exportAsJson=false, " + "headers=Headers\\{User-Agent=OBFUSCATED\\}" @@ -739,6 +784,7 @@ void stringRepresentation() throws IOException, CertificateEncodingException { telemetryExporter = exporterBuilder() .setTimeout(Duration.ofSeconds(5)) + .setConnectTimeout(Duration.ofSeconds(4)) .setEndpoint("http://example:4318/v1/logs") .setCompression("gzip") .addHeader("foo", "bar") @@ -764,6 +810,9 @@ void stringRepresentation() throws IOException, CertificateEncodingException { + "timeoutNanos=" + TimeUnit.SECONDS.toNanos(5) + ", " + + "connectTimeoutNanos=" + + TimeUnit.SECONDS.toNanos(4) + + ", " + "compressionEnabled=true, " + "exportAsJson=false, " + "headers=Headers\\{.*foo=OBFUSCATED.*\\}, " diff --git a/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/GrpcLogRecordExporterBuilderWrapper.java b/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/GrpcLogRecordExporterBuilderWrapper.java index 993b13312f3..916f15e6b2f 100644 --- a/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/GrpcLogRecordExporterBuilderWrapper.java +++ b/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/GrpcLogRecordExporterBuilderWrapper.java @@ -40,6 +40,16 @@ public TelemetryExporterBuilder setTimeout(Duration timeout) { return this; } + @Override + public TelemetryExporterBuilder setConnectTimeout(long timeout, TimeUnit unit) { + throw new UnsupportedOperationException(); + } + + @Override + public TelemetryExporterBuilder setConnectTimeout(Duration timeout) { + throw new UnsupportedOperationException(); + } + @Override public TelemetryExporterBuilder setCompression(String compression) { builder.setCompression(compression); diff --git a/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/GrpcMetricExporterBuilderWrapper.java b/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/GrpcMetricExporterBuilderWrapper.java index 0cfa4401ab1..821baaa729d 100644 --- a/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/GrpcMetricExporterBuilderWrapper.java +++ b/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/GrpcMetricExporterBuilderWrapper.java @@ -40,6 +40,16 @@ public TelemetryExporterBuilder setTimeout(Duration timeout) { return this; } + @Override + public TelemetryExporterBuilder setConnectTimeout(long timeout, TimeUnit unit) { + throw new UnsupportedOperationException(); + } + + @Override + public TelemetryExporterBuilder setConnectTimeout(Duration timeout) { + throw new UnsupportedOperationException(); + } + @Override public TelemetryExporterBuilder setCompression(String compression) { builder.setCompression(compression); diff --git a/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/GrpcSpanExporterBuilderWrapper.java b/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/GrpcSpanExporterBuilderWrapper.java index bc4a10aa8f1..2f86433672e 100644 --- a/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/GrpcSpanExporterBuilderWrapper.java +++ b/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/GrpcSpanExporterBuilderWrapper.java @@ -41,6 +41,16 @@ public TelemetryExporterBuilder setTimeout(Duration timeout) { return this; } + @Override + public TelemetryExporterBuilder setConnectTimeout(long timeout, TimeUnit unit) { + throw new UnsupportedOperationException(); + } + + @Override + public TelemetryExporterBuilder setConnectTimeout(Duration timeout) { + throw new UnsupportedOperationException(); + } + @Override public TelemetryExporterBuilder setCompression(String compression) { builder.setCompression(compression); diff --git a/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/HttpLogRecordExporterBuilderWrapper.java b/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/HttpLogRecordExporterBuilderWrapper.java index 7e007fa6e7b..5fc42608acd 100644 --- a/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/HttpLogRecordExporterBuilderWrapper.java +++ b/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/HttpLogRecordExporterBuilderWrapper.java @@ -41,6 +41,18 @@ public TelemetryExporterBuilder setTimeout(Duration timeout) { return this; } + @Override + public TelemetryExporterBuilder setConnectTimeout(long timeout, TimeUnit unit) { + builder.setConnectTimeout(timeout, unit); + return this; + } + + @Override + public TelemetryExporterBuilder setConnectTimeout(Duration timeout) { + builder.setConnectTimeout(timeout); + return this; + } + @Override public TelemetryExporterBuilder setCompression(String compression) { builder.setCompression(compression); diff --git a/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/HttpMetricExporterBuilderWrapper.java b/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/HttpMetricExporterBuilderWrapper.java index e3d9d1cc20e..e4357378a86 100644 --- a/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/HttpMetricExporterBuilderWrapper.java +++ b/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/HttpMetricExporterBuilderWrapper.java @@ -40,6 +40,18 @@ public TelemetryExporterBuilder setTimeout(Duration timeout) { return this; } + @Override + public TelemetryExporterBuilder setConnectTimeout(long timeout, TimeUnit unit) { + builder.setConnectTimeout(timeout, unit); + return this; + } + + @Override + public TelemetryExporterBuilder setConnectTimeout(Duration timeout) { + builder.setConnectTimeout(timeout); + return this; + } + @Override public TelemetryExporterBuilder setCompression(String compression) { builder.setCompression(compression); diff --git a/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/HttpSpanExporterBuilderWrapper.java b/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/HttpSpanExporterBuilderWrapper.java index 63660c4314b..550d25c26e1 100644 --- a/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/HttpSpanExporterBuilderWrapper.java +++ b/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/HttpSpanExporterBuilderWrapper.java @@ -40,6 +40,18 @@ public TelemetryExporterBuilder setTimeout(Duration timeout) { return this; } + @Override + public TelemetryExporterBuilder setConnectTimeout(long timeout, TimeUnit unit) { + builder.setConnectTimeout(timeout, unit); + return this; + } + + @Override + public TelemetryExporterBuilder setConnectTimeout(Duration timeout) { + builder.setConnectTimeout(timeout); + return this; + } + @Override public TelemetryExporterBuilder setCompression(String compression) { builder.setCompression(compression); diff --git a/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/ManagedChannelTelemetryExporterBuilder.java b/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/ManagedChannelTelemetryExporterBuilder.java index 79781eb5809..fbad7272a76 100644 --- a/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/ManagedChannelTelemetryExporterBuilder.java +++ b/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/ManagedChannelTelemetryExporterBuilder.java @@ -76,6 +76,18 @@ public TelemetryExporterBuilder setTimeout(Duration timeout) { return this; } + @Override + public TelemetryExporterBuilder setConnectTimeout(long timeout, TimeUnit unit) { + delegate.setConnectTimeout(timeout, unit); + return this; + } + + @Override + public TelemetryExporterBuilder setConnectTimeout(Duration timeout) { + delegate.setConnectTimeout(timeout); + return this; + } + @Override public TelemetryExporterBuilder setCompression(String compression) { delegate.setCompression(compression); diff --git a/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/TelemetryExporterBuilder.java b/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/TelemetryExporterBuilder.java index 95b62e88a28..6fbe78149e5 100644 --- a/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/TelemetryExporterBuilder.java +++ b/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/TelemetryExporterBuilder.java @@ -38,6 +38,10 @@ static TelemetryExporterBuilder wrap(OtlpGrpcLogRecordExporterBui TelemetryExporterBuilder setTimeout(Duration timeout); + TelemetryExporterBuilder setConnectTimeout(long timeout, TimeUnit unit); + + TelemetryExporterBuilder setConnectTimeout(Duration timeout); + TelemetryExporterBuilder setCompression(String compression); TelemetryExporterBuilder addHeader(String key, String value); diff --git a/exporters/sender/jdk/src/main/java/io/opentelemetry/exporter/sender/jdk/internal/JdkHttpSender.java b/exporters/sender/jdk/src/main/java/io/opentelemetry/exporter/sender/jdk/internal/JdkHttpSender.java index 25866a162fc..93098b8312b 100644 --- a/exporters/sender/jdk/src/main/java/io/opentelemetry/exporter/sender/jdk/internal/JdkHttpSender.java +++ b/exporters/sender/jdk/src/main/java/io/opentelemetry/exporter/sender/jdk/internal/JdkHttpSender.java @@ -84,11 +84,12 @@ public final class JdkHttpSender implements HttpSender { boolean compressionEnabled, String contentType, long timeoutNanos, + long connectTimeoutNanos, Supplier> headerSupplier, @Nullable RetryPolicy retryPolicy, @Nullable SSLContext sslContext) { this( - configureClient(sslContext), + configureClient(sslContext, connectTimeoutNanos), endpoint, compressionEnabled, contentType, @@ -97,12 +98,10 @@ public final class JdkHttpSender implements HttpSender { retryPolicy); } - private static HttpClient configureClient(@Nullable SSLContext sslContext) { + private static HttpClient configureClient( + @Nullable SSLContext sslContext, long connectionTimeoutNanos) { HttpClient.Builder builder = - HttpClient.newBuilder() - // Aligned with OkHttpClient default connect timeout - // TODO (jack-berg): Consider making connect timeout configurable - .connectTimeout(Duration.ofSeconds(10)); + HttpClient.newBuilder().connectTimeout(Duration.ofNanos(connectionTimeoutNanos)); if (sslContext != null) { builder.sslContext(sslContext); } diff --git a/exporters/sender/jdk/src/main/java/io/opentelemetry/exporter/sender/jdk/internal/JdkHttpSenderProvider.java b/exporters/sender/jdk/src/main/java/io/opentelemetry/exporter/sender/jdk/internal/JdkHttpSenderProvider.java index dbe93eef3a3..5e3496b1496 100644 --- a/exporters/sender/jdk/src/main/java/io/opentelemetry/exporter/sender/jdk/internal/JdkHttpSenderProvider.java +++ b/exporters/sender/jdk/src/main/java/io/opentelemetry/exporter/sender/jdk/internal/JdkHttpSenderProvider.java @@ -29,6 +29,7 @@ public HttpSender createSender( boolean compressionEnabled, String contentType, long timeoutNanos, + long connectTimeout, Supplier> headerSupplier, @Nullable Authenticator authenticator, @Nullable RetryPolicy retryPolicy, @@ -39,6 +40,7 @@ public HttpSender createSender( compressionEnabled, contentType, timeoutNanos, + connectTimeout, headerSupplier, retryPolicy, sslContext); diff --git a/exporters/sender/jdk/src/test/java/io/opentelemetry/exporter/sender/jdk/internal/JdkHttpSenderTest.java b/exporters/sender/jdk/src/test/java/io/opentelemetry/exporter/sender/jdk/internal/JdkHttpSenderTest.java index 19cb3f997ac..0bf99ab9525 100644 --- a/exporters/sender/jdk/src/test/java/io/opentelemetry/exporter/sender/jdk/internal/JdkHttpSenderTest.java +++ b/exporters/sender/jdk/src/test/java/io/opentelemetry/exporter/sender/jdk/internal/JdkHttpSenderTest.java @@ -20,6 +20,7 @@ import java.net.http.HttpConnectTimeoutException; import java.time.Duration; import java.util.Collections; +import java.util.concurrent.TimeUnit; import javax.net.ssl.SSLException; import org.assertj.core.api.InstanceOfAssertFactories; import org.junit.jupiter.api.BeforeEach; @@ -93,10 +94,17 @@ void sendInternal_NonRetryableException() throws IOException, InterruptedExcepti } @Test - void defaultConnectTimeout() { + void connectTimeout() { sender = new JdkHttpSender( - "http://localhost", true, "text/plain", 1, Collections::emptyMap, null, null); + "http://localhost", + true, + "text/plain", + 1, + TimeUnit.SECONDS.toNanos(10), + Collections::emptyMap, + null, + null); assertThat(sender) .extracting("client", as(InstanceOfAssertFactories.type(HttpClient.class))) diff --git a/exporters/sender/okhttp/src/main/java/io/opentelemetry/exporter/sender/okhttp/internal/OkHttpHttpSender.java b/exporters/sender/okhttp/src/main/java/io/opentelemetry/exporter/sender/okhttp/internal/OkHttpHttpSender.java index 2355a94ba60..18356f23962 100644 --- a/exporters/sender/okhttp/src/main/java/io/opentelemetry/exporter/sender/okhttp/internal/OkHttpHttpSender.java +++ b/exporters/sender/okhttp/src/main/java/io/opentelemetry/exporter/sender/okhttp/internal/OkHttpHttpSender.java @@ -47,11 +47,13 @@ public final class OkHttpHttpSender implements HttpSender { private final MediaType mediaType; /** Create a sender. */ + @SuppressWarnings("TooManyParameters") public OkHttpHttpSender( String endpoint, boolean compressionEnabled, String contentType, long timeoutNanos, + long connectionTimeoutNanos, Supplier> headerSupplier, @Nullable Authenticator authenticator, @Nullable RetryPolicy retryPolicy, @@ -60,6 +62,7 @@ public OkHttpHttpSender( OkHttpClient.Builder builder = new OkHttpClient.Builder() .dispatcher(OkHttpUtil.newDispatcher()) + .connectTimeout(Duration.ofNanos(connectionTimeoutNanos)) .callTimeout(Duration.ofNanos(timeoutNanos)); if (authenticator != null) { diff --git a/exporters/sender/okhttp/src/main/java/io/opentelemetry/exporter/sender/okhttp/internal/OkHttpHttpSenderProvider.java b/exporters/sender/okhttp/src/main/java/io/opentelemetry/exporter/sender/okhttp/internal/OkHttpHttpSenderProvider.java index edf5e9cf45e..16a767f5c62 100644 --- a/exporters/sender/okhttp/src/main/java/io/opentelemetry/exporter/sender/okhttp/internal/OkHttpHttpSenderProvider.java +++ b/exporters/sender/okhttp/src/main/java/io/opentelemetry/exporter/sender/okhttp/internal/OkHttpHttpSenderProvider.java @@ -29,6 +29,7 @@ public HttpSender createSender( boolean compressionEnabled, String contentType, long timeoutNanos, + long connectTimeout, Supplier> headerSupplier, @Nullable Authenticator authenticator, @Nullable RetryPolicy retryPolicy, @@ -39,6 +40,7 @@ public HttpSender createSender( compressionEnabled, contentType, timeoutNanos, + connectTimeout, headerSupplier, authenticator, retryPolicy, diff --git a/exporters/sender/okhttp/src/test/java/io/opentelemetry/exporter/sender/okhttp/internal/OkHttpHttpSuppressionTest.java b/exporters/sender/okhttp/src/test/java/io/opentelemetry/exporter/sender/okhttp/internal/OkHttpHttpSuppressionTest.java index 22c2c4a0dd0..87da2a18e84 100644 --- a/exporters/sender/okhttp/src/test/java/io/opentelemetry/exporter/sender/okhttp/internal/OkHttpHttpSuppressionTest.java +++ b/exporters/sender/okhttp/src/test/java/io/opentelemetry/exporter/sender/okhttp/internal/OkHttpHttpSuppressionTest.java @@ -34,6 +34,6 @@ void send(OkHttpHttpSender sender, Runnable onSuccess, Runnable onFailure) { @Override OkHttpHttpSender createSender(String endpoint) { return new OkHttpHttpSender( - endpoint, false, "text/plain", 10L, Collections::emptyMap, null, null, null, null); + endpoint, false, "text/plain", 10L, 10L, Collections::emptyMap, null, null, null, null); } } From f1fc1c75b837c9b799e1826c58ef1c82b6c3d24c Mon Sep 17 00:00:00 2001 From: jack-berg <34418638+jack-berg@users.noreply.github.com> Date: Thu, 7 Dec 2023 17:22:21 -0600 Subject: [PATCH 142/901] Revert com.gradle.enterprise 3.16 upgrade (#6059) --- settings.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/settings.gradle.kts b/settings.gradle.kts index 4fe708002e2..8e4fc690d1b 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -1,7 +1,7 @@ pluginManagement { plugins { id("com.github.johnrengelman.shadow") version "8.1.1" - id("com.gradle.enterprise") version "3.16" + id("com.gradle.enterprise") version "3.15.1" id("de.undercouch.download") version "5.5.0" id("org.jsonschema2pojo") version "1.2.1" id("io.github.gradle-nexus.publish-plugin") version "1.3.0" From 3bb221fb5d73f28018d4f119bcaaa939fc675678 Mon Sep 17 00:00:00 2001 From: Chung Nguyen Date: Fri, 8 Dec 2023 15:24:09 +0100 Subject: [PATCH 143/901] add hasAttributesSatisfying overload to AbstractPointAssert (#6048) --- .../opentelemetry-sdk-testing.txt | 5 +- .../testing/assertj/AbstractPointAssert.java | 8 ++++ .../testing/assertj/MetricAssertionsTest.java | 48 ++++++++++++++++--- 3 files changed, 54 insertions(+), 7 deletions(-) diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-testing.txt b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-testing.txt index df26146497b..c1e98158b3d 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-testing.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-testing.txt @@ -1,2 +1,5 @@ Comparing source compatibility of against -No changes. \ No newline at end of file +*** MODIFIED CLASS: PUBLIC ABSTRACT io.opentelemetry.sdk.testing.assertj.AbstractPointAssert (not serializable) + === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 + GENERIC TEMPLATES: === PointAssertT:io.opentelemetry.sdk.testing.assertj.AbstractPointAssert, === PointT:io.opentelemetry.sdk.metrics.data.PointData + +++ NEW METHOD: PUBLIC(+) FINAL(+) io.opentelemetry.sdk.testing.assertj.AbstractPointAssert hasAttributesSatisfying(java.util.function.Consumer) diff --git a/sdk/testing/src/main/java/io/opentelemetry/sdk/testing/assertj/AbstractPointAssert.java b/sdk/testing/src/main/java/io/opentelemetry/sdk/testing/assertj/AbstractPointAssert.java index cf7454c0405..0a3425958e0 100644 --- a/sdk/testing/src/main/java/io/opentelemetry/sdk/testing/assertj/AbstractPointAssert.java +++ b/sdk/testing/src/main/java/io/opentelemetry/sdk/testing/assertj/AbstractPointAssert.java @@ -14,6 +14,7 @@ import java.util.Arrays; import java.util.Map; import java.util.Set; +import java.util.function.Consumer; import javax.annotation.Nullable; import org.assertj.core.api.AbstractAssert; import org.assertj.core.api.Assertions; @@ -111,6 +112,13 @@ public final PointAssertT hasAttributesSatisfying(Iterable a return myself; } + /** Asserts the point has attributes satisfying the given condition. */ + public final PointAssertT hasAttributesSatisfying(Consumer attributes) { + isNotNull(); + assertThat(actual.getAttributes()).as("attributes").satisfies(attributes); + return myself; + } + /** * Asserts the point has attributes matching all {@code assertions} and no more. Assertions can be * created using methods like {@link OpenTelemetryAssertions#satisfies(AttributeKey, diff --git a/sdk/testing/src/test/java/io/opentelemetry/sdk/testing/assertj/MetricAssertionsTest.java b/sdk/testing/src/test/java/io/opentelemetry/sdk/testing/assertj/MetricAssertionsTest.java index 7d9fba741ea..299e4ab36fa 100644 --- a/sdk/testing/src/test/java/io/opentelemetry/sdk/testing/assertj/MetricAssertionsTest.java +++ b/sdk/testing/src/test/java/io/opentelemetry/sdk/testing/assertj/MetricAssertionsTest.java @@ -5,6 +5,7 @@ package io.opentelemetry.sdk.testing.assertj; +import static io.opentelemetry.api.common.AttributeKey.stringKey; import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.assertThat; import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.attributeEntry; import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.equalTo; @@ -60,9 +61,9 @@ class MetricAssertionsTest { private static final InstrumentationScopeInfo INSTRUMENTATION_SCOPE_INFO = InstrumentationScopeInfo.builder("opentelemetry").setVersion("1.0").build(); - private static final AttributeKey DOG = AttributeKey.stringKey("dog"); - private static final AttributeKey BEAR = AttributeKey.stringKey("bear"); - private static final AttributeKey CAT = AttributeKey.stringKey("cat"); + private static final AttributeKey DOG = stringKey("dog"); + private static final AttributeKey BEAR = stringKey("bear"); + private static final AttributeKey CAT = stringKey("cat"); private static final AttributeKey WARM = AttributeKey.booleanKey("warm"); private static final AttributeKey TEMPERATURE = AttributeKey.longKey("temperature"); private static final AttributeKey LENGTH = AttributeKey.doubleKey("length"); @@ -317,7 +318,7 @@ void doubleGauge() { attributes -> assertThat(attributes) .hasSize(2) - .containsEntry(AttributeKey.stringKey("dog"), "bark") + .containsEntry(stringKey("dog"), "bark") .hasEntrySatisfying(DOG, value -> assertThat(value).hasSize(4)) .hasEntrySatisfying( AttributeKey.booleanKey("dog is cute"), @@ -454,7 +455,19 @@ void doubleGauge() { equalTo(CONDITIONS, Arrays.asList(false, true)), equalTo(SCORES, Arrays.asList(0L, 1L)), equalTo(COINS, Arrays.asList(0.01, 0.05, 0.1)), - satisfies(LENGTH, val -> val.isCloseTo(1, offset(0.3)))))); + satisfies(LENGTH, val -> val.isCloseTo(1, offset(0.3)))) + .hasAttributesSatisfying( + attributes -> + assertThat(attributes) + .hasSize(8) + .containsEntry(stringKey("bear"), "mya") + .containsEntry("warm", true) + .containsEntry("temperature", 30L) + .containsEntry("colors", "red", "blue") + .containsEntry("conditions", false, true) + .containsEntry("scores", 0L, 1L) + .containsEntry("coins", 0.01, 0.05, 0.1) + .containsEntry("length", 1.2)))); } @Test @@ -500,7 +513,7 @@ void doubleGaugeFailure() { resource.hasAttributesSatisfying( attributes -> assertThat(attributes) - .containsEntry(AttributeKey.stringKey("dog"), "meow")))) + .containsEntry(stringKey("dog"), "meow")))) .isInstanceOf(AssertionError.class); assertThatThrownBy( () -> @@ -774,6 +787,29 @@ void doubleGaugeFailure() { satisfies( COINS, val -> val.containsExactly(0.01, 0.05, 0.1)))))) .isInstanceOf(AssertionError.class); + assertThatThrownBy( + () -> + assertThat(DOUBLE_GAUGE_METRIC) + .hasDoubleGaugeSatisfying( + gauge -> + gauge.hasPointsSatisfying( + point -> point.hasAttributes(Attributes.empty()), + point -> + point.hasAttributesSatisfying( + attributes -> + assertThat(attributes) + .hasSize(8) + .containsEntry( + stringKey("bear"), + "WRONG BEAR NAME") // Failed here + .containsEntry("warm", true) + .containsEntry("temperature", 30L) + .containsEntry("colors", "red", "blue") + .containsEntry("conditions", false, true) + .containsEntry("scores", 0L, 1L) + .containsEntry("coins", 0.01, 0.05, 0.1) + .containsEntry("length", 1.2))))) + .isInstanceOf(AssertionError.class); } // The above tests verify shared behavior in AbstractPointDataAssert and MetricDataAssert so we From 9f3456fd5d81df4efb293066ea5ef74ccb4cca1f Mon Sep 17 00:00:00 2001 From: Peter Findeisen Date: Fri, 8 Dec 2023 06:24:36 -0800 Subject: [PATCH 144/901] Issue 6037 - Wrapping "invalid" SpanContexts in Span does not preserve SpanContext (#6044) --- api/all/src/main/java/io/opentelemetry/api/trace/Span.java | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/api/all/src/main/java/io/opentelemetry/api/trace/Span.java b/api/all/src/main/java/io/opentelemetry/api/trace/Span.java index 898e05a4e9d..a54e7666c9c 100644 --- a/api/all/src/main/java/io/opentelemetry/api/trace/Span.java +++ b/api/all/src/main/java/io/opentelemetry/api/trace/Span.java @@ -74,16 +74,13 @@ static Span getInvalid() { /** * Returns a non-recording {@link Span} that holds the provided {@link SpanContext} but has no * functionality. It will not be exported and all tracing operations are no-op, but it can be used - * to propagate a valid {@link SpanContext} downstream. + * to propagate a {@link SpanContext} downstream. */ static Span wrap(SpanContext spanContext) { if (spanContext == null) { ApiUsageLogger.log("context is null"); return getInvalid(); } - if (!spanContext.isValid()) { - return getInvalid(); - } return PropagatedSpan.create(spanContext); } From 4c6039769a4756575a9d5fb6de16bfbd9ff5906f Mon Sep 17 00:00:00 2001 From: jack-berg <34418638+jack-berg@users.noreply.github.com> Date: Fri, 8 Dec 2023 08:37:14 -0600 Subject: [PATCH 145/901] Add OTLP header supplier configuration option (#6004) --- .../opentelemetry-exporter-otlp.txt | 12 +++++ .../internal/grpc/GrpcExporterBuilder.java | 47 ++++++++++++++--- .../internal/grpc/GrpcSenderProvider.java | 3 +- .../internal/http/HttpExporterBuilder.java | 50 ++++++++++++++----- .../internal/http/HttpSenderProvider.java | 3 +- .../otlp/trace/OltpExporterBenchmark.java | 6 ++- .../OtlpHttpLogRecordExporterBuilder.java | 19 +++++-- .../OtlpHttpMetricExporterBuilder.java | 20 ++++++-- .../trace/OtlpHttpSpanExporterBuilder.java | 19 +++++-- .../OtlpGrpcLogRecordExporterBuilder.java | 21 ++++++-- .../OtlpGrpcMetricExporterBuilder.java | 22 ++++++-- .../trace/OtlpGrpcSpanExporterBuilder.java | 21 ++++++-- .../AbstractGrpcTelemetryExporterTest.java | 19 +++++-- .../AbstractHttpTelemetryExporterTest.java | 22 ++++++-- .../GrpcLogRecordExporterBuilderWrapper.java | 9 ++++ .../GrpcMetricExporterBuilderWrapper.java | 9 ++++ .../GrpcSpanExporterBuilderWrapper.java | 9 ++++ .../HttpLogRecordExporterBuilderWrapper.java | 9 ++++ .../HttpMetricExporterBuilderWrapper.java | 9 ++++ .../HttpSpanExporterBuilderWrapper.java | 9 ++++ ...anagedChannelTelemetryExporterBuilder.java | 8 +++ .../internal/TelemetryExporterBuilder.java | 4 ++ .../internal/UpstreamGrpcSender.java | 23 ++++++++- .../internal/UpstreamGrpcSenderProvider.java | 28 ++++------- .../sender/jdk/internal/JdkHttpSender.java | 12 +++-- .../jdk/internal/JdkHttpSenderProvider.java | 3 +- .../okhttp/internal/OkHttpGrpcSender.java | 27 +++++----- .../internal/OkHttpGrpcSenderProvider.java | 5 +- .../okhttp/internal/OkHttpHttpSender.java | 12 +++-- .../internal/OkHttpHttpSenderProvider.java | 3 +- .../internal/OkHttpGrpcSuppressionTest.java | 2 +- 31 files changed, 372 insertions(+), 93 deletions(-) diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-otlp.txt b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-otlp.txt index b889d450445..7c0ed9b5e5f 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-otlp.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-otlp.txt @@ -3,11 +3,23 @@ Comparing source compatibility of against === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 +++ NEW METHOD: PUBLIC(+) io.opentelemetry.exporter.otlp.http.logs.OtlpHttpLogRecordExporterBuilder setConnectTimeout(long, java.util.concurrent.TimeUnit) +++ NEW METHOD: PUBLIC(+) io.opentelemetry.exporter.otlp.http.logs.OtlpHttpLogRecordExporterBuilder setConnectTimeout(java.time.Duration) + +++ NEW METHOD: PUBLIC(+) io.opentelemetry.exporter.otlp.http.logs.OtlpHttpLogRecordExporterBuilder setHeaders(java.util.function.Supplier>) *** MODIFIED CLASS: PUBLIC FINAL io.opentelemetry.exporter.otlp.http.metrics.OtlpHttpMetricExporterBuilder (not serializable) === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 +++ NEW METHOD: PUBLIC(+) io.opentelemetry.exporter.otlp.http.metrics.OtlpHttpMetricExporterBuilder setConnectTimeout(long, java.util.concurrent.TimeUnit) +++ NEW METHOD: PUBLIC(+) io.opentelemetry.exporter.otlp.http.metrics.OtlpHttpMetricExporterBuilder setConnectTimeout(java.time.Duration) + +++ NEW METHOD: PUBLIC(+) io.opentelemetry.exporter.otlp.http.metrics.OtlpHttpMetricExporterBuilder setHeaders(java.util.function.Supplier>) *** MODIFIED CLASS: PUBLIC FINAL io.opentelemetry.exporter.otlp.http.trace.OtlpHttpSpanExporterBuilder (not serializable) === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 +++ NEW METHOD: PUBLIC(+) io.opentelemetry.exporter.otlp.http.trace.OtlpHttpSpanExporterBuilder setConnectTimeout(long, java.util.concurrent.TimeUnit) +++ NEW METHOD: PUBLIC(+) io.opentelemetry.exporter.otlp.http.trace.OtlpHttpSpanExporterBuilder setConnectTimeout(java.time.Duration) + +++ NEW METHOD: PUBLIC(+) io.opentelemetry.exporter.otlp.http.trace.OtlpHttpSpanExporterBuilder setHeaders(java.util.function.Supplier>) +*** MODIFIED CLASS: PUBLIC FINAL io.opentelemetry.exporter.otlp.logs.OtlpGrpcLogRecordExporterBuilder (not serializable) + === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 + +++ NEW METHOD: PUBLIC(+) io.opentelemetry.exporter.otlp.logs.OtlpGrpcLogRecordExporterBuilder setHeaders(java.util.function.Supplier>) +*** MODIFIED CLASS: PUBLIC FINAL io.opentelemetry.exporter.otlp.metrics.OtlpGrpcMetricExporterBuilder (not serializable) + === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 + +++ NEW METHOD: PUBLIC(+) io.opentelemetry.exporter.otlp.metrics.OtlpGrpcMetricExporterBuilder setHeaders(java.util.function.Supplier>) +*** MODIFIED CLASS: PUBLIC FINAL io.opentelemetry.exporter.otlp.trace.OtlpGrpcSpanExporterBuilder (not serializable) + === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 + +++ NEW METHOD: PUBLIC(+) io.opentelemetry.exporter.otlp.trace.OtlpGrpcSpanExporterBuilder setHeaders(java.util.function.Supplier>) diff --git a/exporters/common/src/main/java/io/opentelemetry/exporter/internal/grpc/GrpcExporterBuilder.java b/exporters/common/src/main/java/io/opentelemetry/exporter/internal/grpc/GrpcExporterBuilder.java index 6260db41c73..bef1db06224 100644 --- a/exporters/common/src/main/java/io/opentelemetry/exporter/internal/grpc/GrpcExporterBuilder.java +++ b/exporters/common/src/main/java/io/opentelemetry/exporter/internal/grpc/GrpcExporterBuilder.java @@ -16,7 +16,10 @@ import io.opentelemetry.sdk.common.export.RetryPolicy; import java.net.URI; import java.time.Duration; +import java.util.ArrayList; +import java.util.Collections; import java.util.HashMap; +import java.util.List; import java.util.Map; import java.util.ServiceLoader; import java.util.StringJoiner; @@ -49,7 +52,8 @@ public class GrpcExporterBuilder { private long timeoutNanos; private URI endpoint; private boolean compressionEnabled = false; - private final Map headers = new HashMap<>(); + private final Map constantHeaders = new HashMap<>(); + private Supplier> headerSupplier = Collections::emptyMap; private TlsConfigHelper tlsConfigHelper = new TlsConfigHelper(); @Nullable private RetryPolicy retryPolicy; private Supplier meterProviderSupplier = GlobalOpenTelemetry::getMeterProvider; @@ -113,8 +117,13 @@ public GrpcExporterBuilder setSslContext( return this; } - public GrpcExporterBuilder addHeader(String key, String value) { - headers.put(key, value); + public GrpcExporterBuilder addConstantHeader(String key, String value) { + constantHeaders.put(key, value); + return this; + } + + public GrpcExporterBuilder setHeadersSupplier(Supplier> headerSupplier) { + this.headerSupplier = headerSupplier; return this; } @@ -142,7 +151,8 @@ public GrpcExporterBuilder copy() { copy.timeoutNanos = timeoutNanos; copy.endpoint = endpoint; copy.compressionEnabled = compressionEnabled; - copy.headers.putAll(headers); + copy.constantHeaders.putAll(constantHeaders); + copy.headerSupplier = headerSupplier; copy.tlsConfigHelper = tlsConfigHelper.copy(); if (retryPolicy != null) { copy.retryPolicy = retryPolicy.toBuilder().build(); @@ -153,6 +163,27 @@ public GrpcExporterBuilder copy() { } public GrpcExporter build() { + Supplier>> headerSupplier = + () -> { + Map> result = new HashMap<>(); + Map supplierResult = this.headerSupplier.get(); + if (supplierResult != null) { + supplierResult.forEach( + (key, value) -> result.put(key, Collections.singletonList(value))); + } + constantHeaders.forEach( + (key, value) -> + result.merge( + key, + Collections.singletonList(value), + (v1, v2) -> { + List merged = new ArrayList<>(v1); + merged.addAll(v2); + return merged; + })); + return result; + }; + GrpcSenderProvider grpcSenderProvider = resolveGrpcSenderProvider(); GrpcSender grpcSender = grpcSenderProvider.createSender( @@ -160,7 +191,7 @@ public GrpcExporter build() { grpcEndpointPath, compressionEnabled, timeoutNanos, - headers, + headerSupplier, grpcChannel, grpcStubFactory, retryPolicy, @@ -183,7 +214,11 @@ public String toString(boolean includePrefixAndSuffix) { joiner.add("timeoutNanos=" + timeoutNanos); joiner.add("compressionEnabled=" + compressionEnabled); StringJoiner headersJoiner = new StringJoiner(", ", "Headers{", "}"); - headers.forEach((key, value) -> headersJoiner.add(key + "=OBFUSCATED")); + constantHeaders.forEach((key, value) -> headersJoiner.add(key + "=OBFUSCATED")); + Map headers = headerSupplier.get(); + if (headers != null) { + headers.forEach((key, value) -> headersJoiner.add(key + "=OBFUSCATED")); + } joiner.add("headers=" + headersJoiner); if (retryPolicy != null) { joiner.add("retryPolicy=" + retryPolicy); diff --git a/exporters/common/src/main/java/io/opentelemetry/exporter/internal/grpc/GrpcSenderProvider.java b/exporters/common/src/main/java/io/opentelemetry/exporter/internal/grpc/GrpcSenderProvider.java index f3cacdf5409..c8c584f6e58 100644 --- a/exporters/common/src/main/java/io/opentelemetry/exporter/internal/grpc/GrpcSenderProvider.java +++ b/exporters/common/src/main/java/io/opentelemetry/exporter/internal/grpc/GrpcSenderProvider.java @@ -9,6 +9,7 @@ import io.opentelemetry.exporter.internal.marshal.Marshaler; import io.opentelemetry.sdk.common.export.RetryPolicy; import java.net.URI; +import java.util.List; import java.util.Map; import java.util.function.BiFunction; import java.util.function.Supplier; @@ -32,7 +33,7 @@ GrpcSender createSender( String endpointPath, boolean compressionEnabled, long timeoutNanos, - Map headers, + Supplier>> headersSupplier, @Nullable Object managedChannel, Supplier>> stubFactory, @Nullable RetryPolicy retryPolicy, diff --git a/exporters/common/src/main/java/io/opentelemetry/exporter/internal/http/HttpExporterBuilder.java b/exporters/common/src/main/java/io/opentelemetry/exporter/internal/http/HttpExporterBuilder.java index d39601b48bc..ad46956a702 100644 --- a/exporters/common/src/main/java/io/opentelemetry/exporter/internal/http/HttpExporterBuilder.java +++ b/exporters/common/src/main/java/io/opentelemetry/exporter/internal/http/HttpExporterBuilder.java @@ -14,8 +14,10 @@ import io.opentelemetry.exporter.internal.marshal.Marshaler; import io.opentelemetry.sdk.common.export.RetryPolicy; import java.net.URI; +import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; +import java.util.List; import java.util.Map; import java.util.ServiceLoader; import java.util.StringJoiner; @@ -49,7 +51,8 @@ public final class HttpExporterBuilder { private long connectTimeoutNanos = TimeUnit.SECONDS.toNanos(DEFAULT_CONNECT_TIMEOUT_SECS); private boolean compressionEnabled = false; private boolean exportAsJson = false; - @Nullable private Map headers; + private final Map constantHeaders = new HashMap<>(); + private Supplier> headerSupplier = Collections::emptyMap; private TlsConfigHelper tlsConfigHelper = new TlsConfigHelper(); @Nullable private RetryPolicy retryPolicy; @@ -84,11 +87,13 @@ public HttpExporterBuilder setCompression(String compressionMethod) { return this; } - public HttpExporterBuilder addHeader(String key, String value) { - if (headers == null) { - headers = new HashMap<>(); - } - headers.put(key, value); + public HttpExporterBuilder addConstantHeaders(String key, String value) { + constantHeaders.put(key, value); + return this; + } + + public HttpExporterBuilder setHeadersSupplier(Supplier> headerSupplier) { + this.headerSupplier = headerSupplier; return this; } @@ -137,9 +142,8 @@ public HttpExporterBuilder copy() { copy.connectTimeoutNanos = connectTimeoutNanos; copy.exportAsJson = exportAsJson; copy.compressionEnabled = compressionEnabled; - if (headers != null) { - copy.headers = new HashMap<>(headers); - } + copy.constantHeaders.putAll(constantHeaders); + copy.headerSupplier = headerSupplier; copy.tlsConfigHelper = tlsConfigHelper.copy(); if (retryPolicy != null) { copy.retryPolicy = retryPolicy.toBuilder().build(); @@ -150,8 +154,26 @@ public HttpExporterBuilder copy() { } public HttpExporter build() { - Map headers = this.headers == null ? Collections.emptyMap() : this.headers; - Supplier> headerSupplier = () -> headers; + Supplier>> headerSupplier = + () -> { + Map> result = new HashMap<>(); + Map supplierResult = this.headerSupplier.get(); + if (supplierResult != null) { + supplierResult.forEach( + (key, value) -> result.put(key, Collections.singletonList(value))); + } + constantHeaders.forEach( + (key, value) -> + result.merge( + key, + Collections.singletonList(value), + (v1, v2) -> { + List merged = new ArrayList<>(v1); + merged.addAll(v2); + return merged; + })); + return result; + }; HttpSenderProvider httpSenderProvider = resolveHttpSenderProvider(); HttpSender httpSender = @@ -183,11 +205,13 @@ public String toString(boolean includePrefixAndSuffix) { joiner.add("connectTimeoutNanos=" + connectTimeoutNanos); joiner.add("compressionEnabled=" + compressionEnabled); joiner.add("exportAsJson=" + exportAsJson); + StringJoiner headersJoiner = new StringJoiner(", ", "Headers{", "}"); + constantHeaders.forEach((key, value) -> headersJoiner.add(key + "=OBFUSCATED")); + Map headers = headerSupplier.get(); if (headers != null) { - StringJoiner headersJoiner = new StringJoiner(", ", "Headers{", "}"); headers.forEach((key, value) -> headersJoiner.add(key + "=OBFUSCATED")); - joiner.add("headers=" + headersJoiner); } + joiner.add("headers=" + headersJoiner); if (retryPolicy != null) { joiner.add("retryPolicy=" + retryPolicy); } diff --git a/exporters/common/src/main/java/io/opentelemetry/exporter/internal/http/HttpSenderProvider.java b/exporters/common/src/main/java/io/opentelemetry/exporter/internal/http/HttpSenderProvider.java index fba8f4ebb5e..6ab06f31d98 100644 --- a/exporters/common/src/main/java/io/opentelemetry/exporter/internal/http/HttpSenderProvider.java +++ b/exporters/common/src/main/java/io/opentelemetry/exporter/internal/http/HttpSenderProvider.java @@ -7,6 +7,7 @@ import io.opentelemetry.exporter.internal.auth.Authenticator; import io.opentelemetry.sdk.common.export.RetryPolicy; +import java.util.List; import java.util.Map; import java.util.function.Supplier; import javax.annotation.Nullable; @@ -30,7 +31,7 @@ HttpSender createSender( String contentType, long timeoutNanos, long connectTimeout, - Supplier> headerSupplier, + Supplier>> headerSupplier, @Nullable Authenticator authenticator, @Nullable RetryPolicy retryPolicy, @Nullable SSLContext sslContext, diff --git a/exporters/otlp/all/src/jmh/java/io/opentelemetry/exporter/otlp/trace/OltpExporterBenchmark.java b/exporters/otlp/all/src/jmh/java/io/opentelemetry/exporter/otlp/trace/OltpExporterBenchmark.java index 942f66573d3..1ad124271a3 100644 --- a/exporters/otlp/all/src/jmh/java/io/opentelemetry/exporter/otlp/trace/OltpExporterBenchmark.java +++ b/exporters/otlp/all/src/jmh/java/io/opentelemetry/exporter/otlp/trace/OltpExporterBenchmark.java @@ -84,7 +84,9 @@ public void setUp() { "otlp", "span", new UpstreamGrpcSender<>( - MarshalerTraceServiceGrpc.newFutureStub(defaultGrpcChannel, null), 10), + MarshalerTraceServiceGrpc.newFutureStub(defaultGrpcChannel, null), + 10, + Collections::emptyMap), MeterProvider::noop); okhttpGrpcSender = @@ -97,7 +99,7 @@ public void setUp() { .toString(), /* compressionEnabled= */ false, 10, - Collections.emptyMap(), + Collections::emptyMap, null, null, null), diff --git a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/logs/OtlpHttpLogRecordExporterBuilder.java b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/logs/OtlpHttpLogRecordExporterBuilder.java index 9780567565a..9b8a52df9c3 100644 --- a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/logs/OtlpHttpLogRecordExporterBuilder.java +++ b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/logs/OtlpHttpLogRecordExporterBuilder.java @@ -15,6 +15,7 @@ import io.opentelemetry.exporter.otlp.internal.OtlpUserAgent; import io.opentelemetry.sdk.common.export.RetryPolicy; import java.time.Duration; +import java.util.Map; import java.util.concurrent.TimeUnit; import java.util.function.Supplier; import javax.net.ssl.SSLContext; @@ -33,7 +34,7 @@ public final class OtlpHttpLogRecordExporterBuilder { OtlpHttpLogRecordExporterBuilder(HttpExporterBuilder delegate) { this.delegate = delegate; - OtlpUserAgent.addUserAgentHeader(delegate::addHeader); + OtlpUserAgent.addUserAgentHeader(delegate::addConstantHeaders); } OtlpHttpLogRecordExporterBuilder() { @@ -103,9 +104,21 @@ public OtlpHttpLogRecordExporterBuilder setCompression(String compressionMethod) return this; } - /** Add header to requests. */ + /** + * Add a constant header to requests. If the {@code key} collides with another constant header + * name or a one from {@link #setHeaders(Supplier)}, the values from both are included. + */ public OtlpHttpLogRecordExporterBuilder addHeader(String key, String value) { - delegate.addHeader(key, value); + delegate.addConstantHeaders(key, value); + return this; + } + + /** + * Set the supplier of headers to add to requests. If a key from the map collides with a constant + * from {@link #addHeader(String, String)}, the values from both are included. + */ + public OtlpHttpLogRecordExporterBuilder setHeaders(Supplier> headerSupplier) { + delegate.setHeadersSupplier(headerSupplier); return this; } diff --git a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/metrics/OtlpHttpMetricExporterBuilder.java b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/metrics/OtlpHttpMetricExporterBuilder.java index 01a29681c32..d31a510b251 100644 --- a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/metrics/OtlpHttpMetricExporterBuilder.java +++ b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/metrics/OtlpHttpMetricExporterBuilder.java @@ -18,7 +18,9 @@ import io.opentelemetry.sdk.metrics.export.DefaultAggregationSelector; import io.opentelemetry.sdk.metrics.export.MetricExporter; import java.time.Duration; +import java.util.Map; import java.util.concurrent.TimeUnit; +import java.util.function.Supplier; import javax.net.ssl.SSLContext; import javax.net.ssl.X509TrustManager; @@ -44,7 +46,7 @@ public final class OtlpHttpMetricExporterBuilder { OtlpHttpMetricExporterBuilder(HttpExporterBuilder delegate) { this.delegate = delegate; delegate.setMeterProvider(MeterProvider::noop); - OtlpUserAgent.addUserAgentHeader(delegate::addHeader); + OtlpUserAgent.addUserAgentHeader(delegate::addConstantHeaders); } OtlpHttpMetricExporterBuilder() { @@ -114,9 +116,21 @@ public OtlpHttpMetricExporterBuilder setCompression(String compressionMethod) { return this; } - /** Add header to requests. */ + /** + * Add a constant header to requests. If the {@code key} collides with another constant header + * name or a one from {@link #setHeaders(Supplier)}, the values from both are included. + */ public OtlpHttpMetricExporterBuilder addHeader(String key, String value) { - delegate.addHeader(key, value); + delegate.addConstantHeaders(key, value); + return this; + } + + /** + * Set the supplier of headers to add to requests. If a key from the map collides with a constant + * from {@link #addHeader(String, String)}, the values from both are included. + */ + public OtlpHttpMetricExporterBuilder setHeaders(Supplier> headerSupplier) { + delegate.setHeadersSupplier(headerSupplier); return this; } diff --git a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/trace/OtlpHttpSpanExporterBuilder.java b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/trace/OtlpHttpSpanExporterBuilder.java index eba2ee786a3..96cf2c2a2f4 100644 --- a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/trace/OtlpHttpSpanExporterBuilder.java +++ b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/trace/OtlpHttpSpanExporterBuilder.java @@ -15,6 +15,7 @@ import io.opentelemetry.exporter.otlp.internal.OtlpUserAgent; import io.opentelemetry.sdk.common.export.RetryPolicy; import java.time.Duration; +import java.util.Map; import java.util.concurrent.TimeUnit; import java.util.function.Supplier; import javax.net.ssl.SSLContext; @@ -33,7 +34,7 @@ public final class OtlpHttpSpanExporterBuilder { OtlpHttpSpanExporterBuilder(HttpExporterBuilder delegate) { this.delegate = delegate; - OtlpUserAgent.addUserAgentHeader(delegate::addHeader); + OtlpUserAgent.addUserAgentHeader(delegate::addConstantHeaders); } OtlpHttpSpanExporterBuilder() { @@ -103,9 +104,21 @@ public OtlpHttpSpanExporterBuilder setCompression(String compressionMethod) { return this; } - /** Add header to requests. */ + /** + * Add a constant header to requests. If the {@code key} collides with another constant header + * name or a one from {@link #setHeaders(Supplier)}, the values from both are included. + */ public OtlpHttpSpanExporterBuilder addHeader(String key, String value) { - delegate.addHeader(key, value); + delegate.addConstantHeaders(key, value); + return this; + } + + /** + * Set the supplier of headers to add to requests. If a key from the map collides with a constant + * from {@link #addHeader(String, String)}, the values from both are included. + */ + public OtlpHttpSpanExporterBuilder setHeaders(Supplier> headerSupplier) { + delegate.setHeadersSupplier(headerSupplier); return this; } diff --git a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/logs/OtlpGrpcLogRecordExporterBuilder.java b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/logs/OtlpGrpcLogRecordExporterBuilder.java index cbdf26886c1..2fd6cdb5000 100644 --- a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/logs/OtlpGrpcLogRecordExporterBuilder.java +++ b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/logs/OtlpGrpcLogRecordExporterBuilder.java @@ -17,6 +17,7 @@ import io.opentelemetry.sdk.common.export.RetryPolicy; import java.net.URI; import java.time.Duration; +import java.util.Map; import java.util.concurrent.TimeUnit; import java.util.function.Supplier; import javax.net.ssl.SSLContext; @@ -43,7 +44,7 @@ public final class OtlpGrpcLogRecordExporterBuilder { OtlpGrpcLogRecordExporterBuilder(GrpcExporterBuilder delegate) { this.delegate = delegate; - OtlpUserAgent.addUserAgentHeader(delegate::addHeader); + OtlpUserAgent.addUserAgentHeader(delegate::addConstantHeader); } OtlpGrpcLogRecordExporterBuilder() { @@ -151,15 +152,27 @@ public OtlpGrpcLogRecordExporterBuilder setSslContext( } /** - * Add header to request. Optional. Applicable only if {@link - * OtlpGrpcLogRecordExporterBuilder#setChannel(ManagedChannel)} is not used to set channel. + * Add a constant header to requests. If the {@code key} collides with another constant header + * name or a one from {@link #setHeaders(Supplier)}, the values from both are included. Applicable + * only if {@link OtlpGrpcLogRecordExporterBuilder#setChannel(ManagedChannel)} is not used to set + * channel. * * @param key header key * @param value header value * @return this builder's instance */ public OtlpGrpcLogRecordExporterBuilder addHeader(String key, String value) { - delegate.addHeader(key, value); + delegate.addConstantHeader(key, value); + return this; + } + + /** + * Set the supplier of headers to add to requests. If a key from the map collides with a constant + * from {@link #addHeader(String, String)}, the values from both are included. Applicable only if + * {@link OtlpGrpcLogRecordExporterBuilder#setChannel(ManagedChannel)} is not used to set channel. + */ + public OtlpGrpcLogRecordExporterBuilder setHeaders(Supplier> headerSupplier) { + delegate.setHeadersSupplier(headerSupplier); return this; } diff --git a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/metrics/OtlpGrpcMetricExporterBuilder.java b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/metrics/OtlpGrpcMetricExporterBuilder.java index 11ba7460868..00e4bcabd2e 100644 --- a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/metrics/OtlpGrpcMetricExporterBuilder.java +++ b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/metrics/OtlpGrpcMetricExporterBuilder.java @@ -20,7 +20,9 @@ import io.opentelemetry.sdk.metrics.export.MetricExporter; import java.net.URI; import java.time.Duration; +import java.util.Map; import java.util.concurrent.TimeUnit; +import java.util.function.Supplier; import javax.net.ssl.SSLContext; import javax.net.ssl.X509TrustManager; @@ -54,7 +56,7 @@ public final class OtlpGrpcMetricExporterBuilder { OtlpGrpcMetricExporterBuilder(GrpcExporterBuilder delegate) { this.delegate = delegate; delegate.setMeterProvider(MeterProvider::noop); - OtlpUserAgent.addUserAgentHeader(delegate::addHeader); + OtlpUserAgent.addUserAgentHeader(delegate::addConstantHeader); } OtlpGrpcMetricExporterBuilder() { @@ -163,15 +165,27 @@ public OtlpGrpcMetricExporterBuilder setSslContext( } /** - * Add header to request. Optional. Applicable only if {@link - * OtlpGrpcMetricExporterBuilder#setChannel(ManagedChannel)} is not used to set channel. + * Add a constant header to requests. If the {@code key} collides with another constant header + * name or a one from {@link #setHeaders(Supplier)}, the values from both are included. Applicable + * only if {@link OtlpGrpcMetricExporterBuilder#setChannel(ManagedChannel)} is not used to set + * channel. * * @param key header key * @param value header value * @return this builder's instance */ public OtlpGrpcMetricExporterBuilder addHeader(String key, String value) { - delegate.addHeader(key, value); + delegate.addConstantHeader(key, value); + return this; + } + + /** + * Set the supplier of headers to add to requests. If a key from the map collides with a constant + * from {@link #addHeader(String, String)}, the values from both are included. Applicable only if + * {@link OtlpGrpcMetricExporterBuilder#setChannel(ManagedChannel)} is not used to set channel. + */ + public OtlpGrpcMetricExporterBuilder setHeaders(Supplier> headerSupplier) { + delegate.setHeadersSupplier(headerSupplier); return this; } diff --git a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/trace/OtlpGrpcSpanExporterBuilder.java b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/trace/OtlpGrpcSpanExporterBuilder.java index 77e0f3ae01a..c3e286b5a22 100644 --- a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/trace/OtlpGrpcSpanExporterBuilder.java +++ b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/trace/OtlpGrpcSpanExporterBuilder.java @@ -17,6 +17,7 @@ import io.opentelemetry.sdk.common.export.RetryPolicy; import java.net.URI; import java.time.Duration; +import java.util.Map; import java.util.concurrent.TimeUnit; import java.util.function.Supplier; import javax.net.ssl.SSLContext; @@ -39,7 +40,7 @@ public final class OtlpGrpcSpanExporterBuilder { OtlpGrpcSpanExporterBuilder(GrpcExporterBuilder delegate) { this.delegate = delegate; - OtlpUserAgent.addUserAgentHeader(delegate::addHeader); + OtlpUserAgent.addUserAgentHeader(delegate::addConstantHeader); } OtlpGrpcSpanExporterBuilder() { @@ -148,15 +149,27 @@ public OtlpGrpcSpanExporterBuilder setSslContext( } /** - * Add header to request. Optional. Applicable only if {@link - * OtlpGrpcSpanExporterBuilder#setChannel(ManagedChannel)} is not called. + * Add a constant header to requests. If the {@code key} collides with another constant header + * name or a one from {@link #setHeaders(Supplier)}, the values from both are included. Applicable + * only if {@link OtlpGrpcSpanExporterBuilder#setChannel(ManagedChannel)} is not used to set + * channel. * * @param key header key * @param value header value * @return this builder's instance */ public OtlpGrpcSpanExporterBuilder addHeader(String key, String value) { - delegate.addHeader(key, value); + delegate.addConstantHeader(key, value); + return this; + } + + /** + * Set the supplier of headers to add to requests. If a key from the map collides with a constant + * from {@link #addHeader(String, String)}, the values from both are included. Applicable only if + * {@link OtlpGrpcSpanExporterBuilder#setChannel(ManagedChannel)} is not used to set channel. + */ + public OtlpGrpcSpanExporterBuilder setHeaders(Supplier> headerSupplier) { + delegate.setHeadersSupplier(headerSupplier); return this; } diff --git a/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/AbstractGrpcTelemetryExporterTest.java b/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/AbstractGrpcTelemetryExporterTest.java index 5c2c6b665a7..c2490029aac 100644 --- a/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/AbstractGrpcTelemetryExporterTest.java +++ b/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/AbstractGrpcTelemetryExporterTest.java @@ -291,18 +291,31 @@ void authorityWithAuth() { @Test void withHeaders() { + AtomicInteger count = new AtomicInteger(); TelemetryExporter exporter = exporterBuilder() .setEndpoint(server.httpUri().toString()) - .addHeader("key", "value") + .addHeader("key1", "value1") + .setHeaders(() -> Collections.singletonMap("key2", "value" + count.incrementAndGet())) .build(); try { + // Export twice to ensure header supplier gets invoked twice CompletableResultCode result = exporter.export(Collections.singletonList(generateFakeTelemetry())); assertThat(result.join(10, TimeUnit.SECONDS).isSuccess()).isTrue(); + result = exporter.export(Collections.singletonList(generateFakeTelemetry())); + assertThat(result.join(10, TimeUnit.SECONDS).isSuccess()).isTrue(); + assertThat(httpRequests) - .singleElement() - .satisfies(req -> assertThat(req.headers().get("key")).isEqualTo("value")); + .satisfiesExactly( + req -> { + assertThat(req.headers().get("key1")).isEqualTo("value1"); + assertThat(req.headers().get("key2")).isEqualTo("value" + (count.get() - 1)); + }, + req -> { + assertThat(req.headers().get("key1")).isEqualTo("value1"); + assertThat(req.headers().get("key2")).isEqualTo("value" + count.get()); + }); } finally { exporter.shutdown(); } diff --git a/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/AbstractHttpTelemetryExporterTest.java b/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/AbstractHttpTelemetryExporterTest.java index c306e4fbc2f..a29b9f0b5b2 100644 --- a/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/AbstractHttpTelemetryExporterTest.java +++ b/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/AbstractHttpTelemetryExporterTest.java @@ -326,15 +326,31 @@ void authorityWithAuth() { @Test void withHeaders() { + AtomicInteger count = new AtomicInteger(); TelemetryExporter exporter = - exporterBuilder().setEndpoint(server.httpUri() + path).addHeader("key", "value").build(); + exporterBuilder() + .setEndpoint(server.httpUri() + path) + .addHeader("key1", "value1") + .setHeaders(() -> Collections.singletonMap("key2", "value" + count.incrementAndGet())) + .build(); try { + // Export twice to ensure header supplier gets invoked twice CompletableResultCode result = exporter.export(Collections.singletonList(generateFakeTelemetry())); assertThat(result.join(10, TimeUnit.SECONDS).isSuccess()).isTrue(); + result = exporter.export(Collections.singletonList(generateFakeTelemetry())); + assertThat(result.join(10, TimeUnit.SECONDS).isSuccess()).isTrue(); + assertThat(httpRequests) - .singleElement() - .satisfies(req -> assertThat(req.headers().get("key")).isEqualTo("value")); + .satisfiesExactly( + req -> { + assertThat(req.headers().get("key1")).isEqualTo("value1"); + assertThat(req.headers().get("key2")).isEqualTo("value" + (count.get() - 1)); + }, + req -> { + assertThat(req.headers().get("key1")).isEqualTo("value1"); + assertThat(req.headers().get("key2")).isEqualTo("value" + count.get()); + }); } finally { exporter.shutdown(); } diff --git a/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/GrpcLogRecordExporterBuilderWrapper.java b/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/GrpcLogRecordExporterBuilderWrapper.java index 916f15e6b2f..5495a9d6bcd 100644 --- a/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/GrpcLogRecordExporterBuilderWrapper.java +++ b/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/GrpcLogRecordExporterBuilderWrapper.java @@ -11,7 +11,9 @@ import io.opentelemetry.sdk.common.export.RetryPolicy; import io.opentelemetry.sdk.logs.data.LogRecordData; import java.time.Duration; +import java.util.Map; import java.util.concurrent.TimeUnit; +import java.util.function.Supplier; import javax.net.ssl.SSLContext; import javax.net.ssl.X509TrustManager; @@ -62,6 +64,13 @@ public TelemetryExporterBuilder addHeader(String key, String valu return this; } + @Override + public TelemetryExporterBuilder setHeaders( + Supplier> headerSupplier) { + builder.setHeaders(headerSupplier); + return this; + } + @Override public TelemetryExporterBuilder setAuthenticator(Authenticator authenticator) { return this; diff --git a/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/GrpcMetricExporterBuilderWrapper.java b/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/GrpcMetricExporterBuilderWrapper.java index 821baaa729d..ff9a53a7ca5 100644 --- a/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/GrpcMetricExporterBuilderWrapper.java +++ b/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/GrpcMetricExporterBuilderWrapper.java @@ -11,7 +11,9 @@ import io.opentelemetry.sdk.common.export.RetryPolicy; import io.opentelemetry.sdk.metrics.data.MetricData; import java.time.Duration; +import java.util.Map; import java.util.concurrent.TimeUnit; +import java.util.function.Supplier; import javax.net.ssl.SSLContext; import javax.net.ssl.X509TrustManager; @@ -62,6 +64,13 @@ public TelemetryExporterBuilder addHeader(String key, String value) return this; } + @Override + public TelemetryExporterBuilder setHeaders( + Supplier> headerSupplier) { + builder.setHeaders(headerSupplier); + return this; + } + @Override public TelemetryExporterBuilder setAuthenticator(Authenticator authenticator) { return this; diff --git a/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/GrpcSpanExporterBuilderWrapper.java b/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/GrpcSpanExporterBuilderWrapper.java index 2f86433672e..59068809909 100644 --- a/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/GrpcSpanExporterBuilderWrapper.java +++ b/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/GrpcSpanExporterBuilderWrapper.java @@ -11,7 +11,9 @@ import io.opentelemetry.sdk.common.export.RetryPolicy; import io.opentelemetry.sdk.trace.data.SpanData; import java.time.Duration; +import java.util.Map; import java.util.concurrent.TimeUnit; +import java.util.function.Supplier; import javax.net.ssl.SSLContext; import javax.net.ssl.X509TrustManager; @@ -63,6 +65,13 @@ public TelemetryExporterBuilder addHeader(String key, String value) { return this; } + @Override + public TelemetryExporterBuilder setHeaders( + Supplier> headerSupplier) { + builder.setHeaders(headerSupplier); + return this; + } + @Override public TelemetryExporterBuilder setAuthenticator(Authenticator authenticator) { return this; diff --git a/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/HttpLogRecordExporterBuilderWrapper.java b/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/HttpLogRecordExporterBuilderWrapper.java index 5fc42608acd..a849395cbcf 100644 --- a/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/HttpLogRecordExporterBuilderWrapper.java +++ b/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/HttpLogRecordExporterBuilderWrapper.java @@ -10,7 +10,9 @@ import io.opentelemetry.sdk.common.export.RetryPolicy; import io.opentelemetry.sdk.logs.data.LogRecordData; import java.time.Duration; +import java.util.Map; import java.util.concurrent.TimeUnit; +import java.util.function.Supplier; import javax.net.ssl.SSLContext; import javax.net.ssl.X509TrustManager; @@ -65,6 +67,13 @@ public TelemetryExporterBuilder addHeader(String key, String valu return this; } + @Override + public TelemetryExporterBuilder setHeaders( + Supplier> headerSupplier) { + builder.setHeaders(headerSupplier); + return this; + } + @Override public TelemetryExporterBuilder setAuthenticator(Authenticator authenticator) { Authenticator.setAuthenticatorOnDelegate(builder, authenticator); diff --git a/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/HttpMetricExporterBuilderWrapper.java b/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/HttpMetricExporterBuilderWrapper.java index e4357378a86..51f5eff0b3b 100644 --- a/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/HttpMetricExporterBuilderWrapper.java +++ b/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/HttpMetricExporterBuilderWrapper.java @@ -10,7 +10,9 @@ import io.opentelemetry.sdk.common.export.RetryPolicy; import io.opentelemetry.sdk.metrics.data.MetricData; import java.time.Duration; +import java.util.Map; import java.util.concurrent.TimeUnit; +import java.util.function.Supplier; import javax.net.ssl.SSLContext; import javax.net.ssl.X509TrustManager; @@ -64,6 +66,13 @@ public TelemetryExporterBuilder addHeader(String key, String value) return this; } + @Override + public TelemetryExporterBuilder setHeaders( + Supplier> headerSupplier) { + builder.setHeaders(headerSupplier); + return this; + } + @Override public TelemetryExporterBuilder setAuthenticator(Authenticator authenticator) { Authenticator.setAuthenticatorOnDelegate(builder, authenticator); diff --git a/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/HttpSpanExporterBuilderWrapper.java b/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/HttpSpanExporterBuilderWrapper.java index 550d25c26e1..90bc3ab00ea 100644 --- a/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/HttpSpanExporterBuilderWrapper.java +++ b/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/HttpSpanExporterBuilderWrapper.java @@ -10,7 +10,9 @@ import io.opentelemetry.sdk.common.export.RetryPolicy; import io.opentelemetry.sdk.trace.data.SpanData; import java.time.Duration; +import java.util.Map; import java.util.concurrent.TimeUnit; +import java.util.function.Supplier; import javax.net.ssl.SSLContext; import javax.net.ssl.X509TrustManager; @@ -64,6 +66,13 @@ public TelemetryExporterBuilder addHeader(String key, String value) { return this; } + @Override + public TelemetryExporterBuilder setHeaders( + Supplier> headerSupplier) { + builder.setHeaders(headerSupplier); + return this; + } + @Override public TelemetryExporterBuilder setAuthenticator(Authenticator authenticator) { Authenticator.setAuthenticatorOnDelegate(builder, authenticator); diff --git a/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/ManagedChannelTelemetryExporterBuilder.java b/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/ManagedChannelTelemetryExporterBuilder.java index fbad7272a76..be7d97b9678 100644 --- a/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/ManagedChannelTelemetryExporterBuilder.java +++ b/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/ManagedChannelTelemetryExporterBuilder.java @@ -21,7 +21,9 @@ import java.net.URI; import java.time.Duration; import java.util.Collection; +import java.util.Map; import java.util.concurrent.TimeUnit; +import java.util.function.Supplier; import javax.annotation.Nullable; import javax.net.ssl.SSLContext; import javax.net.ssl.SSLException; @@ -100,6 +102,12 @@ public TelemetryExporterBuilder addHeader(String key, String value) { return this; } + @Override + public TelemetryExporterBuilder setHeaders(Supplier> headerSupplier) { + delegate.setHeaders(headerSupplier); + return this; + } + @Override public TelemetryExporterBuilder setAuthenticator(Authenticator authenticator) { delegate.setAuthenticator(authenticator); diff --git a/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/TelemetryExporterBuilder.java b/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/TelemetryExporterBuilder.java index 6fbe78149e5..3f0b03b2e54 100644 --- a/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/TelemetryExporterBuilder.java +++ b/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/TelemetryExporterBuilder.java @@ -14,7 +14,9 @@ import io.opentelemetry.sdk.metrics.data.MetricData; import io.opentelemetry.sdk.trace.data.SpanData; import java.time.Duration; +import java.util.Map; import java.util.concurrent.TimeUnit; +import java.util.function.Supplier; import javax.net.ssl.SSLContext; import javax.net.ssl.X509TrustManager; @@ -46,6 +48,8 @@ static TelemetryExporterBuilder wrap(OtlpGrpcLogRecordExporterBui TelemetryExporterBuilder addHeader(String key, String value); + TelemetryExporterBuilder setHeaders(Supplier> headerSupplier); + TelemetryExporterBuilder setAuthenticator(Authenticator authenticator); TelemetryExporterBuilder setTrustedCertificates(byte[] certificates); diff --git a/exporters/sender/grpc-managed-channel/src/main/java/io/opentelemetry/exporter/sender/grpc/managedchannel/internal/UpstreamGrpcSender.java b/exporters/sender/grpc-managed-channel/src/main/java/io/opentelemetry/exporter/sender/grpc/managedchannel/internal/UpstreamGrpcSender.java index 2a18eaf2b53..28f813accc7 100644 --- a/exporters/sender/grpc-managed-channel/src/main/java/io/opentelemetry/exporter/sender/grpc/managedchannel/internal/UpstreamGrpcSender.java +++ b/exporters/sender/grpc-managed-channel/src/main/java/io/opentelemetry/exporter/sender/grpc/managedchannel/internal/UpstreamGrpcSender.java @@ -8,14 +8,19 @@ import com.google.common.util.concurrent.FutureCallback; import com.google.common.util.concurrent.Futures; import com.google.common.util.concurrent.MoreExecutors; +import io.grpc.Metadata; import io.grpc.Status; +import io.grpc.stub.MetadataUtils; import io.opentelemetry.exporter.internal.grpc.GrpcResponse; import io.opentelemetry.exporter.internal.grpc.GrpcSender; import io.opentelemetry.exporter.internal.grpc.MarshalerServiceStub; import io.opentelemetry.exporter.internal.marshal.Marshaler; import io.opentelemetry.sdk.common.CompletableResultCode; +import java.util.List; +import java.util.Map; import java.util.concurrent.TimeUnit; import java.util.function.BiConsumer; +import java.util.function.Supplier; import org.checkerframework.checker.nullness.qual.Nullable; /** @@ -28,11 +33,16 @@ public final class UpstreamGrpcSender implements GrpcSender private final MarshalerServiceStub stub; private final long timeoutNanos; + private final Supplier>> headersSupplier; /** Creates a new {@link UpstreamGrpcSender}. */ - public UpstreamGrpcSender(MarshalerServiceStub stub, long timeoutNanos) { + public UpstreamGrpcSender( + MarshalerServiceStub stub, + long timeoutNanos, + Supplier>> headersSupplier) { this.timeoutNanos = timeoutNanos; this.stub = stub; + this.headersSupplier = headersSupplier; } @Override @@ -41,6 +51,17 @@ public void send(T request, Runnable onSuccess, BiConsumer 0) { stub = stub.withDeadlineAfter(timeoutNanos, TimeUnit.NANOSECONDS); } + Map> headers = headersSupplier.get(); + if (headers != null) { + Metadata metadata = new Metadata(); + for (Map.Entry> entry : headers.entrySet()) { + metadata.put( + Metadata.Key.of(entry.getKey(), Metadata.ASCII_STRING_MARSHALLER), + String.join(",", entry.getValue())); + } + stub = stub.withInterceptors(MetadataUtils.newAttachHeadersInterceptor(metadata)); + } + Futures.addCallback( stub.export(request), new FutureCallback() { diff --git a/exporters/sender/grpc-managed-channel/src/main/java/io/opentelemetry/exporter/sender/grpc/managedchannel/internal/UpstreamGrpcSenderProvider.java b/exporters/sender/grpc-managed-channel/src/main/java/io/opentelemetry/exporter/sender/grpc/managedchannel/internal/UpstreamGrpcSenderProvider.java index b560712351f..34200681980 100644 --- a/exporters/sender/grpc-managed-channel/src/main/java/io/opentelemetry/exporter/sender/grpc/managedchannel/internal/UpstreamGrpcSenderProvider.java +++ b/exporters/sender/grpc-managed-channel/src/main/java/io/opentelemetry/exporter/sender/grpc/managedchannel/internal/UpstreamGrpcSenderProvider.java @@ -6,16 +6,14 @@ package io.opentelemetry.exporter.sender.grpc.managedchannel.internal; import io.grpc.Channel; -import io.grpc.ClientInterceptors; import io.grpc.Codec; -import io.grpc.Metadata; -import io.grpc.stub.MetadataUtils; import io.opentelemetry.exporter.internal.grpc.GrpcSender; import io.opentelemetry.exporter.internal.grpc.GrpcSenderProvider; import io.opentelemetry.exporter.internal.grpc.MarshalerServiceStub; import io.opentelemetry.exporter.internal.marshal.Marshaler; import io.opentelemetry.sdk.common.export.RetryPolicy; import java.net.URI; +import java.util.List; import java.util.Map; import java.util.function.BiFunction; import java.util.function.Supplier; @@ -37,35 +35,29 @@ public GrpcSender createSender( String endpointPath, boolean compressionEnabled, long timeoutNanos, - Map headers, + Supplier>> headersSupplier, @Nullable Object managedChannel, Supplier>> stubFactory, @Nullable RetryPolicy retryPolicy, @Nullable SSLContext sslContext, @Nullable X509TrustManager trustManager) { - Metadata metadata = new Metadata(); String authorityOverride = null; - for (Map.Entry entry : headers.entrySet()) { - String name = entry.getKey(); - String value = entry.getValue(); - if (name.equals("host")) { - authorityOverride = value; - continue; + Map> headers = headersSupplier.get(); + if (headers != null) { + for (Map.Entry> entry : headers.entrySet()) { + if (entry.getKey().equals("host") && !entry.getValue().isEmpty()) { + authorityOverride = entry.getValue().get(0); + } } - metadata.put(Metadata.Key.of(name, Metadata.ASCII_STRING_MARSHALLER), value); } - Channel channel = - ClientInterceptors.intercept( - (Channel) managedChannel, MetadataUtils.newAttachHeadersInterceptor(metadata)); - Codec codec = compressionEnabled ? new Codec.Gzip() : Codec.Identity.NONE; MarshalerServiceStub stub = stubFactory .get() - .apply(channel, authorityOverride) + .apply((Channel) managedChannel, authorityOverride) .withCompression(codec.getMessageEncoding()); - return new UpstreamGrpcSender<>(stub, timeoutNanos); + return new UpstreamGrpcSender<>(stub, timeoutNanos, headersSupplier); } } diff --git a/exporters/sender/jdk/src/main/java/io/opentelemetry/exporter/sender/jdk/internal/JdkHttpSender.java b/exporters/sender/jdk/src/main/java/io/opentelemetry/exporter/sender/jdk/internal/JdkHttpSender.java index 93098b8312b..673b315d230 100644 --- a/exporters/sender/jdk/src/main/java/io/opentelemetry/exporter/sender/jdk/internal/JdkHttpSender.java +++ b/exporters/sender/jdk/src/main/java/io/opentelemetry/exporter/sender/jdk/internal/JdkHttpSender.java @@ -18,6 +18,7 @@ import java.net.http.HttpResponse; import java.nio.ByteBuffer; import java.time.Duration; +import java.util.List; import java.util.Map; import java.util.Set; import java.util.concurrent.CompletableFuture; @@ -54,7 +55,7 @@ public final class JdkHttpSender implements HttpSender { private final boolean compressionEnabled; private final String contentType; private final long timeoutNanos; - private final Supplier> headerSupplier; + private final Supplier>> headerSupplier; @Nullable private final RetryPolicy retryPolicy; // Visible for testing @@ -64,7 +65,7 @@ public final class JdkHttpSender implements HttpSender { boolean compressionEnabled, String contentType, long timeoutNanos, - Supplier> headerSupplier, + Supplier>> headerSupplier, @Nullable RetryPolicy retryPolicy) { this.client = client; try { @@ -85,7 +86,7 @@ public final class JdkHttpSender implements HttpSender { String contentType, long timeoutNanos, long connectTimeoutNanos, - Supplier> headerSupplier, + Supplier>> headerSupplier, @Nullable RetryPolicy retryPolicy, @Nullable SSLContext sslContext) { this( @@ -139,7 +140,10 @@ HttpResponse sendInternal(Consumer marshaler) throws IOExc long startTimeNanos = System.nanoTime(); HttpRequest.Builder requestBuilder = HttpRequest.newBuilder().uri(uri).timeout(Duration.ofNanos(timeoutNanos)); - headerSupplier.get().forEach(requestBuilder::setHeader); + Map> headers = headerSupplier.get(); + if (headers != null) { + headers.forEach((key, values) -> values.forEach(value -> requestBuilder.header(key, value))); + } requestBuilder.header("Content-Type", contentType); NoCopyByteArrayOutputStream os = threadLocalBaos.get(); diff --git a/exporters/sender/jdk/src/main/java/io/opentelemetry/exporter/sender/jdk/internal/JdkHttpSenderProvider.java b/exporters/sender/jdk/src/main/java/io/opentelemetry/exporter/sender/jdk/internal/JdkHttpSenderProvider.java index 5e3496b1496..2478079dce6 100644 --- a/exporters/sender/jdk/src/main/java/io/opentelemetry/exporter/sender/jdk/internal/JdkHttpSenderProvider.java +++ b/exporters/sender/jdk/src/main/java/io/opentelemetry/exporter/sender/jdk/internal/JdkHttpSenderProvider.java @@ -9,6 +9,7 @@ import io.opentelemetry.exporter.internal.http.HttpSender; import io.opentelemetry.exporter.internal.http.HttpSenderProvider; import io.opentelemetry.sdk.common.export.RetryPolicy; +import java.util.List; import java.util.Map; import java.util.function.Supplier; import javax.annotation.Nullable; @@ -30,7 +31,7 @@ public HttpSender createSender( String contentType, long timeoutNanos, long connectTimeout, - Supplier> headerSupplier, + Supplier>> headerSupplier, @Nullable Authenticator authenticator, @Nullable RetryPolicy retryPolicy, @Nullable SSLContext sslContext, diff --git a/exporters/sender/okhttp/src/main/java/io/opentelemetry/exporter/sender/okhttp/internal/OkHttpGrpcSender.java b/exporters/sender/okhttp/src/main/java/io/opentelemetry/exporter/sender/okhttp/internal/OkHttpGrpcSender.java index 9ed05b003b5..24ade7fae5a 100644 --- a/exporters/sender/okhttp/src/main/java/io/opentelemetry/exporter/sender/okhttp/internal/OkHttpGrpcSender.java +++ b/exporters/sender/okhttp/src/main/java/io/opentelemetry/exporter/sender/okhttp/internal/OkHttpGrpcSender.java @@ -37,14 +37,15 @@ import java.time.Duration; import java.util.Arrays; import java.util.Collections; +import java.util.List; import java.util.Map; import java.util.function.BiConsumer; +import java.util.function.Supplier; import javax.annotation.Nullable; import javax.net.ssl.SSLContext; import javax.net.ssl.X509TrustManager; import okhttp3.Call; import okhttp3.Callback; -import okhttp3.Headers; import okhttp3.HttpUrl; import okhttp3.OkHttpClient; import okhttp3.Protocol; @@ -65,7 +66,7 @@ public final class OkHttpGrpcSender implements GrpcSender>> headersSupplier; private final boolean compressionEnabled; /** Creates a new {@link OkHttpGrpcSender}. */ @@ -73,7 +74,7 @@ public OkHttpGrpcSender( String endpoint, boolean compressionEnabled, long timeoutNanos, - Map headers, + Supplier>> headersSupplier, @Nullable RetryPolicy retryPolicy, @Nullable SSLContext sslContext, @Nullable X509TrustManager trustManager) { @@ -94,22 +95,24 @@ public OkHttpGrpcSender( clientBuilder.protocols(Arrays.asList(Protocol.HTTP_2, Protocol.HTTP_1_1)); } this.client = clientBuilder.build(); - - Headers.Builder headersBuilder = new Headers.Builder(); - headers.forEach(headersBuilder::add); - headersBuilder.add("te", "trailers"); - if (compressionEnabled) { - headersBuilder.add("grpc-encoding", "gzip"); - } - this.headers = headersBuilder.build(); + this.headersSupplier = headersSupplier; this.url = HttpUrl.get(endpoint); this.compressionEnabled = compressionEnabled; } @Override public void send(T request, Runnable onSuccess, BiConsumer onError) { - Request.Builder requestBuilder = new Request.Builder().url(url).headers(headers); + Request.Builder requestBuilder = new Request.Builder().url(url); + Map> headers = headersSupplier.get(); + if (headers != null) { + headers.forEach( + (key, values) -> values.forEach(value -> requestBuilder.addHeader(key, value))); + } + requestBuilder.addHeader("te", "trailers"); + if (compressionEnabled) { + requestBuilder.addHeader("grpc-encoding", "gzip"); + } RequestBody requestBody = new GrpcRequestBody(request, compressionEnabled); requestBuilder.post(requestBody); diff --git a/exporters/sender/okhttp/src/main/java/io/opentelemetry/exporter/sender/okhttp/internal/OkHttpGrpcSenderProvider.java b/exporters/sender/okhttp/src/main/java/io/opentelemetry/exporter/sender/okhttp/internal/OkHttpGrpcSenderProvider.java index c1cbb3be664..6ac663495b0 100644 --- a/exporters/sender/okhttp/src/main/java/io/opentelemetry/exporter/sender/okhttp/internal/OkHttpGrpcSenderProvider.java +++ b/exporters/sender/okhttp/src/main/java/io/opentelemetry/exporter/sender/okhttp/internal/OkHttpGrpcSenderProvider.java @@ -12,6 +12,7 @@ import io.opentelemetry.exporter.internal.marshal.Marshaler; import io.opentelemetry.sdk.common.export.RetryPolicy; import java.net.URI; +import java.util.List; import java.util.Map; import java.util.function.BiFunction; import java.util.function.Supplier; @@ -33,7 +34,7 @@ public GrpcSender createSender( String endpointPath, boolean compressionEnabled, long timeoutNanos, - Map headers, + Supplier>> headersSupplier, @Nullable Object managedChannel, Supplier>> stubFactory, @Nullable RetryPolicy retryPolicy, @@ -43,7 +44,7 @@ public GrpcSender createSender( endpoint.resolve(endpointPath).toString(), compressionEnabled, timeoutNanos, - headers, + headersSupplier, retryPolicy, sslContext, trustManager); diff --git a/exporters/sender/okhttp/src/main/java/io/opentelemetry/exporter/sender/okhttp/internal/OkHttpHttpSender.java b/exporters/sender/okhttp/src/main/java/io/opentelemetry/exporter/sender/okhttp/internal/OkHttpHttpSender.java index 18356f23962..337a722a06d 100644 --- a/exporters/sender/okhttp/src/main/java/io/opentelemetry/exporter/sender/okhttp/internal/OkHttpHttpSender.java +++ b/exporters/sender/okhttp/src/main/java/io/opentelemetry/exporter/sender/okhttp/internal/OkHttpHttpSender.java @@ -14,6 +14,7 @@ import java.io.IOException; import java.io.OutputStream; import java.time.Duration; +import java.util.List; import java.util.Map; import java.util.function.Consumer; import java.util.function.Supplier; @@ -43,7 +44,7 @@ public final class OkHttpHttpSender implements HttpSender { private final OkHttpClient client; private final HttpUrl url; private final boolean compressionEnabled; - private final Supplier> headerSupplier; + private final Supplier>> headerSupplier; private final MediaType mediaType; /** Create a sender. */ @@ -54,7 +55,7 @@ public OkHttpHttpSender( String contentType, long timeoutNanos, long connectionTimeoutNanos, - Supplier> headerSupplier, + Supplier>> headerSupplier, @Nullable Authenticator authenticator, @Nullable RetryPolicy retryPolicy, @Nullable SSLContext sslContext, @@ -96,7 +97,12 @@ public void send( Consumer onResponse, Consumer onError) { Request.Builder requestBuilder = new Request.Builder().url(url); - headerSupplier.get().forEach(requestBuilder::addHeader); + + Map> headers = headerSupplier.get(); + if (headers != null) { + headers.forEach( + (key, values) -> values.forEach(value -> requestBuilder.addHeader(key, value))); + } RequestBody body = new RawRequestBody(marshaler, contentLength, mediaType); if (compressionEnabled) { requestBuilder.addHeader("Content-Encoding", "gzip"); diff --git a/exporters/sender/okhttp/src/main/java/io/opentelemetry/exporter/sender/okhttp/internal/OkHttpHttpSenderProvider.java b/exporters/sender/okhttp/src/main/java/io/opentelemetry/exporter/sender/okhttp/internal/OkHttpHttpSenderProvider.java index 16a767f5c62..18573049082 100644 --- a/exporters/sender/okhttp/src/main/java/io/opentelemetry/exporter/sender/okhttp/internal/OkHttpHttpSenderProvider.java +++ b/exporters/sender/okhttp/src/main/java/io/opentelemetry/exporter/sender/okhttp/internal/OkHttpHttpSenderProvider.java @@ -9,6 +9,7 @@ import io.opentelemetry.exporter.internal.http.HttpSender; import io.opentelemetry.exporter.internal.http.HttpSenderProvider; import io.opentelemetry.sdk.common.export.RetryPolicy; +import java.util.List; import java.util.Map; import java.util.function.Supplier; import javax.net.ssl.SSLContext; @@ -30,7 +31,7 @@ public HttpSender createSender( String contentType, long timeoutNanos, long connectTimeout, - Supplier> headerSupplier, + Supplier>> headerSupplier, @Nullable Authenticator authenticator, @Nullable RetryPolicy retryPolicy, @Nullable SSLContext sslContext, diff --git a/exporters/sender/okhttp/src/test/java/io/opentelemetry/exporter/sender/okhttp/internal/OkHttpGrpcSuppressionTest.java b/exporters/sender/okhttp/src/test/java/io/opentelemetry/exporter/sender/okhttp/internal/OkHttpGrpcSuppressionTest.java index df52ff0f891..482eadc1bd4 100644 --- a/exporters/sender/okhttp/src/test/java/io/opentelemetry/exporter/sender/okhttp/internal/OkHttpGrpcSuppressionTest.java +++ b/exporters/sender/okhttp/src/test/java/io/opentelemetry/exporter/sender/okhttp/internal/OkHttpGrpcSuppressionTest.java @@ -21,7 +21,7 @@ void send(OkHttpGrpcSender sender, Runnable onSuccess, Runnable @Override OkHttpGrpcSender createSender(String endpoint) { return new OkHttpGrpcSender<>( - "https://localhost", false, 10L, Collections.emptyMap(), null, null, null); + "https://localhost", false, 10L, Collections::emptyMap, null, null, null); } protected static class DummyMarshaler extends MarshalerWithSize { From 05db74f4f4272a39ca1e8a2de23c51ea3ef1e268 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 8 Dec 2023 08:40:20 -0600 Subject: [PATCH 146/901] Update dependency org.owasp:dependency-check-gradle to v9.0.4 (#6064) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- buildSrc/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts index 4e5be662aa1..055eaea862d 100644 --- a/buildSrc/build.gradle.kts +++ b/buildSrc/build.gradle.kts @@ -58,7 +58,7 @@ dependencies { implementation("net.ltgt.gradle:gradle-errorprone-plugin:3.1.0") implementation("net.ltgt.gradle:gradle-nullaway-plugin:1.6.0") implementation("org.jetbrains.kotlin:kotlin-gradle-plugin:1.9.21") - implementation("org.owasp:dependency-check-gradle:9.0.3") + implementation("org.owasp:dependency-check-gradle:9.0.4") implementation("ru.vyarus:gradle-animalsniffer-plugin:1.7.1") } From e90a6f636b875cd271240f35d10449b34321aa9e Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 8 Dec 2023 09:15:35 -0600 Subject: [PATCH 147/901] Update dependency com.linecorp.armeria:armeria-bom to v1.26.4 (#6062) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- dependencyManagement/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index 7c3d709e58d..9e1ba7ef698 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -11,7 +11,7 @@ val DEPENDENCY_BOMS = listOf( "com.fasterxml.jackson:jackson-bom:2.16.0", "com.google.guava:guava-bom:32.1.3-jre", "com.google.protobuf:protobuf-bom:3.25.1", - "com.linecorp.armeria:armeria-bom:1.26.3", + "com.linecorp.armeria:armeria-bom:1.26.4", "com.squareup.okhttp3:okhttp-bom:4.12.0", "com.squareup.okio:okio-bom:3.6.0", // applies to transitive dependencies of okhttp "io.grpc:grpc-bom:1.60.0", From 3a6613f9a35981f1172c38853f50d6f8ba8c398b Mon Sep 17 00:00:00 2001 From: jack-berg <34418638+jack-berg@users.noreply.github.com> Date: Fri, 8 Dec 2023 13:57:04 -0600 Subject: [PATCH 148/901] Prepare for 1.33.0 release (#6065) --- CHANGELOG.md | 48 +++++++++++++++++++ .../OtlpHttpLogRecordExporterBuilder.java | 6 +++ .../OtlpHttpMetricExporterBuilder.java | 6 +++ .../trace/OtlpHttpSpanExporterBuilder.java | 6 +++ .../OtlpGrpcLogRecordExporterBuilder.java | 2 + .../OtlpGrpcMetricExporterBuilder.java | 2 + .../trace/OtlpGrpcSpanExporterBuilder.java | 2 + .../spi/AutoConfigurationCustomizer.java | 4 ++ .../testing/assertj/AbstractPointAssert.java | 6 ++- 9 files changed, 81 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c0039e5f114..ca6347b6b43 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,54 @@ ## Unreleased +### API + +* Fix issue where wrapping "invalid" SpanContexts in Span does not preserve SpanContext + ([#6044](https://github.com/open-telemetry/opentelemetry-java/pull/6044)) + +#### Incubator + +* Refactor and add to ExtendedTracer, add ExtendedContextPropagators + ([#6017](https://github.com/open-telemetry/opentelemetry-java/pull/6017)) +* Base64 encode AnyValue bytes in string representation + ([#6003](https://github.com/open-telemetry/opentelemetry-java/pull/6003)) + +### SDK + +#### Exporters + +* Add connectTimeout configuration option OtlpHttp{Signal}Exporters + ([#5941](https://github.com/open-telemetry/opentelemetry-java/pull/5941)) +* Add ability for Otlp{Protocol}LogRecordExporter to serialize log body any value + ([#5938](https://github.com/open-telemetry/opentelemetry-java/pull/5938)) +* Android environments can now handle base64 encoded PEM keys, remove exception handling in + TlsUtil#decodePem + ([#6034](https://github.com/open-telemetry/opentelemetry-java/pull/6034)) +* Add header supplier configuration option to OTLP exporters + ([#6004](https://github.com/open-telemetry/opentelemetry-java/pull/6004)) + + +#### Extensions + +* Add autoconfigure option for customizing SpanProcessor, LogRecordProcessor + ([#5986](https://github.com/open-telemetry/opentelemetry-java/pull/5986)) +* Incubator allows for simpler creation of start-only and end-only SpanProcessors. + ([#5923](https://github.com/open-telemetry/opentelemetry-java/pull/5923)) + +#### Testing + +* Add hasAttributesSatisfying overload to AbstractPointAssert + ([#6048](https://github.com/open-telemetry/opentelemetry-java/pull/6048)) + +### Project Tooling + +* Building animal sniffer signatures directly from android corelib + ([#5973](https://github.com/open-telemetry/opentelemetry-java/pull/5973)) +* Target kotlin 1.6 in kotlin extension + ([#5910](https://github.com/open-telemetry/opentelemetry-java/pull/5910)) +* Define language version compatibility requirements + ([#5983](https://github.com/open-telemetry/opentelemetry-java/pull/5983)) + ## Version 1.32.0 (2023-11-13) ### API diff --git a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/logs/OtlpHttpLogRecordExporterBuilder.java b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/logs/OtlpHttpLogRecordExporterBuilder.java index 9b8a52df9c3..59a84e76e72 100644 --- a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/logs/OtlpHttpLogRecordExporterBuilder.java +++ b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/logs/OtlpHttpLogRecordExporterBuilder.java @@ -64,6 +64,8 @@ public OtlpHttpLogRecordExporterBuilder setTimeout(Duration timeout) { /** * Sets the maximum time to wait for new connections to be established. If unset, defaults to * {@value HttpExporterBuilder#DEFAULT_CONNECT_TIMEOUT_SECS}s. + * + * @since 1.33.0 */ public OtlpHttpLogRecordExporterBuilder setConnectTimeout(long timeout, TimeUnit unit) { requireNonNull(unit, "unit"); @@ -75,6 +77,8 @@ public OtlpHttpLogRecordExporterBuilder setConnectTimeout(long timeout, TimeUnit /** * Sets the maximum time to wait for new connections to be established. If unset, defaults to * {@value HttpExporterBuilder#DEFAULT_CONNECT_TIMEOUT_SECS}s. + * + * @since 1.33.0 */ public OtlpHttpLogRecordExporterBuilder setConnectTimeout(Duration timeout) { requireNonNull(timeout, "timeout"); @@ -116,6 +120,8 @@ public OtlpHttpLogRecordExporterBuilder addHeader(String key, String value) { /** * Set the supplier of headers to add to requests. If a key from the map collides with a constant * from {@link #addHeader(String, String)}, the values from both are included. + * + * @since 1.33.0 */ public OtlpHttpLogRecordExporterBuilder setHeaders(Supplier> headerSupplier) { delegate.setHeadersSupplier(headerSupplier); diff --git a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/metrics/OtlpHttpMetricExporterBuilder.java b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/metrics/OtlpHttpMetricExporterBuilder.java index d31a510b251..5d573da557e 100644 --- a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/metrics/OtlpHttpMetricExporterBuilder.java +++ b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/metrics/OtlpHttpMetricExporterBuilder.java @@ -76,6 +76,8 @@ public OtlpHttpMetricExporterBuilder setTimeout(Duration timeout) { /** * Sets the maximum time to wait for new connections to be established. If unset, defaults to * {@value HttpExporterBuilder#DEFAULT_CONNECT_TIMEOUT_SECS}s. + * + * @since 1.33.0 */ public OtlpHttpMetricExporterBuilder setConnectTimeout(long timeout, TimeUnit unit) { requireNonNull(unit, "unit"); @@ -87,6 +89,8 @@ public OtlpHttpMetricExporterBuilder setConnectTimeout(long timeout, TimeUnit un /** * Sets the maximum time to wait for new connections to be established. If unset, defaults to * {@value HttpExporterBuilder#DEFAULT_CONNECT_TIMEOUT_SECS}s. + * + * @since 1.33.0 */ public OtlpHttpMetricExporterBuilder setConnectTimeout(Duration timeout) { requireNonNull(timeout, "timeout"); @@ -128,6 +132,8 @@ public OtlpHttpMetricExporterBuilder addHeader(String key, String value) { /** * Set the supplier of headers to add to requests. If a key from the map collides with a constant * from {@link #addHeader(String, String)}, the values from both are included. + * + * @since 1.33.0 */ public OtlpHttpMetricExporterBuilder setHeaders(Supplier> headerSupplier) { delegate.setHeadersSupplier(headerSupplier); diff --git a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/trace/OtlpHttpSpanExporterBuilder.java b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/trace/OtlpHttpSpanExporterBuilder.java index 96cf2c2a2f4..58768c98881 100644 --- a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/trace/OtlpHttpSpanExporterBuilder.java +++ b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/trace/OtlpHttpSpanExporterBuilder.java @@ -64,6 +64,8 @@ public OtlpHttpSpanExporterBuilder setTimeout(Duration timeout) { /** * Sets the maximum time to wait for new connections to be established. If unset, defaults to * {@value HttpExporterBuilder#DEFAULT_CONNECT_TIMEOUT_SECS}s. + * + * @since 1.33.0 */ public OtlpHttpSpanExporterBuilder setConnectTimeout(long timeout, TimeUnit unit) { requireNonNull(unit, "unit"); @@ -75,6 +77,8 @@ public OtlpHttpSpanExporterBuilder setConnectTimeout(long timeout, TimeUnit unit /** * Sets the maximum time to wait for new connections to be established. If unset, defaults to * {@value HttpExporterBuilder#DEFAULT_CONNECT_TIMEOUT_SECS}s. + * + * @since 1.33.0 */ public OtlpHttpSpanExporterBuilder setConnectTimeout(Duration timeout) { requireNonNull(timeout, "timeout"); @@ -116,6 +120,8 @@ public OtlpHttpSpanExporterBuilder addHeader(String key, String value) { /** * Set the supplier of headers to add to requests. If a key from the map collides with a constant * from {@link #addHeader(String, String)}, the values from both are included. + * + * @since 1.33.0 */ public OtlpHttpSpanExporterBuilder setHeaders(Supplier> headerSupplier) { delegate.setHeadersSupplier(headerSupplier); diff --git a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/logs/OtlpGrpcLogRecordExporterBuilder.java b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/logs/OtlpGrpcLogRecordExporterBuilder.java index 2fd6cdb5000..b04014fc729 100644 --- a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/logs/OtlpGrpcLogRecordExporterBuilder.java +++ b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/logs/OtlpGrpcLogRecordExporterBuilder.java @@ -170,6 +170,8 @@ public OtlpGrpcLogRecordExporterBuilder addHeader(String key, String value) { * Set the supplier of headers to add to requests. If a key from the map collides with a constant * from {@link #addHeader(String, String)}, the values from both are included. Applicable only if * {@link OtlpGrpcLogRecordExporterBuilder#setChannel(ManagedChannel)} is not used to set channel. + * + * @since 1.33.0 */ public OtlpGrpcLogRecordExporterBuilder setHeaders(Supplier> headerSupplier) { delegate.setHeadersSupplier(headerSupplier); diff --git a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/metrics/OtlpGrpcMetricExporterBuilder.java b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/metrics/OtlpGrpcMetricExporterBuilder.java index 00e4bcabd2e..43a0dbdcc41 100644 --- a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/metrics/OtlpGrpcMetricExporterBuilder.java +++ b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/metrics/OtlpGrpcMetricExporterBuilder.java @@ -183,6 +183,8 @@ public OtlpGrpcMetricExporterBuilder addHeader(String key, String value) { * Set the supplier of headers to add to requests. If a key from the map collides with a constant * from {@link #addHeader(String, String)}, the values from both are included. Applicable only if * {@link OtlpGrpcMetricExporterBuilder#setChannel(ManagedChannel)} is not used to set channel. + * + * @since 1.33.0 */ public OtlpGrpcMetricExporterBuilder setHeaders(Supplier> headerSupplier) { delegate.setHeadersSupplier(headerSupplier); diff --git a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/trace/OtlpGrpcSpanExporterBuilder.java b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/trace/OtlpGrpcSpanExporterBuilder.java index c3e286b5a22..884a8dea172 100644 --- a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/trace/OtlpGrpcSpanExporterBuilder.java +++ b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/trace/OtlpGrpcSpanExporterBuilder.java @@ -167,6 +167,8 @@ public OtlpGrpcSpanExporterBuilder addHeader(String key, String value) { * Set the supplier of headers to add to requests. If a key from the map collides with a constant * from {@link #addHeader(String, String)}, the values from both are included. Applicable only if * {@link OtlpGrpcSpanExporterBuilder#setChannel(ManagedChannel)} is not used to set channel. + * + * @since 1.33.0 */ public OtlpGrpcSpanExporterBuilder setHeaders(Supplier> headerSupplier) { delegate.setHeadersSupplier(headerSupplier); diff --git a/sdk-extensions/autoconfigure-spi/src/main/java/io/opentelemetry/sdk/autoconfigure/spi/AutoConfigurationCustomizer.java b/sdk-extensions/autoconfigure-spi/src/main/java/io/opentelemetry/sdk/autoconfigure/spi/AutoConfigurationCustomizer.java index e49ab220875..03edca120bc 100644 --- a/sdk-extensions/autoconfigure-spi/src/main/java/io/opentelemetry/sdk/autoconfigure/spi/AutoConfigurationCustomizer.java +++ b/sdk-extensions/autoconfigure-spi/src/main/java/io/opentelemetry/sdk/autoconfigure/spi/AutoConfigurationCustomizer.java @@ -73,6 +73,8 @@ AutoConfigurationCustomizer addSpanExporterCustomizer( * delayed data. * *

    Multiple calls will execute the customizers in order. + * + * @since 1.33.0 */ default AutoConfigurationCustomizer addSpanProcessorCustomizer( BiFunction @@ -192,6 +194,8 @@ default AutoConfigurationCustomizer addLogRecordExporterCustomizer( * logs or delay logs for enhancing them with external, delayed data. * *

    Multiple calls will execute the customizers in order. + * + * @since 1.33.0 */ default AutoConfigurationCustomizer addLogRecordProcessorCustomizer( BiFunction diff --git a/sdk/testing/src/main/java/io/opentelemetry/sdk/testing/assertj/AbstractPointAssert.java b/sdk/testing/src/main/java/io/opentelemetry/sdk/testing/assertj/AbstractPointAssert.java index 0a3425958e0..41da09a10e5 100644 --- a/sdk/testing/src/main/java/io/opentelemetry/sdk/testing/assertj/AbstractPointAssert.java +++ b/sdk/testing/src/main/java/io/opentelemetry/sdk/testing/assertj/AbstractPointAssert.java @@ -112,7 +112,11 @@ public final PointAssertT hasAttributesSatisfying(Iterable a return myself; } - /** Asserts the point has attributes satisfying the given condition. */ + /** + * Asserts the point has attributes satisfying the given condition. + * + * @since 1.33.0 + */ public final PointAssertT hasAttributesSatisfying(Consumer attributes) { isNotNull(); assertThat(actual.getAttributes()).as("attributes").satisfies(attributes); From 3086418d625cc25dddbd14d48615075ba446342f Mon Sep 17 00:00:00 2001 From: OpenTelemetry Bot <107717825+opentelemetrybot@users.noreply.github.com> Date: Fri, 8 Dec 2023 21:21:43 +0100 Subject: [PATCH 149/901] Update version to 1.34.0 (#6067) --- CHANGELOG.md | 2 ++ version.gradle.kts | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ca6347b6b43..be0063fb05b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,8 @@ ## Unreleased +## Version 1.33.0 (2023-12-08) + ### API * Fix issue where wrapping "invalid" SpanContexts in Span does not preserve SpanContext diff --git a/version.gradle.kts b/version.gradle.kts index 3c385255433..8c54ed12381 100644 --- a/version.gradle.kts +++ b/version.gradle.kts @@ -1,7 +1,7 @@ val snapshot = true allprojects { - var ver = "1.33.0" + var ver = "1.34.0" val release = findProperty("otel.release") if (release != null) { ver += "-" + release From 6e536238df5989fb100b198d91fdf733fa5ae5f6 Mon Sep 17 00:00:00 2001 From: jack-berg <34418638+jack-berg@users.noreply.github.com> Date: Fri, 8 Dec 2023 21:50:39 -0600 Subject: [PATCH 150/901] Post release 1.33.0 (#6068) --- README.md | 76 +++++++++---------- .../1.33.0_vs_1.32.0/opentelemetry-api.txt | 2 + .../opentelemetry-context.txt | 2 + .../opentelemetry-exporter-common.txt | 2 + .../opentelemetry-exporter-jaeger-thrift.txt | 2 + .../opentelemetry-exporter-jaeger.txt | 2 + .../opentelemetry-exporter-logging-otlp.txt | 2 + .../opentelemetry-exporter-logging.txt | 2 + .../opentelemetry-exporter-otlp-common.txt | 2 + .../opentelemetry-exporter-otlp.txt | 25 ++++++ ...y-exporter-sender-grpc-managed-channel.txt | 2 + .../opentelemetry-exporter-sender-okhttp.txt | 2 + .../opentelemetry-exporter-zipkin.txt | 2 + .../opentelemetry-extension-kotlin.txt | 9 +++ ...ntelemetry-extension-trace-propagators.txt | 2 + .../opentelemetry-opentracing-shim.txt | 2 + .../opentelemetry-sdk-common.txt | 2 + ...emetry-sdk-extension-autoconfigure-spi.txt | 5 ++ ...ntelemetry-sdk-extension-autoconfigure.txt | 5 ++ ...ry-sdk-extension-jaeger-remote-sampler.txt | 2 + .../opentelemetry-sdk-logs.txt | 2 + .../opentelemetry-sdk-metrics.txt | 2 + .../opentelemetry-sdk-testing.txt | 5 ++ .../opentelemetry-sdk-trace.txt | 2 + .../1.33.0_vs_1.32.0/opentelemetry-sdk.txt | 2 + .../opentelemetry-exporter-otlp.txt | 25 +----- .../opentelemetry-extension-kotlin.txt | 9 +-- ...emetry-sdk-extension-autoconfigure-spi.txt | 5 +- ...ntelemetry-sdk-extension-autoconfigure.txt | 5 +- .../opentelemetry-sdk-testing.txt | 5 +- 30 files changed, 130 insertions(+), 82 deletions(-) create mode 100644 docs/apidiffs/1.33.0_vs_1.32.0/opentelemetry-api.txt create mode 100644 docs/apidiffs/1.33.0_vs_1.32.0/opentelemetry-context.txt create mode 100644 docs/apidiffs/1.33.0_vs_1.32.0/opentelemetry-exporter-common.txt create mode 100644 docs/apidiffs/1.33.0_vs_1.32.0/opentelemetry-exporter-jaeger-thrift.txt create mode 100644 docs/apidiffs/1.33.0_vs_1.32.0/opentelemetry-exporter-jaeger.txt create mode 100644 docs/apidiffs/1.33.0_vs_1.32.0/opentelemetry-exporter-logging-otlp.txt create mode 100644 docs/apidiffs/1.33.0_vs_1.32.0/opentelemetry-exporter-logging.txt create mode 100644 docs/apidiffs/1.33.0_vs_1.32.0/opentelemetry-exporter-otlp-common.txt create mode 100644 docs/apidiffs/1.33.0_vs_1.32.0/opentelemetry-exporter-otlp.txt create mode 100644 docs/apidiffs/1.33.0_vs_1.32.0/opentelemetry-exporter-sender-grpc-managed-channel.txt create mode 100644 docs/apidiffs/1.33.0_vs_1.32.0/opentelemetry-exporter-sender-okhttp.txt create mode 100644 docs/apidiffs/1.33.0_vs_1.32.0/opentelemetry-exporter-zipkin.txt create mode 100644 docs/apidiffs/1.33.0_vs_1.32.0/opentelemetry-extension-kotlin.txt create mode 100644 docs/apidiffs/1.33.0_vs_1.32.0/opentelemetry-extension-trace-propagators.txt create mode 100644 docs/apidiffs/1.33.0_vs_1.32.0/opentelemetry-opentracing-shim.txt create mode 100644 docs/apidiffs/1.33.0_vs_1.32.0/opentelemetry-sdk-common.txt create mode 100644 docs/apidiffs/1.33.0_vs_1.32.0/opentelemetry-sdk-extension-autoconfigure-spi.txt create mode 100644 docs/apidiffs/1.33.0_vs_1.32.0/opentelemetry-sdk-extension-autoconfigure.txt create mode 100644 docs/apidiffs/1.33.0_vs_1.32.0/opentelemetry-sdk-extension-jaeger-remote-sampler.txt create mode 100644 docs/apidiffs/1.33.0_vs_1.32.0/opentelemetry-sdk-logs.txt create mode 100644 docs/apidiffs/1.33.0_vs_1.32.0/opentelemetry-sdk-metrics.txt create mode 100644 docs/apidiffs/1.33.0_vs_1.32.0/opentelemetry-sdk-testing.txt create mode 100644 docs/apidiffs/1.33.0_vs_1.32.0/opentelemetry-sdk-trace.txt create mode 100644 docs/apidiffs/1.33.0_vs_1.32.0/opentelemetry-sdk.txt diff --git a/README.md b/README.md index e14f66c7fc6..68e72d15953 100644 --- a/README.md +++ b/README.md @@ -102,7 +102,7 @@ dependency versions in sync. io.opentelemetry opentelemetry-bom - 1.32.0 + 1.33.0 pom import @@ -121,7 +121,7 @@ dependency versions in sync. ```groovy dependencies { - implementation platform("io.opentelemetry:opentelemetry-bom:1.32.0") + implementation platform("io.opentelemetry:opentelemetry-bom:1.33.0") implementation('io.opentelemetry:opentelemetry-api') } ``` @@ -130,8 +130,8 @@ Note that if you want to use any artifacts that have not fully stabilized yet (s ```groovy dependencies { - implementation platform("io.opentelemetry:opentelemetry-bom:1.32.0") - implementation platform('io.opentelemetry:opentelemetry-bom-alpha:1.32.0-alpha') + implementation platform("io.opentelemetry:opentelemetry-bom:1.33.0") + implementation platform('io.opentelemetry:opentelemetry-bom-alpha:1.33.0-alpha') implementation('io.opentelemetry:opentelemetry-api') implementation('io.opentelemetry:opentelemetry-exporter-prometheus') @@ -159,7 +159,7 @@ We strongly recommend using our published BOM to keep all dependency versions in io.opentelemetry opentelemetry-bom - 1.33.0-SNAPSHOT + 1.34.0-SNAPSHOT pom import @@ -182,7 +182,7 @@ repositories { } dependencies { - implementation platform("io.opentelemetry:opentelemetry-bom:1.33.0-SNAPSHOT") + implementation platform("io.opentelemetry:opentelemetry-bom:1.34.0-SNAPSHOT") implementation('io.opentelemetry:opentelemetry-api') } ``` @@ -227,53 +227,53 @@ dependency as follows, replacing `{{artifact-id}}` with the value from the "Arti | Component | Description | Artifact ID | Version | Javadoc | |----------------------------------------------|----------------------------------------|---------------------------|-------------------------------------------------------------|---------| -| [Bill of Materials (BOM)](./bom) | Bill of materials for stable artifacts | `opentelemetry-bom` | 1.32.0 | N/A | -| [Alpha Bill of Materials (BOM)](./bom-alpha) | Bill of materials for alpha artifacts | `opentelemetry-bom-alpha` | 1.32.0-alpha | N/A | +| [Bill of Materials (BOM)](./bom) | Bill of materials for stable artifacts | `opentelemetry-bom` | 1.33.0 | N/A | +| [Alpha Bill of Materials (BOM)](./bom-alpha) | Bill of materials for alpha artifacts | `opentelemetry-bom-alpha` | 1.33.0-alpha | N/A | ### API | Component | Description | Artifact ID | Version | Javadoc | |-----------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|----------------------------|-------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------| -| [API](./api/all) | OpenTelemetry API, including metrics, traces, baggage, context | `opentelemetry-api` | 1.32.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-api.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-api) | -| [Events API](./api/events) | OpenTelemetry Event API for emitting events. | `opentelemetry-api-events` | 1.32.0-alpha | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-api-events.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-api-events) | -| [Context API](./context) | OpenTelemetry context API | `opentelemetry-context` | 1.32.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-context.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-context) | +| [API](./api/all) | OpenTelemetry API, including metrics, traces, baggage, context | `opentelemetry-api` | 1.33.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-api.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-api) | +| [Events API](./api/events) | OpenTelemetry Event API for emitting events. | `opentelemetry-api-events` | 1.33.0-alpha | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-api-events.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-api-events) | +| [Context API](./context) | OpenTelemetry context API | `opentelemetry-context` | 1.33.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-context.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-context) | ### API Extensions | Component | Description | Artifact ID | Version | Javadoc | |---------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|---------------------------------------------|-------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| [Kotlin Extension](./extensions/kotlin) | Context extension for coroutines | `opentelemetry-extension-kotlin` | 1.32.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-extension-kotlin.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-extension-kotlin) | -| [Trace Propagators Extension](./extensions/trace-propagators) | Trace propagators, including B3, Jaeger, OT Trace | `opentelemetry-extension-trace-propagators` | 1.32.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-extension-trace-propagators.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-extension-trace-propagators) | -| [Incubator Extension](./extensions/incubator) | API incubator, including pass through propagator, and extended tracer | `opentelemetry-extension-incubator` | 1.32.0-alpha | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-extension-incubator.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-extension-incubator) | +| [Kotlin Extension](./extensions/kotlin) | Context extension for coroutines | `opentelemetry-extension-kotlin` | 1.33.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-extension-kotlin.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-extension-kotlin) | +| [Trace Propagators Extension](./extensions/trace-propagators) | Trace propagators, including B3, Jaeger, OT Trace | `opentelemetry-extension-trace-propagators` | 1.33.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-extension-trace-propagators.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-extension-trace-propagators) | +| [Incubator Extension](./extensions/incubator) | API incubator, including pass through propagator, and extended tracer | `opentelemetry-extension-incubator` | 1.33.0-alpha | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-extension-incubator.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-extension-incubator) | ### SDK | Component | Description | Artifact ID | Version | Javadoc | |------------------------------|--------------------------------------------------------|-----------------------------|---------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| [SDK](./sdk/all) | OpenTelemetry SDK, including metrics, traces, and logs | `opentelemetry-sdk` | 1.32.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk) | -| [Metrics SDK](./sdk/metrics) | OpenTelemetry metrics SDK | `opentelemetry-sdk-metrics` | 1.32.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-metrics.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-metrics) | -| [Trace SDK](./sdk/trace) | OpenTelemetry trace SDK | `opentelemetry-sdk-trace` | 1.32.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-trace.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-trace) | -| [Log SDK](./sdk/logs) | OpenTelemetry log SDK | `opentelemetry-sdk-logs` | 1.32.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-logs.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-logs) | -| [SDK Common](./sdk/common) | Shared SDK components | `opentelemetry-sdk-common` | 1.32.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-common.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-common) | -| [SDK Testing](./sdk/testing) | Components for testing OpenTelemetry instrumentation | `opentelemetry-sdk-testing` | 1.32.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-testing.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-testing) | +| [SDK](./sdk/all) | OpenTelemetry SDK, including metrics, traces, and logs | `opentelemetry-sdk` | 1.33.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk) | +| [Metrics SDK](./sdk/metrics) | OpenTelemetry metrics SDK | `opentelemetry-sdk-metrics` | 1.33.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-metrics.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-metrics) | +| [Trace SDK](./sdk/trace) | OpenTelemetry trace SDK | `opentelemetry-sdk-trace` | 1.33.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-trace.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-trace) | +| [Log SDK](./sdk/logs) | OpenTelemetry log SDK | `opentelemetry-sdk-logs` | 1.33.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-logs.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-logs) | +| [SDK Common](./sdk/common) | Shared SDK components | `opentelemetry-sdk-common` | 1.33.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-common.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-common) | +| [SDK Testing](./sdk/testing) | Components for testing OpenTelemetry instrumentation | `opentelemetry-sdk-testing` | 1.33.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-testing.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-testing) | ### SDK Exporters | Component | Description | Artifact ID | Version | Javadoc | |-----------------------------------------------------------------------|------------------------------------------------------------------------------|------------------------------------------------------|-------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| [OTLP Exporters](./exporters/otlp/all) | OTLP gRPC & HTTP exporters, including traces, metrics, and logs | `opentelemetry-exporter-otlp` | 1.32.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-otlp.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-otlp) | -| [OTLP Logging Exporters](./exporters/logging-otlp) | Logging exporters in OTLP JSON encoding, including traces, metrics, and logs | `opentelemetry-exporter-logging-otlp` | 1.32.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-logging-otlp.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-logging-otlp) | -| [OTLP Common](./exporters/otlp/common) | Shared OTLP components (internal) | `opentelemetry-exporter-otlp-common` | 1.32.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-otlp-common.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-otlp-common) | -| [Jaeger gRPC Exporter](./exporters/jaeger) | Jaeger gRPC trace exporter (deprecated [1]) | `opentelemetry-exporter-jaeger` | 1.32.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-jaeger.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-jaeger) | -| [Jaeger Thrift Exporter](./exporters/jaeger-thrift) | Jaeger thrift trace exporter (deprecated [1]) | `opentelemetry-exporter-jaeger-thift` | 1.32.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-jaeger-thrift.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-jaeger-thrift) | -| [Logging Exporter](./exporters/logging) | Logging exporters, including metrics, traces, and logs | `opentelemetry-exporter-logging` | 1.32.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-logging.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-logging) | -| [Zipkin Exporter](./exporters/zipkin) | Zipkin trace exporter | `opentelemetry-exporter-zipkin` | 1.32.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-zipkin.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-zipkin) | -| [Prometheus Exporter](./exporters/prometheus) | Prometheus metric exporter | `opentelemetry-exporter-prometheus` | 1.32.0-alpha | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-prometheus.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-prometheus) | -| [Exporter Common](./exporters/common) | Shared exporter components (internal) | `opentelemetry-exporter-common` | 1.32.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-common.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-common) | -| [OkHttp Sender](./exporters/sender/okhttp) | OkHttp implementation of HttpSender (internal) | `opentelemetry-exporter-sender-okhttp` | 1.32.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-sender-okhttp.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-sender-okhttp) | -| [JDK Sender](./exporters/sender/okhttp) | Java 11+ native HttpClient implementation of HttpSender (internal) | `opentelemetry-exporter-sender-jdk` | 1.32.0-alpha | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-sender-jdk.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-sender-jdk) | | -| [gRPC ManagedChannel Sender](./exporters/sender/grpc-managed-channel) | gRPC ManagedChannel implementation of GrpcSender (internal) | `opentelemetry-exporter-sender-grpc-managed-channel` | 1.32.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-sender-grpc-managed-channel.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-sender-grpc-managed-channel) | | +| [OTLP Exporters](./exporters/otlp/all) | OTLP gRPC & HTTP exporters, including traces, metrics, and logs | `opentelemetry-exporter-otlp` | 1.33.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-otlp.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-otlp) | +| [OTLP Logging Exporters](./exporters/logging-otlp) | Logging exporters in OTLP JSON encoding, including traces, metrics, and logs | `opentelemetry-exporter-logging-otlp` | 1.33.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-logging-otlp.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-logging-otlp) | +| [OTLP Common](./exporters/otlp/common) | Shared OTLP components (internal) | `opentelemetry-exporter-otlp-common` | 1.33.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-otlp-common.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-otlp-common) | +| [Jaeger gRPC Exporter](./exporters/jaeger) | Jaeger gRPC trace exporter (deprecated [1]) | `opentelemetry-exporter-jaeger` | 1.33.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-jaeger.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-jaeger) | +| [Jaeger Thrift Exporter](./exporters/jaeger-thrift) | Jaeger thrift trace exporter (deprecated [1]) | `opentelemetry-exporter-jaeger-thift` | 1.33.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-jaeger-thrift.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-jaeger-thrift) | +| [Logging Exporter](./exporters/logging) | Logging exporters, including metrics, traces, and logs | `opentelemetry-exporter-logging` | 1.33.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-logging.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-logging) | +| [Zipkin Exporter](./exporters/zipkin) | Zipkin trace exporter | `opentelemetry-exporter-zipkin` | 1.33.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-zipkin.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-zipkin) | +| [Prometheus Exporter](./exporters/prometheus) | Prometheus metric exporter | `opentelemetry-exporter-prometheus` | 1.33.0-alpha | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-prometheus.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-prometheus) | +| [Exporter Common](./exporters/common) | Shared exporter components (internal) | `opentelemetry-exporter-common` | 1.33.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-common.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-common) | +| [OkHttp Sender](./exporters/sender/okhttp) | OkHttp implementation of HttpSender (internal) | `opentelemetry-exporter-sender-okhttp` | 1.33.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-sender-okhttp.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-sender-okhttp) | +| [JDK Sender](./exporters/sender/okhttp) | Java 11+ native HttpClient implementation of HttpSender (internal) | `opentelemetry-exporter-sender-jdk` | 1.33.0-alpha | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-sender-jdk.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-sender-jdk) | | +| [gRPC ManagedChannel Sender](./exporters/sender/grpc-managed-channel) | gRPC ManagedChannel implementation of GrpcSender (internal) | `opentelemetry-exporter-sender-grpc-managed-channel` | 1.33.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-sender-grpc-managed-channel.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-sender-grpc-managed-channel) | | **[1]**: Jaeger now has [native support for OTLP](https://opentelemetry.io/blog/2022/jaeger-native-otlp/) and jaeger @@ -286,17 +286,17 @@ additional versions will be published. | Component | Description | Artifact ID | Version | Javadoc | |-------------------------------------------------------------------------------|------------------------------------------------------------------------------------|-----------------------------------------------------|-------------------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| [SDK Autoconfigure](./sdk-extensions/autoconfigure) | Autoconfigure OpenTelemetry SDK from env vars, system properties, and SPI | `opentelemetry-sdk-extension-autoconfigure` | 1.32.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-extension-autoconfigure.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-extension-autoconfigure) | -| [SDK Autoconfigure SPI](./sdk-extensions/autoconfigure-spi) | Service Provider Interface (SPI) definitions for autoconfigure | `opentelemetry-sdk-extension-autoconfigure-spi` | 1.32.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-extension-autoconfigure-spi.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-extension-autoconfigure-spi) | -| [SDK Jaeger Remote Sampler Extension](./sdk-extensions/jaeger-remote-sampler) | Sampler which obtains sampling configuration from remote Jaeger server | `opentelemetry-sdk-extension-jaeger-remote-sampler` | 1.32.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-extension-jaeger-remote-sampler.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-extension-jaeger-remote-sampler) | -| [SDK Incubator](./sdk-extensions/incubator) | SDK incubator, including YAML based view configuration, LeakDetectingSpanProcessor | `opentelemetry-sdk-extension-incubator` | 1.32.0-alpha | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-extension-incubator.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-extension-incubator) | +| [SDK Autoconfigure](./sdk-extensions/autoconfigure) | Autoconfigure OpenTelemetry SDK from env vars, system properties, and SPI | `opentelemetry-sdk-extension-autoconfigure` | 1.33.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-extension-autoconfigure.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-extension-autoconfigure) | +| [SDK Autoconfigure SPI](./sdk-extensions/autoconfigure-spi) | Service Provider Interface (SPI) definitions for autoconfigure | `opentelemetry-sdk-extension-autoconfigure-spi` | 1.33.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-extension-autoconfigure-spi.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-extension-autoconfigure-spi) | +| [SDK Jaeger Remote Sampler Extension](./sdk-extensions/jaeger-remote-sampler) | Sampler which obtains sampling configuration from remote Jaeger server | `opentelemetry-sdk-extension-jaeger-remote-sampler` | 1.33.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-extension-jaeger-remote-sampler.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-extension-jaeger-remote-sampler) | +| [SDK Incubator](./sdk-extensions/incubator) | SDK incubator, including YAML based view configuration, LeakDetectingSpanProcessor | `opentelemetry-sdk-extension-incubator` | 1.33.0-alpha | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-extension-incubator.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-extension-incubator) | ### Shims | Component | Description | Artifact ID | Version | Javadoc | |----------------------------------------|--------------------------------------------------------------|----------------------------------|-------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| [OpenCensus Shim](./opencensus-shim) | Bridge opencensus metrics into the OpenTelemetry metrics SDK | `opentelemetry-opencensus-shim` | 1.32.0-alpha | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-opencensus-shim.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-opencensus-shim) | -| [OpenTracing Shim](./opentracing-shim) | Bridge opentracing spans into the OpenTelemetry trace API | `opentelemetry-opentracing-shim` | 1.32.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-opentracing-shim.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-opentracing-shim) | +| [OpenCensus Shim](./opencensus-shim) | Bridge opencensus metrics into the OpenTelemetry metrics SDK | `opentelemetry-opencensus-shim` | 1.33.0-alpha | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-opencensus-shim.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-opencensus-shim) | +| [OpenTracing Shim](./opentracing-shim) | Bridge opentracing spans into the OpenTelemetry trace API | `opentelemetry-opentracing-shim` | 1.33.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-opentracing-shim.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-opentracing-shim) | ## Contributing diff --git a/docs/apidiffs/1.33.0_vs_1.32.0/opentelemetry-api.txt b/docs/apidiffs/1.33.0_vs_1.32.0/opentelemetry-api.txt new file mode 100644 index 00000000000..df26146497b --- /dev/null +++ b/docs/apidiffs/1.33.0_vs_1.32.0/opentelemetry-api.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of against +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.33.0_vs_1.32.0/opentelemetry-context.txt b/docs/apidiffs/1.33.0_vs_1.32.0/opentelemetry-context.txt new file mode 100644 index 00000000000..df26146497b --- /dev/null +++ b/docs/apidiffs/1.33.0_vs_1.32.0/opentelemetry-context.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of against +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.33.0_vs_1.32.0/opentelemetry-exporter-common.txt b/docs/apidiffs/1.33.0_vs_1.32.0/opentelemetry-exporter-common.txt new file mode 100644 index 00000000000..df26146497b --- /dev/null +++ b/docs/apidiffs/1.33.0_vs_1.32.0/opentelemetry-exporter-common.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of against +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.33.0_vs_1.32.0/opentelemetry-exporter-jaeger-thrift.txt b/docs/apidiffs/1.33.0_vs_1.32.0/opentelemetry-exporter-jaeger-thrift.txt new file mode 100644 index 00000000000..df26146497b --- /dev/null +++ b/docs/apidiffs/1.33.0_vs_1.32.0/opentelemetry-exporter-jaeger-thrift.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of against +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.33.0_vs_1.32.0/opentelemetry-exporter-jaeger.txt b/docs/apidiffs/1.33.0_vs_1.32.0/opentelemetry-exporter-jaeger.txt new file mode 100644 index 00000000000..df26146497b --- /dev/null +++ b/docs/apidiffs/1.33.0_vs_1.32.0/opentelemetry-exporter-jaeger.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of against +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.33.0_vs_1.32.0/opentelemetry-exporter-logging-otlp.txt b/docs/apidiffs/1.33.0_vs_1.32.0/opentelemetry-exporter-logging-otlp.txt new file mode 100644 index 00000000000..df26146497b --- /dev/null +++ b/docs/apidiffs/1.33.0_vs_1.32.0/opentelemetry-exporter-logging-otlp.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of against +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.33.0_vs_1.32.0/opentelemetry-exporter-logging.txt b/docs/apidiffs/1.33.0_vs_1.32.0/opentelemetry-exporter-logging.txt new file mode 100644 index 00000000000..df26146497b --- /dev/null +++ b/docs/apidiffs/1.33.0_vs_1.32.0/opentelemetry-exporter-logging.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of against +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.33.0_vs_1.32.0/opentelemetry-exporter-otlp-common.txt b/docs/apidiffs/1.33.0_vs_1.32.0/opentelemetry-exporter-otlp-common.txt new file mode 100644 index 00000000000..df26146497b --- /dev/null +++ b/docs/apidiffs/1.33.0_vs_1.32.0/opentelemetry-exporter-otlp-common.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of against +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.33.0_vs_1.32.0/opentelemetry-exporter-otlp.txt b/docs/apidiffs/1.33.0_vs_1.32.0/opentelemetry-exporter-otlp.txt new file mode 100644 index 00000000000..7c0ed9b5e5f --- /dev/null +++ b/docs/apidiffs/1.33.0_vs_1.32.0/opentelemetry-exporter-otlp.txt @@ -0,0 +1,25 @@ +Comparing source compatibility of against +*** MODIFIED CLASS: PUBLIC FINAL io.opentelemetry.exporter.otlp.http.logs.OtlpHttpLogRecordExporterBuilder (not serializable) + === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 + +++ NEW METHOD: PUBLIC(+) io.opentelemetry.exporter.otlp.http.logs.OtlpHttpLogRecordExporterBuilder setConnectTimeout(long, java.util.concurrent.TimeUnit) + +++ NEW METHOD: PUBLIC(+) io.opentelemetry.exporter.otlp.http.logs.OtlpHttpLogRecordExporterBuilder setConnectTimeout(java.time.Duration) + +++ NEW METHOD: PUBLIC(+) io.opentelemetry.exporter.otlp.http.logs.OtlpHttpLogRecordExporterBuilder setHeaders(java.util.function.Supplier>) +*** MODIFIED CLASS: PUBLIC FINAL io.opentelemetry.exporter.otlp.http.metrics.OtlpHttpMetricExporterBuilder (not serializable) + === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 + +++ NEW METHOD: PUBLIC(+) io.opentelemetry.exporter.otlp.http.metrics.OtlpHttpMetricExporterBuilder setConnectTimeout(long, java.util.concurrent.TimeUnit) + +++ NEW METHOD: PUBLIC(+) io.opentelemetry.exporter.otlp.http.metrics.OtlpHttpMetricExporterBuilder setConnectTimeout(java.time.Duration) + +++ NEW METHOD: PUBLIC(+) io.opentelemetry.exporter.otlp.http.metrics.OtlpHttpMetricExporterBuilder setHeaders(java.util.function.Supplier>) +*** MODIFIED CLASS: PUBLIC FINAL io.opentelemetry.exporter.otlp.http.trace.OtlpHttpSpanExporterBuilder (not serializable) + === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 + +++ NEW METHOD: PUBLIC(+) io.opentelemetry.exporter.otlp.http.trace.OtlpHttpSpanExporterBuilder setConnectTimeout(long, java.util.concurrent.TimeUnit) + +++ NEW METHOD: PUBLIC(+) io.opentelemetry.exporter.otlp.http.trace.OtlpHttpSpanExporterBuilder setConnectTimeout(java.time.Duration) + +++ NEW METHOD: PUBLIC(+) io.opentelemetry.exporter.otlp.http.trace.OtlpHttpSpanExporterBuilder setHeaders(java.util.function.Supplier>) +*** MODIFIED CLASS: PUBLIC FINAL io.opentelemetry.exporter.otlp.logs.OtlpGrpcLogRecordExporterBuilder (not serializable) + === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 + +++ NEW METHOD: PUBLIC(+) io.opentelemetry.exporter.otlp.logs.OtlpGrpcLogRecordExporterBuilder setHeaders(java.util.function.Supplier>) +*** MODIFIED CLASS: PUBLIC FINAL io.opentelemetry.exporter.otlp.metrics.OtlpGrpcMetricExporterBuilder (not serializable) + === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 + +++ NEW METHOD: PUBLIC(+) io.opentelemetry.exporter.otlp.metrics.OtlpGrpcMetricExporterBuilder setHeaders(java.util.function.Supplier>) +*** MODIFIED CLASS: PUBLIC FINAL io.opentelemetry.exporter.otlp.trace.OtlpGrpcSpanExporterBuilder (not serializable) + === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 + +++ NEW METHOD: PUBLIC(+) io.opentelemetry.exporter.otlp.trace.OtlpGrpcSpanExporterBuilder setHeaders(java.util.function.Supplier>) diff --git a/docs/apidiffs/1.33.0_vs_1.32.0/opentelemetry-exporter-sender-grpc-managed-channel.txt b/docs/apidiffs/1.33.0_vs_1.32.0/opentelemetry-exporter-sender-grpc-managed-channel.txt new file mode 100644 index 00000000000..df26146497b --- /dev/null +++ b/docs/apidiffs/1.33.0_vs_1.32.0/opentelemetry-exporter-sender-grpc-managed-channel.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of against +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.33.0_vs_1.32.0/opentelemetry-exporter-sender-okhttp.txt b/docs/apidiffs/1.33.0_vs_1.32.0/opentelemetry-exporter-sender-okhttp.txt new file mode 100644 index 00000000000..df26146497b --- /dev/null +++ b/docs/apidiffs/1.33.0_vs_1.32.0/opentelemetry-exporter-sender-okhttp.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of against +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.33.0_vs_1.32.0/opentelemetry-exporter-zipkin.txt b/docs/apidiffs/1.33.0_vs_1.32.0/opentelemetry-exporter-zipkin.txt new file mode 100644 index 00000000000..df26146497b --- /dev/null +++ b/docs/apidiffs/1.33.0_vs_1.32.0/opentelemetry-exporter-zipkin.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of against +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.33.0_vs_1.32.0/opentelemetry-extension-kotlin.txt b/docs/apidiffs/1.33.0_vs_1.32.0/opentelemetry-extension-kotlin.txt new file mode 100644 index 00000000000..1945e8c996d --- /dev/null +++ b/docs/apidiffs/1.33.0_vs_1.32.0/opentelemetry-extension-kotlin.txt @@ -0,0 +1,9 @@ +Comparing source compatibility of against +=== UNCHANGED CLASS: PUBLIC FINAL io.opentelemetry.extension.kotlin.ContextExtensionsKt (not serializable) + === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 + *** MODIFIED ANNOTATION: kotlin.Metadata + === UNCHANGED ELEMENT: xi=48 + *** MODIFIED ELEMENT: mv=1,6,0 (<- 1,9,0) + === UNCHANGED ELEMENT: k=2 + === UNCHANGED ELEMENT: d1=�� � ��� ��� ��� ���� ����0�*�0�� ����0�*�0�� ����0�*�0�¨�� + === UNCHANGED ELEMENT: d2=asContextElement,Lkotlin/coroutines/CoroutineContext;,Lio/opentelemetry/context/Context;,Lio/opentelemetry/context/ImplicitContextKeyed;,getOpenTelemetryContext,opentelemetry-extension-kotlin diff --git a/docs/apidiffs/1.33.0_vs_1.32.0/opentelemetry-extension-trace-propagators.txt b/docs/apidiffs/1.33.0_vs_1.32.0/opentelemetry-extension-trace-propagators.txt new file mode 100644 index 00000000000..df26146497b --- /dev/null +++ b/docs/apidiffs/1.33.0_vs_1.32.0/opentelemetry-extension-trace-propagators.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of against +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.33.0_vs_1.32.0/opentelemetry-opentracing-shim.txt b/docs/apidiffs/1.33.0_vs_1.32.0/opentelemetry-opentracing-shim.txt new file mode 100644 index 00000000000..df26146497b --- /dev/null +++ b/docs/apidiffs/1.33.0_vs_1.32.0/opentelemetry-opentracing-shim.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of against +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.33.0_vs_1.32.0/opentelemetry-sdk-common.txt b/docs/apidiffs/1.33.0_vs_1.32.0/opentelemetry-sdk-common.txt new file mode 100644 index 00000000000..df26146497b --- /dev/null +++ b/docs/apidiffs/1.33.0_vs_1.32.0/opentelemetry-sdk-common.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of against +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.33.0_vs_1.32.0/opentelemetry-sdk-extension-autoconfigure-spi.txt b/docs/apidiffs/1.33.0_vs_1.32.0/opentelemetry-sdk-extension-autoconfigure-spi.txt new file mode 100644 index 00000000000..9f4a3fbb37a --- /dev/null +++ b/docs/apidiffs/1.33.0_vs_1.32.0/opentelemetry-sdk-extension-autoconfigure-spi.txt @@ -0,0 +1,5 @@ +Comparing source compatibility of against +*** MODIFIED INTERFACE: PUBLIC ABSTRACT io.opentelemetry.sdk.autoconfigure.spi.AutoConfigurationCustomizer (not serializable) + === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 + +++ NEW METHOD: PUBLIC(+) io.opentelemetry.sdk.autoconfigure.spi.AutoConfigurationCustomizer addLogRecordProcessorCustomizer(java.util.function.BiFunction) + +++ NEW METHOD: PUBLIC(+) io.opentelemetry.sdk.autoconfigure.spi.AutoConfigurationCustomizer addSpanProcessorCustomizer(java.util.function.BiFunction) diff --git a/docs/apidiffs/1.33.0_vs_1.32.0/opentelemetry-sdk-extension-autoconfigure.txt b/docs/apidiffs/1.33.0_vs_1.32.0/opentelemetry-sdk-extension-autoconfigure.txt new file mode 100644 index 00000000000..c4389093f93 --- /dev/null +++ b/docs/apidiffs/1.33.0_vs_1.32.0/opentelemetry-sdk-extension-autoconfigure.txt @@ -0,0 +1,5 @@ +Comparing source compatibility of against +*** MODIFIED CLASS: PUBLIC FINAL io.opentelemetry.sdk.autoconfigure.AutoConfiguredOpenTelemetrySdkBuilder (not serializable) + === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 + +++ NEW METHOD: PUBLIC(+) io.opentelemetry.sdk.autoconfigure.spi.AutoConfigurationCustomizer addLogRecordProcessorCustomizer(java.util.function.BiFunction) + +++ NEW METHOD: PUBLIC(+) io.opentelemetry.sdk.autoconfigure.AutoConfiguredOpenTelemetrySdkBuilder addSpanProcessorCustomizer(java.util.function.BiFunction) diff --git a/docs/apidiffs/1.33.0_vs_1.32.0/opentelemetry-sdk-extension-jaeger-remote-sampler.txt b/docs/apidiffs/1.33.0_vs_1.32.0/opentelemetry-sdk-extension-jaeger-remote-sampler.txt new file mode 100644 index 00000000000..df26146497b --- /dev/null +++ b/docs/apidiffs/1.33.0_vs_1.32.0/opentelemetry-sdk-extension-jaeger-remote-sampler.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of against +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.33.0_vs_1.32.0/opentelemetry-sdk-logs.txt b/docs/apidiffs/1.33.0_vs_1.32.0/opentelemetry-sdk-logs.txt new file mode 100644 index 00000000000..df26146497b --- /dev/null +++ b/docs/apidiffs/1.33.0_vs_1.32.0/opentelemetry-sdk-logs.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of against +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.33.0_vs_1.32.0/opentelemetry-sdk-metrics.txt b/docs/apidiffs/1.33.0_vs_1.32.0/opentelemetry-sdk-metrics.txt new file mode 100644 index 00000000000..df26146497b --- /dev/null +++ b/docs/apidiffs/1.33.0_vs_1.32.0/opentelemetry-sdk-metrics.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of against +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.33.0_vs_1.32.0/opentelemetry-sdk-testing.txt b/docs/apidiffs/1.33.0_vs_1.32.0/opentelemetry-sdk-testing.txt new file mode 100644 index 00000000000..c1e98158b3d --- /dev/null +++ b/docs/apidiffs/1.33.0_vs_1.32.0/opentelemetry-sdk-testing.txt @@ -0,0 +1,5 @@ +Comparing source compatibility of against +*** MODIFIED CLASS: PUBLIC ABSTRACT io.opentelemetry.sdk.testing.assertj.AbstractPointAssert (not serializable) + === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 + GENERIC TEMPLATES: === PointAssertT:io.opentelemetry.sdk.testing.assertj.AbstractPointAssert, === PointT:io.opentelemetry.sdk.metrics.data.PointData + +++ NEW METHOD: PUBLIC(+) FINAL(+) io.opentelemetry.sdk.testing.assertj.AbstractPointAssert hasAttributesSatisfying(java.util.function.Consumer) diff --git a/docs/apidiffs/1.33.0_vs_1.32.0/opentelemetry-sdk-trace.txt b/docs/apidiffs/1.33.0_vs_1.32.0/opentelemetry-sdk-trace.txt new file mode 100644 index 00000000000..df26146497b --- /dev/null +++ b/docs/apidiffs/1.33.0_vs_1.32.0/opentelemetry-sdk-trace.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of against +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.33.0_vs_1.32.0/opentelemetry-sdk.txt b/docs/apidiffs/1.33.0_vs_1.32.0/opentelemetry-sdk.txt new file mode 100644 index 00000000000..df26146497b --- /dev/null +++ b/docs/apidiffs/1.33.0_vs_1.32.0/opentelemetry-sdk.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of against +No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-otlp.txt b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-otlp.txt index 7c0ed9b5e5f..df26146497b 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-otlp.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-otlp.txt @@ -1,25 +1,2 @@ Comparing source compatibility of against -*** MODIFIED CLASS: PUBLIC FINAL io.opentelemetry.exporter.otlp.http.logs.OtlpHttpLogRecordExporterBuilder (not serializable) - === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 - +++ NEW METHOD: PUBLIC(+) io.opentelemetry.exporter.otlp.http.logs.OtlpHttpLogRecordExporterBuilder setConnectTimeout(long, java.util.concurrent.TimeUnit) - +++ NEW METHOD: PUBLIC(+) io.opentelemetry.exporter.otlp.http.logs.OtlpHttpLogRecordExporterBuilder setConnectTimeout(java.time.Duration) - +++ NEW METHOD: PUBLIC(+) io.opentelemetry.exporter.otlp.http.logs.OtlpHttpLogRecordExporterBuilder setHeaders(java.util.function.Supplier>) -*** MODIFIED CLASS: PUBLIC FINAL io.opentelemetry.exporter.otlp.http.metrics.OtlpHttpMetricExporterBuilder (not serializable) - === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 - +++ NEW METHOD: PUBLIC(+) io.opentelemetry.exporter.otlp.http.metrics.OtlpHttpMetricExporterBuilder setConnectTimeout(long, java.util.concurrent.TimeUnit) - +++ NEW METHOD: PUBLIC(+) io.opentelemetry.exporter.otlp.http.metrics.OtlpHttpMetricExporterBuilder setConnectTimeout(java.time.Duration) - +++ NEW METHOD: PUBLIC(+) io.opentelemetry.exporter.otlp.http.metrics.OtlpHttpMetricExporterBuilder setHeaders(java.util.function.Supplier>) -*** MODIFIED CLASS: PUBLIC FINAL io.opentelemetry.exporter.otlp.http.trace.OtlpHttpSpanExporterBuilder (not serializable) - === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 - +++ NEW METHOD: PUBLIC(+) io.opentelemetry.exporter.otlp.http.trace.OtlpHttpSpanExporterBuilder setConnectTimeout(long, java.util.concurrent.TimeUnit) - +++ NEW METHOD: PUBLIC(+) io.opentelemetry.exporter.otlp.http.trace.OtlpHttpSpanExporterBuilder setConnectTimeout(java.time.Duration) - +++ NEW METHOD: PUBLIC(+) io.opentelemetry.exporter.otlp.http.trace.OtlpHttpSpanExporterBuilder setHeaders(java.util.function.Supplier>) -*** MODIFIED CLASS: PUBLIC FINAL io.opentelemetry.exporter.otlp.logs.OtlpGrpcLogRecordExporterBuilder (not serializable) - === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 - +++ NEW METHOD: PUBLIC(+) io.opentelemetry.exporter.otlp.logs.OtlpGrpcLogRecordExporterBuilder setHeaders(java.util.function.Supplier>) -*** MODIFIED CLASS: PUBLIC FINAL io.opentelemetry.exporter.otlp.metrics.OtlpGrpcMetricExporterBuilder (not serializable) - === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 - +++ NEW METHOD: PUBLIC(+) io.opentelemetry.exporter.otlp.metrics.OtlpGrpcMetricExporterBuilder setHeaders(java.util.function.Supplier>) -*** MODIFIED CLASS: PUBLIC FINAL io.opentelemetry.exporter.otlp.trace.OtlpGrpcSpanExporterBuilder (not serializable) - === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 - +++ NEW METHOD: PUBLIC(+) io.opentelemetry.exporter.otlp.trace.OtlpGrpcSpanExporterBuilder setHeaders(java.util.function.Supplier>) +No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-extension-kotlin.txt b/docs/apidiffs/current_vs_latest/opentelemetry-extension-kotlin.txt index 1945e8c996d..df26146497b 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-extension-kotlin.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-extension-kotlin.txt @@ -1,9 +1,2 @@ Comparing source compatibility of against -=== UNCHANGED CLASS: PUBLIC FINAL io.opentelemetry.extension.kotlin.ContextExtensionsKt (not serializable) - === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 - *** MODIFIED ANNOTATION: kotlin.Metadata - === UNCHANGED ELEMENT: xi=48 - *** MODIFIED ELEMENT: mv=1,6,0 (<- 1,9,0) - === UNCHANGED ELEMENT: k=2 - === UNCHANGED ELEMENT: d1=�� � ��� ��� ��� ���� ����0�*�0�� ����0�*�0�� ����0�*�0�¨�� - === UNCHANGED ELEMENT: d2=asContextElement,Lkotlin/coroutines/CoroutineContext;,Lio/opentelemetry/context/Context;,Lio/opentelemetry/context/ImplicitContextKeyed;,getOpenTelemetryContext,opentelemetry-extension-kotlin +No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-extension-autoconfigure-spi.txt b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-extension-autoconfigure-spi.txt index 9f4a3fbb37a..df26146497b 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-extension-autoconfigure-spi.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-extension-autoconfigure-spi.txt @@ -1,5 +1,2 @@ Comparing source compatibility of against -*** MODIFIED INTERFACE: PUBLIC ABSTRACT io.opentelemetry.sdk.autoconfigure.spi.AutoConfigurationCustomizer (not serializable) - === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 - +++ NEW METHOD: PUBLIC(+) io.opentelemetry.sdk.autoconfigure.spi.AutoConfigurationCustomizer addLogRecordProcessorCustomizer(java.util.function.BiFunction) - +++ NEW METHOD: PUBLIC(+) io.opentelemetry.sdk.autoconfigure.spi.AutoConfigurationCustomizer addSpanProcessorCustomizer(java.util.function.BiFunction) +No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-extension-autoconfigure.txt b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-extension-autoconfigure.txt index c4389093f93..df26146497b 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-extension-autoconfigure.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-extension-autoconfigure.txt @@ -1,5 +1,2 @@ Comparing source compatibility of against -*** MODIFIED CLASS: PUBLIC FINAL io.opentelemetry.sdk.autoconfigure.AutoConfiguredOpenTelemetrySdkBuilder (not serializable) - === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 - +++ NEW METHOD: PUBLIC(+) io.opentelemetry.sdk.autoconfigure.spi.AutoConfigurationCustomizer addLogRecordProcessorCustomizer(java.util.function.BiFunction) - +++ NEW METHOD: PUBLIC(+) io.opentelemetry.sdk.autoconfigure.AutoConfiguredOpenTelemetrySdkBuilder addSpanProcessorCustomizer(java.util.function.BiFunction) +No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-testing.txt b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-testing.txt index c1e98158b3d..df26146497b 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-testing.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-testing.txt @@ -1,5 +1,2 @@ Comparing source compatibility of against -*** MODIFIED CLASS: PUBLIC ABSTRACT io.opentelemetry.sdk.testing.assertj.AbstractPointAssert (not serializable) - === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 - GENERIC TEMPLATES: === PointAssertT:io.opentelemetry.sdk.testing.assertj.AbstractPointAssert, === PointT:io.opentelemetry.sdk.metrics.data.PointData - +++ NEW METHOD: PUBLIC(+) FINAL(+) io.opentelemetry.sdk.testing.assertj.AbstractPointAssert hasAttributesSatisfying(java.util.function.Consumer) +No changes. \ No newline at end of file From ffd53c7d56f3d14cdb13e8489d18d3d14b71da33 Mon Sep 17 00:00:00 2001 From: Asaf Mesika Date: Fri, 15 Dec 2023 00:21:39 +0200 Subject: [PATCH 151/901] Memory Mode: Adding first part support for synchronous instruments - storage (#5998) Co-authored-by: jack-berg <34418638+jack-berg@users.noreply.github.com> --- .../sdk/common/export/MemoryMode.java | 18 + .../sdk/metrics/ViewBuilder.java | 7 +- .../internal/aggregator/AggregatorHandle.java | 16 + .../DefaultSynchronousMetricStorage.java | 89 +++- .../state/SynchronousMetricStorageTest.java | 452 ++++++++++++++++-- 5 files changed, 532 insertions(+), 50 deletions(-) diff --git a/sdk/common/src/main/java/io/opentelemetry/sdk/common/export/MemoryMode.java b/sdk/common/src/main/java/io/opentelemetry/sdk/common/export/MemoryMode.java index 5cd9fea40f8..4ebf23a9deb 100644 --- a/sdk/common/src/main/java/io/opentelemetry/sdk/common/export/MemoryMode.java +++ b/sdk/common/src/main/java/io/opentelemetry/sdk/common/export/MemoryMode.java @@ -17,6 +17,21 @@ public enum MemoryMode { * *

    In this mode, the SDK reuses objects to reduce allocations, at the expense of disallowing * concurrent collections / exports. + * + *

    Metric Signal: For DELTA aggregation temporality, the memory used for recording and + * aggregating metric values is kept between MetricReader collect operation, to avoid memory + * allocations. When the configured maximum cardinality of Attributes is reached, unused + * Attributes are cleared from memory during collect operation, at the cost of requiring new + * memory allocations the next time those attributes are used. Allocations can be minimized by + * increasing the configured max cardinality. For example, suppose instrumentation has recorded + * values for 1000 unique Attributes while the max cardinality configured was 2000. If after a + * collection only 100 unique Attributes values are recorded, the MetricReader's collect operation + * would return 100 points, while in memory the Attributes data structure keeps 1000 unique + * Attributes. If a user recorded values for 3000 unique attributes, the values for the first 1999 + * Attributes would be recorded, and the rest of 1001 unique Attributes values would be recorded + * in the CARDINALITY_OVERFLOW Attributes. If after several collect operations, the user now + * records values to only 500 unique attributes, during collect operation, the unused 1500 + * Attributes memory would be cleared from memory. */ REUSABLE_DATA, @@ -25,6 +40,9 @@ public enum MemoryMode { * *

    In this mode, the SDK passes immutable objects to exporters / readers, increasing * allocations but ensuring safe concurrent exports. + * + *

    Metric Signal: In DELTA aggregation temporality, the memory used for recording and + * aggregating Attributes values is cleared during a MetricReader collect operation. */ IMMUTABLE_DATA } diff --git a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/ViewBuilder.java b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/ViewBuilder.java index b1f60e35b94..26996df4bdf 100644 --- a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/ViewBuilder.java +++ b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/ViewBuilder.java @@ -7,6 +7,7 @@ import static io.opentelemetry.sdk.metrics.internal.view.AttributesProcessor.setIncludes; +import io.opentelemetry.sdk.common.export.MemoryMode; import io.opentelemetry.sdk.metrics.internal.SdkMeterProviderUtil; import io.opentelemetry.sdk.metrics.internal.aggregator.AggregatorFactory; import io.opentelemetry.sdk.metrics.internal.state.MetricStorage; @@ -96,6 +97,7 @@ public ViewBuilder setAttributeFilter(Predicate keyFilter) { *

    Note: not currently stable but additional attribute processors can be configured via {@link * SdkMeterProviderUtil#appendAllBaggageAttributes(ViewBuilder)}. */ + @SuppressWarnings("unused") ViewBuilder addAttributesProcessor(AttributesProcessor attributesProcessor) { this.processor = this.processor.then(attributesProcessor); return this; @@ -105,7 +107,10 @@ ViewBuilder addAttributesProcessor(AttributesProcessor attributesProcessor) { * Set the cardinality limit. * *

    Note: not currently stable but cardinality limit can be configured via - * SdkMeterProviderUtil#setCardinalityLimit(ViewBuilder, int)}. + * SdkMeterProviderUtil#setCardinalityLimit(ViewBuilder, int). + * + *

    Read {@link MemoryMode} to understand the memory usage behavior of reaching cardinality + * limit. * * @param cardinalityLimit the maximum number of series for a metric */ diff --git a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/aggregator/AggregatorHandle.java b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/aggregator/AggregatorHandle.java index 6e3b3f06f53..2bf7c8c4db6 100644 --- a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/aggregator/AggregatorHandle.java +++ b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/aggregator/AggregatorHandle.java @@ -28,6 +28,7 @@ public abstract class AggregatorHandle exemplarReservoir; + private volatile boolean valuesRecorded = false; protected AggregatorHandle(ExemplarReservoir exemplarReservoir) { this.exemplarReservoir = exemplarReservoir; @@ -39,6 +40,10 @@ protected AggregatorHandle(ExemplarReservoir exemplarReservoir) { */ public final T aggregateThenMaybeReset( long startEpochNanos, long epochNanos, Attributes attributes, boolean reset) { + if (reset) { + valuesRecorded = false; + } + return doAggregateThenMaybeReset( startEpochNanos, epochNanos, @@ -69,6 +74,7 @@ public final void recordLong(long value, Attributes attributes, Context context) */ public final void recordLong(long value) { doRecordLong(value); + valuesRecorded = true; } /** @@ -94,6 +100,7 @@ public final void recordDouble(double value, Attributes attributes, Context cont */ public final void recordDouble(double value) { doRecordDouble(value); + valuesRecorded = true; } /** @@ -104,4 +111,13 @@ protected void doRecordDouble(double value) { throw new UnsupportedOperationException( "This aggregator does not support recording double values."); } + + /** + * Checks whether this handle has values recorded. + * + * @return True if values has been recorded to it + */ + public boolean hasRecordedValues() { + return valuesRecorded; + } } diff --git a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/state/DefaultSynchronousMetricStorage.java b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/state/DefaultSynchronousMetricStorage.java index cf31f90cb24..191223bfeac 100644 --- a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/state/DefaultSynchronousMetricStorage.java +++ b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/state/DefaultSynchronousMetricStorage.java @@ -5,9 +5,14 @@ package io.opentelemetry.sdk.metrics.internal.state; +import static io.opentelemetry.sdk.common.export.MemoryMode.IMMUTABLE_DATA; +import static io.opentelemetry.sdk.common.export.MemoryMode.REUSABLE_DATA; +import static io.opentelemetry.sdk.metrics.data.AggregationTemporality.DELTA; + import io.opentelemetry.api.common.Attributes; import io.opentelemetry.context.Context; import io.opentelemetry.sdk.common.InstrumentationScopeInfo; +import io.opentelemetry.sdk.common.export.MemoryMode; import io.opentelemetry.sdk.internal.ThrottlingLogger; import io.opentelemetry.sdk.metrics.data.AggregationTemporality; import io.opentelemetry.sdk.metrics.data.ExemplarData; @@ -50,6 +55,16 @@ public final class DefaultSynchronousMetricStorage aggregatorHolder = new AggregatorHolder<>(); private final AttributesProcessor attributesProcessor; + private final MemoryMode memoryMode; + + // Only populated if memoryMode == REUSABLE_DATA + private final ArrayList reusableResultList = new ArrayList<>(); + + // Only populated if memoryMode == REUSABLE_DATA and + // aggregationTemporality is DELTA + private volatile ConcurrentHashMap> + previousCollectionAggregatorHandles = new ConcurrentHashMap<>(); + /** * This field is set to 1 less than the actual intended cardinality limit, allowing the last slot * to be filled by the {@link MetricStorage#CARDINALITY_OVERFLOW} series. @@ -74,6 +89,7 @@ public final class DefaultSynchronousMetricStorage getHolderForRecord() { /** * Called on the {@link AggregatorHolder} obtained from {@link #getHolderForRecord()} to indicate - * that recording is complete and it is safe to collect. + * that recording is complete, and it is safe to collect. */ private void releaseHolderForRecord(AggregatorHolder aggregatorHolder) { aggregatorHolder.activeRecordingThreads.addAndGet(-2); @@ -185,16 +201,20 @@ public MetricData collect( InstrumentationScopeInfo instrumentationScopeInfo, long startEpochNanos, long epochNanos) { - boolean reset = aggregationTemporality == AggregationTemporality.DELTA; + boolean reset = aggregationTemporality == DELTA; long start = - aggregationTemporality == AggregationTemporality.DELTA + aggregationTemporality == DELTA ? registeredReader.getLastCollectEpochNanos() : startEpochNanos; ConcurrentHashMap> aggregatorHandles; if (reset) { AggregatorHolder holder = this.aggregatorHolder; - this.aggregatorHolder = new AggregatorHolder<>(); + this.aggregatorHolder = + (memoryMode == REUSABLE_DATA) + ? new AggregatorHolder<>(previousCollectionAggregatorHandles) + : new AggregatorHolder<>(); + // Increment recordsInProgress by 1, which produces an odd number acting as a signal that // record operations should re-read the volatile this.aggregatorHolder. // Repeatedly grab recordsInProgress until it is <= 1, which signals all active record @@ -208,15 +228,56 @@ public MetricData collect( aggregatorHandles = this.aggregatorHolder.aggregatorHandles; } + List points; + if (memoryMode == REUSABLE_DATA) { + reusableResultList.clear(); + points = reusableResultList; + } else { + points = new ArrayList<>(aggregatorHandles.size()); + } + + // In DELTA aggregation temporality each Attributes is reset to 0 + // every time we perform a collection (by definition of DELTA). + // In IMMUTABLE_DATA MemoryMode, this is accomplished by removing all aggregator handles + // (into which the values are recorded) effectively starting from 0 + // for each recorded Attributes. + // In REUSABLE_DATA MemoryMode, we strive for zero allocations. Since even removing + // a key-value from a map and putting it again on next recording will cost an allocation, + // we are keeping the aggregator handles in their map, and only reset their value once + // we finish collecting the aggregated value from each one. + // The SDK must adhere to keeping no more than maxCardinality unique Attributes in memory, + // hence during collect(), when the map is at full capacity, we try to clear away unused + // aggregator handles, so on next recording cycle using this map, there will be room for newly + // recorded Attributes. This comes at the expanse of memory allocations. This can be avoided + // if the user chooses to increase the maxCardinality. + if (memoryMode == REUSABLE_DATA && reset) { + if (aggregatorHandles.size() >= maxCardinality) { + aggregatorHandles.forEach( + (attribute, handle) -> { + if (!handle.hasRecordedValues()) { + aggregatorHandles.remove(attribute); + } + }); + } + } + // Grab aggregated points. - List points = new ArrayList<>(aggregatorHandles.size()); aggregatorHandles.forEach( (attributes, handle) -> { + if (!handle.hasRecordedValues()) { + return; + } T point = handle.aggregateThenMaybeReset(start, epochNanos, attributes, reset); - if (reset) { + + if (reset && memoryMode == IMMUTABLE_DATA) { // Return the aggregator to the pool. + // The pool is only used in DELTA temporality (since in CUMULATIVE the handler is + // always used as it is the place accumulating the values and never resets) + // AND only in IMMUTABLE_DATA memory mode since in REUSABLE_DATA we avoid + // using the pool since it allocates memory internally on each put() or remove() aggregatorHandlePool.offer(handle); } + if (point != null) { points.add(point); } @@ -229,6 +290,10 @@ public MetricData collect( aggregatorHandlePool.poll(); } + if (reset && memoryMode == REUSABLE_DATA) { + previousCollectionAggregatorHandles = aggregatorHandles; + } + if (points.isEmpty()) { return EmptyMetricData.getInstance(); } @@ -243,8 +308,7 @@ public MetricDescriptor getMetricDescriptor() { } private static class AggregatorHolder { - private final ConcurrentHashMap> aggregatorHandles = - new ConcurrentHashMap<>(); + private final ConcurrentHashMap> aggregatorHandles; // Recording threads grab the current interval (AggregatorHolder) and atomically increment // this by 2 before recording against it (and then decrement by two when done). // @@ -260,5 +324,14 @@ private static class AggregatorHolder(); + } + + private AggregatorHolder( + ConcurrentHashMap> aggregatorHandles) { + this.aggregatorHandles = aggregatorHandles; + } } } diff --git a/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/internal/state/SynchronousMetricStorageTest.java b/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/internal/state/SynchronousMetricStorageTest.java index f808a0e85f1..2d548acc169 100644 --- a/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/internal/state/SynchronousMetricStorageTest.java +++ b/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/internal/state/SynchronousMetricStorageTest.java @@ -20,9 +20,11 @@ import io.opentelemetry.context.Context; import io.opentelemetry.internal.testing.slf4j.SuppressLogger; import io.opentelemetry.sdk.common.InstrumentationScopeInfo; +import io.opentelemetry.sdk.common.export.MemoryMode; import io.opentelemetry.sdk.metrics.Aggregation; import io.opentelemetry.sdk.metrics.InstrumentType; import io.opentelemetry.sdk.metrics.InstrumentValueType; +import io.opentelemetry.sdk.metrics.data.AggregationTemporality; import io.opentelemetry.sdk.metrics.data.ExemplarData; import io.opentelemetry.sdk.metrics.data.LongExemplarData; import io.opentelemetry.sdk.metrics.data.LongPointData; @@ -39,6 +41,7 @@ import io.opentelemetry.sdk.metrics.internal.view.AttributesProcessor; import io.opentelemetry.sdk.metrics.internal.view.ViewRegistry; import io.opentelemetry.sdk.resources.Resource; +import io.opentelemetry.sdk.testing.assertj.DoubleSumAssert; import io.opentelemetry.sdk.testing.exporter.InMemoryMetricReader; import io.opentelemetry.sdk.testing.time.TestClock; import java.time.Duration; @@ -47,10 +50,12 @@ import java.util.concurrent.CountDownLatch; import java.util.function.BiConsumer; import java.util.stream.Stream; +import org.assertj.core.api.Assertions; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.RegisterExtension; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.EnumSource; import org.junit.jupiter.params.provider.MethodSource; import org.slf4j.event.Level; @@ -75,19 +80,36 @@ public class SynchronousMetricStorageTest { LogCapturer logs = LogCapturer.create().captureForType(DefaultSynchronousMetricStorage.class, Level.DEBUG); - private final RegisteredReader deltaReader = - RegisteredReader.create(InMemoryMetricReader.createDelta(), ViewRegistry.create()); - private final RegisteredReader cumulativeReader = - RegisteredReader.create(InMemoryMetricReader.create(), ViewRegistry.create()); + private RegisteredReader deltaReader; + private RegisteredReader cumulativeReader; private final TestClock testClock = TestClock.create(); - private final Aggregator aggregator = - spy( - ((AggregatorFactory) Aggregation.sum()) - .createAggregator(DESCRIPTOR, ExemplarFilter.alwaysOff())); + private Aggregator aggregator; private final AttributesProcessor attributesProcessor = AttributesProcessor.noop(); - @Test - void recordDouble_NaN() { + private void initialize(MemoryMode memoryMode) { + deltaReader = + RegisteredReader.create( + InMemoryMetricReader.builder() + .setAggregationTemporalitySelector(unused -> AggregationTemporality.DELTA) + .setMemoryMode(memoryMode) + .build(), + ViewRegistry.create()); + + cumulativeReader = + RegisteredReader.create( + InMemoryMetricReader.builder().setMemoryMode(memoryMode).build(), + ViewRegistry.create()); + + aggregator = + spy( + ((AggregatorFactory) Aggregation.sum()) + .createAggregator(DESCRIPTOR, ExemplarFilter.alwaysOff())); + } + + @ParameterizedTest + @EnumSource(MemoryMode.class) + void recordDouble_NaN(MemoryMode memoryMode) { + initialize(memoryMode); DefaultSynchronousMetricStorage storage = new DefaultSynchronousMetricStorage<>( cumulativeReader, @@ -105,8 +127,11 @@ void recordDouble_NaN() { .isEqualTo(EmptyMetricData.getInstance()); } - @Test - void attributesProcessor_applied() { + @ParameterizedTest + @EnumSource(MemoryMode.class) + void attributesProcessor_applied(MemoryMode memoryMode) { + initialize(memoryMode); + Attributes attributes = Attributes.builder().put("K", "V").build(); AttributesProcessor attributesProcessor = AttributesProcessor.append(Attributes.builder().put("modifiedK", "modifiedV").build()); @@ -129,8 +154,11 @@ void attributesProcessor_applied() { attributeEntry("K", "V"), attributeEntry("modifiedK", "modifiedV")))); } - @Test - void recordAndCollect_CumulativeDoesNotReset() { + @ParameterizedTest + @EnumSource(MemoryMode.class) + void recordAndCollect_CumulativeDoesNotReset(MemoryMode memoryMode) { + initialize(memoryMode); + DefaultSynchronousMetricStorage storage = new DefaultSynchronousMetricStorage<>( cumulativeReader, @@ -176,7 +204,9 @@ void recordAndCollect_CumulativeDoesNotReset() { } @Test - void recordAndCollect_DeltaResets() { + void recordAndCollect_DeltaResets_ImmutableData() { + initialize(MemoryMode.IMMUTABLE_DATA); + DefaultSynchronousMetricStorage storage = new DefaultSynchronousMetricStorage<>( deltaReader, METRIC_DESCRIPTOR, aggregator, attributesProcessor, CARDINALITY_LIMIT); @@ -223,7 +253,107 @@ void recordAndCollect_DeltaResets() { } @Test - void recordAndCollect_CumulativeAtLimit() { + void recordAndCollect_DeltaResets_ReusableData() { + initialize(MemoryMode.REUSABLE_DATA); + + DefaultSynchronousMetricStorage storage = + new DefaultSynchronousMetricStorage<>( + deltaReader, METRIC_DESCRIPTOR, aggregator, attributesProcessor, CARDINALITY_LIMIT); + + // Record measurement and collect at time 10 + storage.recordDouble(3, Attributes.empty(), Context.current()); + verify(aggregator, times(1)).createHandle(); + assertThat(storage.getAggregatorHandlePool()).hasSize(0); + assertThat(storage.collect(RESOURCE, INSTRUMENTATION_SCOPE_INFO, 0, 10)) + .hasDoubleSumSatisfying( + sum -> + sum.isDelta() + .hasPointsSatisfying( + point -> point.hasStartEpochNanos(0).hasEpochNanos(10).hasValue(3))); + assertThat(storage.getAggregatorHandlePool()).hasSize(0); + + deltaReader.setLastCollectEpochNanos(10); + + // Record measurement and collect at time 30 + storage.recordDouble(3, Attributes.empty(), Context.current()); + + // We're switched to secondary map so a handle will be created + verify(aggregator, times(2)).createHandle(); + assertThat(storage.getAggregatorHandlePool()).hasSize(0); + assertThat(storage.collect(RESOURCE, INSTRUMENTATION_SCOPE_INFO, 0, 30)) + .hasDoubleSumSatisfying( + sum -> + sum.isDelta() + .hasPointsSatisfying( + point -> point.hasStartEpochNanos(10).hasEpochNanos(30).hasValue(3))); + assertThat(storage.getAggregatorHandlePool()).hasSize(0); + + deltaReader.setLastCollectEpochNanos(30); + + // Record measurements and collect at time 35 + storage.recordDouble(2, Attributes.empty(), Context.current()); + storage.recordDouble(4, Attributes.of(AttributeKey.stringKey("foo"), "bar"), Context.current()); + + // We don't delete aggregator handles unless max cardinality reached, hence + // aggregator handle is still there, thus no handle was created for empty(), but it will for + // the "foo" + verify(aggregator, times(3)).createHandle(); + assertThat(storage.getAggregatorHandlePool()).hasSize(0); + + MetricData metricData = storage.collect(RESOURCE, INSTRUMENTATION_SCOPE_INFO, 0, 35); + assertThat(metricData).hasDoubleSumSatisfying(DoubleSumAssert::isDelta); + assertThat(metricData) + .hasDoubleSumSatisfying( + sum -> + sum.satisfies( + sumData -> + assertThat(sumData.getPoints()) + .hasSize(2) + .anySatisfy( + point -> { + assertThat(point.getStartEpochNanos()).isEqualTo(30); + assertThat(point.getEpochNanos()).isEqualTo(35); + assertThat(point.getValue()).isEqualTo(2); + assertThat(point.getAttributes()).isEqualTo(Attributes.empty()); + }) + .anySatisfy( + point -> { + assertThat(point.getStartEpochNanos()).isEqualTo(30); + assertThat(point.getEpochNanos()).isEqualTo(35); + assertThat(point.getValue()).isEqualTo(4); + assertThat(point.getAttributes()) + .isEqualTo( + Attributes.of(AttributeKey.stringKey("foo"), "bar")); + }))); + + assertThat(storage.getAggregatorHandlePool()).hasSize(0); + + deltaReader.setLastCollectEpochNanos(40); + storage.recordDouble(6, Attributes.of(AttributeKey.stringKey("foo"), "bar"), Context.current()); + + assertThat(storage.collect(RESOURCE, INSTRUMENTATION_SCOPE_INFO, 0, 45)) + .hasDoubleSumSatisfying( + sum -> + sum.satisfies( + sumData -> + assertThat(sumData.getPoints()) + .hasSize(1) + .allSatisfy( + point -> { + assertThat(point.getStartEpochNanos()).isEqualTo(40); + assertThat(point.getEpochNanos()).isEqualTo(45); + assertThat(point.getValue()).isEqualTo(6); + assertThat(point.getAttributes()) + .isEqualTo( + Attributes.of(AttributeKey.stringKey("foo"), "bar")); + }))); + } + + @ParameterizedTest + @EnumSource(MemoryMode.class) + void recordAndCollect_CumulativeAtLimit(MemoryMode memoryMode) { + initialize(memoryMode); + DefaultSynchronousMetricStorage storage = new DefaultSynchronousMetricStorage<>( cumulativeReader, @@ -292,7 +422,9 @@ void recordAndCollect_CumulativeAtLimit() { } @Test - void recordAndCollect_DeltaAtLimit() { + void recordAndCollect_DeltaAtLimit_ImmutableDataMemoryMode() { + initialize(MemoryMode.IMMUTABLE_DATA); + DefaultSynchronousMetricStorage storage = new DefaultSynchronousMetricStorage<>( deltaReader, METRIC_DESCRIPTOR, aggregator, attributesProcessor, CARDINALITY_LIMIT); @@ -319,6 +451,7 @@ void recordAndCollect_DeltaAtLimit() { assertThat(point.getValue()).isEqualTo(3); }))); assertThat(storage.getAggregatorHandlePool()).hasSize(CARDINALITY_LIMIT - 1); + assertThat(logs.getEvents()).isEmpty(); deltaReader.setLastCollectEpochNanos(10); @@ -384,6 +517,227 @@ void recordAndCollect_DeltaAtLimit() { logs.assertContains("Instrument name has exceeded the maximum allowed cardinality"); } + @Test + void recordAndCollect_DeltaAtLimit_ReusableDataMemoryMode() { + initialize(MemoryMode.REUSABLE_DATA); + + DefaultSynchronousMetricStorage storage = + new DefaultSynchronousMetricStorage<>( + deltaReader, METRIC_DESCRIPTOR, aggregator, attributesProcessor, CARDINALITY_LIMIT); + + // Record measurements for CARDINALITY_LIMIT - 1, since 1 slot is reserved for the overflow + // series + for (int i = 0; i < CARDINALITY_LIMIT - 1; i++) { + storage.recordDouble( + 3, Attributes.builder().put("key", "value" + i).build(), Context.current()); + } + verify(aggregator, times(CARDINALITY_LIMIT - 1)).createHandle(); + + // First collect + MetricData metricData = storage.collect(RESOURCE, INSTRUMENTATION_SCOPE_INFO, 0, 10); + + assertThat(metricData) + .hasDoubleSumSatisfying( + sum -> + sum.satisfies( + sumData -> + Assertions.assertThat(sumData.getPoints()) + .hasSize(CARDINALITY_LIMIT - 1) + .allSatisfy( + point -> { + Assertions.assertThat(point.getStartEpochNanos()).isEqualTo(0); + Assertions.assertThat(point.getEpochNanos()).isEqualTo(10); + Assertions.assertThat(point.getValue()).isEqualTo(3); + }))); + + assertThat(logs.getEvents()).isEmpty(); + + deltaReader.setLastCollectEpochNanos(10); + + // Record CARDINALITY_LIMIT measurements, causing one measurement to exceed the cardinality + // limit and fall into the overflow series + for (int i = 0; i < CARDINALITY_LIMIT; i++) { + storage.recordDouble( + 3, Attributes.builder().put("key", "value" + i).build(), Context.current()); + } + + // After first collection, we expect the secondary map which is empty to be used, + // hence handle creation will still take place + // The +1 is for the overflow handle + verify(aggregator, times((CARDINALITY_LIMIT - 1) * 2 + 1)).createHandle(); + + // Second collect + metricData = storage.collect(RESOURCE, INSTRUMENTATION_SCOPE_INFO, 0, 20); + + assertThat(metricData) + .hasDoubleSumSatisfying( + sum -> + sum.satisfies( + sumData -> + assertThat(sumData.getPoints()) + .hasSize(CARDINALITY_LIMIT) + .allSatisfy( + point -> { + assertThat(point.getStartEpochNanos()).isEqualTo(10); + assertThat(point.getEpochNanos()).isEqualTo(20); + assertThat(point.getValue()).isEqualTo(3); + }) + .noneMatch( + point -> + ("value" + CARDINALITY_LIMIT) + .equals( + point + .getAttributes() + .get(AttributeKey.stringKey("key")))) + .satisfiesOnlyOnce( + point -> + assertThat(point.getAttributes()) + .isEqualTo(MetricStorage.CARDINALITY_OVERFLOW)))); + + assertThat(storage.getAggregatorHandlePool()).isEmpty(); + + logs.assertContains("Instrument name has exceeded the maximum allowed cardinality"); + } + + @Test + void recordAndCollect_DeltaAtLimit_ReusableDataMemoryMode_ExpireUnused() { + initialize(MemoryMode.REUSABLE_DATA); + + DefaultSynchronousMetricStorage storage = + new DefaultSynchronousMetricStorage<>( + deltaReader, METRIC_DESCRIPTOR, aggregator, attributesProcessor, CARDINALITY_LIMIT); + + // 1st recording: Recording goes to active map + for (int i = 0; i < CARDINALITY_LIMIT - 1; i++) { + storage.recordDouble( + 3, Attributes.builder().put("key", "value" + i).build(), Context.current()); + } + + // This will switch next recordings to the secondary map (which is empty) + // by making it the active map + storage.collect(RESOURCE, INSTRUMENTATION_SCOPE_INFO, 0, 10); + + // 2nd recording + deltaReader.setLastCollectEpochNanos(10); + for (int i = 0; i < CARDINALITY_LIMIT - 1; i++) { + storage.recordDouble( + 3, Attributes.builder().put("key", "value" + i).build(), Context.current()); + } + + // This switches maps again, so next recordings will be to the first map + storage.collect(RESOURCE, INSTRUMENTATION_SCOPE_INFO, 10, 20); + + // 3rd recording: We're recording unseen attributes to a map we know is full, + // since it was filled during 1st recording + deltaReader.setLastCollectEpochNanos(20); + for (int i = CARDINALITY_LIMIT - 1; i < (CARDINALITY_LIMIT - 1) + 15; i++) { + storage.recordDouble( + 3, Attributes.builder().put("key", "value" + i).build(), Context.current()); + } + + MetricData metricData = storage.collect(RESOURCE, INSTRUMENTATION_SCOPE_INFO, 20, 30); + + assertOnlyOverflowWasRecorded(metricData, 20, 30, 15 * 3); + + // 4th recording: We're recording unseen attributes to a map we know is full, + // since it was filled during *2nd* recording + deltaReader.setLastCollectEpochNanos(30); + for (int i = CARDINALITY_LIMIT - 1; i < (CARDINALITY_LIMIT - 1) + 15; i++) { + storage.recordDouble( + 3, Attributes.builder().put("key", "value" + i).build(), Context.current()); + } + + metricData = storage.collect(RESOURCE, INSTRUMENTATION_SCOPE_INFO, 30, 40); + + assertOnlyOverflowWasRecorded(metricData, 30, 40, 15 * 3); + + // 5th recording: Map should be empty, since all handlers were removed due to + // no recording being done to them + deltaReader.setLastCollectEpochNanos(40); + for (int i = 0; i < 10; i++) { + storage.recordDouble( + 3, Attributes.builder().put("key", "value" + i).build(), Context.current()); + } + + metricData = storage.collect(RESOURCE, INSTRUMENTATION_SCOPE_INFO, 40, 50); + + assertNumberOfPoints(metricData, 10); + assertAllPointsWithValue(metricData, 40, 50, 3); + assertOverflowDoesNotExists(metricData); + + // 6th recording: Map should be empty (we switched to secondary map), since all handlers + // were removed due to no recordings being done to them + deltaReader.setLastCollectEpochNanos(50); + for (int i = 0; i < 12; i++) { + storage.recordDouble( + 4, Attributes.builder().put("key", "value" + i).build(), Context.current()); + } + + metricData = storage.collect(RESOURCE, INSTRUMENTATION_SCOPE_INFO, 50, 60); + + assertNumberOfPoints(metricData, 12); + assertAllPointsWithValue(metricData, 50, 60, 4); + assertOverflowDoesNotExists(metricData); + } + + @SuppressWarnings("SameParameterValue") + private static void assertOnlyOverflowWasRecorded( + MetricData metricData, long startTime, long endTime, double value) { + + assertThat(metricData) + .hasDoubleSumSatisfying( + sum -> + sum.satisfies( + sumData -> + assertThat(sumData.getPoints()) + .hasSize(1) + .allSatisfy( + point -> { + assertThat(point.getStartEpochNanos()).isEqualTo(startTime); + assertThat(point.getEpochNanos()).isEqualTo(endTime); + assertThat(point.getValue()).isEqualTo(value); + assertThat(point.getAttributes()) + .isEqualTo(MetricStorage.CARDINALITY_OVERFLOW); + }))); + } + + private static void assertNumberOfPoints(MetricData metricData, int numberOfPoints) { + assertThat(metricData) + .hasDoubleSumSatisfying( + sum -> + sum.satisfies(sumData -> assertThat(sumData.getPoints()).hasSize(numberOfPoints))); + } + + private static void assertAllPointsWithValue( + MetricData metricData, long startTime, long endTime, double value) { + assertThat(metricData) + .hasDoubleSumSatisfying( + sum -> + sum.satisfies( + sumData -> + assertThat(sumData.getPoints()) + .allSatisfy( + point -> { + assertThat(point.getStartEpochNanos()).isEqualTo(startTime); + assertThat(point.getEpochNanos()).isEqualTo(endTime); + assertThat(point.getValue()).isEqualTo(value); + }))); + } + + private static void assertOverflowDoesNotExists(MetricData metricData) { + assertThat(metricData) + .hasDoubleSumSatisfying( + sum -> + sum.satisfies( + sumData -> + assertThat(sumData.getPoints()) + .noneMatch( + point -> + point + .getAttributes() + .equals(MetricStorage.CARDINALITY_OVERFLOW)))); + } + @ParameterizedTest @MethodSource("concurrentStressTestArguments") void recordAndCollect_concurrentStressTest( @@ -439,29 +793,45 @@ void recordAndCollect_concurrentStressTest( } private static Stream concurrentStressTestArguments() { - Aggregator aggregator = - ((AggregatorFactory) Aggregation.sum()) - .createAggregator(DESCRIPTOR, ExemplarFilter.alwaysOff()); - return Stream.of( - Arguments.of( - // Delta - new DefaultSynchronousMetricStorage<>( - RegisteredReader.create(InMemoryMetricReader.createDelta(), ViewRegistry.create()), - METRIC_DESCRIPTOR, - aggregator, - AttributesProcessor.noop(), - CARDINALITY_LIMIT), - (BiConsumer) - (value, cumulativeCount) -> cumulativeCount.addAndGet(value)), - Arguments.of( - // Cumulative - new DefaultSynchronousMetricStorage<>( - RegisteredReader.create(InMemoryMetricReader.create(), ViewRegistry.create()), - METRIC_DESCRIPTOR, - aggregator, - AttributesProcessor.noop(), - CARDINALITY_LIMIT), - (BiConsumer) - (value, cumulativeCount) -> cumulativeCount.set(value))); + List argumentsList = new ArrayList<>(); + + for (MemoryMode memoryMode : MemoryMode.values()) { + Aggregator aggregator = + ((AggregatorFactory) Aggregation.sum()) + .createAggregator(DESCRIPTOR, ExemplarFilter.alwaysOff()); + + argumentsList.add( + Arguments.of( + // Delta + new DefaultSynchronousMetricStorage<>( + RegisteredReader.create( + InMemoryMetricReader.builder() + .setAggregationTemporalitySelector(unused -> AggregationTemporality.DELTA) + .setMemoryMode(memoryMode) + .build(), + ViewRegistry.create()), + METRIC_DESCRIPTOR, + aggregator, + AttributesProcessor.noop(), + CARDINALITY_LIMIT), + (BiConsumer) + (value, cumulativeCount) -> cumulativeCount.addAndGet(value))); + + argumentsList.add( + Arguments.of( + // Cumulative + new DefaultSynchronousMetricStorage<>( + RegisteredReader.create( + InMemoryMetricReader.builder().setMemoryMode(memoryMode).build(), + ViewRegistry.create()), + METRIC_DESCRIPTOR, + aggregator, + AttributesProcessor.noop(), + CARDINALITY_LIMIT), + (BiConsumer) + (value, cumulativeCount) -> cumulativeCount.set(value))); + } + + return argumentsList.stream(); } } From 5412905f212496edfafc4d8bec106af0b5021d82 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 18 Dec 2023 11:02:23 -0600 Subject: [PATCH 152/901] Update dependency io.zipkin.brave:brave-bom to v5.17.0 (#6081) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- dependencyManagement/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index 9e1ba7ef698..1c198afdb33 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -16,7 +16,7 @@ val DEPENDENCY_BOMS = listOf( "com.squareup.okio:okio-bom:3.6.0", // applies to transitive dependencies of okhttp "io.grpc:grpc-bom:1.60.0", "io.netty:netty-bom:4.1.101.Final", - "io.zipkin.brave:brave-bom:5.16.0", + "io.zipkin.brave:brave-bom:5.17.0", "io.zipkin.reporter2:zipkin-reporter-bom:2.16.4", "org.assertj:assertj-bom:3.24.2", "org.junit:junit-bom:5.10.1", From 97386403ce8d6671b05ec3d6f2559b87dec736be Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 18 Dec 2023 11:02:52 -0600 Subject: [PATCH 153/901] Update dependency org.owasp:dependency-check-gradle to v9.0.7 (#6073) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- buildSrc/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts index 055eaea862d..db442381e74 100644 --- a/buildSrc/build.gradle.kts +++ b/buildSrc/build.gradle.kts @@ -58,7 +58,7 @@ dependencies { implementation("net.ltgt.gradle:gradle-errorprone-plugin:3.1.0") implementation("net.ltgt.gradle:gradle-nullaway-plugin:1.6.0") implementation("org.jetbrains.kotlin:kotlin-gradle-plugin:1.9.21") - implementation("org.owasp:dependency-check-gradle:9.0.4") + implementation("org.owasp:dependency-check-gradle:9.0.7") implementation("ru.vyarus:gradle-animalsniffer-plugin:1.7.1") } From 6c6800a8213664beb3da67e4440b540e94ff85bf Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 18 Dec 2023 11:03:44 -0600 Subject: [PATCH 154/901] Update actions/upload-artifact action to v4 (#6077) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/build.yml | 2 +- .github/workflows/owasp-dependency-check-daily.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 0732faec59a..8243beff8f7 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -78,7 +78,7 @@ jobs: - uses: codecov/codecov-action@v3 if: ${{ matrix.coverage }} - - uses: actions/upload-artifact@v3 + - uses: actions/upload-artifact@v4 if: ${{ matrix.coverage }} with: name: coverage-report diff --git a/.github/workflows/owasp-dependency-check-daily.yml b/.github/workflows/owasp-dependency-check-daily.yml index ae86cb64c13..c5a8f292df7 100644 --- a/.github/workflows/owasp-dependency-check-daily.yml +++ b/.github/workflows/owasp-dependency-check-daily.yml @@ -25,6 +25,6 @@ jobs: - name: Upload report if: always() - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: path: javaagent/build/reports From ecd11ea5db6c99546383a3e4ee2a68c9c3937cdd Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 18 Dec 2023 11:04:20 -0600 Subject: [PATCH 155/901] Update github/codeql-action action to v3 (#6074) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/codeql-daily.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/codeql-daily.yml b/.github/workflows/codeql-daily.yml index 90032c303bc..9aef4c78c47 100644 --- a/.github/workflows/codeql-daily.yml +++ b/.github/workflows/codeql-daily.yml @@ -20,7 +20,7 @@ jobs: java-version: 17 - name: Initialize CodeQL - uses: github/codeql-action/init@v2 + uses: github/codeql-action/init@v3 with: languages: java # using "latest" helps to keep up with the latest Kotlin support @@ -33,7 +33,7 @@ jobs: arguments: assemble --no-build-cache - name: Perform CodeQL analysis - uses: github/codeql-action/analyze@v2 + uses: github/codeql-action/analyze@v3 open-issue-on-failure: # open an issue on failure because it can be easy to miss CI failure notifications From b3e6045a720997b6e90d15ad65879f768bb5272d Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 18 Dec 2023 11:25:14 -0600 Subject: [PATCH 156/901] Update dependency io.netty:netty-bom to v4.1.104.Final (#6072) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- dependencyManagement/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index 1c198afdb33..867103aa141 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -15,7 +15,7 @@ val DEPENDENCY_BOMS = listOf( "com.squareup.okhttp3:okhttp-bom:4.12.0", "com.squareup.okio:okio-bom:3.6.0", // applies to transitive dependencies of okhttp "io.grpc:grpc-bom:1.60.0", - "io.netty:netty-bom:4.1.101.Final", + "io.netty:netty-bom:4.1.104.Final", "io.zipkin.brave:brave-bom:5.17.0", "io.zipkin.reporter2:zipkin-reporter-bom:2.16.4", "org.assertj:assertj-bom:3.24.2", From 2634bcad7a1c4e878feb77dbf07d87647e7a538a Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 18 Dec 2023 11:25:23 -0600 Subject: [PATCH 157/901] Update dependency io.zipkin.reporter2:zipkin-reporter-bom to v2.17.1 (#6070) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- dependencyManagement/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index 867103aa141..6883f064c6c 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -17,7 +17,7 @@ val DEPENDENCY_BOMS = listOf( "io.grpc:grpc-bom:1.60.0", "io.netty:netty-bom:4.1.104.Final", "io.zipkin.brave:brave-bom:5.17.0", - "io.zipkin.reporter2:zipkin-reporter-bom:2.16.4", + "io.zipkin.reporter2:zipkin-reporter-bom:2.17.1", "org.assertj:assertj-bom:3.24.2", "org.junit:junit-bom:5.10.1", "org.testcontainers:testcontainers-bom:1.19.3", From 867d25be415b1acaf0d5a0b9f16fb4016e09130e Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 18 Dec 2023 11:25:34 -0600 Subject: [PATCH 158/901] Update dependency com.squareup.okio:okio-bom to v3.7.0 (#6080) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- dependencyManagement/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index 6883f064c6c..89f76b39ff3 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -13,7 +13,7 @@ val DEPENDENCY_BOMS = listOf( "com.google.protobuf:protobuf-bom:3.25.1", "com.linecorp.armeria:armeria-bom:1.26.4", "com.squareup.okhttp3:okhttp-bom:4.12.0", - "com.squareup.okio:okio-bom:3.6.0", // applies to transitive dependencies of okhttp + "com.squareup.okio:okio-bom:3.7.0", // applies to transitive dependencies of okhttp "io.grpc:grpc-bom:1.60.0", "io.netty:netty-bom:4.1.104.Final", "io.zipkin.brave:brave-bom:5.17.0", From d1e2d09fa44d616e23c1802fa5f707cc96fa4bda Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 18 Dec 2023 16:09:56 -0600 Subject: [PATCH 159/901] Update plugin com.gradle.enterprise to v3.16.1 (#6060) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- settings.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/settings.gradle.kts b/settings.gradle.kts index 8e4fc690d1b..73b53ac9612 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -1,7 +1,7 @@ pluginManagement { plugins { id("com.github.johnrengelman.shadow") version "8.1.1" - id("com.gradle.enterprise") version "3.15.1" + id("com.gradle.enterprise") version "3.16.1" id("de.undercouch.download") version "5.5.0" id("org.jsonschema2pojo") version "1.2.1" id("io.github.gradle-nexus.publish-plugin") version "1.3.0" From 0b32fe2fdafeb08c6d0639c67bbe3ef6d0322ba8 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 18 Dec 2023 16:57:42 -0600 Subject: [PATCH 160/901] Update dependency com.google.guava:guava-bom to v33 (#6083) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- dependencyManagement/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index 89f76b39ff3..4517f63601b 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -9,7 +9,7 @@ rootProject.extra["versions"] = dependencyVersions val DEPENDENCY_BOMS = listOf( "com.fasterxml.jackson:jackson-bom:2.16.0", - "com.google.guava:guava-bom:32.1.3-jre", + "com.google.guava:guava-bom:33.0.0-jre", "com.google.protobuf:protobuf-bom:3.25.1", "com.linecorp.armeria:armeria-bom:1.26.4", "com.squareup.okhttp3:okhttp-bom:4.12.0", From eea1fe0e996cfdfe1e7ed373bb9a41c19bb90ade Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 20 Dec 2023 08:30:03 -0600 Subject: [PATCH 161/901] Update dependency com.google.guava:guava to v33 (#6085) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- buildSrc/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts index db442381e74..6b6f9c152e6 100644 --- a/buildSrc/build.gradle.kts +++ b/buildSrc/build.gradle.kts @@ -47,7 +47,7 @@ dependencies { // When updating, update above in plugins too implementation("com.diffplug.spotless:spotless-plugin-gradle:6.23.3") // Needed for japicmp but not automatically brought in for some reason. - implementation("com.google.guava:guava:32.1.3-jre") + implementation("com.google.guava:guava:33.0.0-jre") implementation("com.squareup:javapoet:1.13.0") implementation("com.squareup.wire:wire-compiler") implementation("com.squareup.wire:wire-gradle-plugin") From 227580ba0956fcd43429d684b7e0798c8723481a Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 22 Dec 2023 15:53:29 -0800 Subject: [PATCH 162/901] Update dependency nl.jqno.equalsverifier:equalsverifier to v3.15.5 (#6094) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- dependencyManagement/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index 4517f63601b..fa5f9d3ec6f 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -70,7 +70,7 @@ val DEPENDENCIES = listOf( "io.opentracing:opentracing-api:0.33.0", "io.opentracing:opentracing-noop:0.33.0", "junit:junit:4.13.2", - "nl.jqno.equalsverifier:equalsverifier:3.15.4", + "nl.jqno.equalsverifier:equalsverifier:3.15.5", "org.awaitility:awaitility:4.2.0", "org.bouncycastle:bcpkix-jdk15on:1.70", "org.codehaus.mojo:animal-sniffer-annotations:1.23", From 4f6cc700b58d88e1bbe5b4fd65e82c11dec7976d Mon Sep 17 00:00:00 2001 From: Jean Bisutti Date: Tue, 2 Jan 2024 17:03:51 +0100 Subject: [PATCH 163/901] Ability to access version.properties API file with GraalVM native (#6095) --- .../opentelemetry-api/reflect-config.json | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 api/all/src/main/resources/META-INF/native-image/io.opentelemetry/opentelemetry-api/reflect-config.json diff --git a/api/all/src/main/resources/META-INF/native-image/io.opentelemetry/opentelemetry-api/reflect-config.json b/api/all/src/main/resources/META-INF/native-image/io.opentelemetry/opentelemetry-api/reflect-config.json new file mode 100644 index 00000000000..a8c57fbdb83 --- /dev/null +++ b/api/all/src/main/resources/META-INF/native-image/io.opentelemetry/opentelemetry-api/reflect-config.json @@ -0,0 +1,10 @@ +{ + "resources": { + "includes": [ + { + "pattern":"\\Qio/opentelemetry/api/version.properties\\E" + } + ] + }, + "bundles": [] +} From e588eb80420a29a020b41618169546e5198d60aa Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 2 Jan 2024 11:17:11 -0600 Subject: [PATCH 164/901] Update dependency org.assertj:assertj-bom to v3.25.0 (#6102) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- dependencyManagement/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index fa5f9d3ec6f..f29bf90af96 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -18,7 +18,7 @@ val DEPENDENCY_BOMS = listOf( "io.netty:netty-bom:4.1.104.Final", "io.zipkin.brave:brave-bom:5.17.0", "io.zipkin.reporter2:zipkin-reporter-bom:2.17.1", - "org.assertj:assertj-bom:3.24.2", + "org.assertj:assertj-bom:3.25.0", "org.junit:junit-bom:5.10.1", "org.testcontainers:testcontainers-bom:1.19.3", "org.snakeyaml:snakeyaml-engine:2.7" From 1b4f5aeab5f9d788c6af68fa8b4b0fb1ee66626d Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 2 Jan 2024 11:34:11 -0600 Subject: [PATCH 165/901] Update dependency checkstyle to v10.12.7 (#6101) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- buildSrc/src/main/kotlin/otel.java-conventions.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/buildSrc/src/main/kotlin/otel.java-conventions.gradle.kts b/buildSrc/src/main/kotlin/otel.java-conventions.gradle.kts index ea77a98b438..d079343e045 100644 --- a/buildSrc/src/main/kotlin/otel.java-conventions.gradle.kts +++ b/buildSrc/src/main/kotlin/otel.java-conventions.gradle.kts @@ -35,7 +35,7 @@ java { checkstyle { configDirectory.set(file("$rootDir/buildscripts/")) - toolVersion = "10.12.6" + toolVersion = "10.12.7" isIgnoreFailures = false configProperties["rootDir"] = rootDir } From fcd7812d776989a38425866f426e9608aed77e22 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 2 Jan 2024 11:36:58 -0600 Subject: [PATCH 166/901] Update slf4jVersion to v2.0.10 (#6099) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- dependencyManagement/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index f29bf90af96..a15719ffaee 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -29,7 +29,7 @@ val errorProneVersion = "2.23.0" val jmhVersion = "1.37" // Mockito 5.x.x requires Java 11 https://github.com/mockito/mockito/releases/tag/v5.0.0 val mockitoVersion = "4.11.0" -val slf4jVersion = "2.0.9" +val slf4jVersion = "2.0.10" val opencensusVersion = "0.31.1" val prometheusClientVersion = "0.16.0" From a265b288fd569f8e96bbbadabc4de3e17c80bea2 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 2 Jan 2024 11:37:19 -0600 Subject: [PATCH 167/901] Update dependency com.fasterxml.jackson:jackson-bom to v2.16.1 (#6096) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- dependencyManagement/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index a15719ffaee..a8a5563609a 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -8,7 +8,7 @@ val dependencyVersions = hashMapOf() rootProject.extra["versions"] = dependencyVersions val DEPENDENCY_BOMS = listOf( - "com.fasterxml.jackson:jackson-bom:2.16.0", + "com.fasterxml.jackson:jackson-bom:2.16.1", "com.google.guava:guava-bom:33.0.0-jre", "com.google.protobuf:protobuf-bom:3.25.1", "com.linecorp.armeria:armeria-bom:1.26.4", From d81dabff4b96c46ef7239ffded1ccde736f63a70 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 2 Jan 2024 11:37:39 -0600 Subject: [PATCH 168/901] Update dependency com.uber.nullaway:nullaway to v0.10.19 (#6097) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- dependencyManagement/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index a8a5563609a..e32e0b14ca4 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -60,7 +60,7 @@ val DEPENDENCIES = listOf( "com.google.guava:guava-beta-checker:1.0", "com.sun.net.httpserver:http:20070405", "com.tngtech.archunit:archunit-junit5:1.2.1", - "com.uber.nullaway:nullaway:0.10.18", + "com.uber.nullaway:nullaway:0.10.19", "edu.berkeley.cs.jqf:jqf-fuzz:1.7", // jqf-fuzz version 1.8+ requires Java 11+ "eu.rekawek.toxiproxy:toxiproxy-java:2.1.7", "io.github.netmikey.logunit:logunit-jul:2.0.0", From b48893bb9daf4a9c9546ef8250bd84fafd764b9e Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 2 Jan 2024 11:43:10 -0600 Subject: [PATCH 169/901] Update dependency io.grpc:grpc-bom to v1.60.1 (#6091) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- dependencyManagement/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index e32e0b14ca4..566cca58427 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -14,7 +14,7 @@ val DEPENDENCY_BOMS = listOf( "com.linecorp.armeria:armeria-bom:1.26.4", "com.squareup.okhttp3:okhttp-bom:4.12.0", "com.squareup.okio:okio-bom:3.7.0", // applies to transitive dependencies of okhttp - "io.grpc:grpc-bom:1.60.0", + "io.grpc:grpc-bom:1.60.1", "io.netty:netty-bom:4.1.104.Final", "io.zipkin.brave:brave-bom:5.17.0", "io.zipkin.reporter2:zipkin-reporter-bom:2.17.1", From 0c436e0a297a8dc5e5c5d79f824e46841a523ca6 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 2 Jan 2024 11:54:34 -0600 Subject: [PATCH 170/901] Update dependency org.jetbrains.kotlin:kotlin-gradle-plugin to v1.9.22 (#6090) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- buildSrc/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts index 6b6f9c152e6..a3b5d22de27 100644 --- a/buildSrc/build.gradle.kts +++ b/buildSrc/build.gradle.kts @@ -57,7 +57,7 @@ dependencies { implementation("me.champeau.jmh:jmh-gradle-plugin:0.7.2") implementation("net.ltgt.gradle:gradle-errorprone-plugin:3.1.0") implementation("net.ltgt.gradle:gradle-nullaway-plugin:1.6.0") - implementation("org.jetbrains.kotlin:kotlin-gradle-plugin:1.9.21") + implementation("org.jetbrains.kotlin:kotlin-gradle-plugin:1.9.22") implementation("org.owasp:dependency-check-gradle:9.0.7") implementation("ru.vyarus:gradle-animalsniffer-plugin:1.7.1") } From e1b1963088826459757ce05dfd759d824af2003b Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 2 Jan 2024 12:59:29 -0600 Subject: [PATCH 171/901] Update errorProneVersion to v2.24.0 (#6092) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Co-authored-by: Jack Berg --- dependencyManagement/build.gradle.kts | 2 +- .../sdk/metrics/internal/export/RegisteredReaderTest.java | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index 566cca58427..c2f4eb5bd00 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -25,7 +25,7 @@ val DEPENDENCY_BOMS = listOf( ) val autoValueVersion = "1.10.4" -val errorProneVersion = "2.23.0" +val errorProneVersion = "2.24.0" val jmhVersion = "1.37" // Mockito 5.x.x requires Java 11 https://github.com/mockito/mockito/releases/tag/v5.0.0 val mockitoVersion = "4.11.0" diff --git a/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/internal/export/RegisteredReaderTest.java b/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/internal/export/RegisteredReaderTest.java index 36e727c861e..e151876e6a9 100644 --- a/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/internal/export/RegisteredReaderTest.java +++ b/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/internal/export/RegisteredReaderTest.java @@ -24,7 +24,6 @@ void create_UniqueIdentity() { RegisteredReader registeredReader1 = RegisteredReader.create(reader, ViewRegistry.create()); RegisteredReader registeredReader2 = RegisteredReader.create(reader, ViewRegistry.create()); - assertThat(registeredReader1).isEqualTo(registeredReader1); assertThat(registeredReader1).isNotEqualTo(registeredReader2); assertThat(registeredReader1.hashCode()).isEqualTo(registeredReader1.hashCode()); From 60ae0af7f683af11588bc540c052d8f3bc40ef74 Mon Sep 17 00:00:00 2001 From: jack-berg <34418638+jack-berg@users.noreply.github.com> Date: Tue, 2 Jan 2024 15:00:54 -0600 Subject: [PATCH 172/901] Add compressor SPI to support additional compression algos (#5990) --- .../internal/compression/Compressor.java | 32 +++++++ .../compression/CompressorProvider.java | 18 ++++ .../internal/compression/CompressorUtil.java | 59 ++++++++++++ .../internal/compression/GzipCompressor.java | 37 ++++++++ .../internal/http/HttpExporterBuilder.java | 16 ++-- .../internal/http/HttpSenderProvider.java | 3 +- .../OtlpHttpLogRecordExporterBuilder.java | 15 ++- .../OtlpHttpMetricExporterBuilder.java | 15 ++- .../trace/OtlpHttpSpanExporterBuilder.java | 15 ++- .../AbstractHttpTelemetryExporterTest.java | 63 +++++++++---- .../internal/compressor/Base64Compressor.java | 35 +++++++ .../compressor/Base64CompressorProvider.java | 17 ++++ ...er.internal.compression.CompressorProvider | 1 + .../sender/jdk/internal/JdkHttpSender.java | 20 ++-- .../jdk/internal/JdkHttpSenderProvider.java | 5 +- .../jdk/internal/JdkHttpSenderTest.java | 4 +- .../okhttp/internal/OkHttpHttpSender.java | 27 +++--- .../internal/OkHttpHttpSenderProvider.java | 5 +- .../internal/HttpExporterBuilderTest.java | 92 ------------------- .../internal/OkHttpHttpSuppressionTest.java | 2 +- 20 files changed, 327 insertions(+), 154 deletions(-) create mode 100644 exporters/common/src/main/java/io/opentelemetry/exporter/internal/compression/Compressor.java create mode 100644 exporters/common/src/main/java/io/opentelemetry/exporter/internal/compression/CompressorProvider.java create mode 100644 exporters/common/src/main/java/io/opentelemetry/exporter/internal/compression/CompressorUtil.java create mode 100644 exporters/common/src/main/java/io/opentelemetry/exporter/internal/compression/GzipCompressor.java create mode 100644 exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/compressor/Base64Compressor.java create mode 100644 exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/compressor/Base64CompressorProvider.java create mode 100644 exporters/otlp/testing-internal/src/main/resources/META-INF/services/io.opentelemetry.exporter.internal.compression.CompressorProvider delete mode 100644 exporters/sender/okhttp/src/test/java/io/opentelemetry/exporter/sender/okhttp/internal/HttpExporterBuilderTest.java diff --git a/exporters/common/src/main/java/io/opentelemetry/exporter/internal/compression/Compressor.java b/exporters/common/src/main/java/io/opentelemetry/exporter/internal/compression/Compressor.java new file mode 100644 index 00000000000..71894cc9d4a --- /dev/null +++ b/exporters/common/src/main/java/io/opentelemetry/exporter/internal/compression/Compressor.java @@ -0,0 +1,32 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.exporter.internal.compression; + +import java.io.IOException; +import java.io.OutputStream; +import javax.annotation.concurrent.ThreadSafe; + +/** + * An abstraction for compressing messages. Implementation MUST be thread safe as the same instance + * is expected to be used many times and concurrently. Instances are usually singletons. + * + *

    This class is internal and is hence not for public use. Its APIs are unstable and can change + * at any time. + */ +@ThreadSafe +public interface Compressor { + + /** + * The name of the compressor encoding. + * + *

    Used to identify the compressor during configuration and to populate the {@code + * Content-Encoding} header. + */ + String getEncoding(); + + /** Wrap the {@code outputStream} with a compressing output stream. */ + OutputStream compress(OutputStream outputStream) throws IOException; +} diff --git a/exporters/common/src/main/java/io/opentelemetry/exporter/internal/compression/CompressorProvider.java b/exporters/common/src/main/java/io/opentelemetry/exporter/internal/compression/CompressorProvider.java new file mode 100644 index 00000000000..6b4518f1ea0 --- /dev/null +++ b/exporters/common/src/main/java/io/opentelemetry/exporter/internal/compression/CompressorProvider.java @@ -0,0 +1,18 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.exporter.internal.compression; + +/** + * A service provider interface (SPI) for providing {@link Compressor}s. + * + *

    This class is internal and is hence not for public use. Its APIs are unstable and can change + * at any time. + */ +public interface CompressorProvider { + + /** Return the {@link Compressor}. */ + Compressor getInstance(); +} diff --git a/exporters/common/src/main/java/io/opentelemetry/exporter/internal/compression/CompressorUtil.java b/exporters/common/src/main/java/io/opentelemetry/exporter/internal/compression/CompressorUtil.java new file mode 100644 index 00000000000..6a777f759ba --- /dev/null +++ b/exporters/common/src/main/java/io/opentelemetry/exporter/internal/compression/CompressorUtil.java @@ -0,0 +1,59 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.exporter.internal.compression; + +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; +import java.util.ServiceLoader; +import java.util.Set; + +/** + * Utilities for resolving SPI {@link Compressor}s. + * + *

    This class is internal and is hence not for public use. Its APIs are unstable and can change + * at any time. + * + * @see CompressorProvider + */ +public final class CompressorUtil { + + private static final Map compressorRegistry = buildCompressorRegistry(); + + private CompressorUtil() {} + + /** Get list of loaded compressors, named according to {@link Compressor#getEncoding()}. */ + public static Set supportedCompressors() { + return Collections.unmodifiableSet(compressorRegistry.keySet()); + } + + /** + * Resolve the {@link Compressor} with the {@link Compressor#getEncoding()} equal to the {@code + * encoding}. + * + * @throws IllegalArgumentException if no match is found + */ + public static Compressor resolveCompressor(String encoding) { + Compressor compressor = compressorRegistry.get(encoding); + if (compressor == null) { + throw new IllegalArgumentException( + "Could not resolve compressor for encoding \"" + encoding + "\"."); + } + return compressor; + } + + private static Map buildCompressorRegistry() { + Map compressors = new HashMap<>(); + for (CompressorProvider spi : + ServiceLoader.load(CompressorProvider.class, CompressorUtil.class.getClassLoader())) { + Compressor compressor = spi.getInstance(); + compressors.put(compressor.getEncoding(), compressor); + } + // Hardcode gzip compressor + compressors.put(GzipCompressor.getInstance().getEncoding(), GzipCompressor.getInstance()); + return compressors; + } +} diff --git a/exporters/common/src/main/java/io/opentelemetry/exporter/internal/compression/GzipCompressor.java b/exporters/common/src/main/java/io/opentelemetry/exporter/internal/compression/GzipCompressor.java new file mode 100644 index 00000000000..7395fdb41b1 --- /dev/null +++ b/exporters/common/src/main/java/io/opentelemetry/exporter/internal/compression/GzipCompressor.java @@ -0,0 +1,37 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.exporter.internal.compression; + +import java.io.IOException; +import java.io.OutputStream; +import java.util.zip.GZIPOutputStream; + +/** + * Gzip {@link Compressor}. + * + *

    This class is internal and is hence not for public use. Its APIs are unstable and can change + * at any time. + */ +public final class GzipCompressor implements Compressor { + + private static final GzipCompressor INSTANCE = new GzipCompressor(); + + private GzipCompressor() {} + + public static GzipCompressor getInstance() { + return INSTANCE; + } + + @Override + public String getEncoding() { + return "gzip"; + } + + @Override + public OutputStream compress(OutputStream outputStream) throws IOException { + return new GZIPOutputStream(outputStream); + } +} diff --git a/exporters/common/src/main/java/io/opentelemetry/exporter/internal/http/HttpExporterBuilder.java b/exporters/common/src/main/java/io/opentelemetry/exporter/internal/http/HttpExporterBuilder.java index ad46956a702..2285cc97729 100644 --- a/exporters/common/src/main/java/io/opentelemetry/exporter/internal/http/HttpExporterBuilder.java +++ b/exporters/common/src/main/java/io/opentelemetry/exporter/internal/http/HttpExporterBuilder.java @@ -11,6 +11,7 @@ import io.opentelemetry.exporter.internal.ExporterBuilderUtil; import io.opentelemetry.exporter.internal.TlsConfigHelper; import io.opentelemetry.exporter.internal.auth.Authenticator; +import io.opentelemetry.exporter.internal.compression.Compressor; import io.opentelemetry.exporter.internal.marshal.Marshaler; import io.opentelemetry.sdk.common.export.RetryPolicy; import java.net.URI; @@ -19,6 +20,7 @@ import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Optional; import java.util.ServiceLoader; import java.util.StringJoiner; import java.util.concurrent.TimeUnit; @@ -48,8 +50,8 @@ public final class HttpExporterBuilder { private String endpoint; private long timeoutNanos = TimeUnit.SECONDS.toNanos(DEFAULT_TIMEOUT_SECS); + @Nullable private Compressor compressor; private long connectTimeoutNanos = TimeUnit.SECONDS.toNanos(DEFAULT_CONNECT_TIMEOUT_SECS); - private boolean compressionEnabled = false; private boolean exportAsJson = false; private final Map constantHeaders = new HashMap<>(); private Supplier> headerSupplier = Collections::emptyMap; @@ -82,8 +84,8 @@ public HttpExporterBuilder setEndpoint(String endpoint) { return this; } - public HttpExporterBuilder setCompression(String compressionMethod) { - this.compressionEnabled = compressionMethod.equals("gzip"); + public HttpExporterBuilder setCompression(@Nullable Compressor compressor) { + this.compressor = compressor; return this; } @@ -141,7 +143,7 @@ public HttpExporterBuilder copy() { copy.timeoutNanos = timeoutNanos; copy.connectTimeoutNanos = connectTimeoutNanos; copy.exportAsJson = exportAsJson; - copy.compressionEnabled = compressionEnabled; + copy.compressor = compressor; copy.constantHeaders.putAll(constantHeaders); copy.headerSupplier = headerSupplier; copy.tlsConfigHelper = tlsConfigHelper.copy(); @@ -179,7 +181,7 @@ public HttpExporter build() { HttpSender httpSender = httpSenderProvider.createSender( endpoint, - compressionEnabled, + compressor, exportAsJson ? "application/json" : "application/x-protobuf", timeoutNanos, connectTimeoutNanos, @@ -202,8 +204,10 @@ public String toString(boolean includePrefixAndSuffix) { joiner.add("type=" + type); joiner.add("endpoint=" + endpoint); joiner.add("timeoutNanos=" + timeoutNanos); + joiner.add( + "compressorEncoding=" + + Optional.ofNullable(compressor).map(Compressor::getEncoding).orElse(null)); joiner.add("connectTimeoutNanos=" + connectTimeoutNanos); - joiner.add("compressionEnabled=" + compressionEnabled); joiner.add("exportAsJson=" + exportAsJson); StringJoiner headersJoiner = new StringJoiner(", ", "Headers{", "}"); constantHeaders.forEach((key, value) -> headersJoiner.add(key + "=OBFUSCATED")); diff --git a/exporters/common/src/main/java/io/opentelemetry/exporter/internal/http/HttpSenderProvider.java b/exporters/common/src/main/java/io/opentelemetry/exporter/internal/http/HttpSenderProvider.java index 6ab06f31d98..20d4322ae67 100644 --- a/exporters/common/src/main/java/io/opentelemetry/exporter/internal/http/HttpSenderProvider.java +++ b/exporters/common/src/main/java/io/opentelemetry/exporter/internal/http/HttpSenderProvider.java @@ -6,6 +6,7 @@ package io.opentelemetry.exporter.internal.http; import io.opentelemetry.exporter.internal.auth.Authenticator; +import io.opentelemetry.exporter.internal.compression.Compressor; import io.opentelemetry.sdk.common.export.RetryPolicy; import java.util.List; import java.util.Map; @@ -27,7 +28,7 @@ public interface HttpSenderProvider { @SuppressWarnings("TooManyParameters") HttpSender createSender( String endpoint, - boolean compressionEnabled, + @Nullable Compressor compressor, String contentType, long timeoutNanos, long connectTimeout, diff --git a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/logs/OtlpHttpLogRecordExporterBuilder.java b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/logs/OtlpHttpLogRecordExporterBuilder.java index 59a84e76e72..5861cd15832 100644 --- a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/logs/OtlpHttpLogRecordExporterBuilder.java +++ b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/logs/OtlpHttpLogRecordExporterBuilder.java @@ -7,15 +7,18 @@ import static io.opentelemetry.api.internal.Utils.checkArgument; import static java.util.Objects.requireNonNull; +import static java.util.stream.Collectors.joining; import io.opentelemetry.api.GlobalOpenTelemetry; import io.opentelemetry.api.metrics.MeterProvider; +import io.opentelemetry.exporter.internal.compression.CompressorUtil; import io.opentelemetry.exporter.internal.http.HttpExporterBuilder; import io.opentelemetry.exporter.internal.otlp.logs.LogsRequestMarshaler; import io.opentelemetry.exporter.otlp.internal.OtlpUserAgent; import io.opentelemetry.sdk.common.export.RetryPolicy; import java.time.Duration; import java.util.Map; +import java.util.Set; import java.util.concurrent.TimeUnit; import java.util.function.Supplier; import javax.net.ssl.SSLContext; @@ -101,10 +104,16 @@ public OtlpHttpLogRecordExporterBuilder setEndpoint(String endpoint) { */ public OtlpHttpLogRecordExporterBuilder setCompression(String compressionMethod) { requireNonNull(compressionMethod, "compressionMethod"); + if (compressionMethod.equals("none")) { + delegate.setCompression(null); + return this; + } + Set supportedCompressionMethods = CompressorUtil.supportedCompressors(); checkArgument( - compressionMethod.equals("gzip") || compressionMethod.equals("none"), - "Unsupported compression method. Supported compression methods include: gzip, none."); - delegate.setCompression(compressionMethod); + supportedCompressionMethods.contains(compressionMethod), + "Unsupported compressionMethod. Compression method must be \"none\" or one of: " + + supportedCompressionMethods.stream().collect(joining(",", "[", "]"))); + delegate.setCompression(CompressorUtil.resolveCompressor(compressionMethod)); return this; } diff --git a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/metrics/OtlpHttpMetricExporterBuilder.java b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/metrics/OtlpHttpMetricExporterBuilder.java index 5d573da557e..9f97d7b3f9e 100644 --- a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/metrics/OtlpHttpMetricExporterBuilder.java +++ b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/metrics/OtlpHttpMetricExporterBuilder.java @@ -7,8 +7,10 @@ import static io.opentelemetry.api.internal.Utils.checkArgument; import static java.util.Objects.requireNonNull; +import static java.util.stream.Collectors.joining; import io.opentelemetry.api.metrics.MeterProvider; +import io.opentelemetry.exporter.internal.compression.CompressorUtil; import io.opentelemetry.exporter.internal.http.HttpExporterBuilder; import io.opentelemetry.exporter.internal.otlp.metrics.MetricsRequestMarshaler; import io.opentelemetry.exporter.otlp.internal.OtlpUserAgent; @@ -19,6 +21,7 @@ import io.opentelemetry.sdk.metrics.export.MetricExporter; import java.time.Duration; import java.util.Map; +import java.util.Set; import java.util.concurrent.TimeUnit; import java.util.function.Supplier; import javax.net.ssl.SSLContext; @@ -113,10 +116,16 @@ public OtlpHttpMetricExporterBuilder setEndpoint(String endpoint) { */ public OtlpHttpMetricExporterBuilder setCompression(String compressionMethod) { requireNonNull(compressionMethod, "compressionMethod"); + if (compressionMethod.equals("none")) { + delegate.setCompression(null); + return this; + } + Set supportedCompressionMethods = CompressorUtil.supportedCompressors(); checkArgument( - compressionMethod.equals("gzip") || compressionMethod.equals("none"), - "Unsupported compression method. Supported compression methods include: gzip, none."); - delegate.setCompression(compressionMethod); + supportedCompressionMethods.contains(compressionMethod), + "Unsupported compressionMethod. Compression method must be \"none\" or one of: " + + supportedCompressionMethods.stream().collect(joining(",", "[", "]"))); + delegate.setCompression(CompressorUtil.resolveCompressor(compressionMethod)); return this; } diff --git a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/trace/OtlpHttpSpanExporterBuilder.java b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/trace/OtlpHttpSpanExporterBuilder.java index 58768c98881..ed5975aa4b2 100644 --- a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/trace/OtlpHttpSpanExporterBuilder.java +++ b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/trace/OtlpHttpSpanExporterBuilder.java @@ -7,15 +7,18 @@ import static io.opentelemetry.api.internal.Utils.checkArgument; import static java.util.Objects.requireNonNull; +import static java.util.stream.Collectors.joining; import io.opentelemetry.api.GlobalOpenTelemetry; import io.opentelemetry.api.metrics.MeterProvider; +import io.opentelemetry.exporter.internal.compression.CompressorUtil; import io.opentelemetry.exporter.internal.http.HttpExporterBuilder; import io.opentelemetry.exporter.internal.otlp.traces.TraceRequestMarshaler; import io.opentelemetry.exporter.otlp.internal.OtlpUserAgent; import io.opentelemetry.sdk.common.export.RetryPolicy; import java.time.Duration; import java.util.Map; +import java.util.Set; import java.util.concurrent.TimeUnit; import java.util.function.Supplier; import javax.net.ssl.SSLContext; @@ -101,10 +104,16 @@ public OtlpHttpSpanExporterBuilder setEndpoint(String endpoint) { */ public OtlpHttpSpanExporterBuilder setCompression(String compressionMethod) { requireNonNull(compressionMethod, "compressionMethod"); + if (compressionMethod.equals("none")) { + delegate.setCompression(null); + return this; + } + Set supportedCompressionMethods = CompressorUtil.supportedCompressors(); checkArgument( - compressionMethod.equals("gzip") || compressionMethod.equals("none"), - "Unsupported compression method. Supported compression methods include: gzip, none."); - delegate.setCompression(compressionMethod); + supportedCompressionMethods.contains(compressionMethod), + "Unsupported compressionMethod. Compression method must be \"none\" or one of: " + + supportedCompressionMethods.stream().collect(joining(",", "[", "]"))); + delegate.setCompression(CompressorUtil.resolveCompressor(compressionMethod)); return this; } diff --git a/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/AbstractHttpTelemetryExporterTest.java b/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/AbstractHttpTelemetryExporterTest.java index a29b9f0b5b2..3b903ba0c32 100644 --- a/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/AbstractHttpTelemetryExporterTest.java +++ b/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/AbstractHttpTelemetryExporterTest.java @@ -27,8 +27,10 @@ import com.linecorp.armeria.testing.junit5.server.ServerExtension; import io.github.netmikey.logunit.api.LogCapturer; import io.opentelemetry.exporter.internal.TlsUtil; +import io.opentelemetry.exporter.internal.compression.GzipCompressor; import io.opentelemetry.exporter.internal.http.HttpExporter; import io.opentelemetry.exporter.internal.marshal.Marshaler; +import io.opentelemetry.exporter.otlp.testing.internal.compressor.Base64Compressor; import io.opentelemetry.internal.testing.slf4j.SuppressLogger; import io.opentelemetry.proto.collector.logs.v1.ExportLogsServiceRequest; import io.opentelemetry.proto.collector.logs.v1.ExportLogsServiceResponse; @@ -49,6 +51,7 @@ import java.time.Duration; import java.util.ArrayList; import java.util.Arrays; +import java.util.Base64; import java.util.Collections; import java.util.List; import java.util.concurrent.CompletableFuture; @@ -66,6 +69,7 @@ import okio.Buffer; import okio.GzipSource; import okio.Okio; +import okio.Source; import org.assertj.core.api.iterable.ThrowingExtractor; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.AfterEach; @@ -163,8 +167,7 @@ public HttpResponse serve(ServiceRequestContext ctx, HttpRequest req) { aggReq -> { T request; try { - byte[] requestBody = - maybeGzipInflate(aggReq.headers(), aggReq.content().array()); + byte[] requestBody = maybeInflate(aggReq.headers(), aggReq.content().array()); request = parse.extractThrows(requestBody); } catch (IOException e) { throw new UncheckedIOException(e); @@ -181,15 +184,22 @@ public HttpResponse serve(ServiceRequestContext ctx, HttpRequest req) { return HttpResponse.of(responseFuture); } - private static byte[] maybeGzipInflate(RequestHeaders requestHeaders, byte[] content) + private static byte[] maybeInflate(RequestHeaders requestHeaders, byte[] content) throws IOException { - if (!requestHeaders.contains("content-encoding", "gzip")) { - return content; + if (requestHeaders.contains("content-encoding", "gzip")) { + Buffer buffer = new Buffer(); + GzipSource gzipSource = new GzipSource(Okio.source(new ByteArrayInputStream(content))); + gzipSource.read(buffer, Integer.MAX_VALUE); + return buffer.readByteArray(); } - Buffer buffer = new Buffer(); - GzipSource gzipSource = new GzipSource(Okio.source(new ByteArrayInputStream(content))); - gzipSource.read(buffer, Integer.MAX_VALUE); - return buffer.readByteArray(); + if (requestHeaders.contains("content-encoding", "base64")) { + Buffer buffer = new Buffer(); + Source base64Source = + Okio.source(Base64.getDecoder().wrap(new ByteArrayInputStream(content))); + base64Source.read(buffer, Integer.MAX_VALUE); + return buffer.readByteArray(); + } + return content; } } @@ -275,9 +285,7 @@ void multipleItems() { void compressionWithNone() { TelemetryExporter exporter = exporterBuilder().setEndpoint(server.httpUri() + path).setCompression("none").build(); - assertThat(exporter.unwrap()) - .extracting("delegate.httpSender.compressionEnabled") - .isEqualTo(false); + assertThat(exporter.unwrap()).extracting("delegate.httpSender.compressor").isNull(); try { CompletableResultCode result = exporter.export(Collections.singletonList(generateFakeTelemetry())); @@ -295,8 +303,8 @@ void compressionWithGzip() { TelemetryExporter exporter = exporterBuilder().setEndpoint(server.httpUri() + path).setCompression("gzip").build(); assertThat(exporter.unwrap()) - .extracting("delegate.httpSender.compressionEnabled") - .isEqualTo(true); + .extracting("delegate.httpSender.compressor") + .isEqualTo(GzipCompressor.getInstance()); try { CompletableResultCode result = exporter.export(Collections.singletonList(generateFakeTelemetry())); @@ -309,6 +317,25 @@ void compressionWithGzip() { } } + @Test + void compressionWithSpiCompressor() { + TelemetryExporter exporter = + exporterBuilder().setEndpoint(server.httpUri() + path).setCompression("base64").build(); + assertThat(exporter.unwrap()) + .extracting("delegate.httpSender.compressor") + .isEqualTo(Base64Compressor.getInstance()); + try { + CompletableResultCode result = + exporter.export(Collections.singletonList(generateFakeTelemetry())); + assertThat(result.join(10, TimeUnit.SECONDS).isSuccess()).isTrue(); + assertThat(httpRequests) + .singleElement() + .satisfies(req -> assertThat(req.headers().get("content-encoding")).isEqualTo("base64")); + } finally { + exporter.shutdown(); + } + } + @Test void authorityWithAuth() { TelemetryExporter exporter = @@ -659,6 +686,8 @@ void validConfig() { .doesNotThrowAnyException(); assertThatCode(() -> exporterBuilder().setCompression("gzip")).doesNotThrowAnyException(); + // SPI compressor available for this test but not packaged with OTLP exporter + assertThatCode(() -> exporterBuilder().setCompression("base64")).doesNotThrowAnyException(); assertThatCode(() -> exporterBuilder().setCompression("none")).doesNotThrowAnyException(); assertThatCode(() -> exporterBuilder().addHeader("foo", "bar").addHeader("baz", "qux")) @@ -711,7 +740,7 @@ void invalidConfig() { assertThatThrownBy(() -> exporterBuilder().setCompression("foo")) .isInstanceOf(IllegalArgumentException.class) .hasMessage( - "Unsupported compression method. Supported compression methods include: gzip, none."); + "Unsupported compressionMethod. Compression method must be \"none\" or one of: [base64,gzip]"); } @Test @@ -786,10 +815,10 @@ void stringRepresentation() throws IOException, CertificateEncodingException { + "timeoutNanos=" + TimeUnit.SECONDS.toNanos(10) + ", " + + "compressorEncoding=null, " + "connectTimeoutNanos=" + TimeUnit.SECONDS.toNanos(10) + ", " - + "compressionEnabled=false, " + "exportAsJson=false, " + "headers=Headers\\{User-Agent=OBFUSCATED\\}" + "\\}"); @@ -826,10 +855,10 @@ void stringRepresentation() throws IOException, CertificateEncodingException { + "timeoutNanos=" + TimeUnit.SECONDS.toNanos(5) + ", " + + "compressorEncoding=gzip, " + "connectTimeoutNanos=" + TimeUnit.SECONDS.toNanos(4) + ", " - + "compressionEnabled=true, " + "exportAsJson=false, " + "headers=Headers\\{.*foo=OBFUSCATED.*\\}, " + "retryPolicy=RetryPolicy\\{maxAttempts=2, initialBackoff=PT0\\.05S, maxBackoff=PT3S, backoffMultiplier=1\\.3\\}" diff --git a/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/compressor/Base64Compressor.java b/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/compressor/Base64Compressor.java new file mode 100644 index 00000000000..b0b3121d635 --- /dev/null +++ b/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/compressor/Base64Compressor.java @@ -0,0 +1,35 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.exporter.otlp.testing.internal.compressor; + +import io.opentelemetry.exporter.internal.compression.Compressor; +import java.io.OutputStream; +import java.util.Base64; + +/** + * This exists to test the compressor SPI mechanism but does not actually compress data in any + * useful way. + */ +public class Base64Compressor implements Compressor { + + private static final Base64Compressor INSTANCE = new Base64Compressor(); + + private Base64Compressor() {} + + public static Base64Compressor getInstance() { + return INSTANCE; + } + + @Override + public String getEncoding() { + return "base64"; + } + + @Override + public OutputStream compress(OutputStream outputStream) { + return Base64.getEncoder().wrap(outputStream); + } +} diff --git a/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/compressor/Base64CompressorProvider.java b/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/compressor/Base64CompressorProvider.java new file mode 100644 index 00000000000..8d4b4a6cdbc --- /dev/null +++ b/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/compressor/Base64CompressorProvider.java @@ -0,0 +1,17 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.exporter.otlp.testing.internal.compressor; + +import io.opentelemetry.exporter.internal.compression.Compressor; +import io.opentelemetry.exporter.internal.compression.CompressorProvider; + +public class Base64CompressorProvider implements CompressorProvider { + + @Override + public Compressor getInstance() { + return Base64Compressor.getInstance(); + } +} diff --git a/exporters/otlp/testing-internal/src/main/resources/META-INF/services/io.opentelemetry.exporter.internal.compression.CompressorProvider b/exporters/otlp/testing-internal/src/main/resources/META-INF/services/io.opentelemetry.exporter.internal.compression.CompressorProvider new file mode 100644 index 00000000000..6fac487c249 --- /dev/null +++ b/exporters/otlp/testing-internal/src/main/resources/META-INF/services/io.opentelemetry.exporter.internal.compression.CompressorProvider @@ -0,0 +1 @@ +io.opentelemetry.exporter.otlp.testing.internal.compressor.Base64CompressorProvider diff --git a/exporters/sender/jdk/src/main/java/io/opentelemetry/exporter/sender/jdk/internal/JdkHttpSender.java b/exporters/sender/jdk/src/main/java/io/opentelemetry/exporter/sender/jdk/internal/JdkHttpSender.java index 673b315d230..73d895a4883 100644 --- a/exporters/sender/jdk/src/main/java/io/opentelemetry/exporter/sender/jdk/internal/JdkHttpSender.java +++ b/exporters/sender/jdk/src/main/java/io/opentelemetry/exporter/sender/jdk/internal/JdkHttpSender.java @@ -5,6 +5,7 @@ package io.opentelemetry.exporter.sender.jdk.internal; +import io.opentelemetry.exporter.internal.compression.Compressor; import io.opentelemetry.exporter.internal.http.HttpSender; import io.opentelemetry.sdk.common.CompletableResultCode; import io.opentelemetry.sdk.common.export.RetryPolicy; @@ -29,7 +30,6 @@ import java.util.concurrent.TimeUnit; import java.util.function.Consumer; import java.util.function.Supplier; -import java.util.zip.GZIPOutputStream; import javax.annotation.Nullable; import javax.net.ssl.SSLContext; import javax.net.ssl.SSLException; @@ -52,7 +52,7 @@ public final class JdkHttpSender implements HttpSender { private final ExecutorService executorService = Executors.newFixedThreadPool(5); private final HttpClient client; private final URI uri; - private final boolean compressionEnabled; + @Nullable private final Compressor compressor; private final String contentType; private final long timeoutNanos; private final Supplier>> headerSupplier; @@ -62,7 +62,7 @@ public final class JdkHttpSender implements HttpSender { JdkHttpSender( HttpClient client, String endpoint, - boolean compressionEnabled, + @Nullable Compressor compressor, String contentType, long timeoutNanos, Supplier>> headerSupplier, @@ -73,7 +73,7 @@ public final class JdkHttpSender implements HttpSender { } catch (URISyntaxException e) { throw new IllegalArgumentException(e); } - this.compressionEnabled = compressionEnabled; + this.compressor = compressor; this.contentType = contentType; this.timeoutNanos = timeoutNanos; this.headerSupplier = headerSupplier; @@ -82,7 +82,7 @@ public final class JdkHttpSender implements HttpSender { JdkHttpSender( String endpoint, - boolean compressionEnabled, + @Nullable Compressor compressor, String contentType, long timeoutNanos, long connectTimeoutNanos, @@ -92,7 +92,7 @@ public final class JdkHttpSender implements HttpSender { this( configureClient(sslContext, connectTimeoutNanos), endpoint, - compressionEnabled, + compressor, contentType, timeoutNanos, headerSupplier, @@ -148,10 +148,10 @@ HttpResponse sendInternal(Consumer marshaler) throws IOExc NoCopyByteArrayOutputStream os = threadLocalBaos.get(); os.reset(); - if (compressionEnabled) { - requestBuilder.header("Content-Encoding", "gzip"); - try (GZIPOutputStream gzos = new GZIPOutputStream(os)) { - marshaler.accept(gzos); + if (compressor != null) { + requestBuilder.header("Content-Encoding", compressor.getEncoding()); + try (OutputStream compressed = compressor.compress(os)) { + marshaler.accept(compressed); } catch (IOException e) { throw new IllegalStateException(e); } diff --git a/exporters/sender/jdk/src/main/java/io/opentelemetry/exporter/sender/jdk/internal/JdkHttpSenderProvider.java b/exporters/sender/jdk/src/main/java/io/opentelemetry/exporter/sender/jdk/internal/JdkHttpSenderProvider.java index 2478079dce6..1891cf27c85 100644 --- a/exporters/sender/jdk/src/main/java/io/opentelemetry/exporter/sender/jdk/internal/JdkHttpSenderProvider.java +++ b/exporters/sender/jdk/src/main/java/io/opentelemetry/exporter/sender/jdk/internal/JdkHttpSenderProvider.java @@ -6,6 +6,7 @@ package io.opentelemetry.exporter.sender.jdk.internal; import io.opentelemetry.exporter.internal.auth.Authenticator; +import io.opentelemetry.exporter.internal.compression.Compressor; import io.opentelemetry.exporter.internal.http.HttpSender; import io.opentelemetry.exporter.internal.http.HttpSenderProvider; import io.opentelemetry.sdk.common.export.RetryPolicy; @@ -27,7 +28,7 @@ public final class JdkHttpSenderProvider implements HttpSenderProvider { @Override public HttpSender createSender( String endpoint, - boolean compressionEnabled, + @Nullable Compressor compressor, String contentType, long timeoutNanos, long connectTimeout, @@ -38,7 +39,7 @@ public HttpSender createSender( @Nullable X509TrustManager trustManager) { return new JdkHttpSender( endpoint, - compressionEnabled, + compressor, contentType, timeoutNanos, connectTimeout, diff --git a/exporters/sender/jdk/src/test/java/io/opentelemetry/exporter/sender/jdk/internal/JdkHttpSenderTest.java b/exporters/sender/jdk/src/test/java/io/opentelemetry/exporter/sender/jdk/internal/JdkHttpSenderTest.java index 0bf99ab9525..1e2ee939863 100644 --- a/exporters/sender/jdk/src/test/java/io/opentelemetry/exporter/sender/jdk/internal/JdkHttpSenderTest.java +++ b/exporters/sender/jdk/src/test/java/io/opentelemetry/exporter/sender/jdk/internal/JdkHttpSenderTest.java @@ -53,7 +53,7 @@ void setup() throws IOException, InterruptedException { mockHttpClient, "http://10.255.255.1", // Connecting to a non-routable IP address to trigger connection // timeout - false, + null, "text/plain", Duration.ofSeconds(10).toNanos(), Collections::emptyMap, @@ -98,7 +98,7 @@ void connectTimeout() { sender = new JdkHttpSender( "http://localhost", - true, + null, "text/plain", 1, TimeUnit.SECONDS.toNanos(10), diff --git a/exporters/sender/okhttp/src/main/java/io/opentelemetry/exporter/sender/okhttp/internal/OkHttpHttpSender.java b/exporters/sender/okhttp/src/main/java/io/opentelemetry/exporter/sender/okhttp/internal/OkHttpHttpSender.java index 337a722a06d..7724416c7fe 100644 --- a/exporters/sender/okhttp/src/main/java/io/opentelemetry/exporter/sender/okhttp/internal/OkHttpHttpSender.java +++ b/exporters/sender/okhttp/src/main/java/io/opentelemetry/exporter/sender/okhttp/internal/OkHttpHttpSender.java @@ -8,6 +8,7 @@ import io.opentelemetry.exporter.internal.InstrumentationUtil; import io.opentelemetry.exporter.internal.RetryUtil; import io.opentelemetry.exporter.internal.auth.Authenticator; +import io.opentelemetry.exporter.internal.compression.Compressor; import io.opentelemetry.exporter.internal.http.HttpSender; import io.opentelemetry.sdk.common.CompletableResultCode; import io.opentelemetry.sdk.common.export.RetryPolicy; @@ -30,7 +31,6 @@ import okhttp3.RequestBody; import okhttp3.ResponseBody; import okio.BufferedSink; -import okio.GzipSink; import okio.Okio; /** @@ -43,7 +43,7 @@ public final class OkHttpHttpSender implements HttpSender { private final OkHttpClient client; private final HttpUrl url; - private final boolean compressionEnabled; + @Nullable private final Compressor compressor; private final Supplier>> headerSupplier; private final MediaType mediaType; @@ -51,7 +51,7 @@ public final class OkHttpHttpSender implements HttpSender { @SuppressWarnings("TooManyParameters") public OkHttpHttpSender( String endpoint, - boolean compressionEnabled, + @Nullable Compressor compressor, String contentType, long timeoutNanos, long connectionTimeoutNanos, @@ -85,7 +85,7 @@ public OkHttpHttpSender( } this.client = builder.build(); this.url = HttpUrl.get(endpoint); - this.compressionEnabled = compressionEnabled; + this.compressor = compressor; this.mediaType = MediaType.parse(contentType); this.headerSupplier = headerSupplier; } @@ -104,9 +104,9 @@ public void send( (key, values) -> values.forEach(value -> requestBuilder.addHeader(key, value))); } RequestBody body = new RawRequestBody(marshaler, contentLength, mediaType); - if (compressionEnabled) { - requestBuilder.addHeader("Content-Encoding", "gzip"); - requestBuilder.post(new GzipRequestBody(body)); + if (compressor != null) { + requestBuilder.addHeader("Content-Encoding", compressor.getEncoding()); + requestBuilder.post(new CompressedRequestBody(compressor, body)); } else { requestBuilder.post(body); } @@ -188,10 +188,12 @@ public void writeTo(BufferedSink bufferedSink) { } } - private static class GzipRequestBody extends RequestBody { + private static class CompressedRequestBody extends RequestBody { + private final Compressor compressor; private final RequestBody requestBody; - private GzipRequestBody(RequestBody requestBody) { + private CompressedRequestBody(Compressor compressor, RequestBody requestBody) { + this.compressor = compressor; this.requestBody = requestBody; } @@ -207,9 +209,10 @@ public long contentLength() { @Override public void writeTo(BufferedSink bufferedSink) throws IOException { - BufferedSink gzipSink = Okio.buffer(new GzipSink(bufferedSink)); - requestBody.writeTo(gzipSink); - gzipSink.close(); + BufferedSink compressedSink = + Okio.buffer(Okio.sink(compressor.compress(bufferedSink.outputStream()))); + requestBody.writeTo(compressedSink); + compressedSink.close(); } } } diff --git a/exporters/sender/okhttp/src/main/java/io/opentelemetry/exporter/sender/okhttp/internal/OkHttpHttpSenderProvider.java b/exporters/sender/okhttp/src/main/java/io/opentelemetry/exporter/sender/okhttp/internal/OkHttpHttpSenderProvider.java index 18573049082..d969a1ee23d 100644 --- a/exporters/sender/okhttp/src/main/java/io/opentelemetry/exporter/sender/okhttp/internal/OkHttpHttpSenderProvider.java +++ b/exporters/sender/okhttp/src/main/java/io/opentelemetry/exporter/sender/okhttp/internal/OkHttpHttpSenderProvider.java @@ -6,6 +6,7 @@ package io.opentelemetry.exporter.sender.okhttp.internal; import io.opentelemetry.exporter.internal.auth.Authenticator; +import io.opentelemetry.exporter.internal.compression.Compressor; import io.opentelemetry.exporter.internal.http.HttpSender; import io.opentelemetry.exporter.internal.http.HttpSenderProvider; import io.opentelemetry.sdk.common.export.RetryPolicy; @@ -27,7 +28,7 @@ public final class OkHttpHttpSenderProvider implements HttpSenderProvider { @Override public HttpSender createSender( String endpoint, - boolean compressionEnabled, + @Nullable Compressor compressor, String contentType, long timeoutNanos, long connectTimeout, @@ -38,7 +39,7 @@ public HttpSender createSender( @Nullable X509TrustManager trustManager) { return new OkHttpHttpSender( endpoint, - compressionEnabled, + compressor, contentType, timeoutNanos, connectTimeout, diff --git a/exporters/sender/okhttp/src/test/java/io/opentelemetry/exporter/sender/okhttp/internal/HttpExporterBuilderTest.java b/exporters/sender/okhttp/src/test/java/io/opentelemetry/exporter/sender/okhttp/internal/HttpExporterBuilderTest.java deleted file mode 100644 index b7b80453be0..00000000000 --- a/exporters/sender/okhttp/src/test/java/io/opentelemetry/exporter/sender/okhttp/internal/HttpExporterBuilderTest.java +++ /dev/null @@ -1,92 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package io.opentelemetry.exporter.sender.okhttp.internal; - -import static org.assertj.core.api.Assertions.assertThat; - -import io.opentelemetry.exporter.internal.http.HttpExporter; -import io.opentelemetry.exporter.internal.http.HttpExporterBuilder; -import io.opentelemetry.exporter.internal.marshal.Marshaler; -import org.junit.jupiter.api.Test; - -class HttpExporterBuilderTest { - - private final HttpExporterBuilder builder = - new HttpExporterBuilder<>("otlp", "span", "http://localhost:4318/v1/traces"); - - @Test - void compressionDefault() { - HttpExporter exporter = builder.build(); - try { - assertThat(exporter) - .isInstanceOfSatisfying( - HttpExporter.class, - otlp -> - assertThat(otlp) - .extracting("httpSender") - .isInstanceOf(OkHttpHttpSender.class) - .extracting("compressionEnabled") - .isEqualTo(false)); - } finally { - exporter.shutdown(); - } - } - - @Test - void compressionNone() { - HttpExporter exporter = builder.setCompression("none").build(); - try { - assertThat(exporter) - .isInstanceOfSatisfying( - HttpExporter.class, - otlp -> - assertThat(otlp) - .extracting("httpSender") - .isInstanceOf(OkHttpHttpSender.class) - .extracting("compressionEnabled") - .isEqualTo(false)); - } finally { - exporter.shutdown(); - } - } - - @Test - void compressionGzip() { - HttpExporter exporter = builder.setCompression("gzip").build(); - try { - assertThat(exporter) - .isInstanceOfSatisfying( - HttpExporter.class, - otlp -> - assertThat(otlp) - .extracting("httpSender") - .isInstanceOf(OkHttpHttpSender.class) - .extracting("compressionEnabled") - .isEqualTo(true)); - } finally { - exporter.shutdown(); - } - } - - @Test - void compressionEnabledAndDisabled() { - HttpExporter exporter = - builder.setCompression("gzip").setCompression("none").build(); - try { - assertThat(exporter) - .isInstanceOfSatisfying( - HttpExporter.class, - otlp -> - assertThat(otlp) - .extracting("httpSender") - .isInstanceOf(OkHttpHttpSender.class) - .extracting("compressionEnabled") - .isEqualTo(false)); - } finally { - exporter.shutdown(); - } - } -} diff --git a/exporters/sender/okhttp/src/test/java/io/opentelemetry/exporter/sender/okhttp/internal/OkHttpHttpSuppressionTest.java b/exporters/sender/okhttp/src/test/java/io/opentelemetry/exporter/sender/okhttp/internal/OkHttpHttpSuppressionTest.java index 87da2a18e84..0227826d4cd 100644 --- a/exporters/sender/okhttp/src/test/java/io/opentelemetry/exporter/sender/okhttp/internal/OkHttpHttpSuppressionTest.java +++ b/exporters/sender/okhttp/src/test/java/io/opentelemetry/exporter/sender/okhttp/internal/OkHttpHttpSuppressionTest.java @@ -34,6 +34,6 @@ void send(OkHttpHttpSender sender, Runnable onSuccess, Runnable onFailure) { @Override OkHttpHttpSender createSender(String endpoint) { return new OkHttpHttpSender( - endpoint, false, "text/plain", 10L, 10L, Collections::emptyMap, null, null, null, null); + endpoint, null, "text/plain", 10L, 10L, Collections::emptyMap, null, null, null, null); } } From 42679988e2621c5c68fbdc50bec6dab86a790877 Mon Sep 17 00:00:00 2001 From: jack-berg <34418638+jack-berg@users.noreply.github.com> Date: Tue, 2 Jan 2024 17:33:13 -0600 Subject: [PATCH 173/901] Fix owasp dependency check (#6086) --- all/build.gradle.kts | 5 +++++ .../src/main/kotlin/otel.java-conventions.gradle.kts | 9 +++++++-- context/build.gradle.kts | 10 ++++++++++ sdk/metrics/build.gradle.kts | 4 ++++ 4 files changed, 26 insertions(+), 2 deletions(-) diff --git a/all/build.gradle.kts b/all/build.gradle.kts index b205e053fe1..aa302ed598b 100644 --- a/all/build.gradle.kts +++ b/all/build.gradle.kts @@ -23,6 +23,11 @@ tasks { } } +// Skip OWASP dependencyCheck task on test module +dependencyCheck { + skip = true +} + val testTasks = mutableListOf() dependencies { diff --git a/buildSrc/src/main/kotlin/otel.java-conventions.gradle.kts b/buildSrc/src/main/kotlin/otel.java-conventions.gradle.kts index d079343e045..7dd9d091f67 100644 --- a/buildSrc/src/main/kotlin/otel.java-conventions.gradle.kts +++ b/buildSrc/src/main/kotlin/otel.java-conventions.gradle.kts @@ -41,14 +41,19 @@ checkstyle { } dependencyCheck { - skipConfigurations = listOf( + skipConfigurations = mutableListOf( "errorprone", "checkstyle", "annotationProcessor", + "java9AnnotationProcessor", + "moduleAnnotationProcessor", + "testAnnotationProcessor", + "testJpmsAnnotationProcessor", "animalsniffer", - "spotless865457264", // spotless865457264 is a weird configuration that's only added in jaeger-proto, jaeger-remote-sampler + "spotless996155815", // spotless996155815 is a weird configuration that's only added in jaeger-proto, jaeger-remote-sampler "js2p", "jmhAnnotationProcessor", + "jmhBasedTestAnnotationProcessor", "jmhCompileClasspath", "jmhRuntimeClasspath", "jmhRuntimeOnly") diff --git a/context/build.gradle.kts b/context/build.gradle.kts index a0e17cb0145..6c8fa63837c 100644 --- a/context/build.gradle.kts +++ b/context/build.gradle.kts @@ -16,6 +16,16 @@ dependencies { testImplementation("com.google.guava:guava") } +dependencyCheck { + skipConfigurations.add("braveInOtelTestAnnotationProcessor") + skipConfigurations.add("grpcInOtelTestAnnotationProcessor") + skipConfigurations.add("otelAsBraveTestAnnotationProcessor") + skipConfigurations.add("otelInBraveTestAnnotationProcessor") + skipConfigurations.add("otelInGrpcTestAnnotationProcessor") + skipConfigurations.add("storageWrappersTestAnnotationProcessor") + skipConfigurations.add("strictContextEnabledTestAnnotationProcessor") +} + testing { suites { register("grpcInOtelTest") { diff --git a/sdk/metrics/build.gradle.kts b/sdk/metrics/build.gradle.kts index 010291e3d72..590a312b043 100644 --- a/sdk/metrics/build.gradle.kts +++ b/sdk/metrics/build.gradle.kts @@ -30,6 +30,10 @@ dependencies { jmh(project(":sdk:testing")) } +dependencyCheck { + skipConfigurations.add("debugEnabledTestAnnotationProcessor") +} + testing { suites { register("debugEnabledTest") { From de65a4ba1ef8d1aa55213c658c316fa369f39e30 Mon Sep 17 00:00:00 2001 From: jack-berg <34418638+jack-berg@users.noreply.github.com> Date: Tue, 2 Jan 2024 17:53:08 -0600 Subject: [PATCH 174/901] Test OTLP exporters with different OkHttp versions (#6045) --- exporters/otlp/all/build.gradle.kts | 41 ++++++++++++++++++- .../exporter/otlp/OkHttpVersionTest.java | 27 ++++++++++++ ...HttpLogRecordExporterOkHttpSenderTest.java | 0 ...tlpHttpMetricExporterOkHttpSenderTest.java | 0 .../OtlpHttpSpanExporterOkHttpSenderTest.java | 0 .../logs/OtlpGrpcLogRecordExporterTest.java | 0 .../metrics/OtlpGrpcMetricExporterTest.java | 0 .../traces}/OtlpGrpcSpanExporterTest.java | 3 +- 8 files changed, 68 insertions(+), 3 deletions(-) create mode 100644 exporters/otlp/all/src/testDefaultSender/java/io/opentelemetry/exporter/otlp/OkHttpVersionTest.java rename exporters/otlp/all/src/{test => testDefaultSender}/java/io/opentelemetry/exporter/otlp/http/logs/OtlpHttpLogRecordExporterOkHttpSenderTest.java (100%) rename exporters/otlp/all/src/{test => testDefaultSender}/java/io/opentelemetry/exporter/otlp/http/metrics/OtlpHttpMetricExporterOkHttpSenderTest.java (100%) rename exporters/otlp/all/src/{test => testDefaultSender}/java/io/opentelemetry/exporter/otlp/http/trace/OtlpHttpSpanExporterOkHttpSenderTest.java (100%) rename exporters/otlp/all/src/{test => testDefaultSender}/java/io/opentelemetry/exporter/otlp/logs/OtlpGrpcLogRecordExporterTest.java (100%) rename exporters/otlp/all/src/{test => testDefaultSender}/java/io/opentelemetry/exporter/otlp/metrics/OtlpGrpcMetricExporterTest.java (100%) rename exporters/otlp/all/src/{test/java/io/opentelemetry/exporter/otlp/trace => testDefaultSender/java/io/opentelemetry/exporter/otlp/traces}/OtlpGrpcSpanExporterTest.java (94%) diff --git a/exporters/otlp/all/build.gradle.kts b/exporters/otlp/all/build.gradle.kts index e7b87b9efa9..0c0ef6b75b7 100644 --- a/exporters/otlp/all/build.gradle.kts +++ b/exporters/otlp/all/build.gradle.kts @@ -24,8 +24,6 @@ dependencies { testImplementation(project(":exporters:otlp:testing-internal")) testImplementation("com.linecorp.armeria:armeria-junit5") - testImplementation("com.google.api.grpc:proto-google-common-protos") - testImplementation("com.squareup.okhttp3:okhttp-tls") testImplementation("io.grpc:grpc-stub") jmhImplementation(project(":sdk:testing")) @@ -41,6 +39,45 @@ val testJavaVersion: String? by project testing { suites { + listOf( + "LATEST", + "4.11.0" + ).forEach { + register("testOkHttpVersion$it") { + sources { + java { + setSrcDirs(listOf("src/testDefaultSender/java")) + } + } + dependencies { + implementation(project(":exporters:sender:okhttp")) + implementation(project(":exporters:otlp:testing-internal")) + + implementation(platform("com.squareup.okhttp3:okhttp-bom")) { + // Only impose dependency constraint if not testing the LATEST version, which is defined in /dependencyManagement/build.gradle.kts + if (!it.equals("LATEST")) { + version { + strictly(it) + } + } + } + + implementation("com.squareup.okhttp3:okhttp") + implementation("io.grpc:grpc-stub") + } + + targets { + all { + testTask { + // Only enable test suite for non-LATEST in GitHub CI (CI=true) + enabled = it.equals("LATEST") || "true".equals(System.getenv("CI")) + systemProperty("expected.okhttp.version", it) + } + } + } + } + } + register("testGrpcNetty") { dependencies { implementation(project(":exporters:sender:grpc-managed-channel")) diff --git a/exporters/otlp/all/src/testDefaultSender/java/io/opentelemetry/exporter/otlp/OkHttpVersionTest.java b/exporters/otlp/all/src/testDefaultSender/java/io/opentelemetry/exporter/otlp/OkHttpVersionTest.java new file mode 100644 index 00000000000..8798781bb3f --- /dev/null +++ b/exporters/otlp/all/src/testDefaultSender/java/io/opentelemetry/exporter/otlp/OkHttpVersionTest.java @@ -0,0 +1,27 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.exporter.otlp; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assumptions.assumeThat; + +import java.util.logging.Level; +import java.util.logging.Logger; +import okhttp3.OkHttp; +import org.junit.jupiter.api.Test; + +class OkHttpVersionTest { + + private static final Logger LOGGER = Logger.getLogger(OkHttpVersionTest.class.getName()); + + @Test + void expectedOkHttpVersion() { + String expectedVersion = System.getProperty("expected.okhttp.version"); + LOGGER.log(Level.WARNING, "Testing okhttp version " + expectedVersion); + assumeThat(expectedVersion.equals("LATEST")).isFalse(); + assertThat(OkHttp.VERSION).isEqualTo(expectedVersion); + } +} diff --git a/exporters/otlp/all/src/test/java/io/opentelemetry/exporter/otlp/http/logs/OtlpHttpLogRecordExporterOkHttpSenderTest.java b/exporters/otlp/all/src/testDefaultSender/java/io/opentelemetry/exporter/otlp/http/logs/OtlpHttpLogRecordExporterOkHttpSenderTest.java similarity index 100% rename from exporters/otlp/all/src/test/java/io/opentelemetry/exporter/otlp/http/logs/OtlpHttpLogRecordExporterOkHttpSenderTest.java rename to exporters/otlp/all/src/testDefaultSender/java/io/opentelemetry/exporter/otlp/http/logs/OtlpHttpLogRecordExporterOkHttpSenderTest.java diff --git a/exporters/otlp/all/src/test/java/io/opentelemetry/exporter/otlp/http/metrics/OtlpHttpMetricExporterOkHttpSenderTest.java b/exporters/otlp/all/src/testDefaultSender/java/io/opentelemetry/exporter/otlp/http/metrics/OtlpHttpMetricExporterOkHttpSenderTest.java similarity index 100% rename from exporters/otlp/all/src/test/java/io/opentelemetry/exporter/otlp/http/metrics/OtlpHttpMetricExporterOkHttpSenderTest.java rename to exporters/otlp/all/src/testDefaultSender/java/io/opentelemetry/exporter/otlp/http/metrics/OtlpHttpMetricExporterOkHttpSenderTest.java diff --git a/exporters/otlp/all/src/test/java/io/opentelemetry/exporter/otlp/http/trace/OtlpHttpSpanExporterOkHttpSenderTest.java b/exporters/otlp/all/src/testDefaultSender/java/io/opentelemetry/exporter/otlp/http/trace/OtlpHttpSpanExporterOkHttpSenderTest.java similarity index 100% rename from exporters/otlp/all/src/test/java/io/opentelemetry/exporter/otlp/http/trace/OtlpHttpSpanExporterOkHttpSenderTest.java rename to exporters/otlp/all/src/testDefaultSender/java/io/opentelemetry/exporter/otlp/http/trace/OtlpHttpSpanExporterOkHttpSenderTest.java diff --git a/exporters/otlp/all/src/test/java/io/opentelemetry/exporter/otlp/logs/OtlpGrpcLogRecordExporterTest.java b/exporters/otlp/all/src/testDefaultSender/java/io/opentelemetry/exporter/otlp/logs/OtlpGrpcLogRecordExporterTest.java similarity index 100% rename from exporters/otlp/all/src/test/java/io/opentelemetry/exporter/otlp/logs/OtlpGrpcLogRecordExporterTest.java rename to exporters/otlp/all/src/testDefaultSender/java/io/opentelemetry/exporter/otlp/logs/OtlpGrpcLogRecordExporterTest.java diff --git a/exporters/otlp/all/src/test/java/io/opentelemetry/exporter/otlp/metrics/OtlpGrpcMetricExporterTest.java b/exporters/otlp/all/src/testDefaultSender/java/io/opentelemetry/exporter/otlp/metrics/OtlpGrpcMetricExporterTest.java similarity index 100% rename from exporters/otlp/all/src/test/java/io/opentelemetry/exporter/otlp/metrics/OtlpGrpcMetricExporterTest.java rename to exporters/otlp/all/src/testDefaultSender/java/io/opentelemetry/exporter/otlp/metrics/OtlpGrpcMetricExporterTest.java diff --git a/exporters/otlp/all/src/test/java/io/opentelemetry/exporter/otlp/trace/OtlpGrpcSpanExporterTest.java b/exporters/otlp/all/src/testDefaultSender/java/io/opentelemetry/exporter/otlp/traces/OtlpGrpcSpanExporterTest.java similarity index 94% rename from exporters/otlp/all/src/test/java/io/opentelemetry/exporter/otlp/trace/OtlpGrpcSpanExporterTest.java rename to exporters/otlp/all/src/testDefaultSender/java/io/opentelemetry/exporter/otlp/traces/OtlpGrpcSpanExporterTest.java index 9017cd4584e..a74b5e39977 100644 --- a/exporters/otlp/all/src/test/java/io/opentelemetry/exporter/otlp/trace/OtlpGrpcSpanExporterTest.java +++ b/exporters/otlp/all/src/testDefaultSender/java/io/opentelemetry/exporter/otlp/traces/OtlpGrpcSpanExporterTest.java @@ -3,7 +3,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -package io.opentelemetry.exporter.otlp.trace; +package io.opentelemetry.exporter.otlp.traces; import static org.assertj.core.api.Assertions.assertThat; @@ -13,6 +13,7 @@ import io.opentelemetry.exporter.otlp.testing.internal.FakeTelemetryUtil; import io.opentelemetry.exporter.otlp.testing.internal.TelemetryExporter; import io.opentelemetry.exporter.otlp.testing.internal.TelemetryExporterBuilder; +import io.opentelemetry.exporter.otlp.trace.OtlpGrpcSpanExporter; import io.opentelemetry.exporter.sender.okhttp.internal.OkHttpGrpcSender; import io.opentelemetry.proto.trace.v1.ResourceSpans; import io.opentelemetry.sdk.trace.data.SpanData; From d45fb3f5dc458b80bbab2ebfb91caa14dcb392e1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20St=C3=A4ber?= Date: Wed, 3 Jan 2024 16:51:35 +0100 Subject: [PATCH 175/901] Exponential Histogram support to the Prometheus exporter (#6015) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Fabian Stäber --- dependencyManagement/build.gradle.kts | 1 + exporters/prometheus/build.gradle.kts | 5 +- .../exporter/prometheus/NameSanitizer.java | 48 - .../prometheus/Otel2PrometheusConverter.java | 551 +++++++++ .../prometheus/PrometheusHttpServer.java | 238 +--- .../PrometheusHttpServerBuilder.java | 28 +- .../PrometheusMetricNameMapper.java | 104 -- .../prometheus/PrometheusMetricReader.java | 58 + .../exporter/prometheus/PrometheusType.java | 57 - .../prometheus/PrometheusUnitsHelper.java | 268 ++-- .../exporter/prometheus/Serializer.java | 707 ----------- .../prometheus/NameSanitizerTest.java | 63 - .../prometheus/PrometheusHttpServerTest.java | 104 +- .../PrometheusMetricNameMapperTest.java | 163 --- .../PrometheusMetricReaderTest.java | 1075 +++++++++++++++++ .../prometheus/PrometheusUnitsHelperTest.java | 39 +- .../exporter/prometheus/SerializerTest.java | 335 ----- .../exporter/prometheus/TestConstants.java | 378 ------ .../PrometheusMetricReaderProviderTest.java | 3 + 19 files changed, 1894 insertions(+), 2331 deletions(-) delete mode 100644 exporters/prometheus/src/main/java/io/opentelemetry/exporter/prometheus/NameSanitizer.java create mode 100644 exporters/prometheus/src/main/java/io/opentelemetry/exporter/prometheus/Otel2PrometheusConverter.java delete mode 100644 exporters/prometheus/src/main/java/io/opentelemetry/exporter/prometheus/PrometheusMetricNameMapper.java create mode 100644 exporters/prometheus/src/main/java/io/opentelemetry/exporter/prometheus/PrometheusMetricReader.java delete mode 100644 exporters/prometheus/src/main/java/io/opentelemetry/exporter/prometheus/PrometheusType.java delete mode 100644 exporters/prometheus/src/main/java/io/opentelemetry/exporter/prometheus/Serializer.java delete mode 100644 exporters/prometheus/src/test/java/io/opentelemetry/exporter/prometheus/NameSanitizerTest.java delete mode 100644 exporters/prometheus/src/test/java/io/opentelemetry/exporter/prometheus/PrometheusMetricNameMapperTest.java create mode 100644 exporters/prometheus/src/test/java/io/opentelemetry/exporter/prometheus/PrometheusMetricReaderTest.java delete mode 100644 exporters/prometheus/src/test/java/io/opentelemetry/exporter/prometheus/SerializerTest.java delete mode 100644 exporters/prometheus/src/test/java/io/opentelemetry/exporter/prometheus/TestConstants.java diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index c2f4eb5bd00..9c0f53936b1 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -69,6 +69,7 @@ val DEPENDENCIES = listOf( "io.opentelemetry.contrib:opentelemetry-aws-xray-propagator:1.29.0-alpha", "io.opentracing:opentracing-api:0.33.0", "io.opentracing:opentracing-noop:0.33.0", + "io.prometheus:prometheus-metrics-exporter-httpserver:1.1.0", "junit:junit:4.13.2", "nl.jqno.equalsverifier:equalsverifier:3.15.5", "org.awaitility:awaitility:4.2.0", diff --git a/exporters/prometheus/build.gradle.kts b/exporters/prometheus/build.gradle.kts index d746c074bbf..31044c70b23 100644 --- a/exporters/prometheus/build.gradle.kts +++ b/exporters/prometheus/build.gradle.kts @@ -12,14 +12,15 @@ dependencies { api(project(":sdk:metrics")) implementation(project(":sdk-extensions:autoconfigure-spi")) + implementation("io.prometheus:prometheus-metrics-exporter-httpserver") - compileOnly("com.sun.net.httpserver:http") compileOnly("com.google.auto.value:auto-value-annotations") annotationProcessor("com.google.auto.value:auto-value") + testImplementation(project(":sdk:testing")) testImplementation("io.opentelemetry.proto:opentelemetry-proto") - + testImplementation("com.sun.net.httpserver:http") testImplementation("com.google.guava:guava") testImplementation("com.linecorp.armeria:armeria") testImplementation("com.linecorp.armeria:armeria-junit5") diff --git a/exporters/prometheus/src/main/java/io/opentelemetry/exporter/prometheus/NameSanitizer.java b/exporters/prometheus/src/main/java/io/opentelemetry/exporter/prometheus/NameSanitizer.java deleted file mode 100644 index 9e8c62c4ede..00000000000 --- a/exporters/prometheus/src/main/java/io/opentelemetry/exporter/prometheus/NameSanitizer.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package io.opentelemetry.exporter.prometheus; - -import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; -import java.util.function.Function; -import java.util.regex.Pattern; - -/** Sanitizes a metric or label name. */ -class NameSanitizer implements Function { - - static final NameSanitizer INSTANCE = new NameSanitizer(); - - static final Pattern SANITIZE_CONSECUTIVE_UNDERSCORES = Pattern.compile("[_]{2,}"); - - private static final Pattern SANITIZE_PREFIX_PATTERN = Pattern.compile("^[^a-zA-Z_:]"); - private static final Pattern SANITIZE_BODY_PATTERN = Pattern.compile("[^a-zA-Z0-9_:]"); - - private final Function delegate; - private final Map cache = new ConcurrentHashMap<>(); - - NameSanitizer() { - this(NameSanitizer::sanitizeMetricName); - } - - // visible for testing - NameSanitizer(Function delegate) { - this.delegate = delegate; - } - - @Override - public String apply(String labelName) { - return cache.computeIfAbsent(labelName, delegate); - } - - private static String sanitizeMetricName(String metricName) { - return SANITIZE_CONSECUTIVE_UNDERSCORES - .matcher( - SANITIZE_BODY_PATTERN - .matcher(SANITIZE_PREFIX_PATTERN.matcher(metricName).replaceFirst("_")) - .replaceAll("_")) - .replaceAll("_"); - } -} diff --git a/exporters/prometheus/src/main/java/io/opentelemetry/exporter/prometheus/Otel2PrometheusConverter.java b/exporters/prometheus/src/main/java/io/opentelemetry/exporter/prometheus/Otel2PrometheusConverter.java new file mode 100644 index 00000000000..67a5870015c --- /dev/null +++ b/exporters/prometheus/src/main/java/io/opentelemetry/exporter/prometheus/Otel2PrometheusConverter.java @@ -0,0 +1,551 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.exporter.prometheus; + +import static io.prometheus.metrics.model.snapshots.PrometheusNaming.sanitizeLabelName; +import static io.prometheus.metrics.model.snapshots.PrometheusNaming.sanitizeMetricName; + +import io.opentelemetry.api.common.Attributes; +import io.opentelemetry.api.trace.SpanContext; +import io.opentelemetry.sdk.common.InstrumentationScopeInfo; +import io.opentelemetry.sdk.internal.ThrottlingLogger; +import io.opentelemetry.sdk.metrics.data.AggregationTemporality; +import io.opentelemetry.sdk.metrics.data.DoubleExemplarData; +import io.opentelemetry.sdk.metrics.data.DoublePointData; +import io.opentelemetry.sdk.metrics.data.ExemplarData; +import io.opentelemetry.sdk.metrics.data.ExponentialHistogramBuckets; +import io.opentelemetry.sdk.metrics.data.ExponentialHistogramData; +import io.opentelemetry.sdk.metrics.data.ExponentialHistogramPointData; +import io.opentelemetry.sdk.metrics.data.HistogramData; +import io.opentelemetry.sdk.metrics.data.HistogramPointData; +import io.opentelemetry.sdk.metrics.data.LongExemplarData; +import io.opentelemetry.sdk.metrics.data.LongPointData; +import io.opentelemetry.sdk.metrics.data.MetricData; +import io.opentelemetry.sdk.metrics.data.SumData; +import io.opentelemetry.sdk.metrics.data.SummaryPointData; +import io.opentelemetry.sdk.metrics.data.ValueAtQuantile; +import io.opentelemetry.sdk.resources.Resource; +import io.prometheus.metrics.model.snapshots.ClassicHistogramBuckets; +import io.prometheus.metrics.model.snapshots.CounterSnapshot; +import io.prometheus.metrics.model.snapshots.CounterSnapshot.CounterDataPointSnapshot; +import io.prometheus.metrics.model.snapshots.Exemplar; +import io.prometheus.metrics.model.snapshots.Exemplars; +import io.prometheus.metrics.model.snapshots.GaugeSnapshot; +import io.prometheus.metrics.model.snapshots.GaugeSnapshot.GaugeDataPointSnapshot; +import io.prometheus.metrics.model.snapshots.HistogramSnapshot; +import io.prometheus.metrics.model.snapshots.HistogramSnapshot.HistogramDataPointSnapshot; +import io.prometheus.metrics.model.snapshots.InfoSnapshot; +import io.prometheus.metrics.model.snapshots.InfoSnapshot.InfoDataPointSnapshot; +import io.prometheus.metrics.model.snapshots.Labels; +import io.prometheus.metrics.model.snapshots.MetricMetadata; +import io.prometheus.metrics.model.snapshots.MetricSnapshot; +import io.prometheus.metrics.model.snapshots.MetricSnapshots; +import io.prometheus.metrics.model.snapshots.NativeHistogramBuckets; +import io.prometheus.metrics.model.snapshots.Quantile; +import io.prometheus.metrics.model.snapshots.Quantiles; +import io.prometheus.metrics.model.snapshots.SummarySnapshot; +import io.prometheus.metrics.model.snapshots.SummarySnapshot.SummaryDataPointSnapshot; +import io.prometheus.metrics.model.snapshots.Unit; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Locale; +import java.util.Map; +import java.util.Set; +import java.util.concurrent.TimeUnit; +import java.util.logging.Level; +import java.util.logging.Logger; +import javax.annotation.Nullable; + +/** Convert OpenTelemetry {@link MetricData} to Prometheus {@link MetricSnapshots}. */ +final class Otel2PrometheusConverter { + + private static final Logger LOGGER = Logger.getLogger(Otel2PrometheusConverter.class.getName()); + private static final ThrottlingLogger THROTTLING_LOGGER = new ThrottlingLogger(LOGGER); + private final boolean otelScopeEnabled; + private static final String OTEL_SCOPE_NAME = "otel_scope_name"; + private static final String OTEL_SCOPE_VERSION = "otel_scope_version"; + private static final long NANOS_PER_MILLISECOND = TimeUnit.MILLISECONDS.toNanos(1); + + /** + * Constructor with feature flag parameter. + * + * @param otelScopeEnabled enable generation of the OpenTelemetry instrumentation scope info + * metric and labels. + */ + Otel2PrometheusConverter(boolean otelScopeEnabled) { + this.otelScopeEnabled = otelScopeEnabled; + } + + MetricSnapshots convert(@Nullable Collection metricDataCollection) { + if (metricDataCollection == null || metricDataCollection.isEmpty()) { + return MetricSnapshots.of(); + } + Map snapshotsByName = new HashMap<>(metricDataCollection.size()); + Resource resource = null; + Set scopes = new LinkedHashSet<>(); + for (MetricData metricData : metricDataCollection) { + MetricSnapshot snapshot = convert(metricData); + if (snapshot == null) { + continue; + } + putOrMerge(snapshotsByName, snapshot); + if (resource == null) { + resource = metricData.getResource(); + } + if (otelScopeEnabled && !metricData.getInstrumentationScopeInfo().getAttributes().isEmpty()) { + scopes.add(metricData.getInstrumentationScopeInfo()); + } + } + if (resource != null) { + putOrMerge(snapshotsByName, makeTargetInfo(resource)); + } + if (otelScopeEnabled && !scopes.isEmpty()) { + putOrMerge(snapshotsByName, makeScopeInfo(scopes)); + } + return new MetricSnapshots(snapshotsByName.values()); + } + + @Nullable + private MetricSnapshot convert(MetricData metricData) { + + // Note that AggregationTemporality.DELTA should never happen + // because PrometheusMetricReader#getAggregationTemporality returns CUMULATIVE. + + MetricMetadata metadata = convertMetadata(metricData); + InstrumentationScopeInfo scope = metricData.getInstrumentationScopeInfo(); + switch (metricData.getType()) { + case LONG_GAUGE: + return convertLongGauge(metadata, scope, metricData.getLongGaugeData().getPoints()); + case DOUBLE_GAUGE: + return convertDoubleGauge(metadata, scope, metricData.getDoubleGaugeData().getPoints()); + case LONG_SUM: + SumData longSumData = metricData.getLongSumData(); + if (longSumData.getAggregationTemporality() == AggregationTemporality.DELTA) { + return null; + } else if (longSumData.isMonotonic()) { + return convertLongCounter(metadata, scope, longSumData.getPoints()); + } else { + return convertLongGauge(metadata, scope, longSumData.getPoints()); + } + case DOUBLE_SUM: + SumData doubleSumData = metricData.getDoubleSumData(); + if (doubleSumData.getAggregationTemporality() == AggregationTemporality.DELTA) { + return null; + } else if (doubleSumData.isMonotonic()) { + return convertDoubleCounter(metadata, scope, doubleSumData.getPoints()); + } else { + return convertDoubleGauge(metadata, scope, doubleSumData.getPoints()); + } + case HISTOGRAM: + HistogramData histogramData = metricData.getHistogramData(); + if (histogramData.getAggregationTemporality() == AggregationTemporality.DELTA) { + return null; + } else { + return convertHistogram(metadata, scope, histogramData.getPoints()); + } + case EXPONENTIAL_HISTOGRAM: + ExponentialHistogramData exponentialHistogramData = + metricData.getExponentialHistogramData(); + if (exponentialHistogramData.getAggregationTemporality() == AggregationTemporality.DELTA) { + return null; + } else { + return convertExponentialHistogram(metadata, scope, exponentialHistogramData.getPoints()); + } + case SUMMARY: + return convertSummary(metadata, scope, metricData.getSummaryData().getPoints()); + } + return null; + } + + private GaugeSnapshot convertLongGauge( + MetricMetadata metadata, + InstrumentationScopeInfo scope, + Collection dataPoints) { + List data = new ArrayList<>(dataPoints.size()); + for (LongPointData longData : dataPoints) { + data.add( + new GaugeDataPointSnapshot( + (double) longData.getValue(), + convertAttributes(scope, longData.getAttributes()), + convertLongExemplar(longData.getExemplars()))); + } + return new GaugeSnapshot(metadata, data); + } + + private CounterSnapshot convertLongCounter( + MetricMetadata metadata, + InstrumentationScopeInfo scope, + Collection dataPoints) { + List data = + new ArrayList(dataPoints.size()); + for (LongPointData longData : dataPoints) { + data.add( + new CounterDataPointSnapshot( + (double) longData.getValue(), + convertAttributes(scope, longData.getAttributes()), + convertLongExemplar(longData.getExemplars()), + longData.getStartEpochNanos() / NANOS_PER_MILLISECOND)); + } + return new CounterSnapshot(metadata, data); + } + + private GaugeSnapshot convertDoubleGauge( + MetricMetadata metadata, + InstrumentationScopeInfo scope, + Collection dataPoints) { + List data = new ArrayList<>(dataPoints.size()); + for (DoublePointData doubleData : dataPoints) { + data.add( + new GaugeDataPointSnapshot( + doubleData.getValue(), + convertAttributes(scope, doubleData.getAttributes()), + convertDoubleExemplar(doubleData.getExemplars()))); + } + return new GaugeSnapshot(metadata, data); + } + + private CounterSnapshot convertDoubleCounter( + MetricMetadata metadata, + InstrumentationScopeInfo scope, + Collection dataPoints) { + List data = new ArrayList<>(dataPoints.size()); + for (DoublePointData doubleData : dataPoints) { + data.add( + new CounterDataPointSnapshot( + doubleData.getValue(), + convertAttributes(scope, doubleData.getAttributes()), + convertDoubleExemplar(doubleData.getExemplars()), + doubleData.getStartEpochNanos() / NANOS_PER_MILLISECOND)); + } + return new CounterSnapshot(metadata, data); + } + + private HistogramSnapshot convertHistogram( + MetricMetadata metadata, + InstrumentationScopeInfo scope, + Collection dataPoints) { + List data = new ArrayList<>(dataPoints.size()); + for (HistogramPointData histogramData : dataPoints) { + List boundaries = new ArrayList<>(histogramData.getBoundaries().size() + 1); + boundaries.addAll(histogramData.getBoundaries()); + boundaries.add(Double.POSITIVE_INFINITY); + data.add( + new HistogramDataPointSnapshot( + ClassicHistogramBuckets.of(boundaries, histogramData.getCounts()), + histogramData.getSum(), + convertAttributes(scope, histogramData.getAttributes()), + convertDoubleExemplars(histogramData.getExemplars()), + histogramData.getStartEpochNanos() / NANOS_PER_MILLISECOND)); + } + return new HistogramSnapshot(metadata, data); + } + + @Nullable + private HistogramSnapshot convertExponentialHistogram( + MetricMetadata metadata, + InstrumentationScopeInfo scope, + Collection dataPoints) { + List data = new ArrayList<>(dataPoints.size()); + for (ExponentialHistogramPointData histogramData : dataPoints) { + int scale = histogramData.getScale(); + if (scale < -4) { + THROTTLING_LOGGER.log( + Level.WARNING, + "Dropping histogram " + + metadata.getName() + + " with attributes " + + histogramData.getAttributes() + + " because it has scale < -4 which is unsupported in Prometheus"); + return null; + } + // Scale > 8 are not supported in Prometheus. Histograms with scale > 8 are scaled down to 8. + int scaleDown = scale > 8 ? scale - 8 : 0; + data.add( + new HistogramDataPointSnapshot( + scale - scaleDown, + histogramData.getZeroCount(), + 0L, + convertExponentialHistogramBuckets(histogramData.getPositiveBuckets(), scaleDown), + convertExponentialHistogramBuckets(histogramData.getNegativeBuckets(), scaleDown), + histogramData.getSum(), + convertAttributes(scope, histogramData.getAttributes()), + convertDoubleExemplars(histogramData.getExemplars()), + histogramData.getStartEpochNanos() / NANOS_PER_MILLISECOND)); + } + return new HistogramSnapshot(metadata, data); + } + + private static NativeHistogramBuckets convertExponentialHistogramBuckets( + ExponentialHistogramBuckets buckets, int scaleDown) { + if (buckets.getBucketCounts().isEmpty()) { + return NativeHistogramBuckets.EMPTY; + } + List otelCounts = buckets.getBucketCounts(); + List indexes = new ArrayList<>(otelCounts.size()); + List counts = new ArrayList<>(otelCounts.size()); + int previousIndex = (buckets.getOffset() >> scaleDown) + 1; + long count = 0; + for (int i = 0; i < otelCounts.size(); i++) { + int index = ((buckets.getOffset() + i) >> scaleDown) + 1; + if (index > previousIndex) { + indexes.add(previousIndex); + counts.add(count); + previousIndex = index; + count = 0; + } + count += otelCounts.get(i); + } + indexes.add(previousIndex); + counts.add(count); + return NativeHistogramBuckets.of(indexes, counts); + } + + private SummarySnapshot convertSummary( + MetricMetadata metadata, + InstrumentationScopeInfo scope, + Collection dataPoints) { + List data = new ArrayList<>(dataPoints.size()); + for (SummaryPointData summaryData : dataPoints) { + data.add( + new SummaryDataPointSnapshot( + summaryData.getCount(), + summaryData.getSum(), + convertQuantiles(summaryData.getValues()), + convertAttributes(scope, summaryData.getAttributes()), + Exemplars.EMPTY, // Exemplars for Summaries not implemented yet. + summaryData.getStartEpochNanos() / NANOS_PER_MILLISECOND)); + } + return new SummarySnapshot(metadata, data); + } + + private static Quantiles convertQuantiles(List values) { + List result = new ArrayList<>(values.size()); + for (ValueAtQuantile value : values) { + result.add(new Quantile(value.getQuantile(), value.getValue())); + } + return Quantiles.of(result); + } + + @Nullable + private Exemplar convertLongExemplar(List exemplars) { + if (exemplars.isEmpty()) { + return null; + } else { + LongExemplarData exemplar = exemplars.get(0); + return convertExemplar((double) exemplar.getValue(), exemplar); + } + } + + /** Converts the first exemplar in the list if available, else returns {#code null}. */ + @Nullable + private Exemplar convertDoubleExemplar(List exemplars) { + if (exemplars.isEmpty()) { + return null; + } else { + DoubleExemplarData exemplar = exemplars.get(0); + return convertExemplar(exemplar.getValue(), exemplar); + } + } + + /** Converts the first exemplar in the list if available, else returns {#code null}. */ + private Exemplars convertDoubleExemplars(List exemplars) { + List result = new ArrayList<>(exemplars.size()); + for (DoubleExemplarData exemplar : exemplars) { + result.add(convertExemplar(exemplar.getValue(), exemplar)); + } + return Exemplars.of(result); + } + + private Exemplar convertExemplar(double value, ExemplarData exemplar) { + SpanContext spanContext = exemplar.getSpanContext(); + if (spanContext.isValid()) { + return new Exemplar( + value, + convertAttributes( + null, + exemplar.getFilteredAttributes(), + "trace_id", + spanContext.getTraceId(), + "span_id", + spanContext.getSpanId()), + exemplar.getEpochNanos() / NANOS_PER_MILLISECOND); + } else { + return new Exemplar( + value, + convertAttributes(null, exemplar.getFilteredAttributes()), + exemplar.getEpochNanos() / NANOS_PER_MILLISECOND); + } + } + + private InfoSnapshot makeTargetInfo(Resource resource) { + return new InfoSnapshot( + new MetricMetadata("target"), + Collections.singletonList( + new InfoDataPointSnapshot(convertAttributes(null, resource.getAttributes())))); + } + + private InfoSnapshot makeScopeInfo(Set scopes) { + List prometheusScopeInfos = new ArrayList<>(scopes.size()); + for (InstrumentationScopeInfo scope : scopes) { + prometheusScopeInfos.add( + new InfoDataPointSnapshot(convertAttributes(scope, scope.getAttributes()))); + } + return new InfoSnapshot(new MetricMetadata("otel_scope"), prometheusScopeInfos); + } + + /** + * Convert OpenTelemetry attributes to Prometheus labels. + * + * @param scope will be converted to {@code otel_scope_*} labels if {@code otelScopeEnabled} is + * {@code true}. + * @param attributes the attributes to be converted. + * @param additionalAttributes optional list of key/value pairs, may be empty. + */ + private Labels convertAttributes( + @Nullable InstrumentationScopeInfo scope, + Attributes attributes, + String... additionalAttributes) { + int numberOfScopeAttributes = 0; + if (otelScopeEnabled && scope != null) { + numberOfScopeAttributes = scope.getVersion() == null ? 1 : 2; + } + String[] names = + new String[attributes.size() + numberOfScopeAttributes + additionalAttributes.length / 2]; + String[] values = new String[names.length]; + int[] pos = new int[] {0}; // using an array because we want to increment in a forEach() lambda. + attributes.forEach( + (key, value) -> { + names[pos[0]] = sanitizeLabelName(key.getKey()); + values[pos[0]] = value.toString(); + pos[0]++; + }); + for (int i = 0; i < additionalAttributes.length; i += 2) { + names[pos[0]] = additionalAttributes[i]; + values[pos[0]] = additionalAttributes[i + 1]; + pos[0]++; + } + if (otelScopeEnabled && scope != null) { + names[pos[0]] = OTEL_SCOPE_NAME; + values[pos[0]] = scope.getName(); + pos[0]++; + if (scope.getVersion() != null) { + names[pos[0]] = OTEL_SCOPE_VERSION; + values[pos[0]] = scope.getVersion(); + pos[0]++; + } + } + return Labels.of(names, values); + } + + private static MetricMetadata convertMetadata(MetricData metricData) { + String name = sanitizeMetricName(metricData.getName()); + String help = metricData.getDescription(); + Unit unit = PrometheusUnitsHelper.convertUnit(metricData.getUnit()); + if (unit != null && !name.endsWith(unit.toString())) { + name += "_" + unit; + } + return new MetricMetadata(name, help, unit); + } + + private static void putOrMerge( + Map snapshotsByName, MetricSnapshot snapshot) { + String name = snapshot.getMetadata().getName(); + if (snapshotsByName.containsKey(name)) { + MetricSnapshot merged = merge(snapshotsByName.get(name), snapshot); + if (merged != null) { + snapshotsByName.put(name, merged); + } + } else { + snapshotsByName.put(name, snapshot); + } + } + + /** + * OpenTelemetry may use the same metric name multiple times but in different instrumentation + * scopes. In that case, we try to merge the metrics. They will have different {@code + * otel_scope_name} attributes. However, merging is only possible if the metrics have the same + * type. If the type differs, we log a message and drop one of them. + */ + @Nullable + private static MetricSnapshot merge(MetricSnapshot a, MetricSnapshot b) { + MetricMetadata metadata = mergeMetadata(a.getMetadata(), b.getMetadata()); + if (metadata == null) { + return null; + } + int numberOfDataPoints = a.getDataPoints().size() + b.getDataPoints().size(); + if (a instanceof GaugeSnapshot && b instanceof GaugeSnapshot) { + List dataPoints = new ArrayList<>(numberOfDataPoints); + dataPoints.addAll(((GaugeSnapshot) a).getDataPoints()); + dataPoints.addAll(((GaugeSnapshot) b).getDataPoints()); + return new GaugeSnapshot(metadata, dataPoints); + } else if (a instanceof CounterSnapshot && b instanceof CounterSnapshot) { + List dataPoints = new ArrayList<>(numberOfDataPoints); + dataPoints.addAll(((CounterSnapshot) a).getDataPoints()); + dataPoints.addAll(((CounterSnapshot) b).getDataPoints()); + return new CounterSnapshot(metadata, dataPoints); + } else if (a instanceof HistogramSnapshot && b instanceof HistogramSnapshot) { + List dataPoints = new ArrayList<>(numberOfDataPoints); + dataPoints.addAll(((HistogramSnapshot) a).getDataPoints()); + dataPoints.addAll(((HistogramSnapshot) b).getDataPoints()); + return new HistogramSnapshot(metadata, dataPoints); + } else if (a instanceof SummarySnapshot && b instanceof SummarySnapshot) { + List dataPoints = new ArrayList<>(numberOfDataPoints); + dataPoints.addAll(((SummarySnapshot) a).getDataPoints()); + dataPoints.addAll(((SummarySnapshot) b).getDataPoints()); + return new SummarySnapshot(metadata, dataPoints); + } else if (a instanceof InfoSnapshot && b instanceof InfoSnapshot) { + List dataPoints = new ArrayList<>(numberOfDataPoints); + dataPoints.addAll(((InfoSnapshot) a).getDataPoints()); + dataPoints.addAll(((InfoSnapshot) b).getDataPoints()); + return new InfoSnapshot(metadata, dataPoints); + } else { + THROTTLING_LOGGER.log( + Level.WARNING, + "Conflicting metric name " + + a.getMetadata().getPrometheusName() + + ": Found one metric with type " + + typeString(a) + + " and one of type " + + typeString(b) + + ". Dropping the one with type " + + typeString(b) + + "."); + return null; + } + } + + @Nullable + private static MetricMetadata mergeMetadata(MetricMetadata a, MetricMetadata b) { + String name = a.getPrometheusName(); + if (a.getName().equals(b.getName())) { + name = a.getName(); + } + String help = null; + if (a.getHelp() != null && a.getHelp().equals(b.getHelp())) { + help = a.getHelp(); + } + Unit unit = a.getUnit(); + if (unit != null && !unit.equals(b.getUnit())) { + THROTTLING_LOGGER.log( + Level.WARNING, + "Conflicting metrics: Multiple metrics with name " + + name + + " but different units found. Dropping the one with unit " + + b.getUnit()); + return null; + } + return new MetricMetadata(name, help, unit); + } + + private static String typeString(MetricSnapshot snapshot) { + // Simple helper for a log message. + return snapshot.getClass().getSimpleName().replace("Snapshot", "").toLowerCase(Locale.ENGLISH); + } +} diff --git a/exporters/prometheus/src/main/java/io/opentelemetry/exporter/prometheus/PrometheusHttpServer.java b/exporters/prometheus/src/main/java/io/opentelemetry/exporter/prometheus/PrometheusHttpServer.java index cf1515a645e..6b89884e6b7 100644 --- a/exporters/prometheus/src/main/java/io/opentelemetry/exporter/prometheus/PrometheusHttpServer.java +++ b/exporters/prometheus/src/main/java/io/opentelemetry/exporter/prometheus/PrometheusHttpServer.java @@ -10,56 +10,31 @@ package io.opentelemetry.exporter.prometheus; -import static java.util.stream.Collectors.joining; - -import com.sun.net.httpserver.HttpExchange; -import com.sun.net.httpserver.HttpHandler; -import com.sun.net.httpserver.HttpServer; import io.opentelemetry.sdk.common.CompletableResultCode; -import io.opentelemetry.sdk.internal.DaemonThreadFactory; import io.opentelemetry.sdk.metrics.InstrumentType; import io.opentelemetry.sdk.metrics.data.AggregationTemporality; -import io.opentelemetry.sdk.metrics.data.MetricData; import io.opentelemetry.sdk.metrics.export.CollectionRegistration; import io.opentelemetry.sdk.metrics.export.MetricReader; +import io.prometheus.metrics.exporter.httpserver.HTTPServer; +import io.prometheus.metrics.exporter.httpserver.MetricsHandler; +import io.prometheus.metrics.model.registry.PrometheusRegistry; import java.io.IOException; -import java.io.OutputStream; import java.io.UncheckedIOException; -import java.net.HttpURLConnection; -import java.net.InetAddress; import java.net.InetSocketAddress; -import java.net.URLDecoder; -import java.nio.charset.StandardCharsets; -import java.util.Collection; -import java.util.Collections; -import java.util.HashSet; -import java.util.List; -import java.util.Set; -import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ExecutorService; import java.util.concurrent.TimeUnit; -import java.util.function.Predicate; -import java.util.function.Supplier; -import java.util.logging.Level; -import java.util.logging.Logger; -import java.util.zip.GZIPOutputStream; import javax.annotation.Nullable; /** * A {@link MetricReader} that starts an HTTP server that will collect metrics and serialize to * Prometheus text format on request. */ -// Very similar to -// https://github.com/prometheus/client_java/blob/master/simpleclient_httpserver/src/main/java/io/prometheus/client/exporter/HTTPServer.java public final class PrometheusHttpServer implements MetricReader { - private static final DaemonThreadFactory THREAD_FACTORY = - new DaemonThreadFactory("prometheus-http"); - private static final Logger LOGGER = Logger.getLogger(PrometheusHttpServer.class.getName()); - - private final HttpServer server; - private final ExecutorService executor; - private volatile CollectionRegistration collectionRegistration = CollectionRegistration.noop(); + private final HTTPServer httpServer; + private final PrometheusMetricReader prometheusMetricReader; + private final PrometheusRegistry prometheusRegistry; + private final String host; /** * Returns a new {@link PrometheusHttpServer} which can be registered to an {@link @@ -75,87 +50,61 @@ public static PrometheusHttpServerBuilder builder() { return new PrometheusHttpServerBuilder(); } - PrometheusHttpServer(String host, int port, ExecutorService executor) { + PrometheusHttpServer( + String host, + int port, + @Nullable ExecutorService executor, + PrometheusRegistry prometheusRegistry, + boolean otelScopeEnabled) { + this.prometheusMetricReader = new PrometheusMetricReader(otelScopeEnabled); + this.host = host; + this.prometheusRegistry = prometheusRegistry; + prometheusRegistry.register(prometheusMetricReader); try { - server = createServer(host, port); + this.httpServer = + HTTPServer.builder() + .hostname(host) + .port(port) + .executorService(executor) + .registry(prometheusRegistry) + .defaultHandler(new MetricsHandler(prometheusRegistry)) + .buildAndStart(); } catch (IOException e) { throw new UncheckedIOException("Could not create Prometheus HTTP server", e); } - MetricsHandler metricsHandler = - new MetricsHandler(() -> collectionRegistration.collectAllMetrics()); - server.createContext("/", metricsHandler); - server.createContext("/metrics", metricsHandler); - server.createContext("/-/healthy", HealthHandler.INSTANCE); - this.executor = executor; - server.setExecutor(executor); - - start(); - } - - private static HttpServer createServer(String host, int port) throws IOException { - IOException exception = null; - for (InetAddress address : InetAddress.getAllByName(host)) { - try { - return HttpServer.create(new InetSocketAddress(address, port), 3); - } catch (IOException e) { - if (exception == null) { - exception = e; - } else { - exception.addSuppressed(e); - } - } - } - assert exception != null; - throw exception; - } - - private void start() { - // server.start must be called from a daemon thread for it to be a daemon. - if (Thread.currentThread().isDaemon()) { - server.start(); - return; - } - - Thread thread = THREAD_FACTORY.newThread(server::start); - thread.start(); - try { - thread.join(); - } catch (InterruptedException e) { - Thread.currentThread().interrupt(); - } } @Override public AggregationTemporality getAggregationTemporality(InstrumentType instrumentType) { - return AggregationTemporality.CUMULATIVE; + return prometheusMetricReader.getAggregationTemporality(instrumentType); } @Override public void register(CollectionRegistration registration) { - this.collectionRegistration = registration; + prometheusMetricReader.register(registration); } @Override public CompletableResultCode forceFlush() { - return CompletableResultCode.ofSuccess(); + return prometheusMetricReader.forceFlush(); } @Override public CompletableResultCode shutdown() { CompletableResultCode result = new CompletableResultCode(); - Thread thread = - THREAD_FACTORY.newThread( - () -> { - try { - server.stop(10); - executor.shutdownNow(); - } catch (Throwable t) { - result.fail(); - return; - } - result.succeed(); - }); - thread.start(); + Runnable shutdownFunction = + () -> { + try { + prometheusRegistry.unregister(prometheusMetricReader); + httpServer.stop(); + prometheusMetricReader.shutdown().whenComplete(result::succeed); + } catch (Throwable t) { + result.fail(); + } + }; + Thread shutdownThread = new Thread(shutdownFunction, "prometheus-httpserver-shutdown"); + shutdownThread.setDaemon(true); + shutdownThread.start(); return result; } @@ -166,112 +115,11 @@ public void close() { @Override public String toString() { - return "PrometheusHttpServer{address=" + server.getAddress() + "}"; + return "PrometheusHttpServer{address=" + getAddress() + "}"; } // Visible for testing. InetSocketAddress getAddress() { - return server.getAddress(); - } - - private static class MetricsHandler implements HttpHandler { - - private final Set allConflictHeaderNames = - Collections.newSetFromMap(new ConcurrentHashMap<>()); - - private final Supplier> metricsSupplier; - - private MetricsHandler(Supplier> metricsSupplier) { - this.metricsSupplier = metricsSupplier; - } - - @Override - public void handle(HttpExchange exchange) throws IOException { - Collection metrics = metricsSupplier.get(); - Set requestedNames = parseQuery(exchange.getRequestURI().getRawQuery()); - Predicate filter = - requestedNames.isEmpty() ? unused -> true : requestedNames::contains; - Serializer serializer = - Serializer.create(exchange.getRequestHeaders().getFirst("Accept"), filter); - exchange.getResponseHeaders().set("Content-Type", serializer.contentType()); - - boolean compress = shouldUseCompression(exchange); - if (compress) { - exchange.getResponseHeaders().set("Content-Encoding", "gzip"); - } - - if (exchange.getRequestMethod().equals("HEAD")) { - exchange.sendResponseHeaders(HttpURLConnection.HTTP_OK, -1); - } else { - exchange.sendResponseHeaders(HttpURLConnection.HTTP_OK, 0); - OutputStream out; - if (compress) { - out = new GZIPOutputStream(exchange.getResponseBody()); - } else { - out = exchange.getResponseBody(); - } - Set conflictHeaderNames = serializer.write(metrics, out); - conflictHeaderNames.removeAll(allConflictHeaderNames); - if (conflictHeaderNames.size() > 0 && LOGGER.isLoggable(Level.WARNING)) { - LOGGER.log( - Level.WARNING, - "Metric conflict(s) detected. Multiple metrics with same name but different type: " - + conflictHeaderNames.stream().collect(joining(",", "[", "]"))); - allConflictHeaderNames.addAll(conflictHeaderNames); - } - } - exchange.close(); - } - } - - private static boolean shouldUseCompression(HttpExchange exchange) { - List encodingHeaders = exchange.getRequestHeaders().get("Accept-Encoding"); - if (encodingHeaders == null) { - return false; - } - - for (String encodingHeader : encodingHeaders) { - String[] encodings = encodingHeader.split(","); - for (String encoding : encodings) { - if (encoding.trim().equalsIgnoreCase("gzip")) { - return true; - } - } - } - return false; - } - - private static Set parseQuery(@Nullable String query) throws IOException { - if (query == null) { - return Collections.emptySet(); - } - Set names = new HashSet<>(); - String[] pairs = query.split("&"); - for (String pair : pairs) { - int idx = pair.indexOf("="); - if (idx != -1 && URLDecoder.decode(pair.substring(0, idx), "UTF-8").equals("name[]")) { - names.add(URLDecoder.decode(pair.substring(idx + 1), "UTF-8")); - } - } - return names; - } - - private enum HealthHandler implements HttpHandler { - INSTANCE; - - private static final byte[] RESPONSE = "Exporter is Healthy.".getBytes(StandardCharsets.UTF_8); - private static final String CONTENT_LENGTH_VALUE = String.valueOf(RESPONSE.length); - - @Override - public void handle(HttpExchange exchange) throws IOException { - exchange.getResponseHeaders().set("Content-Length", CONTENT_LENGTH_VALUE); - if (exchange.getRequestMethod().equals("HEAD")) { - exchange.sendResponseHeaders(HttpURLConnection.HTTP_OK, -1); - } else { - exchange.sendResponseHeaders(HttpURLConnection.HTTP_OK, RESPONSE.length); - exchange.getResponseBody().write(RESPONSE); - } - exchange.close(); - } + return new InetSocketAddress(host, httpServer.getPort()); } } diff --git a/exporters/prometheus/src/main/java/io/opentelemetry/exporter/prometheus/PrometheusHttpServerBuilder.java b/exporters/prometheus/src/main/java/io/opentelemetry/exporter/prometheus/PrometheusHttpServerBuilder.java index 539f46811ed..975091a93b5 100644 --- a/exporters/prometheus/src/main/java/io/opentelemetry/exporter/prometheus/PrometheusHttpServerBuilder.java +++ b/exporters/prometheus/src/main/java/io/opentelemetry/exporter/prometheus/PrometheusHttpServerBuilder.java @@ -8,9 +8,8 @@ import static io.opentelemetry.api.internal.Utils.checkArgument; import static java.util.Objects.requireNonNull; -import io.opentelemetry.sdk.internal.DaemonThreadFactory; +import io.prometheus.metrics.model.registry.PrometheusRegistry; import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; import javax.annotation.Nullable; /** A builder for {@link PrometheusHttpServer}. */ @@ -21,6 +20,8 @@ public final class PrometheusHttpServerBuilder { private String host = DEFAULT_HOST; private int port = DEFAULT_PORT; + private PrometheusRegistry prometheusRegistry = new PrometheusRegistry(); + private boolean otelScopeEnabled = true; @Nullable private ExecutorService executor; @@ -46,21 +47,26 @@ public PrometheusHttpServerBuilder setExecutor(ExecutorService executor) { return this; } + /** Sets the {@link PrometheusRegistry} to be used for {@link PrometheusHttpServer}. */ + public PrometheusHttpServerBuilder setPrometheusRegistry(PrometheusRegistry prometheusRegistry) { + requireNonNull(prometheusRegistry, "prometheusRegistry"); + this.prometheusRegistry = prometheusRegistry; + return this; + } + + /** Set if the {@code otel_scope_*} attributes are generated. Default is {@code true}. */ + public PrometheusHttpServerBuilder setOtelScopeEnabled(boolean otelScopeEnabled) { + this.otelScopeEnabled = otelScopeEnabled; + return this; + } + /** * Returns a new {@link PrometheusHttpServer} with the configuration of this builder which can be * registered with a {@link io.opentelemetry.sdk.metrics.SdkMeterProvider}. */ public PrometheusHttpServer build() { - ExecutorService executorService = this.executor; - if (executorService == null) { - executorService = getDefaultExecutor(); - } - return new PrometheusHttpServer(host, port, executorService); + return new PrometheusHttpServer(host, port, executor, prometheusRegistry, otelScopeEnabled); } PrometheusHttpServerBuilder() {} - - private static ExecutorService getDefaultExecutor() { - return Executors.newFixedThreadPool(5, new DaemonThreadFactory("prometheus-http")); - } } diff --git a/exporters/prometheus/src/main/java/io/opentelemetry/exporter/prometheus/PrometheusMetricNameMapper.java b/exporters/prometheus/src/main/java/io/opentelemetry/exporter/prometheus/PrometheusMetricNameMapper.java deleted file mode 100644 index 0cdc35ea33d..00000000000 --- a/exporters/prometheus/src/main/java/io/opentelemetry/exporter/prometheus/PrometheusMetricNameMapper.java +++ /dev/null @@ -1,104 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package io.opentelemetry.exporter.prometheus; - -import com.google.auto.value.AutoValue; -import io.opentelemetry.api.internal.StringUtils; -import io.opentelemetry.sdk.metrics.data.MetricData; -import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; -import java.util.function.BiFunction; -import javax.annotation.concurrent.Immutable; - -/** A class that maps a raw metric name to Prometheus equivalent name. */ -class PrometheusMetricNameMapper implements BiFunction { - private static final String TOTAL_SUFFIX = "_total"; - static final PrometheusMetricNameMapper INSTANCE = new PrometheusMetricNameMapper(); - - private final Map cache = new ConcurrentHashMap<>(); - private final BiFunction delegate; - - // private constructor - prevent external object initialization - private PrometheusMetricNameMapper() { - this(PrometheusMetricNameMapper::mapToPrometheusName); - } - - // Visible for testing - PrometheusMetricNameMapper(BiFunction delegate) { - this.delegate = delegate; - } - - @Override - public String apply(MetricData rawMetric, PrometheusType prometheusType) { - return cache.computeIfAbsent( - createKeyForCacheMapping(rawMetric, prometheusType), - metricData -> delegate.apply(rawMetric, prometheusType)); - } - - private static String mapToPrometheusName(MetricData rawMetric, PrometheusType prometheusType) { - String name = NameSanitizer.INSTANCE.apply(rawMetric.getName()); - String prometheusEquivalentUnit = - PrometheusUnitsHelper.getEquivalentPrometheusUnit(rawMetric.getUnit()); - boolean shouldAppendUnit = - !StringUtils.isNullOrEmpty(prometheusEquivalentUnit) - && !name.contains(prometheusEquivalentUnit); - // trim counter's _total suffix so the unit is placed before it. - if (prometheusType == PrometheusType.COUNTER && name.endsWith(TOTAL_SUFFIX)) { - name = name.substring(0, name.length() - TOTAL_SUFFIX.length()); - } - // append prometheus unit if not null or empty. - if (shouldAppendUnit) { - name = name + "_" + prometheusEquivalentUnit; - } - - // replace _total suffix, or add if it wasn't already present. - if (prometheusType == PrometheusType.COUNTER) { - name = name + TOTAL_SUFFIX; - } - // special case - gauge - if (rawMetric.getUnit().equals("1") - && prometheusType == PrometheusType.GAUGE - && !name.contains("ratio")) { - name = name + "_ratio"; - } - return name; - } - - /** - * Creates a suitable mapping key to be used for maintaining mapping between raw metric and its - * equivalent Prometheus name. - * - * @param metricData the metric data for which the mapping is to be created. - * @param prometheusType the prometheus type to which the metric is to be mapped. - * @return an {@link ImmutableMappingKey} that can be used as a key for mapping between metric - * data and its prometheus equivalent name. - */ - private static ImmutableMappingKey createKeyForCacheMapping( - MetricData metricData, PrometheusType prometheusType) { - return ImmutableMappingKey.create( - metricData.getName(), metricData.getUnit(), prometheusType.name()); - } - - /** - * Objects of this class acts as mapping keys for Prometheus metric mapping cache used in {@link - * PrometheusMetricNameMapper}. - */ - @Immutable - @AutoValue - abstract static class ImmutableMappingKey { - static ImmutableMappingKey create( - String rawMetricName, String rawMetricUnit, String prometheusType) { - return new AutoValue_PrometheusMetricNameMapper_ImmutableMappingKey( - rawMetricName, rawMetricUnit, prometheusType); - } - - abstract String rawMetricName(); - - abstract String rawMetricUnit(); - - abstract String prometheusType(); - } -} diff --git a/exporters/prometheus/src/main/java/io/opentelemetry/exporter/prometheus/PrometheusMetricReader.java b/exporters/prometheus/src/main/java/io/opentelemetry/exporter/prometheus/PrometheusMetricReader.java new file mode 100644 index 00000000000..02ac63e4d81 --- /dev/null +++ b/exporters/prometheus/src/main/java/io/opentelemetry/exporter/prometheus/PrometheusMetricReader.java @@ -0,0 +1,58 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.exporter.prometheus; + +import io.opentelemetry.sdk.common.CompletableResultCode; +import io.opentelemetry.sdk.metrics.InstrumentType; +import io.opentelemetry.sdk.metrics.data.AggregationTemporality; +import io.opentelemetry.sdk.metrics.export.CollectionRegistration; +import io.opentelemetry.sdk.metrics.export.MetricReader; +import io.prometheus.metrics.model.registry.MultiCollector; +import io.prometheus.metrics.model.snapshots.MetricSnapshots; + +/** + * This is the bridge between Prometheus and OpenTelemetry. + * + *

    The {@link PrometheusMetricReader} is a Prometheus {@link MultiCollector} and can be + * registered with the {@link io.prometheus.metrics.model.registry.PrometheusRegistry + * PrometheusRegistry}. It's also an OpenTelemetry {@link MetricReader} and can be registered with a + * {@link io.opentelemetry.sdk.metrics.SdkMeterProvider SdkMeterProvider}. + */ +public class PrometheusMetricReader implements MetricReader, MultiCollector { + + private volatile CollectionRegistration collectionRegistration = CollectionRegistration.noop(); + private final Otel2PrometheusConverter converter; + + /** See {@link Otel2PrometheusConverter#Otel2PrometheusConverter(boolean)}. */ + public PrometheusMetricReader(boolean otelScopeEnabled) { + this.converter = new Otel2PrometheusConverter(otelScopeEnabled); + } + + @Override + public AggregationTemporality getAggregationTemporality(InstrumentType instrumentType) { + return AggregationTemporality.CUMULATIVE; + } + + @Override + public void register(CollectionRegistration registration) { + this.collectionRegistration = registration; + } + + @Override + public CompletableResultCode forceFlush() { + return CompletableResultCode.ofSuccess(); + } + + @Override + public CompletableResultCode shutdown() { + return CompletableResultCode.ofSuccess(); + } + + @Override + public MetricSnapshots collect() { + return converter.convert(collectionRegistration.collectAllMetrics()); + } +} diff --git a/exporters/prometheus/src/main/java/io/opentelemetry/exporter/prometheus/PrometheusType.java b/exporters/prometheus/src/main/java/io/opentelemetry/exporter/prometheus/PrometheusType.java deleted file mode 100644 index 8f55022d3b8..00000000000 --- a/exporters/prometheus/src/main/java/io/opentelemetry/exporter/prometheus/PrometheusType.java +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package io.opentelemetry.exporter.prometheus; - -import io.opentelemetry.sdk.metrics.data.DoublePointData; -import io.opentelemetry.sdk.metrics.data.LongPointData; -import io.opentelemetry.sdk.metrics.data.MetricData; -import io.opentelemetry.sdk.metrics.data.SumData; - -// Four types we use are same in prometheus and openmetrics format -enum PrometheusType { - GAUGE("gauge"), - COUNTER("counter"), - SUMMARY("summary"), - HISTOGRAM("histogram"); - - private final String typeString; - - PrometheusType(String typeString) { - this.typeString = typeString; - } - - static PrometheusType forMetric(MetricData metric) { - switch (metric.getType()) { - case LONG_GAUGE: - case DOUBLE_GAUGE: - return GAUGE; - case LONG_SUM: - SumData longSumData = metric.getLongSumData(); - if (longSumData.isMonotonic()) { - return COUNTER; - } - return GAUGE; - case DOUBLE_SUM: - SumData doubleSumData = metric.getDoubleSumData(); - if (doubleSumData.isMonotonic()) { - return COUNTER; - } - return GAUGE; - case SUMMARY: - return SUMMARY; - case HISTOGRAM: - case EXPONENTIAL_HISTOGRAM: - return HISTOGRAM; - } - throw new IllegalArgumentException( - "Unsupported metric type, this generally indicates version misalignment " - + "among opentelemetry dependencies. Please make sure to use opentelemetry-bom."); - } - - String getTypeString() { - return typeString; - } -} diff --git a/exporters/prometheus/src/main/java/io/opentelemetry/exporter/prometheus/PrometheusUnitsHelper.java b/exporters/prometheus/src/main/java/io/opentelemetry/exporter/prometheus/PrometheusUnitsHelper.java index a0ca81669d9..9657b88ada5 100644 --- a/exporters/prometheus/src/main/java/io/opentelemetry/exporter/prometheus/PrometheusUnitsHelper.java +++ b/exporters/prometheus/src/main/java/io/opentelemetry/exporter/prometheus/PrometheusUnitsHelper.java @@ -5,208 +5,94 @@ package io.opentelemetry.exporter.prometheus; -import static io.opentelemetry.exporter.prometheus.NameSanitizer.SANITIZE_CONSECUTIVE_UNDERSCORES; +import io.prometheus.metrics.model.snapshots.Unit; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; +import javax.annotation.Nullable; -import io.opentelemetry.api.internal.StringUtils; -import java.util.regex.Pattern; +/** Convert OpenTelemetry unit names to Prometheus units. */ +class PrometheusUnitsHelper { -/** - * A utility class that contains helper function(s) to aid conversion from OTLP to Prometheus units. - * - * @see OpenMetrics - * specification for units - * @see Prometheus best practices - * for units - */ -final class PrometheusUnitsHelper { - - private static final Pattern INVALID_CHARACTERS_PATTERN = Pattern.compile("[^a-zA-Z0-9]"); - private static final Pattern CHARACTERS_BETWEEN_BRACES_PATTERN = Pattern.compile("\\{(.*?)}"); - private static final Pattern SANITIZE_LEADING_UNDERSCORES = Pattern.compile("^_+"); - private static final Pattern SANITIZE_TRAILING_UNDERSCORES = Pattern.compile("_+$"); - - private PrometheusUnitsHelper() { - // Prevent object creation for utility classes - } + private static final Map pluralNames = new ConcurrentHashMap<>(); + private static final Map singularNames = new ConcurrentHashMap<>(); + private static final Map predefinedUnits = new ConcurrentHashMap<>(); - /** - * A utility function that returns the equivalent Prometheus name for the provided OTLP metric - * unit. - * - * @param rawMetricUnitName The raw metric unit for which Prometheus metric unit needs to be - * computed. - * @return the computed Prometheus metric unit equivalent of the OTLP metric un - */ - static String getEquivalentPrometheusUnit(String rawMetricUnitName) { - if (StringUtils.isNullOrEmpty(rawMetricUnitName)) { - return rawMetricUnitName; - } - // Drop units specified between curly braces - String convertedMetricUnitName = removeUnitPortionInBraces(rawMetricUnitName); - // Handling for the "per" unit(s), e.g. foo/bar -> foo_per_bar - convertedMetricUnitName = convertRateExpressedToPrometheusUnit(convertedMetricUnitName); - // Converting abbreviated unit names to full names - return cleanUpString(getPrometheusUnit(convertedMetricUnitName)); + // See + // https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/c3b2997563106e11d39f66eec629fde25dce2bdd/pkg/translator/prometheus/normalize_name.go#L19-L19 + static { + // Time + initUnit("a", "years", "year"); + initUnit("mo", "months", "month"); + initUnit("wk", "weeks", "week"); + initUnit("d", "days", "day"); + initUnit("h", "hours", "hour"); + initUnit("min", "minutes", "minute"); + initUnit("s", "seconds", "second"); + initUnit("ms", "milliseconds", "millisecond"); + initUnit("us", "microseconds", "microsecond"); + initUnit("ns", "nanoseconds", "nanosecond"); + // Bytes + initUnit("By", "bytes", "byte"); + initUnit("KiBy", "kibibytes", "kibibyte"); + initUnit("MiBy", "mebibytes", "mebibyte"); + initUnit("GiBy", "gibibytes", "gibibyte"); + initUnit("TiBy", "tibibytes", "tibibyte"); + initUnit("KBy", "kilobytes", "kilobyte"); + initUnit("MBy", "megabytes", "megabyte"); + initUnit("GBy", "gigabytes", "gigabyte"); + initUnit("TBy", "terabytes", "terabyte"); + // SI + initUnit("m", "meters", "meter"); + initUnit("V", "volts", "volt"); + initUnit("A", "amperes", "ampere"); + initUnit("J", "joules", "joule"); + initUnit("W", "watts", "watt"); + initUnit("g", "grams", "gram"); + // Misc + initUnit("Cel", "celsius"); + initUnit("Hz", "hertz"); + initUnit("%", "percent"); + initUnit("1", "ratio"); } - /** - * This method is used to convert the units expressed as a rate via '/' symbol in their name to - * their expanded text equivalent. For instance, km/h => km_per_hour. The method operates on the - * input by splitting it in 2 parts - before and after '/' symbol and will attempt to expand any - * known unit abbreviation in both parts. Unknown abbreviations & unsupported characters will - * remain unchanged in the final output of this function. - * - * @param rateExpressedUnit The rate unit input that needs to be converted to its text equivalent. - * @return The text equivalent of unit expressed as rate. If the input does not contain '/', the - * function returns it as-is. - */ - private static String convertRateExpressedToPrometheusUnit(String rateExpressedUnit) { - if (!rateExpressedUnit.contains("/")) { - return rateExpressedUnit; - } - String[] rateEntities = rateExpressedUnit.split("/", 2); - // Only convert rate expressed units if it's a valid expression - if (rateEntities[1].equals("")) { - return rateExpressedUnit; - } - return getPrometheusUnit(rateEntities[0]) + "_per_" + getPrometheusPerUnit(rateEntities[1]); - } + private PrometheusUnitsHelper() {} - /** - * This method drops all characters enclosed within '{}' (including the curly braces) by replacing - * them with an empty string. Note that this method will not produce the intended effect if there - * are nested curly braces within the outer enclosure of '{}'. - * - *

    For instance, {packet{s}s} => s}. - * - * @param unit The input unit from which text within curly braces needs to be removed. - * @return The resulting unit after removing the text within '{}'. - */ - private static String removeUnitPortionInBraces(String unit) { - return CHARACTERS_BETWEEN_BRACES_PATTERN.matcher(unit).replaceAll(""); + private static void initUnit(String otelName, String pluralName) { + pluralNames.put(otelName, pluralName); + predefinedUnits.put(otelName, new Unit(pluralName)); } - /** - * Replaces all characters that are not a letter or a digit with '_' to make the resulting string - * Prometheus compliant. This method also removes leading and trailing underscores - this is done - * to keep the resulting unit similar to what is produced from the collector's implementation. - * - * @param string The string input that needs to be made Prometheus compliant. - * @return the cleaned-up Prometheus compliant string. - */ - private static String cleanUpString(String string) { - return SANITIZE_LEADING_UNDERSCORES - .matcher( - SANITIZE_TRAILING_UNDERSCORES - .matcher( - SANITIZE_CONSECUTIVE_UNDERSCORES - .matcher(INVALID_CHARACTERS_PATTERN.matcher(string).replaceAll("_")) - .replaceAll("_")) - .replaceAll("")) - .replaceAll(""); + private static void initUnit(String otelName, String pluralName, String singularName) { + initUnit(otelName, pluralName); + singularNames.put(otelName, singularName); } - /** - * This method retrieves the expanded Prometheus unit name for known abbreviations. OTLP metrics - * use the c/s notation as specified at UCUM. The list of - * mappings is adopted from OpenTelemetry - * Collector Contrib. - * - * @param unitAbbreviation The unit that name that needs to be expanded/converted to Prometheus - * units. - * @return The expanded/converted unit name if known, otherwise returns the input unit name as-is. - */ - private static String getPrometheusUnit(String unitAbbreviation) { - switch (unitAbbreviation) { - // Time - case "d": - return "days"; - case "h": - return "hours"; - case "min": - return "minutes"; - case "s": - return "seconds"; - case "ms": - return "milliseconds"; - case "us": - return "microseconds"; - case "ns": - return "nanoseconds"; - // Bytes - case "By": - return "bytes"; - case "KiBy": - return "kibibytes"; - case "MiBy": - return "mebibytes"; - case "GiBy": - return "gibibytes"; - case "TiBy": - return "tibibytes"; - case "KBy": - return "kilobytes"; - case "MBy": - return "megabytes"; - case "GBy": - return "gigabytes"; - case "TBy": - return "terabytes"; - // SI - case "m": - return "meters"; - case "V": - return "volts"; - case "A": - return "amperes"; - case "J": - return "joules"; - case "W": - return "watts"; - case "g": - return "grams"; - // Misc - case "Cel": - return "celsius"; - case "Hz": - return "hertz"; - case "1": - return ""; - case "%": - return "percent"; - default: - return unitAbbreviation; + @Nullable + static Unit convertUnit(String otelUnit) { + if (otelUnit.isEmpty() || otelUnit.equals("1")) { + // The spec says "1" should be translated to "ratio", but this is not implemented in the Java + // SDK. + return null; } - } - - /** - * This method retrieves the expanded Prometheus unit name to be used with "per" units for known - * units. For example: s => per second (singular) - * - * @param perUnitAbbreviation The unit abbreviation used in a 'per' unit. - * @return The expanded unit equivalent to be used in 'per' unit if the input is a known unit, - * otherwise returns the input as-is. - */ - private static String getPrometheusPerUnit(String perUnitAbbreviation) { - switch (perUnitAbbreviation) { - case "s": - return "second"; - case "m": - return "minute"; - case "h": - return "hour"; - case "d": - return "day"; - case "w": - return "week"; - case "mo": - return "month"; - case "y": - return "year"; - default: - return perUnitAbbreviation; + if (otelUnit.contains("{")) { + otelUnit = otelUnit.replaceAll("\\{[^}]*}", "").trim(); + if (otelUnit.isEmpty() || otelUnit.equals("/")) { + return null; + } + } + if (predefinedUnits.containsKey(otelUnit)) { + return predefinedUnits.get(otelUnit); + } + if (otelUnit.contains("/")) { + String[] parts = otelUnit.split("/", 2); + String part1 = pluralNames.getOrDefault(parts[0], parts[0]).trim(); + String part2 = singularNames.getOrDefault(parts[1], parts[1]).trim(); + if (part1.isEmpty()) { + return new Unit("per_" + part2); + } else { + return new Unit(part1 + "_per_" + part2); + } } + return new Unit(otelUnit); } } diff --git a/exporters/prometheus/src/main/java/io/opentelemetry/exporter/prometheus/Serializer.java b/exporters/prometheus/src/main/java/io/opentelemetry/exporter/prometheus/Serializer.java deleted file mode 100644 index a7089d03abb..00000000000 --- a/exporters/prometheus/src/main/java/io/opentelemetry/exporter/prometheus/Serializer.java +++ /dev/null @@ -1,707 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -// Includes work from: - -/* - * Prometheus instrumentation library for JVM applications - * Copyright 2012-2015 The Prometheus Authors - * - * This product includes software developed at - * Boxever Ltd. (http://www.boxever.com/). - * - * This product includes software developed at - * SoundCloud Ltd. (http://soundcloud.com/). - * - * This product includes software developed as part of the - * Ocelli project by Netflix Inc. (https://github.com/Netflix/ocelli/). - */ - -package io.opentelemetry.exporter.prometheus; - -import io.opentelemetry.api.common.AttributeKey; -import io.opentelemetry.api.common.Attributes; -import io.opentelemetry.api.trace.SpanContext; -import io.opentelemetry.sdk.common.InstrumentationScopeInfo; -import io.opentelemetry.sdk.internal.ThrottlingLogger; -import io.opentelemetry.sdk.metrics.data.AggregationTemporality; -import io.opentelemetry.sdk.metrics.data.DoubleExemplarData; -import io.opentelemetry.sdk.metrics.data.DoublePointData; -import io.opentelemetry.sdk.metrics.data.ExemplarData; -import io.opentelemetry.sdk.metrics.data.HistogramPointData; -import io.opentelemetry.sdk.metrics.data.LongExemplarData; -import io.opentelemetry.sdk.metrics.data.LongPointData; -import io.opentelemetry.sdk.metrics.data.MetricData; -import io.opentelemetry.sdk.metrics.data.MetricDataType; -import io.opentelemetry.sdk.metrics.data.PointData; -import io.opentelemetry.sdk.metrics.data.SummaryPointData; -import io.opentelemetry.sdk.metrics.data.ValueAtQuantile; -import io.opentelemetry.sdk.resources.Resource; -import java.io.BufferedWriter; -import java.io.IOException; -import java.io.OutputStream; -import java.io.OutputStreamWriter; -import java.io.UncheckedIOException; -import java.io.Writer; -import java.nio.charset.StandardCharsets; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.HashSet; -import java.util.LinkedHashMap; -import java.util.LinkedHashSet; -import java.util.List; -import java.util.Map; -import java.util.Optional; -import java.util.Set; -import java.util.concurrent.TimeUnit; -import java.util.function.BiConsumer; -import java.util.function.Predicate; -import java.util.logging.Level; -import java.util.logging.Logger; -import javax.annotation.Nullable; - -/** Serializes metrics into Prometheus exposition formats. */ -// Adapted from -// https://github.com/prometheus/client_java/blob/master/simpleclient_common/src/main/java/io/prometheus/client/exporter/common/TextFormat.java -abstract class Serializer { - - private static final Logger LOGGER = Logger.getLogger(Serializer.class.getName()); - private static final ThrottlingLogger THROTTLING_LOGGER = new ThrottlingLogger(LOGGER); - - static Serializer create(@Nullable String acceptHeader, Predicate filter) { - if (acceptHeader == null) { - return new Prometheus004Serializer(filter); - } - - for (String accepts : acceptHeader.split(",")) { - if ("application/openmetrics-text".equals(accepts.split(";")[0].trim())) { - return new OpenMetrics100Serializer(filter); - } - } - - return new Prometheus004Serializer(filter); - } - - private final Predicate metricNameFilter; - - Serializer(Predicate metricNameFilter) { - this.metricNameFilter = metricNameFilter; - } - - abstract String contentType(); - - abstract String headerName(String name, MetricData rawMetric, PrometheusType type); - - abstract void writeHelp(Writer writer, String description) throws IOException; - - abstract void writeTimestamp(Writer writer, long timestampNanos) throws IOException; - - abstract void writeExemplar( - Writer writer, - Collection exemplars, - double minExemplar, - double maxExemplar) - throws IOException; - - abstract void writeEof(Writer writer) throws IOException; - - final Set write(Collection metrics, OutputStream output) throws IOException { - Set conflictMetricNames = new HashSet<>(); - Map> metricsByName = new LinkedHashMap<>(); - Set scopes = new LinkedHashSet<>(); - // Iterate through metrics, filtering and grouping by headerName - for (MetricData metric : metrics) { - // Not supported in specification yet. - if (metric.getType() == MetricDataType.EXPONENTIAL_HISTOGRAM) { - continue; - } - // PrometheusHttpServer#getAggregationTemporality specifies cumulative temporality for - // all instruments, but non-SDK MetricProducers may not conform. We drop delta - // temporality metrics to avoid the complexity of stateful transformation to cumulative. - if (isDeltaTemporality(metric)) { - continue; - } - PrometheusType prometheusType = PrometheusType.forMetric(metric); - String metricName = PrometheusMetricNameMapper.INSTANCE.apply(metric, prometheusType); - // Skip metrics which do not pass metricNameFilter - if (!metricNameFilter.test(metricName)) { - continue; - } - List metricsWithHeaderName = - metricsByName.computeIfAbsent(metricName, unused -> new ArrayList<>()); - // Skip metrics with the same name but different type - if (metricsWithHeaderName.size() > 0 - && prometheusType != PrometheusType.forMetric(metricsWithHeaderName.get(0))) { - conflictMetricNames.add(metricName); - continue; - } - - metricsWithHeaderName.add(metric); - scopes.add(metric.getInstrumentationScopeInfo()); - } - - Optional optResource = metrics.stream().findFirst().map(MetricData::getResource); - try (Writer writer = - new BufferedWriter(new OutputStreamWriter(output, StandardCharsets.UTF_8))) { - if (optResource.isPresent()) { - writeResource(optResource.get(), writer); - } - for (InstrumentationScopeInfo scope : scopes) { - writeScopeInfo(scope, writer); - } - for (Map.Entry> entry : metricsByName.entrySet()) { - write(entry.getValue(), entry.getKey(), writer); - } - writeEof(writer); - } - return conflictMetricNames; - } - - private void write(List metrics, String metricName, Writer writer) - throws IOException { - // Write header based on first metric - MetricData first = metrics.get(0); - PrometheusType type = PrometheusType.forMetric(first); - String headerName = headerName(metricName, first, type); - String description = metrics.get(0).getDescription(); - - writer.write("# TYPE "); - writer.write(headerName); - writer.write(' '); - writer.write(type.getTypeString()); - writer.write('\n'); - - writer.write("# HELP "); - writer.write(headerName); - writer.write(' '); - writeHelp(writer, description); - writer.write('\n'); - - // Then write the metrics. - for (MetricData metric : metrics) { - write(metric, metricName, writer); - } - } - - private void write(MetricData metric, String metricName, Writer writer) throws IOException { - for (PointData point : getPoints(metric)) { - switch (metric.getType()) { - case DOUBLE_SUM: - case DOUBLE_GAUGE: - writePoint( - writer, - metric.getInstrumentationScopeInfo(), - metricName, - ((DoublePointData) point).getValue(), - point.getAttributes(), - point.getEpochNanos()); - break; - case LONG_SUM: - case LONG_GAUGE: - writePoint( - writer, - metric.getInstrumentationScopeInfo(), - metricName, - (double) ((LongPointData) point).getValue(), - point.getAttributes(), - point.getEpochNanos()); - break; - case HISTOGRAM: - writeHistogram( - writer, metric.getInstrumentationScopeInfo(), metricName, (HistogramPointData) point); - break; - case SUMMARY: - writeSummary( - writer, metric.getInstrumentationScopeInfo(), metricName, (SummaryPointData) point); - break; - case EXPONENTIAL_HISTOGRAM: - throw new IllegalArgumentException("Can't happen"); - } - } - } - - private static boolean isDeltaTemporality(MetricData metricData) { - switch (metricData.getType()) { - case LONG_GAUGE: - case DOUBLE_GAUGE: - case SUMMARY: - return false; - case LONG_SUM: - return metricData.getLongSumData().getAggregationTemporality() - == AggregationTemporality.DELTA; - case DOUBLE_SUM: - return metricData.getDoubleSumData().getAggregationTemporality() - == AggregationTemporality.DELTA; - case HISTOGRAM: - return metricData.getHistogramData().getAggregationTemporality() - == AggregationTemporality.DELTA; - default: - } - throw new IllegalArgumentException("Can't happen"); - } - - private static void writeResource(Resource resource, Writer writer) throws IOException { - if (resource.getAttributes().isEmpty()) { - return; - } - - writer.write("# TYPE target info\n"); - writer.write("# HELP target Target metadata\n"); - writer.write("target_info{"); - writeAttributePairs(writer, /* initialComma= */ false, resource.getAttributes()); - writer.write("} 1\n"); - } - - private static void writeScopeInfo( - InstrumentationScopeInfo instrumentationScopeInfo, Writer writer) throws IOException { - if (instrumentationScopeInfo.getAttributes().isEmpty()) { - return; - } - - writer.write("# TYPE otel_scope_info info\n"); - writer.write("# HELP otel_scope_info Scope metadata\n"); - writer.write("otel_scope_info{"); - writeScopeNameAndVersion(writer, instrumentationScopeInfo); - writeAttributePairs(writer, /* initialComma= */ true, instrumentationScopeInfo.getAttributes()); - writer.write("} 1\n"); - } - - private void writeHistogram( - Writer writer, - InstrumentationScopeInfo instrumentationScopeInfo, - String name, - HistogramPointData point) - throws IOException { - writePoint( - writer, - instrumentationScopeInfo, - name + "_count", - (double) point.getCount(), - point.getAttributes(), - point.getEpochNanos()); - writePoint( - writer, - instrumentationScopeInfo, - name + "_sum", - point.getSum(), - point.getAttributes(), - point.getEpochNanos()); - - long cumulativeCount = 0; - List counts = point.getCounts(); - for (int i = 0; i < counts.size(); i++) { - // This is the upper boundary (inclusive). I.e. all values should be < this value (LE - - // Less-then-or-Equal). - double boundary = getBucketUpperBound(point, i); - - cumulativeCount += counts.get(i); - writePoint( - writer, - instrumentationScopeInfo, - name + "_bucket", - (double) cumulativeCount, - point.getAttributes(), - point.getEpochNanos(), - "le", - boundary, - point.getExemplars(), - getBucketLowerBound(point, i), - boundary); - } - } - - /** - * Returns the lower bound of a bucket (all values would have been greater than). - * - * @param bucketIndex The bucket index, should match {@link HistogramPointData#getCounts()} index. - */ - static double getBucketLowerBound(HistogramPointData point, int bucketIndex) { - return bucketIndex > 0 ? point.getBoundaries().get(bucketIndex - 1) : Double.NEGATIVE_INFINITY; - } - - /** - * Returns the upper inclusive bound of a bucket (all values would have been less then or equal). - * - * @param bucketIndex The bucket index, should match {@link HistogramPointData#getCounts()} index. - */ - static double getBucketUpperBound(HistogramPointData point, int bucketIndex) { - List boundaries = point.getBoundaries(); - return (bucketIndex < boundaries.size()) - ? boundaries.get(bucketIndex) - : Double.POSITIVE_INFINITY; - } - - private void writeSummary( - Writer writer, - InstrumentationScopeInfo instrumentationScopeInfo, - String name, - SummaryPointData point) - throws IOException { - writePoint( - writer, - instrumentationScopeInfo, - name + "_count", - (double) point.getCount(), - point.getAttributes(), - point.getEpochNanos()); - writePoint( - writer, - instrumentationScopeInfo, - name + "_sum", - point.getSum(), - point.getAttributes(), - point.getEpochNanos()); - - List valueAtQuantiles = point.getValues(); - for (ValueAtQuantile valueAtQuantile : valueAtQuantiles) { - writePoint( - writer, - instrumentationScopeInfo, - name, - valueAtQuantile.getValue(), - point.getAttributes(), - point.getEpochNanos(), - "quantile", - valueAtQuantile.getQuantile(), - Collections.emptyList(), - 0, - 0); - } - } - - private void writePoint( - Writer writer, - InstrumentationScopeInfo instrumentationScopeInfo, - String name, - double value, - Attributes attributes, - long epochNanos) - throws IOException { - writer.write(name); - writeAttributes(writer, instrumentationScopeInfo, attributes); - writer.write(' '); - writeDouble(writer, value); - writer.write(' '); - writeTimestamp(writer, epochNanos); - writer.write('\n'); - } - - private void writePoint( - Writer writer, - InstrumentationScopeInfo instrumentationScopeInfo, - String name, - double value, - Attributes attributes, - long epochNanos, - String additionalAttrKey, - double additionalAttrValue, - Collection exemplars, - double minExemplar, - double maxExemplar) - throws IOException { - writer.write(name); - writeAttributes( - writer, instrumentationScopeInfo, attributes, additionalAttrKey, additionalAttrValue); - writer.write(' '); - writeDouble(writer, value); - writer.write(' '); - writeTimestamp(writer, epochNanos); - writeExemplar(writer, exemplars, minExemplar, maxExemplar); - writer.write('\n'); - } - - private static void writeAttributes( - Writer writer, InstrumentationScopeInfo instrumentationScopeInfo, Attributes attributes) - throws IOException { - writer.write('{'); - writeScopeNameAndVersion(writer, instrumentationScopeInfo); - if (!attributes.isEmpty()) { - writeAttributePairs(writer, /* initialComma= */ true, attributes); - } - writer.write('}'); - } - - private static void writeAttributes( - Writer writer, - InstrumentationScopeInfo instrumentationScopeInfo, - Attributes attributes, - String additionalAttrKey, - double additionalAttrValue) - throws IOException { - writer.write('{'); - writeScopeNameAndVersion(writer, instrumentationScopeInfo); - writer.write(','); - if (!attributes.isEmpty()) { - writeAttributePairs(writer, /* initialComma= */ false, attributes); - writer.write(','); - } - writer.write(additionalAttrKey); - writer.write("=\""); - writeDouble(writer, additionalAttrValue); - writer.write('"'); - writer.write('}'); - } - - private static void writeScopeNameAndVersion( - Writer writer, InstrumentationScopeInfo instrumentationScopeInfo) throws IOException { - writer.write("otel_scope_name=\""); - writer.write(instrumentationScopeInfo.getName()); - writer.write("\""); - if (instrumentationScopeInfo.getVersion() != null) { - writer.write(",otel_scope_version=\""); - writer.write(instrumentationScopeInfo.getVersion()); - writer.write("\""); - } - } - - private static void writeAttributePairs( - Writer writer, boolean initialComma, Attributes attributes) throws IOException { - try { - // This logic handles colliding attribute keys by joining the values, - // separated by a semicolon. It relies on the attributes being sorted, so that - // colliding attribute keys are in subsequent iterations of the for loop. - attributes.forEach( - new BiConsumer, Object>() { - boolean initialAttribute = true; - String previousKey = ""; - String previousValue = ""; - - @Override - public void accept(AttributeKey key, Object value) { - try { - String sanitizedKey = NameSanitizer.INSTANCE.apply(key.getKey()); - int compare = sanitizedKey.compareTo(previousKey); - if (compare == 0) { - // This key collides with the previous one. Append the value - // to the previous value instead of writing the key again. - writer.write(';'); - } else { - if (compare < 0) { - THROTTLING_LOGGER.log( - Level.WARNING, - "Dropping out-of-order attribute " - + sanitizedKey - + "=" - + value - + ", which occurred after " - + previousKey - + ". This can occur when an alternative Attribute implementation is used."); - } - if (!initialAttribute) { - writer.write('"'); - } - if (initialComma || !initialAttribute) { - writer.write(','); - } - writer.write(sanitizedKey); - writer.write("=\""); - } - String stringValue = value.toString(); - writeEscapedLabelValue(writer, stringValue); - previousKey = sanitizedKey; - previousValue = stringValue; - initialAttribute = false; - } catch (IOException e) { - throw new UncheckedIOException(e); - } - } - }); - if (!attributes.isEmpty()) { - writer.write('"'); - } - } catch (UncheckedIOException e) { - throw e.getCause(); - } - } - - private static void writeDouble(Writer writer, double d) throws IOException { - if (d == Double.POSITIVE_INFINITY) { - writer.write("+Inf"); - } else if (d == Double.NEGATIVE_INFINITY) { - writer.write("-Inf"); - } else { - writer.write(Double.toString(d)); - } - } - - static void writeEscapedLabelValue(Writer writer, String s) throws IOException { - for (int i = 0; i < s.length(); i++) { - char c = s.charAt(i); - switch (c) { - case '\\': - writer.write("\\\\"); - break; - case '\"': - writer.write("\\\""); - break; - case '\n': - writer.write("\\n"); - break; - default: - writer.write(c); - } - } - } - - static class Prometheus004Serializer extends Serializer { - - Prometheus004Serializer(Predicate metricNameFilter) { - super(metricNameFilter); - } - - @Override - String contentType() { - return "text/plain; version=0.0.4; charset=utf-8"; - } - - @Override - String headerName(String name, MetricData rawMetric, PrometheusType type) { - return name; - } - - @Override - void writeHelp(Writer writer, String help) throws IOException { - for (int i = 0; i < help.length(); i++) { - char c = help.charAt(i); - switch (c) { - case '\\': - writer.write("\\\\"); - break; - case '\n': - writer.write("\\n"); - break; - default: - writer.write(c); - } - } - } - - @Override - void writeTimestamp(Writer writer, long timestampNanos) throws IOException { - writer.write(Long.toString(TimeUnit.NANOSECONDS.toMillis(timestampNanos))); - } - - @Override - void writeExemplar( - Writer writer, - Collection exemplars, - double minExemplar, - double maxExemplar) { - // Don't write exemplars - } - - @Override - void writeEof(Writer writer) { - // Don't write EOF - } - } - - static class OpenMetrics100Serializer extends Serializer { - - OpenMetrics100Serializer(Predicate metricNameFilter) { - super(metricNameFilter); - } - - @Override - String contentType() { - return "application/openmetrics-text; version=1.0.0; charset=utf-8"; - } - - @Override - String headerName(String name, MetricData rawMetric, PrometheusType type) { - // If the name didn't originally have a _total suffix, and we added it later, omit it from the - // header. - String sanitizedOriginalName = NameSanitizer.INSTANCE.apply(rawMetric.getName()); - if (!sanitizedOriginalName.endsWith("_total") && (type == PrometheusType.COUNTER)) { - return name.substring(0, name.length() - "_total".length()); - } - return name; - } - - @Override - void writeHelp(Writer writer, String description) throws IOException { - writeEscapedLabelValue(writer, description); - } - - @Override - void writeTimestamp(Writer writer, long timestampNanos) throws IOException { - long timestampMillis = TimeUnit.NANOSECONDS.toMillis(timestampNanos); - writer.write(Long.toString(timestampMillis / 1000)); - writer.write("."); - long millis = timestampMillis % 1000; - if (millis < 100) { - writer.write('0'); - } - if (millis < 10) { - writer.write('0'); - } - writer.write(Long.toString(millis)); - } - - @Override - void writeExemplar( - Writer writer, - Collection exemplars, - double minExemplar, - double maxExemplar) - throws IOException { - for (ExemplarData exemplar : exemplars) { - double value = getExemplarValue(exemplar); - if (value > minExemplar && value <= maxExemplar) { - writer.write(" # {"); - SpanContext spanContext = exemplar.getSpanContext(); - if (spanContext.isValid()) { - // NB: Output sorted to match prometheus client library even though it shouldn't matter. - // OTel generally outputs in trace_id span_id order though so we can consider breaking - // from reference implementation if it makes sense. - writer.write("span_id=\""); - writer.write(spanContext.getSpanId()); - writer.write("\",trace_id=\""); - writer.write(spanContext.getTraceId()); - writer.write('"'); - } - writer.write("} "); - writeDouble(writer, value); - writer.write(' '); - writeTimestamp(writer, exemplar.getEpochNanos()); - // Only write one exemplar. - return; - } - } - } - - @Override - void writeEof(Writer writer) throws IOException { - writer.write("# EOF\n"); - } - } - - static Collection getPoints(MetricData metricData) { - switch (metricData.getType()) { - case DOUBLE_GAUGE: - return metricData.getDoubleGaugeData().getPoints(); - case DOUBLE_SUM: - return metricData.getDoubleSumData().getPoints(); - case LONG_GAUGE: - return metricData.getLongGaugeData().getPoints(); - case LONG_SUM: - return metricData.getLongSumData().getPoints(); - case SUMMARY: - return metricData.getSummaryData().getPoints(); - case HISTOGRAM: - return metricData.getHistogramData().getPoints(); - case EXPONENTIAL_HISTOGRAM: - return metricData.getExponentialHistogramData().getPoints(); - } - return Collections.emptyList(); - } - - private static double getExemplarValue(ExemplarData exemplar) { - return exemplar instanceof DoubleExemplarData - ? ((DoubleExemplarData) exemplar).getValue() - : (double) ((LongExemplarData) exemplar).getValue(); - } -} diff --git a/exporters/prometheus/src/test/java/io/opentelemetry/exporter/prometheus/NameSanitizerTest.java b/exporters/prometheus/src/test/java/io/opentelemetry/exporter/prometheus/NameSanitizerTest.java deleted file mode 100644 index 56eb36f085b..00000000000 --- a/exporters/prometheus/src/test/java/io/opentelemetry/exporter/prometheus/NameSanitizerTest.java +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package io.opentelemetry.exporter.prometheus; - -import static org.assertj.core.api.Assertions.assertThat; - -import java.util.concurrent.atomic.AtomicInteger; -import java.util.function.Function; -import java.util.stream.Stream; -import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.Arguments; -import org.junit.jupiter.params.provider.MethodSource; - -class NameSanitizerTest { - - @Test - void testSanitizerCaching() { - AtomicInteger count = new AtomicInteger(); - Function delegate = labelName -> labelName + count.incrementAndGet(); - NameSanitizer sanitizer = new NameSanitizer(delegate); - String labelName = "http.name"; - - assertThat(sanitizer.apply(labelName)).isEqualTo("http.name1"); - assertThat(sanitizer.apply(labelName)).isEqualTo("http.name1"); - assertThat(sanitizer.apply(labelName)).isEqualTo("http.name1"); - assertThat(sanitizer.apply(labelName)).isEqualTo("http.name1"); - assertThat(sanitizer.apply(labelName)).isEqualTo("http.name1"); - assertThat(count).hasValue(1); - } - - @ParameterizedTest - @MethodSource("provideMetricNamesForTest") - void testSanitizerCleansing(String unsanitizedName, String sanitizedName) { - Assertions.assertEquals(sanitizedName, NameSanitizer.INSTANCE.apply(unsanitizedName)); - } - - private static Stream provideMetricNamesForTest() { - return Stream.of( - // valid name - already sanitized - Arguments.of( - "active_directory_ds_replication_network_io", - "active_directory_ds_replication_network_io"), - // consecutive underscores - Arguments.of("cpu_sp__d_hertz", "cpu_sp_d_hertz"), - // leading and trailing underscores - should be fine - Arguments.of("_cpu_speed_hertz_", "_cpu_speed_hertz_"), - // unsupported characters replaced - Arguments.of("metric_unit_$1000", "metric_unit_1000"), - // multiple unsupported characters - whitespace - Arguments.of("sample_me%%$$$_count_ !!@unit include", "sample_me_count_unit_include"), - // metric names cannot start with a number - Arguments.of("1_some_metric_name", "_some_metric_name"), - // metric names can have : - Arguments.of("sample_metric_name__:_per_meter", "sample_metric_name_:_per_meter"), - // Illegal characters - Arguments.of("cpu_sp$$d_hertz", "cpu_sp_d_hertz")); - } -} diff --git a/exporters/prometheus/src/test/java/io/opentelemetry/exporter/prometheus/PrometheusHttpServerTest.java b/exporters/prometheus/src/test/java/io/opentelemetry/exporter/prometheus/PrometheusHttpServerTest.java index 7f65cf1e0c2..9f172e83804 100644 --- a/exporters/prometheus/src/test/java/io/opentelemetry/exporter/prometheus/PrometheusHttpServerTest.java +++ b/exporters/prometheus/src/test/java/io/opentelemetry/exporter/prometheus/PrometheusHttpServerTest.java @@ -33,6 +33,7 @@ import io.opentelemetry.sdk.metrics.internal.data.ImmutableMetricData; import io.opentelemetry.sdk.metrics.internal.data.ImmutableSumData; import io.opentelemetry.sdk.resources.Resource; +import io.prometheus.metrics.exporter.httpserver.HTTPServer; import java.io.ByteArrayInputStream; import java.io.IOException; import java.net.ServerSocket; @@ -52,8 +53,6 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.RegisterExtension; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.ValueSource; class PrometheusHttpServerTest { private static final AtomicReference> metricData = new AtomicReference<>(); @@ -65,7 +64,7 @@ class PrometheusHttpServerTest { static WebClient client; @RegisterExtension - LogCapturer logs = LogCapturer.create().captureForType(PrometheusHttpServer.class); + LogCapturer logs = LogCapturer.create().captureForType(Otel2PrometheusConverter.class); @BeforeAll static void beforeAll() { @@ -108,35 +107,32 @@ void invalidConfig() { .hasMessage("host must not be empty"); } - @ParameterizedTest - @ValueSource(strings = {"/metrics", "/"}) - void fetchPrometheus(String endpoint) { - AggregatedHttpResponse response = client.get(endpoint).aggregate().join(); + @Test + void fetchPrometheus() { + AggregatedHttpResponse response = client.get("/metrics").aggregate().join(); assertThat(response.status()).isEqualTo(HttpStatus.OK); assertThat(response.headers().get(HttpHeaderNames.CONTENT_TYPE)) .isEqualTo("text/plain; version=0.0.4; charset=utf-8"); assertThat(response.contentUtf8()) .isEqualTo( - "# TYPE target info\n" - + "# HELP target Target metadata\n" - + "target_info{kr=\"vr\"} 1\n" + "# HELP grpc_name_total long_description\n" + "# TYPE grpc_name_total counter\n" - + "# HELP grpc_name_total long_description\n" - + "grpc_name_total{otel_scope_name=\"grpc\",otel_scope_version=\"version\",kp=\"vp\"} 5.0 0\n" - + "# TYPE http_name_total counter\n" + + "grpc_name_total{kp=\"vp\",otel_scope_name=\"grpc\",otel_scope_version=\"version\"} 5.0\n" + "# HELP http_name_total double_description\n" - + "http_name_total{otel_scope_name=\"http\",otel_scope_version=\"version\",kp=\"vp\"} 3.5 0\n"); + + "# TYPE http_name_total counter\n" + + "http_name_total{kp=\"vp\",otel_scope_name=\"http\",otel_scope_version=\"version\"} 3.5\n" + + "# TYPE target_info gauge\n" + + "target_info{kr=\"vr\"} 1\n"); } - @ParameterizedTest - @ValueSource(strings = {"/metrics", "/"}) - void fetchOpenMetrics(String endpoint) { + @Test + void fetchOpenMetrics() { AggregatedHttpResponse response = client .execute( RequestHeaders.of( HttpMethod.GET, - endpoint, + "/metrics", HttpHeaderNames.ACCEPT, "application/openmetrics-text")) .aggregate() @@ -146,33 +142,35 @@ void fetchOpenMetrics(String endpoint) { .isEqualTo("application/openmetrics-text; version=1.0.0; charset=utf-8"); assertThat(response.contentUtf8()) .isEqualTo( - "# TYPE target info\n" - + "# HELP target Target metadata\n" - + "target_info{kr=\"vr\"} 1\n" - + "# TYPE grpc_name counter\n" + "# TYPE grpc_name counter\n" + "# HELP grpc_name long_description\n" - + "grpc_name_total{otel_scope_name=\"grpc\",otel_scope_version=\"version\",kp=\"vp\"} 5.0 0.000\n" + + "grpc_name_total{kp=\"vp\",otel_scope_name=\"grpc\",otel_scope_version=\"version\"} 5.0\n" + "# TYPE http_name counter\n" + "# HELP http_name double_description\n" - + "http_name_total{otel_scope_name=\"http\",otel_scope_version=\"version\",kp=\"vp\"} 3.5 0.000\n" + + "http_name_total{kp=\"vp\",otel_scope_name=\"http\",otel_scope_version=\"version\"} 3.5\n" + + "# TYPE target info\n" + + "target_info{kr=\"vr\"} 1\n" + "# EOF\n"); } @Test void fetchFiltered() { AggregatedHttpResponse response = - client.get("/?name[]=grpc_name_total&name[]=bears_total").aggregate().join(); + client + .get("/?name[]=grpc_name_total&name[]=bears_total&name[]=target_info") + .aggregate() + .join(); assertThat(response.status()).isEqualTo(HttpStatus.OK); assertThat(response.headers().get(HttpHeaderNames.CONTENT_TYPE)) .isEqualTo("text/plain; version=0.0.4; charset=utf-8"); assertThat(response.contentUtf8()) .isEqualTo( - "# TYPE target info\n" - + "# HELP target Target metadata\n" - + "target_info{kr=\"vr\"} 1\n" - + "# TYPE grpc_name_total counter\n" + "" + "# HELP grpc_name_total long_description\n" - + "grpc_name_total{otel_scope_name=\"grpc\",otel_scope_version=\"version\",kp=\"vp\"} 5.0 0\n"); + + "# TYPE grpc_name_total counter\n" + + "grpc_name_total{kp=\"vp\",otel_scope_name=\"grpc\",otel_scope_version=\"version\"} 5.0\n" + + "# TYPE target_info gauge\n" + + "target_info{kr=\"vr\"} 1\n"); } @Test @@ -182,7 +180,7 @@ void fetchPrometheusCompressed() throws IOException { .decorator(RetryingClient.newDecorator(RetryRule.failsafe())) .addHeader(HttpHeaderNames.ACCEPT_ENCODING, "gzip") .build(); - AggregatedHttpResponse response = client.get("/").aggregate().join(); + AggregatedHttpResponse response = client.get("/metrics").aggregate().join(); assertThat(response.status()).isEqualTo(HttpStatus.OK); assertThat(response.headers().get(HttpHeaderNames.CONTENT_TYPE)) .isEqualTo("text/plain; version=0.0.4; charset=utf-8"); @@ -191,15 +189,14 @@ void fetchPrometheusCompressed() throws IOException { String content = new String(ByteStreams.toByteArray(gis), StandardCharsets.UTF_8); assertThat(content) .isEqualTo( - "# TYPE target info\n" - + "# HELP target Target metadata\n" - + "target_info{kr=\"vr\"} 1\n" + "# HELP grpc_name_total long_description\n" + "# TYPE grpc_name_total counter\n" - + "# HELP grpc_name_total long_description\n" - + "grpc_name_total{otel_scope_name=\"grpc\",otel_scope_version=\"version\",kp=\"vp\"} 5.0 0\n" - + "# TYPE http_name_total counter\n" + + "grpc_name_total{kp=\"vp\",otel_scope_name=\"grpc\",otel_scope_version=\"version\"} 5.0\n" + "# HELP http_name_total double_description\n" - + "http_name_total{otel_scope_name=\"http\",otel_scope_version=\"version\",kp=\"vp\"} 3.5 0\n"); + + "# TYPE http_name_total counter\n" + + "http_name_total{kp=\"vp\",otel_scope_name=\"http\",otel_scope_version=\"version\"} 3.5\n" + + "# TYPE target_info gauge\n" + + "target_info{kr=\"vr\"} 1\n"); } @Test @@ -216,7 +213,7 @@ void fetchHealth() { AggregatedHttpResponse response = client.get("/-/healthy").aggregate().join(); assertThat(response.status()).isEqualTo(HttpStatus.OK); - assertThat(response.contentUtf8()).isEqualTo("Exporter is Healthy."); + assertThat(response.contentUtf8()).isEqualTo("Exporter is healthy.\n"); } @Test @@ -260,28 +257,22 @@ void fetch_DuplicateMetrics() { Collections.singletonList( ImmutableLongPointData.create(123, 456, Attributes.empty(), 3)))))); - AggregatedHttpResponse response = client.get("/").aggregate().join(); + AggregatedHttpResponse response = client.get("/metrics").aggregate().join(); assertThat(response.status()).isEqualTo(HttpStatus.OK); assertThat(response.headers().get(HttpHeaderNames.CONTENT_TYPE)) .isEqualTo("text/plain; version=0.0.4; charset=utf-8"); assertThat(response.contentUtf8()) .isEqualTo( - "# TYPE target info\n" - + "# HELP target Target metadata\n" - + "target_info{kr=\"vr\"} 1\n" - + "# TYPE foo_unit_total counter\n" - + "# HELP foo_unit_total description1\n" - + "foo_unit_total{otel_scope_name=\"scope1\"} 1.0 0\n" - + "foo_unit_total{otel_scope_name=\"scope2\"} 2.0 0\n"); + "# TYPE foo_unit_total counter\n" + + "foo_unit_total{otel_scope_name=\"scope1\"} 1.0\n" + + "foo_unit_total{otel_scope_name=\"scope2\"} 2.0\n" + + "# TYPE target_info gauge\n" + + "target_info{kr=\"vr\"} 1\n"); // Validate conflict warning message assertThat(logs.getEvents()).hasSize(1); logs.assertContains( - "Metric conflict(s) detected. Multiple metrics with same name but different type: [foo_unit_total]"); - - // Make another request and confirm warning is only logged once - client.get("/").aggregate().join(); - assertThat(logs.getEvents()).hasSize(1); + "Conflicting metric name foo_unit: Found one metric with type counter and one of type gauge. Dropping the one with type gauge."); } @Test @@ -293,8 +284,9 @@ void stringRepresentation() { @Test void defaultExecutor() { assertThat(prometheusServer) - .extracting("executor", as(InstanceOfAssertFactories.type(ThreadPoolExecutor.class))) - .satisfies(executor -> assertThat(executor.getCorePoolSize()).isEqualTo(5)); + .extracting("httpServer", as(InstanceOfAssertFactories.type(HTTPServer.class))) + .extracting("executorService", as(InstanceOfAssertFactories.type(ThreadPoolExecutor.class))) + .satisfies(executor -> assertThat(executor.getCorePoolSize()).isEqualTo(1)); } @Test @@ -311,8 +303,10 @@ void customExecutor() throws IOException { .setExecutor(scheduledExecutor) .build()) { assertThat(server) + .extracting("httpServer", as(InstanceOfAssertFactories.type(HTTPServer.class))) .extracting( - "executor", as(InstanceOfAssertFactories.type(ScheduledThreadPoolExecutor.class))) + "executorService", + as(InstanceOfAssertFactories.type(ScheduledThreadPoolExecutor.class))) .satisfies(executor -> assertThat(executor).isSameAs(scheduledExecutor)); } } diff --git a/exporters/prometheus/src/test/java/io/opentelemetry/exporter/prometheus/PrometheusMetricNameMapperTest.java b/exporters/prometheus/src/test/java/io/opentelemetry/exporter/prometheus/PrometheusMetricNameMapperTest.java deleted file mode 100644 index 6a677c361ef..00000000000 --- a/exporters/prometheus/src/test/java/io/opentelemetry/exporter/prometheus/PrometheusMetricNameMapperTest.java +++ /dev/null @@ -1,163 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package io.opentelemetry.exporter.prometheus; - -import static io.opentelemetry.exporter.prometheus.TestConstants.DELTA_HISTOGRAM; -import static io.opentelemetry.exporter.prometheus.TestConstants.DOUBLE_GAUGE; -import static io.opentelemetry.exporter.prometheus.TestConstants.MONOTONIC_CUMULATIVE_LONG_SUM; -import static io.opentelemetry.exporter.prometheus.TestConstants.SUMMARY; -import static org.assertj.core.api.Assertions.assertThat; -import static org.junit.jupiter.api.Assertions.assertEquals; - -import io.opentelemetry.sdk.metrics.data.MetricData; -import io.opentelemetry.sdk.metrics.internal.data.ImmutableMetricData; -import java.util.concurrent.atomic.AtomicInteger; -import java.util.function.BiFunction; -import java.util.stream.Stream; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.Arguments; -import org.junit.jupiter.params.provider.MethodSource; - -class PrometheusMetricNameMapperTest { - - @Test - void prometheusMetricNameMapperCaching() { - AtomicInteger count = new AtomicInteger(); - BiFunction delegate = - (metricData, prometheusType) -> - String.join( - "_", - metricData.getName(), - prometheusType.name(), - Integer.toString(count.incrementAndGet())); - PrometheusMetricNameMapper mapper = new PrometheusMetricNameMapper(delegate); - - assertThat(mapper.apply(MONOTONIC_CUMULATIVE_LONG_SUM, PrometheusType.GAUGE)) - .isEqualTo("monotonic.cumulative.long.sum_GAUGE_1"); - assertThat(mapper.apply(MONOTONIC_CUMULATIVE_LONG_SUM, PrometheusType.GAUGE)) - .isEqualTo("monotonic.cumulative.long.sum_GAUGE_1"); - assertThat(mapper.apply(MONOTONIC_CUMULATIVE_LONG_SUM, PrometheusType.GAUGE)) - .isEqualTo("monotonic.cumulative.long.sum_GAUGE_1"); - assertThat(mapper.apply(MONOTONIC_CUMULATIVE_LONG_SUM, PrometheusType.GAUGE)) - .isEqualTo("monotonic.cumulative.long.sum_GAUGE_1"); - assertThat(mapper.apply(MONOTONIC_CUMULATIVE_LONG_SUM, PrometheusType.GAUGE)) - .isEqualTo("monotonic.cumulative.long.sum_GAUGE_1"); - assertThat(count).hasValue(1); - } - - @ParameterizedTest - @MethodSource("provideRawMetricDataForTest") - void metricNameSerializationTest(MetricData metricData, String expectedSerializedName) { - assertEquals( - expectedSerializedName, - PrometheusMetricNameMapper.INSTANCE.apply( - metricData, PrometheusType.forMetric(metricData))); - } - - private static Stream provideRawMetricDataForTest() { - return Stream.of( - // special case for gauge - Arguments.of(createSampleMetricData("sample", "1", PrometheusType.GAUGE), "sample_ratio"), - // special case for gauge with drop - metric unit should match "1" to be converted to - // "ratio" - Arguments.of( - createSampleMetricData("sample", "1{dropped}", PrometheusType.GAUGE), "sample"), - // Gauge without "1" as unit - Arguments.of(createSampleMetricData("sample", "unit", PrometheusType.GAUGE), "sample_unit"), - // special case with counter - Arguments.of( - createSampleMetricData("sample", "unit", PrometheusType.COUNTER), "sample_unit_total"), - // special case unit "1", but no gauge - "1" is dropped - Arguments.of(createSampleMetricData("sample", "1", PrometheusType.COUNTER), "sample_total"), - // units expressed as numbers other than 1 are retained - Arguments.of( - createSampleMetricData("sample", "2", PrometheusType.COUNTER), "sample_2_total"), - // metric name with unsupported characters - Arguments.of( - createSampleMetricData("s%%ple", "%/m", PrometheusType.SUMMARY), - "s_ple_percent_per_minute"), - // metric name with dropped portions - Arguments.of( - createSampleMetricData("s%%ple", "%/m", PrometheusType.SUMMARY), - "s_ple_percent_per_minute"), - // metric unit as a number other than 1 is not treated specially - Arguments.of( - createSampleMetricData("metric_name", "2", PrometheusType.SUMMARY), "metric_name_2"), - // metric unit is not appended if the name already contains the unit - Arguments.of( - createSampleMetricData("metric_name_total", "total", PrometheusType.COUNTER), - "metric_name_total"), - // metric unit is not appended if the name already contains the unit - special case for - // total with non-counter type - Arguments.of( - createSampleMetricData("metric_name_total", "total", PrometheusType.SUMMARY), - "metric_name_total"), - // metric unit not appended if present in metric name - special case for ratio - Arguments.of( - createSampleMetricData("metric_name_ratio", "1", PrometheusType.GAUGE), - "metric_name_ratio"), - // metric unit not appended if present in metric name - special case for ratio - unit not - // gauge - Arguments.of( - createSampleMetricData("metric_name_ratio", "1", PrometheusType.SUMMARY), - "metric_name_ratio"), - // metric unit is not appended if the name already contains the unit - unit can be anywhere - Arguments.of( - createSampleMetricData("metric_hertz", "hertz", PrometheusType.GAUGE), "metric_hertz"), - // metric unit is not appended if the name already contains the unit - applies to every unit - Arguments.of( - createSampleMetricData("metric_hertz_total", "hertz_total", PrometheusType.COUNTER), - "metric_hertz_total"), - // metric unit is not appended if the name already contains the unit - order matters - Arguments.of( - createSampleMetricData("metric_total_hertz", "hertz_total", PrometheusType.COUNTER), - "metric_total_hertz_hertz_total_total"), - // metric name cannot start with a number - Arguments.of( - createSampleMetricData("2_metric_name", "By", PrometheusType.SUMMARY), - "_metric_name_bytes")); - } - - static MetricData createSampleMetricData( - String metricName, String metricUnit, PrometheusType prometheusType) { - switch (prometheusType) { - case SUMMARY: - return ImmutableMetricData.createDoubleSummary( - SUMMARY.getResource(), - SUMMARY.getInstrumentationScopeInfo(), - metricName, - SUMMARY.getDescription(), - metricUnit, - SUMMARY.getSummaryData()); - case COUNTER: - return ImmutableMetricData.createLongSum( - MONOTONIC_CUMULATIVE_LONG_SUM.getResource(), - MONOTONIC_CUMULATIVE_LONG_SUM.getInstrumentationScopeInfo(), - metricName, - MONOTONIC_CUMULATIVE_LONG_SUM.getDescription(), - metricUnit, - MONOTONIC_CUMULATIVE_LONG_SUM.getLongSumData()); - case GAUGE: - return ImmutableMetricData.createDoubleGauge( - DOUBLE_GAUGE.getResource(), - DOUBLE_GAUGE.getInstrumentationScopeInfo(), - metricName, - DOUBLE_GAUGE.getDescription(), - metricUnit, - DOUBLE_GAUGE.getDoubleGaugeData()); - case HISTOGRAM: - return ImmutableMetricData.createDoubleHistogram( - DELTA_HISTOGRAM.getResource(), - DELTA_HISTOGRAM.getInstrumentationScopeInfo(), - metricName, - DELTA_HISTOGRAM.getDescription(), - metricUnit, - DELTA_HISTOGRAM.getHistogramData()); - } - throw new IllegalArgumentException(); - } -} diff --git a/exporters/prometheus/src/test/java/io/opentelemetry/exporter/prometheus/PrometheusMetricReaderTest.java b/exporters/prometheus/src/test/java/io/opentelemetry/exporter/prometheus/PrometheusMetricReaderTest.java new file mode 100644 index 00000000000..95a22379ef9 --- /dev/null +++ b/exporters/prometheus/src/test/java/io/opentelemetry/exporter/prometheus/PrometheusMetricReaderTest.java @@ -0,0 +1,1075 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.exporter.prometheus; + +import static java.util.stream.Collectors.joining; +import static org.assertj.core.api.Assertions.assertThat; + +import io.opentelemetry.api.common.Attributes; +import io.opentelemetry.api.metrics.DoubleCounter; +import io.opentelemetry.api.metrics.DoubleHistogram; +import io.opentelemetry.api.metrics.DoubleUpDownCounter; +import io.opentelemetry.api.metrics.LongCounter; +import io.opentelemetry.api.metrics.LongHistogram; +import io.opentelemetry.api.metrics.LongUpDownCounter; +import io.opentelemetry.api.metrics.Meter; +import io.opentelemetry.api.trace.Span; +import io.opentelemetry.api.trace.Tracer; +import io.opentelemetry.context.Scope; +import io.opentelemetry.sdk.metrics.Aggregation; +import io.opentelemetry.sdk.metrics.InstrumentSelector; +import io.opentelemetry.sdk.metrics.SdkMeterProvider; +import io.opentelemetry.sdk.metrics.View; +import io.opentelemetry.sdk.resources.Resource; +import io.opentelemetry.sdk.testing.time.TestClock; +import io.opentelemetry.sdk.trace.SdkTracerProvider; +import io.prometheus.metrics.expositionformats.OpenMetricsTextFormatWriter; +import io.prometheus.metrics.expositionformats.PrometheusProtobufWriter; +import io.prometheus.metrics.model.snapshots.HistogramSnapshot; +import io.prometheus.metrics.model.snapshots.HistogramSnapshot.HistogramDataPointSnapshot; +import io.prometheus.metrics.model.snapshots.MetricSnapshots; +import io.prometheus.metrics.model.snapshots.NativeHistogramBuckets; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.nio.charset.StandardCharsets; +import java.time.Duration; +import java.time.Instant; +import java.util.Arrays; +import java.util.Random; +import java.util.concurrent.TimeUnit; +import java.util.regex.Pattern; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.Test; + +class PrometheusMetricReaderTest { + + private final TestClock testClock = TestClock.create(); + private String createdTimestamp; + private PrometheusMetricReader reader; + private Meter meter; + private Tracer tracer; + + @BeforeEach + void setUp() { + this.testClock.setTime(Instant.ofEpochMilli((System.currentTimeMillis() / 100) * 100)); + this.createdTimestamp = convertTimestamp(testClock.now()); + this.reader = new PrometheusMetricReader(true); + this.meter = + SdkMeterProvider.builder() + .setClock(testClock) + .registerMetricReader(this.reader) + .setResource( + Resource.getDefault().toBuilder().put("telemetry.sdk.version", "1.x.x").build()) + .registerView( + InstrumentSelector.builder().setName("my.exponential.histogram").build(), + View.builder() + .setAggregation(Aggregation.base2ExponentialBucketHistogram()) + .build()) + .build() + .meterBuilder("test") + .build(); + this.tracer = + SdkTracerProvider.builder().setClock(testClock).build().tracerBuilder("test").build(); + } + + @Test + void longCounterComplete() throws IOException { + LongCounter counter = + meter + .counterBuilder("requests.size") + .setDescription("some help text") + .setUnit("By") + .build(); + Span span1 = tracer.spanBuilder("test").startSpan(); + try (Scope scope = span1.makeCurrent()) { + counter.add(3, Attributes.builder().put("animal", "bear").build()); + } finally { + span1.end(); + } + Span span2 = tracer.spanBuilder("test").startSpan(); + try (Scope scope = span2.makeCurrent()) { + counter.add(2, Attributes.builder().put("animal", "mouse").build()); + } finally { + span2.end(); + } + assertCounterComplete(reader.collect(), span1, span2); + } + + @Test + void doubleCounterComplete() throws IOException { + DoubleCounter counter = + meter + .counterBuilder("requests.size") + .setDescription("some help text") + .setUnit("By") + .ofDoubles() + .build(); + Span span1 = tracer.spanBuilder("test").startSpan(); + try (Scope scope = span1.makeCurrent()) { + counter.add(3.0, Attributes.builder().put("animal", "bear").build()); + } finally { + span1.end(); + } + Span span2 = tracer.spanBuilder("test").startSpan(); + try (Scope scope = span2.makeCurrent()) { + counter.add(2.0, Attributes.builder().put("animal", "mouse").build()); + } finally { + span2.end(); + } + assertCounterComplete(reader.collect(), span1, span2); + } + + private void assertCounterComplete(MetricSnapshots snapshots, Span span1, Span span2) + throws IOException { + String expected = + "" + + "# TYPE requests_size_bytes counter\n" + + "# UNIT requests_size_bytes bytes\n" + + "# HELP requests_size_bytes some help text\n" + + "requests_size_bytes_total{animal=\"bear\",otel_scope_name=\"test\"} 3.0 # {span_id=\"" + + span1.getSpanContext().getSpanId() + + "\",trace_id=\"" + + span1.getSpanContext().getTraceId() + + "\"} 3.0 \n" + + "requests_size_bytes_created{animal=\"bear\",otel_scope_name=\"test\"} " + + createdTimestamp + + "\n" + + "requests_size_bytes_total{animal=\"mouse\",otel_scope_name=\"test\"} 2.0 # {span_id=\"" + + span2.getSpanContext().getSpanId() + + "\",trace_id=\"" + + span2.getSpanContext().getTraceId() + + "\"} 2.0 \n" + + "requests_size_bytes_created{animal=\"mouse\",otel_scope_name=\"test\"} " + + createdTimestamp + + "\n" + + "# TYPE target info\n" + + "target_info{service_name=\"unknown_service:java\",telemetry_sdk_language=\"java\",telemetry_sdk_name=\"opentelemetry\",telemetry_sdk_version=\"1.x.x\"} 1\n" + + "# EOF\n"; + assertMatches(expected, toOpenMetrics(snapshots)); + } + + @Test + void longCounterMinimal() throws IOException { + LongCounter counter = meter.counterBuilder("requests").build(); + counter.add(2); + assertCounterMinimal(reader.collect()); + } + + @Test + void doubleCounterMinimal() throws IOException { + DoubleCounter counter = meter.counterBuilder("requests").ofDoubles().build(); + counter.add(2.0); + assertCounterMinimal(reader.collect()); + } + + private void assertCounterMinimal(MetricSnapshots snapshots) throws IOException { + String expected = + "" + + "# TYPE requests counter\n" + + "requests_total{otel_scope_name=\"test\"} 2.0\n" + + "requests_created{otel_scope_name=\"test\"} " + + createdTimestamp + + "\n" + + "# TYPE target info\n" + + "target_info{service_name=\"unknown_service:java\",telemetry_sdk_language=\"java\",telemetry_sdk_name=\"opentelemetry\",telemetry_sdk_version=\"1.x.x\"} 1\n" + + "# EOF\n"; + assertThat(toOpenMetrics(snapshots)).isEqualTo(expected); + } + + @Test + void longUpDownCounterComplete() throws IOException { + LongUpDownCounter counter = + meter + .upDownCounterBuilder("queue.size") + .setDescription("some help text") + .setUnit("By") + .build(); + Span span1 = tracer.spanBuilder("test").startSpan(); + try (Scope scope = span1.makeCurrent()) { + counter.add(3, Attributes.builder().put("animal", "bear").build()); + } finally { + span1.end(); + } + Span span2 = tracer.spanBuilder("test").startSpan(); + try (Scope scope = span2.makeCurrent()) { + counter.add(2, Attributes.builder().put("animal", "mouse").build()); + } finally { + span2.end(); + } + assertUpDownCounterComplete(reader.collect(), span1, span2); + } + + @Test + void doubleUpDownCounterComplete() throws IOException { + DoubleUpDownCounter counter = + meter + .upDownCounterBuilder("queue.size") + .setDescription("some help text") + .setUnit("By") + .ofDoubles() + .build(); + Span span1 = tracer.spanBuilder("test").startSpan(); + try (Scope scope = span1.makeCurrent()) { + counter.add(3.0, Attributes.builder().put("animal", "bear").build()); + } finally { + span1.end(); + } + Span span2 = tracer.spanBuilder("test").startSpan(); + try (Scope scope = span2.makeCurrent()) { + counter.add(2.0, Attributes.builder().put("animal", "mouse").build()); + } finally { + span2.end(); + } + assertUpDownCounterComplete(reader.collect(), span1, span2); + } + + private static void assertUpDownCounterComplete(MetricSnapshots snapshots, Span span1, Span span2) + throws IOException { + String expected = + "" + + "# TYPE queue_size_bytes gauge\n" + + "# UNIT queue_size_bytes bytes\n" + + "# HELP queue_size_bytes some help text\n" + + "queue_size_bytes{animal=\"bear\",otel_scope_name=\"test\"} 3.0 # {span_id=\"" + + span1.getSpanContext().getSpanId() + + "\",trace_id=\"" + + span1.getSpanContext().getTraceId() + + "\"} 3.0 \n" + + "queue_size_bytes{animal=\"mouse\",otel_scope_name=\"test\"} 2.0 # {span_id=\"" + + span2.getSpanContext().getSpanId() + + "\",trace_id=\"" + + span2.getSpanContext().getTraceId() + + "\"} 2.0 \n" + + "# TYPE target info\n" + + "target_info{service_name=\"unknown_service:java\",telemetry_sdk_language=\"java\",telemetry_sdk_name=\"opentelemetry\",telemetry_sdk_version=\"1.x.x\"} 1\n" + + "# EOF\n"; + assertMatches(expected, toOpenMetrics(snapshots)); + } + + @Test + void longUpDownCounterMinimal() throws IOException { + LongUpDownCounter counter = meter.upDownCounterBuilder("users.active").build(); + counter.add(27); + assertUpDownCounterMinimal(reader.collect()); + } + + @Test + void doubleUpDownCounterMinimal() throws IOException { + DoubleUpDownCounter counter = meter.upDownCounterBuilder("users.active").ofDoubles().build(); + counter.add(27.0); + assertUpDownCounterMinimal(reader.collect()); + } + + private static void assertUpDownCounterMinimal(MetricSnapshots snapshots) throws IOException { + String expected = + "" + + "# TYPE target info\n" + + "target_info{service_name=\"unknown_service:java\",telemetry_sdk_language=\"java\",telemetry_sdk_name=\"opentelemetry\",telemetry_sdk_version=\"1.x.x\"} 1\n" + + "# TYPE users_active gauge\n" + + "users_active{otel_scope_name=\"test\"} 27.0\n" + + "# EOF\n"; + assertThat(toOpenMetrics(snapshots)).isEqualTo(expected); + } + + @Test + void longGaugeComplete() throws IOException { + meter + .gaugeBuilder("temperature") + .setUnit("Cel") + .setDescription("help text") + .ofLongs() + .buildWithCallback( + m -> { + m.record(23, Attributes.builder().put("location", "inside").build()); + m.record(17, Attributes.builder().put("location", "outside").build()); + }); + assertGaugeComplete(reader.collect()); + } + + @Test + void doubleGaugeComplete() throws IOException { + meter + .gaugeBuilder("temperature") + .setUnit("Cel") + .setDescription("help text") + .buildWithCallback( + m -> { + m.record(23.0, Attributes.builder().put("location", "inside").build()); + m.record(17.0, Attributes.builder().put("location", "outside").build()); + }); + assertGaugeComplete(reader.collect()); + } + + private static void assertGaugeComplete(MetricSnapshots snapshots) throws IOException { + String expected = + "" + + "# TYPE target info\n" + + "target_info{service_name=\"unknown_service:java\",telemetry_sdk_language=\"java\",telemetry_sdk_name=\"opentelemetry\",telemetry_sdk_version=\"1.x.x\"} 1\n" + + "# TYPE temperature_celsius gauge\n" + + "# UNIT temperature_celsius celsius\n" + + "# HELP temperature_celsius help text\n" + + "temperature_celsius{location=\"inside\",otel_scope_name=\"test\"} 23.0\n" + + "temperature_celsius{location=\"outside\",otel_scope_name=\"test\"} 17.0\n" + + "# EOF\n"; + assertThat(toOpenMetrics(snapshots)).isEqualTo(expected); + } + + @Test + void longGaugeMinimal() throws IOException { + meter.gaugeBuilder("my_gauge").ofLongs().buildWithCallback(m -> m.record(2)); + assertGaugeMinimal(reader.collect()); + } + + @Test + void doubleGaugeMinimal() throws IOException { + meter.gaugeBuilder("my_gauge").buildWithCallback(m -> m.record(2.0)); + assertGaugeMinimal(reader.collect()); + } + + private static void assertGaugeMinimal(MetricSnapshots snapshots) throws IOException { + String expected = + "" + + "# TYPE my_gauge gauge\n" + + "my_gauge{otel_scope_name=\"test\"} 2.0\n" + + "# TYPE target info\n" + + "target_info{service_name=\"unknown_service:java\",telemetry_sdk_language=\"java\",telemetry_sdk_name=\"opentelemetry\",telemetry_sdk_version=\"1.x.x\"} 1\n" + + "# EOF\n"; + assertThat(toOpenMetrics(snapshots)).isEqualTo(expected); + } + + @Test + void longHistogramComplete() throws IOException { + LongHistogram histogram = + meter + .histogramBuilder("request.size") + .setDescription("some help text") + .setUnit("By") + .ofLongs() + .build(); + Span span1 = tracer.spanBuilder("test").startSpan(); + try (Scope scope = span1.makeCurrent()) { + histogram.record(173, Attributes.builder().put("animal", "bear").build()); + } finally { + span1.end(); + } + Span span2 = tracer.spanBuilder("test").startSpan(); + try (Scope scope = span2.makeCurrent()) { + histogram.record(400, Attributes.builder().put("animal", "bear").build()); + } finally { + span1.end(); + } + Span span3 = tracer.spanBuilder("test").startSpan(); + try (Scope scope = span3.makeCurrent()) { + histogram.record(204, Attributes.builder().put("animal", "mouse").build()); + } finally { + span3.end(); + } + assertHistogramComplete(reader.collect(), span1, span2, span3); + } + + @Test + void doubleHistogramComplete() throws IOException { + DoubleHistogram histogram = + meter + .histogramBuilder("request.size") + .setDescription("some help text") + .setUnit("By") + .build(); + Span span1 = tracer.spanBuilder("test").startSpan(); + try (Scope scope = span1.makeCurrent()) { + histogram.record(173.0, Attributes.builder().put("animal", "bear").build()); + } finally { + span1.end(); + } + Span span2 = tracer.spanBuilder("test").startSpan(); + try (Scope scope = span2.makeCurrent()) { + histogram.record(400.0, Attributes.builder().put("animal", "bear").build()); + } finally { + span1.end(); + } + Span span3 = tracer.spanBuilder("test").startSpan(); + try (Scope scope = span3.makeCurrent()) { + histogram.record(204.0, Attributes.builder().put("animal", "mouse").build()); + } finally { + span3.end(); + } + assertHistogramComplete(reader.collect(), span1, span2, span3); + } + + private void assertHistogramComplete( + MetricSnapshots snapshots, Span span1, Span span2, Span span3) throws IOException { + String expected = + "" + + "# TYPE request_size_bytes histogram\n" + + "# UNIT request_size_bytes bytes\n" + + "# HELP request_size_bytes some help text\n" + + "request_size_bytes_bucket{animal=\"bear\",otel_scope_name=\"test\",le=\"0.0\"} 0\n" + + "request_size_bytes_bucket{animal=\"bear\",otel_scope_name=\"test\",le=\"5.0\"} 0\n" + + "request_size_bytes_bucket{animal=\"bear\",otel_scope_name=\"test\",le=\"10.0\"} 0\n" + + "request_size_bytes_bucket{animal=\"bear\",otel_scope_name=\"test\",le=\"25.0\"} 0\n" + + "request_size_bytes_bucket{animal=\"bear\",otel_scope_name=\"test\",le=\"50.0\"} 0\n" + + "request_size_bytes_bucket{animal=\"bear\",otel_scope_name=\"test\",le=\"75.0\"} 0\n" + + "request_size_bytes_bucket{animal=\"bear\",otel_scope_name=\"test\",le=\"100.0\"} 0\n" + + "request_size_bytes_bucket{animal=\"bear\",otel_scope_name=\"test\",le=\"250.0\"} 1 # {span_id=\"" + + span1.getSpanContext().getSpanId() + + "\",trace_id=\"" + + span1.getSpanContext().getTraceId() + + "\"} 173.0 \n" + + "request_size_bytes_bucket{animal=\"bear\",otel_scope_name=\"test\",le=\"500.0\"} 2 # {span_id=\"" + + span2.getSpanContext().getSpanId() + + "\",trace_id=\"" + + span2.getSpanContext().getTraceId() + + "\"} 400.0 \n" + + "request_size_bytes_bucket{animal=\"bear\",otel_scope_name=\"test\",le=\"750.0\"} 2\n" + + "request_size_bytes_bucket{animal=\"bear\",otel_scope_name=\"test\",le=\"1000.0\"} 2\n" + + "request_size_bytes_bucket{animal=\"bear\",otel_scope_name=\"test\",le=\"2500.0\"} 2\n" + + "request_size_bytes_bucket{animal=\"bear\",otel_scope_name=\"test\",le=\"5000.0\"} 2\n" + + "request_size_bytes_bucket{animal=\"bear\",otel_scope_name=\"test\",le=\"7500.0\"} 2\n" + + "request_size_bytes_bucket{animal=\"bear\",otel_scope_name=\"test\",le=\"10000.0\"} 2\n" + + "request_size_bytes_bucket{animal=\"bear\",otel_scope_name=\"test\",le=\"+Inf\"} 2\n" + + "request_size_bytes_count{animal=\"bear\",otel_scope_name=\"test\"} 2\n" + + "request_size_bytes_sum{animal=\"bear\",otel_scope_name=\"test\"} 573.0\n" + + "request_size_bytes_created{animal=\"bear\",otel_scope_name=\"test\"} " + + createdTimestamp + + "\n" + + "request_size_bytes_bucket{animal=\"mouse\",otel_scope_name=\"test\",le=\"0.0\"} 0\n" + + "request_size_bytes_bucket{animal=\"mouse\",otel_scope_name=\"test\",le=\"5.0\"} 0\n" + + "request_size_bytes_bucket{animal=\"mouse\",otel_scope_name=\"test\",le=\"10.0\"} 0\n" + + "request_size_bytes_bucket{animal=\"mouse\",otel_scope_name=\"test\",le=\"25.0\"} 0\n" + + "request_size_bytes_bucket{animal=\"mouse\",otel_scope_name=\"test\",le=\"50.0\"} 0\n" + + "request_size_bytes_bucket{animal=\"mouse\",otel_scope_name=\"test\",le=\"75.0\"} 0\n" + + "request_size_bytes_bucket{animal=\"mouse\",otel_scope_name=\"test\",le=\"100.0\"} 0\n" + + "request_size_bytes_bucket{animal=\"mouse\",otel_scope_name=\"test\",le=\"250.0\"} 1 # {span_id=\"" + + span3.getSpanContext().getSpanId() + + "\",trace_id=\"" + + span3.getSpanContext().getTraceId() + + "\"} 204.0 \n" + + "request_size_bytes_bucket{animal=\"mouse\",otel_scope_name=\"test\",le=\"500.0\"} 1\n" + + "request_size_bytes_bucket{animal=\"mouse\",otel_scope_name=\"test\",le=\"750.0\"} 1\n" + + "request_size_bytes_bucket{animal=\"mouse\",otel_scope_name=\"test\",le=\"1000.0\"} 1\n" + + "request_size_bytes_bucket{animal=\"mouse\",otel_scope_name=\"test\",le=\"2500.0\"} 1\n" + + "request_size_bytes_bucket{animal=\"mouse\",otel_scope_name=\"test\",le=\"5000.0\"} 1\n" + + "request_size_bytes_bucket{animal=\"mouse\",otel_scope_name=\"test\",le=\"7500.0\"} 1\n" + + "request_size_bytes_bucket{animal=\"mouse\",otel_scope_name=\"test\",le=\"10000.0\"} 1\n" + + "request_size_bytes_bucket{animal=\"mouse\",otel_scope_name=\"test\",le=\"+Inf\"} 1\n" + + "request_size_bytes_count{animal=\"mouse\",otel_scope_name=\"test\"} 1\n" + + "request_size_bytes_sum{animal=\"mouse\",otel_scope_name=\"test\"} 204.0\n" + + "request_size_bytes_created{animal=\"mouse\",otel_scope_name=\"test\"} " + + createdTimestamp + + "\n" + + "# TYPE target info\n" + + "target_info{service_name=\"unknown_service:java\",telemetry_sdk_language=\"java\",telemetry_sdk_name=\"opentelemetry\",telemetry_sdk_version=\"1.x.x\"} 1\n" + + "# EOF\n"; + assertMatches(expected, toOpenMetrics(snapshots)); + } + + @Test + void longHistogramMinimal() throws IOException { + LongHistogram histogram = meter.histogramBuilder("request.size").ofLongs().build(); + histogram.record(173); + histogram.record(173); + histogram.record(100_000); + assertHistogramMinimal(reader.collect()); + } + + @Test + void doubleHistogramMinimal() throws IOException { + DoubleHistogram histogram = meter.histogramBuilder("request.size").build(); + histogram.record(173.0); + histogram.record(173.0); + histogram.record(100_000.0); + assertHistogramMinimal(reader.collect()); + } + + private void assertHistogramMinimal(MetricSnapshots snapshots) throws IOException { + String expected = + "" + + "# TYPE request_size histogram\n" + + "request_size_bucket{otel_scope_name=\"test\",le=\"0.0\"} 0\n" + + "request_size_bucket{otel_scope_name=\"test\",le=\"5.0\"} 0\n" + + "request_size_bucket{otel_scope_name=\"test\",le=\"10.0\"} 0\n" + + "request_size_bucket{otel_scope_name=\"test\",le=\"25.0\"} 0\n" + + "request_size_bucket{otel_scope_name=\"test\",le=\"50.0\"} 0\n" + + "request_size_bucket{otel_scope_name=\"test\",le=\"75.0\"} 0\n" + + "request_size_bucket{otel_scope_name=\"test\",le=\"100.0\"} 0\n" + + "request_size_bucket{otel_scope_name=\"test\",le=\"250.0\"} 2\n" + + "request_size_bucket{otel_scope_name=\"test\",le=\"500.0\"} 2\n" + + "request_size_bucket{otel_scope_name=\"test\",le=\"750.0\"} 2\n" + + "request_size_bucket{otel_scope_name=\"test\",le=\"1000.0\"} 2\n" + + "request_size_bucket{otel_scope_name=\"test\",le=\"2500.0\"} 2\n" + + "request_size_bucket{otel_scope_name=\"test\",le=\"5000.0\"} 2\n" + + "request_size_bucket{otel_scope_name=\"test\",le=\"7500.0\"} 2\n" + + "request_size_bucket{otel_scope_name=\"test\",le=\"10000.0\"} 2\n" + + "request_size_bucket{otel_scope_name=\"test\",le=\"+Inf\"} 3\n" + + "request_size_count{otel_scope_name=\"test\"} 3\n" + + "request_size_sum{otel_scope_name=\"test\"} 100346.0\n" + + "request_size_created{otel_scope_name=\"test\"} " + + createdTimestamp + + "\n" + + "# TYPE target info\n" + + "target_info{service_name=\"unknown_service:java\",telemetry_sdk_language=\"java\",telemetry_sdk_name=\"opentelemetry\",telemetry_sdk_version=\"1.x.x\"} 1\n" + + "# EOF\n"; + assertThat(toOpenMetrics(snapshots)).isEqualTo(expected); + } + + @Test + @Disabled("disabled until #6010 is fixed") + void exponentialLongHistogramComplete() throws IOException { + LongHistogram histogram = + meter + .histogramBuilder("my.exponential.histogram") + .setDescription("some help text") + .setUnit("By") + .ofLongs() + .build(); + Span span1 = tracer.spanBuilder("test").startSpan(); + try (Scope scope = span1.makeCurrent()) { + histogram.record(7, Attributes.builder().put("animal", "bear").build()); + } finally { + span1.end(); + } + histogram.record(0, Attributes.builder().put("animal", "bear").build()); + Span span2 = tracer.spanBuilder("test").startSpan(); + try (Scope scope = span2.makeCurrent()) { + histogram.record(3, Attributes.builder().put("animal", "mouse").build()); + } finally { + span2.end(); + } + assertExponentialHistogramComplete(reader.collect(), span1, span2); + } + + @Test + void exponentialDoubleHistogramComplete() throws IOException { + DoubleHistogram histogram = + meter + .histogramBuilder("my.exponential.histogram") + .setDescription("some help text") + .setUnit("By") + .build(); + Span span1 = tracer.spanBuilder("test").startSpan(); + try (Scope scope = span1.makeCurrent()) { + histogram.record(7.0, Attributes.builder().put("animal", "bear").build()); + } finally { + span1.end(); + } + histogram.record(0.0, Attributes.builder().put("animal", "bear").build()); + Span span2 = tracer.spanBuilder("test").startSpan(); + try (Scope scope = span2.makeCurrent()) { + histogram.record(3.0, Attributes.builder().put("animal", "mouse").build()); + } finally { + span2.end(); + } + assertExponentialHistogramComplete(reader.collect(), span1, span2); + } + + private static void assertExponentialHistogramComplete( + MetricSnapshots snapshots, Span span1, Span span2) { + String expected = + "" + + "name: \"my_exponential_histogram_bytes\"\n" + + "help: \"some help text\"\n" + + "type: HISTOGRAM\n" + + "metric {\n" + + " label {\n" + + " name: \"animal\"\n" + + " value: \"bear\"\n" + + " }\n" + + " label {\n" + + " name: \"otel_scope_name\"\n" + + " value: \"test\"\n" + + " }\n" + + " histogram {\n" + + " sample_count: 2\n" + + " sample_sum: 7.0\n" + + " bucket {\n" + + " cumulative_count: 2\n" + + " upper_bound: Infinity\n" + + " exemplar {\n" + + " label {\n" + + " name: \"span_id\"\n" + + " value: \"" + + span1.getSpanContext().getSpanId() + + "\"\n" + + " }\n" + + " label {\n" + + " name: \"trace_id\"\n" + + " value: \"" + + span1.getSpanContext().getTraceId() + + "\"\n" + + " }\n" + + " value: 7.0\n" + + " timestamp {\n" + + " seconds: \n" + + " nanos: \n" + + " }\n" + + " }\n" + + " }\n" + + " schema: 8\n" + + " zero_threshold: 0.0\n" + + " zero_count: 1\n" + + " positive_span {\n" + + " offset: 719\n" + + " length: 1\n" + + " }\n" + + " positive_delta: 1\n" + + " }\n" + + "}\n" + + "metric {\n" + + " label {\n" + + " name: \"animal\"\n" + + " value: \"mouse\"\n" + + " }\n" + + " label {\n" + + " name: \"otel_scope_name\"\n" + + " value: \"test\"\n" + + " }\n" + + " histogram {\n" + + " sample_count: 1\n" + + " sample_sum: 3.0\n" + + " bucket {\n" + + " cumulative_count: 1\n" + + " upper_bound: Infinity\n" + + " exemplar {\n" + + " label {\n" + + " name: \"span_id\"\n" + + " value: \"" + + span2.getSpanContext().getSpanId() + + "\"\n" + + " }\n" + + " label {\n" + + " name: \"trace_id\"\n" + + " value: \"" + + span2.getSpanContext().getTraceId() + + "\"\n" + + " }\n" + + " value: 3.0\n" + + " timestamp {\n" + + " seconds: \n" + + " nanos: \n" + + " }\n" + + " }\n" + + " }\n" + + " schema: 8\n" + + " zero_threshold: 0.0\n" + + " zero_count: 0\n" + + " positive_span {\n" + + " offset: 406\n" + + " length: 1\n" + + " }\n" + + " positive_delta: 1\n" + + " }\n" + + "}\n" + + "name: \"target_info\"\n" + + "type: GAUGE\n" + + "metric {\n" + + " label {\n" + + " name: \"service_name\"\n" + + " value: \"unknown_service:java\"\n" + + " }\n" + + " label {\n" + + " name: \"telemetry_sdk_language\"\n" + + " value: \"java\"\n" + + " }\n" + + " label {\n" + + " name: \"telemetry_sdk_name\"\n" + + " value: \"opentelemetry\"\n" + + " }\n" + + " label {\n" + + " name: \"telemetry_sdk_version\"\n" + + " value: \"1.x.x\"\n" + + " }\n" + + " gauge {\n" + + " value: 1.0\n" + + " }\n" + + "}\n"; + assertMatches(expected, toPrometheusProtobuf(snapshots)); + } + + @Test + void exponentialLongHistogramMinimal() throws IOException { + LongHistogram histogram = meter.histogramBuilder("my.exponential.histogram").ofLongs().build(); + histogram.record(1, Attributes.builder().put("animal", "bear").build()); + assertExponentialHistogramMinimal(reader.collect()); + } + + @Test + void exponentialDoubleHistogramMinimal() throws IOException { + DoubleHistogram histogram = meter.histogramBuilder("my.exponential.histogram").build(); + histogram.record(1.0, Attributes.builder().put("animal", "bear").build()); + assertExponentialHistogramMinimal(reader.collect()); + } + + private static void assertExponentialHistogramMinimal(MetricSnapshots snapshots) { + String expected = + "" + + "name: \"my_exponential_histogram\"\n" + + "help: \"\"\n" + + "type: HISTOGRAM\n" + + "metric {\n" + + " label {\n" + + " name: \"animal\"\n" + + " value: \"bear\"\n" + + " }\n" + + " label {\n" + + " name: \"otel_scope_name\"\n" + + " value: \"test\"\n" + + " }\n" + + " histogram {\n" + + " sample_count: 1\n" + + " sample_sum: 1.0\n" + + " schema: 8\n" + + " zero_threshold: 0.0\n" + + " zero_count: 0\n" + + " positive_span {\n" + + " offset: 0\n" + + " length: 1\n" + + " }\n" + + " positive_delta: 1\n" + + " }\n" + + "}\n" + + "name: \"target_info\"\n" + + "type: GAUGE\n" + + "metric {\n" + + " label {\n" + + " name: \"service_name\"\n" + + " value: \"unknown_service:java\"\n" + + " }\n" + + " label {\n" + + " name: \"telemetry_sdk_language\"\n" + + " value: \"java\"\n" + + " }\n" + + " label {\n" + + " name: \"telemetry_sdk_name\"\n" + + " value: \"opentelemetry\"\n" + + " }\n" + + " label {\n" + + " name: \"telemetry_sdk_version\"\n" + + " value: \"1.x.x\"\n" + + " }\n" + + " gauge {\n" + + " value: 1.0\n" + + " }\n" + + "}\n"; + assertMatches(expected, toPrometheusProtobuf(snapshots)); + } + + @Test + void exponentialHistogramBucketConversion() { + Random random = new Random(); + for (int i = 0; i < 100_000; i++) { + int otelScale = random.nextInt(24) - 4; + int prometheusScale = Math.min(otelScale, 8); + PrometheusMetricReader reader = new PrometheusMetricReader(true); + Meter meter = + SdkMeterProvider.builder() + .registerMetricReader(reader) + .registerView( + InstrumentSelector.builder().setName("my.exponential.histogram").build(), + View.builder() + .setAggregation(Aggregation.base2ExponentialBucketHistogram(160, otelScale)) + .build()) + .build() + .meterBuilder("test") + .build(); + int orderOfMagnitude = random.nextInt(18) - 9; + double observation = random.nextDouble() * Math.pow(10, orderOfMagnitude); + if (observation == 0) { + continue; + } + DoubleHistogram histogram = meter.histogramBuilder("my.exponential.histogram").build(); + histogram.record(observation); + MetricSnapshots snapshots = reader.collect(); + HistogramSnapshot snapshot = (HistogramSnapshot) snapshots.get(0); + HistogramDataPointSnapshot dataPoint = snapshot.getDataPoints().get(0); + assertThat(dataPoint.getNativeSchema()).isEqualTo(prometheusScale); + NativeHistogramBuckets buckets = dataPoint.getNativeBucketsForPositiveValues(); + assertThat(buckets.size()).isEqualTo(1); + int index = buckets.getBucketIndex(0); + double base = Math.pow(2, Math.pow(2, -prometheusScale)); + double lowerBound = Math.pow(base, index - 1); + double upperBound = Math.pow(base, index); + assertThat(lowerBound).isLessThan(observation); + assertThat(upperBound).isGreaterThanOrEqualTo(observation); + } + } + + @Test + void exponentialLongHistogramScaleDown() throws IOException { + // The following histogram will have the default scale, which is 20. + DoubleHistogram histogram = meter.histogramBuilder("my.exponential.histogram").build(); + double base = Math.pow(2, Math.pow(2, -20)); + int i; + for (i = 0; i < Math.pow(2, 12); i++) { + histogram.record(Math.pow(base, i)); // one observation per bucket + } + for (int j = 0; j < 10; j++) { + histogram.record(Math.pow(base, i + 2 * j)); // few empty buckets between the observations + } + MetricSnapshots snapshots = reader.collect(); + HistogramSnapshot snapshot = (HistogramSnapshot) snapshots.get(0); + HistogramDataPointSnapshot dataPoint = snapshot.getDataPoints().get(0); + assertThat(dataPoint.getNativeSchema()).isEqualTo(8); // scaled down from 20 to 8. + NativeHistogramBuckets buckets = dataPoint.getNativeBucketsForPositiveValues(); + assertThat(buckets.size()).isEqualTo(3); + // In bucket 0 we have exactly one observation: the value 1.0 + assertThat(buckets.getBucketIndex(0)).isEqualTo(0); + assertThat(buckets.getCount(0)).isEqualTo(1); + // In bucket 1 we have 4095 observations + assertThat(buckets.getBucketIndex(1)).isEqualTo(1); + assertThat(buckets.getCount(1)).isEqualTo(4095); + // In bucket 2 we have 10 observations (despite the empty buckets all observations fall into the + // same bucket at scale 8) + assertThat(buckets.getBucketIndex(2)).isEqualTo(2); + assertThat(buckets.getCount(2)).isEqualTo(10); + } + + @Test + void instrumentationScope() throws IOException { + SdkMeterProvider meterProvider = + SdkMeterProvider.builder() + .setClock(testClock) + .registerMetricReader(this.reader) + .setResource( + Resource.getDefault().toBuilder().put("telemetry.sdk.version", "1.x.x").build()) + .build(); + Meter meter1 = meterProvider.meterBuilder("scopeA").setInstrumentationVersion("1.1").build(); + Meter meter2 = meterProvider.meterBuilder("scopeB").setInstrumentationVersion("1.2").build(); + meter1 + .counterBuilder("processing.time") + .setDescription("processing time in seconds") + .setUnit("s") + .ofDoubles() + .build() + .add(3.3, Attributes.builder().put("a", "b").build()); + meter2 + .counterBuilder("processing.time") + .setDescription("processing time in seconds") + .setUnit("s") + .ofDoubles() + .build() + .add(3.3, Attributes.builder().put("a", "b").build()); + String expected = + "" + + "# TYPE processing_time_seconds counter\n" + + "# UNIT processing_time_seconds seconds\n" + + "# HELP processing_time_seconds processing time in seconds\n" + + "processing_time_seconds_total{a=\"b\",otel_scope_name=\"scopeA\",otel_scope_version=\"1.1\"} 3.3\n" + + "processing_time_seconds_created{a=\"b\",otel_scope_name=\"scopeA\",otel_scope_version=\"1.1\"} " + + createdTimestamp + + "\n" + + "processing_time_seconds_total{a=\"b\",otel_scope_name=\"scopeB\",otel_scope_version=\"1.2\"} 3.3\n" + + "processing_time_seconds_created{a=\"b\",otel_scope_name=\"scopeB\",otel_scope_version=\"1.2\"} " + + createdTimestamp + + "\n" + + "# TYPE target info\n" + + "target_info{service_name=\"unknown_service:java\",telemetry_sdk_language=\"java\",telemetry_sdk_name=\"opentelemetry\",telemetry_sdk_version=\"1.x.x\"} 1\n" + + "# EOF\n"; + assertThat(toOpenMetrics(reader.collect())).isEqualTo(expected); + } + + @Test + void nameSuffix() throws IOException { + LongCounter unitAndTotal = + meter.counterBuilder("request.duration.seconds.total").setUnit("s").build(); + unitAndTotal.add(1); + LongCounter unitOnly = meter.counterBuilder("response.duration.seconds").setUnit("s").build(); + unitOnly.add(2); + LongCounter totalOnly = meter.counterBuilder("processing.duration.total").setUnit("s").build(); + totalOnly.add(3); + LongCounter noSuffix = meter.counterBuilder("queue.time").setUnit("s").build(); + noSuffix.add(4); + String expected = + "" + + "# TYPE processing_duration_seconds counter\n" + + "# UNIT processing_duration_seconds seconds\n" + + "processing_duration_seconds_total{otel_scope_name=\"test\"} 3.0\n" + + "processing_duration_seconds_created{otel_scope_name=\"test\"} " + + createdTimestamp + + "\n" + + "# TYPE queue_time_seconds counter\n" + + "# UNIT queue_time_seconds seconds\n" + + "queue_time_seconds_total{otel_scope_name=\"test\"} 4.0\n" + + "queue_time_seconds_created{otel_scope_name=\"test\"} " + + createdTimestamp + + "\n" + + "# TYPE request_duration_seconds counter\n" + + "# UNIT request_duration_seconds seconds\n" + + "request_duration_seconds_total{otel_scope_name=\"test\"} 1.0\n" + + "request_duration_seconds_created{otel_scope_name=\"test\"} " + + createdTimestamp + + "\n" + + "# TYPE response_duration_seconds counter\n" + + "# UNIT response_duration_seconds seconds\n" + + "response_duration_seconds_total{otel_scope_name=\"test\"} 2.0\n" + + "response_duration_seconds_created{otel_scope_name=\"test\"} " + + createdTimestamp + + "\n" + + "# TYPE target info\n" + + "target_info{service_name=\"unknown_service:java\",telemetry_sdk_language=\"java\",telemetry_sdk_name=\"opentelemetry\",telemetry_sdk_version=\"1.x.x\"} 1\n" + + "# EOF\n"; + assertThat(toOpenMetrics(reader.collect())).isEqualTo(expected); + } + + @Test + void nameSuffixUnit() throws IOException { + LongCounter counter = meter.counterBuilder("request.duration.seconds").setUnit("s").build(); + counter.add(1); + String expected = + "" + + "# TYPE request_duration_seconds counter\n" + + "# UNIT request_duration_seconds seconds\n" + + "request_duration_seconds_total{otel_scope_name=\"test\"} 1.0\n" + + "request_duration_seconds_created{otel_scope_name=\"test\"} " + + createdTimestamp + + "\n" + + "# TYPE target info\n" + + "target_info{service_name=\"unknown_service:java\",telemetry_sdk_language=\"java\",telemetry_sdk_name=\"opentelemetry\",telemetry_sdk_version=\"1.x.x\"} 1\n" + + "# EOF\n"; + assertThat(toOpenMetrics(reader.collect())).isEqualTo(expected); + } + + @Test + void illegalCharacters() throws IOException { + LongCounter counter = meter.counterBuilder("prod/request.count").build(); + counter.add(1, Attributes.builder().put("user-count", 30).build()); + String expected = + "" + + "# TYPE prod_request_count counter\n" + + "prod_request_count_total{otel_scope_name=\"test\",user_count=\"30\"} 1.0\n" + + "prod_request_count_created{otel_scope_name=\"test\",user_count=\"30\"} " + + createdTimestamp + + "\n" + + "# TYPE target info\n" + + "target_info{service_name=\"unknown_service:java\",telemetry_sdk_language=\"java\",telemetry_sdk_name=\"opentelemetry\",telemetry_sdk_version=\"1.x.x\"} 1\n" + + "# EOF\n"; + assertThat(toOpenMetrics(reader.collect())).isEqualTo(expected); + } + + @Test + void createdTimestamp() throws IOException { + + LongCounter counter = meter.counterBuilder("requests").build(); + testClock.advance(Duration.ofMillis(1)); + counter.add(3, Attributes.builder().put("animal", "bear").build()); + testClock.advance(Duration.ofMillis(1)); + counter.add(2, Attributes.builder().put("animal", "mouse").build()); + testClock.advance(Duration.ofMillis(1)); + + // There is a curious difference between Prometheus and OpenTelemetry: + // In Prometheus metrics the _created timestamp is per data point, + // i.e. the _created timestamp says when this specific set of label values + // was first observed. + // In the OTel Java SDK the _created timestamp is the initialization time + // of the SdkMeterProvider, i.e. all data points will have the same _created timestamp. + // So we expect the _created timestamp to be the start time of the application, + // not the timestamp when the counter or an individual data point was created. + String expected = + "" + + "# TYPE requests counter\n" + + "requests_total{animal=\"bear\",otel_scope_name=\"test\"} 3.0\n" + + "requests_created{animal=\"bear\",otel_scope_name=\"test\"} " + + createdTimestamp + + "\n" + + "requests_total{animal=\"mouse\",otel_scope_name=\"test\"} 2.0\n" + + "requests_created{animal=\"mouse\",otel_scope_name=\"test\"} " + + createdTimestamp + + "\n" + + "# TYPE target info\n" + + "target_info{service_name=\"unknown_service:java\",telemetry_sdk_language=\"java\",telemetry_sdk_name=\"opentelemetry\",telemetry_sdk_version=\"1.x.x\"} 1\n" + + "# EOF\n"; + assertThat(toOpenMetrics(reader.collect())).isEqualTo(expected); + } + + @Test + void otelScopeComplete() throws IOException { + // There is currently no API for adding scope attributes. + // However, we can at least test the otel_scope_version attribute. + Meter meter = + SdkMeterProvider.builder() + .setClock(testClock) + .registerMetricReader(this.reader) + .setResource( + Resource.getDefault().toBuilder().put("telemetry.sdk.version", "1.x.x").build()) + .build() + .meterBuilder("test-scope") + .setInstrumentationVersion("a.b.c") + .build(); + LongCounter counter = meter.counterBuilder("test.count").build(); + counter.add(1); + String expected = + "" + + "# TYPE target info\n" + + "target_info{service_name=\"unknown_service:java\",telemetry_sdk_language=\"java\",telemetry_sdk_name=\"opentelemetry\",telemetry_sdk_version=\"1.x.x\"} 1\n" + + "# TYPE test_count counter\n" + + "test_count_total{otel_scope_name=\"test-scope\",otel_scope_version=\"a.b.c\"} 1.0\n" + + "test_count_created{otel_scope_name=\"test-scope\",otel_scope_version=\"a.b.c\"} " + + createdTimestamp + + "\n" + + "# EOF\n"; + assertThat(toOpenMetrics(reader.collect())).isEqualTo(expected); + } + + @Test + void otelScopeDisabled() throws IOException { + PrometheusMetricReader reader = new PrometheusMetricReader(false); + Meter meter = + SdkMeterProvider.builder() + .setClock(testClock) + .registerMetricReader(reader) + .setResource( + Resource.getDefault().toBuilder().put("telemetry.sdk.version", "1.x.x").build()) + .build() + .meterBuilder("test-scope") + .setInstrumentationVersion("a.b.c") + .build(); + LongCounter counter = meter.counterBuilder("test.count").build(); + counter.add(1); + String expected = + "" + + "# TYPE target info\n" + + "target_info{service_name=\"unknown_service:java\",telemetry_sdk_language=\"java\",telemetry_sdk_name=\"opentelemetry\",telemetry_sdk_version=\"1.x.x\"} 1\n" + + "# TYPE test_count counter\n" + + "test_count_total 1.0\n" + + "test_count_created " + + createdTimestamp + + "\n" + + "# EOF\n"; + assertThat(toOpenMetrics(reader.collect())).isEqualTo(expected); + } + + /** + * Unfortunately there is no easy way to use {@link TestClock} for Exemplar timestamps. Test if + * {@code expected} equals {@code actual} but {@code } matches arbitrary timestamps. + */ + private static void assertMatches(String expected, String actual) { + String[] parts = expected.split(Pattern.quote("")); + String timestampRegex = "[0-9]+(\\.[0-9]+)?"; + + String regex = Arrays.stream(parts).map(Pattern::quote).collect(joining(timestampRegex)); + + assertThat(actual) + .as("Expected: " + expected + "\nActual: " + actual) + .matches(Pattern.compile(regex)); + } + + private static String toOpenMetrics(MetricSnapshots snapshots) throws IOException { + ByteArrayOutputStream out = new ByteArrayOutputStream(); + OpenMetricsTextFormatWriter writer = new OpenMetricsTextFormatWriter(true, true); + writer.write(out, snapshots); + return out.toString(StandardCharsets.UTF_8.name()); + } + + private static String toPrometheusProtobuf(MetricSnapshots snapshots) { + PrometheusProtobufWriter writer = new PrometheusProtobufWriter(); + return writer.toDebugString(snapshots); + } + + private static String convertTimestamp(long nanoTime) { + String millis = Long.toString(TimeUnit.NANOSECONDS.toMillis(nanoTime)); + return millis.substring(0, millis.length() - 3) + "." + millis.substring(millis.length() - 3); + } +} diff --git a/exporters/prometheus/src/test/java/io/opentelemetry/exporter/prometheus/PrometheusUnitsHelperTest.java b/exporters/prometheus/src/test/java/io/opentelemetry/exporter/prometheus/PrometheusUnitsHelperTest.java index 2a8d01f0ce3..aa44005978d 100644 --- a/exporters/prometheus/src/test/java/io/opentelemetry/exporter/prometheus/PrometheusUnitsHelperTest.java +++ b/exporters/prometheus/src/test/java/io/opentelemetry/exporter/prometheus/PrometheusUnitsHelperTest.java @@ -6,7 +6,9 @@ package io.opentelemetry.exporter.prometheus; import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNull; +import io.prometheus.metrics.model.snapshots.Unit; import java.util.stream.Stream; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; @@ -16,8 +18,13 @@ class PrometheusUnitsHelperTest { @ParameterizedTest @MethodSource("providePrometheusOTelUnitEquivalentPairs") - public void testPrometheusUnitEquivalency(String otlpUnit, String prometheusUnit) { - assertEquals(prometheusUnit, PrometheusUnitsHelper.getEquivalentPrometheusUnit(otlpUnit)); + public void testPrometheusUnitEquivalency(String otlpUnit, String expectedPrometheusUnit) { + Unit actualPrometheusUnit = PrometheusUnitsHelper.convertUnit(otlpUnit); + if (expectedPrometheusUnit == null) { + assertNull(actualPrometheusUnit); + } else { + assertEquals(expectedPrometheusUnit, actualPrometheusUnit.toString()); + } } private static Stream providePrometheusOTelUnitEquivalentPairs() { @@ -63,46 +70,34 @@ private static Stream providePrometheusOTelUnitEquivalentPairs() { // Unit not found - Case sensitive Arguments.of("S", "S"), // Special case - 1 - Arguments.of("1", ""), + Arguments.of("1", null), // Special Case - Drop metric units in {} - Arguments.of("{packets}", ""), + Arguments.of("{packets}", null), // Special Case - Dropped metric units only in {} Arguments.of("{packets}V", "volts"), // Special Case - Dropped metric units with 'per' unit handling applicable - Arguments.of("{scanned}/{returned}", ""), + Arguments.of("{scanned}/{returned}", null), // Special Case - Dropped metric units with 'per' unit handling applicable Arguments.of("{objects}/s", "per_second"), // Units expressing rate - 'per' units, both units expanded Arguments.of("m/s", "meters_per_second"), // Units expressing rate - per minute - Arguments.of("m/m", "meters_per_minute"), + Arguments.of("m/min", "meters_per_minute"), // Units expressing rate - per day Arguments.of("A/d", "amperes_per_day"), // Units expressing rate - per week - Arguments.of("W/w", "watts_per_week"), + Arguments.of("W/wk", "watts_per_week"), // Units expressing rate - per month Arguments.of("J/mo", "joules_per_month"), // Units expressing rate - per year - Arguments.of("TBy/y", "terabytes_per_year"), + Arguments.of("TBy/a", "terabytes_per_year"), // Units expressing rate - 'per' units, both units unknown Arguments.of("v/v", "v_per_v"), // Units expressing rate - 'per' units, first unit unknown Arguments.of("km/h", "km_per_hour"), // Units expressing rate - 'per' units, 'per' unit unknown - Arguments.of("g/g", "grams_per_g"), + Arguments.of("g/x", "grams_per_x"), // Misc - unit containing known abbreviations improperly formatted - Arguments.of("watts_W", "watts_W"), - // Unsupported symbols - Arguments.of("°F", "F"), - // Unsupported symbols - multiple - Arguments.of("unit+=.:,!* & #unused", "unit_unused"), - // Unsupported symbols - 'per' units - Arguments.of("__test $/°C", "test_per_C"), - // Unsupported symbols - whitespace - Arguments.of("\t", ""), - // Null unit - Arguments.of(null, null), - // Misc - unit cleanup - no case match special char - Arguments.of("$1000", "1000")); + Arguments.of("watts_W", "watts_W")); } } diff --git a/exporters/prometheus/src/test/java/io/opentelemetry/exporter/prometheus/SerializerTest.java b/exporters/prometheus/src/test/java/io/opentelemetry/exporter/prometheus/SerializerTest.java deleted file mode 100644 index b76c390eab7..00000000000 --- a/exporters/prometheus/src/test/java/io/opentelemetry/exporter/prometheus/SerializerTest.java +++ /dev/null @@ -1,335 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package io.opentelemetry.exporter.prometheus; - -import static io.opentelemetry.exporter.prometheus.TestConstants.CUMULATIVE_HISTOGRAM_NO_ATTRIBUTES; -import static io.opentelemetry.exporter.prometheus.TestConstants.CUMULATIVE_HISTOGRAM_SINGLE_ATTRIBUTE; -import static io.opentelemetry.exporter.prometheus.TestConstants.DELTA_DOUBLE_SUM; -import static io.opentelemetry.exporter.prometheus.TestConstants.DELTA_HISTOGRAM; -import static io.opentelemetry.exporter.prometheus.TestConstants.DELTA_LONG_SUM; -import static io.opentelemetry.exporter.prometheus.TestConstants.DOUBLE_GAUGE; -import static io.opentelemetry.exporter.prometheus.TestConstants.DOUBLE_GAUGE_COLLIDING_ATTRIBUTES; -import static io.opentelemetry.exporter.prometheus.TestConstants.DOUBLE_GAUGE_MULTIPLE_ATTRIBUTES; -import static io.opentelemetry.exporter.prometheus.TestConstants.DOUBLE_GAUGE_NO_ATTRIBUTES; -import static io.opentelemetry.exporter.prometheus.TestConstants.LONG_GAUGE; -import static io.opentelemetry.exporter.prometheus.TestConstants.MONOTONIC_CUMULATIVE_DOUBLE_SUM; -import static io.opentelemetry.exporter.prometheus.TestConstants.MONOTONIC_CUMULATIVE_DOUBLE_SUM_WITH_SUFFIX_TOTAL; -import static io.opentelemetry.exporter.prometheus.TestConstants.MONOTONIC_CUMULATIVE_LONG_SUM; -import static io.opentelemetry.exporter.prometheus.TestConstants.NON_MONOTONIC_CUMULATIVE_DOUBLE_SUM; -import static io.opentelemetry.exporter.prometheus.TestConstants.NON_MONOTONIC_CUMULATIVE_LONG_SUM; -import static io.opentelemetry.exporter.prometheus.TestConstants.SUMMARY; -import static org.assertj.core.api.Assertions.assertThat; - -import io.github.netmikey.logunit.api.LogCapturer; -import io.opentelemetry.api.common.AttributeKey; -import io.opentelemetry.api.common.Attributes; -import io.opentelemetry.api.common.AttributesBuilder; -import io.opentelemetry.internal.testing.slf4j.SuppressLogger; -import io.opentelemetry.sdk.common.InstrumentationScopeInfo; -import io.opentelemetry.sdk.metrics.data.AggregationTemporality; -import io.opentelemetry.sdk.metrics.data.MetricData; -import io.opentelemetry.sdk.metrics.internal.data.ImmutableDoublePointData; -import io.opentelemetry.sdk.metrics.internal.data.ImmutableMetricData; -import io.opentelemetry.sdk.metrics.internal.data.ImmutableSumData; -import io.opentelemetry.sdk.resources.Resource; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.UncheckedIOException; -import java.util.Arrays; -import java.util.Collections; -import java.util.LinkedHashMap; -import java.util.Map; -import java.util.function.BiConsumer; -import org.jetbrains.annotations.Nullable; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.RegisterExtension; - -class SerializerTest { - - @RegisterExtension - private final LogCapturer logCapturer = - LogCapturer.create().captureForLogger(Serializer.class.getName()); - - @Test - void prometheus004() { - // Same output as prometheus client library except for these changes which are compatible with - // Prometheus - // TYPE / HELP line order reversed - // Attributes do not end in trailing comma - assertThat( - serialize004( - MONOTONIC_CUMULATIVE_DOUBLE_SUM, - MONOTONIC_CUMULATIVE_DOUBLE_SUM_WITH_SUFFIX_TOTAL, - NON_MONOTONIC_CUMULATIVE_DOUBLE_SUM, - DELTA_DOUBLE_SUM, // Deltas are dropped - MONOTONIC_CUMULATIVE_LONG_SUM, - NON_MONOTONIC_CUMULATIVE_LONG_SUM, - DELTA_LONG_SUM, // Deltas are dropped - DOUBLE_GAUGE, - LONG_GAUGE, - SUMMARY, - DELTA_HISTOGRAM, // Deltas are dropped - CUMULATIVE_HISTOGRAM_NO_ATTRIBUTES, - CUMULATIVE_HISTOGRAM_SINGLE_ATTRIBUTE, - DOUBLE_GAUGE_NO_ATTRIBUTES, - DOUBLE_GAUGE_MULTIPLE_ATTRIBUTES, - DOUBLE_GAUGE_COLLIDING_ATTRIBUTES)) - .isEqualTo( - "# TYPE target info\n" - + "# HELP target Target metadata\n" - + "target_info{kr=\"vr\"} 1\n" - + "# TYPE otel_scope_info info\n" - + "# HELP otel_scope_info Scope metadata\n" - + "otel_scope_info{otel_scope_name=\"full\",otel_scope_version=\"version\",ks=\"vs\"} 1\n" - + "# TYPE monotonic_cumulative_double_sum_seconds_total counter\n" - + "# HELP monotonic_cumulative_double_sum_seconds_total description\n" - + "monotonic_cumulative_double_sum_seconds_total{otel_scope_name=\"full\",otel_scope_version=\"version\",type=\"mcds\"} 5.0 1633950672000\n" - + "# TYPE monotonic_cumulative_double_sum_suffix_seconds_total counter\n" - + "# HELP monotonic_cumulative_double_sum_suffix_seconds_total description\n" - + "monotonic_cumulative_double_sum_suffix_seconds_total{otel_scope_name=\"full\",otel_scope_version=\"version\",type=\"mcds\"} 5.0 1633950672000\n" - + "# TYPE non_monotonic_cumulative_double_sum_seconds gauge\n" - + "# HELP non_monotonic_cumulative_double_sum_seconds description\n" - + "non_monotonic_cumulative_double_sum_seconds{otel_scope_name=\"full\",otel_scope_version=\"version\",type=\"nmcds\"} 5.0 1633950672000\n" - + "# TYPE monotonic_cumulative_long_sum_seconds_total counter\n" - + "# HELP monotonic_cumulative_long_sum_seconds_total unused\n" - + "monotonic_cumulative_long_sum_seconds_total{otel_scope_name=\"full\",otel_scope_version=\"version\",type=\"mcls\"} 5.0 1633950672000\n" - + "# TYPE non_monotonic_cumulative_long_sum_seconds gauge\n" - + "# HELP non_monotonic_cumulative_long_sum_seconds unused\n" - + "non_monotonic_cumulative_long_sum_seconds{otel_scope_name=\"full\",otel_scope_version=\"version\",type=\"nmcls\"} 5.0 1633950672000\n" - + "# TYPE double_gauge_seconds gauge\n" - + "# HELP double_gauge_seconds unused\n" - + "double_gauge_seconds{otel_scope_name=\"full\",otel_scope_version=\"version\",type=\"dg\"} 5.0 1633950672000\n" - + "# TYPE long_gauge_seconds gauge\n" - + "# HELP long_gauge_seconds unused\n" - + "long_gauge_seconds{otel_scope_name=\"full\",otel_scope_version=\"version\",type=\"lg\"} 5.0 1633950672000\n" - + "# TYPE summary_seconds summary\n" - + "# HELP summary_seconds unused\n" - + "summary_seconds_count{otel_scope_name=\"full\",otel_scope_version=\"version\",type=\"s\"} 5.0 1633950672000\n" - + "summary_seconds_sum{otel_scope_name=\"full\",otel_scope_version=\"version\",type=\"s\"} 7.0 1633950672000\n" - + "summary_seconds{otel_scope_name=\"full\",otel_scope_version=\"version\",type=\"s\",quantile=\"0.9\"} 0.1 1633950672000\n" - + "summary_seconds{otel_scope_name=\"full\",otel_scope_version=\"version\",type=\"s\",quantile=\"0.99\"} 0.3 1633950672000\n" - + "# TYPE cumulative_histogram_no_attributes_seconds histogram\n" - + "# HELP cumulative_histogram_no_attributes_seconds unused\n" - + "cumulative_histogram_no_attributes_seconds_count{otel_scope_name=\"full\",otel_scope_version=\"version\"} 2.0 1633950672000\n" - + "cumulative_histogram_no_attributes_seconds_sum{otel_scope_name=\"full\",otel_scope_version=\"version\"} 1.0 1633950672000\n" - + "cumulative_histogram_no_attributes_seconds_bucket{otel_scope_name=\"full\",otel_scope_version=\"version\",le=\"+Inf\"} 2.0 1633950672000\n" - + "# TYPE cumulative_histogram_single_attribute_seconds histogram\n" - + "# HELP cumulative_histogram_single_attribute_seconds unused\n" - + "cumulative_histogram_single_attribute_seconds_count{otel_scope_name=\"full\",otel_scope_version=\"version\",type=\"hs\"} 2.0 1633950672000\n" - + "cumulative_histogram_single_attribute_seconds_sum{otel_scope_name=\"full\",otel_scope_version=\"version\",type=\"hs\"} 1.0 1633950672000\n" - + "cumulative_histogram_single_attribute_seconds_bucket{otel_scope_name=\"full\",otel_scope_version=\"version\",type=\"hs\",le=\"+Inf\"} 2.0 1633950672000\n" - + "# TYPE double_gauge_no_attributes_seconds gauge\n" - + "# HELP double_gauge_no_attributes_seconds unused\n" - + "double_gauge_no_attributes_seconds{otel_scope_name=\"full\",otel_scope_version=\"version\"} 7.0 1633950672000\n" - + "# TYPE double_gauge_multiple_attributes_seconds gauge\n" - + "# HELP double_gauge_multiple_attributes_seconds unused\n" - + "double_gauge_multiple_attributes_seconds{otel_scope_name=\"full\",otel_scope_version=\"version\",animal=\"bear\",type=\"dgma\"} 8.0 1633950672000\n" - + "# TYPE double_gauge_colliding_attributes_seconds gauge\n" - + "# HELP double_gauge_colliding_attributes_seconds unused\n" - + "double_gauge_colliding_attributes_seconds{otel_scope_name=\"full\",otel_scope_version=\"version\",foo_bar=\"a;b\",type=\"dgma\"} 8.0 1633950672000\n"); - assertThat(logCapturer.size()).isZero(); - } - - @Test - void openMetrics() { - assertThat( - serializeOpenMetrics( - MONOTONIC_CUMULATIVE_DOUBLE_SUM, - MONOTONIC_CUMULATIVE_DOUBLE_SUM_WITH_SUFFIX_TOTAL, - NON_MONOTONIC_CUMULATIVE_DOUBLE_SUM, - DELTA_DOUBLE_SUM, // Deltas are dropped - MONOTONIC_CUMULATIVE_LONG_SUM, - NON_MONOTONIC_CUMULATIVE_LONG_SUM, - DELTA_LONG_SUM, // Deltas are dropped - DOUBLE_GAUGE, - LONG_GAUGE, - SUMMARY, - DELTA_HISTOGRAM, // Deltas are dropped - CUMULATIVE_HISTOGRAM_NO_ATTRIBUTES, - CUMULATIVE_HISTOGRAM_SINGLE_ATTRIBUTE, - DOUBLE_GAUGE_NO_ATTRIBUTES, - DOUBLE_GAUGE_MULTIPLE_ATTRIBUTES, - DOUBLE_GAUGE_COLLIDING_ATTRIBUTES)) - .isEqualTo( - "# TYPE target info\n" - + "# HELP target Target metadata\n" - + "target_info{kr=\"vr\"} 1\n" - + "# TYPE otel_scope_info info\n" - + "# HELP otel_scope_info Scope metadata\n" - + "otel_scope_info{otel_scope_name=\"full\",otel_scope_version=\"version\",ks=\"vs\"} 1\n" - + "# TYPE monotonic_cumulative_double_sum_seconds counter\n" - + "# HELP monotonic_cumulative_double_sum_seconds description\n" - + "monotonic_cumulative_double_sum_seconds_total{otel_scope_name=\"full\",otel_scope_version=\"version\",type=\"mcds\"} 5.0 1633950672.000\n" - + "# TYPE monotonic_cumulative_double_sum_suffix_seconds_total counter\n" - + "# HELP monotonic_cumulative_double_sum_suffix_seconds_total description\n" - + "monotonic_cumulative_double_sum_suffix_seconds_total{otel_scope_name=\"full\",otel_scope_version=\"version\",type=\"mcds\"} 5.0 1633950672.000\n" - + "# TYPE non_monotonic_cumulative_double_sum_seconds gauge\n" - + "# HELP non_monotonic_cumulative_double_sum_seconds description\n" - + "non_monotonic_cumulative_double_sum_seconds{otel_scope_name=\"full\",otel_scope_version=\"version\",type=\"nmcds\"} 5.0 1633950672.000\n" - + "# TYPE monotonic_cumulative_long_sum_seconds counter\n" - + "# HELP monotonic_cumulative_long_sum_seconds unused\n" - + "monotonic_cumulative_long_sum_seconds_total{otel_scope_name=\"full\",otel_scope_version=\"version\",type=\"mcls\"} 5.0 1633950672.000\n" - + "# TYPE non_monotonic_cumulative_long_sum_seconds gauge\n" - + "# HELP non_monotonic_cumulative_long_sum_seconds unused\n" - + "non_monotonic_cumulative_long_sum_seconds{otel_scope_name=\"full\",otel_scope_version=\"version\",type=\"nmcls\"} 5.0 1633950672.000\n" - + "# TYPE double_gauge_seconds gauge\n" - + "# HELP double_gauge_seconds unused\n" - + "double_gauge_seconds{otel_scope_name=\"full\",otel_scope_version=\"version\",type=\"dg\"} 5.0 1633950672.000\n" - + "# TYPE long_gauge_seconds gauge\n" - + "# HELP long_gauge_seconds unused\n" - + "long_gauge_seconds{otel_scope_name=\"full\",otel_scope_version=\"version\",type=\"lg\"} 5.0 1633950672.000\n" - + "# TYPE summary_seconds summary\n" - + "# HELP summary_seconds unused\n" - + "summary_seconds_count{otel_scope_name=\"full\",otel_scope_version=\"version\",type=\"s\"} 5.0 1633950672.000\n" - + "summary_seconds_sum{otel_scope_name=\"full\",otel_scope_version=\"version\",type=\"s\"} 7.0 1633950672.000\n" - + "summary_seconds{otel_scope_name=\"full\",otel_scope_version=\"version\",type=\"s\",quantile=\"0.9\"} 0.1 1633950672.000\n" - + "summary_seconds{otel_scope_name=\"full\",otel_scope_version=\"version\",type=\"s\",quantile=\"0.99\"} 0.3 1633950672.000\n" - + "# TYPE cumulative_histogram_no_attributes_seconds histogram\n" - + "# HELP cumulative_histogram_no_attributes_seconds unused\n" - + "cumulative_histogram_no_attributes_seconds_count{otel_scope_name=\"full\",otel_scope_version=\"version\"} 2.0 1633950672.000\n" - + "cumulative_histogram_no_attributes_seconds_sum{otel_scope_name=\"full\",otel_scope_version=\"version\"} 1.0 1633950672.000\n" - + "cumulative_histogram_no_attributes_seconds_bucket{otel_scope_name=\"full\",otel_scope_version=\"version\",le=\"+Inf\"} 2.0 1633950672.000 # {span_id=\"0000000000000002\",trace_id=\"00000000000000000000000000000001\"} 4.0 0.001\n" - + "# TYPE cumulative_histogram_single_attribute_seconds histogram\n" - + "# HELP cumulative_histogram_single_attribute_seconds unused\n" - + "cumulative_histogram_single_attribute_seconds_count{otel_scope_name=\"full\",otel_scope_version=\"version\",type=\"hs\"} 2.0 1633950672.000\n" - + "cumulative_histogram_single_attribute_seconds_sum{otel_scope_name=\"full\",otel_scope_version=\"version\",type=\"hs\"} 1.0 1633950672.000\n" - + "cumulative_histogram_single_attribute_seconds_bucket{otel_scope_name=\"full\",otel_scope_version=\"version\",type=\"hs\",le=\"+Inf\"} 2.0 1633950672.000 # {span_id=\"0000000000000002\",trace_id=\"00000000000000000000000000000001\"} 4.0 0.001\n" - + "# TYPE double_gauge_no_attributes_seconds gauge\n" - + "# HELP double_gauge_no_attributes_seconds unused\n" - + "double_gauge_no_attributes_seconds{otel_scope_name=\"full\",otel_scope_version=\"version\"} 7.0 1633950672.000\n" - + "# TYPE double_gauge_multiple_attributes_seconds gauge\n" - + "# HELP double_gauge_multiple_attributes_seconds unused\n" - + "double_gauge_multiple_attributes_seconds{otel_scope_name=\"full\",otel_scope_version=\"version\",animal=\"bear\",type=\"dgma\"} 8.0 1633950672.000\n" - + "# TYPE double_gauge_colliding_attributes_seconds gauge\n" - + "# HELP double_gauge_colliding_attributes_seconds unused\n" - + "double_gauge_colliding_attributes_seconds{otel_scope_name=\"full\",otel_scope_version=\"version\",foo_bar=\"a;b\",type=\"dgma\"} 8.0 1633950672.000\n" - + "# EOF\n"); - assertThat(logCapturer.size()).isZero(); - } - - @Test - @SuppressLogger(Serializer.class) - void outOfOrderedAttributes() { - // Alternative attributes implementation which sorts entries by the order they were added rather - // than lexicographically - // all attributes are retained, we log a warning, and b_key and b.key are not be merged - LinkedHashMap, Object> attributesMap = new LinkedHashMap<>(); - attributesMap.put(AttributeKey.stringKey("b_key"), "val1"); - attributesMap.put(AttributeKey.stringKey("a_key"), "val2"); - attributesMap.put(AttributeKey.stringKey("b.key"), "val3"); - Attributes attributes = new MapAttributes(attributesMap); - - MetricData metricData = - ImmutableMetricData.createDoubleSum( - Resource.builder().put("kr", "vr").build(), - InstrumentationScopeInfo.builder("scope").setVersion("1.0.0").build(), - "sum", - "description", - "s", - ImmutableSumData.create( - /* isMonotonic= */ true, - AggregationTemporality.CUMULATIVE, - Collections.singletonList( - ImmutableDoublePointData.create( - 1633947011000000000L, 1633950672000000000L, attributes, 5)))); - - assertThat(serialize004(metricData)) - .isEqualTo( - "# TYPE target info\n" - + "# HELP target Target metadata\n" - + "target_info{kr=\"vr\"} 1\n" - + "# TYPE sum_seconds_total counter\n" - + "# HELP sum_seconds_total description\n" - + "sum_seconds_total{otel_scope_name=\"scope\",otel_scope_version=\"1.0.0\",b_key=\"val1\",a_key=\"val2\",b_key=\"val3\"} 5.0 1633950672000\n"); - logCapturer.assertContains( - "Dropping out-of-order attribute a_key=val2, which occurred after b_key. This can occur when an alternative Attribute implementation is used."); - } - - @Test - void emptyResource() { - MetricData metricData = - ImmutableMetricData.createDoubleSum( - Resource.empty(), - InstrumentationScopeInfo.builder("scope").setVersion("1.0.0").build(), - "monotonic.cumulative.double.sum", - "description", - "s", - ImmutableSumData.create( - /* isMonotonic= */ true, - AggregationTemporality.CUMULATIVE, - Collections.singletonList( - ImmutableDoublePointData.create( - 1633947011000000000L, 1633950672000000000L, Attributes.empty(), 5)))); - - assertThat(serialize004(metricData)) - .isEqualTo( - "# TYPE monotonic_cumulative_double_sum_seconds_total counter\n" - + "# HELP monotonic_cumulative_double_sum_seconds_total description\n" - + "monotonic_cumulative_double_sum_seconds_total{otel_scope_name=\"scope\",otel_scope_version=\"1.0.0\"} 5.0 1633950672000\n"); - } - - private static String serialize004(MetricData... metrics) { - ByteArrayOutputStream bos = new ByteArrayOutputStream(); - try { - new Serializer.Prometheus004Serializer(unused -> true).write(Arrays.asList(metrics), bos); - return bos.toString("UTF-8"); - } catch (IOException e) { - throw new UncheckedIOException(e); - } - } - - private static String serializeOpenMetrics(MetricData... metrics) { - ByteArrayOutputStream bos = new ByteArrayOutputStream(); - try { - new Serializer.OpenMetrics100Serializer(unused -> true).write(Arrays.asList(metrics), bos); - return bos.toString("UTF-8"); - } catch (IOException e) { - throw new UncheckedIOException(e); - } - } - - @SuppressWarnings("unchecked") - private static class MapAttributes implements Attributes { - - private final LinkedHashMap, Object> map; - - @SuppressWarnings("NonApiType") - private MapAttributes(LinkedHashMap, Object> map) { - this.map = map; - } - - @Nullable - @Override - public T get(AttributeKey key) { - return (T) map.get(key); - } - - @Override - public void forEach(BiConsumer, ? super Object> consumer) { - map.forEach(consumer); - } - - @Override - public int size() { - return map.size(); - } - - @Override - public boolean isEmpty() { - return map.isEmpty(); - } - - @Override - public Map, Object> asMap() { - return map; - } - - @Override - public AttributesBuilder toBuilder() { - throw new UnsupportedOperationException("not supported"); - } - } -} diff --git a/exporters/prometheus/src/test/java/io/opentelemetry/exporter/prometheus/TestConstants.java b/exporters/prometheus/src/test/java/io/opentelemetry/exporter/prometheus/TestConstants.java deleted file mode 100644 index 3edc286c9ee..00000000000 --- a/exporters/prometheus/src/test/java/io/opentelemetry/exporter/prometheus/TestConstants.java +++ /dev/null @@ -1,378 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package io.opentelemetry.exporter.prometheus; - -import static io.opentelemetry.api.common.AttributeKey.stringKey; - -import io.opentelemetry.api.common.AttributeKey; -import io.opentelemetry.api.common.Attributes; -import io.opentelemetry.api.trace.SpanContext; -import io.opentelemetry.api.trace.TraceFlags; -import io.opentelemetry.api.trace.TraceState; -import io.opentelemetry.sdk.common.InstrumentationScopeInfo; -import io.opentelemetry.sdk.metrics.data.AggregationTemporality; -import io.opentelemetry.sdk.metrics.data.MetricData; -import io.opentelemetry.sdk.metrics.internal.data.ImmutableDoubleExemplarData; -import io.opentelemetry.sdk.metrics.internal.data.ImmutableDoublePointData; -import io.opentelemetry.sdk.metrics.internal.data.ImmutableGaugeData; -import io.opentelemetry.sdk.metrics.internal.data.ImmutableHistogramData; -import io.opentelemetry.sdk.metrics.internal.data.ImmutableHistogramPointData; -import io.opentelemetry.sdk.metrics.internal.data.ImmutableLongPointData; -import io.opentelemetry.sdk.metrics.internal.data.ImmutableMetricData; -import io.opentelemetry.sdk.metrics.internal.data.ImmutableSumData; -import io.opentelemetry.sdk.metrics.internal.data.ImmutableSummaryData; -import io.opentelemetry.sdk.metrics.internal.data.ImmutableSummaryPointData; -import io.opentelemetry.sdk.metrics.internal.data.ImmutableValueAtQuantile; -import io.opentelemetry.sdk.resources.Resource; -import java.util.Arrays; -import java.util.Collections; -import java.util.concurrent.TimeUnit; - -/** A helper class encapsulating immutable static data that can be shared across all the tests. */ -class TestConstants { - - private TestConstants() { - // Private constructor to prevent instantiation - } - - private static final AttributeKey TYPE = stringKey("type"); - - static final MetricData MONOTONIC_CUMULATIVE_DOUBLE_SUM = - ImmutableMetricData.createDoubleSum( - Resource.create(Attributes.of(stringKey("kr"), "vr")), - InstrumentationScopeInfo.builder("full") - .setVersion("version") - .setAttributes(Attributes.of(stringKey("ks"), "vs")) - .build(), - "monotonic.cumulative.double.sum", - "description", - "s", - ImmutableSumData.create( - /* isMonotonic= */ true, - AggregationTemporality.CUMULATIVE, - Collections.singletonList( - ImmutableDoublePointData.create( - 1633947011000000000L, - 1633950672000000000L, - Attributes.of(TYPE, "mcds"), - 5)))); - - static final MetricData MONOTONIC_CUMULATIVE_DOUBLE_SUM_WITH_SUFFIX_TOTAL = - ImmutableMetricData.createDoubleSum( - Resource.create(Attributes.of(stringKey("kr"), "vr")), - InstrumentationScopeInfo.builder("full") - .setVersion("version") - .setAttributes(Attributes.of(stringKey("ks"), "vs")) - .build(), - "monotonic.cumulative.double.sum.suffix.total", - "description", - "s", - ImmutableSumData.create( - /* isMonotonic= */ true, - AggregationTemporality.CUMULATIVE, - Collections.singletonList( - ImmutableDoublePointData.create( - 1633947011000000000L, - 1633950672000000000L, - Attributes.of(TYPE, "mcds"), - 5)))); - - static final MetricData NON_MONOTONIC_CUMULATIVE_DOUBLE_SUM = - ImmutableMetricData.createDoubleSum( - Resource.create(Attributes.of(stringKey("kr"), "vr")), - InstrumentationScopeInfo.builder("full") - .setVersion("version") - .setAttributes(Attributes.of(stringKey("ks"), "vs")) - .build(), - "non.monotonic.cumulative.double.sum", - "description", - "s", - ImmutableSumData.create( - /* isMonotonic= */ false, - AggregationTemporality.CUMULATIVE, - Collections.singletonList( - ImmutableDoublePointData.create( - 1633947011000000000L, - 1633950672000000000L, - Attributes.of(TYPE, "nmcds"), - 5)))); - - static final MetricData DELTA_DOUBLE_SUM = - ImmutableMetricData.createDoubleSum( - Resource.create(Attributes.of(stringKey("kr"), "vr")), - InstrumentationScopeInfo.builder("full") - .setVersion("version") - .setAttributes(Attributes.of(stringKey("ks"), "vs")) - .build(), - "delta.double.sum", - "unused", - "s", - ImmutableSumData.create( - /* isMonotonic= */ true, - AggregationTemporality.DELTA, - Collections.singletonList( - ImmutableDoublePointData.create( - 1633947011000000000L, - 1633950672000000000L, - Attributes.of(TYPE, "mdds"), - 5)))); - - static final MetricData MONOTONIC_CUMULATIVE_LONG_SUM = - ImmutableMetricData.createLongSum( - Resource.create(Attributes.of(stringKey("kr"), "vr")), - InstrumentationScopeInfo.builder("full") - .setVersion("version") - .setAttributes(Attributes.of(stringKey("ks"), "vs")) - .build(), - "monotonic.cumulative.long.sum", - "unused", - "s", - ImmutableSumData.create( - /* isMonotonic= */ true, - AggregationTemporality.CUMULATIVE, - Collections.singletonList( - ImmutableLongPointData.create( - 1633947011000000000L, - 1633950672000000000L, - Attributes.of(TYPE, "mcls"), - 5)))); - - static final MetricData NON_MONOTONIC_CUMULATIVE_LONG_SUM = - ImmutableMetricData.createLongSum( - Resource.create(Attributes.of(stringKey("kr"), "vr")), - InstrumentationScopeInfo.builder("full") - .setVersion("version") - .setAttributes(Attributes.of(stringKey("ks"), "vs")) - .build(), - "non.monotonic.cumulative.long_sum", - "unused", - "s", - ImmutableSumData.create( - /* isMonotonic= */ false, - AggregationTemporality.CUMULATIVE, - Collections.singletonList( - ImmutableLongPointData.create( - 1633947011000000000L, - 1633950672000000000L, - Attributes.of(TYPE, "nmcls"), - 5)))); - static final MetricData DELTA_LONG_SUM = - ImmutableMetricData.createLongSum( - Resource.create(Attributes.of(stringKey("kr"), "vr")), - InstrumentationScopeInfo.builder("full") - .setVersion("version") - .setAttributes(Attributes.of(stringKey("ks"), "vs")) - .build(), - "delta.long.sum", - "unused", - "s", - ImmutableSumData.create( - /* isMonotonic= */ true, - AggregationTemporality.DELTA, - Collections.singletonList( - ImmutableLongPointData.create( - 1633947011000000000L, - 1633950672000000000L, - Attributes.of(TYPE, "mdls"), - 5)))); - - static final MetricData DOUBLE_GAUGE = - ImmutableMetricData.createDoubleGauge( - Resource.create(Attributes.of(stringKey("kr"), "vr")), - InstrumentationScopeInfo.builder("full") - .setVersion("version") - .setAttributes(Attributes.of(stringKey("ks"), "vs")) - .build(), - "double.gauge", - "unused", - "s", - ImmutableGaugeData.create( - Collections.singletonList( - ImmutableDoublePointData.create( - 1633947011000000000L, 1633950672000000000L, Attributes.of(TYPE, "dg"), 5)))); - static final MetricData LONG_GAUGE = - ImmutableMetricData.createLongGauge( - Resource.create(Attributes.of(stringKey("kr"), "vr")), - InstrumentationScopeInfo.builder("full") - .setVersion("version") - .setAttributes(Attributes.of(stringKey("ks"), "vs")) - .build(), - "long.gauge", - "unused", - "s", - ImmutableGaugeData.create( - Collections.singletonList( - ImmutableLongPointData.create( - 1633947011000000000L, 1633950672000000000L, Attributes.of(TYPE, "lg"), 5)))); - static final MetricData SUMMARY = - ImmutableMetricData.createDoubleSummary( - Resource.create(Attributes.of(stringKey("kr"), "vr")), - InstrumentationScopeInfo.builder("full") - .setVersion("version") - .setAttributes(Attributes.of(stringKey("ks"), "vs")) - .build(), - "summary", - "unused", - "s", - ImmutableSummaryData.create( - Collections.singletonList( - ImmutableSummaryPointData.create( - 1633947011000000000L, - 1633950672000000000L, - Attributes.of(TYPE, "s"), - 5, - 7, - Arrays.asList( - ImmutableValueAtQuantile.create(0.9, 0.1), - ImmutableValueAtQuantile.create(0.99, 0.3)))))); - - static final MetricData DELTA_HISTOGRAM = - ImmutableMetricData.createDoubleHistogram( - Resource.create(Attributes.of(stringKey("kr"), "vr")), - InstrumentationScopeInfo.builder("full") - .setVersion("version") - .setAttributes(Attributes.of(stringKey("ks"), "vs")) - .build(), - "delta.histogram", - "unused", - "s", - ImmutableHistogramData.create( - AggregationTemporality.DELTA, - Collections.singletonList( - ImmutableHistogramPointData.create( - 1633947011000000000L, - 1633950672000000000L, - Attributes.empty(), - 1.0, - /* hasMin= */ false, - 0, - /* hasMax= */ false, - 0, - Collections.emptyList(), - Collections.singletonList(2L), - Collections.emptyList())))); - - static final MetricData CUMULATIVE_HISTOGRAM_NO_ATTRIBUTES = - ImmutableMetricData.createDoubleHistogram( - Resource.create(Attributes.of(stringKey("kr"), "vr")), - InstrumentationScopeInfo.builder("full") - .setVersion("version") - .setAttributes(Attributes.of(stringKey("ks"), "vs")) - .build(), - "cumulative.histogram.no.attributes", - "unused", - "s", - ImmutableHistogramData.create( - AggregationTemporality.CUMULATIVE, - Collections.singletonList( - ImmutableHistogramPointData.create( - 1633947011000000000L, - 1633950672000000000L, - Attributes.empty(), - 1.0, - /* hasMin= */ false, - 0, - /* hasMax= */ false, - 0, - Collections.emptyList(), - Collections.singletonList(2L), - Collections.singletonList( - ImmutableDoubleExemplarData.create( - Attributes.empty(), - TimeUnit.MILLISECONDS.toNanos(1L), - SpanContext.create( - "00000000000000000000000000000001", - "0000000000000002", - TraceFlags.getDefault(), - TraceState.getDefault()), - /* value= */ 4)))))); - - static final MetricData CUMULATIVE_HISTOGRAM_SINGLE_ATTRIBUTE = - ImmutableMetricData.createDoubleHistogram( - Resource.create(Attributes.of(stringKey("kr"), "vr")), - InstrumentationScopeInfo.builder("full") - .setVersion("version") - .setAttributes(Attributes.of(stringKey("ks"), "vs")) - .build(), - "cumulative.histogram.single.attribute", - "unused", - "s", - ImmutableHistogramData.create( - AggregationTemporality.CUMULATIVE, - Collections.singletonList( - ImmutableHistogramPointData.create( - 1633947011000000000L, - 1633950672000000000L, - Attributes.of(TYPE, "hs"), - 1.0, - /* hasMin= */ false, - 0, - /* hasMax= */ false, - 0, - Collections.emptyList(), - Collections.singletonList(2L), - Collections.singletonList( - ImmutableDoubleExemplarData.create( - Attributes.empty(), - TimeUnit.MILLISECONDS.toNanos(1L), - SpanContext.create( - "00000000000000000000000000000001", - "0000000000000002", - TraceFlags.getDefault(), - TraceState.getDefault()), - /* value= */ 4)))))); - - static final MetricData DOUBLE_GAUGE_NO_ATTRIBUTES = - ImmutableMetricData.createDoubleGauge( - Resource.create(Attributes.of(stringKey("kr"), "vr")), - InstrumentationScopeInfo.builder("full") - .setVersion("version") - .setAttributes(Attributes.of(stringKey("ks"), "vs")) - .build(), - "double.gauge.no.attributes", - "unused", - "s", - ImmutableGaugeData.create( - Collections.singletonList( - ImmutableDoublePointData.create( - 1633947011000000000L, 1633950672000000000L, Attributes.empty(), 7)))); - - static final MetricData DOUBLE_GAUGE_MULTIPLE_ATTRIBUTES = - ImmutableMetricData.createDoubleGauge( - Resource.create(Attributes.of(stringKey("kr"), "vr")), - InstrumentationScopeInfo.builder("full") - .setVersion("version") - .setAttributes(Attributes.of(stringKey("ks"), "vs")) - .build(), - "double.gauge.multiple.attributes", - "unused", - "s", - ImmutableGaugeData.create( - Collections.singletonList( - ImmutableDoublePointData.create( - 1633947011000000000L, - 1633950672000000000L, - Attributes.of(TYPE, "dgma", stringKey("animal"), "bear"), - 8)))); - static final MetricData DOUBLE_GAUGE_COLLIDING_ATTRIBUTES = - ImmutableMetricData.createDoubleGauge( - Resource.create(Attributes.of(stringKey("kr"), "vr")), - InstrumentationScopeInfo.builder("full") - .setVersion("version") - .setAttributes(Attributes.of(stringKey("ks"), "vs")) - .build(), - "double.gauge.colliding.attributes", - "unused", - "s", - ImmutableGaugeData.create( - Collections.singletonList( - ImmutableDoublePointData.create( - 1633947011000000000L, - 1633950672000000000L, - Attributes.of( - TYPE, "dgma", stringKey("foo.bar"), "a", stringKey("foo_bar"), "b"), - 8)))); -} diff --git a/exporters/prometheus/src/test/java/io/opentelemetry/exporter/prometheus/internal/PrometheusMetricReaderProviderTest.java b/exporters/prometheus/src/test/java/io/opentelemetry/exporter/prometheus/internal/PrometheusMetricReaderProviderTest.java index 9cc1acd2614..58504e2e7e9 100644 --- a/exporters/prometheus/src/test/java/io/opentelemetry/exporter/prometheus/internal/PrometheusMetricReaderProviderTest.java +++ b/exporters/prometheus/src/test/java/io/opentelemetry/exporter/prometheus/internal/PrometheusMetricReaderProviderTest.java @@ -15,6 +15,7 @@ import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties; import io.opentelemetry.sdk.autoconfigure.spi.internal.DefaultConfigProperties; import io.opentelemetry.sdk.metrics.export.MetricReader; +import io.prometheus.metrics.exporter.httpserver.HTTPServer; import java.io.IOException; import java.net.ServerSocket; import java.util.HashMap; @@ -49,6 +50,7 @@ void createMetricReader_Default() throws IOException { try (MetricReader metricReader = provider.createMetricReader(configProperties)) { assertThat(metricReader) .isInstanceOf(PrometheusHttpServer.class) + .extracting("httpServer", as(InstanceOfAssertFactories.type(HTTPServer.class))) .extracting("server", as(InstanceOfAssertFactories.type(HttpServer.class))) .satisfies( server -> { @@ -78,6 +80,7 @@ void createMetricReader_WithConfiguration() throws IOException { try (MetricReader metricReader = provider.createMetricReader(DefaultConfigProperties.createFromMap(config))) { assertThat(metricReader) + .extracting("httpServer", as(InstanceOfAssertFactories.type(HTTPServer.class))) .extracting("server", as(InstanceOfAssertFactories.type(HttpServer.class))) .satisfies( server -> { From 17b8f4355da0932e25a66fffd03f01ad8ea95f5e Mon Sep 17 00:00:00 2001 From: jack-berg <34418638+jack-berg@users.noreply.github.com> Date: Wed, 3 Jan 2024 11:50:38 -0600 Subject: [PATCH 176/901] Read normalized otel.config.file property (#6105) Co-authored-by: Trask Stalnaker --- .../AutoConfiguredOpenTelemetrySdkBuilder.java | 3 ++- .../autoconfigure/FileConfigurationTest.java | 11 ++++++++++- .../autoconfigure/FileConfigurationTest.java | 18 +++++++++++++----- 3 files changed, 25 insertions(+), 7 deletions(-) diff --git a/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/AutoConfiguredOpenTelemetrySdkBuilder.java b/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/AutoConfiguredOpenTelemetrySdkBuilder.java index 2d10524e276..05935556aba 100644 --- a/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/AutoConfiguredOpenTelemetrySdkBuilder.java +++ b/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/AutoConfiguredOpenTelemetrySdkBuilder.java @@ -479,10 +479,11 @@ public AutoConfiguredOpenTelemetrySdk build() { @Nullable private static AutoConfiguredOpenTelemetrySdk maybeConfigureFromFile(ConfigProperties config) { - String configurationFile = config.getString("OTEL_CONFIG_FILE"); + String configurationFile = config.getString("otel.config.file"); if (configurationFile == null || configurationFile.isEmpty()) { return null; } + logger.fine("Autoconfiguring from configuration file: " + configurationFile); FileInputStream fis; try { fis = new FileInputStream(configurationFile); diff --git a/sdk-extensions/autoconfigure/src/test/java/io/opentelemetry/sdk/autoconfigure/FileConfigurationTest.java b/sdk-extensions/autoconfigure/src/test/java/io/opentelemetry/sdk/autoconfigure/FileConfigurationTest.java index e6aa1759d32..418dd263625 100644 --- a/sdk-extensions/autoconfigure/src/test/java/io/opentelemetry/sdk/autoconfigure/FileConfigurationTest.java +++ b/sdk-extensions/autoconfigure/src/test/java/io/opentelemetry/sdk/autoconfigure/FileConfigurationTest.java @@ -7,6 +7,7 @@ import static org.assertj.core.api.Assertions.assertThatThrownBy; +import io.github.netmikey.logunit.api.LogCapturer; import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties; import io.opentelemetry.sdk.autoconfigure.spi.ConfigurationException; import io.opentelemetry.sdk.autoconfigure.spi.internal.DefaultConfigProperties; @@ -16,10 +17,17 @@ import java.nio.file.Path; import java.util.Collections; import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; import org.junit.jupiter.api.io.TempDir; +import org.slf4j.event.Level; class FileConfigurationTest { + @RegisterExtension + static final LogCapturer logCapturer = + LogCapturer.create() + .captureForLogger(AutoConfiguredOpenTelemetrySdkBuilder.class.getName(), Level.TRACE); + @Test void configFile(@TempDir Path tempDir) throws IOException { String yaml = @@ -36,11 +44,12 @@ void configFile(@TempDir Path tempDir) throws IOException { Files.write(path, yaml.getBytes(StandardCharsets.UTF_8)); ConfigProperties config = DefaultConfigProperties.createFromMap( - Collections.singletonMap("OTEL_CONFIG_FILE", path.toString())); + Collections.singletonMap("otel.config.file", path.toString())); assertThatThrownBy(() -> AutoConfiguredOpenTelemetrySdk.builder().setConfig(config).build()) .isInstanceOf(ConfigurationException.class) .hasMessage( "Error configuring from file. Is opentelemetry-sdk-extension-incubator on the classpath?"); + logCapturer.assertContains("Autoconfiguring from configuration file: " + path); } } diff --git a/sdk-extensions/autoconfigure/src/testFullConfig/java/io/opentelemetry/sdk/autoconfigure/FileConfigurationTest.java b/sdk-extensions/autoconfigure/src/testFullConfig/java/io/opentelemetry/sdk/autoconfigure/FileConfigurationTest.java index dd11494958f..ea726ca3472 100644 --- a/sdk-extensions/autoconfigure/src/testFullConfig/java/io/opentelemetry/sdk/autoconfigure/FileConfigurationTest.java +++ b/sdk-extensions/autoconfigure/src/testFullConfig/java/io/opentelemetry/sdk/autoconfigure/FileConfigurationTest.java @@ -15,6 +15,7 @@ import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; +import io.github.netmikey.logunit.api.LogCapturer; import io.opentelemetry.api.GlobalOpenTelemetry; import io.opentelemetry.api.OpenTelemetry; import io.opentelemetry.api.baggage.propagation.W3CBaggagePropagator; @@ -41,11 +42,17 @@ import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.RegisterExtension; import org.junit.jupiter.api.io.TempDir; +import org.slf4j.event.Level; class FileConfigurationTest { @RegisterExtension private static final CleanupExtension cleanup = new CleanupExtension(); + @RegisterExtension + static final LogCapturer logCapturer = + LogCapturer.create() + .captureForLogger(AutoConfiguredOpenTelemetrySdkBuilder.class.getName(), Level.TRACE); + @TempDir private Path tempDir; private Path configFilePath; @@ -71,7 +78,7 @@ void setup() throws IOException { void configFile_Valid() { ConfigProperties config = DefaultConfigProperties.createFromMap( - Collections.singletonMap("OTEL_CONFIG_FILE", configFilePath.toString())); + Collections.singletonMap("otel.config.file", configFilePath.toString())); OpenTelemetrySdk expectedSdk = OpenTelemetrySdk.builder() .setTracerProvider( @@ -102,13 +109,14 @@ void configFile_Valid() { assertThat(autoConfiguredOpenTelemetrySdk.getResource()).isEqualTo(Resource.getDefault()); verify(builder, times(1)).shutdownHook(autoConfiguredOpenTelemetrySdk.getOpenTelemetrySdk()); assertThat(Runtime.getRuntime().removeShutdownHook(thread)).isTrue(); + logCapturer.assertContains("Autoconfiguring from configuration file: " + configFilePath); } @Test void configFile_NoShutdownHook() { ConfigProperties config = DefaultConfigProperties.createFromMap( - Collections.singletonMap("OTEL_CONFIG_FILE", configFilePath.toString())); + Collections.singletonMap("otel.config.file", configFilePath.toString())); AutoConfiguredOpenTelemetrySdkBuilder builder = spy(AutoConfiguredOpenTelemetrySdk.builder()); AutoConfiguredOpenTelemetrySdk autoConfiguredOpenTelemetrySdk = @@ -123,7 +131,7 @@ void configFile_setResultAsGlobalFalse() { GlobalOpenTelemetry.set(OpenTelemetry.noop()); ConfigProperties config = DefaultConfigProperties.createFromMap( - Collections.singletonMap("OTEL_CONFIG_FILE", configFilePath.toString())); + Collections.singletonMap("otel.config.file", configFilePath.toString())); AutoConfiguredOpenTelemetrySdk autoConfiguredOpenTelemetrySdk = AutoConfiguredOpenTelemetrySdk.builder().setConfig(config).build(); @@ -139,7 +147,7 @@ void configFile_setResultAsGlobalFalse() { void configFile_setResultAsGlobalTrue() { ConfigProperties config = DefaultConfigProperties.createFromMap( - Collections.singletonMap("OTEL_CONFIG_FILE", configFilePath.toString())); + Collections.singletonMap("otel.config.file", configFilePath.toString())); AutoConfiguredOpenTelemetrySdk autoConfiguredOpenTelemetrySdk = AutoConfiguredOpenTelemetrySdk.builder().setConfig(config).setResultAsGlobal().build(); @@ -169,7 +177,7 @@ void configFile_Error(@TempDir Path tempDir) throws IOException { Files.write(path, yaml.getBytes(StandardCharsets.UTF_8)); ConfigProperties config = DefaultConfigProperties.createFromMap( - Collections.singletonMap("OTEL_CONFIG_FILE", path.toString())); + Collections.singletonMap("otel.config.file", path.toString())); assertThatThrownBy(() -> AutoConfiguredOpenTelemetrySdk.builder().setConfig(config).build()) .isInstanceOf(ConfigurationException.class) From 517ef88ca16928d6d514125c78c166e3e663dc2f Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 3 Jan 2024 12:16:00 -0600 Subject: [PATCH 177/901] Update errorProneVersion to v2.24.1 (#6111) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- dependencyManagement/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index 9c0f53936b1..598de3a7ae0 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -25,7 +25,7 @@ val DEPENDENCY_BOMS = listOf( ) val autoValueVersion = "1.10.4" -val errorProneVersion = "2.24.0" +val errorProneVersion = "2.24.1" val jmhVersion = "1.37" // Mockito 5.x.x requires Java 11 https://github.com/mockito/mockito/releases/tag/v5.0.0 val mockitoVersion = "4.11.0" From bc0df3b4d587350134c20d196b6ecae78079837b Mon Sep 17 00:00:00 2001 From: jack-berg <34418638+jack-berg@users.noreply.github.com> Date: Wed, 3 Jan 2024 15:29:26 -0600 Subject: [PATCH 178/901] Fix autoconfigure javadoc explaining behavior when disabled (#6109) --- .../autoconfigure/AutoConfiguredOpenTelemetrySdk.java | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/AutoConfiguredOpenTelemetrySdk.java b/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/AutoConfiguredOpenTelemetrySdk.java index 7d1bb1ba2cb..997df49062c 100644 --- a/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/AutoConfiguredOpenTelemetrySdk.java +++ b/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/AutoConfiguredOpenTelemetrySdk.java @@ -7,6 +7,7 @@ import com.google.auto.value.AutoValue; import io.opentelemetry.api.GlobalOpenTelemetry; +import io.opentelemetry.api.OpenTelemetry; import io.opentelemetry.sdk.OpenTelemetrySdk; import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties; import io.opentelemetry.sdk.resources.Resource; @@ -47,8 +48,12 @@ static AutoConfiguredOpenTelemetrySdk create( } /** - * Returns the {@link OpenTelemetrySdk} that was auto-configured, or {@code null} if the SDK has - * been disabled. + * Returns the {@link OpenTelemetrySdk} that was auto-configured, or an effectively noop instance + * if the SDK has been disabled. + * + *

    The instance returned if the SDK is disabled is equivalent to {@code + * OpenTelemetrySdk.builder().build()}, which is notably not the same as {@link + * OpenTelemetry#noop()}. */ public abstract OpenTelemetrySdk getOpenTelemetrySdk(); From 63fe7084d28388902fc6781d4c45ef942c0c224e Mon Sep 17 00:00:00 2001 From: jack-berg <34418638+jack-berg@users.noreply.github.com> Date: Wed, 3 Jan 2024 15:32:08 -0600 Subject: [PATCH 179/901] Only call SpanProcessor onStart / onEnd if required (#6112) --- .../io/opentelemetry/sdk/trace/SdkSpan.java | 8 +++- .../opentelemetry/sdk/trace/SdkSpanTest.java | 42 +++++++++++++++++++ 2 files changed, 48 insertions(+), 2 deletions(-) diff --git a/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/SdkSpan.java b/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/SdkSpan.java index c6e72632547..70608e35a32 100644 --- a/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/SdkSpan.java +++ b/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/SdkSpan.java @@ -194,7 +194,9 @@ static SdkSpan startSpan( startEpochNanos); // Call onStart here instead of calling in the constructor to make sure the span is completely // initialized. - spanProcessor.onStart(parentContext, span); + if (spanProcessor.isStartRequired()) { + spanProcessor.onStart(parentContext, span); + } return span; } @@ -448,7 +450,9 @@ private void endInternal(long endEpochNanos) { this.endEpochNanos = endEpochNanos; hasEnded = true; } - spanProcessor.onEnd(this); + if (spanProcessor.isEndRequired()) { + spanProcessor.onEnd(this); + } } @Override diff --git a/sdk/trace/src/test/java/io/opentelemetry/sdk/trace/SdkSpanTest.java b/sdk/trace/src/test/java/io/opentelemetry/sdk/trace/SdkSpanTest.java index a87c58d7c3c..d117a7b2e82 100644 --- a/sdk/trace/src/test/java/io/opentelemetry/sdk/trace/SdkSpanTest.java +++ b/sdk/trace/src/test/java/io/opentelemetry/sdk/trace/SdkSpanTest.java @@ -16,6 +16,10 @@ import static java.util.stream.Collectors.joining; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; import io.opentelemetry.api.common.AttributeKey; import io.opentelemetry.api.common.Attributes; @@ -60,9 +64,12 @@ import org.mockito.Mock; import org.mockito.Mockito; import org.mockito.junit.jupiter.MockitoExtension; +import org.mockito.junit.jupiter.MockitoSettings; +import org.mockito.quality.Strictness; @SuppressWarnings({"rawtypes", "unchecked"}) @ExtendWith(MockitoExtension.class) +@MockitoSettings(strictness = Strictness.LENIENT) class SdkSpanTest { private static final String SPAN_NAME = "MySpanName"; private static final String SPAN_NEW_NAME = "NewName"; @@ -97,6 +104,8 @@ void setUp() { } expectedAttributes = builder.build(); testClock = TestClock.create(Instant.ofEpochSecond(0, START_EPOCH_NANOS)); + when(spanProcessor.isStartRequired()).thenReturn(true); + when(spanProcessor.isEndRequired()).thenReturn(true); } @Test @@ -1040,6 +1049,39 @@ void badArgsIgnored() { assertThat(data.getName()).isEqualTo(SPAN_NAME); } + @Test + void onStartOnEndNotRequired() { + when(spanProcessor.isStartRequired()).thenReturn(false); + when(spanProcessor.isEndRequired()).thenReturn(false); + + SpanLimits spanLimits = SpanLimits.getDefault(); + SdkSpan span = + SdkSpan.startSpan( + spanContext, + SPAN_NAME, + instrumentationScopeInfo, + SpanKind.INTERNAL, + parentSpanId != null + ? Span.wrap( + SpanContext.create( + traceId, parentSpanId, TraceFlags.getDefault(), TraceState.getDefault())) + : Span.getInvalid(), + Context.root(), + spanLimits, + spanProcessor, + testClock, + resource, + AttributesMap.create( + spanLimits.getMaxNumberOfAttributes(), spanLimits.getMaxAttributeValueLength()), + Collections.emptyList(), + 1, + 0); + verify(spanProcessor, never()).onStart(any(), any()); + + span.end(); + verify(spanProcessor, never()).onEnd(any()); + } + private SdkSpan createTestSpanWithAttributes(Map attributes) { SpanLimits spanLimits = SpanLimits.getDefault(); AttributesMap attributesMap = From b4ed53211bb6f893bed9dbde119847d180638862 Mon Sep 17 00:00:00 2001 From: jack-berg <34418638+jack-berg@users.noreply.github.com> Date: Wed, 3 Jan 2024 17:06:47 -0600 Subject: [PATCH 180/901] Propagate serialization IOException instead of rethrowing as runtime (#6082) Co-authored-by: Ricardo Mestre --- .../exporter/internal/http/HttpExporter.java | 23 ++--------- .../internal/http/HttpExporterBuilder.java | 1 + .../exporter/internal/http/HttpSender.java | 4 +- .../internal/http/HttpSenderProvider.java | 1 + exporters/sender/jdk/build.gradle.kts | 2 + .../sender/jdk/internal/JdkHttpSender.java | 25 +++++++++--- .../jdk/internal/JdkHttpSenderProvider.java | 2 + .../jdk/internal/JdkHttpSenderTest.java | 21 ++++++++-- exporters/sender/okhttp/build.gradle.kts | 1 + .../okhttp/internal/OkHttpHttpSender.java | 23 +++++++---- .../internal/OkHttpHttpSenderProvider.java | 2 + .../internal/AuthenticatingExporterTest.java | 1 + .../internal/OkHttpHttpSuppressionTest.java | 38 ++++++++++++------- 13 files changed, 94 insertions(+), 50 deletions(-) diff --git a/exporters/common/src/main/java/io/opentelemetry/exporter/internal/http/HttpExporter.java b/exporters/common/src/main/java/io/opentelemetry/exporter/internal/http/HttpExporter.java index f7af7150f74..befb579d964 100644 --- a/exporters/common/src/main/java/io/opentelemetry/exporter/internal/http/HttpExporter.java +++ b/exporters/common/src/main/java/io/opentelemetry/exporter/internal/http/HttpExporter.java @@ -12,9 +12,7 @@ import io.opentelemetry.sdk.common.CompletableResultCode; import io.opentelemetry.sdk.internal.ThrottlingLogger; import java.io.IOException; -import java.io.OutputStream; import java.util.concurrent.atomic.AtomicBoolean; -import java.util.function.Consumer; import java.util.function.Supplier; import java.util.logging.Level; import java.util.logging.Logger; @@ -37,7 +35,6 @@ public final class HttpExporter { private final String type; private final HttpSender httpSender; private final ExporterMetrics exporterMetrics; - private final boolean exportAsJson; public HttpExporter( String exporterName, @@ -51,7 +48,6 @@ public HttpExporter( exportAsJson ? ExporterMetrics.createHttpJson(exporterName, type, meterProviderSupplier) : ExporterMetrics.createHttpProtobuf(exporterName, type, meterProviderSupplier); - this.exportAsJson = exportAsJson; } public CompletableResultCode export(T exportRequest, int numItems) { @@ -63,21 +59,8 @@ public CompletableResultCode export(T exportRequest, int numItems) { CompletableResultCode result = new CompletableResultCode(); - Consumer marshaler = - os -> { - try { - if (exportAsJson) { - exportRequest.writeJsonTo(os); - } else { - exportRequest.writeBinaryTo(os); - } - } catch (IOException e) { - throw new IllegalStateException(e); - } - }; - httpSender.send( - marshaler, + exportRequest, exportRequest.getBinarySerializedSize(), httpResponse -> { int statusCode = httpResponse.statusCode(); @@ -90,11 +73,11 @@ public CompletableResultCode export(T exportRequest, int numItems) { exporterMetrics.addFailed(numItems); - byte[] body; + byte[] body = null; try { body = httpResponse.responseBody(); } catch (IOException ex) { - throw new IllegalStateException(ex); + logger.log(Level.FINE, "Unable to obtain response body", ex); } String status = extractErrorStatus(httpResponse.statusMessage(), body); diff --git a/exporters/common/src/main/java/io/opentelemetry/exporter/internal/http/HttpExporterBuilder.java b/exporters/common/src/main/java/io/opentelemetry/exporter/internal/http/HttpExporterBuilder.java index 2285cc97729..3b8275e2529 100644 --- a/exporters/common/src/main/java/io/opentelemetry/exporter/internal/http/HttpExporterBuilder.java +++ b/exporters/common/src/main/java/io/opentelemetry/exporter/internal/http/HttpExporterBuilder.java @@ -182,6 +182,7 @@ public HttpExporter build() { httpSenderProvider.createSender( endpoint, compressor, + exportAsJson, exportAsJson ? "application/json" : "application/x-protobuf", timeoutNanos, connectTimeoutNanos, diff --git a/exporters/common/src/main/java/io/opentelemetry/exporter/internal/http/HttpSender.java b/exporters/common/src/main/java/io/opentelemetry/exporter/internal/http/HttpSender.java index f7e21cb781a..dc5c775a530 100644 --- a/exporters/common/src/main/java/io/opentelemetry/exporter/internal/http/HttpSender.java +++ b/exporters/common/src/main/java/io/opentelemetry/exporter/internal/http/HttpSender.java @@ -5,9 +5,9 @@ package io.opentelemetry.exporter.internal.http; +import io.opentelemetry.exporter.internal.marshal.Marshaler; import io.opentelemetry.sdk.common.CompletableResultCode; import java.io.IOException; -import java.io.OutputStream; import java.util.function.Consumer; /** @@ -33,7 +33,7 @@ public interface HttpSender { * @param onError the callback to invoke when the HTTP request could not be executed */ void send( - Consumer marshaler, + Marshaler marshaler, int contentLength, Consumer onResponse, Consumer onError); diff --git a/exporters/common/src/main/java/io/opentelemetry/exporter/internal/http/HttpSenderProvider.java b/exporters/common/src/main/java/io/opentelemetry/exporter/internal/http/HttpSenderProvider.java index 20d4322ae67..90259734d12 100644 --- a/exporters/common/src/main/java/io/opentelemetry/exporter/internal/http/HttpSenderProvider.java +++ b/exporters/common/src/main/java/io/opentelemetry/exporter/internal/http/HttpSenderProvider.java @@ -29,6 +29,7 @@ public interface HttpSenderProvider { HttpSender createSender( String endpoint, @Nullable Compressor compressor, + boolean exportAsJson, String contentType, long timeoutNanos, long connectTimeout, diff --git a/exporters/sender/jdk/build.gradle.kts b/exporters/sender/jdk/build.gradle.kts index 80fb0f870d3..13f77b14824 100644 --- a/exporters/sender/jdk/build.gradle.kts +++ b/exporters/sender/jdk/build.gradle.kts @@ -9,6 +9,8 @@ otelJava.moduleName.set("io.opentelemetry.exporter.sender.jdk.internal") dependencies { implementation(project(":exporters:common")) implementation(project(":sdk:common")) + + compileOnly("com.fasterxml.jackson.core:jackson-core") } tasks { diff --git a/exporters/sender/jdk/src/main/java/io/opentelemetry/exporter/sender/jdk/internal/JdkHttpSender.java b/exporters/sender/jdk/src/main/java/io/opentelemetry/exporter/sender/jdk/internal/JdkHttpSender.java index 73d895a4883..838e1d5e20f 100644 --- a/exporters/sender/jdk/src/main/java/io/opentelemetry/exporter/sender/jdk/internal/JdkHttpSender.java +++ b/exporters/sender/jdk/src/main/java/io/opentelemetry/exporter/sender/jdk/internal/JdkHttpSender.java @@ -7,11 +7,13 @@ import io.opentelemetry.exporter.internal.compression.Compressor; import io.opentelemetry.exporter.internal.http.HttpSender; +import io.opentelemetry.exporter.internal.marshal.Marshaler; import io.opentelemetry.sdk.common.CompletableResultCode; import io.opentelemetry.sdk.common.export.RetryPolicy; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.OutputStream; +import java.io.UncheckedIOException; import java.net.URI; import java.net.URISyntaxException; import java.net.http.HttpClient; @@ -53,6 +55,7 @@ public final class JdkHttpSender implements HttpSender { private final HttpClient client; private final URI uri; @Nullable private final Compressor compressor; + private final boolean exportAsJson; private final String contentType; private final long timeoutNanos; private final Supplier>> headerSupplier; @@ -63,6 +66,7 @@ public final class JdkHttpSender implements HttpSender { HttpClient client, String endpoint, @Nullable Compressor compressor, + boolean exportAsJson, String contentType, long timeoutNanos, Supplier>> headerSupplier, @@ -74,6 +78,7 @@ public final class JdkHttpSender implements HttpSender { throw new IllegalArgumentException(e); } this.compressor = compressor; + this.exportAsJson = exportAsJson; this.contentType = contentType; this.timeoutNanos = timeoutNanos; this.headerSupplier = headerSupplier; @@ -83,6 +88,7 @@ public final class JdkHttpSender implements HttpSender { JdkHttpSender( String endpoint, @Nullable Compressor compressor, + boolean exportAsJson, String contentType, long timeoutNanos, long connectTimeoutNanos, @@ -93,6 +99,7 @@ public final class JdkHttpSender implements HttpSender { configureClient(sslContext, connectTimeoutNanos), endpoint, compressor, + exportAsJson, contentType, timeoutNanos, headerSupplier, @@ -111,7 +118,7 @@ private static HttpClient configureClient( @Override public void send( - Consumer marshaler, + Marshaler marshaler, int contentLength, Consumer onResponse, Consumer onError) { @@ -121,7 +128,7 @@ public void send( try { return sendInternal(marshaler); } catch (IOException e) { - throw new IllegalStateException(e); + throw new UncheckedIOException(e); } }, executorService) @@ -136,7 +143,7 @@ public void send( } // Visible for testing - HttpResponse sendInternal(Consumer marshaler) throws IOException { + HttpResponse sendInternal(Marshaler marshaler) throws IOException { long startTimeNanos = System.nanoTime(); HttpRequest.Builder requestBuilder = HttpRequest.newBuilder().uri(uri).timeout(Duration.ofNanos(timeoutNanos)); @@ -151,12 +158,12 @@ HttpResponse sendInternal(Consumer marshaler) throws IOExc if (compressor != null) { requestBuilder.header("Content-Encoding", compressor.getEncoding()); try (OutputStream compressed = compressor.compress(os)) { - marshaler.accept(compressed); + write(marshaler, compressed); } catch (IOException e) { throw new IllegalStateException(e); } } else { - marshaler.accept(os); + write(marshaler, os); } ByteBufferPool byteBufferPool = threadLocalByteBufPool.get(); @@ -211,6 +218,14 @@ HttpResponse sendInternal(Consumer marshaler) throws IOExc throw exception; } + private void write(Marshaler marshaler, OutputStream os) throws IOException { + if (exportAsJson) { + marshaler.writeJsonTo(os); + } else { + marshaler.writeBinaryTo(os); + } + } + private HttpResponse sendRequest( HttpRequest.Builder requestBuilder, ByteBufferPool byteBufferPool) throws IOException { try { diff --git a/exporters/sender/jdk/src/main/java/io/opentelemetry/exporter/sender/jdk/internal/JdkHttpSenderProvider.java b/exporters/sender/jdk/src/main/java/io/opentelemetry/exporter/sender/jdk/internal/JdkHttpSenderProvider.java index 1891cf27c85..c4c6bf071cc 100644 --- a/exporters/sender/jdk/src/main/java/io/opentelemetry/exporter/sender/jdk/internal/JdkHttpSenderProvider.java +++ b/exporters/sender/jdk/src/main/java/io/opentelemetry/exporter/sender/jdk/internal/JdkHttpSenderProvider.java @@ -29,6 +29,7 @@ public final class JdkHttpSenderProvider implements HttpSenderProvider { public HttpSender createSender( String endpoint, @Nullable Compressor compressor, + boolean exportAsJson, String contentType, long timeoutNanos, long connectTimeout, @@ -40,6 +41,7 @@ public HttpSender createSender( return new JdkHttpSender( endpoint, compressor, + exportAsJson, contentType, timeoutNanos, connectTimeout, diff --git a/exporters/sender/jdk/src/test/java/io/opentelemetry/exporter/sender/jdk/internal/JdkHttpSenderTest.java b/exporters/sender/jdk/src/test/java/io/opentelemetry/exporter/sender/jdk/internal/JdkHttpSenderTest.java index 1e2ee939863..e4ce06f466f 100644 --- a/exporters/sender/jdk/src/test/java/io/opentelemetry/exporter/sender/jdk/internal/JdkHttpSenderTest.java +++ b/exporters/sender/jdk/src/test/java/io/opentelemetry/exporter/sender/jdk/internal/JdkHttpSenderTest.java @@ -14,6 +14,8 @@ import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; +import io.opentelemetry.exporter.internal.marshal.Marshaler; +import io.opentelemetry.exporter.internal.marshal.Serializer; import io.opentelemetry.sdk.common.export.RetryPolicy; import java.io.IOException; import java.net.http.HttpClient; @@ -54,6 +56,7 @@ void setup() throws IOException, InterruptedException { "http://10.255.255.1", // Connecting to a non-routable IP address to trigger connection // timeout null, + false, "text/plain", Duration.ofSeconds(10).toNanos(), Collections::emptyMap, @@ -65,7 +68,7 @@ void setup() throws IOException, InterruptedException { @Test void sendInternal_RetryableConnectTimeoutException() throws IOException, InterruptedException { - assertThatThrownBy(() -> sender.sendInternal(marshaler -> {})) + assertThatThrownBy(() -> sender.sendInternal(new NoOpMarshaler())) .isInstanceOf(HttpConnectTimeoutException.class); verify(mockHttpClient, times(2)).send(any(), any()); @@ -75,7 +78,7 @@ void sendInternal_RetryableConnectTimeoutException() throws IOException, Interru void sendInternal_RetryableIoException() throws IOException, InterruptedException { doThrow(new IOException("error!")).when(mockHttpClient).send(any(), any()); - assertThatThrownBy(() -> sender.sendInternal(marshaler -> {})) + assertThatThrownBy(() -> sender.sendInternal(new NoOpMarshaler())) .isInstanceOf(IOException.class) .hasMessage("error!"); @@ -86,7 +89,7 @@ void sendInternal_RetryableIoException() throws IOException, InterruptedExceptio void sendInternal_NonRetryableException() throws IOException, InterruptedException { doThrow(new SSLException("unknown error")).when(mockHttpClient).send(any(), any()); - assertThatThrownBy(() -> sender.sendInternal(marshaler -> {})) + assertThatThrownBy(() -> sender.sendInternal(new NoOpMarshaler())) .isInstanceOf(IOException.class) .hasMessage("unknown error"); @@ -99,6 +102,7 @@ void connectTimeout() { new JdkHttpSender( "http://localhost", null, + false, "text/plain", 1, TimeUnit.SECONDS.toNanos(10), @@ -112,4 +116,15 @@ void connectTimeout() { httpClient -> assertThat(httpClient.connectTimeout().get()).isEqualTo(Duration.ofSeconds(10))); } + + private static class NoOpMarshaler extends Marshaler { + + @Override + public int getBinarySerializedSize() { + return 0; + } + + @Override + protected void writeTo(Serializer output) {} + } } diff --git a/exporters/sender/okhttp/build.gradle.kts b/exporters/sender/okhttp/build.gradle.kts index ef2c6c59c5f..107270e9ada 100644 --- a/exporters/sender/okhttp/build.gradle.kts +++ b/exporters/sender/okhttp/build.gradle.kts @@ -15,6 +15,7 @@ dependencies { implementation("com.squareup.okhttp3:okhttp") compileOnly("io.grpc:grpc-stub") + compileOnly("com.fasterxml.jackson.core:jackson-core") testImplementation("com.linecorp.armeria:armeria-junit5") } diff --git a/exporters/sender/okhttp/src/main/java/io/opentelemetry/exporter/sender/okhttp/internal/OkHttpHttpSender.java b/exporters/sender/okhttp/src/main/java/io/opentelemetry/exporter/sender/okhttp/internal/OkHttpHttpSender.java index 7724416c7fe..656b9258c20 100644 --- a/exporters/sender/okhttp/src/main/java/io/opentelemetry/exporter/sender/okhttp/internal/OkHttpHttpSender.java +++ b/exporters/sender/okhttp/src/main/java/io/opentelemetry/exporter/sender/okhttp/internal/OkHttpHttpSender.java @@ -10,10 +10,10 @@ import io.opentelemetry.exporter.internal.auth.Authenticator; import io.opentelemetry.exporter.internal.compression.Compressor; import io.opentelemetry.exporter.internal.http.HttpSender; +import io.opentelemetry.exporter.internal.marshal.Marshaler; import io.opentelemetry.sdk.common.CompletableResultCode; import io.opentelemetry.sdk.common.export.RetryPolicy; import java.io.IOException; -import java.io.OutputStream; import java.time.Duration; import java.util.List; import java.util.Map; @@ -44,6 +44,7 @@ public final class OkHttpHttpSender implements HttpSender { private final OkHttpClient client; private final HttpUrl url; @Nullable private final Compressor compressor; + private final boolean exportAsJson; private final Supplier>> headerSupplier; private final MediaType mediaType; @@ -52,6 +53,7 @@ public final class OkHttpHttpSender implements HttpSender { public OkHttpHttpSender( String endpoint, @Nullable Compressor compressor, + boolean exportAsJson, String contentType, long timeoutNanos, long connectionTimeoutNanos, @@ -86,13 +88,14 @@ public OkHttpHttpSender( this.client = builder.build(); this.url = HttpUrl.get(endpoint); this.compressor = compressor; + this.exportAsJson = exportAsJson; this.mediaType = MediaType.parse(contentType); this.headerSupplier = headerSupplier; } @Override public void send( - Consumer marshaler, + Marshaler marshaler, int contentLength, Consumer onResponse, Consumer onError) { @@ -103,7 +106,7 @@ public void send( headers.forEach( (key, values) -> values.forEach(value -> requestBuilder.addHeader(key, value))); } - RequestBody body = new RawRequestBody(marshaler, contentLength, mediaType); + RequestBody body = new RawRequestBody(marshaler, exportAsJson, contentLength, mediaType); if (compressor != null) { requestBuilder.addHeader("Content-Encoding", compressor.getEncoding()); requestBuilder.post(new CompressedRequestBody(compressor, body)); @@ -161,13 +164,15 @@ static boolean isRetryable(okhttp3.Response response) { private static class RawRequestBody extends RequestBody { - private final Consumer marshaler; + private final Marshaler marshaler; + private final boolean exportAsJson; private final int contentLength; private final MediaType mediaType; private RawRequestBody( - Consumer marshaler, int contentLength, MediaType mediaType) { + Marshaler marshaler, boolean exportAsJson, int contentLength, MediaType mediaType) { this.marshaler = marshaler; + this.exportAsJson = exportAsJson; this.contentLength = contentLength; this.mediaType = mediaType; } @@ -183,8 +188,12 @@ public MediaType contentType() { } @Override - public void writeTo(BufferedSink bufferedSink) { - marshaler.accept(bufferedSink.outputStream()); + public void writeTo(BufferedSink bufferedSink) throws IOException { + if (exportAsJson) { + marshaler.writeJsonTo(bufferedSink.outputStream()); + } else { + marshaler.writeBinaryTo(bufferedSink.outputStream()); + } } } diff --git a/exporters/sender/okhttp/src/main/java/io/opentelemetry/exporter/sender/okhttp/internal/OkHttpHttpSenderProvider.java b/exporters/sender/okhttp/src/main/java/io/opentelemetry/exporter/sender/okhttp/internal/OkHttpHttpSenderProvider.java index d969a1ee23d..3acad86d038 100644 --- a/exporters/sender/okhttp/src/main/java/io/opentelemetry/exporter/sender/okhttp/internal/OkHttpHttpSenderProvider.java +++ b/exporters/sender/okhttp/src/main/java/io/opentelemetry/exporter/sender/okhttp/internal/OkHttpHttpSenderProvider.java @@ -29,6 +29,7 @@ public final class OkHttpHttpSenderProvider implements HttpSenderProvider { public HttpSender createSender( String endpoint, @Nullable Compressor compressor, + boolean exportAsJson, String contentType, long timeoutNanos, long connectTimeout, @@ -40,6 +41,7 @@ public HttpSender createSender( return new OkHttpHttpSender( endpoint, compressor, + exportAsJson, contentType, timeoutNanos, connectTimeout, diff --git a/exporters/sender/okhttp/src/test/java/io/opentelemetry/exporter/sender/okhttp/internal/AuthenticatingExporterTest.java b/exporters/sender/okhttp/src/test/java/io/opentelemetry/exporter/sender/okhttp/internal/AuthenticatingExporterTest.java index e1c948f550c..a028d9c085b 100644 --- a/exporters/sender/okhttp/src/test/java/io/opentelemetry/exporter/sender/okhttp/internal/AuthenticatingExporterTest.java +++ b/exporters/sender/okhttp/src/test/java/io/opentelemetry/exporter/sender/okhttp/internal/AuthenticatingExporterTest.java @@ -76,6 +76,7 @@ void export_giveup() { server.enqueue(HttpResponse.of(HttpStatus.UNAUTHORIZED)); return Collections.emptyMap(); }) + .exportAsJson() .build(); server.enqueue(HttpResponse.of(HttpStatus.UNAUTHORIZED)); assertThat(exporter.export(marshaler, 0).join(1, TimeUnit.MINUTES).isSuccess()).isFalse(); diff --git a/exporters/sender/okhttp/src/test/java/io/opentelemetry/exporter/sender/okhttp/internal/OkHttpHttpSuppressionTest.java b/exporters/sender/okhttp/src/test/java/io/opentelemetry/exporter/sender/okhttp/internal/OkHttpHttpSuppressionTest.java index 0227826d4cd..046dbee521a 100644 --- a/exporters/sender/okhttp/src/test/java/io/opentelemetry/exporter/sender/okhttp/internal/OkHttpHttpSuppressionTest.java +++ b/exporters/sender/okhttp/src/test/java/io/opentelemetry/exporter/sender/okhttp/internal/OkHttpHttpSuppressionTest.java @@ -5,35 +5,47 @@ package io.opentelemetry.exporter.sender.okhttp.internal; +import io.opentelemetry.exporter.internal.marshal.Marshaler; +import io.opentelemetry.exporter.internal.marshal.ProtoFieldInfo; +import io.opentelemetry.exporter.internal.marshal.Serializer; import java.io.IOException; -import java.io.OutputStream; import java.nio.charset.StandardCharsets; import java.util.Collections; -import java.util.function.Consumer; class OkHttpHttpSuppressionTest extends AbstractOkHttpSuppressionTest { @Override void send(OkHttpHttpSender sender, Runnable onSuccess, Runnable onFailure) { byte[] content = "A".getBytes(StandardCharsets.UTF_8); - Consumer outputStreamConsumer = - outputStream -> { - try { - outputStream.write(content); - } catch (IOException e) { - throw new RuntimeException(e); + Marshaler marshaler = + new Marshaler() { + @Override + public int getBinarySerializedSize() { + return content.length; + } + + @Override + protected void writeTo(Serializer output) throws IOException { + output.serializeBytes(ProtoFieldInfo.create(1, 1, "field"), content); } }; sender.send( - outputStreamConsumer, - content.length, - (response) -> onSuccess.run(), - (error) -> onFailure.run()); + marshaler, content.length, (response) -> onSuccess.run(), (error) -> onFailure.run()); } @Override OkHttpHttpSender createSender(String endpoint) { return new OkHttpHttpSender( - endpoint, null, "text/plain", 10L, 10L, Collections::emptyMap, null, null, null, null); + endpoint, + null, + false, + "text/plain", + 10L, + 10L, + Collections::emptyMap, + null, + null, + null, + null); } } From da7796b3b53a550a632bf206cc3da0d42c05b680 Mon Sep 17 00:00:00 2001 From: jack-berg <34418638+jack-berg@users.noreply.github.com> Date: Thu, 4 Jan 2024 09:36:03 -0600 Subject: [PATCH 181/901] Use minimal fallback managed channel when none is specified (#6110) --- .../otlp/trace/OltpExporterBenchmark.java | 1 + .../AbstractGrpcTelemetryExporterTest.java | 21 ++++++++++++ ...anagedChannelTelemetryExporterBuilder.java | 21 +++++++----- .../internal/UpstreamGrpcSender.java | 10 +++++- .../internal/UpstreamGrpcSenderProvider.java | 32 ++++++++++++++++++- 5 files changed, 75 insertions(+), 10 deletions(-) diff --git a/exporters/otlp/all/src/jmh/java/io/opentelemetry/exporter/otlp/trace/OltpExporterBenchmark.java b/exporters/otlp/all/src/jmh/java/io/opentelemetry/exporter/otlp/trace/OltpExporterBenchmark.java index 1ad124271a3..ef620333474 100644 --- a/exporters/otlp/all/src/jmh/java/io/opentelemetry/exporter/otlp/trace/OltpExporterBenchmark.java +++ b/exporters/otlp/all/src/jmh/java/io/opentelemetry/exporter/otlp/trace/OltpExporterBenchmark.java @@ -85,6 +85,7 @@ public void setUp() { "span", new UpstreamGrpcSender<>( MarshalerTraceServiceGrpc.newFutureStub(defaultGrpcChannel, null), + /* shutdownChannel= */ false, 10, Collections::emptyMap), MeterProvider::noop); diff --git a/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/AbstractGrpcTelemetryExporterTest.java b/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/AbstractGrpcTelemetryExporterTest.java index c2490029aac..0b3d79a2690 100644 --- a/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/AbstractGrpcTelemetryExporterTest.java +++ b/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/AbstractGrpcTelemetryExporterTest.java @@ -5,6 +5,7 @@ package io.opentelemetry.exporter.otlp.testing.internal; +import static org.assertj.core.api.Assertions.as; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatCode; import static org.assertj.core.api.Assertions.assertThatThrownBy; @@ -23,8 +24,10 @@ import com.linecorp.armeria.testing.junit5.server.SelfSignedCertificateExtension; import com.linecorp.armeria.testing.junit5.server.ServerExtension; import io.github.netmikey.logunit.api.LogCapturer; +import io.grpc.ManagedChannel; import io.opentelemetry.exporter.internal.TlsUtil; import io.opentelemetry.exporter.internal.grpc.GrpcExporter; +import io.opentelemetry.exporter.internal.grpc.MarshalerServiceStub; import io.opentelemetry.exporter.internal.marshal.Marshaler; import io.opentelemetry.internal.testing.slf4j.SuppressLogger; import io.opentelemetry.proto.collector.logs.v1.ExportLogsServiceRequest; @@ -61,6 +64,7 @@ import javax.net.ssl.TrustManager; import javax.net.ssl.X509KeyManager; import javax.net.ssl.X509TrustManager; +import org.assertj.core.api.InstanceOfAssertFactories; import org.assertj.core.api.iterable.ThrowingExtractor; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.AfterEach; @@ -215,6 +219,23 @@ void reset() { httpRequests.clear(); } + @Test + void minimalChannel() { + // Test that UpstreamGrpcSender uses minimal fallback managed channel, so skip for + // OkHttpGrpcSender + assumeThat(exporter.unwrap()) + .extracting("delegate.grpcSender") + .matches(sender -> sender.getClass().getSimpleName().equals("UpstreamGrpcSender")); + // When no channel is explicitly set, should fall back to a minimally configured managed channel + TelemetryExporter exporter = exporterBuilder().build(); + assertThat(exporter.shutdown().join(10, TimeUnit.SECONDS).isSuccess()).isTrue(); + assertThat(exporter.unwrap()) + .extracting( + "delegate.grpcSender.stub", + as(InstanceOfAssertFactories.type(MarshalerServiceStub.class))) + .satisfies(stub -> assertThat(((ManagedChannel) stub.getChannel()).isShutdown()).isTrue()); + } + @Test void export() { List telemetry = Collections.singletonList(generateFakeTelemetry()); diff --git a/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/ManagedChannelTelemetryExporterBuilder.java b/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/ManagedChannelTelemetryExporterBuilder.java index be7d97b9678..e5545aa41bd 100644 --- a/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/ManagedChannelTelemetryExporterBuilder.java +++ b/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/ManagedChannelTelemetryExporterBuilder.java @@ -158,16 +158,21 @@ public TelemetryExporterBuilder setChannel(Object channel) { @Override public TelemetryExporter build() { - requireNonNull(channelBuilder, "channel"); + Runnable shutdownCallback; + if (channelBuilder != null) { + try { + setSslContext(channelBuilder, tlsConfigHelper); + } catch (SSLException e) { + throw new IllegalStateException(e); + } - try { - setSslContext(channelBuilder, tlsConfigHelper); - } catch (SSLException e) { - throw new IllegalStateException(e); + ManagedChannel channel = channelBuilder.build(); + delegate.setChannel(channel); + shutdownCallback = channel::shutdownNow; + } else { + shutdownCallback = () -> {}; } - ManagedChannel channel = channelBuilder.build(); - delegate.setChannel(channel); TelemetryExporter delegateExporter = delegate.build(); return new TelemetryExporter() { @Override @@ -182,7 +187,7 @@ public CompletableResultCode export(Collection items) { @Override public CompletableResultCode shutdown() { - channel.shutdownNow(); + shutdownCallback.run(); return delegateExporter.shutdown(); } }; diff --git a/exporters/sender/grpc-managed-channel/src/main/java/io/opentelemetry/exporter/sender/grpc/managedchannel/internal/UpstreamGrpcSender.java b/exporters/sender/grpc-managed-channel/src/main/java/io/opentelemetry/exporter/sender/grpc/managedchannel/internal/UpstreamGrpcSender.java index 28f813accc7..f8fa234e4e6 100644 --- a/exporters/sender/grpc-managed-channel/src/main/java/io/opentelemetry/exporter/sender/grpc/managedchannel/internal/UpstreamGrpcSender.java +++ b/exporters/sender/grpc-managed-channel/src/main/java/io/opentelemetry/exporter/sender/grpc/managedchannel/internal/UpstreamGrpcSender.java @@ -8,6 +8,7 @@ import com.google.common.util.concurrent.FutureCallback; import com.google.common.util.concurrent.Futures; import com.google.common.util.concurrent.MoreExecutors; +import io.grpc.ManagedChannel; import io.grpc.Metadata; import io.grpc.Status; import io.grpc.stub.MetadataUtils; @@ -32,16 +33,19 @@ public final class UpstreamGrpcSender implements GrpcSender { private final MarshalerServiceStub stub; + private final boolean shutdownChannel; private final long timeoutNanos; private final Supplier>> headersSupplier; /** Creates a new {@link UpstreamGrpcSender}. */ public UpstreamGrpcSender( MarshalerServiceStub stub, + boolean shutdownChannel, long timeoutNanos, Supplier>> headersSupplier) { - this.timeoutNanos = timeoutNanos; this.stub = stub; + this.shutdownChannel = shutdownChannel; + this.timeoutNanos = timeoutNanos; this.headersSupplier = headersSupplier; } @@ -82,6 +86,10 @@ public void onFailure(Throwable t) { @Override public CompletableResultCode shutdown() { + if (shutdownChannel) { + ManagedChannel channel = (ManagedChannel) stub.getChannel(); + channel.shutdownNow(); + } return CompletableResultCode.ofSuccess(); } } diff --git a/exporters/sender/grpc-managed-channel/src/main/java/io/opentelemetry/exporter/sender/grpc/managedchannel/internal/UpstreamGrpcSenderProvider.java b/exporters/sender/grpc-managed-channel/src/main/java/io/opentelemetry/exporter/sender/grpc/managedchannel/internal/UpstreamGrpcSenderProvider.java index 34200681980..a4effdbd09c 100644 --- a/exporters/sender/grpc-managed-channel/src/main/java/io/opentelemetry/exporter/sender/grpc/managedchannel/internal/UpstreamGrpcSenderProvider.java +++ b/exporters/sender/grpc-managed-channel/src/main/java/io/opentelemetry/exporter/sender/grpc/managedchannel/internal/UpstreamGrpcSenderProvider.java @@ -7,6 +7,8 @@ import io.grpc.Channel; import io.grpc.Codec; +import io.grpc.ManagedChannel; +import io.grpc.ManagedChannelBuilder; import io.opentelemetry.exporter.internal.grpc.GrpcSender; import io.opentelemetry.exporter.internal.grpc.GrpcSenderProvider; import io.opentelemetry.exporter.internal.grpc.MarshalerServiceStub; @@ -41,6 +43,13 @@ public GrpcSender createSender( @Nullable RetryPolicy retryPolicy, @Nullable SSLContext sslContext, @Nullable X509TrustManager trustManager) { + boolean shutdownChannel = false; + if (managedChannel == null) { + // Shutdown the channel as part of the exporter shutdown sequence if + shutdownChannel = true; + managedChannel = minimalFallbackManagedChannel(endpoint); + } + String authorityOverride = null; Map> headers = headersSupplier.get(); if (headers != null) { @@ -58,6 +67,27 @@ public GrpcSender createSender( .apply((Channel) managedChannel, authorityOverride) .withCompression(codec.getMessageEncoding()); - return new UpstreamGrpcSender<>(stub, timeoutNanos, headersSupplier); + return new UpstreamGrpcSender<>(stub, shutdownChannel, timeoutNanos, headersSupplier); + } + + /** + * If {@link ManagedChannel} is not explicitly set, provide a minimally configured fallback + * channel to avoid failing initialization. + * + *

    This is required to accommodate autoconfigure with {@code + * opentelemetry-exporter-sender-grpc-managed-channel} which will always fail to initialize + * without a fallback channel since there isn't an opportunity to explicitly set the channel. + * + *

    This only incorporates the target address, port, and whether to use plain text. All + * additional settings are intentionally ignored and must be configured with an explicitly set + * {@link ManagedChannel}. + */ + private static ManagedChannel minimalFallbackManagedChannel(URI endpoint) { + ManagedChannelBuilder channelBuilder = + ManagedChannelBuilder.forAddress(endpoint.getHost(), endpoint.getPort()); + if (!endpoint.getScheme().equals("https")) { + channelBuilder.usePlaintext(); + } + return channelBuilder.build(); } } From 5a0dd7ef25039e1cf37c6a66fe19d6751c74bfe2 Mon Sep 17 00:00:00 2001 From: jack-berg <34418638+jack-berg@users.noreply.github.com> Date: Thu, 4 Jan 2024 11:43:23 -0600 Subject: [PATCH 182/901] Base2ExponentialHistogramAggregation maxBuckets must be >= 2 (#6093) --- .../fileconfig/AggregationFactoryTest.java | 4 +- .../Base2ExponentialHistogramAggregation.java | 2 +- .../sdk/metrics/AggregationTest.java | 4 +- ...e2ExponentialHistogramAggregationTest.java | 44 +++++++++++++++++-- 4 files changed, 46 insertions(+), 8 deletions(-) diff --git a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/AggregationFactoryTest.java b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/AggregationFactoryTest.java index 62c5e457606..1f0c6faf5ca 100644 --- a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/AggregationFactoryTest.java +++ b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/AggregationFactoryTest.java @@ -62,8 +62,8 @@ private static Stream createTestCases() { Arguments.of( new Aggregation() .withBase2ExponentialBucketHistogram( - new Base2ExponentialBucketHistogram().withMaxSize(1).withMaxScale(2)), - io.opentelemetry.sdk.metrics.Aggregation.base2ExponentialBucketHistogram(1, 2)), + new Base2ExponentialBucketHistogram().withMaxSize(2).withMaxScale(2)), + io.opentelemetry.sdk.metrics.Aggregation.base2ExponentialBucketHistogram(2, 2)), Arguments.of( new Aggregation() .withExplicitBucketHistogram(new ExplicitBucketHistogram().withBoundaries(null)), diff --git a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/view/Base2ExponentialHistogramAggregation.java b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/view/Base2ExponentialHistogramAggregation.java index a0408bc32fd..f0fdbb5fba5 100644 --- a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/view/Base2ExponentialHistogramAggregation.java +++ b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/view/Base2ExponentialHistogramAggregation.java @@ -58,7 +58,7 @@ public static Aggregation getDefault() { * @return the aggregation */ public static Aggregation create(int maxBuckets, int maxScale) { - checkArgument(maxBuckets >= 1, "maxBuckets must be > 0"); + checkArgument(maxBuckets >= 2, "maxBuckets must be >= 2"); checkArgument(maxScale <= 20 && maxScale >= -10, "maxScale must be -10 <= x <= 20"); return new Base2ExponentialHistogramAggregation(maxBuckets, maxScale); } diff --git a/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/AggregationTest.java b/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/AggregationTest.java index 544eded9b84..7606b321c9a 100644 --- a/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/AggregationTest.java +++ b/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/AggregationTest.java @@ -31,9 +31,9 @@ void haveToString() { assertThat(Aggregation.base2ExponentialBucketHistogram()) .asString() .isEqualTo("Base2ExponentialHistogramAggregation{maxBuckets=160,maxScale=20}"); - assertThat(Aggregation.base2ExponentialBucketHistogram(1, 0)) + assertThat(Aggregation.base2ExponentialBucketHistogram(2, 0)) .asString() - .isEqualTo("Base2ExponentialHistogramAggregation{maxBuckets=1,maxScale=0}"); + .isEqualTo("Base2ExponentialHistogramAggregation{maxBuckets=2,maxScale=0}"); } @Test diff --git a/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/internal/view/Base2ExponentialHistogramAggregationTest.java b/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/internal/view/Base2ExponentialHistogramAggregationTest.java index f6f44e9c72c..1d02a33619d 100644 --- a/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/internal/view/Base2ExponentialHistogramAggregationTest.java +++ b/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/internal/view/Base2ExponentialHistogramAggregationTest.java @@ -8,6 +8,18 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; +import io.opentelemetry.api.common.Attributes; +import io.opentelemetry.sdk.metrics.Aggregation; +import io.opentelemetry.sdk.metrics.InstrumentType; +import io.opentelemetry.sdk.metrics.InstrumentValueType; +import io.opentelemetry.sdk.metrics.data.ExemplarData; +import io.opentelemetry.sdk.metrics.data.ExponentialHistogramPointData; +import io.opentelemetry.sdk.metrics.internal.aggregator.Aggregator; +import io.opentelemetry.sdk.metrics.internal.aggregator.AggregatorFactory; +import io.opentelemetry.sdk.metrics.internal.aggregator.AggregatorHandle; +import io.opentelemetry.sdk.metrics.internal.descriptor.Advice; +import io.opentelemetry.sdk.metrics.internal.descriptor.InstrumentDescriptor; +import io.opentelemetry.sdk.metrics.internal.exemplar.ExemplarFilter; import org.junit.jupiter.api.Test; class Base2ExponentialHistogramAggregationTest { @@ -22,12 +34,38 @@ void goodConfig() { void invalidConfig_Throws() { assertThatThrownBy(() -> Base2ExponentialHistogramAggregation.create(0, 20)) .isInstanceOf(IllegalArgumentException.class) - .hasMessage("maxBuckets must be > 0"); - assertThatThrownBy(() -> Base2ExponentialHistogramAggregation.create(1, 21)) + .hasMessage("maxBuckets must be >= 2"); + assertThatThrownBy(() -> Base2ExponentialHistogramAggregation.create(2, 21)) .isInstanceOf(IllegalArgumentException.class) .hasMessage("maxScale must be -10 <= x <= 20"); - assertThatThrownBy(() -> Base2ExponentialHistogramAggregation.create(1, -11)) + assertThatThrownBy(() -> Base2ExponentialHistogramAggregation.create(2, -11)) .isInstanceOf(IllegalArgumentException.class) .hasMessage("maxScale must be -10 <= x <= 20"); } + + @Test + void minimumBucketsCanAccommodateMaxRange() { + Aggregation aggregation = Base2ExponentialHistogramAggregation.create(2, 20); + Aggregator aggregator = + ((AggregatorFactory) aggregation) + .createAggregator( + InstrumentDescriptor.create( + "foo", + "description", + "unit", + InstrumentType.HISTOGRAM, + InstrumentValueType.DOUBLE, + Advice.empty()), + ExemplarFilter.alwaysOff()); + AggregatorHandle handle = + aggregator.createHandle(); + // Record max range + handle.recordDouble(Double.MIN_VALUE); + handle.recordDouble(Double.MAX_VALUE); + + ExponentialHistogramPointData pointData = + handle.aggregateThenMaybeReset(0, 1, Attributes.empty(), /* reset= */ true); + assertThat(pointData.getCount()).isEqualTo(2); + assertThat(pointData.getScale()).isEqualTo(-11); + } } From 3449c58ef588a2bec990d449bb378dea310eed68 Mon Sep 17 00:00:00 2001 From: jack-berg <34418638+jack-berg@users.noreply.github.com> Date: Thu, 4 Jan 2024 11:43:42 -0600 Subject: [PATCH 183/901] Convert histogram measurements to double before passing recording exemplar reservoir (#6024) Co-authored-by: Trask Stalnaker --- .../internal/exemplar/ExemplarReservoir.java | 14 +++ .../LongToDoubleExemplarReservoir.java | 35 +++++++ .../Base2ExponentialHistogramAggregation.java | 9 +- .../ExplicitBucketHistogramAggregation.java | 5 +- .../sdk/metrics/SdkDoubleHistogramTest.java | 95 +++++++++++++++++++ .../sdk/metrics/SdkLongHistogramTest.java | 95 +++++++++++++++++++ .../LongToDoubleExemplarReservoirTest.java | 39 ++++++++ 7 files changed, 286 insertions(+), 6 deletions(-) create mode 100644 sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/exemplar/LongToDoubleExemplarReservoir.java create mode 100644 sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/internal/exemplar/LongToDoubleExemplarReservoirTest.java diff --git a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/exemplar/ExemplarReservoir.java b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/exemplar/ExemplarReservoir.java index cebd4683fbb..c0de6e0df6a 100644 --- a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/exemplar/ExemplarReservoir.java +++ b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/exemplar/ExemplarReservoir.java @@ -8,6 +8,7 @@ import io.opentelemetry.api.common.Attributes; import io.opentelemetry.context.Context; import io.opentelemetry.sdk.common.Clock; +import io.opentelemetry.sdk.metrics.Aggregation; import io.opentelemetry.sdk.metrics.data.DoubleExemplarData; import io.opentelemetry.sdk.metrics.data.ExemplarData; import io.opentelemetry.sdk.metrics.data.LongExemplarData; @@ -25,6 +26,19 @@ */ public interface ExemplarReservoir { + /** + * Wraps an {@link ExemplarReservoir}, casting calls from {@link + * ExemplarReservoir#offerLongMeasurement(long, Attributes, Context)} to {@link + * ExemplarReservoir#offerDoubleMeasurement(double, Attributes, Context)} such that {@link + * ExemplarReservoir#collectAndReset(Attributes)} only returns {@link DoubleExemplarData}. + * + *

    This is used for {@link Aggregation#explicitBucketHistogram()} and {@link + * Aggregation#base2ExponentialBucketHistogram()} which only support double measurements. + */ + static ExemplarReservoir longToDouble(ExemplarReservoir delegate) { + return new LongToDoubleExemplarReservoir<>(delegate); + } + /** Wraps a {@link ExemplarReservoir} with a measurement pre-filter. */ static ExemplarReservoir filtered( ExemplarFilter filter, ExemplarReservoir original) { diff --git a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/exemplar/LongToDoubleExemplarReservoir.java b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/exemplar/LongToDoubleExemplarReservoir.java new file mode 100644 index 00000000000..c3a6b98fced --- /dev/null +++ b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/exemplar/LongToDoubleExemplarReservoir.java @@ -0,0 +1,35 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.sdk.metrics.internal.exemplar; + +import io.opentelemetry.api.common.Attributes; +import io.opentelemetry.context.Context; +import io.opentelemetry.sdk.metrics.data.ExemplarData; +import java.util.List; + +class LongToDoubleExemplarReservoir implements ExemplarReservoir { + + private final ExemplarReservoir delegate; + + LongToDoubleExemplarReservoir(ExemplarReservoir delegate) { + this.delegate = delegate; + } + + @Override + public void offerDoubleMeasurement(double value, Attributes attributes, Context context) { + delegate.offerDoubleMeasurement(value, attributes, context); + } + + @Override + public void offerLongMeasurement(long value, Attributes attributes, Context context) { + offerDoubleMeasurement((double) value, attributes, context); + } + + @Override + public List collectAndReset(Attributes pointAttributes) { + return delegate.collectAndReset(pointAttributes); + } +} diff --git a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/view/Base2ExponentialHistogramAggregation.java b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/view/Base2ExponentialHistogramAggregation.java index f0fdbb5fba5..287ff589ea6 100644 --- a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/view/Base2ExponentialHistogramAggregation.java +++ b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/view/Base2ExponentialHistogramAggregation.java @@ -72,10 +72,11 @@ public Aggregator createAggr () -> ExemplarReservoir.filtered( exemplarFilter, - ExemplarReservoir.doubleFixedSizeReservoir( - Clock.getDefault(), - Runtime.getRuntime().availableProcessors(), - RandomSupplier.platformDefault())), + ExemplarReservoir.longToDouble( + ExemplarReservoir.doubleFixedSizeReservoir( + Clock.getDefault(), + Runtime.getRuntime().availableProcessors(), + RandomSupplier.platformDefault()))), maxBuckets, maxScale); } diff --git a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/view/ExplicitBucketHistogramAggregation.java b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/view/ExplicitBucketHistogramAggregation.java index 1ec3867dc7e..1ad32b698ba 100644 --- a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/view/ExplicitBucketHistogramAggregation.java +++ b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/view/ExplicitBucketHistogramAggregation.java @@ -57,8 +57,9 @@ public Aggregator createAggr () -> ExemplarReservoir.filtered( exemplarFilter, - ExemplarReservoir.histogramBucketReservoir( - Clock.getDefault(), bucketBoundaries))); + ExemplarReservoir.longToDouble( + ExemplarReservoir.histogramBucketReservoir( + Clock.getDefault(), bucketBoundaries)))); } @Override diff --git a/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/SdkDoubleHistogramTest.java b/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/SdkDoubleHistogramTest.java index dd060736ed6..dd210faad46 100644 --- a/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/SdkDoubleHistogramTest.java +++ b/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/SdkDoubleHistogramTest.java @@ -14,12 +14,16 @@ import io.opentelemetry.api.common.Attributes; import io.opentelemetry.api.metrics.DoubleHistogram; import io.opentelemetry.api.metrics.Meter; +import io.opentelemetry.api.trace.Span; +import io.opentelemetry.api.trace.Tracer; +import io.opentelemetry.context.Scope; import io.opentelemetry.internal.testing.slf4j.SuppressLogger; import io.opentelemetry.sdk.common.InstrumentationScopeInfo; import io.opentelemetry.sdk.metrics.internal.state.DefaultSynchronousMetricStorage; import io.opentelemetry.sdk.resources.Resource; import io.opentelemetry.sdk.testing.exporter.InMemoryMetricReader; import io.opentelemetry.sdk.testing.time.TestClock; +import io.opentelemetry.sdk.trace.SdkTracerProvider; import java.time.Duration; import java.util.Arrays; import java.util.Collections; @@ -275,6 +279,97 @@ void doubleHistogramRecord_NaN() { assertThat(sdkMeterReader.collectAllMetrics()).hasSize(0); } + @Test + void collectMetrics_ExemplarsWithExponentialHistogram() { + InMemoryMetricReader reader = InMemoryMetricReader.create(); + SdkMeterProvider sdkMeterProvider = + SdkMeterProvider.builder() + .setClock(testClock) + .setResource(RESOURCE) + .registerView( + InstrumentSelector.builder().setType(InstrumentType.HISTOGRAM).build(), + View.builder() + .setAggregation(Aggregation.base2ExponentialBucketHistogram()) + .setAttributeFilter(Collections.emptySet()) + .build()) + .registerMetricReader(reader) + .build(); + Meter sdkMeter = sdkMeterProvider.get(getClass().getName()); + DoubleHistogram histogram = sdkMeter.histogramBuilder("testHistogram").build(); + + SdkTracerProvider tracerProvider = SdkTracerProvider.builder().build(); + Tracer tracer = tracerProvider.get("foo"); + + Span span = tracer.spanBuilder("span").startSpan(); + try (Scope unused = span.makeCurrent()) { + histogram.record(10, Attributes.builder().put("key", "value").build()); + } + + assertThat(reader.collectAllMetrics()) + .satisfiesExactly( + metric -> + assertThat(metric) + .hasExponentialHistogramSatisfying( + exponentialHistogram -> + exponentialHistogram.hasPointsSatisfying( + point -> + point + .hasSum(10.0) + .hasAttributes(Attributes.empty()) + .hasExemplarsSatisfying( + exemplar -> + exemplar + .hasValue(10.0) + .hasFilteredAttributes( + Attributes.builder() + .put("key", "value") + .build()))))); + } + + @Test + void collectMetrics_ExemplarsWithExplicitBucketHistogram() { + InMemoryMetricReader reader = InMemoryMetricReader.create(); + SdkMeterProvider sdkMeterProvider = + SdkMeterProvider.builder() + .setClock(testClock) + .setResource(RESOURCE) + .registerView( + InstrumentSelector.builder().setName("*").build(), + View.builder().setAttributeFilter(Collections.emptySet()).build()) + .registerMetricReader(reader) + .build(); + Meter sdkMeter = sdkMeterProvider.get(getClass().getName()); + DoubleHistogram histogram = sdkMeter.histogramBuilder("testHistogram").build(); + + SdkTracerProvider tracerProvider = SdkTracerProvider.builder().build(); + Tracer tracer = tracerProvider.get("foo"); + + Span span = tracer.spanBuilder("span").startSpan(); + try (Scope unused = span.makeCurrent()) { + histogram.record(10, Attributes.builder().put("key", "value").build()); + } + + assertThat(reader.collectAllMetrics()) + .satisfiesExactly( + metric -> + assertThat(metric) + .hasHistogramSatisfying( + explicitHistogram -> + explicitHistogram.hasPointsSatisfying( + point -> + point + .hasSum(10) + .hasAttributes(Attributes.empty()) + .hasExemplarsSatisfying( + exemplar -> + exemplar + .hasValue(10.0) + .hasFilteredAttributes( + Attributes.builder() + .put("key", "value") + .build()))))); + } + @Test void stressTest() { DoubleHistogram doubleHistogram = sdkMeter.histogramBuilder("testHistogram").build(); diff --git a/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/SdkLongHistogramTest.java b/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/SdkLongHistogramTest.java index 09e33faf2cc..dd802ff613f 100644 --- a/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/SdkLongHistogramTest.java +++ b/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/SdkLongHistogramTest.java @@ -14,11 +14,15 @@ import io.opentelemetry.api.common.Attributes; import io.opentelemetry.api.metrics.LongHistogram; import io.opentelemetry.api.metrics.Meter; +import io.opentelemetry.api.trace.Span; +import io.opentelemetry.api.trace.Tracer; +import io.opentelemetry.context.Scope; import io.opentelemetry.internal.testing.slf4j.SuppressLogger; import io.opentelemetry.sdk.common.InstrumentationScopeInfo; import io.opentelemetry.sdk.resources.Resource; import io.opentelemetry.sdk.testing.exporter.InMemoryMetricReader; import io.opentelemetry.sdk.testing.time.TestClock; +import io.opentelemetry.sdk.trace.SdkTracerProvider; import java.time.Duration; import java.util.Arrays; import java.util.Collections; @@ -435,6 +439,97 @@ void longHistogramRecord_NonNegativeCheck() { "Histograms can only record non-negative values. Instrument testHistogram has recorded a negative value."); } + @Test + void collectMetrics_ExemplarsWithExponentialHistogram() { + InMemoryMetricReader reader = InMemoryMetricReader.create(); + SdkMeterProvider sdkMeterProvider = + SdkMeterProvider.builder() + .setClock(testClock) + .setResource(RESOURCE) + .registerView( + InstrumentSelector.builder().setType(InstrumentType.HISTOGRAM).build(), + View.builder() + .setAggregation(Aggregation.base2ExponentialBucketHistogram()) + .setAttributeFilter(Collections.emptySet()) + .build()) + .registerMetricReader(reader) + .build(); + Meter sdkMeter = sdkMeterProvider.get(getClass().getName()); + LongHistogram histogram = sdkMeter.histogramBuilder("testHistogram").ofLongs().build(); + + SdkTracerProvider tracerProvider = SdkTracerProvider.builder().build(); + Tracer tracer = tracerProvider.get("foo"); + + Span span = tracer.spanBuilder("span").startSpan(); + try (Scope unused = span.makeCurrent()) { + histogram.record(10, Attributes.builder().put("key", "value").build()); + } + + assertThat(reader.collectAllMetrics()) + .satisfiesExactly( + metric -> + assertThat(metric) + .hasExponentialHistogramSatisfying( + exponentialHistogram -> + exponentialHistogram.hasPointsSatisfying( + point -> + point + .hasSum(10.0) + .hasAttributes(Attributes.empty()) + .hasExemplarsSatisfying( + exemplar -> + exemplar + .hasValue(10.0) + .hasFilteredAttributes( + Attributes.builder() + .put("key", "value") + .build()))))); + } + + @Test + void collectMetrics_ExemplarsWithExplicitBucketHistogram() { + InMemoryMetricReader reader = InMemoryMetricReader.create(); + SdkMeterProvider sdkMeterProvider = + SdkMeterProvider.builder() + .setClock(testClock) + .setResource(RESOURCE) + .registerView( + InstrumentSelector.builder().setName("*").build(), + View.builder().setAttributeFilter(Collections.emptySet()).build()) + .registerMetricReader(reader) + .build(); + Meter sdkMeter = sdkMeterProvider.get(getClass().getName()); + LongHistogram histogram = sdkMeter.histogramBuilder("testHistogram").ofLongs().build(); + + SdkTracerProvider tracerProvider = SdkTracerProvider.builder().build(); + Tracer tracer = tracerProvider.get("foo"); + + Span span = tracer.spanBuilder("span").startSpan(); + try (Scope unused = span.makeCurrent()) { + histogram.record(10, Attributes.builder().put("key", "value").build()); + } + + assertThat(reader.collectAllMetrics()) + .satisfiesExactly( + metric -> + assertThat(metric) + .hasHistogramSatisfying( + explicitHistogram -> + explicitHistogram.hasPointsSatisfying( + point -> + point + .hasSum(10) + .hasAttributes(Attributes.empty()) + .hasExemplarsSatisfying( + exemplar -> + exemplar + .hasValue(10.0) + .hasFilteredAttributes( + Attributes.builder() + .put("key", "value") + .build()))))); + } + @Test void stressTest() { LongHistogram longHistogram = sdkMeter.histogramBuilder("testHistogram").ofLongs().build(); diff --git a/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/internal/exemplar/LongToDoubleExemplarReservoirTest.java b/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/internal/exemplar/LongToDoubleExemplarReservoirTest.java new file mode 100644 index 00000000000..fc7a5a3c07a --- /dev/null +++ b/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/internal/exemplar/LongToDoubleExemplarReservoirTest.java @@ -0,0 +1,39 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.sdk.metrics.internal.exemplar; + +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyLong; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.verify; + +import io.opentelemetry.api.common.Attributes; +import io.opentelemetry.context.Context; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; + +@ExtendWith(MockitoExtension.class) +class LongToDoubleExemplarReservoirTest { + @Mock ExemplarReservoir delegate; + + @Test + void offerDoubleMeasurement() { + ExemplarReservoir filtered = new LongToDoubleExemplarReservoir<>(delegate); + filtered.offerDoubleMeasurement(1.0, Attributes.empty(), Context.root()); + verify(delegate).offerDoubleMeasurement(1.0, Attributes.empty(), Context.root()); + verify(delegate, never()).offerLongMeasurement(anyLong(), any(), any()); + } + + @Test + void offerLongMeasurement() { + ExemplarReservoir filtered = new LongToDoubleExemplarReservoir<>(delegate); + filtered.offerLongMeasurement(1L, Attributes.empty(), Context.root()); + verify(delegate).offerDoubleMeasurement(1.0, Attributes.empty(), Context.root()); + verify(delegate, never()).offerLongMeasurement(anyLong(), any(), any()); + } +} From f4b5bbe8293c0631c9b9de5540f6550dab6c9491 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 4 Jan 2024 13:01:04 -0600 Subject: [PATCH 184/901] Update dependency org.assertj:assertj-bom to v3.25.1 (#6106) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- dependencyManagement/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index 598de3a7ae0..eb8501ba9a9 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -18,7 +18,7 @@ val DEPENDENCY_BOMS = listOf( "io.netty:netty-bom:4.1.104.Final", "io.zipkin.brave:brave-bom:5.17.0", "io.zipkin.reporter2:zipkin-reporter-bom:2.17.1", - "org.assertj:assertj-bom:3.25.0", + "org.assertj:assertj-bom:3.25.1", "org.junit:junit-bom:5.10.1", "org.testcontainers:testcontainers-bom:1.19.3", "org.snakeyaml:snakeyaml-engine:2.7" From 07351a2e9f20ba4e47fd60b71015966263da384d Mon Sep 17 00:00:00 2001 From: HaloFour Date: Thu, 4 Jan 2024 15:33:30 -0500 Subject: [PATCH 185/901] Add option to export unsampled spans from span processors (#6057) Co-authored-by: jack-berg <34418638+jack-berg@users.noreply.github.com> --- .../opentelemetry-sdk-trace.txt | 12 ++- .../sdk/OpenTelemetrySdkTest.java | 2 +- .../sdk/trace/export/BatchSpanProcessor.java | 10 ++- .../export/BatchSpanProcessorBuilder.java | 11 +++ .../sdk/trace/export/SimpleSpanProcessor.java | 51 ++++++----- .../export/SimpleSpanProcessorBuilder.java | 36 ++++++++ .../trace/export/BatchSpanProcessorTest.java | 33 +++++++ .../trace/export/SimpleSpanProcessorTest.java | 89 ++++++++++++------- 8 files changed, 185 insertions(+), 59 deletions(-) create mode 100644 sdk/trace/src/main/java/io/opentelemetry/sdk/trace/export/SimpleSpanProcessorBuilder.java diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-trace.txt b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-trace.txt index df26146497b..f03b01723c1 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-trace.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-trace.txt @@ -1,2 +1,12 @@ Comparing source compatibility of against -No changes. \ No newline at end of file +*** MODIFIED CLASS: PUBLIC FINAL io.opentelemetry.sdk.trace.export.BatchSpanProcessorBuilder (not serializable) + === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 + +++ NEW METHOD: PUBLIC(+) io.opentelemetry.sdk.trace.export.BatchSpanProcessorBuilder setExportUnsampledSpans(boolean) +*** MODIFIED CLASS: PUBLIC FINAL io.opentelemetry.sdk.trace.export.SimpleSpanProcessor (not serializable) + === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 + +++ NEW METHOD: PUBLIC(+) STATIC(+) io.opentelemetry.sdk.trace.export.SimpleSpanProcessorBuilder builder(io.opentelemetry.sdk.trace.export.SpanExporter) ++++ NEW CLASS: PUBLIC(+) FINAL(+) io.opentelemetry.sdk.trace.export.SimpleSpanProcessorBuilder (not serializable) + +++ CLASS FILE FORMAT VERSION: 52.0 <- n.a. + +++ NEW SUPERCLASS: java.lang.Object + +++ NEW METHOD: PUBLIC(+) io.opentelemetry.sdk.trace.export.SimpleSpanProcessor build() + +++ NEW METHOD: PUBLIC(+) io.opentelemetry.sdk.trace.export.SimpleSpanProcessorBuilder setExportUnsampledSpans(boolean) diff --git a/sdk/all/src/test/java/io/opentelemetry/sdk/OpenTelemetrySdkTest.java b/sdk/all/src/test/java/io/opentelemetry/sdk/OpenTelemetrySdkTest.java index d3216fc9fa2..b6ee0aff2d4 100644 --- a/sdk/all/src/test/java/io/opentelemetry/sdk/OpenTelemetrySdkTest.java +++ b/sdk/all/src/test/java/io/opentelemetry/sdk/OpenTelemetrySdkTest.java @@ -415,7 +415,7 @@ void stringRepresentation() { + "resource=Resource{schemaUrl=null, attributes={service.name=\"otel-test\"}}, " + "spanLimitsSupplier=SpanLimitsValue{maxNumberOfAttributes=128, maxNumberOfEvents=128, maxNumberOfLinks=128, maxNumberOfAttributesPerEvent=128, maxNumberOfAttributesPerLink=128, maxAttributeValueLength=2147483647}, " + "sampler=ParentBased{root:AlwaysOnSampler,remoteParentSampled:AlwaysOnSampler,remoteParentNotSampled:AlwaysOffSampler,localParentSampled:AlwaysOnSampler,localParentNotSampled:AlwaysOffSampler}, " - + "spanProcessor=SimpleSpanProcessor{spanExporter=MultiSpanExporter{spanExporters=[MockSpanExporter{}, MockSpanExporter{}]}}" + + "spanProcessor=SimpleSpanProcessor{spanExporter=MultiSpanExporter{spanExporters=[MockSpanExporter{}, MockSpanExporter{}]}, exportUnsampledSpans=false}" + "}, " + "meterProvider=SdkMeterProvider{" + "clock=SystemClock{}, " diff --git a/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/export/BatchSpanProcessor.java b/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/export/BatchSpanProcessor.java index 126ef59c6c2..da0cf7d080c 100644 --- a/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/export/BatchSpanProcessor.java +++ b/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/export/BatchSpanProcessor.java @@ -53,6 +53,7 @@ public final class BatchSpanProcessor implements SpanProcessor { AttributeKey.booleanKey("dropped"); private static final String SPAN_PROCESSOR_TYPE_VALUE = BatchSpanProcessor.class.getSimpleName(); + private final boolean exportUnsampledSpans; private final Worker worker; private final AtomicBoolean isShutdown = new AtomicBoolean(false); @@ -69,11 +70,13 @@ public static BatchSpanProcessorBuilder builder(SpanExporter spanExporter) { BatchSpanProcessor( SpanExporter spanExporter, + boolean exportUnsampledSpans, MeterProvider meterProvider, long scheduleDelayNanos, int maxQueueSize, int maxExportBatchSize, long exporterTimeoutNanos) { + this.exportUnsampledSpans = exportUnsampledSpans; this.worker = new Worker( spanExporter, @@ -96,10 +99,9 @@ public boolean isStartRequired() { @Override public void onEnd(ReadableSpan span) { - if (span == null || !span.getSpanContext().isSampled()) { - return; + if (span != null && (exportUnsampledSpans || span.getSpanContext().isSampled())) { + worker.addSpan(span); } - worker.addSpan(span); } @Override @@ -135,6 +137,8 @@ public String toString() { return "BatchSpanProcessor{" + "spanExporter=" + worker.spanExporter + + ", exportUnsampledSpans=" + + exportUnsampledSpans + ", scheduleDelayNanos=" + worker.scheduleDelayNanos + ", maxExportBatchSize=" diff --git a/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/export/BatchSpanProcessorBuilder.java b/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/export/BatchSpanProcessorBuilder.java index d801c2296bc..3e155bdfc5d 100644 --- a/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/export/BatchSpanProcessorBuilder.java +++ b/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/export/BatchSpanProcessorBuilder.java @@ -25,6 +25,7 @@ public final class BatchSpanProcessorBuilder { static final int DEFAULT_EXPORT_TIMEOUT_MILLIS = 30_000; private final SpanExporter spanExporter; + private boolean exportUnsampledSpans; private long scheduleDelayNanos = TimeUnit.MILLISECONDS.toNanos(DEFAULT_SCHEDULE_DELAY_MILLIS); private int maxQueueSize = DEFAULT_MAX_QUEUE_SIZE; private int maxExportBatchSize = DEFAULT_MAX_EXPORT_BATCH_SIZE; @@ -35,6 +36,15 @@ public final class BatchSpanProcessorBuilder { this.spanExporter = requireNonNull(spanExporter, "spanExporter"); } + /** + * Sets whether unsampled spans should be exported. If unset, defaults to exporting only sampled + * spans. + */ + public BatchSpanProcessorBuilder setExportUnsampledSpans(boolean exportUnsampledSpans) { + this.exportUnsampledSpans = exportUnsampledSpans; + return this; + } + /** * Sets the delay interval between two consecutive exports. If unset, defaults to {@value * DEFAULT_SCHEDULE_DELAY_MILLIS}ms. @@ -146,6 +156,7 @@ int getMaxExportBatchSize() { public BatchSpanProcessor build() { return new BatchSpanProcessor( spanExporter, + exportUnsampledSpans, meterProvider, scheduleDelayNanos, maxQueueSize, diff --git a/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/export/SimpleSpanProcessor.java b/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/export/SimpleSpanProcessor.java index ba05a5f0e94..3094b8645ca 100644 --- a/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/export/SimpleSpanProcessor.java +++ b/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/export/SimpleSpanProcessor.java @@ -36,7 +36,7 @@ public final class SimpleSpanProcessor implements SpanProcessor { private static final Logger logger = Logger.getLogger(SimpleSpanProcessor.class.getName()); private final SpanExporter spanExporter; - private final boolean sampled; + private final boolean exportUnsampledSpans; private final Set pendingExports = Collections.newSetFromMap(new ConcurrentHashMap<>()); private final AtomicBoolean isShutdown = new AtomicBoolean(false); @@ -53,12 +53,17 @@ public final class SimpleSpanProcessor implements SpanProcessor { */ public static SpanProcessor create(SpanExporter exporter) { requireNonNull(exporter, "exporter"); - return new SimpleSpanProcessor(exporter, /* sampled= */ true); + return builder(exporter).build(); } - SimpleSpanProcessor(SpanExporter spanExporter, boolean sampled) { + public static SimpleSpanProcessorBuilder builder(SpanExporter exporter) { + requireNonNull(exporter, "exporter"); + return new SimpleSpanProcessorBuilder(exporter); + } + + SimpleSpanProcessor(SpanExporter spanExporter, boolean exportUnsampledSpans) { this.spanExporter = requireNonNull(spanExporter, "spanExporter"); - this.sampled = sampled; + this.exportUnsampledSpans = exportUnsampledSpans; } @Override @@ -73,22 +78,21 @@ public boolean isStartRequired() { @Override public void onEnd(ReadableSpan span) { - if (sampled && !span.getSpanContext().isSampled()) { - return; - } - try { - List spans = Collections.singletonList(span.toSpanData()); - CompletableResultCode result = spanExporter.export(spans); - pendingExports.add(result); - result.whenComplete( - () -> { - pendingExports.remove(result); - if (!result.isSuccess()) { - logger.log(Level.FINE, "Exporter failed"); - } - }); - } catch (RuntimeException e) { - logger.log(Level.WARNING, "Exporter threw an Exception", e); + if (span != null && (exportUnsampledSpans || span.getSpanContext().isSampled())) { + try { + List spans = Collections.singletonList(span.toSpanData()); + CompletableResultCode result = spanExporter.export(spans); + pendingExports.add(result); + result.whenComplete( + () -> { + pendingExports.remove(result); + if (!result.isSuccess()) { + logger.log(Level.FINE, "Exporter failed"); + } + }); + } catch (RuntimeException e) { + logger.log(Level.WARNING, "Exporter threw an Exception", e); + } } } @@ -128,6 +132,11 @@ public CompletableResultCode forceFlush() { @Override public String toString() { - return "SimpleSpanProcessor{" + "spanExporter=" + spanExporter + '}'; + return "SimpleSpanProcessor{" + + "spanExporter=" + + spanExporter + + ", exportUnsampledSpans=" + + exportUnsampledSpans + + '}'; } } diff --git a/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/export/SimpleSpanProcessorBuilder.java b/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/export/SimpleSpanProcessorBuilder.java new file mode 100644 index 00000000000..76e5482cd9d --- /dev/null +++ b/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/export/SimpleSpanProcessorBuilder.java @@ -0,0 +1,36 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.sdk.trace.export; + +import static java.util.Objects.requireNonNull; + +/** Builder class for {@link SimpleSpanProcessor}. */ +public final class SimpleSpanProcessorBuilder { + private final SpanExporter spanExporter; + private boolean exportUnsampledSpans; + + SimpleSpanProcessorBuilder(SpanExporter spanExporter) { + this.spanExporter = requireNonNull(spanExporter, "spanExporter"); + } + + /** + * Sets whether unsampled spans should be exported. If unset, defaults to exporting only sampled + * spans. + */ + public SimpleSpanProcessorBuilder setExportUnsampledSpans(boolean exportUnsampledSpans) { + this.exportUnsampledSpans = exportUnsampledSpans; + return this; + } + + /** + * Returns a new {@link SimpleSpanProcessor} with the configuration of this builder. + * + * @return a new {@link SimpleSpanProcessor}. + */ + public SimpleSpanProcessor build() { + return new SimpleSpanProcessor(spanExporter, exportUnsampledSpans); + } +} diff --git a/sdk/trace/src/test/java/io/opentelemetry/sdk/trace/export/BatchSpanProcessorTest.java b/sdk/trace/src/test/java/io/opentelemetry/sdk/trace/export/BatchSpanProcessorTest.java index e659df55183..b774d7fae04 100644 --- a/sdk/trace/src/test/java/io/opentelemetry/sdk/trace/export/BatchSpanProcessorTest.java +++ b/sdk/trace/src/test/java/io/opentelemetry/sdk/trace/export/BatchSpanProcessorTest.java @@ -517,6 +517,38 @@ void exportNotSampledSpans_recordOnly() { assertThat(exported).containsExactly(span.toSpanData()); } + @Test + void exportUnsampledSpans_recordOnly() { + WaitingSpanExporter waitingSpanExporter = + new WaitingSpanExporter(1, CompletableResultCode.ofSuccess()); + + when(mockSampler.shouldSample(any(), any(), any(), any(), any(), anyList())) + .thenReturn(SamplingResult.recordOnly()); + sdkTracerProvider = + SdkTracerProvider.builder() + .addSpanProcessor( + BatchSpanProcessor.builder(waitingSpanExporter) + .setExportUnsampledSpans(true) + .setScheduleDelay(MAX_SCHEDULE_DELAY_MILLIS, TimeUnit.MILLISECONDS) + .build()) + .setSampler(mockSampler) + .build(); + + ReadableSpan span1 = createEndedSpan(SPAN_NAME_1); + when(mockSampler.shouldSample(any(), any(), any(), any(), any(), anyList())) + .thenReturn(SamplingResult.recordAndSample()); + ReadableSpan span2 = createEndedSpan(SPAN_NAME_2); + + // Spans are recorded and exported in the same order as they are ended, we test that a non + // exported span is not exported by creating and ending a sampled span after a non sampled span + // and checking that the first exported span is the sampled span (the non sampled did not get + // exported). + List exported = waitingSpanExporter.waitForExport(); + // Need to check this because otherwise the variable span1 is unused, other option is to not + // have a span1 variable. + assertThat(exported).containsExactly(span1.toSpanData(), span2.toSpanData()); + } + @Test @Timeout(10) @SuppressLogger(SdkTracerProvider.class) @@ -569,6 +601,7 @@ void stringRepresentation() { .hasToString( "BatchSpanProcessor{" + "spanExporter=mockSpanExporter, " + + "exportUnsampledSpans=false, " + "scheduleDelayNanos=5000000000, " + "maxExportBatchSize=512, " + "exporterTimeoutNanos=30000000000}"); diff --git a/sdk/trace/src/test/java/io/opentelemetry/sdk/trace/export/SimpleSpanProcessorTest.java b/sdk/trace/src/test/java/io/opentelemetry/sdk/trace/export/SimpleSpanProcessorTest.java index da46ec2a641..9bcd195bb11 100644 --- a/sdk/trace/src/test/java/io/opentelemetry/sdk/trace/export/SimpleSpanProcessorTest.java +++ b/sdk/trace/src/test/java/io/opentelemetry/sdk/trace/export/SimpleSpanProcessorTest.java @@ -59,7 +59,12 @@ class SimpleSpanProcessorTest { SpanId.getInvalid(), TraceFlags.getSampled(), TraceState.getDefault()); - private static final SpanContext NOT_SAMPLED_SPAN_CONTEXT = SpanContext.getInvalid(); + private static final SpanContext NOT_SAMPLED_SPAN_CONTEXT = + SpanContext.create( + TraceId.getInvalid(), + SpanId.getInvalid(), + TraceFlags.getDefault(), + TraceState.getDefault()); private SpanProcessor simpleSampledSpansProcessor; @@ -100,29 +105,29 @@ void onEndSync_NotSampledSpan() { } @Test - void onEndSync_OnlySampled_NotSampledSpan() { + void onEndSync_ExportUnsampledSpans_NotSampledSpan() { + SpanData spanData = TestUtils.makeBasicSpan(); when(readableSpan.getSpanContext()).thenReturn(NOT_SAMPLED_SPAN_CONTEXT); - when(readableSpan.toSpanData()) - .thenReturn(TestUtils.makeBasicSpan()) - .thenThrow(new RuntimeException()); - SpanProcessor simpleSpanProcessor = SimpleSpanProcessor.create(spanExporter); + when(readableSpan.toSpanData()).thenReturn(spanData); + SpanProcessor simpleSpanProcessor = + SimpleSpanProcessor.builder(spanExporter).setExportUnsampledSpans(true).build(); simpleSpanProcessor.onEnd(readableSpan); - verifyNoInteractions(spanExporter); + verify(spanExporter).export(Collections.singletonList(spanData)); } @Test - void onEndSync_OnlySampled_SampledSpan() { + void onEndSync_ExportUnsampledSpans_SampledSpan() { + SpanData spanData = TestUtils.makeBasicSpan(); when(readableSpan.getSpanContext()).thenReturn(SAMPLED_SPAN_CONTEXT); - when(readableSpan.toSpanData()) - .thenReturn(TestUtils.makeBasicSpan()) - .thenThrow(new RuntimeException()); - SpanProcessor simpleSpanProcessor = SimpleSpanProcessor.create(spanExporter); + when(readableSpan.toSpanData()).thenReturn(spanData); + SpanProcessor simpleSpanProcessor = + SimpleSpanProcessor.builder(spanExporter).setExportUnsampledSpans(true).build(); simpleSpanProcessor.onEnd(readableSpan); - verify(spanExporter).export(Collections.singletonList(TestUtils.makeBasicSpan())); + verify(spanExporter).export(Collections.singletonList(spanData)); } @Test - void tracerSdk_NotSampled_Span() { + void tracerSdk_SampledSpan() { WaitingSpanExporter waitingSpanExporter = new WaitingSpanExporter(1, CompletableResultCode.ofSuccess()); @@ -159,25 +164,43 @@ void tracerSdk_NotSampled_Span() { } @Test - void tracerSdk_NotSampled_RecordingEventsSpan() { - // TODO(bdrutu): Fix this when Sampler return RECORD_ONLY option. - /* - tracer.addSpanProcessor( - BatchSpanProcessor.builder(waitingSpanExporter) - .setScheduleDelayMillis(MAX_SCHEDULE_DELAY_MILLIS) - .reportOnlySampled(false) - .build()); - - io.opentelemetry.trace.Span span = - tracer - .spanBuilder("FOO") - .setSampler(Samplers.neverSample()) - .startSpanWithSampler(); - span.end(); - - List exported = waitingSpanExporter.waitForExport(1); - assertThat(exported).containsExactly(((ReadableSpan) span).toSpanData()); - */ + void tracerSdk_ExportUnsampledSpans_NotSampledSpan() { + WaitingSpanExporter waitingSpanExporter = + new WaitingSpanExporter(1, CompletableResultCode.ofSuccess()); + + SdkTracerProvider sdkTracerProvider = + SdkTracerProvider.builder() + .addSpanProcessor( + SimpleSpanProcessor.builder(waitingSpanExporter) + .setExportUnsampledSpans(true) + .build()) + .setSampler(mockSampler) + .build(); + + when(mockSampler.shouldSample(any(), any(), any(), any(), any(), anyList())) + .thenReturn(SamplingResult.drop()); + + try { + Tracer tracer = sdkTracerProvider.get(getClass().getName()); + tracer.spanBuilder(SPAN_NAME).startSpan(); + tracer.spanBuilder(SPAN_NAME).startSpan(); + + when(mockSampler.shouldSample(any(), any(), any(), any(), any(), anyList())) + .thenReturn(SamplingResult.recordOnly()); + Span span = tracer.spanBuilder(SPAN_NAME).startSpan(); + span.end(); + + // Spans are recorded and exported in the same order as they are ended, we test that a non + // sampled span is not exported by creating and ending a sampled span after a non sampled span + // and checking that the first exported span is the sampled span (the non sampled did not get + // exported). + List exported = waitingSpanExporter.waitForExport(); + // Need to check this because otherwise the variable span1 is unused, other option is to not + // have a span1 variable. + assertThat(exported).containsExactly(((ReadableSpan) span).toSpanData()); + } finally { + sdkTracerProvider.shutdown(); + } } @Test From 1f2a8fef1745fd7be0e6c0e16317f17f7930c56d Mon Sep 17 00:00:00 2001 From: jack-berg <34418638+jack-berg@users.noreply.github.com> Date: Fri, 5 Jan 2024 09:11:06 -0600 Subject: [PATCH 186/901] Prepare 1.34.0 (#6115) --- CHANGELOG.md | 42 +++++++++++++++++++ .../export/BatchSpanProcessorBuilder.java | 4 +- .../sdk/trace/export/SimpleSpanProcessor.java | 5 +++ .../export/SimpleSpanProcessorBuilder.java | 8 +++- 4 files changed, 56 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index be0063fb05b..8e08d72de21 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,48 @@ ## Unreleased +### API + +* Ability to access version.properties API file with GraalVM native + ([#6095](https://github.com/open-telemetry/opentelemetry-java/pull/6095)) + +### SDK + +#### Traces + +* Only call SpanProcessor onStart / onEnd if required + ([#6112](https://github.com/open-telemetry/opentelemetry-java/pull/6112)) +* Add option to export unsampled spans from span processors + ([#6057](https://github.com/open-telemetry/opentelemetry-java/pull/6057)) + +#### Metrics + +* Memory Mode: Adding first part support for synchronous instruments - storage + ([#5998](https://github.com/open-telemetry/opentelemetry-java/pull/5998)) +* Base2ExponentialHistogramAggregation maxBuckets must be >= 2 + ([#6093](https://github.com/open-telemetry/opentelemetry-java/pull/6093)) +* Convert histogram measurements to double before passing recording exemplar reservoir + ([#6024](https://github.com/open-telemetry/opentelemetry-java/pull/6024)) + +#### Exporters + +* Add compressor SPI to support additional compression algos + ([#5990](https://github.com/open-telemetry/opentelemetry-java/pull/5990)) +* Test OTLP exporters with different OkHttp versions + ([#6045](https://github.com/open-telemetry/opentelemetry-java/pull/6045)) +* Refactor prometheus exporter to use `io.prometheus:prometheus-metrics-exporter-httpserver`, add + exponential Histogram support + ([#6015](https://github.com/open-telemetry/opentelemetry-java/pull/6015)) +* UpstreamGrpcSenderProvider uses minimal fallback managed channel when none is specified + ([#6110](https://github.com/open-telemetry/opentelemetry-java/pull/6110)) +* OTLP exporters propagate serialization IOException instead of rethrowing as runtime + ([#6082](https://github.com/open-telemetry/opentelemetry-java/pull/6082)) + +#### Extensions + +* Autoconfigure reads normalized otel.config.file property + ([#6105](https://github.com/open-telemetry/opentelemetry-java/pull/6105)) + ## Version 1.33.0 (2023-12-08) ### API diff --git a/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/export/BatchSpanProcessorBuilder.java b/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/export/BatchSpanProcessorBuilder.java index 3e155bdfc5d..c3235a60f4f 100644 --- a/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/export/BatchSpanProcessorBuilder.java +++ b/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/export/BatchSpanProcessorBuilder.java @@ -25,7 +25,7 @@ public final class BatchSpanProcessorBuilder { static final int DEFAULT_EXPORT_TIMEOUT_MILLIS = 30_000; private final SpanExporter spanExporter; - private boolean exportUnsampledSpans; + private boolean exportUnsampledSpans = false; private long scheduleDelayNanos = TimeUnit.MILLISECONDS.toNanos(DEFAULT_SCHEDULE_DELAY_MILLIS); private int maxQueueSize = DEFAULT_MAX_QUEUE_SIZE; private int maxExportBatchSize = DEFAULT_MAX_EXPORT_BATCH_SIZE; @@ -39,6 +39,8 @@ public final class BatchSpanProcessorBuilder { /** * Sets whether unsampled spans should be exported. If unset, defaults to exporting only sampled * spans. + * + * @since 1.34.0 */ public BatchSpanProcessorBuilder setExportUnsampledSpans(boolean exportUnsampledSpans) { this.exportUnsampledSpans = exportUnsampledSpans; diff --git a/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/export/SimpleSpanProcessor.java b/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/export/SimpleSpanProcessor.java index 3094b8645ca..432d7d056a0 100644 --- a/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/export/SimpleSpanProcessor.java +++ b/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/export/SimpleSpanProcessor.java @@ -56,6 +56,11 @@ public static SpanProcessor create(SpanExporter exporter) { return builder(exporter).build(); } + /** + * Returns a new Builder for {@link SimpleSpanProcessor}. + * + * @since 1.34.0 + */ public static SimpleSpanProcessorBuilder builder(SpanExporter exporter) { requireNonNull(exporter, "exporter"); return new SimpleSpanProcessorBuilder(exporter); diff --git a/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/export/SimpleSpanProcessorBuilder.java b/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/export/SimpleSpanProcessorBuilder.java index 76e5482cd9d..de9f3f9152a 100644 --- a/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/export/SimpleSpanProcessorBuilder.java +++ b/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/export/SimpleSpanProcessorBuilder.java @@ -7,10 +7,14 @@ import static java.util.Objects.requireNonNull; -/** Builder class for {@link SimpleSpanProcessor}. */ +/** + * Builder class for {@link SimpleSpanProcessor}. + * + * @since 1.34.0 + */ public final class SimpleSpanProcessorBuilder { private final SpanExporter spanExporter; - private boolean exportUnsampledSpans; + private boolean exportUnsampledSpans = false; SimpleSpanProcessorBuilder(SpanExporter spanExporter) { this.spanExporter = requireNonNull(spanExporter, "spanExporter"); From c9ea2381215483189a93f5207a940a29638cbb22 Mon Sep 17 00:00:00 2001 From: OpenTelemetry Bot <107717825+opentelemetrybot@users.noreply.github.com> Date: Fri, 5 Jan 2024 16:39:00 +0100 Subject: [PATCH 187/901] Update version to 1.35.0 (#6116) --- CHANGELOG.md | 2 ++ version.gradle.kts | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8e08d72de21..ac2580fe8d2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,8 @@ ## Unreleased +## Version 1.34.0 (2024-01-05) + ### API * Ability to access version.properties API file with GraalVM native diff --git a/version.gradle.kts b/version.gradle.kts index 8c54ed12381..7201568cbc2 100644 --- a/version.gradle.kts +++ b/version.gradle.kts @@ -1,7 +1,7 @@ val snapshot = true allprojects { - var ver = "1.34.0" + var ver = "1.35.0" val release = findProperty("otel.release") if (release != null) { ver += "-" + release From d9f9812d4375a4229caff43bd681c50b7a45776a Mon Sep 17 00:00:00 2001 From: jack-berg <34418638+jack-berg@users.noreply.github.com> Date: Fri, 5 Jan 2024 11:19:28 -0600 Subject: [PATCH 188/901] Post release 1.34.0 (#6118) --- CHANGELOG.md | 7 ++ README.md | 76 +++++++++---------- .../1.34.0_vs_1.33.0/opentelemetry-api.txt | 2 + .../opentelemetry-context.txt | 2 + .../opentelemetry-exporter-common.txt | 2 + .../opentelemetry-exporter-jaeger-thrift.txt | 2 + .../opentelemetry-exporter-jaeger.txt | 2 + .../opentelemetry-exporter-logging-otlp.txt | 2 + .../opentelemetry-exporter-logging.txt | 2 + .../opentelemetry-exporter-otlp-common.txt | 2 + .../opentelemetry-exporter-otlp.txt | 2 + ...y-exporter-sender-grpc-managed-channel.txt | 2 + .../opentelemetry-exporter-sender-okhttp.txt | 2 + .../opentelemetry-exporter-zipkin.txt | 2 + .../opentelemetry-extension-kotlin.txt | 2 + ...ntelemetry-extension-trace-propagators.txt | 2 + .../opentelemetry-opentracing-shim.txt | 2 + .../opentelemetry-sdk-common.txt | 2 + ...emetry-sdk-extension-autoconfigure-spi.txt | 2 + ...ntelemetry-sdk-extension-autoconfigure.txt | 2 + ...ry-sdk-extension-jaeger-remote-sampler.txt | 2 + .../opentelemetry-sdk-logs.txt | 2 + .../opentelemetry-sdk-metrics.txt | 2 + .../opentelemetry-sdk-testing.txt | 2 + .../opentelemetry-sdk-trace.txt | 12 +++ .../1.34.0_vs_1.33.0/opentelemetry-sdk.txt | 2 + .../opentelemetry-sdk-trace.txt | 12 +-- 27 files changed, 104 insertions(+), 49 deletions(-) create mode 100644 docs/apidiffs/1.34.0_vs_1.33.0/opentelemetry-api.txt create mode 100644 docs/apidiffs/1.34.0_vs_1.33.0/opentelemetry-context.txt create mode 100644 docs/apidiffs/1.34.0_vs_1.33.0/opentelemetry-exporter-common.txt create mode 100644 docs/apidiffs/1.34.0_vs_1.33.0/opentelemetry-exporter-jaeger-thrift.txt create mode 100644 docs/apidiffs/1.34.0_vs_1.33.0/opentelemetry-exporter-jaeger.txt create mode 100644 docs/apidiffs/1.34.0_vs_1.33.0/opentelemetry-exporter-logging-otlp.txt create mode 100644 docs/apidiffs/1.34.0_vs_1.33.0/opentelemetry-exporter-logging.txt create mode 100644 docs/apidiffs/1.34.0_vs_1.33.0/opentelemetry-exporter-otlp-common.txt create mode 100644 docs/apidiffs/1.34.0_vs_1.33.0/opentelemetry-exporter-otlp.txt create mode 100644 docs/apidiffs/1.34.0_vs_1.33.0/opentelemetry-exporter-sender-grpc-managed-channel.txt create mode 100644 docs/apidiffs/1.34.0_vs_1.33.0/opentelemetry-exporter-sender-okhttp.txt create mode 100644 docs/apidiffs/1.34.0_vs_1.33.0/opentelemetry-exporter-zipkin.txt create mode 100644 docs/apidiffs/1.34.0_vs_1.33.0/opentelemetry-extension-kotlin.txt create mode 100644 docs/apidiffs/1.34.0_vs_1.33.0/opentelemetry-extension-trace-propagators.txt create mode 100644 docs/apidiffs/1.34.0_vs_1.33.0/opentelemetry-opentracing-shim.txt create mode 100644 docs/apidiffs/1.34.0_vs_1.33.0/opentelemetry-sdk-common.txt create mode 100644 docs/apidiffs/1.34.0_vs_1.33.0/opentelemetry-sdk-extension-autoconfigure-spi.txt create mode 100644 docs/apidiffs/1.34.0_vs_1.33.0/opentelemetry-sdk-extension-autoconfigure.txt create mode 100644 docs/apidiffs/1.34.0_vs_1.33.0/opentelemetry-sdk-extension-jaeger-remote-sampler.txt create mode 100644 docs/apidiffs/1.34.0_vs_1.33.0/opentelemetry-sdk-logs.txt create mode 100644 docs/apidiffs/1.34.0_vs_1.33.0/opentelemetry-sdk-metrics.txt create mode 100644 docs/apidiffs/1.34.0_vs_1.33.0/opentelemetry-sdk-testing.txt create mode 100644 docs/apidiffs/1.34.0_vs_1.33.0/opentelemetry-sdk-trace.txt create mode 100644 docs/apidiffs/1.34.0_vs_1.33.0/opentelemetry-sdk.txt diff --git a/CHANGELOG.md b/CHANGELOG.md index ac2580fe8d2..09d69ff84ba 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,13 @@ ## Version 1.34.0 (2024-01-05) +**NOTE:** This is the LAST release for `opentelemetry-exporter-jaeger` +and `opentelemetry-exporter-jaeger-thift`. Jaeger +has [native support for OTLP](https://opentelemetry.io/blog/2022/jaeger-native-otlp/), and users +should export to jaeger +using [OTLP](https://opentelemetry.io/docs/instrumentation/java/exporters/#otlp-dependencies) +instead. + ### API * Ability to access version.properties API file with GraalVM native diff --git a/README.md b/README.md index 68e72d15953..c0425230e7c 100644 --- a/README.md +++ b/README.md @@ -102,7 +102,7 @@ dependency versions in sync. io.opentelemetry opentelemetry-bom - 1.33.0 + 1.34.0 pom import @@ -121,7 +121,7 @@ dependency versions in sync. ```groovy dependencies { - implementation platform("io.opentelemetry:opentelemetry-bom:1.33.0") + implementation platform("io.opentelemetry:opentelemetry-bom:1.34.0") implementation('io.opentelemetry:opentelemetry-api') } ``` @@ -130,8 +130,8 @@ Note that if you want to use any artifacts that have not fully stabilized yet (s ```groovy dependencies { - implementation platform("io.opentelemetry:opentelemetry-bom:1.33.0") - implementation platform('io.opentelemetry:opentelemetry-bom-alpha:1.33.0-alpha') + implementation platform("io.opentelemetry:opentelemetry-bom:1.34.0") + implementation platform('io.opentelemetry:opentelemetry-bom-alpha:1.34.0-alpha') implementation('io.opentelemetry:opentelemetry-api') implementation('io.opentelemetry:opentelemetry-exporter-prometheus') @@ -159,7 +159,7 @@ We strongly recommend using our published BOM to keep all dependency versions in io.opentelemetry opentelemetry-bom - 1.34.0-SNAPSHOT + 1.35.0-SNAPSHOT pom import @@ -182,7 +182,7 @@ repositories { } dependencies { - implementation platform("io.opentelemetry:opentelemetry-bom:1.34.0-SNAPSHOT") + implementation platform("io.opentelemetry:opentelemetry-bom:1.35.0-SNAPSHOT") implementation('io.opentelemetry:opentelemetry-api') } ``` @@ -227,53 +227,53 @@ dependency as follows, replacing `{{artifact-id}}` with the value from the "Arti | Component | Description | Artifact ID | Version | Javadoc | |----------------------------------------------|----------------------------------------|---------------------------|-------------------------------------------------------------|---------| -| [Bill of Materials (BOM)](./bom) | Bill of materials for stable artifacts | `opentelemetry-bom` | 1.33.0 | N/A | -| [Alpha Bill of Materials (BOM)](./bom-alpha) | Bill of materials for alpha artifacts | `opentelemetry-bom-alpha` | 1.33.0-alpha | N/A | +| [Bill of Materials (BOM)](./bom) | Bill of materials for stable artifacts | `opentelemetry-bom` | 1.34.0 | N/A | +| [Alpha Bill of Materials (BOM)](./bom-alpha) | Bill of materials for alpha artifacts | `opentelemetry-bom-alpha` | 1.34.0-alpha | N/A | ### API | Component | Description | Artifact ID | Version | Javadoc | |-----------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|----------------------------|-------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------| -| [API](./api/all) | OpenTelemetry API, including metrics, traces, baggage, context | `opentelemetry-api` | 1.33.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-api.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-api) | -| [Events API](./api/events) | OpenTelemetry Event API for emitting events. | `opentelemetry-api-events` | 1.33.0-alpha | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-api-events.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-api-events) | -| [Context API](./context) | OpenTelemetry context API | `opentelemetry-context` | 1.33.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-context.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-context) | +| [API](./api/all) | OpenTelemetry API, including metrics, traces, baggage, context | `opentelemetry-api` | 1.34.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-api.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-api) | +| [Events API](./api/events) | OpenTelemetry Event API for emitting events. | `opentelemetry-api-events` | 1.34.0-alpha | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-api-events.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-api-events) | +| [Context API](./context) | OpenTelemetry context API | `opentelemetry-context` | 1.34.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-context.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-context) | ### API Extensions | Component | Description | Artifact ID | Version | Javadoc | |---------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|---------------------------------------------|-------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| [Kotlin Extension](./extensions/kotlin) | Context extension for coroutines | `opentelemetry-extension-kotlin` | 1.33.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-extension-kotlin.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-extension-kotlin) | -| [Trace Propagators Extension](./extensions/trace-propagators) | Trace propagators, including B3, Jaeger, OT Trace | `opentelemetry-extension-trace-propagators` | 1.33.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-extension-trace-propagators.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-extension-trace-propagators) | -| [Incubator Extension](./extensions/incubator) | API incubator, including pass through propagator, and extended tracer | `opentelemetry-extension-incubator` | 1.33.0-alpha | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-extension-incubator.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-extension-incubator) | +| [Kotlin Extension](./extensions/kotlin) | Context extension for coroutines | `opentelemetry-extension-kotlin` | 1.34.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-extension-kotlin.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-extension-kotlin) | +| [Trace Propagators Extension](./extensions/trace-propagators) | Trace propagators, including B3, Jaeger, OT Trace | `opentelemetry-extension-trace-propagators` | 1.34.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-extension-trace-propagators.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-extension-trace-propagators) | +| [Incubator Extension](./extensions/incubator) | API incubator, including pass through propagator, and extended tracer | `opentelemetry-extension-incubator` | 1.34.0-alpha | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-extension-incubator.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-extension-incubator) | ### SDK | Component | Description | Artifact ID | Version | Javadoc | |------------------------------|--------------------------------------------------------|-----------------------------|---------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| [SDK](./sdk/all) | OpenTelemetry SDK, including metrics, traces, and logs | `opentelemetry-sdk` | 1.33.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk) | -| [Metrics SDK](./sdk/metrics) | OpenTelemetry metrics SDK | `opentelemetry-sdk-metrics` | 1.33.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-metrics.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-metrics) | -| [Trace SDK](./sdk/trace) | OpenTelemetry trace SDK | `opentelemetry-sdk-trace` | 1.33.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-trace.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-trace) | -| [Log SDK](./sdk/logs) | OpenTelemetry log SDK | `opentelemetry-sdk-logs` | 1.33.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-logs.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-logs) | -| [SDK Common](./sdk/common) | Shared SDK components | `opentelemetry-sdk-common` | 1.33.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-common.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-common) | -| [SDK Testing](./sdk/testing) | Components for testing OpenTelemetry instrumentation | `opentelemetry-sdk-testing` | 1.33.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-testing.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-testing) | +| [SDK](./sdk/all) | OpenTelemetry SDK, including metrics, traces, and logs | `opentelemetry-sdk` | 1.34.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk) | +| [Metrics SDK](./sdk/metrics) | OpenTelemetry metrics SDK | `opentelemetry-sdk-metrics` | 1.34.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-metrics.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-metrics) | +| [Trace SDK](./sdk/trace) | OpenTelemetry trace SDK | `opentelemetry-sdk-trace` | 1.34.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-trace.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-trace) | +| [Log SDK](./sdk/logs) | OpenTelemetry log SDK | `opentelemetry-sdk-logs` | 1.34.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-logs.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-logs) | +| [SDK Common](./sdk/common) | Shared SDK components | `opentelemetry-sdk-common` | 1.34.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-common.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-common) | +| [SDK Testing](./sdk/testing) | Components for testing OpenTelemetry instrumentation | `opentelemetry-sdk-testing` | 1.34.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-testing.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-testing) | ### SDK Exporters | Component | Description | Artifact ID | Version | Javadoc | |-----------------------------------------------------------------------|------------------------------------------------------------------------------|------------------------------------------------------|-------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| [OTLP Exporters](./exporters/otlp/all) | OTLP gRPC & HTTP exporters, including traces, metrics, and logs | `opentelemetry-exporter-otlp` | 1.33.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-otlp.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-otlp) | -| [OTLP Logging Exporters](./exporters/logging-otlp) | Logging exporters in OTLP JSON encoding, including traces, metrics, and logs | `opentelemetry-exporter-logging-otlp` | 1.33.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-logging-otlp.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-logging-otlp) | -| [OTLP Common](./exporters/otlp/common) | Shared OTLP components (internal) | `opentelemetry-exporter-otlp-common` | 1.33.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-otlp-common.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-otlp-common) | -| [Jaeger gRPC Exporter](./exporters/jaeger) | Jaeger gRPC trace exporter (deprecated [1]) | `opentelemetry-exporter-jaeger` | 1.33.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-jaeger.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-jaeger) | -| [Jaeger Thrift Exporter](./exporters/jaeger-thrift) | Jaeger thrift trace exporter (deprecated [1]) | `opentelemetry-exporter-jaeger-thift` | 1.33.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-jaeger-thrift.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-jaeger-thrift) | -| [Logging Exporter](./exporters/logging) | Logging exporters, including metrics, traces, and logs | `opentelemetry-exporter-logging` | 1.33.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-logging.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-logging) | -| [Zipkin Exporter](./exporters/zipkin) | Zipkin trace exporter | `opentelemetry-exporter-zipkin` | 1.33.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-zipkin.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-zipkin) | -| [Prometheus Exporter](./exporters/prometheus) | Prometheus metric exporter | `opentelemetry-exporter-prometheus` | 1.33.0-alpha | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-prometheus.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-prometheus) | -| [Exporter Common](./exporters/common) | Shared exporter components (internal) | `opentelemetry-exporter-common` | 1.33.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-common.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-common) | -| [OkHttp Sender](./exporters/sender/okhttp) | OkHttp implementation of HttpSender (internal) | `opentelemetry-exporter-sender-okhttp` | 1.33.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-sender-okhttp.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-sender-okhttp) | -| [JDK Sender](./exporters/sender/okhttp) | Java 11+ native HttpClient implementation of HttpSender (internal) | `opentelemetry-exporter-sender-jdk` | 1.33.0-alpha | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-sender-jdk.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-sender-jdk) | | -| [gRPC ManagedChannel Sender](./exporters/sender/grpc-managed-channel) | gRPC ManagedChannel implementation of GrpcSender (internal) | `opentelemetry-exporter-sender-grpc-managed-channel` | 1.33.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-sender-grpc-managed-channel.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-sender-grpc-managed-channel) | | +| [OTLP Exporters](./exporters/otlp/all) | OTLP gRPC & HTTP exporters, including traces, metrics, and logs | `opentelemetry-exporter-otlp` | 1.34.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-otlp.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-otlp) | +| [OTLP Logging Exporters](./exporters/logging-otlp) | Logging exporters in OTLP JSON encoding, including traces, metrics, and logs | `opentelemetry-exporter-logging-otlp` | 1.34.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-logging-otlp.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-logging-otlp) | +| [OTLP Common](./exporters/otlp/common) | Shared OTLP components (internal) | `opentelemetry-exporter-otlp-common` | 1.34.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-otlp-common.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-otlp-common) | +| [Jaeger gRPC Exporter](./exporters/jaeger) | Jaeger gRPC trace exporter (deprecated [1]) | `opentelemetry-exporter-jaeger` | 1.34.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-jaeger.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-jaeger) | +| [Jaeger Thrift Exporter](./exporters/jaeger-thrift) | Jaeger thrift trace exporter (deprecated [1]) | `opentelemetry-exporter-jaeger-thift` | 1.34.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-jaeger-thrift.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-jaeger-thrift) | +| [Logging Exporter](./exporters/logging) | Logging exporters, including metrics, traces, and logs | `opentelemetry-exporter-logging` | 1.34.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-logging.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-logging) | +| [Zipkin Exporter](./exporters/zipkin) | Zipkin trace exporter | `opentelemetry-exporter-zipkin` | 1.34.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-zipkin.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-zipkin) | +| [Prometheus Exporter](./exporters/prometheus) | Prometheus metric exporter | `opentelemetry-exporter-prometheus` | 1.34.0-alpha | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-prometheus.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-prometheus) | +| [Exporter Common](./exporters/common) | Shared exporter components (internal) | `opentelemetry-exporter-common` | 1.34.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-common.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-common) | +| [OkHttp Sender](./exporters/sender/okhttp) | OkHttp implementation of HttpSender (internal) | `opentelemetry-exporter-sender-okhttp` | 1.34.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-sender-okhttp.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-sender-okhttp) | +| [JDK Sender](./exporters/sender/okhttp) | Java 11+ native HttpClient implementation of HttpSender (internal) | `opentelemetry-exporter-sender-jdk` | 1.34.0-alpha | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-sender-jdk.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-sender-jdk) | | +| [gRPC ManagedChannel Sender](./exporters/sender/grpc-managed-channel) | gRPC ManagedChannel implementation of GrpcSender (internal) | `opentelemetry-exporter-sender-grpc-managed-channel` | 1.34.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-sender-grpc-managed-channel.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-sender-grpc-managed-channel) | | **[1]**: Jaeger now has [native support for OTLP](https://opentelemetry.io/blog/2022/jaeger-native-otlp/) and jaeger @@ -286,17 +286,17 @@ additional versions will be published. | Component | Description | Artifact ID | Version | Javadoc | |-------------------------------------------------------------------------------|------------------------------------------------------------------------------------|-----------------------------------------------------|-------------------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| [SDK Autoconfigure](./sdk-extensions/autoconfigure) | Autoconfigure OpenTelemetry SDK from env vars, system properties, and SPI | `opentelemetry-sdk-extension-autoconfigure` | 1.33.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-extension-autoconfigure.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-extension-autoconfigure) | -| [SDK Autoconfigure SPI](./sdk-extensions/autoconfigure-spi) | Service Provider Interface (SPI) definitions for autoconfigure | `opentelemetry-sdk-extension-autoconfigure-spi` | 1.33.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-extension-autoconfigure-spi.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-extension-autoconfigure-spi) | -| [SDK Jaeger Remote Sampler Extension](./sdk-extensions/jaeger-remote-sampler) | Sampler which obtains sampling configuration from remote Jaeger server | `opentelemetry-sdk-extension-jaeger-remote-sampler` | 1.33.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-extension-jaeger-remote-sampler.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-extension-jaeger-remote-sampler) | -| [SDK Incubator](./sdk-extensions/incubator) | SDK incubator, including YAML based view configuration, LeakDetectingSpanProcessor | `opentelemetry-sdk-extension-incubator` | 1.33.0-alpha | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-extension-incubator.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-extension-incubator) | +| [SDK Autoconfigure](./sdk-extensions/autoconfigure) | Autoconfigure OpenTelemetry SDK from env vars, system properties, and SPI | `opentelemetry-sdk-extension-autoconfigure` | 1.34.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-extension-autoconfigure.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-extension-autoconfigure) | +| [SDK Autoconfigure SPI](./sdk-extensions/autoconfigure-spi) | Service Provider Interface (SPI) definitions for autoconfigure | `opentelemetry-sdk-extension-autoconfigure-spi` | 1.34.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-extension-autoconfigure-spi.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-extension-autoconfigure-spi) | +| [SDK Jaeger Remote Sampler Extension](./sdk-extensions/jaeger-remote-sampler) | Sampler which obtains sampling configuration from remote Jaeger server | `opentelemetry-sdk-extension-jaeger-remote-sampler` | 1.34.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-extension-jaeger-remote-sampler.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-extension-jaeger-remote-sampler) | +| [SDK Incubator](./sdk-extensions/incubator) | SDK incubator, including YAML based view configuration, LeakDetectingSpanProcessor | `opentelemetry-sdk-extension-incubator` | 1.34.0-alpha | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-extension-incubator.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-extension-incubator) | ### Shims | Component | Description | Artifact ID | Version | Javadoc | |----------------------------------------|--------------------------------------------------------------|----------------------------------|-------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| [OpenCensus Shim](./opencensus-shim) | Bridge opencensus metrics into the OpenTelemetry metrics SDK | `opentelemetry-opencensus-shim` | 1.33.0-alpha | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-opencensus-shim.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-opencensus-shim) | -| [OpenTracing Shim](./opentracing-shim) | Bridge opentracing spans into the OpenTelemetry trace API | `opentelemetry-opentracing-shim` | 1.33.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-opentracing-shim.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-opentracing-shim) | +| [OpenCensus Shim](./opencensus-shim) | Bridge opencensus metrics into the OpenTelemetry metrics SDK | `opentelemetry-opencensus-shim` | 1.34.0-alpha | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-opencensus-shim.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-opencensus-shim) | +| [OpenTracing Shim](./opentracing-shim) | Bridge opentracing spans into the OpenTelemetry trace API | `opentelemetry-opentracing-shim` | 1.34.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-opentracing-shim.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-opentracing-shim) | ## Contributing diff --git a/docs/apidiffs/1.34.0_vs_1.33.0/opentelemetry-api.txt b/docs/apidiffs/1.34.0_vs_1.33.0/opentelemetry-api.txt new file mode 100644 index 00000000000..df26146497b --- /dev/null +++ b/docs/apidiffs/1.34.0_vs_1.33.0/opentelemetry-api.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of against +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.34.0_vs_1.33.0/opentelemetry-context.txt b/docs/apidiffs/1.34.0_vs_1.33.0/opentelemetry-context.txt new file mode 100644 index 00000000000..df26146497b --- /dev/null +++ b/docs/apidiffs/1.34.0_vs_1.33.0/opentelemetry-context.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of against +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.34.0_vs_1.33.0/opentelemetry-exporter-common.txt b/docs/apidiffs/1.34.0_vs_1.33.0/opentelemetry-exporter-common.txt new file mode 100644 index 00000000000..df26146497b --- /dev/null +++ b/docs/apidiffs/1.34.0_vs_1.33.0/opentelemetry-exporter-common.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of against +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.34.0_vs_1.33.0/opentelemetry-exporter-jaeger-thrift.txt b/docs/apidiffs/1.34.0_vs_1.33.0/opentelemetry-exporter-jaeger-thrift.txt new file mode 100644 index 00000000000..df26146497b --- /dev/null +++ b/docs/apidiffs/1.34.0_vs_1.33.0/opentelemetry-exporter-jaeger-thrift.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of against +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.34.0_vs_1.33.0/opentelemetry-exporter-jaeger.txt b/docs/apidiffs/1.34.0_vs_1.33.0/opentelemetry-exporter-jaeger.txt new file mode 100644 index 00000000000..df26146497b --- /dev/null +++ b/docs/apidiffs/1.34.0_vs_1.33.0/opentelemetry-exporter-jaeger.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of against +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.34.0_vs_1.33.0/opentelemetry-exporter-logging-otlp.txt b/docs/apidiffs/1.34.0_vs_1.33.0/opentelemetry-exporter-logging-otlp.txt new file mode 100644 index 00000000000..df26146497b --- /dev/null +++ b/docs/apidiffs/1.34.0_vs_1.33.0/opentelemetry-exporter-logging-otlp.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of against +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.34.0_vs_1.33.0/opentelemetry-exporter-logging.txt b/docs/apidiffs/1.34.0_vs_1.33.0/opentelemetry-exporter-logging.txt new file mode 100644 index 00000000000..df26146497b --- /dev/null +++ b/docs/apidiffs/1.34.0_vs_1.33.0/opentelemetry-exporter-logging.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of against +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.34.0_vs_1.33.0/opentelemetry-exporter-otlp-common.txt b/docs/apidiffs/1.34.0_vs_1.33.0/opentelemetry-exporter-otlp-common.txt new file mode 100644 index 00000000000..df26146497b --- /dev/null +++ b/docs/apidiffs/1.34.0_vs_1.33.0/opentelemetry-exporter-otlp-common.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of against +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.34.0_vs_1.33.0/opentelemetry-exporter-otlp.txt b/docs/apidiffs/1.34.0_vs_1.33.0/opentelemetry-exporter-otlp.txt new file mode 100644 index 00000000000..df26146497b --- /dev/null +++ b/docs/apidiffs/1.34.0_vs_1.33.0/opentelemetry-exporter-otlp.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of against +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.34.0_vs_1.33.0/opentelemetry-exporter-sender-grpc-managed-channel.txt b/docs/apidiffs/1.34.0_vs_1.33.0/opentelemetry-exporter-sender-grpc-managed-channel.txt new file mode 100644 index 00000000000..df26146497b --- /dev/null +++ b/docs/apidiffs/1.34.0_vs_1.33.0/opentelemetry-exporter-sender-grpc-managed-channel.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of against +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.34.0_vs_1.33.0/opentelemetry-exporter-sender-okhttp.txt b/docs/apidiffs/1.34.0_vs_1.33.0/opentelemetry-exporter-sender-okhttp.txt new file mode 100644 index 00000000000..df26146497b --- /dev/null +++ b/docs/apidiffs/1.34.0_vs_1.33.0/opentelemetry-exporter-sender-okhttp.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of against +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.34.0_vs_1.33.0/opentelemetry-exporter-zipkin.txt b/docs/apidiffs/1.34.0_vs_1.33.0/opentelemetry-exporter-zipkin.txt new file mode 100644 index 00000000000..df26146497b --- /dev/null +++ b/docs/apidiffs/1.34.0_vs_1.33.0/opentelemetry-exporter-zipkin.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of against +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.34.0_vs_1.33.0/opentelemetry-extension-kotlin.txt b/docs/apidiffs/1.34.0_vs_1.33.0/opentelemetry-extension-kotlin.txt new file mode 100644 index 00000000000..df26146497b --- /dev/null +++ b/docs/apidiffs/1.34.0_vs_1.33.0/opentelemetry-extension-kotlin.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of against +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.34.0_vs_1.33.0/opentelemetry-extension-trace-propagators.txt b/docs/apidiffs/1.34.0_vs_1.33.0/opentelemetry-extension-trace-propagators.txt new file mode 100644 index 00000000000..df26146497b --- /dev/null +++ b/docs/apidiffs/1.34.0_vs_1.33.0/opentelemetry-extension-trace-propagators.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of against +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.34.0_vs_1.33.0/opentelemetry-opentracing-shim.txt b/docs/apidiffs/1.34.0_vs_1.33.0/opentelemetry-opentracing-shim.txt new file mode 100644 index 00000000000..df26146497b --- /dev/null +++ b/docs/apidiffs/1.34.0_vs_1.33.0/opentelemetry-opentracing-shim.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of against +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.34.0_vs_1.33.0/opentelemetry-sdk-common.txt b/docs/apidiffs/1.34.0_vs_1.33.0/opentelemetry-sdk-common.txt new file mode 100644 index 00000000000..df26146497b --- /dev/null +++ b/docs/apidiffs/1.34.0_vs_1.33.0/opentelemetry-sdk-common.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of against +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.34.0_vs_1.33.0/opentelemetry-sdk-extension-autoconfigure-spi.txt b/docs/apidiffs/1.34.0_vs_1.33.0/opentelemetry-sdk-extension-autoconfigure-spi.txt new file mode 100644 index 00000000000..df26146497b --- /dev/null +++ b/docs/apidiffs/1.34.0_vs_1.33.0/opentelemetry-sdk-extension-autoconfigure-spi.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of against +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.34.0_vs_1.33.0/opentelemetry-sdk-extension-autoconfigure.txt b/docs/apidiffs/1.34.0_vs_1.33.0/opentelemetry-sdk-extension-autoconfigure.txt new file mode 100644 index 00000000000..df26146497b --- /dev/null +++ b/docs/apidiffs/1.34.0_vs_1.33.0/opentelemetry-sdk-extension-autoconfigure.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of against +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.34.0_vs_1.33.0/opentelemetry-sdk-extension-jaeger-remote-sampler.txt b/docs/apidiffs/1.34.0_vs_1.33.0/opentelemetry-sdk-extension-jaeger-remote-sampler.txt new file mode 100644 index 00000000000..df26146497b --- /dev/null +++ b/docs/apidiffs/1.34.0_vs_1.33.0/opentelemetry-sdk-extension-jaeger-remote-sampler.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of against +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.34.0_vs_1.33.0/opentelemetry-sdk-logs.txt b/docs/apidiffs/1.34.0_vs_1.33.0/opentelemetry-sdk-logs.txt new file mode 100644 index 00000000000..df26146497b --- /dev/null +++ b/docs/apidiffs/1.34.0_vs_1.33.0/opentelemetry-sdk-logs.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of against +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.34.0_vs_1.33.0/opentelemetry-sdk-metrics.txt b/docs/apidiffs/1.34.0_vs_1.33.0/opentelemetry-sdk-metrics.txt new file mode 100644 index 00000000000..df26146497b --- /dev/null +++ b/docs/apidiffs/1.34.0_vs_1.33.0/opentelemetry-sdk-metrics.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of against +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.34.0_vs_1.33.0/opentelemetry-sdk-testing.txt b/docs/apidiffs/1.34.0_vs_1.33.0/opentelemetry-sdk-testing.txt new file mode 100644 index 00000000000..df26146497b --- /dev/null +++ b/docs/apidiffs/1.34.0_vs_1.33.0/opentelemetry-sdk-testing.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of against +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.34.0_vs_1.33.0/opentelemetry-sdk-trace.txt b/docs/apidiffs/1.34.0_vs_1.33.0/opentelemetry-sdk-trace.txt new file mode 100644 index 00000000000..f03b01723c1 --- /dev/null +++ b/docs/apidiffs/1.34.0_vs_1.33.0/opentelemetry-sdk-trace.txt @@ -0,0 +1,12 @@ +Comparing source compatibility of against +*** MODIFIED CLASS: PUBLIC FINAL io.opentelemetry.sdk.trace.export.BatchSpanProcessorBuilder (not serializable) + === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 + +++ NEW METHOD: PUBLIC(+) io.opentelemetry.sdk.trace.export.BatchSpanProcessorBuilder setExportUnsampledSpans(boolean) +*** MODIFIED CLASS: PUBLIC FINAL io.opentelemetry.sdk.trace.export.SimpleSpanProcessor (not serializable) + === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 + +++ NEW METHOD: PUBLIC(+) STATIC(+) io.opentelemetry.sdk.trace.export.SimpleSpanProcessorBuilder builder(io.opentelemetry.sdk.trace.export.SpanExporter) ++++ NEW CLASS: PUBLIC(+) FINAL(+) io.opentelemetry.sdk.trace.export.SimpleSpanProcessorBuilder (not serializable) + +++ CLASS FILE FORMAT VERSION: 52.0 <- n.a. + +++ NEW SUPERCLASS: java.lang.Object + +++ NEW METHOD: PUBLIC(+) io.opentelemetry.sdk.trace.export.SimpleSpanProcessor build() + +++ NEW METHOD: PUBLIC(+) io.opentelemetry.sdk.trace.export.SimpleSpanProcessorBuilder setExportUnsampledSpans(boolean) diff --git a/docs/apidiffs/1.34.0_vs_1.33.0/opentelemetry-sdk.txt b/docs/apidiffs/1.34.0_vs_1.33.0/opentelemetry-sdk.txt new file mode 100644 index 00000000000..df26146497b --- /dev/null +++ b/docs/apidiffs/1.34.0_vs_1.33.0/opentelemetry-sdk.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of against +No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-trace.txt b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-trace.txt index f03b01723c1..df26146497b 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-trace.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-trace.txt @@ -1,12 +1,2 @@ Comparing source compatibility of against -*** MODIFIED CLASS: PUBLIC FINAL io.opentelemetry.sdk.trace.export.BatchSpanProcessorBuilder (not serializable) - === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 - +++ NEW METHOD: PUBLIC(+) io.opentelemetry.sdk.trace.export.BatchSpanProcessorBuilder setExportUnsampledSpans(boolean) -*** MODIFIED CLASS: PUBLIC FINAL io.opentelemetry.sdk.trace.export.SimpleSpanProcessor (not serializable) - === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 - +++ NEW METHOD: PUBLIC(+) STATIC(+) io.opentelemetry.sdk.trace.export.SimpleSpanProcessorBuilder builder(io.opentelemetry.sdk.trace.export.SpanExporter) -+++ NEW CLASS: PUBLIC(+) FINAL(+) io.opentelemetry.sdk.trace.export.SimpleSpanProcessorBuilder (not serializable) - +++ CLASS FILE FORMAT VERSION: 52.0 <- n.a. - +++ NEW SUPERCLASS: java.lang.Object - +++ NEW METHOD: PUBLIC(+) io.opentelemetry.sdk.trace.export.SimpleSpanProcessor build() - +++ NEW METHOD: PUBLIC(+) io.opentelemetry.sdk.trace.export.SimpleSpanProcessorBuilder setExportUnsampledSpans(boolean) +No changes. \ No newline at end of file From ff823f4346f62f316134cb0ff145eedd544e83d2 Mon Sep 17 00:00:00 2001 From: jack-berg <34418638+jack-berg@users.noreply.github.com> Date: Thu, 11 Jan 2024 15:52:44 -0600 Subject: [PATCH 189/901] Recreate graal RetryPolicy issue (#6139) --- .github/workflows/build.yml | 6 +-- ...flect-config.json => resource-config.json} | 0 .../reflect-config.json | 10 ++++ integration-tests/graal/build.gradle.kts | 4 +- .../graal/InitializeSdkTest.java | 53 +++++++++++++++++++ 5 files changed, 69 insertions(+), 4 deletions(-) rename api/all/src/main/resources/META-INF/native-image/io.opentelemetry/opentelemetry-api/{reflect-config.json => resource-config.json} (100%) create mode 100644 exporters/common/src/main/resources/META-INF/native-image/io.opentelemetry.opentelemetry-exporter-common/reflect-config.json create mode 100644 integration-tests/graal/src/test/java/io/opentelemetry/integrationtests/graal/InitializeSdkTest.java diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 8243beff8f7..210f70e2ff7 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -136,8 +136,9 @@ jobs: - uses: actions/checkout@v4 - uses: graalvm/setup-graalvm@v1 with: - version: 'latest' - java-version: '17' + # TODO(jack-berg): Which versions do we need to test? Should we use a matrix scheme? + java-version: '21' + distribution: 'graalvm' components: 'native-image' github-token: ${{ secrets.GITHUB_TOKEN }} - name: Running test @@ -145,7 +146,6 @@ jobs: echo "GRAALVM_HOME: $GRAALVM_HOME" echo "JAVA_HOME: $JAVA_HOME" java --version - gu --version native-image --version ./gradlew nativeTest diff --git a/api/all/src/main/resources/META-INF/native-image/io.opentelemetry/opentelemetry-api/reflect-config.json b/api/all/src/main/resources/META-INF/native-image/io.opentelemetry/opentelemetry-api/resource-config.json similarity index 100% rename from api/all/src/main/resources/META-INF/native-image/io.opentelemetry/opentelemetry-api/reflect-config.json rename to api/all/src/main/resources/META-INF/native-image/io.opentelemetry/opentelemetry-api/resource-config.json diff --git a/exporters/common/src/main/resources/META-INF/native-image/io.opentelemetry.opentelemetry-exporter-common/reflect-config.json b/exporters/common/src/main/resources/META-INF/native-image/io.opentelemetry.opentelemetry-exporter-common/reflect-config.json new file mode 100644 index 00000000000..033ccf44f0c --- /dev/null +++ b/exporters/common/src/main/resources/META-INF/native-image/io.opentelemetry.opentelemetry-exporter-common/reflect-config.json @@ -0,0 +1,10 @@ +[ + { + "name":"io.opentelemetry.sdk.common.export.AutoValue_RetryPolicy", + "queryAllDeclaredMethods":true + }, + { + "name":"io.opentelemetry.sdk.common.export.RetryPolicy", + "queryAllDeclaredMethods":true + } +] diff --git a/integration-tests/graal/build.gradle.kts b/integration-tests/graal/build.gradle.kts index cb39297a76a..090be76a2f5 100644 --- a/integration-tests/graal/build.gradle.kts +++ b/integration-tests/graal/build.gradle.kts @@ -16,7 +16,9 @@ sourceSets { } dependencies { - implementation(project(path = ":sdk:trace-shaded-deps")) + implementation(project(":sdk:all")) + implementation(project(":sdk:trace-shaded-deps")) + implementation(project(":exporters:otlp:all")) } // org.graalvm.buildtools.native pluging requires java 11+ as of version 0.9.26 diff --git a/integration-tests/graal/src/test/java/io/opentelemetry/integrationtests/graal/InitializeSdkTest.java b/integration-tests/graal/src/test/java/io/opentelemetry/integrationtests/graal/InitializeSdkTest.java new file mode 100644 index 00000000000..8826db405de --- /dev/null +++ b/integration-tests/graal/src/test/java/io/opentelemetry/integrationtests/graal/InitializeSdkTest.java @@ -0,0 +1,53 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.integrationtests.graal; + +import static org.assertj.core.api.Assertions.assertThatCode; + +import io.opentelemetry.exporter.otlp.logs.OtlpGrpcLogRecordExporter; +import io.opentelemetry.exporter.otlp.metrics.OtlpGrpcMetricExporter; +import io.opentelemetry.exporter.otlp.trace.OtlpGrpcSpanExporter; +import io.opentelemetry.sdk.OpenTelemetrySdk; +import io.opentelemetry.sdk.logs.SdkLoggerProvider; +import io.opentelemetry.sdk.logs.export.BatchLogRecordProcessor; +import io.opentelemetry.sdk.metrics.SdkMeterProvider; +import io.opentelemetry.sdk.metrics.export.PeriodicMetricReader; +import io.opentelemetry.sdk.trace.SdkTracerProvider; +import io.opentelemetry.sdk.trace.export.BatchSpanProcessor; +import org.junit.jupiter.api.Test; + +class InitializeSdkTest { + + @Test + void initializeSdk() { + assertThatCode( + () -> { + OpenTelemetrySdk sdk = + OpenTelemetrySdk.builder() + .setTracerProvider( + SdkTracerProvider.builder() + .addSpanProcessor( + BatchSpanProcessor.builder(OtlpGrpcSpanExporter.getDefault()) + .build()) + .build()) + .setMeterProvider( + SdkMeterProvider.builder() + .registerMetricReader( + PeriodicMetricReader.create(OtlpGrpcMetricExporter.getDefault())) + .build()) + .setLoggerProvider( + SdkLoggerProvider.builder() + .addLogRecordProcessor( + BatchLogRecordProcessor.builder( + OtlpGrpcLogRecordExporter.getDefault()) + .build()) + .build()) + .build(); + sdk.close(); + }) + .doesNotThrowAnyException(); + } +} From 38b24890afcb0f9b8261b32940d727733e1c208f Mon Sep 17 00:00:00 2001 From: jack-berg <34418638+jack-berg@users.noreply.github.com> Date: Thu, 11 Jan 2024 15:52:56 -0600 Subject: [PATCH 190/901] Fix graal (#6134) From c1490728c92812b4c047d9171734a86a03f8dd96 Mon Sep 17 00:00:00 2001 From: jack-berg <34418638+jack-berg@users.noreply.github.com> Date: Thu, 11 Jan 2024 15:53:10 -0600 Subject: [PATCH 191/901] Restore prometheus metric name mapper tests, fix regressions (#6138) --- .../prometheus/Otel2PrometheusConverter.java | 14 +- .../prometheus/PrometheusUnitsHelper.java | 4 +- .../Otel2PrometheusConverterTest.java | 224 ++++++++++++++++++ .../prometheus/PrometheusHttpServerTest.java | 54 +++-- .../prometheus/PrometheusUnitsHelperTest.java | 2 +- 5 files changed, 264 insertions(+), 34 deletions(-) create mode 100644 exporters/prometheus/src/test/java/io/opentelemetry/exporter/prometheus/Otel2PrometheusConverterTest.java diff --git a/exporters/prometheus/src/main/java/io/opentelemetry/exporter/prometheus/Otel2PrometheusConverter.java b/exporters/prometheus/src/main/java/io/opentelemetry/exporter/prometheus/Otel2PrometheusConverter.java index 67a5870015c..820f1f64d6a 100644 --- a/exporters/prometheus/src/main/java/io/opentelemetry/exporter/prometheus/Otel2PrometheusConverter.java +++ b/exporters/prometheus/src/main/java/io/opentelemetry/exporter/prometheus/Otel2PrometheusConverter.java @@ -183,8 +183,7 @@ private CounterSnapshot convertLongCounter( MetricMetadata metadata, InstrumentationScopeInfo scope, Collection dataPoints) { - List data = - new ArrayList(dataPoints.size()); + List data = new ArrayList<>(dataPoints.size()); for (LongPointData longData : dataPoints) { data.add( new CounterDataPointSnapshot( @@ -449,8 +448,14 @@ private static MetricMetadata convertMetadata(MetricData metricData) { String help = metricData.getDescription(); Unit unit = PrometheusUnitsHelper.convertUnit(metricData.getUnit()); if (unit != null && !name.endsWith(unit.toString())) { - name += "_" + unit; + // Need to re-sanitize metric name since unit may contain illegal characters + name = sanitizeMetricName(name + "_" + unit); + } + // Repeated __ are not allowed according to spec, although this is allowed in prometheus + while (name.contains("__")) { + name = name.replace("__", "_"); } + return new MetricMetadata(name, help, unit); } @@ -538,7 +543,8 @@ private static MetricMetadata mergeMetadata(MetricMetadata a, MetricMetadata b) "Conflicting metrics: Multiple metrics with name " + name + " but different units found. Dropping the one with unit " - + b.getUnit()); + + b.getUnit() + + "."); return null; } return new MetricMetadata(name, help, unit); diff --git a/exporters/prometheus/src/main/java/io/opentelemetry/exporter/prometheus/PrometheusUnitsHelper.java b/exporters/prometheus/src/main/java/io/opentelemetry/exporter/prometheus/PrometheusUnitsHelper.java index 9657b88ada5..db0503eb3fb 100644 --- a/exporters/prometheus/src/main/java/io/opentelemetry/exporter/prometheus/PrometheusUnitsHelper.java +++ b/exporters/prometheus/src/main/java/io/opentelemetry/exporter/prometheus/PrometheusUnitsHelper.java @@ -69,9 +69,7 @@ private static void initUnit(String otelName, String pluralName, String singular @Nullable static Unit convertUnit(String otelUnit) { - if (otelUnit.isEmpty() || otelUnit.equals("1")) { - // The spec says "1" should be translated to "ratio", but this is not implemented in the Java - // SDK. + if (otelUnit.isEmpty()) { return null; } if (otelUnit.contains("{")) { diff --git a/exporters/prometheus/src/test/java/io/opentelemetry/exporter/prometheus/Otel2PrometheusConverterTest.java b/exporters/prometheus/src/test/java/io/opentelemetry/exporter/prometheus/Otel2PrometheusConverterTest.java new file mode 100644 index 00000000000..6347d781498 --- /dev/null +++ b/exporters/prometheus/src/test/java/io/opentelemetry/exporter/prometheus/Otel2PrometheusConverterTest.java @@ -0,0 +1,224 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.exporter.prometheus; + +import static org.assertj.core.api.Assertions.assertThat; + +import io.opentelemetry.api.common.Attributes; +import io.opentelemetry.sdk.common.InstrumentationScopeInfo; +import io.opentelemetry.sdk.metrics.data.AggregationTemporality; +import io.opentelemetry.sdk.metrics.data.MetricData; +import io.opentelemetry.sdk.metrics.data.MetricDataType; +import io.opentelemetry.sdk.metrics.internal.data.ImmutableGaugeData; +import io.opentelemetry.sdk.metrics.internal.data.ImmutableHistogramData; +import io.opentelemetry.sdk.metrics.internal.data.ImmutableHistogramPointData; +import io.opentelemetry.sdk.metrics.internal.data.ImmutableLongPointData; +import io.opentelemetry.sdk.metrics.internal.data.ImmutableMetricData; +import io.opentelemetry.sdk.metrics.internal.data.ImmutableSumData; +import io.opentelemetry.sdk.metrics.internal.data.ImmutableSummaryData; +import io.opentelemetry.sdk.metrics.internal.data.ImmutableSummaryPointData; +import io.opentelemetry.sdk.resources.Resource; +import io.prometheus.metrics.expositionformats.ExpositionFormats; +import io.prometheus.metrics.model.snapshots.MetricSnapshots; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.nio.charset.StandardCharsets; +import java.util.Arrays; +import java.util.Collections; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import java.util.stream.Stream; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; + +class Otel2PrometheusConverterTest { + + private static final Pattern PATTERN = + Pattern.compile( + "# HELP (?.*)\n# TYPE (?.*)\n(?.*)\\{otel_scope_name=\"scope\"}(.|\\n)*"); + + private final Otel2PrometheusConverter converter = new Otel2PrometheusConverter(true); + + @ParameterizedTest + @MethodSource("metricMetadataArgs") + void metricMetadata( + MetricData metricData, String expectedType, String expectedHelp, String expectedMetricName) + throws IOException { + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + MetricSnapshots snapshots = converter.convert(Collections.singletonList(metricData)); + ExpositionFormats.init().getPrometheusTextFormatWriter().write(baos, snapshots); + String expositionFormat = new String(baos.toByteArray(), StandardCharsets.UTF_8); + + // Uncomment to debug exposition format output + // System.out.println(expositionFormat); + + Matcher matcher = PATTERN.matcher(expositionFormat); + assertThat(matcher.matches()).isTrue(); + assertThat(matcher.group("help")).isEqualTo(expectedHelp); + assertThat(matcher.group("type")).isEqualTo(expectedType); + // Note: Summaries and histograms produce output which matches METRIC_NAME_PATTERN multiple + // times. The pattern ends up matching against the first. + assertThat(matcher.group("metricName")).isEqualTo(expectedMetricName); + } + + private static Stream metricMetadataArgs() { + return Stream.of( + // the unity unit "1" is translated to "ratio" + Arguments.of( + createSampleMetricData("sample", "1", MetricDataType.LONG_GAUGE), + "sample_ratio gauge", + "sample_ratio description", + "sample_ratio"), + // unit is appended to metric name + Arguments.of( + createSampleMetricData("sample", "unit", MetricDataType.LONG_GAUGE), + "sample_unit gauge", + "sample_unit description", + "sample_unit"), + // units in curly braces are dropped + Arguments.of( + createSampleMetricData("sample", "1{dropped}", MetricDataType.LONG_GAUGE), + "sample_ratio gauge", + "sample_ratio description", + "sample_ratio"), + // monotonic sums always include _total suffix + Arguments.of( + createSampleMetricData("sample", "unit", MetricDataType.LONG_SUM), + "sample_unit_total counter", + "sample_unit_total description", + "sample_unit_total"), + Arguments.of( + createSampleMetricData("sample", "1", MetricDataType.LONG_SUM), + "sample_ratio_total counter", + "sample_ratio_total description", + "sample_ratio_total"), + // units expressed as numbers other than 1 are retained + Arguments.of( + createSampleMetricData("sample", "2", MetricDataType.LONG_SUM), + "sample_2_total counter", + "sample_2_total description", + "sample_2_total"), + Arguments.of( + createSampleMetricData("metric_name", "2", MetricDataType.SUMMARY), + "metric_name_2 summary", + "metric_name_2 description", + "metric_name_2_count"), + // unsupported characters are translated to "_", repeated "_" are dropped + Arguments.of( + createSampleMetricData("s%%ple", "%/min", MetricDataType.SUMMARY), + "s_ple_percent_per_minute summary", + "s_ple_percent_per_minute description", + "s_ple_percent_per_minute_count"), + // metric unit is not appended if the name already contains the unit + Arguments.of( + createSampleMetricData("metric_name_total", "total", MetricDataType.LONG_SUM), + "metric_name_total counter", + "metric_name_total description", + "metric_name_total"), + // total suffix is stripped because total is a reserved suffixed for monotonic sums + Arguments.of( + createSampleMetricData("metric_name_total", "total", MetricDataType.SUMMARY), + "metric_name summary", + "metric_name description", + "metric_name_count"), + // if metric name ends with unit the unit is omitted + Arguments.of( + createSampleMetricData("metric_name_ratio", "1", MetricDataType.LONG_GAUGE), + "metric_name_ratio gauge", + "metric_name_ratio description", + "metric_name_ratio"), + Arguments.of( + createSampleMetricData("metric_name_ratio", "1", MetricDataType.SUMMARY), + "metric_name_ratio summary", + "metric_name_ratio description", + "metric_name_ratio_count"), + Arguments.of( + createSampleMetricData("metric_hertz", "hertz", MetricDataType.LONG_GAUGE), + "metric_hertz gauge", + "metric_hertz description", + "metric_hertz"), + Arguments.of( + createSampleMetricData("metric_hertz", "hertz", MetricDataType.LONG_SUM), + "metric_hertz_total counter", + "metric_hertz_total description", + "metric_hertz_total"), + // if metric name ends with unit the unit is omitted - order matters + Arguments.of( + createSampleMetricData("metric_total_hertz", "hertz_total", MetricDataType.LONG_SUM), + "metric_total_hertz_hertz_total counter", + "metric_total_hertz_hertz_total description", + "metric_total_hertz_hertz_total"), + // metric name cannot start with a number + Arguments.of( + createSampleMetricData("2_metric_name", "By", MetricDataType.SUMMARY), + "_metric_name_bytes summary", + "_metric_name_bytes description", + "_metric_name_bytes_count")); + } + + static MetricData createSampleMetricData( + String metricName, String metricUnit, MetricDataType metricDataType) { + switch (metricDataType) { + case SUMMARY: + return ImmutableMetricData.createDoubleSummary( + Resource.getDefault(), + InstrumentationScopeInfo.create("scope"), + metricName, + "description", + metricUnit, + ImmutableSummaryData.create( + Collections.singletonList( + ImmutableSummaryPointData.create( + 0, 1, Attributes.empty(), 1, 1, Collections.emptyList())))); + case LONG_SUM: + return ImmutableMetricData.createLongSum( + Resource.getDefault(), + InstrumentationScopeInfo.create("scope"), + metricName, + "description", + metricUnit, + ImmutableSumData.create( + true, + AggregationTemporality.CUMULATIVE, + Collections.singletonList( + ImmutableLongPointData.create(0, 1, Attributes.empty(), 1L)))); + case LONG_GAUGE: + return ImmutableMetricData.createLongGauge( + Resource.getDefault(), + InstrumentationScopeInfo.create("scope"), + metricName, + "description", + metricUnit, + ImmutableGaugeData.create( + Collections.singletonList( + ImmutableLongPointData.create(0, 1, Attributes.empty(), 1L)))); + case HISTOGRAM: + return ImmutableMetricData.createDoubleHistogram( + Resource.getDefault(), + InstrumentationScopeInfo.create("scope"), + metricName, + "description", + metricUnit, + ImmutableHistogramData.create( + AggregationTemporality.CUMULATIVE, + Collections.singletonList( + ImmutableHistogramPointData.create( + 0, + 1, + Attributes.empty(), + 1, + false, + -1, + false, + -1, + Collections.singletonList(1.0), + Arrays.asList(0L, 1L))))); + default: + throw new IllegalArgumentException("Unsupported metric data type: " + metricDataType); + } + } +} diff --git a/exporters/prometheus/src/test/java/io/opentelemetry/exporter/prometheus/PrometheusHttpServerTest.java b/exporters/prometheus/src/test/java/io/opentelemetry/exporter/prometheus/PrometheusHttpServerTest.java index 9f172e83804..d899dddd122 100644 --- a/exporters/prometheus/src/test/java/io/opentelemetry/exporter/prometheus/PrometheusHttpServerTest.java +++ b/exporters/prometheus/src/test/java/io/opentelemetry/exporter/prometheus/PrometheusHttpServerTest.java @@ -115,12 +115,12 @@ void fetchPrometheus() { .isEqualTo("text/plain; version=0.0.4; charset=utf-8"); assertThat(response.contentUtf8()) .isEqualTo( - "# HELP grpc_name_total long_description\n" - + "# TYPE grpc_name_total counter\n" - + "grpc_name_total{kp=\"vp\",otel_scope_name=\"grpc\",otel_scope_version=\"version\"} 5.0\n" - + "# HELP http_name_total double_description\n" - + "# TYPE http_name_total counter\n" - + "http_name_total{kp=\"vp\",otel_scope_name=\"http\",otel_scope_version=\"version\"} 3.5\n" + "# HELP grpc_name_unit_total long_description\n" + + "# TYPE grpc_name_unit_total counter\n" + + "grpc_name_unit_total{kp=\"vp\",otel_scope_name=\"grpc\",otel_scope_version=\"version\"} 5.0\n" + + "# HELP http_name_unit_total double_description\n" + + "# TYPE http_name_unit_total counter\n" + + "http_name_unit_total{kp=\"vp\",otel_scope_name=\"http\",otel_scope_version=\"version\"} 3.5\n" + "# TYPE target_info gauge\n" + "target_info{kr=\"vr\"} 1\n"); } @@ -142,12 +142,14 @@ void fetchOpenMetrics() { .isEqualTo("application/openmetrics-text; version=1.0.0; charset=utf-8"); assertThat(response.contentUtf8()) .isEqualTo( - "# TYPE grpc_name counter\n" - + "# HELP grpc_name long_description\n" - + "grpc_name_total{kp=\"vp\",otel_scope_name=\"grpc\",otel_scope_version=\"version\"} 5.0\n" - + "# TYPE http_name counter\n" - + "# HELP http_name double_description\n" - + "http_name_total{kp=\"vp\",otel_scope_name=\"http\",otel_scope_version=\"version\"} 3.5\n" + "# TYPE grpc_name_unit counter\n" + + "# UNIT grpc_name_unit unit\n" + + "# HELP grpc_name_unit long_description\n" + + "grpc_name_unit_total{kp=\"vp\",otel_scope_name=\"grpc\",otel_scope_version=\"version\"} 5.0\n" + + "# TYPE http_name_unit counter\n" + + "# UNIT http_name_unit unit\n" + + "# HELP http_name_unit double_description\n" + + "http_name_unit_total{kp=\"vp\",otel_scope_name=\"http\",otel_scope_version=\"version\"} 3.5\n" + "# TYPE target info\n" + "target_info{kr=\"vr\"} 1\n" + "# EOF\n"); @@ -157,7 +159,7 @@ void fetchOpenMetrics() { void fetchFiltered() { AggregatedHttpResponse response = client - .get("/?name[]=grpc_name_total&name[]=bears_total&name[]=target_info") + .get("/?name[]=grpc_name_unit_total&name[]=bears_total&name[]=target_info") .aggregate() .join(); assertThat(response.status()).isEqualTo(HttpStatus.OK); @@ -166,9 +168,9 @@ void fetchFiltered() { assertThat(response.contentUtf8()) .isEqualTo( "" - + "# HELP grpc_name_total long_description\n" - + "# TYPE grpc_name_total counter\n" - + "grpc_name_total{kp=\"vp\",otel_scope_name=\"grpc\",otel_scope_version=\"version\"} 5.0\n" + + "# HELP grpc_name_unit_total long_description\n" + + "# TYPE grpc_name_unit_total counter\n" + + "grpc_name_unit_total{kp=\"vp\",otel_scope_name=\"grpc\",otel_scope_version=\"version\"} 5.0\n" + "# TYPE target_info gauge\n" + "target_info{kr=\"vr\"} 1\n"); } @@ -189,12 +191,12 @@ void fetchPrometheusCompressed() throws IOException { String content = new String(ByteStreams.toByteArray(gis), StandardCharsets.UTF_8); assertThat(content) .isEqualTo( - "# HELP grpc_name_total long_description\n" - + "# TYPE grpc_name_total counter\n" - + "grpc_name_total{kp=\"vp\",otel_scope_name=\"grpc\",otel_scope_version=\"version\"} 5.0\n" - + "# HELP http_name_total double_description\n" - + "# TYPE http_name_total counter\n" - + "http_name_total{kp=\"vp\",otel_scope_name=\"http\",otel_scope_version=\"version\"} 3.5\n" + "# HELP grpc_name_unit_total long_description\n" + + "# TYPE grpc_name_unit_total counter\n" + + "grpc_name_unit_total{kp=\"vp\",otel_scope_name=\"grpc\",otel_scope_version=\"version\"} 5.0\n" + + "# HELP http_name_unit_total double_description\n" + + "# TYPE http_name_unit_total counter\n" + + "http_name_unit_total{kp=\"vp\",otel_scope_name=\"http\",otel_scope_version=\"version\"} 3.5\n" + "# TYPE target_info gauge\n" + "target_info{kr=\"vr\"} 1\n"); } @@ -252,7 +254,7 @@ void fetch_DuplicateMetrics() { InstrumentationScopeInfo.create("scope3"), "foo_unit_total", "unused", - "unit", + "", ImmutableGaugeData.create( Collections.singletonList( ImmutableLongPointData.create(123, 456, Attributes.empty(), 3)))))); @@ -272,7 +274,7 @@ void fetch_DuplicateMetrics() { // Validate conflict warning message assertThat(logs.getEvents()).hasSize(1); logs.assertContains( - "Conflicting metric name foo_unit: Found one metric with type counter and one of type gauge. Dropping the one with type gauge."); + "Conflicting metrics: Multiple metrics with name foo_unit but different units found. Dropping the one with unit null."); } @Test @@ -318,7 +320,7 @@ private static List generateTestData() { InstrumentationScopeInfo.builder("grpc").setVersion("version").build(), "grpc.name", "long_description", - "1", + "unit", ImmutableSumData.create( /* isMonotonic= */ true, AggregationTemporality.CUMULATIVE, @@ -330,7 +332,7 @@ private static List generateTestData() { InstrumentationScopeInfo.builder("http").setVersion("version").build(), "http.name", "double_description", - "1", + "unit", ImmutableSumData.create( /* isMonotonic= */ true, AggregationTemporality.CUMULATIVE, diff --git a/exporters/prometheus/src/test/java/io/opentelemetry/exporter/prometheus/PrometheusUnitsHelperTest.java b/exporters/prometheus/src/test/java/io/opentelemetry/exporter/prometheus/PrometheusUnitsHelperTest.java index aa44005978d..658642c024a 100644 --- a/exporters/prometheus/src/test/java/io/opentelemetry/exporter/prometheus/PrometheusUnitsHelperTest.java +++ b/exporters/prometheus/src/test/java/io/opentelemetry/exporter/prometheus/PrometheusUnitsHelperTest.java @@ -70,7 +70,7 @@ private static Stream providePrometheusOTelUnitEquivalentPairs() { // Unit not found - Case sensitive Arguments.of("S", "S"), // Special case - 1 - Arguments.of("1", null), + Arguments.of("1", "ratio"), // Special Case - Drop metric units in {} Arguments.of("{packets}", null), // Special Case - Dropped metric units only in {} From 9c3af76ab90b42da1eea0070413b0da54e88a408 Mon Sep 17 00:00:00 2001 From: OpenTelemetry Bot <107717825+opentelemetrybot@users.noreply.github.com> Date: Fri, 12 Jan 2024 00:44:44 +0100 Subject: [PATCH 192/901] Merge change log updates from release/v1.34.x (#6145) --- CHANGELOG.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 09d69ff84ba..3fece48b3b4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,13 @@ ## Unreleased +## Version 1.34.1 (2024-01-11) + +* Fix prometheus exporter regressions + ([#6138](https://github.com/open-telemetry/opentelemetry-java/pull/6138)) +* Fix native image regression + ([#6134](https://github.com/open-telemetry/opentelemetry-java/pull/6134)) + ## Version 1.34.0 (2024-01-05) **NOTE:** This is the LAST release for `opentelemetry-exporter-jaeger` From 30c75b471512048d91035be213094582bed6e6fd Mon Sep 17 00:00:00 2001 From: jack-berg <34418638+jack-berg@users.noreply.github.com> Date: Fri, 12 Jan 2024 16:52:32 -0600 Subject: [PATCH 193/901] Delete jaeger exporters (#6119) --- README.md | 9 - all/build.gradle.kts | 3 - bom/build.gradle.kts | 2 + exporters/jaeger-proto/README.md | 3 - exporters/jaeger-proto/build.gradle.kts | 25 - .../main/proto/jaeger/api_v2/collector.proto | 23 - .../src/main/proto/jaeger/api_v2/model.proto | 89 ---- .../src/main/proto/jaeger/api_v2/time.proto | 58 --- exporters/jaeger-thrift/build.gradle.kts | 27 -- .../exporter/jaeger/thrift/Adapter.java | 277 ----------- .../thrift/JaegerThriftSpanExporter.java | 170 ------- .../JaegerThriftSpanExporterBuilder.java | 69 --- .../exporter/jaeger/thrift/package-info.java | 9 - .../exporter/jaeger/thrift/AdapterTest.java | 363 --------------- .../thrift/JaegerThriftIntegrationTest.java | 135 ------ .../thrift/JaegerThriftSpanExporterTest.java | 274 ----------- exporters/jaeger/build.gradle.kts | 48 -- .../exporter/jaeger/BatchMarshaler.java | 46 -- .../jaeger/JaegerGrpcSpanExporter.java | 124 ----- .../jaeger/JaegerGrpcSpanExporterBuilder.java | 160 ------- .../exporter/jaeger/KeyValueMarshaler.java | 132 ------ .../exporter/jaeger/LogMarshaler.java | 71 --- .../jaeger/MarshalerCollectorServiceGrpc.java | 88 ---- .../jaeger/PostSpansRequestMarshaler.java | 40 -- .../exporter/jaeger/PostSpansResponse.java | 15 - .../exporter/jaeger/ProcessMarshaler.java | 53 --- .../exporter/jaeger/SpanMarshaler.java | 186 -------- .../exporter/jaeger/SpanRefMarshaler.java | 71 --- .../exporter/jaeger/TimeMarshaler.java | 47 -- .../JaegerGrpcSpanExporterProvider.java | 48 -- .../exporter/jaeger/package-info.java | 9 - exporters/jaeger/src/main/proto/README.md | 1 - ...pi.traces.ConfigurableSpanExporterProvider | 1 - .../jaeger/JaegerGrpcSpanExporterTest.java | 422 ----------------- .../jaeger/JaegerIntegrationTest.java | 118 ----- .../jaeger/PostSpansRequestMarshalerTest.java | 437 ------------------ .../JaegerGrpcSpanExporterProviderTest.java | 69 --- .../src/test/resources/logback-test.xml | 14 - sdk-extensions/autoconfigure/build.gradle.kts | 1 - .../SpanExporterConfigurationTest.java | 3 - sdk/trace/build.gradle.kts | 1 - .../sdk/trace/ExporterBenchmark.java | 16 +- sdk/trace/src/jmh/resources/otel.yaml | 5 +- settings.gradle.kts | 3 - 44 files changed, 4 insertions(+), 3761 deletions(-) delete mode 100644 exporters/jaeger-proto/README.md delete mode 100644 exporters/jaeger-proto/build.gradle.kts delete mode 100644 exporters/jaeger-proto/src/main/proto/jaeger/api_v2/collector.proto delete mode 100644 exporters/jaeger-proto/src/main/proto/jaeger/api_v2/model.proto delete mode 100644 exporters/jaeger-proto/src/main/proto/jaeger/api_v2/time.proto delete mode 100644 exporters/jaeger-thrift/build.gradle.kts delete mode 100644 exporters/jaeger-thrift/src/main/java/io/opentelemetry/exporter/jaeger/thrift/Adapter.java delete mode 100644 exporters/jaeger-thrift/src/main/java/io/opentelemetry/exporter/jaeger/thrift/JaegerThriftSpanExporter.java delete mode 100644 exporters/jaeger-thrift/src/main/java/io/opentelemetry/exporter/jaeger/thrift/JaegerThriftSpanExporterBuilder.java delete mode 100644 exporters/jaeger-thrift/src/main/java/io/opentelemetry/exporter/jaeger/thrift/package-info.java delete mode 100644 exporters/jaeger-thrift/src/test/java/io/opentelemetry/exporter/jaeger/thrift/AdapterTest.java delete mode 100644 exporters/jaeger-thrift/src/test/java/io/opentelemetry/exporter/jaeger/thrift/JaegerThriftIntegrationTest.java delete mode 100644 exporters/jaeger-thrift/src/test/java/io/opentelemetry/exporter/jaeger/thrift/JaegerThriftSpanExporterTest.java delete mode 100644 exporters/jaeger/build.gradle.kts delete mode 100644 exporters/jaeger/src/main/java/io/opentelemetry/exporter/jaeger/BatchMarshaler.java delete mode 100644 exporters/jaeger/src/main/java/io/opentelemetry/exporter/jaeger/JaegerGrpcSpanExporter.java delete mode 100644 exporters/jaeger/src/main/java/io/opentelemetry/exporter/jaeger/JaegerGrpcSpanExporterBuilder.java delete mode 100644 exporters/jaeger/src/main/java/io/opentelemetry/exporter/jaeger/KeyValueMarshaler.java delete mode 100644 exporters/jaeger/src/main/java/io/opentelemetry/exporter/jaeger/LogMarshaler.java delete mode 100644 exporters/jaeger/src/main/java/io/opentelemetry/exporter/jaeger/MarshalerCollectorServiceGrpc.java delete mode 100644 exporters/jaeger/src/main/java/io/opentelemetry/exporter/jaeger/PostSpansRequestMarshaler.java delete mode 100644 exporters/jaeger/src/main/java/io/opentelemetry/exporter/jaeger/PostSpansResponse.java delete mode 100644 exporters/jaeger/src/main/java/io/opentelemetry/exporter/jaeger/ProcessMarshaler.java delete mode 100644 exporters/jaeger/src/main/java/io/opentelemetry/exporter/jaeger/SpanMarshaler.java delete mode 100644 exporters/jaeger/src/main/java/io/opentelemetry/exporter/jaeger/SpanRefMarshaler.java delete mode 100644 exporters/jaeger/src/main/java/io/opentelemetry/exporter/jaeger/TimeMarshaler.java delete mode 100644 exporters/jaeger/src/main/java/io/opentelemetry/exporter/jaeger/internal/JaegerGrpcSpanExporterProvider.java delete mode 100644 exporters/jaeger/src/main/java/io/opentelemetry/exporter/jaeger/package-info.java delete mode 100644 exporters/jaeger/src/main/proto/README.md delete mode 100644 exporters/jaeger/src/main/resources/META-INF/services/io.opentelemetry.sdk.autoconfigure.spi.traces.ConfigurableSpanExporterProvider delete mode 100644 exporters/jaeger/src/test/java/io/opentelemetry/exporter/jaeger/JaegerGrpcSpanExporterTest.java delete mode 100644 exporters/jaeger/src/test/java/io/opentelemetry/exporter/jaeger/JaegerIntegrationTest.java delete mode 100644 exporters/jaeger/src/test/java/io/opentelemetry/exporter/jaeger/PostSpansRequestMarshalerTest.java delete mode 100644 exporters/jaeger/src/test/java/io/opentelemetry/exporter/jaeger/internal/JaegerGrpcSpanExporterProviderTest.java delete mode 100644 exporters/jaeger/src/test/resources/logback-test.xml diff --git a/README.md b/README.md index c0425230e7c..f273a554485 100644 --- a/README.md +++ b/README.md @@ -265,8 +265,6 @@ dependency as follows, replacing `{{artifact-id}}` with the value from the "Arti | [OTLP Exporters](./exporters/otlp/all) | OTLP gRPC & HTTP exporters, including traces, metrics, and logs | `opentelemetry-exporter-otlp` | 1.34.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-otlp.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-otlp) | | [OTLP Logging Exporters](./exporters/logging-otlp) | Logging exporters in OTLP JSON encoding, including traces, metrics, and logs | `opentelemetry-exporter-logging-otlp` | 1.34.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-logging-otlp.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-logging-otlp) | | [OTLP Common](./exporters/otlp/common) | Shared OTLP components (internal) | `opentelemetry-exporter-otlp-common` | 1.34.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-otlp-common.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-otlp-common) | -| [Jaeger gRPC Exporter](./exporters/jaeger) | Jaeger gRPC trace exporter (deprecated [1]) | `opentelemetry-exporter-jaeger` | 1.34.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-jaeger.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-jaeger) | -| [Jaeger Thrift Exporter](./exporters/jaeger-thrift) | Jaeger thrift trace exporter (deprecated [1]) | `opentelemetry-exporter-jaeger-thift` | 1.34.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-jaeger-thrift.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-jaeger-thrift) | | [Logging Exporter](./exporters/logging) | Logging exporters, including metrics, traces, and logs | `opentelemetry-exporter-logging` | 1.34.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-logging.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-logging) | | [Zipkin Exporter](./exporters/zipkin) | Zipkin trace exporter | `opentelemetry-exporter-zipkin` | 1.34.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-zipkin.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-zipkin) | | [Prometheus Exporter](./exporters/prometheus) | Prometheus metric exporter | `opentelemetry-exporter-prometheus` | 1.34.0-alpha | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-prometheus.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-prometheus) | @@ -275,13 +273,6 @@ dependency as follows, replacing `{{artifact-id}}` with the value from the "Arti | [JDK Sender](./exporters/sender/okhttp) | Java 11+ native HttpClient implementation of HttpSender (internal) | `opentelemetry-exporter-sender-jdk` | 1.34.0-alpha | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-sender-jdk.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-sender-jdk) | | | [gRPC ManagedChannel Sender](./exporters/sender/grpc-managed-channel) | gRPC ManagedChannel implementation of GrpcSender (internal) | `opentelemetry-exporter-sender-grpc-managed-channel` | 1.34.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-sender-grpc-managed-channel.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-sender-grpc-managed-channel) | | -**[1]**: Jaeger now -has [native support for OTLP](https://opentelemetry.io/blog/2022/jaeger-native-otlp/) and jaeger -exporters are now deprecated. `opentelemetry-exporter-jaeger-thrift` will continue to be published -until 1.34.0 (January 2024) but no new PRs will be accepted except security related bugfixes. After -1.34.0, `io.opentelemetry:opentelemetry-bom` will reference the last published version, but no -additional versions will be published. - ### SDK Extensions | Component | Description | Artifact ID | Version | Javadoc | diff --git a/all/build.gradle.kts b/all/build.gradle.kts index aa302ed598b..874c93ae1c6 100644 --- a/all/build.gradle.kts +++ b/all/build.gradle.kts @@ -98,9 +98,6 @@ tasks.named("jacocoTestReport") { // Exclude mrjar (jacoco complains), shaded, and generated code !it.absolutePath.contains("META-INF/versions/") && !it.absolutePath.contains("/internal/shaded/") && - !it.absolutePath.contains("io/opentelemetry/proto/") && - !it.absolutePath.contains("io/opentelemetry/exporter/jaeger/proto/") && - !it.absolutePath.contains("io/opentelemetry/exporter/jaeger/internal/protobuf/") && !it.absolutePath.contains("io/opentelemetry/sdk/extension/trace/jaeger/proto/") && !it.absolutePath.contains("AutoValue_") }, diff --git a/bom/build.gradle.kts b/bom/build.gradle.kts index ae50cabc349..3b977ff1263 100644 --- a/bom/build.gradle.kts +++ b/bom/build.gradle.kts @@ -14,3 +14,5 @@ otelBom.addFallback("opentelemetry-extension-annotations", "1.18.0") otelBom.addFallback("opentelemetry-sdk-extension-resources", "1.19.0") otelBom.addFallback("opentelemetry-sdk-extension-aws", "1.19.0") otelBom.addFallback("opentelemetry-extension-aws", "1.20.1") +// NOTE: opentelemetry-exporter-jaeger and opentelemetry-exporter-jaeger-thift are omitted because +// they contain dependencies on internal classes, which may have breaking API changes preventing compilation. diff --git a/exporters/jaeger-proto/README.md b/exporters/jaeger-proto/README.md deleted file mode 100644 index f7e8a0497d8..00000000000 --- a/exporters/jaeger-proto/README.md +++ /dev/null @@ -1,3 +0,0 @@ -# OpenTelemetry - Jaeger Proto (DEPRECATED) - -> **NOTICE**: External use of this artifact is deprecated. diff --git a/exporters/jaeger-proto/build.gradle.kts b/exporters/jaeger-proto/build.gradle.kts deleted file mode 100644 index 165686f909d..00000000000 --- a/exporters/jaeger-proto/build.gradle.kts +++ /dev/null @@ -1,25 +0,0 @@ -plugins { - id("otel.protobuf-conventions") - - id("otel.animalsniffer-conventions") -} - -description = "OpenTelemetry - Jaeger Exporter Proto (Internal Use Only)" -otelJava.moduleName.set("io.opentelemetry.exporter.jaeger.proto") - -dependencies { - api("com.google.protobuf:protobuf-java") - - compileOnly("io.grpc:grpc-api") - compileOnly("io.grpc:grpc-protobuf") - compileOnly("io.grpc:grpc-stub") -} - -tasks { - compileJava { - with(options) { - // Generated code so can't control serialization. - compilerArgs.add("-Xlint:-serial") - } - } -} diff --git a/exporters/jaeger-proto/src/main/proto/jaeger/api_v2/collector.proto b/exporters/jaeger-proto/src/main/proto/jaeger/api_v2/collector.proto deleted file mode 100644 index 03d6b6be8ca..00000000000 --- a/exporters/jaeger-proto/src/main/proto/jaeger/api_v2/collector.proto +++ /dev/null @@ -1,23 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -syntax="proto3"; - -package jaeger.api_v2; - -import "jaeger/api_v2/model.proto"; - -option java_package = "io.opentelemetry.exporter.jaeger.proto.api_v2"; - -message PostSpansRequest { - Batch batch = 1; -} - -message PostSpansResponse { -} - -service CollectorService { - rpc PostSpans(PostSpansRequest) returns (PostSpansResponse) {} -} diff --git a/exporters/jaeger-proto/src/main/proto/jaeger/api_v2/model.proto b/exporters/jaeger-proto/src/main/proto/jaeger/api_v2/model.proto deleted file mode 100644 index 0d2bd212787..00000000000 --- a/exporters/jaeger-proto/src/main/proto/jaeger/api_v2/model.proto +++ /dev/null @@ -1,89 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -syntax="proto3"; - -package jaeger.api_v2; - -import "google/protobuf/timestamp.proto"; -import "google/protobuf/duration.proto"; - -option java_package = "io.opentelemetry.exporter.jaeger.proto.api_v2"; - -enum ValueType { - STRING = 0; - BOOL = 1; - INT64 = 2; - FLOAT64 = 3; - BINARY = 4; -}; - -message Log { - google.protobuf.Timestamp timestamp = 1; - repeated KeyValue fields = 2; -} - -message KeyValue { - string key = 1; - ValueType v_type = 2; - string v_str = 3; - bool v_bool = 4; - int64 v_int64 = 5; - double v_float64 = 6; - bytes v_binary = 7; -} - -enum SpanRefType { - CHILD_OF = 0; - FOLLOWS_FROM = 1; -}; - -message SpanRef { - bytes trace_id = 1; - bytes span_id = 2; - SpanRefType ref_type = 3; -} - -message Process { - string service_name = 1; - repeated KeyValue tags = 2; -} - -message Span { - bytes trace_id = 1; - bytes span_id = 2; - string operation_name = 3; - repeated SpanRef references = 4; - uint32 flags = 5; - google.protobuf.Timestamp start_time = 6; - google.protobuf.Duration duration = 7; - repeated KeyValue tags = 8; - repeated Log logs = 9; - Process process = 10; - string process_id = 11; - repeated string warnings = 12; -} - -message Trace { - message ProcessMapping { - string process_id = 1; - Process process = 2; - } - repeated Span spans = 1; - repeated ProcessMapping process_map = 2; - repeated string warnings = 3; -} - -message Batch { - repeated Span spans = 1; - Process process = 2; -} - -message DependencyLink { - string parent = 1; - string child = 2; - uint64 call_count = 3; - string source = 4; -} diff --git a/exporters/jaeger-proto/src/main/proto/jaeger/api_v2/time.proto b/exporters/jaeger-proto/src/main/proto/jaeger/api_v2/time.proto deleted file mode 100644 index b92529d7a56..00000000000 --- a/exporters/jaeger-proto/src/main/proto/jaeger/api_v2/time.proto +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -// Includes work from: - -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. All rights reserved. -// https://developers.google.com/protocol-buffers/ -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -syntax = "proto3"; - -package io.opentelemetry.internal; - -option java_package = "io.opentelemetry.exporter.jaeger.internal.protobuf"; -option java_outer_classname = "TimeProto"; -option java_multiple_files = true; - -// Copied from google.protobuf.Timestamp to provide access to the wire format. -message Time { - // Represents seconds of UTC time since Unix epoch - // 1970-01-01T00:00:00Z. Must be from 0001-01-01T00:00:00Z to - // 9999-12-31T23:59:59Z inclusive. - int64 seconds = 1; - - // Non-negative fractions of a second at nanosecond resolution. Negative - // second values with fractions must still have non-negative nanos values - // that count forward in time. Must be from 0 to 999,999,999 - // inclusive. - int32 nanos = 2; -} diff --git a/exporters/jaeger-thrift/build.gradle.kts b/exporters/jaeger-thrift/build.gradle.kts deleted file mode 100644 index 383b9d6943c..00000000000 --- a/exporters/jaeger-thrift/build.gradle.kts +++ /dev/null @@ -1,27 +0,0 @@ -plugins { - id("otel.java-conventions") - id("otel.publish-conventions") - - id("otel.animalsniffer-conventions") -} - -description = "OpenTelemetry - Jaeger Thrift Exporter" -otelJava.moduleName.set("io.opentelemetry.exporter.jaeger.thrift") - -dependencies { - api(project(":sdk:all")) - - implementation(project(":sdk:all")) - - implementation("com.fasterxml.jackson.jr:jackson-jr-objects") - implementation("io.jaegertracing:jaeger-client") { - exclude("com.google.code.gson", "gson") - } - - testImplementation("com.fasterxml.jackson.jr:jackson-jr-stree") - testImplementation("org.testcontainers:junit-jupiter") - testImplementation("com.squareup.okhttp3:okhttp") - testImplementation("com.google.guava:guava-testlib") - - testImplementation(project(":sdk:testing")) -} diff --git a/exporters/jaeger-thrift/src/main/java/io/opentelemetry/exporter/jaeger/thrift/Adapter.java b/exporters/jaeger-thrift/src/main/java/io/opentelemetry/exporter/jaeger/thrift/Adapter.java deleted file mode 100644 index cd3bf4ec26f..00000000000 --- a/exporters/jaeger-thrift/src/main/java/io/opentelemetry/exporter/jaeger/thrift/Adapter.java +++ /dev/null @@ -1,277 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package io.opentelemetry.exporter.jaeger.thrift; - -import static io.opentelemetry.api.common.AttributeKey.booleanKey; - -import com.fasterxml.jackson.jr.ob.JSON; -import io.jaegertracing.thriftjava.Log; -import io.jaegertracing.thriftjava.Span; -import io.jaegertracing.thriftjava.SpanRef; -import io.jaegertracing.thriftjava.SpanRefType; -import io.jaegertracing.thriftjava.Tag; -import io.jaegertracing.thriftjava.TagType; -import io.opentelemetry.api.common.AttributeKey; -import io.opentelemetry.api.common.Attributes; -import io.opentelemetry.api.trace.SpanKind; -import io.opentelemetry.api.trace.StatusCode; -import io.opentelemetry.sdk.trace.data.EventData; -import io.opentelemetry.sdk.trace.data.LinkData; -import io.opentelemetry.sdk.trace.data.SpanData; -import java.io.IOException; -import java.io.UncheckedIOException; -import java.math.BigInteger; -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; -import java.util.Locale; -import java.util.concurrent.TimeUnit; -import java.util.stream.Collectors; -import javax.annotation.concurrent.ThreadSafe; - -/** Adapts OpenTelemetry objects to Jaeger objects. */ -@ThreadSafe -final class Adapter { - - static final AttributeKey KEY_ERROR = booleanKey("error"); - static final String KEY_LOG_EVENT = "event"; - static final String KEY_EVENT_DROPPED_ATTRIBUTES_COUNT = "otel.event.dropped_attributes_count"; - static final String KEY_DROPPED_ATTRIBUTES_COUNT = "otel.dropped_attributes_count"; - static final String KEY_DROPPED_EVENTS_COUNT = "otel.dropped_events_count"; - static final String KEY_SPAN_KIND = "span.kind"; - static final String KEY_SPAN_STATUS_MESSAGE = "otel.status_message"; - static final String KEY_SPAN_STATUS_CODE = "otel.status_code"; - static final String KEY_INSTRUMENTATION_SCOPE_NAME = "otel.scope.name"; - static final String KEY_INSTRUMENTATION_SCOPE_VERSION = "otel.scope.version"; - static final String KEY_INSTRUMENTATION_LIBRARY_NAME = "otel.library.name"; - static final String KEY_INSTRUMENTATION_LIBRARY_VERSION = "otel.library.version"; - - private Adapter() {} - - /** - * Converts a list of {@link SpanData} into a collection of Jaeger's {@link Span}. - * - * @param spans the list of spans to be converted - * @return the collection of Jaeger spans - * @see #toJaeger(SpanData) - */ - static List toJaeger(Collection spans) { - return spans.stream().map(Adapter::toJaeger).collect(Collectors.toList()); - } - - /** - * Converts a single {@link SpanData} into a Jaeger's {@link Span}. - * - * @param span the span to be converted - * @return the Jaeger span - */ - static Span toJaeger(SpanData span) { - Span target = new Span(); - - long traceIdHigh = traceIdAsLongHigh(span.getTraceId()); - long traceIdLow = traceIdAsLongLow(span.getTraceId()); - - target.setTraceIdHigh(traceIdHigh); - target.setTraceIdLow(traceIdLow); - target.setSpanId(spanIdAsLong(span.getSpanId())); - target.setOperationName(span.getName()); - target.setStartTime(TimeUnit.NANOSECONDS.toMicros(span.getStartEpochNanos())); - target.setDuration( - TimeUnit.NANOSECONDS.toMicros(span.getEndEpochNanos() - span.getStartEpochNanos())); - - List tags = toTags(span.getAttributes()); - int droppedAttributes = span.getTotalAttributeCount() - span.getAttributes().size(); - if (droppedAttributes > 0) { - tags.add(new Tag(KEY_DROPPED_ATTRIBUTES_COUNT, TagType.LONG).setVLong(droppedAttributes)); - } - - target.setLogs(toJaegerLogs(span.getEvents())); - int droppedEvents = span.getTotalRecordedEvents() - span.getEvents().size(); - if (droppedEvents > 0) { - tags.add(new Tag(KEY_DROPPED_EVENTS_COUNT, TagType.LONG).setVLong(droppedEvents)); - } - - List references = toSpanRefs(span.getLinks()); - - // add the parent span - if (span.getParentSpanContext().isValid()) { - long parentSpanId = spanIdAsLong(span.getParentSpanId()); - references.add(new SpanRef(SpanRefType.CHILD_OF, traceIdLow, traceIdHigh, parentSpanId)); - target.setParentSpanId(parentSpanId); - } - target.setReferences(references); - - if (span.getKind() != SpanKind.INTERNAL) { - tags.add( - new Tag(KEY_SPAN_KIND, TagType.STRING) - .setVStr(span.getKind().name().toLowerCase(Locale.ROOT))); - } - - if (!span.getStatus().getDescription().isEmpty()) { - tags.add( - new Tag(KEY_SPAN_STATUS_MESSAGE, TagType.STRING) - .setVStr(span.getStatus().getDescription())); - } - - if (span.getStatus().getStatusCode() != StatusCode.UNSET) { - tags.add( - new Tag(KEY_SPAN_STATUS_CODE, TagType.STRING) - .setVStr(span.getStatus().getStatusCode().name())); - } - - tags.add( - new Tag(KEY_INSTRUMENTATION_SCOPE_NAME, TagType.STRING) - .setVStr(span.getInstrumentationScopeInfo().getName())); - // Include instrumentation library name for backwards compatibility - tags.add( - new Tag(KEY_INSTRUMENTATION_LIBRARY_NAME, TagType.STRING) - .setVStr(span.getInstrumentationScopeInfo().getName())); - - if (span.getInstrumentationScopeInfo().getVersion() != null) { - tags.add( - new Tag(KEY_INSTRUMENTATION_SCOPE_VERSION, TagType.STRING) - .setVStr(span.getInstrumentationScopeInfo().getVersion())); - // Include instrumentation library name for backwards compatibility - tags.add( - new Tag(KEY_INSTRUMENTATION_LIBRARY_VERSION, TagType.STRING) - .setVStr(span.getInstrumentationScopeInfo().getVersion())); - } - - if (span.getStatus().getStatusCode() == StatusCode.ERROR) { - tags.add(toTag(KEY_ERROR, true)); - } - target.setTags(tags); - - return target; - } - - /** - * Converts {@link EventData}s into a collection of Jaeger's {@link Log}. - * - * @param timedEvents the timed events to be converted - * @return a collection of Jaeger logs - * @see #toJaegerLog(EventData) - */ - // VisibleForTesting - static List toJaegerLogs(List timedEvents) { - return timedEvents.stream().map(Adapter::toJaegerLog).collect(Collectors.toList()); - } - - /** - * Converts a {@link EventData} into Jaeger's {@link Log}. - * - * @param event the timed event to be converted - * @return a Jaeger log - */ - // VisibleForTesting - static Log toJaegerLog(EventData event) { - Log result = new Log(); - result.setTimestamp(TimeUnit.NANOSECONDS.toMicros(event.getEpochNanos())); - result.addToFields(new Tag(KEY_LOG_EVENT, TagType.STRING).setVStr(event.getName())); - - int droppedAttributesCount = event.getDroppedAttributesCount(); - if (droppedAttributesCount > 0) { - result.addToFields( - new Tag(KEY_EVENT_DROPPED_ATTRIBUTES_COUNT, TagType.LONG) - .setVLong(droppedAttributesCount)); - } - List attributeTags = toTags(event.getAttributes()); - for (Tag attributeTag : attributeTags) { - result.addToFields(attributeTag); - } - return result; - } - - /** - * Converts a map of attributes into a collection of Jaeger's {@link Tag}. - * - * @param attributes the span attributes - * @return a collection of Jaeger key values - * @see #toTag - */ - static List toTags(Attributes attributes) { - List results = new ArrayList<>(); - attributes.forEach((key, value) -> results.add(toTag(key, value))); - return results; - } - - /** - * Converts the given {@link AttributeKey} and value into Jaeger's {@link Tag}. - * - * @param key the entry key as string - * @param value the entry value - * @return a Jaeger key value - */ - // VisibleForTesting - static Tag toTag(AttributeKey key, Object value) { - switch (key.getType()) { - case STRING: - return new Tag(key.getKey(), TagType.STRING).setVStr((String) value); - case LONG: - return new Tag(key.getKey(), TagType.LONG).setVLong((long) value); - case BOOLEAN: - return new Tag(key.getKey(), TagType.BOOL).setVBool((boolean) value); - case DOUBLE: - return new Tag(key.getKey(), TagType.DOUBLE).setVDouble((double) value); - default: - try { - return new Tag(key.getKey(), TagType.STRING).setVStr(JSON.std.asString(value)); - } catch (IOException e) { - // Can't have an exception serializing a plain Java object to a String. Add an exception - // mostly to satisfy the compiler. - throw new UncheckedIOException( - "Error serializing a plain Java object to String. " - + "This is a bug in the OpenTelemetry library.", - e); - } - } - } - - /** - * Converts {@link LinkData}s into a collection of Jaeger's {@link SpanRef}. - * - * @param links the span's links property to be converted - * @return a collection of Jaeger span references - */ - // VisibleForTesting - static List toSpanRefs(List links) { - List spanRefs = new ArrayList<>(links.size()); - for (LinkData link : links) { - spanRefs.add(toSpanRef(link)); - } - return spanRefs; - } - - /** - * Converts a single {@link LinkData} into a Jaeger's {@link SpanRef}. - * - * @param link the OpenTelemetry link to be converted - * @return the Jaeger span reference - */ - // VisibleForTesting - static SpanRef toSpanRef(LinkData link) { - // we can assume that all links are *follows from* - // https://github.com/open-telemetry/opentelemetry-java/issues/475 - // https://github.com/open-telemetry/opentelemetry-java/pull/481/files#r312577862 - return new SpanRef( - SpanRefType.FOLLOWS_FROM, - traceIdAsLongLow(link.getSpanContext().getTraceId()), - traceIdAsLongHigh(link.getSpanContext().getTraceId()), - spanIdAsLong(link.getSpanContext().getSpanId())); - } - - private static long traceIdAsLongHigh(String traceId) { - return new BigInteger(traceId.substring(0, 16), 16).longValue(); - } - - private static long traceIdAsLongLow(String traceId) { - return new BigInteger(traceId.substring(16, 32), 16).longValue(); - } - - private static long spanIdAsLong(String spanId) { - return new BigInteger(spanId, 16).longValue(); - } -} diff --git a/exporters/jaeger-thrift/src/main/java/io/opentelemetry/exporter/jaeger/thrift/JaegerThriftSpanExporter.java b/exporters/jaeger-thrift/src/main/java/io/opentelemetry/exporter/jaeger/thrift/JaegerThriftSpanExporter.java deleted file mode 100644 index bfab4122b05..00000000000 --- a/exporters/jaeger-thrift/src/main/java/io/opentelemetry/exporter/jaeger/thrift/JaegerThriftSpanExporter.java +++ /dev/null @@ -1,170 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package io.opentelemetry.exporter.jaeger.thrift; - -import io.jaegertracing.internal.exceptions.SenderException; -import io.jaegertracing.thrift.internal.senders.ThriftSender; -import io.jaegertracing.thriftjava.Process; -import io.jaegertracing.thriftjava.Span; -import io.jaegertracing.thriftjava.Tag; -import io.jaegertracing.thriftjava.TagType; -import io.opentelemetry.api.common.AttributeKey; -import io.opentelemetry.sdk.common.CompletableResultCode; -import io.opentelemetry.sdk.internal.ThrottlingLogger; -import io.opentelemetry.sdk.resources.Resource; -import io.opentelemetry.sdk.trace.data.SpanData; -import io.opentelemetry.sdk.trace.export.SpanExporter; -import java.net.InetAddress; -import java.net.UnknownHostException; -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; -import java.util.Map; -import java.util.concurrent.atomic.AtomicBoolean; -import java.util.logging.Level; -import java.util.logging.Logger; -import java.util.stream.Collectors; -import javax.annotation.concurrent.ThreadSafe; - -/** - * Exports spans to Jaeger via Thrift, using Jaeger's thrift model. - * - * @deprecated Use {@code OtlpGrpcSpanExporter} or {@code OtlpHttpSpanExporter} from opentelemetry-exporter-otlp - * instead. - */ -@ThreadSafe -@Deprecated -public final class JaegerThriftSpanExporter implements SpanExporter { - - private static final AttributeKey SERVICE_NAME = AttributeKey.stringKey("service.name"); - - static final String DEFAULT_ENDPOINT = "http://localhost:14268/api/traces"; - - private static final String DEFAULT_HOST_NAME = "unknown"; - private static final String CLIENT_VERSION_KEY = "jaeger.version"; - private static final String CLIENT_VERSION_VALUE = "opentelemetry-java"; - private static final String HOSTNAME_KEY = "hostname"; - private static final String IP_KEY = "ip"; - private static final String IP_DEFAULT = "0.0.0.0"; - - private final ThrottlingLogger logger = - new ThrottlingLogger(Logger.getLogger(JaegerThriftSpanExporter.class.getName())); - private final AtomicBoolean isShutdown = new AtomicBoolean(); - private final ThriftSender thriftSender; - private final Process process; - - /** - * Creates a new Jaeger gRPC Span Reporter with the given name, using the given channel. - * - * @param thriftSender The sender used for sending the data. - */ - JaegerThriftSpanExporter(ThriftSender thriftSender) { - this.thriftSender = thriftSender; - String hostname; - String ipv4; - - try { - hostname = InetAddress.getLocalHost().getHostName(); - ipv4 = InetAddress.getLocalHost().getHostAddress(); - } catch (UnknownHostException e) { - hostname = DEFAULT_HOST_NAME; - ipv4 = IP_DEFAULT; - } - - Tag clientTag = new Tag(CLIENT_VERSION_KEY, TagType.STRING).setVStr(CLIENT_VERSION_VALUE); - Tag ipv4Tag = new Tag(IP_KEY, TagType.STRING).setVStr(ipv4); - Tag hostnameTag = new Tag(HOSTNAME_KEY, TagType.STRING).setVStr(hostname); - - this.process = new Process(); - this.process.addToTags(clientTag); - this.process.addToTags(ipv4Tag); - this.process.addToTags(hostnameTag); - } - - /** - * Submits all the given spans in a single batch to the Jaeger collector. - * - * @param spans the list of sampled Spans to be exported. - * @return the result of the operation - */ - @Override - public CompletableResultCode export(Collection spans) { - if (isShutdown.get()) { - return CompletableResultCode.ofFailure(); - } - - Map> batches = - spans.stream().collect(Collectors.groupingBy(SpanData::getResource)).entrySet().stream() - .collect( - Collectors.toMap( - entry -> createProcess(entry.getKey()), - entry -> Adapter.toJaeger(entry.getValue()))); - List batchResults = new ArrayList<>(batches.size()); - batches.forEach( - (process, jaegerSpans) -> { - CompletableResultCode batchResult = new CompletableResultCode(); - batchResults.add(batchResult); - try { - // todo: consider making truly async - thriftSender.send(process, jaegerSpans); - batchResult.succeed(); - } catch (SenderException e) { - logger.log(Level.WARNING, "Failed to export spans", e); - batchResult.fail(); - } - }); - return CompletableResultCode.ofAll(batchResults); - } - - private Process createProcess(Resource resource) { - Process result = new Process(this.process); - - String serviceName = resource.getAttribute(SERVICE_NAME); - if (serviceName == null || serviceName.isEmpty()) { - serviceName = Resource.getDefault().getAttribute(SERVICE_NAME); - } - // In practice should never be null unless the default Resource spec is changed. - if (serviceName != null) { - result.setServiceName(serviceName); - } - - List tags = Adapter.toTags(resource.getAttributes()); - tags.forEach(result::addToTags); - return result; - } - - /** - * The Jaeger exporter does not batch spans, so this method will immediately return with success. - * - * @return always Success - */ - @Override - public CompletableResultCode flush() { - return CompletableResultCode.ofSuccess(); - } - - /** - * Returns a new builder instance for this exporter. - * - * @return a new builder instance for this exporter. - */ - public static JaegerThriftSpanExporterBuilder builder() { - return new JaegerThriftSpanExporterBuilder(); - } - - /** - * Initiates an orderly shutdown in which preexisting calls continue but new calls are immediately - * cancelled. - */ - @Override - public CompletableResultCode shutdown() { - if (!isShutdown.compareAndSet(false, true)) { - logger.log(Level.INFO, "Calling shutdown() multiple times."); - } - return CompletableResultCode.ofSuccess(); - } -} diff --git a/exporters/jaeger-thrift/src/main/java/io/opentelemetry/exporter/jaeger/thrift/JaegerThriftSpanExporterBuilder.java b/exporters/jaeger-thrift/src/main/java/io/opentelemetry/exporter/jaeger/thrift/JaegerThriftSpanExporterBuilder.java deleted file mode 100644 index faa88e53a21..00000000000 --- a/exporters/jaeger-thrift/src/main/java/io/opentelemetry/exporter/jaeger/thrift/JaegerThriftSpanExporterBuilder.java +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package io.opentelemetry.exporter.jaeger.thrift; - -import io.jaegertracing.thrift.internal.senders.HttpSender; -import io.jaegertracing.thrift.internal.senders.ThriftSender; -import javax.annotation.Nullable; -import org.apache.thrift.transport.TTransportException; - -/** - * Builder utility for this exporter. - * - * @deprecated Use {@code OtlpGrpcSpanExporter} or {@code OtlpHttpSpanExporter} from opentelemetry-exporter-otlp - * instead. - */ -@Deprecated -public final class JaegerThriftSpanExporterBuilder { - - private String endpoint = JaegerThriftSpanExporter.DEFAULT_ENDPOINT; - @Nullable private ThriftSender thriftSender; - - /** - * Explicitly set the {@link ThriftSender} instance to use for this Exporter. Will override any - * endpoint that has been set. - * - * @param thriftSender The ThriftSender to use. - * @return this. - */ - public JaegerThriftSpanExporterBuilder setThriftSender(ThriftSender thriftSender) { - this.thriftSender = thriftSender; - return this; - } - - /** - * Sets the Jaeger endpoint to connect to. Needs to include the full API path for trace ingest. - * - *

    Optional, defaults to "http://localhost:14268/api/traces". - * - * @param endpoint The Jaeger endpoint URL, ex. "https://jaegerhost:14268/api/traces". - * @return this. - */ - public JaegerThriftSpanExporterBuilder setEndpoint(String endpoint) { - this.endpoint = endpoint; - return this; - } - - /** - * Constructs a new instance of the exporter based on the builder's values. - * - * @return a new exporter's instance. - */ - public JaegerThriftSpanExporter build() { - ThriftSender thriftSender = this.thriftSender; - if (thriftSender == null) { - try { - thriftSender = new HttpSender.Builder(endpoint).build(); - } catch (TTransportException e) { - throw new IllegalStateException("Failed to construct a thrift HttpSender.", e); - } - } - return new JaegerThriftSpanExporter(thriftSender); - } - - JaegerThriftSpanExporterBuilder() {} -} diff --git a/exporters/jaeger-thrift/src/main/java/io/opentelemetry/exporter/jaeger/thrift/package-info.java b/exporters/jaeger-thrift/src/main/java/io/opentelemetry/exporter/jaeger/thrift/package-info.java deleted file mode 100644 index 1173e8d8452..00000000000 --- a/exporters/jaeger-thrift/src/main/java/io/opentelemetry/exporter/jaeger/thrift/package-info.java +++ /dev/null @@ -1,9 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -@ParametersAreNonnullByDefault -package io.opentelemetry.exporter.jaeger.thrift; - -import javax.annotation.ParametersAreNonnullByDefault; diff --git a/exporters/jaeger-thrift/src/test/java/io/opentelemetry/exporter/jaeger/thrift/AdapterTest.java b/exporters/jaeger-thrift/src/test/java/io/opentelemetry/exporter/jaeger/thrift/AdapterTest.java deleted file mode 100644 index a084b671a36..00000000000 --- a/exporters/jaeger-thrift/src/test/java/io/opentelemetry/exporter/jaeger/thrift/AdapterTest.java +++ /dev/null @@ -1,363 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package io.opentelemetry.exporter.jaeger.thrift; - -import static io.opentelemetry.api.common.AttributeKey.booleanArrayKey; -import static io.opentelemetry.api.common.AttributeKey.booleanKey; -import static io.opentelemetry.api.common.AttributeKey.doubleArrayKey; -import static io.opentelemetry.api.common.AttributeKey.doubleKey; -import static io.opentelemetry.api.common.AttributeKey.longArrayKey; -import static io.opentelemetry.api.common.AttributeKey.longKey; -import static io.opentelemetry.api.common.AttributeKey.stringArrayKey; -import static io.opentelemetry.api.common.AttributeKey.stringKey; -import static java.util.concurrent.TimeUnit.MILLISECONDS; -import static org.assertj.core.api.Assertions.assertThat; - -import com.google.common.io.BaseEncoding; -import io.jaegertracing.thriftjava.Log; -import io.jaegertracing.thriftjava.SpanRef; -import io.jaegertracing.thriftjava.SpanRefType; -import io.jaegertracing.thriftjava.Tag; -import io.opentelemetry.api.common.Attributes; -import io.opentelemetry.api.trace.SpanContext; -import io.opentelemetry.api.trace.SpanKind; -import io.opentelemetry.api.trace.StatusCode; -import io.opentelemetry.api.trace.TraceFlags; -import io.opentelemetry.api.trace.TraceState; -import io.opentelemetry.sdk.resources.Resource; -import io.opentelemetry.sdk.testing.trace.TestSpanData; -import io.opentelemetry.sdk.trace.data.EventData; -import io.opentelemetry.sdk.trace.data.LinkData; -import io.opentelemetry.sdk.trace.data.SpanData; -import io.opentelemetry.sdk.trace.data.StatusData; -import java.nio.ByteBuffer; -import java.nio.ByteOrder; -import java.util.Arrays; -import java.util.Collection; -import java.util.Collections; -import java.util.List; -import javax.annotation.Nullable; -import org.junit.jupiter.api.Test; - -/** Unit tests for {@link Adapter}. */ -class AdapterTest { - private static final BaseEncoding hex = BaseEncoding.base16().lowerCase(); - private static final String LINK_TRACE_ID = "ff000000000000000000000000cba123"; - private static final String LINK_SPAN_ID = "0000000000fed456"; - private static final String TRACE_ID = "0000000000000000ff00000000abc123"; - private static final String SPAN_ID = "ff00000000def456"; - private static final String PARENT_SPAN_ID = "0000000000aef789"; - - @Test - void testThriftSpans() { - long duration = 900; // ms - long startMs = System.currentTimeMillis(); - long endMs = startMs + duration; - - SpanData span = getSpanData(startMs, endMs, SpanKind.SERVER); - List spans = Collections.singletonList(span); - - List jaegerSpans = Adapter.toJaeger(spans); - - // the span contents are checked somewhere else - assertThat(jaegerSpans).hasSize(1); - } - - @Test - void testThriftSpan() { - long duration = 900; // ms - long startMs = System.currentTimeMillis(); - long endMs = startMs + duration; - - SpanData span = getSpanData(startMs, endMs, SpanKind.SERVER, 2, 4); - - // test - io.jaegertracing.thriftjava.Span jaegerSpan = Adapter.toJaeger(span); - - String rebuildTraceId = - traceIdFromLongs(jaegerSpan.getTraceIdHigh(), jaegerSpan.getTraceIdLow()); - assertThat(rebuildTraceId).isEqualTo(span.getTraceId()); - assertThat(spanIdFromLong(jaegerSpan.getSpanId())).isEqualTo(span.getSpanId()); - assertThat(jaegerSpan.getOperationName()).isEqualTo("GET /api/endpoint"); - assertThat(jaegerSpan.getStartTime()).isEqualTo(MILLISECONDS.toMicros(startMs)); - assertThat(jaegerSpan.getDuration()).isEqualTo(MILLISECONDS.toMicros(duration)); - - assertThat(jaegerSpan.getTagsSize()).isEqualTo(8); - assertThat(getValue(jaegerSpan.getTags(), Adapter.KEY_SPAN_KIND).getVStr()).isEqualTo("server"); - assertThat(getValue(jaegerSpan.getTags(), Adapter.KEY_SPAN_STATUS_CODE).getVLong()) - .isEqualTo(0); - assertThat(getValue(jaegerSpan.getTags(), Adapter.KEY_SPAN_STATUS_MESSAGE).getVStr()) - .isEqualTo("ok!"); - assertThat(getValue(jaegerSpan.getTags(), Adapter.KEY_DROPPED_EVENTS_COUNT).getVLong()) - .isEqualTo(1); - assertThat(getValue(jaegerSpan.getTags(), Adapter.KEY_DROPPED_ATTRIBUTES_COUNT).getVLong()) - .isEqualTo(3); - - assertThat(jaegerSpan.getLogsSize()).isEqualTo(1); - Log log = jaegerSpan.getLogs().get(0); - assertThat(getValue(log.getFields(), Adapter.KEY_LOG_EVENT).getVStr()) - .isEqualTo("the log message"); - assertThat(getValue(log.getFields(), "foo").getVStr()).isEqualTo("bar"); - - assertThat(jaegerSpan.getReferencesSize()).isEqualTo(2); - - assertHasFollowsFrom(jaegerSpan); - assertHasParent(jaegerSpan); - } - - @Test - void testThriftSpan_internal() { - long duration = 900; // ms - long startMs = System.currentTimeMillis(); - long endMs = startMs + duration; - - SpanData span = getSpanData(startMs, endMs, SpanKind.INTERNAL); - - // test - io.jaegertracing.thriftjava.Span jaegerSpan = Adapter.toJaeger(span); - - assertThat(jaegerSpan.getTagsSize()).isEqualTo(5); - assertThat(getValue(jaegerSpan.getTags(), Adapter.KEY_SPAN_KIND)).isNull(); - } - - @Test - void testJaegerLogs() { - // prepare - EventData eventsData = getTimedEvent(); - - // test - Collection logs = Adapter.toJaegerLogs(Collections.singletonList(eventsData)); - - // verify - assertThat(logs).hasSize(1); - } - - @Test - void testJaegerLog() { - // prepare - EventData event = getTimedEvent(); - - // test - Log log = Adapter.toJaegerLog(event); - - // verify - assertThat(log.getFieldsSize()).isEqualTo(2); - - assertThat(getValue(log.getFields(), Adapter.KEY_LOG_EVENT).getVStr()) - .isEqualTo("the log message"); - assertThat(getValue(log.getFields(), "foo").getVStr()).isEqualTo("bar"); - assertThat(getValue(log.getFields(), Adapter.KEY_EVENT_DROPPED_ATTRIBUTES_COUNT)).isNull(); - } - - @Test - void jaegerLog_droppedAttributes() { - EventData event = getTimedEvent(3); - - // test - Log log = Adapter.toJaegerLog(event); - - // verify - assertThat(getValue(log.getFields(), Adapter.KEY_EVENT_DROPPED_ATTRIBUTES_COUNT).getVLong()) - .isEqualTo(2); - } - - @Test - void testKeyValue() { - // test - Tag kvB = Adapter.toTag(booleanKey("valueB"), true); - Tag kvD = Adapter.toTag(doubleKey("valueD"), 1.); - Tag kvI = Adapter.toTag(longKey("valueI"), 2L); - Tag kvS = Adapter.toTag(stringKey("valueS"), "foobar"); - Tag kvArrayB = Adapter.toTag(booleanArrayKey("valueArrayB"), Arrays.asList(true, false)); - Tag kvArrayD = Adapter.toTag(doubleArrayKey("valueArrayD"), Arrays.asList(1.2345, 6.789)); - Tag kvArrayI = Adapter.toTag(longArrayKey("valueArrayI"), Arrays.asList(12345L, 67890L)); - Tag kvArrayS = Adapter.toTag(stringArrayKey("valueArrayS"), Arrays.asList("foobar", "barfoo")); - - // verify - assertThat(kvB.isVBool()).isTrue(); - - assertThat(kvD.getVDouble()).isEqualTo(1); - assertThat(kvI.getVLong()).isEqualTo(2); - assertThat(kvS.getVStr()).isEqualTo("foobar"); - assertThat(kvArrayB.getVStr()).isEqualTo("[true,false]"); - assertThat(kvArrayD.getVStr()).isEqualTo("[1.2345,6.789]"); - assertThat(kvArrayI.getVStr()).isEqualTo("[12345,67890]"); - assertThat(kvArrayS.getVStr()).isEqualTo("[\"foobar\",\"barfoo\"]"); - } - - @Test - void testSpanRefs() { - // prepare - LinkData link = - LinkData.create(createSpanContext("00000000000000000000000000cba123", "0000000000fed456")); - - // test - Collection spanRefs = Adapter.toSpanRefs(Collections.singletonList(link)); - - // verify - assertThat(spanRefs).hasSize(1); // the actual span ref is tested in another test - } - - @Test - void testSpanRef() { - // prepare - LinkData link = LinkData.create(createSpanContext(TRACE_ID, SPAN_ID)); - - // test - SpanRef spanRef = Adapter.toSpanRef(link); - - // verify - assertThat(spanIdFromLong(spanRef.getSpanId())).isEqualTo(SPAN_ID); - assertThat(traceIdFromLongs(spanRef.getTraceIdHigh(), spanRef.getTraceIdLow())) - .isEqualTo(TRACE_ID); - assertThat(spanRef.getRefType()).isEqualTo(SpanRefType.FOLLOWS_FROM); - } - - @Test - void testStatusNotUnset() { - long startMs = System.currentTimeMillis(); - long endMs = startMs + 900; - SpanData span = - TestSpanData.builder() - .setHasEnded(true) - .setSpanContext(createSpanContext(TRACE_ID, SPAN_ID)) - .setName("GET /api/endpoint") - .setStartEpochNanos(MILLISECONDS.toNanos(startMs)) - .setEndEpochNanos(MILLISECONDS.toNanos(endMs)) - .setKind(SpanKind.SERVER) - .setStatus(StatusData.error()) - .setTotalRecordedEvents(0) - .setTotalRecordedLinks(0) - .build(); - - assertThat(Adapter.toJaeger(span)).isNotNull(); - } - - @Test - void testSpanError() { - Attributes attributes = - Attributes.of( - stringKey("error.type"), - this.getClass().getName(), - stringKey("error.message"), - "server error"); - long startMs = System.currentTimeMillis(); - long endMs = startMs + 900; - SpanData span = - TestSpanData.builder() - .setHasEnded(true) - .setSpanContext(createSpanContext(TRACE_ID, SPAN_ID)) - .setName("GET /api/endpoint") - .setStartEpochNanos(MILLISECONDS.toNanos(startMs)) - .setEndEpochNanos(MILLISECONDS.toNanos(endMs)) - .setKind(SpanKind.SERVER) - .setStatus(StatusData.error()) - .setAttributes(attributes) - .setTotalRecordedEvents(0) - .setTotalRecordedLinks(0) - .build(); - - io.jaegertracing.thriftjava.Span jaegerSpan = Adapter.toJaeger(span); - assertThat(getValue(jaegerSpan.getTags(), "error.type").getVStr()) - .isEqualTo(this.getClass().getName()); - assertThat(getValue(jaegerSpan.getTags(), "error").isVBool()).isTrue(); - } - - private static EventData getTimedEvent() { - return getTimedEvent(-1); - } - - private static EventData getTimedEvent(int totalAttributeCount) { - long epochNanos = MILLISECONDS.toNanos(System.currentTimeMillis()); - Attributes attributes = Attributes.of(stringKey("foo"), "bar"); - if (totalAttributeCount <= 0) { - totalAttributeCount = attributes.size(); - } - return EventData.create(epochNanos, "the log message", attributes, totalAttributeCount); - } - - private static SpanData getSpanData(long startMs, long endMs, SpanKind kind) { - return getSpanData(startMs, endMs, kind, 1, 1); - } - - private static SpanData getSpanData( - long startMs, long endMs, SpanKind kind, int totalRecordedEvents, int totalAttributeCount) { - Attributes attributes = Attributes.of(booleanKey("valueB"), true); - - LinkData link = LinkData.create(createSpanContext(LINK_TRACE_ID, LINK_SPAN_ID), attributes); - - return TestSpanData.builder() - .setHasEnded(true) - .setSpanContext(createSpanContext(TRACE_ID, SPAN_ID)) - .setParentSpanContext( - SpanContext.create( - TRACE_ID, PARENT_SPAN_ID, TraceFlags.getDefault(), TraceState.getDefault())) - .setName("GET /api/endpoint") - .setStartEpochNanos(MILLISECONDS.toNanos(startMs)) - .setEndEpochNanos(MILLISECONDS.toNanos(endMs)) - .setAttributes(Attributes.of(booleanKey("valueB"), true)) - .setTotalAttributeCount(totalAttributeCount) - .setEvents(Collections.singletonList(getTimedEvent())) - .setTotalRecordedEvents(totalRecordedEvents) - .setLinks(Collections.singletonList(link)) - .setTotalRecordedLinks(1) - .setKind(kind) - .setResource(Resource.create(Attributes.empty())) - .setStatus(StatusData.create(StatusCode.OK, "ok!")) - .build(); - } - - private static SpanContext createSpanContext(String traceId, String spanId) { - return SpanContext.create(traceId, spanId, TraceFlags.getDefault(), TraceState.getDefault()); - } - - @Nullable - private static Tag getValue(List tagsList, String s) { - for (Tag kv : tagsList) { - if (kv.getKey().equals(s)) { - return kv; - } - } - return null; - } - - private static void assertHasFollowsFrom(io.jaegertracing.thriftjava.Span jaegerSpan) { - boolean found = false; - for (SpanRef spanRef : jaegerSpan.getReferences()) { - - if (SpanRefType.FOLLOWS_FROM.equals(spanRef.getRefType())) { - assertThat(traceIdFromLongs(spanRef.getTraceIdHigh(), spanRef.getTraceIdLow())) - .isEqualTo(LINK_TRACE_ID); - assertThat(spanIdFromLong(spanRef.getSpanId())).isEqualTo(LINK_SPAN_ID); - found = true; - } - } - assertThat(found).isTrue(); - } - - private static void assertHasParent(io.jaegertracing.thriftjava.Span jaegerSpan) { - boolean found = false; - for (SpanRef spanRef : jaegerSpan.getReferences()) { - if (SpanRefType.CHILD_OF.equals(spanRef.getRefType())) { - assertThat(traceIdFromLongs(spanRef.getTraceIdHigh(), spanRef.getTraceIdLow())) - .isEqualTo(TRACE_ID); - assertThat(spanIdFromLong(spanRef.getSpanId())).isEqualTo(PARENT_SPAN_ID); - found = true; - } - } - assertThat(found).isTrue(); - assertThat(spanIdFromLong(jaegerSpan.getParentSpanId())).isEqualTo(PARENT_SPAN_ID); - } - - private static String traceIdFromLongs(long high, long low) { - return hex.encode( - ByteBuffer.allocate(16).order(ByteOrder.BIG_ENDIAN).putLong(high).putLong(low).array()); - } - - private static String spanIdFromLong(long id) { - return hex.encode(ByteBuffer.allocate(8).order(ByteOrder.BIG_ENDIAN).putLong(id).array()); - } -} diff --git a/exporters/jaeger-thrift/src/test/java/io/opentelemetry/exporter/jaeger/thrift/JaegerThriftIntegrationTest.java b/exporters/jaeger-thrift/src/test/java/io/opentelemetry/exporter/jaeger/thrift/JaegerThriftIntegrationTest.java deleted file mode 100644 index fe95b30894b..00000000000 --- a/exporters/jaeger-thrift/src/test/java/io/opentelemetry/exporter/jaeger/thrift/JaegerThriftIntegrationTest.java +++ /dev/null @@ -1,135 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package io.opentelemetry.exporter.jaeger.thrift; - -import static io.opentelemetry.api.common.AttributeKey.stringKey; - -import com.fasterxml.jackson.core.TreeNode; -import com.fasterxml.jackson.jr.ob.JSON; -import com.fasterxml.jackson.jr.stree.JacksonJrsTreeCodec; -import io.jaegertracing.thrift.internal.senders.UdpSender; -import io.opentelemetry.api.OpenTelemetry; -import io.opentelemetry.api.trace.Span; -import io.opentelemetry.sdk.OpenTelemetrySdk; -import io.opentelemetry.sdk.resources.Resource; -import io.opentelemetry.sdk.trace.SdkTracerProvider; -import io.opentelemetry.sdk.trace.export.SimpleSpanProcessor; -import java.time.Duration; -import okhttp3.OkHttpClient; -import okhttp3.Request; -import okhttp3.Response; -import org.apache.thrift.transport.TTransportException; -import org.awaitility.Awaitility; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.ValueSource; -import org.slf4j.LoggerFactory; -import org.testcontainers.containers.GenericContainer; -import org.testcontainers.containers.output.Slf4jLogConsumer; -import org.testcontainers.containers.wait.strategy.Wait; -import org.testcontainers.images.PullPolicy; -import org.testcontainers.junit.jupiter.Container; -import org.testcontainers.junit.jupiter.Testcontainers; - -@Testcontainers(disabledWithoutDocker = true) -@SuppressWarnings("deprecation") // Testing deprecated code -class JaegerThriftIntegrationTest { - private static final OkHttpClient client = new OkHttpClient(); - - private static final int QUERY_PORT = 16686; - private static final int THRIFT_HTTP_PORT = 14268; - - private static final int THRIFT_UDP_PORT = 6831; - private static final int HEALTH_PORT = 14269; - private static final String SERVICE_NAME = "E2E-test"; - private static final String JAEGER_URL = "http://localhost"; - - @Container - public static final GenericContainer jaegerContainer = - new GenericContainer<>("ghcr.io/open-telemetry/opentelemetry-java/jaeger:1.32") - .withImagePullPolicy(PullPolicy.alwaysPull()) - .withExposedPorts(THRIFT_HTTP_PORT, THRIFT_UDP_PORT, QUERY_PORT, HEALTH_PORT) - .withLogConsumer(new Slf4jLogConsumer(LoggerFactory.getLogger("jaeger"))) - .waitingFor(Wait.forHttp("/").forPort(HEALTH_PORT)); - - @ParameterizedTest - @ValueSource(booleans = {false, true}) - void testJaegerIntegration(boolean udp) { - OpenTelemetry openTelemetry = initOpenTelemetry(udp); - imitateWork(openTelemetry); - Awaitility.await() - .atMost(Duration.ofSeconds(30)) - .until(JaegerThriftIntegrationTest::assertJaegerHasATrace); - } - - private static OpenTelemetry initOpenTelemetry(boolean udp) { - JaegerThriftSpanExporterBuilder jaegerExporter = JaegerThriftSpanExporter.builder(); - - if (udp) { - int mappedPort = jaegerContainer.getMappedPort(THRIFT_UDP_PORT); - try { - jaegerExporter.setThriftSender(new UdpSender("localhost", mappedPort, 0)); - } catch (TTransportException e) { - throw new IllegalStateException(e); - } - } else { - int mappedPort = jaegerContainer.getMappedPort(THRIFT_HTTP_PORT); - jaegerExporter.setEndpoint(JAEGER_URL + ":" + mappedPort + "/api/traces"); - } - - return OpenTelemetrySdk.builder() - .setTracerProvider( - SdkTracerProvider.builder() - .addSpanProcessor(SimpleSpanProcessor.create(jaegerExporter.build())) - .setResource( - Resource.getDefault().toBuilder() - .put(stringKey("service.name"), SERVICE_NAME) - .build()) - .build()) - .build(); - } - - private void imitateWork(OpenTelemetry openTelemetry) { - Span span = - openTelemetry.getTracer(getClass().getCanonicalName()).spanBuilder("Test span").startSpan(); - span.addEvent("some event"); - try { - Thread.sleep(1000); - } catch (InterruptedException e) { - throw new RuntimeException(e); - } - span.end(); - } - - private static boolean assertJaegerHasATrace() { - try { - Integer mappedPort = jaegerContainer.getMappedPort(QUERY_PORT); - String url = - String.format( - "%s/api/traces?service=%s", - String.format(JAEGER_URL + ":%d", mappedPort), SERVICE_NAME); - - Request request = - new Request.Builder() - .url(url) - .header("Content-Type", "application/json") - .header("Accept", "application/json") - .build(); - - TreeNode json; - try (Response response = client.newCall(request).execute()) { - json = - JSON.builder() - .treeCodec(new JacksonJrsTreeCodec()) - .build() - .treeFrom(response.body().byteStream()); - } - - return json.get("data").get(0).get("traceID") != null; - } catch (Exception e) { - return false; - } - } -} diff --git a/exporters/jaeger-thrift/src/test/java/io/opentelemetry/exporter/jaeger/thrift/JaegerThriftSpanExporterTest.java b/exporters/jaeger-thrift/src/test/java/io/opentelemetry/exporter/jaeger/thrift/JaegerThriftSpanExporterTest.java deleted file mode 100644 index f90ceddbad7..00000000000 --- a/exporters/jaeger-thrift/src/test/java/io/opentelemetry/exporter/jaeger/thrift/JaegerThriftSpanExporterTest.java +++ /dev/null @@ -1,274 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package io.opentelemetry.exporter.jaeger.thrift; - -import static io.opentelemetry.api.common.AttributeKey.stringKey; -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.Mockito.verify; - -import io.github.netmikey.logunit.api.LogCapturer; -import io.jaegertracing.internal.exceptions.SenderException; -import io.jaegertracing.thrift.internal.senders.ThriftSender; -import io.jaegertracing.thriftjava.Process; -import io.jaegertracing.thriftjava.Span; -import io.jaegertracing.thriftjava.SpanRef; -import io.jaegertracing.thriftjava.SpanRefType; -import io.jaegertracing.thriftjava.Tag; -import io.jaegertracing.thriftjava.TagType; -import io.opentelemetry.api.common.Attributes; -import io.opentelemetry.api.trace.SpanContext; -import io.opentelemetry.api.trace.SpanKind; -import io.opentelemetry.api.trace.TraceFlags; -import io.opentelemetry.api.trace.TraceState; -import io.opentelemetry.internal.testing.slf4j.SuppressLogger; -import io.opentelemetry.sdk.common.CompletableResultCode; -import io.opentelemetry.sdk.common.InstrumentationScopeInfo; -import io.opentelemetry.sdk.resources.Resource; -import io.opentelemetry.sdk.testing.trace.TestSpanData; -import io.opentelemetry.sdk.trace.data.SpanData; -import io.opentelemetry.sdk.trace.data.StatusData; -import java.net.InetAddress; -import java.net.UnknownHostException; -import java.time.Duration; -import java.util.Arrays; -import java.util.Collections; -import java.util.List; -import java.util.concurrent.TimeUnit; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.junit.jupiter.api.extension.RegisterExtension; -import org.mockito.Mock; -import org.mockito.junit.jupiter.MockitoExtension; - -@ExtendWith(MockitoExtension.class) -@SuppressWarnings("deprecation") // Testing deprecated code -class JaegerThriftSpanExporterTest { - - private static final String TRACE_ID = "a0000000000000000000000000abc123"; - private static final long TRACE_ID_HIGH = 0xa000000000000000L; - private static final long TRACE_ID_LOW = 0x0000000000abc123L; - private static final String SPAN_ID = "00000f0000def456"; - private static final long SPAN_ID_LONG = 0x00000f0000def456L; - private static final String SPAN_ID_2 = "00a0000000aef789"; - private static final long SPAN_ID_2_LONG = 0x00a0000000aef789L; - private static final SpanContext SPAN_CONTEXT = - SpanContext.create(TRACE_ID, SPAN_ID, TraceFlags.getDefault(), TraceState.getDefault()); - private static final SpanContext SPAN_CONTEXT_2 = - SpanContext.create(TRACE_ID, SPAN_ID_2, TraceFlags.getDefault(), TraceState.getDefault()); - private static final Duration DURATION = Duration.ofMillis(900); - - @RegisterExtension - LogCapturer logs = LogCapturer.create().captureForType(JaegerThriftSpanExporter.class); - - private JaegerThriftSpanExporter exporter; - @Mock private ThriftSender thriftSender; - - @BeforeEach - void beforeEach() { - exporter = JaegerThriftSpanExporter.builder().setThriftSender(thriftSender).build(); - } - - @Test - void testExport() throws SenderException, UnknownHostException { - SpanData span = - testSpanData( - Resource.create( - Attributes.of( - stringKey("service.name"), - "myServiceName", - stringKey("resource-attr-key"), - "resource-attr-value")), - "GET /api/endpoint", - SPAN_CONTEXT, - SPAN_CONTEXT_2); - - // test - CompletableResultCode result = exporter.export(Collections.singletonList(span)); - result.join(1, TimeUnit.SECONDS); - assertThat(result.isSuccess()).isEqualTo(true); - - // verify - Process expectedProcess = new Process("myServiceName"); - expectedProcess.addToTags( - new Tag("jaeger.version", TagType.STRING).setVStr("opentelemetry-java")); - expectedProcess.addToTags( - new Tag("ip", TagType.STRING).setVStr(InetAddress.getLocalHost().getHostAddress())); - expectedProcess.addToTags( - new Tag("hostname", TagType.STRING).setVStr(InetAddress.getLocalHost().getHostName())); - expectedProcess.addToTags( - new Tag("resource-attr-key", TagType.STRING).setVStr("resource-attr-value")); - expectedProcess.addToTags(new Tag("service.name", TagType.STRING).setVStr("myServiceName")); - - Span expectedSpan = - new Span() - .setTraceIdHigh(TRACE_ID_HIGH) - .setTraceIdLow(TRACE_ID_LOW) - .setSpanId(SPAN_ID_LONG) - .setOperationName("GET /api/endpoint") - .setReferences( - Collections.singletonList( - new SpanRef() - .setSpanId(SPAN_ID_2_LONG) - .setTraceIdHigh(TRACE_ID_HIGH) - .setTraceIdLow(TRACE_ID_LOW) - .setRefType(SpanRefType.CHILD_OF))) - .setParentSpanId(SPAN_ID_2_LONG) - .setStartTime(TimeUnit.NANOSECONDS.toMicros(span.getStartEpochNanos())) - .setDuration(DURATION.toMillis() * 1000) - .setLogs(Collections.emptyList()); - expectedSpan.addToTags(new Tag("span.kind", TagType.STRING).setVStr("consumer")); - expectedSpan.addToTags(new Tag("otel.status_code", TagType.STRING).setVStr("OK")); - expectedSpan.addToTags( - new Tag("otel.scope.name", TagType.STRING).setVStr("io.opentelemetry.auto")); - expectedSpan.addToTags( - new Tag("otel.library.name", TagType.STRING).setVStr("io.opentelemetry.auto")); - expectedSpan.addToTags(new Tag("otel.scope.version", TagType.STRING).setVStr("1.0.0")); - expectedSpan.addToTags(new Tag("otel.library.version", TagType.STRING).setVStr("1.0.0")); - - List expectedSpans = Collections.singletonList(expectedSpan); - verify(thriftSender).send(expectedProcess, expectedSpans); - } - - @Test - void testExportMultipleResources() throws SenderException, UnknownHostException { - SpanData span = - testSpanData( - Resource.create( - Attributes.of( - stringKey("service.name"), - "myServiceName1", - stringKey("resource-attr-key-1"), - "resource-attr-value-1")), - "GET /api/endpoint/1", - SPAN_CONTEXT, - SpanContext.getInvalid()); - - SpanData span2 = - testSpanData( - Resource.create( - Attributes.of( - stringKey("service.name"), - "myServiceName2", - stringKey("resource-attr-key-2"), - "resource-attr-value-2")), - "GET /api/endpoint/2", - SPAN_CONTEXT_2, - SpanContext.getInvalid()); - - // test - CompletableResultCode result = exporter.export(Arrays.asList(span, span2)); - result.join(1, TimeUnit.SECONDS); - assertThat(result.isSuccess()).isEqualTo(true); - - // verify - Process expectedProcess1 = new Process("myServiceName1"); - expectedProcess1.addToTags( - new Tag("jaeger.version", TagType.STRING).setVStr("opentelemetry-java")); - expectedProcess1.addToTags( - new Tag("ip", TagType.STRING).setVStr(InetAddress.getLocalHost().getHostAddress())); - expectedProcess1.addToTags( - new Tag("hostname", TagType.STRING).setVStr(InetAddress.getLocalHost().getHostName())); - expectedProcess1.addToTags( - new Tag("resource-attr-key-1", TagType.STRING).setVStr("resource-attr-value-1")); - expectedProcess1.addToTags(new Tag("service.name", TagType.STRING).setVStr("myServiceName1")); - - Process expectedProcess2 = new Process("myServiceName2"); - expectedProcess2.addToTags( - new Tag("jaeger.version", TagType.STRING).setVStr("opentelemetry-java")); - expectedProcess2.addToTags( - new Tag("ip", TagType.STRING).setVStr(InetAddress.getLocalHost().getHostAddress())); - expectedProcess2.addToTags( - new Tag("hostname", TagType.STRING).setVStr(InetAddress.getLocalHost().getHostName())); - expectedProcess2.addToTags( - new Tag("resource-attr-key-2", TagType.STRING).setVStr("resource-attr-value-2")); - expectedProcess2.addToTags(new Tag("service.name", TagType.STRING).setVStr("myServiceName2")); - - Span expectedSpan1 = - new Span() - .setTraceIdHigh(TRACE_ID_HIGH) - .setTraceIdLow(TRACE_ID_LOW) - .setSpanId(SPAN_ID_LONG) - .setOperationName("GET /api/endpoint/1") - .setReferences(Collections.emptyList()) - .setStartTime(TimeUnit.NANOSECONDS.toMicros(span.getStartEpochNanos())) - .setDuration(DURATION.toMillis() * 1000) - .setLogs(Collections.emptyList()); - expectedSpan1.addToTags(new Tag("span.kind", TagType.STRING).setVStr("consumer")); - expectedSpan1.addToTags(new Tag("otel.status_code", TagType.STRING).setVStr("OK")); - expectedSpan1.addToTags( - new Tag("otel.scope.name", TagType.STRING).setVStr("io.opentelemetry.auto")); - expectedSpan1.addToTags( - new Tag("otel.library.name", TagType.STRING).setVStr("io.opentelemetry.auto")); - expectedSpan1.addToTags(new Tag("otel.scope.version", TagType.STRING).setVStr("1.0.0")); - expectedSpan1.addToTags(new Tag("otel.library.version", TagType.STRING).setVStr("1.0.0")); - - Span expectedSpan2 = - new Span() - .setTraceIdHigh(TRACE_ID_HIGH) - .setTraceIdLow(TRACE_ID_LOW) - .setSpanId(SPAN_ID_2_LONG) - .setOperationName("GET /api/endpoint/2") - .setReferences(Collections.emptyList()) - .setStartTime(TimeUnit.NANOSECONDS.toMicros(span2.getStartEpochNanos())) - .setDuration(DURATION.toMillis() * 1000) - .setLogs(Collections.emptyList()); - expectedSpan2.addToTags(new Tag("span.kind", TagType.STRING).setVStr("consumer")); - expectedSpan2.addToTags(new Tag("otel.status_code", TagType.STRING).setVStr("OK")); - expectedSpan2.addToTags( - new Tag("otel.scope.name", TagType.STRING).setVStr("io.opentelemetry.auto")); - expectedSpan2.addToTags( - new Tag("otel.library.name", TagType.STRING).setVStr("io.opentelemetry.auto")); - expectedSpan2.addToTags(new Tag("otel.scope.version", TagType.STRING).setVStr("1.0.0")); - expectedSpan2.addToTags(new Tag("otel.library.version", TagType.STRING).setVStr("1.0.0")); - - verify(thriftSender).send(expectedProcess2, Collections.singletonList(expectedSpan2)); - verify(thriftSender).send(expectedProcess1, Collections.singletonList(expectedSpan1)); - } - - @Test - @SuppressLogger(JaegerThriftSpanExporter.class) - void shutdown() { - assertThat(exporter.shutdown().join(1, TimeUnit.SECONDS).isSuccess()).isTrue(); - assertThat(logs.getEvents()).isEmpty(); - assertThat( - exporter - .export( - Collections.singletonList( - testSpanData( - Resource.getDefault(), - "span name", - SPAN_CONTEXT, - SpanContext.getInvalid()))) - .join(10, TimeUnit.SECONDS) - .isSuccess()) - .isFalse(); - assertThat(exporter.shutdown().join(1, TimeUnit.SECONDS).isSuccess()).isTrue(); - logs.assertContains("Calling shutdown() multiple times."); - } - - private static SpanData testSpanData( - Resource resource, String spanName, SpanContext spanContext, SpanContext parentContext) { - long startMs = System.currentTimeMillis(); - long endMs = startMs + DURATION.toMillis(); - return TestSpanData.builder() - .setHasEnded(true) - .setSpanContext(spanContext) - .setParentSpanContext(parentContext) - .setName(spanName) - .setStartEpochNanos(TimeUnit.MILLISECONDS.toNanos(startMs)) - .setEndEpochNanos(TimeUnit.MILLISECONDS.toNanos(endMs)) - .setStatus(StatusData.ok()) - .setKind(SpanKind.CONSUMER) - .setLinks(Collections.emptyList()) - .setTotalRecordedLinks(0) - .setTotalRecordedEvents(0) - .setInstrumentationScopeInfo( - InstrumentationScopeInfo.builder("io.opentelemetry.auto").setVersion("1.0.0").build()) - .setResource(resource) - .build(); - } -} diff --git a/exporters/jaeger/build.gradle.kts b/exporters/jaeger/build.gradle.kts deleted file mode 100644 index f59e6d62042..00000000000 --- a/exporters/jaeger/build.gradle.kts +++ /dev/null @@ -1,48 +0,0 @@ -plugins { - id("otel.java-conventions") - id("otel.publish-conventions") - - id("otel.animalsniffer-conventions") - - id("com.squareup.wire") -} - -description = "OpenTelemetry - Jaeger Exporter" -otelJava.moduleName.set("io.opentelemetry.exporter.jaeger") - -dependencies { - api(project(":sdk:all")) - - protoSource(project(":exporters:jaeger-proto")) - - implementation(project(":exporters:common")) - implementation(project(":exporters:sender:okhttp")) - implementation(project(":sdk-extensions:autoconfigure-spi")) - - compileOnly("io.grpc:grpc-stub") - - implementation("com.fasterxml.jackson.jr:jackson-jr-objects") - - testImplementation(project(":exporters:jaeger-proto")) - - testImplementation("com.fasterxml.jackson.jr:jackson-jr-stree") - testImplementation("com.google.protobuf:protobuf-java-util") - testImplementation("com.linecorp.armeria:armeria-junit5") - testImplementation("com.linecorp.armeria:armeria-grpc-protocol") - testImplementation("com.squareup.okhttp3:okhttp") - testImplementation("org.testcontainers:junit-jupiter") - - testImplementation(project(":sdk:testing")) -} - -wire { - custom { - schemaHandlerFactoryClass = "io.opentelemetry.gradle.ProtoFieldsWireHandlerFactory" - } -} - -afterEvaluate { - tasks.getByName("generateMainProtos") { - setDependsOn(configurations.getByName("protoPath")) - } -} diff --git a/exporters/jaeger/src/main/java/io/opentelemetry/exporter/jaeger/BatchMarshaler.java b/exporters/jaeger/src/main/java/io/opentelemetry/exporter/jaeger/BatchMarshaler.java deleted file mode 100644 index 4900b7a47d9..00000000000 --- a/exporters/jaeger/src/main/java/io/opentelemetry/exporter/jaeger/BatchMarshaler.java +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package io.opentelemetry.exporter.jaeger; - -import io.opentelemetry.exporter.internal.marshal.MarshalerUtil; -import io.opentelemetry.exporter.internal.marshal.MarshalerWithSize; -import io.opentelemetry.exporter.internal.marshal.Serializer; -import io.opentelemetry.exporter.jaeger.proto.api_v2.internal.Batch; -import io.opentelemetry.sdk.resources.Resource; -import io.opentelemetry.sdk.trace.data.SpanData; -import java.io.IOException; -import java.util.List; - -final class BatchMarshaler extends MarshalerWithSize { - - private final SpanMarshaler[] spans; - private final ProcessMarshaler process; - - static BatchMarshaler create(List spans, Resource resource) { - SpanMarshaler[] spanMarshalers = SpanMarshaler.createRepeated(spans); - ProcessMarshaler processMarshaler = ProcessMarshaler.create(resource); - return new BatchMarshaler(spanMarshalers, processMarshaler); - } - - BatchMarshaler(SpanMarshaler[] spans, ProcessMarshaler process) { - super(calculateSize(spans, process)); - this.spans = spans; - this.process = process; - } - - @Override - protected void writeTo(Serializer output) throws IOException { - output.serializeRepeatedMessage(Batch.SPANS, spans); - output.serializeMessage(Batch.PROCESS, process); - } - - private static int calculateSize(SpanMarshaler[] spans, ProcessMarshaler process) { - int size = 0; - size += MarshalerUtil.sizeRepeatedMessage(Batch.SPANS, spans); - size += MarshalerUtil.sizeMessage(Batch.PROCESS, process); - return size; - } -} diff --git a/exporters/jaeger/src/main/java/io/opentelemetry/exporter/jaeger/JaegerGrpcSpanExporter.java b/exporters/jaeger/src/main/java/io/opentelemetry/exporter/jaeger/JaegerGrpcSpanExporter.java deleted file mode 100644 index acaa3ea42ad..00000000000 --- a/exporters/jaeger/src/main/java/io/opentelemetry/exporter/jaeger/JaegerGrpcSpanExporter.java +++ /dev/null @@ -1,124 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package io.opentelemetry.exporter.jaeger; - -import io.opentelemetry.api.common.AttributeKey; -import io.opentelemetry.exporter.internal.grpc.GrpcExporter; -import io.opentelemetry.sdk.common.CompletableResultCode; -import io.opentelemetry.sdk.resources.Resource; -import io.opentelemetry.sdk.trace.data.SpanData; -import io.opentelemetry.sdk.trace.export.SpanExporter; -import java.net.InetAddress; -import java.net.UnknownHostException; -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; -import java.util.stream.Collectors; -import javax.annotation.concurrent.ThreadSafe; - -/** - * Exports spans to Jaeger via gRPC, using Jaeger's protobuf model. - * - * @deprecated Use {@code OtlpGrpcSpanExporter} or {@code OtlpHttpSpanExporter} from opentelemetry-exporter-otlp - * instead. - */ -@ThreadSafe -@Deprecated -public final class JaegerGrpcSpanExporter implements SpanExporter { - - private static final String DEFAULT_HOST_NAME = "unknown"; - private static final AttributeKey CLIENT_VERSION_KEY = - AttributeKey.stringKey("jaeger.version"); - private static final String CLIENT_VERSION_VALUE = "opentelemetry-java"; - private static final AttributeKey HOSTNAME_KEY = AttributeKey.stringKey("hostname"); - private static final String IP_DEFAULT = "0.0.0.0"; - // Visible for testing - static final AttributeKey IP_KEY = AttributeKey.stringKey("ip"); - - private final GrpcExporter delegate; - - // Jaeger-specific resource information - private final Resource jaegerResource; - - JaegerGrpcSpanExporter(GrpcExporter delegate) { - this.delegate = delegate; - - String hostname; - String ipv4; - - try { - hostname = InetAddress.getLocalHost().getHostName(); - ipv4 = InetAddress.getLocalHost().getHostAddress(); - } catch (UnknownHostException e) { - hostname = DEFAULT_HOST_NAME; - ipv4 = IP_DEFAULT; - } - - jaegerResource = - Resource.builder() - .put(CLIENT_VERSION_KEY, CLIENT_VERSION_VALUE) - .put(IP_KEY, ipv4) - .put(HOSTNAME_KEY, hostname) - .build(); - } - - /** - * Submits all the given spans in a single batch to the Jaeger collector. - * - * @param spans the list of sampled Spans to be exported. - * @return the result of the operation - */ - @Override - public CompletableResultCode export(Collection spans) { - List results = new ArrayList<>(); - spans.stream() - .collect(Collectors.groupingBy(SpanData::getResource)) - .forEach( - (resource, spanData) -> - results.add(delegate.export(buildRequest(resource, spanData), spanData.size()))); - - return CompletableResultCode.ofAll(results); - } - - private PostSpansRequestMarshaler buildRequest(Resource resource, List spans) { - Resource mergedResource = jaegerResource.merge(resource); - return PostSpansRequestMarshaler.create(spans, mergedResource); - } - - /** - * The Jaeger exporter does not batch spans, so this method will immediately return with success. - * - * @return always Success - */ - @Override - public CompletableResultCode flush() { - return CompletableResultCode.ofSuccess(); - } - - /** - * Returns a new builder instance for this exporter. - * - * @return a new builder instance for this exporter. - */ - public static JaegerGrpcSpanExporterBuilder builder() { - return new JaegerGrpcSpanExporterBuilder(); - } - - /** - * Initiates an orderly shutdown in which preexisting calls continue but new calls are immediately - * cancelled. - */ - @Override - public CompletableResultCode shutdown() { - return delegate.shutdown(); - } - - // Visible for testing - Resource getJaegerResource() { - return jaegerResource; - } -} diff --git a/exporters/jaeger/src/main/java/io/opentelemetry/exporter/jaeger/JaegerGrpcSpanExporterBuilder.java b/exporters/jaeger/src/main/java/io/opentelemetry/exporter/jaeger/JaegerGrpcSpanExporterBuilder.java deleted file mode 100644 index 4255401ae00..00000000000 --- a/exporters/jaeger/src/main/java/io/opentelemetry/exporter/jaeger/JaegerGrpcSpanExporterBuilder.java +++ /dev/null @@ -1,160 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package io.opentelemetry.exporter.jaeger; - -import static io.opentelemetry.api.internal.Utils.checkArgument; -import static java.util.Objects.requireNonNull; - -import io.grpc.ManagedChannel; -import io.opentelemetry.api.GlobalOpenTelemetry; -import io.opentelemetry.api.metrics.MeterProvider; -import io.opentelemetry.exporter.internal.grpc.GrpcExporterBuilder; -import java.net.URI; -import java.time.Duration; -import java.util.concurrent.TimeUnit; -import javax.net.ssl.SSLContext; -import javax.net.ssl.X509TrustManager; - -/** - * Builder utility for this exporter. - * - * @deprecated Use {@code OtlpGrpcSpanExporter} or {@code OtlpHttpSpanExporter} from opentelemetry-exporter-otlp - * instead. - */ -@Deprecated -public final class JaegerGrpcSpanExporterBuilder { - - private static final String GRPC_SERVICE_NAME = "jaeger.api_v2.CollectorService"; - - // Visible for testing - static final String GRPC_ENDPOINT_PATH = "/" + GRPC_SERVICE_NAME + "/PostSpans"; - - private static final String DEFAULT_ENDPOINT_URL = "http://localhost:14250"; - private static final URI DEFAULT_ENDPOINT = URI.create(DEFAULT_ENDPOINT_URL); - private static final long DEFAULT_TIMEOUT_SECS = 10; - - private final GrpcExporterBuilder delegate; - - JaegerGrpcSpanExporterBuilder() { - delegate = - new GrpcExporterBuilder<>( - "jaeger", - "span", - DEFAULT_TIMEOUT_SECS, - DEFAULT_ENDPOINT, - () -> MarshalerCollectorServiceGrpc::newFutureStub, - GRPC_ENDPOINT_PATH); - } - - /** - * Sets the managed channel to use when communicating with the backend. Takes precedence over - * {@link #setEndpoint(String)} if both are called. - * - * @param channel the channel to use. - * @return this. - * @deprecated Use {@link #setEndpoint(String)}. If you have a use case not satisfied by the - * methods on this builder, please file an issue to let us know what it is. - */ - @Deprecated - public JaegerGrpcSpanExporterBuilder setChannel(ManagedChannel channel) { - delegate.setChannel(channel); - return this; - } - - /** - * Sets the Jaeger endpoint to connect to. If unset, defaults to {@value DEFAULT_ENDPOINT_URL}. - * The endpoint must start with either http:// or https://. - */ - public JaegerGrpcSpanExporterBuilder setEndpoint(String endpoint) { - requireNonNull(endpoint, "endpoint"); - delegate.setEndpoint(endpoint); - return this; - } - - /** - * Sets the method used to compress payloads. If unset, compression is disabled. Currently - * supported compression methods include "gzip" and "none". - * - * @since 1.20.0 - */ - public JaegerGrpcSpanExporterBuilder setCompression(String compressionMethod) { - requireNonNull(compressionMethod, "compressionMethod"); - checkArgument( - compressionMethod.equals("gzip") || compressionMethod.equals("none"), - "Unsupported compression method. Supported compression methods include: gzip, none."); - delegate.setCompression(compressionMethod); - return this; - } - - /** - * Sets the maximum time to wait for the collector to process an exported batch of spans. If - * unset, defaults to {@value DEFAULT_TIMEOUT_SECS}s. - */ - public JaegerGrpcSpanExporterBuilder setTimeout(long timeout, TimeUnit unit) { - requireNonNull(unit, "unit"); - checkArgument(timeout >= 0, "timeout must be non-negative"); - delegate.setTimeout(timeout, unit); - return this; - } - - /** - * Sets the maximum time to wait for the collector to process an exported batch of spans. If - * unset, defaults to {@value DEFAULT_TIMEOUT_SECS}s. - */ - public JaegerGrpcSpanExporterBuilder setTimeout(Duration timeout) { - requireNonNull(timeout, "timeout"); - delegate.setTimeout(timeout); - return this; - } - - /** - * Sets the certificate chain to use for verifying servers when TLS is enabled. The {@code byte[]} - * should contain an X.509 certificate collection in PEM format. If not set, TLS connections will - * use the system default trusted certificates. - */ - public JaegerGrpcSpanExporterBuilder setTrustedCertificates(byte[] trustedCertificatesPem) { - delegate.setTrustManagerFromCerts(trustedCertificatesPem); - return this; - } - - /** Sets the client key and chain to use for verifying servers when mTLS is enabled. */ - public JaegerGrpcSpanExporterBuilder setClientTls(byte[] privateKeyPem, byte[] certificatePem) { - delegate.setKeyManagerFromCerts(privateKeyPem, certificatePem); - return this; - } - - /** - * Sets the "bring-your-own" SSLContext for use with TLS. Users should call this _or_ set raw - * certificate bytes, but not both. - */ - public JaegerGrpcSpanExporterBuilder setSslContext( - SSLContext sslContext, X509TrustManager trustManager) { - delegate.setSslContext(sslContext, trustManager); - return this; - } - - /** - * Sets the {@link MeterProvider} to use to collect metrics related to export. If not set, uses - * {@link GlobalOpenTelemetry#getMeterProvider()}. - * - * @since 1.15.0 - */ - public JaegerGrpcSpanExporterBuilder setMeterProvider(MeterProvider meterProvider) { - requireNonNull(meterProvider, "meterProvider"); - delegate.setMeterProvider(() -> meterProvider); - return this; - } - - /** - * Constructs a new instance of the exporter based on the builder's values. - * - * @return a new exporter's instance. - */ - public JaegerGrpcSpanExporter build() { - return new JaegerGrpcSpanExporter(delegate.build()); - } -} diff --git a/exporters/jaeger/src/main/java/io/opentelemetry/exporter/jaeger/KeyValueMarshaler.java b/exporters/jaeger/src/main/java/io/opentelemetry/exporter/jaeger/KeyValueMarshaler.java deleted file mode 100644 index 09f8b2f5734..00000000000 --- a/exporters/jaeger/src/main/java/io/opentelemetry/exporter/jaeger/KeyValueMarshaler.java +++ /dev/null @@ -1,132 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package io.opentelemetry.exporter.jaeger; - -import com.fasterxml.jackson.jr.ob.JSON; -import io.opentelemetry.api.common.AttributeKey; -import io.opentelemetry.api.common.Attributes; -import io.opentelemetry.exporter.internal.marshal.MarshalerUtil; -import io.opentelemetry.exporter.internal.marshal.MarshalerWithSize; -import io.opentelemetry.exporter.internal.marshal.ProtoEnumInfo; -import io.opentelemetry.exporter.internal.marshal.Serializer; -import io.opentelemetry.exporter.jaeger.proto.api_v2.internal.KeyValue; -import io.opentelemetry.exporter.jaeger.proto.api_v2.internal.ValueType; -import java.io.IOException; -import java.util.ArrayList; -import java.util.List; - -@SuppressWarnings({ - "checkstyle:LocalVariableName", - "checkstyle:MemberName", - "checkstyle:ParameterName", -}) -final class KeyValueMarshaler extends MarshalerWithSize { - - private static final byte[] EMPTY_BYTES = new byte[0]; - - private final byte[] keyUtf8; - private final ProtoEnumInfo valueType; - private final byte[] vStrUtf8; - private final boolean vBool; - private final long vInt64; - private final double vFloat64; - - static List createRepeated(Attributes attributes) { - if (attributes.isEmpty()) { - return new ArrayList<>(); - } - - List marshalers = new ArrayList<>(attributes.size()); - attributes.forEach((attributeKey, o) -> marshalers.add(create(attributeKey, o))); - return marshalers; - } - - static KeyValueMarshaler create(AttributeKey key, Object value) { - byte[] keyUtf8 = MarshalerUtil.toBytes(key.getKey()); - - // Default is the 0 value, string in this case - ProtoEnumInfo valueType = ValueType.STRING; - byte[] vStrUtf8 = EMPTY_BYTES; - boolean vBool = false; - long vInt64 = 0; - double vFloat64 = 0; - - switch (key.getType()) { - case STRING: - valueType = ValueType.STRING; - vStrUtf8 = MarshalerUtil.toBytes(((String) value)); - break; - case BOOLEAN: - valueType = ValueType.BOOL; - vBool = (boolean) value; - break; - case LONG: - valueType = ValueType.INT64; - vInt64 = (long) value; - break; - case DOUBLE: - valueType = ValueType.FLOAT64; - vFloat64 = (double) value; - break; - case STRING_ARRAY: - case BOOLEAN_ARRAY: - case LONG_ARRAY: - case DOUBLE_ARRAY: - valueType = ValueType.STRING; - try { - vStrUtf8 = JSON.std.asBytes(value); - } catch (IOException e) { - // Can't happen, just ignore it. - } - break; - } - - return new KeyValueMarshaler(keyUtf8, valueType, vStrUtf8, vBool, vInt64, vFloat64); - } - - KeyValueMarshaler( - byte[] keyUtf8, - ProtoEnumInfo valueType, - byte[] vStrUtf8, - boolean vBool, - long vInt64, - double vFloat64) { - super(calculateSize(keyUtf8, valueType, vStrUtf8, vBool, vInt64, vFloat64)); - this.keyUtf8 = keyUtf8; - this.valueType = valueType; - this.vStrUtf8 = vStrUtf8; - this.vBool = vBool; - this.vInt64 = vInt64; - this.vFloat64 = vFloat64; - } - - @Override - protected void writeTo(Serializer output) throws IOException { - output.serializeString(KeyValue.KEY, keyUtf8); - output.serializeEnum(KeyValue.V_TYPE, valueType); - output.serializeString(KeyValue.V_STR, vStrUtf8); - output.serializeBool(KeyValue.V_BOOL, vBool); - output.serializeInt64(KeyValue.V_INT64, vInt64); - output.serializeDouble(KeyValue.V_FLOAT64, vFloat64); - } - - private static int calculateSize( - byte[] keyUtf8, - ProtoEnumInfo valueType, - byte[] vStrUtf8, - boolean vBool, - long vInt64, - double vFloat64) { - int size = 0; - size += MarshalerUtil.sizeBytes(KeyValue.KEY, keyUtf8); - size += MarshalerUtil.sizeEnum(KeyValue.V_TYPE, valueType); - size += MarshalerUtil.sizeBytes(KeyValue.V_STR, vStrUtf8); - size += MarshalerUtil.sizeBool(KeyValue.V_BOOL, vBool); - size += MarshalerUtil.sizeInt64(KeyValue.V_INT64, vInt64); - size += MarshalerUtil.sizeDouble(KeyValue.V_FLOAT64, vFloat64); - return size; - } -} diff --git a/exporters/jaeger/src/main/java/io/opentelemetry/exporter/jaeger/LogMarshaler.java b/exporters/jaeger/src/main/java/io/opentelemetry/exporter/jaeger/LogMarshaler.java deleted file mode 100644 index be871489f0b..00000000000 --- a/exporters/jaeger/src/main/java/io/opentelemetry/exporter/jaeger/LogMarshaler.java +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package io.opentelemetry.exporter.jaeger; - -import io.opentelemetry.api.common.AttributeKey; -import io.opentelemetry.exporter.internal.marshal.MarshalerUtil; -import io.opentelemetry.exporter.internal.marshal.MarshalerWithSize; -import io.opentelemetry.exporter.internal.marshal.Serializer; -import io.opentelemetry.exporter.jaeger.proto.api_v2.internal.Log; -import io.opentelemetry.sdk.trace.data.EventData; -import java.io.IOException; -import java.util.List; - -final class LogMarshaler extends MarshalerWithSize { - - private static final AttributeKey KEY_LOG_EVENT = AttributeKey.stringKey("event"); - private static final AttributeKey KEY_EVENT_DROPPED_ATTRIBUTES_COUNT = - AttributeKey.longKey("otel.event.dropped_attributes_count"); - - private final TimeMarshaler timestamp; - private final List fields; - - static LogMarshaler[] createRepeated(List events) { - int len = events.size(); - LogMarshaler[] marshalers = new LogMarshaler[len]; - for (int i = 0; i < len; i++) { - marshalers[i] = create(events.get(i)); - } - return marshalers; - } - - static LogMarshaler create(EventData event) { - TimeMarshaler timestamp = TimeMarshaler.create(event.getEpochNanos()); - - List fields = KeyValueMarshaler.createRepeated(event.getAttributes()); - - // name is a top-level property in OpenTelemetry - fields.add(KeyValueMarshaler.create(KEY_LOG_EVENT, event.getName())); - - int droppedAttributesCount = event.getDroppedAttributesCount(); - if (droppedAttributesCount > 0) { - fields.add( - KeyValueMarshaler.create( - KEY_EVENT_DROPPED_ATTRIBUTES_COUNT, (long) droppedAttributesCount)); - } - - return new LogMarshaler(timestamp, fields); - } - - LogMarshaler(TimeMarshaler timestamp, List fields) { - super(calculateSize(timestamp, fields)); - this.timestamp = timestamp; - this.fields = fields; - } - - @Override - protected void writeTo(Serializer output) throws IOException { - output.serializeMessage(Log.TIMESTAMP, timestamp); - output.serializeRepeatedMessage(Log.FIELDS, fields); - } - - private static int calculateSize(TimeMarshaler timestamp, List fields) { - int size = 0; - size += MarshalerUtil.sizeMessage(Log.TIMESTAMP, timestamp); - size += MarshalerUtil.sizeRepeatedMessage(Log.FIELDS, fields); - return size; - } -} diff --git a/exporters/jaeger/src/main/java/io/opentelemetry/exporter/jaeger/MarshalerCollectorServiceGrpc.java b/exporters/jaeger/src/main/java/io/opentelemetry/exporter/jaeger/MarshalerCollectorServiceGrpc.java deleted file mode 100644 index 7eb71fb71d1..00000000000 --- a/exporters/jaeger/src/main/java/io/opentelemetry/exporter/jaeger/MarshalerCollectorServiceGrpc.java +++ /dev/null @@ -1,88 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package io.opentelemetry.exporter.jaeger; - -import static io.grpc.MethodDescriptor.generateFullMethodName; - -import com.google.common.util.concurrent.ListenableFuture; -import io.grpc.CallOptions; -import io.grpc.Channel; -import io.grpc.MethodDescriptor; -import io.grpc.stub.ClientCalls; -import io.opentelemetry.exporter.internal.grpc.MarshalerInputStream; -import io.opentelemetry.exporter.internal.grpc.MarshalerServiceStub; -import java.io.InputStream; -import javax.annotation.Nullable; - -// Adapted from the protoc generated code for CollectorServiceGrpc. -final class MarshalerCollectorServiceGrpc { - - private static final String SERVICE_NAME = "jaeger.api_v2.CollectorService"; - - private static final MethodDescriptor.Marshaller REQUEST_MARSHALLER = - new MethodDescriptor.Marshaller() { - @Override - public InputStream stream(PostSpansRequestMarshaler value) { - return new MarshalerInputStream(value); - } - - @Override - public PostSpansRequestMarshaler parse(InputStream stream) { - throw new UnsupportedOperationException("Only for serializing"); - } - }; - - private static final MethodDescriptor.Marshaller RESPONSE_MARSHALER = - new MethodDescriptor.Marshaller() { - @Override - public InputStream stream(PostSpansResponse value) { - throw new UnsupportedOperationException("Only for parsing"); - } - - @Override - public PostSpansResponse parse(InputStream stream) { - return PostSpansResponse.INSTANCE; - } - }; - - private static final MethodDescriptor - getPostSpansMethod = - MethodDescriptor.newBuilder() - .setType(MethodDescriptor.MethodType.UNARY) - .setFullMethodName(generateFullMethodName(SERVICE_NAME, "PostSpans")) - .setRequestMarshaller(REQUEST_MARSHALLER) - .setResponseMarshaller(RESPONSE_MARSHALER) - .build(); - - static CollectorServiceFutureStub newFutureStub( - Channel channel, @Nullable String authorityOverride) { - return CollectorServiceFutureStub.newStub( - (c, options) -> new CollectorServiceFutureStub(c, options.withAuthority(authorityOverride)), - channel); - } - - static final class CollectorServiceFutureStub - extends MarshalerServiceStub< - PostSpansRequestMarshaler, PostSpansResponse, CollectorServiceFutureStub> { - private CollectorServiceFutureStub(Channel channel, CallOptions callOptions) { - super(channel, callOptions); - } - - @Override - protected MarshalerCollectorServiceGrpc.CollectorServiceFutureStub build( - Channel channel, CallOptions callOptions) { - return new MarshalerCollectorServiceGrpc.CollectorServiceFutureStub(channel, callOptions); - } - - @Override - public ListenableFuture export(PostSpansRequestMarshaler request) { - return ClientCalls.futureUnaryCall( - getChannel().newCall(getPostSpansMethod, getCallOptions()), request); - } - } - - private MarshalerCollectorServiceGrpc() {} -} diff --git a/exporters/jaeger/src/main/java/io/opentelemetry/exporter/jaeger/PostSpansRequestMarshaler.java b/exporters/jaeger/src/main/java/io/opentelemetry/exporter/jaeger/PostSpansRequestMarshaler.java deleted file mode 100644 index 69347f82c80..00000000000 --- a/exporters/jaeger/src/main/java/io/opentelemetry/exporter/jaeger/PostSpansRequestMarshaler.java +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package io.opentelemetry.exporter.jaeger; - -import io.opentelemetry.exporter.internal.marshal.MarshalerUtil; -import io.opentelemetry.exporter.internal.marshal.MarshalerWithSize; -import io.opentelemetry.exporter.internal.marshal.Serializer; -import io.opentelemetry.exporter.jaeger.proto.api_v2.internal.PostSpansRequest; -import io.opentelemetry.sdk.resources.Resource; -import io.opentelemetry.sdk.trace.data.SpanData; -import java.io.IOException; -import java.util.List; - -final class PostSpansRequestMarshaler extends MarshalerWithSize { - - private final BatchMarshaler batch; - - static PostSpansRequestMarshaler create(List spans, Resource resource) { - return new PostSpansRequestMarshaler(BatchMarshaler.create(spans, resource)); - } - - PostSpansRequestMarshaler(BatchMarshaler batch) { - super(calculateSize(batch)); - this.batch = batch; - } - - @Override - protected void writeTo(Serializer output) throws IOException { - output.serializeMessage(PostSpansRequest.BATCH, batch); - } - - private static int calculateSize(BatchMarshaler batch) { - int size = 0; - size += MarshalerUtil.sizeMessage(PostSpansRequest.BATCH, batch); - return size; - } -} diff --git a/exporters/jaeger/src/main/java/io/opentelemetry/exporter/jaeger/PostSpansResponse.java b/exporters/jaeger/src/main/java/io/opentelemetry/exporter/jaeger/PostSpansResponse.java deleted file mode 100644 index 3daa41ce560..00000000000 --- a/exporters/jaeger/src/main/java/io/opentelemetry/exporter/jaeger/PostSpansResponse.java +++ /dev/null @@ -1,15 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package io.opentelemetry.exporter.jaeger; - -// A Java object to correspond to the gRPC response for the Collector.PostSpans method. If fields -// are added to the type in the future, this can be converted to an actual class. -// -// It may seem like Void could be used instead but gRPC does not allow response values to be -// null. -enum PostSpansResponse { - INSTANCE; -} diff --git a/exporters/jaeger/src/main/java/io/opentelemetry/exporter/jaeger/ProcessMarshaler.java b/exporters/jaeger/src/main/java/io/opentelemetry/exporter/jaeger/ProcessMarshaler.java deleted file mode 100644 index e50027a894c..00000000000 --- a/exporters/jaeger/src/main/java/io/opentelemetry/exporter/jaeger/ProcessMarshaler.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package io.opentelemetry.exporter.jaeger; - -import io.opentelemetry.api.common.AttributeKey; -import io.opentelemetry.exporter.internal.marshal.MarshalerUtil; -import io.opentelemetry.exporter.internal.marshal.MarshalerWithSize; -import io.opentelemetry.exporter.internal.marshal.Serializer; -import io.opentelemetry.exporter.jaeger.proto.api_v2.internal.Process; -import io.opentelemetry.sdk.resources.Resource; -import java.io.IOException; -import java.util.List; - -final class ProcessMarshaler extends MarshalerWithSize { - - private static final AttributeKey SERVICE_NAME = AttributeKey.stringKey("service.name"); - - private final byte[] serviceNameUtf8; - private final List tags; - - static ProcessMarshaler create(Resource resource) { - String serviceName = resource.getAttribute(SERVICE_NAME); - if (serviceName == null || serviceName.isEmpty()) { - serviceName = Resource.getDefault().getAttribute(SERVICE_NAME); - } - - return new ProcessMarshaler( - MarshalerUtil.toBytes(serviceName), - KeyValueMarshaler.createRepeated(resource.getAttributes())); - } - - ProcessMarshaler(byte[] serviceNameUtf8, List tags) { - super(calculateSize(serviceNameUtf8, tags)); - this.serviceNameUtf8 = serviceNameUtf8; - this.tags = tags; - } - - @Override - protected void writeTo(Serializer output) throws IOException { - output.serializeString(Process.SERVICE_NAME, serviceNameUtf8); - output.serializeRepeatedMessage(Process.TAGS, tags); - } - - private static int calculateSize(byte[] serviceNameUtf8, List tags) { - int size = 0; - size += MarshalerUtil.sizeBytes(Process.SERVICE_NAME, serviceNameUtf8); - size += MarshalerUtil.sizeRepeatedMessage(Process.TAGS, tags); - return size; - } -} diff --git a/exporters/jaeger/src/main/java/io/opentelemetry/exporter/jaeger/SpanMarshaler.java b/exporters/jaeger/src/main/java/io/opentelemetry/exporter/jaeger/SpanMarshaler.java deleted file mode 100644 index 40f2457eecf..00000000000 --- a/exporters/jaeger/src/main/java/io/opentelemetry/exporter/jaeger/SpanMarshaler.java +++ /dev/null @@ -1,186 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package io.opentelemetry.exporter.jaeger; - -import static io.opentelemetry.api.common.AttributeKey.booleanKey; - -import io.opentelemetry.api.common.AttributeKey; -import io.opentelemetry.api.trace.SpanContext; -import io.opentelemetry.api.trace.SpanKind; -import io.opentelemetry.api.trace.StatusCode; -import io.opentelemetry.exporter.internal.marshal.MarshalerUtil; -import io.opentelemetry.exporter.internal.marshal.MarshalerWithSize; -import io.opentelemetry.exporter.internal.marshal.Serializer; -import io.opentelemetry.exporter.jaeger.proto.api_v2.internal.Span; -import io.opentelemetry.sdk.trace.data.SpanData; -import java.io.IOException; -import java.util.List; -import java.util.Locale; - -final class SpanMarshaler extends MarshalerWithSize { - - private static final AttributeKey KEY_ERROR = booleanKey("error"); - private static final AttributeKey KEY_DROPPED_ATTRIBUTES_COUNT = - AttributeKey.longKey("otel.dropped_attributes_count"); - private static final AttributeKey KEY_DROPPED_EVENTS_COUNT = - AttributeKey.longKey("otel.dropped_events_count"); - private static final AttributeKey KEY_SPAN_KIND = AttributeKey.stringKey("span.kind"); - private static final AttributeKey KEY_SPAN_STATUS_MESSAGE = - AttributeKey.stringKey("otel.status_description"); - private static final AttributeKey KEY_SPAN_STATUS_CODE = - AttributeKey.stringKey("otel.status_code"); - private static final AttributeKey KEY_INSTRUMENTATION_SCOPE_NAME = - AttributeKey.stringKey("otel.scope.name"); - private static final AttributeKey KEY_INSTRUMENTATION_SCOPE_VERSION = - AttributeKey.stringKey("otel.scope.version"); - private static final AttributeKey KEY_INSTRUMENTATION_LIBRARY_NAME = - AttributeKey.stringKey("otel.library.name"); - private static final AttributeKey KEY_INSTRUMENTATION_LIBRARY_VERSION = - AttributeKey.stringKey("otel.library.version"); - - private final String traceId; - private final String spanId; - private final byte[] operationNameUtf8; - private final TimeMarshaler startTime; - private final TimeMarshaler duration; - private final List tags; - private final LogMarshaler[] logs; - private final List references; - - static SpanMarshaler[] createRepeated(List spans) { - int len = spans.size(); - SpanMarshaler[] marshalers = new SpanMarshaler[len]; - for (int i = 0; i < len; i++) { - marshalers[i] = SpanMarshaler.create(spans.get(i)); - } - return marshalers; - } - - static SpanMarshaler create(SpanData span) { - String traceId = span.getSpanContext().getTraceId(); - String spanId = span.getSpanContext().getSpanId(); - byte[] operationNameUtf8 = MarshalerUtil.toBytes(span.getName()); - TimeMarshaler startTime = TimeMarshaler.create(span.getStartEpochNanos()); - TimeMarshaler duration = - TimeMarshaler.create(span.getEndEpochNanos() - span.getStartEpochNanos()); - - List tags = KeyValueMarshaler.createRepeated(span.getAttributes()); - int droppedAttributes = span.getTotalAttributeCount() - span.getAttributes().size(); - if (droppedAttributes > 0) { - tags.add(KeyValueMarshaler.create(KEY_DROPPED_ATTRIBUTES_COUNT, (long) droppedAttributes)); - } - - LogMarshaler[] logs = LogMarshaler.createRepeated(span.getEvents()); - int droppedEvents = span.getTotalRecordedEvents() - span.getEvents().size(); - if (droppedEvents > 0) { - tags.add(KeyValueMarshaler.create(KEY_DROPPED_EVENTS_COUNT, (long) droppedEvents)); - } - - List references = SpanRefMarshaler.createRepeated(span.getLinks()); - - // add the parent span - SpanContext parentSpanContext = span.getParentSpanContext(); - if (parentSpanContext.isValid()) { - references.add(SpanRefMarshaler.create(parentSpanContext)); - } - - if (span.getKind() != SpanKind.INTERNAL) { - tags.add( - KeyValueMarshaler.create(KEY_SPAN_KIND, span.getKind().name().toLowerCase(Locale.ROOT))); - } - - if (!span.getStatus().getDescription().isEmpty()) { - tags.add( - KeyValueMarshaler.create(KEY_SPAN_STATUS_MESSAGE, span.getStatus().getDescription())); - } - - if (span.getStatus().getStatusCode() != StatusCode.UNSET) { - tags.add( - KeyValueMarshaler.create(KEY_SPAN_STATUS_CODE, span.getStatus().getStatusCode().name())); - } - - tags.add( - KeyValueMarshaler.create( - KEY_INSTRUMENTATION_SCOPE_NAME, span.getInstrumentationScopeInfo().getName())); - // Include instrumentation library name for backwards compatibility - tags.add( - KeyValueMarshaler.create( - KEY_INSTRUMENTATION_LIBRARY_NAME, span.getInstrumentationScopeInfo().getName())); - - if (span.getInstrumentationScopeInfo().getVersion() != null) { - tags.add( - KeyValueMarshaler.create( - KEY_INSTRUMENTATION_SCOPE_VERSION, span.getInstrumentationScopeInfo().getVersion())); - // Include instrumentation library name for backwards compatibility - tags.add( - KeyValueMarshaler.create( - KEY_INSTRUMENTATION_LIBRARY_VERSION, - span.getInstrumentationScopeInfo().getVersion())); - } - - if (span.getStatus().getStatusCode() == StatusCode.ERROR) { - tags.add(KeyValueMarshaler.create(KEY_ERROR, true)); - } - - return new SpanMarshaler( - traceId, spanId, operationNameUtf8, startTime, duration, tags, logs, references); - } - - SpanMarshaler( - String traceId, - String spanId, - byte[] operationNameUtf8, - TimeMarshaler startTime, - TimeMarshaler duration, - List tags, - LogMarshaler[] logs, - List references) { - super( - calculateSize( - traceId, spanId, operationNameUtf8, startTime, duration, tags, logs, references)); - this.traceId = traceId; - this.spanId = spanId; - this.operationNameUtf8 = operationNameUtf8; - this.startTime = startTime; - this.duration = duration; - this.tags = tags; - this.logs = logs; - this.references = references; - } - - @Override - protected void writeTo(Serializer output) throws IOException { - output.serializeTraceId(Span.TRACE_ID, traceId); - output.serializeSpanId(Span.SPAN_ID, spanId); - output.serializeString(Span.OPERATION_NAME, operationNameUtf8); - output.serializeMessage(Span.START_TIME, startTime); - output.serializeMessage(Span.DURATION, duration); - output.serializeRepeatedMessage(Span.TAGS, tags); - output.serializeRepeatedMessage(Span.LOGS, logs); - output.serializeRepeatedMessage(Span.REFERENCES, references); - } - - private static int calculateSize( - String traceId, - String spanId, - byte[] operationNameUtf8, - TimeMarshaler startTime, - TimeMarshaler duration, - List tags, - LogMarshaler[] logs, - List references) { - int size = 0; - size += MarshalerUtil.sizeTraceId(Span.TRACE_ID, traceId); - size += MarshalerUtil.sizeSpanId(Span.SPAN_ID, spanId); - size += MarshalerUtil.sizeBytes(Span.OPERATION_NAME, operationNameUtf8); - size += MarshalerUtil.sizeMessage(Span.START_TIME, startTime); - size += MarshalerUtil.sizeMessage(Span.DURATION, duration); - size += MarshalerUtil.sizeRepeatedMessage(Span.TAGS, tags); - size += MarshalerUtil.sizeRepeatedMessage(Span.LOGS, logs); - size += MarshalerUtil.sizeRepeatedMessage(Span.REFERENCES, references); - return size; - } -} diff --git a/exporters/jaeger/src/main/java/io/opentelemetry/exporter/jaeger/SpanRefMarshaler.java b/exporters/jaeger/src/main/java/io/opentelemetry/exporter/jaeger/SpanRefMarshaler.java deleted file mode 100644 index a6dd61a418a..00000000000 --- a/exporters/jaeger/src/main/java/io/opentelemetry/exporter/jaeger/SpanRefMarshaler.java +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package io.opentelemetry.exporter.jaeger; - -import io.opentelemetry.api.trace.SpanContext; -import io.opentelemetry.exporter.internal.marshal.MarshalerUtil; -import io.opentelemetry.exporter.internal.marshal.MarshalerWithSize; -import io.opentelemetry.exporter.internal.marshal.ProtoEnumInfo; -import io.opentelemetry.exporter.internal.marshal.Serializer; -import io.opentelemetry.exporter.jaeger.proto.api_v2.internal.SpanRef; -import io.opentelemetry.exporter.jaeger.proto.api_v2.internal.SpanRefType; -import io.opentelemetry.sdk.trace.data.LinkData; -import java.io.IOException; -import java.util.ArrayList; -import java.util.List; - -final class SpanRefMarshaler extends MarshalerWithSize { - - private final String traceId; - private final String spanId; - private final ProtoEnumInfo refType; - - static List createRepeated(List links) { - List marshalers = new ArrayList<>(links.size()); - for (LinkData link : links) { - // we can assume that all links are *follows from* - // https://github.com/open-telemetry/opentelemetry-java/issues/475 - // https://github.com/open-telemetry/opentelemetry-java/pull/481/files#r312577862 - marshalers.add(create(link)); - ; - } - return marshalers; - } - - static SpanRefMarshaler create(SpanContext spanContext) { - return new SpanRefMarshaler( - spanContext.getTraceId(), spanContext.getSpanId(), SpanRefType.CHILD_OF); - } - - static SpanRefMarshaler create(LinkData link) { - return new SpanRefMarshaler( - link.getSpanContext().getTraceId(), - link.getSpanContext().getSpanId(), - SpanRefType.FOLLOWS_FROM); - } - - SpanRefMarshaler(String traceId, String spanId, ProtoEnumInfo refType) { - super(calculateSize(traceId, spanId, refType)); - this.traceId = traceId; - this.spanId = spanId; - this.refType = refType; - } - - @Override - protected void writeTo(Serializer output) throws IOException { - output.serializeTraceId(SpanRef.TRACE_ID, traceId); - output.serializeSpanId(SpanRef.SPAN_ID, spanId); - output.serializeEnum(SpanRef.REF_TYPE, refType); - } - - private static int calculateSize(String traceId, String spanId, ProtoEnumInfo refType) { - int size = 0; - size += MarshalerUtil.sizeTraceId(SpanRef.TRACE_ID, traceId); - size += MarshalerUtil.sizeSpanId(SpanRef.SPAN_ID, spanId); - size += MarshalerUtil.sizeEnum(SpanRef.REF_TYPE, refType); - return size; - } -} diff --git a/exporters/jaeger/src/main/java/io/opentelemetry/exporter/jaeger/TimeMarshaler.java b/exporters/jaeger/src/main/java/io/opentelemetry/exporter/jaeger/TimeMarshaler.java deleted file mode 100644 index 961e5461133..00000000000 --- a/exporters/jaeger/src/main/java/io/opentelemetry/exporter/jaeger/TimeMarshaler.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package io.opentelemetry.exporter.jaeger; - -import io.opentelemetry.exporter.internal.marshal.MarshalerUtil; -import io.opentelemetry.exporter.internal.marshal.MarshalerWithSize; -import io.opentelemetry.exporter.internal.marshal.Serializer; -import io.opentelemetry.exporter.jaeger.internal.protobuf.internal.Time; -import java.io.IOException; -import java.util.concurrent.TimeUnit; - -// The wire format for Timestamp and Duration are exactly the same. Just implement one Marshaler -// for them. -final class TimeMarshaler extends MarshalerWithSize { - private static final long NANOS_PER_SECOND = TimeUnit.SECONDS.toNanos(1); - - private final long seconds; - private final int nanos; - - static TimeMarshaler create(long timeNanos) { - long seconds = timeNanos / NANOS_PER_SECOND; - int nanos = (int) (timeNanos % NANOS_PER_SECOND); - return new TimeMarshaler(seconds, nanos); - } - - TimeMarshaler(long seconds, int nanos) { - super(calculateSize(seconds, nanos)); - this.seconds = seconds; - this.nanos = nanos; - } - - @Override - protected void writeTo(Serializer output) throws IOException { - output.serializeInt64(Time.SECONDS, seconds); - output.serializeInt32(Time.NANOS, nanos); - } - - private static int calculateSize(long seconds, int nanos) { - int size = 0; - size += MarshalerUtil.sizeInt64(Time.SECONDS, seconds); - size += MarshalerUtil.sizeInt32(Time.NANOS, nanos); - return size; - } -} diff --git a/exporters/jaeger/src/main/java/io/opentelemetry/exporter/jaeger/internal/JaegerGrpcSpanExporterProvider.java b/exporters/jaeger/src/main/java/io/opentelemetry/exporter/jaeger/internal/JaegerGrpcSpanExporterProvider.java deleted file mode 100644 index bf3ba40b477..00000000000 --- a/exporters/jaeger/src/main/java/io/opentelemetry/exporter/jaeger/internal/JaegerGrpcSpanExporterProvider.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package io.opentelemetry.exporter.jaeger.internal; - -import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties; -import io.opentelemetry.sdk.autoconfigure.spi.traces.ConfigurableSpanExporterProvider; -import io.opentelemetry.sdk.trace.export.SpanExporter; -import java.time.Duration; - -/** - * {@link SpanExporter} SPI implementation for {@link - * io.opentelemetry.exporter.jaeger.JaegerGrpcSpanExporter}. - * - *

    This class is internal and is hence not for public use. Its APIs are unstable and can change - * at any time. - * - * @deprecated Use {@code OtlpGrpcSpanExporter} or {@code OtlpHttpSpanExporter} from opentelemetry-exporter-otlp - * instead. - */ -@Deprecated -public class JaegerGrpcSpanExporterProvider implements ConfigurableSpanExporterProvider { - @Override - public String getName() { - return "jaeger"; - } - - @Override - public SpanExporter createExporter(ConfigProperties config) { - io.opentelemetry.exporter.jaeger.JaegerGrpcSpanExporterBuilder builder = - io.opentelemetry.exporter.jaeger.JaegerGrpcSpanExporter.builder(); - - String endpoint = config.getString("otel.exporter.jaeger.endpoint"); - if (endpoint != null) { - builder.setEndpoint(endpoint); - } - - Duration timeout = config.getDuration("otel.exporter.jaeger.timeout"); - if (timeout != null) { - builder.setTimeout(timeout); - } - - return builder.build(); - } -} diff --git a/exporters/jaeger/src/main/java/io/opentelemetry/exporter/jaeger/package-info.java b/exporters/jaeger/src/main/java/io/opentelemetry/exporter/jaeger/package-info.java deleted file mode 100644 index 23e486e2fd8..00000000000 --- a/exporters/jaeger/src/main/java/io/opentelemetry/exporter/jaeger/package-info.java +++ /dev/null @@ -1,9 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -@ParametersAreNonnullByDefault -package io.opentelemetry.exporter.jaeger; - -import javax.annotation.ParametersAreNonnullByDefault; diff --git a/exporters/jaeger/src/main/proto/README.md b/exporters/jaeger/src/main/proto/README.md deleted file mode 100644 index f36259bdd21..00000000000 --- a/exporters/jaeger/src/main/proto/README.md +++ /dev/null @@ -1 +0,0 @@ -Non-empty folder required for wire proto compiler. diff --git a/exporters/jaeger/src/main/resources/META-INF/services/io.opentelemetry.sdk.autoconfigure.spi.traces.ConfigurableSpanExporterProvider b/exporters/jaeger/src/main/resources/META-INF/services/io.opentelemetry.sdk.autoconfigure.spi.traces.ConfigurableSpanExporterProvider deleted file mode 100644 index 4c94f1676f8..00000000000 --- a/exporters/jaeger/src/main/resources/META-INF/services/io.opentelemetry.sdk.autoconfigure.spi.traces.ConfigurableSpanExporterProvider +++ /dev/null @@ -1 +0,0 @@ -io.opentelemetry.exporter.jaeger.internal.JaegerGrpcSpanExporterProvider diff --git a/exporters/jaeger/src/test/java/io/opentelemetry/exporter/jaeger/JaegerGrpcSpanExporterTest.java b/exporters/jaeger/src/test/java/io/opentelemetry/exporter/jaeger/JaegerGrpcSpanExporterTest.java deleted file mode 100644 index 994998d6176..00000000000 --- a/exporters/jaeger/src/test/java/io/opentelemetry/exporter/jaeger/JaegerGrpcSpanExporterTest.java +++ /dev/null @@ -1,422 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package io.opentelemetry.exporter.jaeger; - -import static io.opentelemetry.api.common.AttributeKey.stringKey; -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatCode; -import static org.assertj.core.api.Assertions.assertThatThrownBy; -import static org.assertj.core.api.Assertions.fail; - -import com.google.protobuf.InvalidProtocolBufferException; -import com.linecorp.armeria.server.ServerBuilder; -import com.linecorp.armeria.server.ServiceRequestContext; -import com.linecorp.armeria.server.grpc.protocol.AbstractUnaryGrpcService; -import com.linecorp.armeria.testing.junit5.server.SelfSignedCertificateExtension; -import com.linecorp.armeria.testing.junit5.server.ServerExtension; -import io.github.netmikey.logunit.api.LogCapturer; -import io.opentelemetry.api.common.Attributes; -import io.opentelemetry.api.metrics.MeterProvider; -import io.opentelemetry.api.trace.SpanContext; -import io.opentelemetry.api.trace.SpanId; -import io.opentelemetry.api.trace.SpanKind; -import io.opentelemetry.api.trace.TraceFlags; -import io.opentelemetry.api.trace.TraceId; -import io.opentelemetry.api.trace.TraceState; -import io.opentelemetry.exporter.internal.TlsUtil; -import io.opentelemetry.exporter.internal.grpc.GrpcExporter; -import io.opentelemetry.exporter.jaeger.proto.api_v2.Collector; -import io.opentelemetry.exporter.jaeger.proto.api_v2.Model; -import io.opentelemetry.internal.testing.slf4j.SuppressLogger; -import io.opentelemetry.sdk.common.CompletableResultCode; -import io.opentelemetry.sdk.common.InstrumentationScopeInfo; -import io.opentelemetry.sdk.resources.Resource; -import io.opentelemetry.sdk.testing.trace.TestSpanData; -import io.opentelemetry.sdk.trace.IdGenerator; -import io.opentelemetry.sdk.trace.data.SpanData; -import io.opentelemetry.sdk.trace.data.StatusData; -import java.net.InetAddress; -import java.net.URISyntaxException; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.List; -import java.util.Optional; -import java.util.concurrent.BlockingQueue; -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.CompletionStage; -import java.util.concurrent.LinkedBlockingDeque; -import java.util.concurrent.TimeUnit; -import javax.net.ssl.KeyManager; -import javax.net.ssl.SSLContext; -import javax.net.ssl.TrustManager; -import javax.net.ssl.X509KeyManager; -import javax.net.ssl.X509TrustManager; -import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.RegisterExtension; - -@SuppressWarnings("deprecation") // Testing deprecated code -class JaegerGrpcSpanExporterTest { - private static final BlockingQueue postedRequests = - new LinkedBlockingDeque<>(); - - @RegisterExtension - static final ServerExtension server = - new ServerExtension() { - @Override - protected void configure(ServerBuilder sb) { - sb.service( - JaegerGrpcSpanExporterBuilder.GRPC_ENDPOINT_PATH, - new AbstractUnaryGrpcService() { - @Override - protected CompletionStage handleMessage( - ServiceRequestContext ctx, byte[] message) { - try { - postedRequests.add(Collector.PostSpansRequest.parseFrom(message)); - } catch (InvalidProtocolBufferException e) { - CompletableFuture future = new CompletableFuture<>(); - future.completeExceptionally(e); - return future; - } - return CompletableFuture.completedFuture( - Collector.PostSpansResponse.getDefaultInstance().toByteArray()); - } - }); - } - }; - - @RegisterExtension LogCapturer logs = LogCapturer.create().captureForType(GrpcExporter.class); - - @RegisterExtension - static final SelfSignedCertificateExtension serverTls = new SelfSignedCertificateExtension(); - - @RegisterExtension - static final SelfSignedCertificateExtension clientTls = new SelfSignedCertificateExtension(); - - private JaegerGrpcSpanExporter exporter; - - @BeforeEach - void setUp() { - exporter = - JaegerGrpcSpanExporter.builder() - .setEndpoint(server.httpUri().toString()) - .setMeterProvider(MeterProvider.noop()) - .build(); - } - - @AfterEach - void tearDown() { - exporter.shutdown(); - postedRequests.clear(); - } - - @Test - void testExport() throws Exception { - SpanData span = - testSpanData( - Resource.create( - Attributes.of( - stringKey("service.name"), - "myServiceName", - stringKey("resource-attr-key"), - "resource-attr-value")), - "GET /api/endpoint"); - - // test - CompletableResultCode result = exporter.export(Collections.singletonList(span)); - result.join(10, TimeUnit.SECONDS); - assertThat(result.isSuccess()).isEqualTo(true); - - // verify - assertThat(postedRequests).hasSize(1); - Model.Batch batch = postedRequests.poll().getBatch(); - assertThat(batch.getSpans(0).getOperationName()).isEqualTo("GET /api/endpoint"); - assertThat(SpanId.fromBytes(batch.getSpans(0).getSpanId().toByteArray())) - .isEqualTo(span.getSpanContext().getSpanId()); - - assertThat( - getTagValue(batch.getProcess().getTagsList(), "resource-attr-key") - .orElseThrow(() -> new AssertionError("resource-attr-key not found")) - .getVStr()) - .isEqualTo("resource-attr-value"); - - verifyBatch(batch); - assertThat(batch.getProcess().getServiceName()).isEqualTo("myServiceName"); - } - - @Test - void testExportMultipleResources() throws Exception { - SpanData span = - testSpanData( - Resource.create( - Attributes.of( - stringKey("service.name"), - "myServiceName1", - stringKey("resource-attr-key-1"), - "resource-attr-value-1")), - "GET /api/endpoint/1"); - - SpanData span2 = - testSpanData( - Resource.create( - Attributes.of( - stringKey("service.name"), - "myServiceName2", - stringKey("resource-attr-key-2"), - "resource-attr-value-2")), - "GET /api/endpoint/2"); - - // test - CompletableResultCode result = exporter.export(Arrays.asList(span, span2)); - result.join(10, TimeUnit.SECONDS); - assertThat(result.isSuccess()).isEqualTo(true); - - // verify - assertThat(postedRequests).hasSize(2); - List requests = new ArrayList<>(postedRequests); - assertThat(requests).hasSize(2); - for (Collector.PostSpansRequest request : requests) { - Model.Batch batch = request.getBatch(); - - verifyBatch(batch); - - Optional processTag = - getTagValue(batch.getProcess().getTagsList(), "resource-attr-key-1"); - Optional processTag2 = - getTagValue(batch.getProcess().getTagsList(), "resource-attr-key-2"); - if (processTag.isPresent()) { - assertThat(processTag2.isPresent()).isFalse(); - assertThat(batch.getSpans(0).getOperationName()).isEqualTo("GET /api/endpoint/1"); - assertThat(SpanId.fromBytes(batch.getSpans(0).getSpanId().toByteArray())) - .isEqualTo(span.getSpanContext().getSpanId()); - assertThat(processTag.get().getVStr()).isEqualTo("resource-attr-value-1"); - assertThat(batch.getProcess().getServiceName()).isEqualTo("myServiceName1"); - } else if (processTag2.isPresent()) { - assertThat(batch.getSpans(0).getOperationName()).isEqualTo("GET /api/endpoint/2"); - assertThat(SpanId.fromBytes(batch.getSpans(0).getSpanId().toByteArray())) - .isEqualTo(span2.getSpanContext().getSpanId()); - assertThat(processTag2.get().getVStr()).isEqualTo("resource-attr-value-2"); - assertThat(batch.getProcess().getServiceName()).isEqualTo("myServiceName2"); - } else { - fail("No process tag resource-attr-key-1 or resource-attr-key-2"); - } - } - } - - private void verifyBatch(Model.Batch batch) throws Exception { - assertThat(batch.getSpansCount()).isEqualTo(1); - assertThat(TraceId.fromBytes(batch.getSpans(0).getTraceId().toByteArray())).isNotNull(); - assertThat(batch.getProcess().getTagsCount()).isEqualTo(5); - - assertThat( - getSpanTagValue(batch.getSpans(0), "otel.scope.name") - .orElseThrow(() -> new AssertionError("otel.scope.name not found")) - .getVStr()) - .isEqualTo("io.opentelemetry.auto"); - - assertThat( - getSpanTagValue(batch.getSpans(0), "otel.library.name") - .orElseThrow(() -> new AssertionError("otel.library.name not found")) - .getVStr()) - .isEqualTo("io.opentelemetry.auto"); - - assertThat( - getSpanTagValue(batch.getSpans(0), "otel.library.version") - .orElseThrow(() -> new AssertionError("otel.library.version not found")) - .getVStr()) - .isEqualTo("1.0.0"); - - assertThat( - getSpanTagValue(batch.getSpans(0), "otel.scope.version") - .orElseThrow(() -> new AssertionError("otel.scope.version not found")) - .getVStr()) - .isEqualTo("1.0.0"); - - assertThat( - getTagValue(batch.getProcess().getTagsList(), "ip") - .orElseThrow(() -> new AssertionError("ip not found")) - .getVStr()) - .isEqualTo(exporter.getJaegerResource().getAttribute(JaegerGrpcSpanExporter.IP_KEY)); - - assertThat( - getTagValue(batch.getProcess().getTagsList(), "hostname") - .orElseThrow(() -> new AssertionError("hostname not found")) - .getVStr()) - .isEqualTo(InetAddress.getLocalHost().getHostName()); - - assertThat( - getTagValue(batch.getProcess().getTagsList(), "jaeger.version") - .orElseThrow(() -> new AssertionError("jaeger.version not found")) - .getVStr()) - .isEqualTo("opentelemetry-java"); - } - - private static Optional getSpanTagValue(Model.Span span, String tagKey) { - return getTagValue(span.getTagsList(), tagKey); - } - - private static Optional getTagValue(List tags, String tagKey) { - return tags.stream().filter(kv -> kv.getKey().equals(tagKey)).findFirst(); - } - - private static SpanData testSpanData(Resource resource, String spanName) { - long duration = 900; // ms - long startMs = System.currentTimeMillis(); - long endMs = startMs + duration; - return TestSpanData.builder() - .setHasEnded(true) - .setSpanContext( - SpanContext.create( - IdGenerator.random().generateTraceId(), - IdGenerator.random().generateSpanId(), - TraceFlags.getSampled(), - TraceState.getDefault())) - .setName(spanName) - .setStartEpochNanos(TimeUnit.MILLISECONDS.toNanos(startMs)) - .setEndEpochNanos(TimeUnit.MILLISECONDS.toNanos(endMs)) - .setStatus(StatusData.ok()) - .setKind(SpanKind.CONSUMER) - .setLinks(Collections.emptyList()) - .setTotalRecordedLinks(0) - .setTotalRecordedEvents(0) - .setInstrumentationScopeInfo( - InstrumentationScopeInfo.builder("io.opentelemetry.auto").setVersion("1.0.0").build()) - .setResource(resource) - .build(); - } - - @Test - void validTrustedConfig() throws Exception { - assertThatCode( - () -> - JaegerGrpcSpanExporter.builder() - .setTrustedCertificates(serverTls.certificate().getEncoded())) - .doesNotThrowAnyException(); - } - - @Test - void validClientKeyConfig() throws Exception { - assertThatCode( - () -> - JaegerGrpcSpanExporter.builder() - .setClientTls( - clientTls.privateKey().getEncoded(), serverTls.certificate().getEncoded())) - .doesNotThrowAnyException(); - } - - @Test - void validSslContextConfig() throws Exception { - X509TrustManager trustManager = TlsUtil.trustManager(serverTls.certificate().getEncoded()); - - X509KeyManager keyManager = - TlsUtil.keyManager( - clientTls.privateKey().getEncoded(), clientTls.certificate().getEncoded()); - - SSLContext sslContext = SSLContext.getInstance("TLS"); - sslContext.init(new KeyManager[] {keyManager}, new TrustManager[] {trustManager}, null); - - assertThatCode(() -> JaegerGrpcSpanExporter.builder().setSslContext(sslContext, trustManager)) - .doesNotThrowAnyException(); - } - - @Test - @SuppressWarnings("PreferJavaTimeOverload") - void invalidConfig() { - assertThatThrownBy(() -> JaegerGrpcSpanExporter.builder().setTimeout(-1, TimeUnit.MILLISECONDS)) - .isInstanceOf(IllegalArgumentException.class) - .hasMessage("timeout must be non-negative"); - assertThatThrownBy(() -> JaegerGrpcSpanExporter.builder().setTimeout(1, null)) - .isInstanceOf(NullPointerException.class) - .hasMessage("unit"); - assertThatThrownBy(() -> JaegerGrpcSpanExporter.builder().setTimeout(null)) - .isInstanceOf(NullPointerException.class) - .hasMessage("timeout"); - - assertThatThrownBy(() -> JaegerGrpcSpanExporter.builder().setEndpoint(null)) - .isInstanceOf(NullPointerException.class) - .hasMessage("endpoint"); - assertThatThrownBy(() -> JaegerGrpcSpanExporter.builder().setEndpoint("😺://localhost")) - .isInstanceOf(IllegalArgumentException.class) - .hasMessage("Invalid endpoint, must be a URL: 😺://localhost") - .hasCauseInstanceOf(URISyntaxException.class); - assertThatThrownBy(() -> JaegerGrpcSpanExporter.builder().setEndpoint("localhost")) - .isInstanceOf(IllegalArgumentException.class) - .hasMessage("Invalid endpoint, must start with http:// or https://: localhost"); - assertThatThrownBy(() -> JaegerGrpcSpanExporter.builder().setEndpoint("gopher://localhost")) - .isInstanceOf(IllegalArgumentException.class) - .hasMessage("Invalid endpoint, must start with http:// or https://: gopher://localhost"); - - assertThatThrownBy(() -> JaegerGrpcSpanExporter.builder().setCompression(null)) - .isInstanceOf(NullPointerException.class) - .hasMessage("compressionMethod"); - assertThatThrownBy(() -> JaegerGrpcSpanExporter.builder().setCompression("foo")) - .isInstanceOf(IllegalArgumentException.class) - .hasMessage( - "Unsupported compression method. Supported compression methods include: gzip, none."); - } - - @Test - void compressionDefault() { - JaegerGrpcSpanExporter exporter = JaegerGrpcSpanExporter.builder().build(); - try { - assertThat(exporter).extracting("delegate.grpcSender.compressionEnabled").isEqualTo(false); - } finally { - exporter.shutdown(); - } - } - - @Test - void compressionNone() { - JaegerGrpcSpanExporter exporter = - JaegerGrpcSpanExporter.builder().setCompression("none").build(); - try { - assertThat(exporter).extracting("delegate.grpcSender.compressionEnabled").isEqualTo(false); - } finally { - exporter.shutdown(); - } - } - - @Test - void compressionGzip() { - JaegerGrpcSpanExporter exporter = - JaegerGrpcSpanExporter.builder().setCompression("gzip").build(); - try { - assertThat(exporter).extracting("delegate.grpcSender.compressionEnabled").isEqualTo(true); - } finally { - exporter.shutdown(); - } - } - - @Test - void compressionEnabledAndDisabled() { - JaegerGrpcSpanExporter exporter = - JaegerGrpcSpanExporter.builder().setCompression("gzip").setCompression("none").build(); - try { - assertThat(exporter).extracting("delegate.grpcSender.compressionEnabled").isEqualTo(false); - } finally { - exporter.shutdown(); - } - } - - @Test - @SuppressLogger(GrpcExporter.class) - void shutdown() { - JaegerGrpcSpanExporter exporter = - JaegerGrpcSpanExporter.builder().setEndpoint(server.httpUri().toString()).build(); - assertThat(exporter.shutdown().join(1, TimeUnit.SECONDS).isSuccess()).isTrue(); - assertThat(logs.getEvents()).isEmpty(); - assertThat( - exporter - .export(Collections.singletonList(testSpanData(Resource.getDefault(), "span name"))) - .join(10, TimeUnit.SECONDS) - .isSuccess()) - .isFalse(); - assertThat(exporter.shutdown().join(1, TimeUnit.SECONDS).isSuccess()).isTrue(); - logs.assertContains("Calling shutdown() multiple times."); - } -} diff --git a/exporters/jaeger/src/test/java/io/opentelemetry/exporter/jaeger/JaegerIntegrationTest.java b/exporters/jaeger/src/test/java/io/opentelemetry/exporter/jaeger/JaegerIntegrationTest.java deleted file mode 100644 index bfd7db8046f..00000000000 --- a/exporters/jaeger/src/test/java/io/opentelemetry/exporter/jaeger/JaegerIntegrationTest.java +++ /dev/null @@ -1,118 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package io.opentelemetry.exporter.jaeger; - -import static io.opentelemetry.api.common.AttributeKey.stringKey; - -import com.fasterxml.jackson.core.TreeNode; -import com.fasterxml.jackson.jr.ob.JSON; -import com.fasterxml.jackson.jr.stree.JacksonJrsTreeCodec; -import io.opentelemetry.api.OpenTelemetry; -import io.opentelemetry.api.trace.Span; -import io.opentelemetry.sdk.OpenTelemetrySdk; -import io.opentelemetry.sdk.resources.Resource; -import io.opentelemetry.sdk.trace.SdkTracerProvider; -import io.opentelemetry.sdk.trace.export.SimpleSpanProcessor; -import io.opentelemetry.sdk.trace.export.SpanExporter; -import java.time.Duration; -import okhttp3.OkHttpClient; -import okhttp3.Request; -import okhttp3.Response; -import org.awaitility.Awaitility; -import org.junit.jupiter.api.Test; -import org.testcontainers.containers.GenericContainer; -import org.testcontainers.containers.wait.strategy.Wait; -import org.testcontainers.images.PullPolicy; -import org.testcontainers.junit.jupiter.Container; -import org.testcontainers.junit.jupiter.Testcontainers; - -@Testcontainers(disabledWithoutDocker = true) -@SuppressWarnings("deprecation") // Testing deprecated code -class JaegerIntegrationTest { - private static final OkHttpClient client = new OkHttpClient(); - - private static final int QUERY_PORT = 16686; - private static final int COLLECTOR_PORT = 14250; - private static final int HEALTH_PORT = 14269; - private static final String SERVICE_NAME = "E2E-test"; - private static final String JAEGER_URL = "http://localhost"; - - @Container - public static final GenericContainer jaegerContainer = - new GenericContainer<>("ghcr.io/open-telemetry/opentelemetry-java/jaeger:1.32") - .withImagePullPolicy(PullPolicy.alwaysPull()) - .withExposedPorts(COLLECTOR_PORT, QUERY_PORT, HEALTH_PORT) - .waitingFor(Wait.forHttp("/").forPort(HEALTH_PORT)); - - @Test - void testJaegerIntegration() { - OpenTelemetry openTelemetry = initOpenTelemetry(); - imitateWork(openTelemetry); - Awaitility.await() - .atMost(Duration.ofSeconds(30)) - .until(JaegerIntegrationTest::assertJaegerHaveTrace); - } - - private static OpenTelemetry initOpenTelemetry() { - SpanExporter jaegerExporter = - JaegerGrpcSpanExporter.builder() - .setEndpoint("http://localhost:" + jaegerContainer.getMappedPort(COLLECTOR_PORT)) - .setTimeout(Duration.ofSeconds(30)) - .build(); - return OpenTelemetrySdk.builder() - .setTracerProvider( - SdkTracerProvider.builder() - .addSpanProcessor(SimpleSpanProcessor.create(jaegerExporter)) - .setResource( - Resource.getDefault().toBuilder() - .put(stringKey("service.name"), SERVICE_NAME) - .build()) - .build()) - .build(); - } - - private void imitateWork(OpenTelemetry openTelemetry) { - Span span = - openTelemetry.getTracer(getClass().getCanonicalName()).spanBuilder("Test span").startSpan(); - span.addEvent("some event"); - try { - Thread.sleep(1000); - } catch (InterruptedException e) { - throw new RuntimeException(e); - } - span.end(); - } - - private static boolean assertJaegerHaveTrace() { - try { - String url = - String.format( - "%s/api/traces?service=%s", - String.format(JAEGER_URL + ":%d", jaegerContainer.getMappedPort(QUERY_PORT)), - SERVICE_NAME); - - Request request = - new Request.Builder() - .url(url) - .header("Content-Type", "application/json") - .header("Accept", "application/json") - .build(); - - TreeNode json; - try (Response response = client.newCall(request).execute()) { - json = - JSON.builder() - .treeCodec(new JacksonJrsTreeCodec()) - .build() - .treeFrom(response.body().byteStream()); - } - - return json.get("data").get(0).get("traceID") != null; - } catch (Exception e) { - return false; - } - } -} diff --git a/exporters/jaeger/src/test/java/io/opentelemetry/exporter/jaeger/PostSpansRequestMarshalerTest.java b/exporters/jaeger/src/test/java/io/opentelemetry/exporter/jaeger/PostSpansRequestMarshalerTest.java deleted file mode 100644 index 00e10c2124e..00000000000 --- a/exporters/jaeger/src/test/java/io/opentelemetry/exporter/jaeger/PostSpansRequestMarshalerTest.java +++ /dev/null @@ -1,437 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package io.opentelemetry.exporter.jaeger; - -import static io.opentelemetry.api.common.AttributeKey.booleanArrayKey; -import static io.opentelemetry.api.common.AttributeKey.booleanKey; -import static io.opentelemetry.api.common.AttributeKey.doubleArrayKey; -import static io.opentelemetry.api.common.AttributeKey.doubleKey; -import static io.opentelemetry.api.common.AttributeKey.longArrayKey; -import static io.opentelemetry.api.common.AttributeKey.longKey; -import static io.opentelemetry.api.common.AttributeKey.stringArrayKey; -import static io.opentelemetry.api.common.AttributeKey.stringKey; -import static org.assertj.core.api.Assertions.assertThat; - -import com.google.protobuf.InvalidProtocolBufferException; -import com.google.protobuf.Message; -import com.google.protobuf.util.Durations; -import com.google.protobuf.util.Timestamps; -import io.opentelemetry.api.common.Attributes; -import io.opentelemetry.api.trace.SpanContext; -import io.opentelemetry.api.trace.SpanId; -import io.opentelemetry.api.trace.SpanKind; -import io.opentelemetry.api.trace.TraceFlags; -import io.opentelemetry.api.trace.TraceId; -import io.opentelemetry.api.trace.TraceState; -import io.opentelemetry.exporter.internal.marshal.Marshaler; -import io.opentelemetry.exporter.jaeger.proto.api_v2.Model; -import io.opentelemetry.sdk.resources.Resource; -import io.opentelemetry.sdk.testing.trace.TestSpanData; -import io.opentelemetry.sdk.trace.data.EventData; -import io.opentelemetry.sdk.trace.data.LinkData; -import io.opentelemetry.sdk.trace.data.SpanData; -import io.opentelemetry.sdk.trace.data.StatusData; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.UncheckedIOException; -import java.util.Arrays; -import java.util.Collections; -import java.util.List; -import java.util.concurrent.TimeUnit; -import javax.annotation.Nullable; -import org.junit.jupiter.api.Test; - -class PostSpansRequestMarshalerTest { - - private static final String KEY_LOG_EVENT = "event"; - private static final String KEY_EVENT_DROPPED_ATTRIBUTES_COUNT = - "otel.event.dropped_attributes_count"; - private static final String KEY_DROPPED_ATTRIBUTES_COUNT = "otel.dropped_attributes_count"; - private static final String KEY_DROPPED_EVENTS_COUNT = "otel.dropped_events_count"; - private static final String KEY_SPAN_KIND = "span.kind"; - - private static final String LINK_TRACE_ID = "00000000000000000000000000cba123"; - private static final String LINK_SPAN_ID = "0000000000fed456"; - private static final String TRACE_ID = "00000000000000000000000000abc123"; - private static final String SPAN_ID = "0000000000def456"; - private static final String PARENT_SPAN_ID = "0000000000aef789"; - - @Test - void testProtoSpans() { - long duration = 900; // ms - long startMs = System.currentTimeMillis(); - long endMs = startMs + duration; - - SpanData span = getSpanData(startMs, endMs, SpanKind.SERVER); - List spans = Collections.singletonList(span); - - SpanMarshaler[] jaegerSpans = SpanMarshaler.createRepeated(spans); - - // the span contents are checked somewhere else - assertThat(jaegerSpans).hasSize(1); - } - - @Test - @SuppressWarnings({"ProtoTimestampGetSecondsGetNano", "ProtoDurationGetSecondsGetNano"}) - void testProtoSpan() { - long duration = 900; // ms - long startMs = System.currentTimeMillis(); - long endMs = startMs + duration; - - SpanData span = getSpanData(startMs, endMs, SpanKind.SERVER, 2); - - // test - Model.Span jaegerSpan = parse(Model.Span.getDefaultInstance(), SpanMarshaler.create(span)); - assertThat(TraceId.fromBytes(jaegerSpan.getTraceId().toByteArray())) - .isEqualTo(span.getTraceId()); - assertThat(SpanId.fromBytes(jaegerSpan.getSpanId().toByteArray())).isEqualTo(span.getSpanId()); - assertThat(jaegerSpan.getOperationName()).isEqualTo("GET /api/endpoint"); - assertThat(jaegerSpan.getStartTime()).isEqualTo(Timestamps.fromMillis(startMs)); - assertThat(jaegerSpan.getDuration()).isEqualTo(Durations.fromMillis(duration)); - - assertThat(jaegerSpan.getTagsCount()).isEqualTo(7); - Model.KeyValue keyValue = getValue(jaegerSpan.getTagsList(), KEY_SPAN_KIND); - assertThat(keyValue).isNotNull(); - assertThat(keyValue.getVStr()).isEqualTo("server"); - - Model.KeyValue droppedAttributes = - getValue(jaegerSpan.getTagsList(), KEY_DROPPED_ATTRIBUTES_COUNT); - assertThat(droppedAttributes) - .isEqualTo( - Model.KeyValue.newBuilder() - .setKey(KEY_DROPPED_ATTRIBUTES_COUNT) - .setVType(Model.ValueType.INT64) - .setVInt64(2) - .build()); - - assertThat(jaegerSpan.getLogsCount()).isEqualTo(1); - Model.KeyValue droppedEvents = getValue(jaegerSpan.getTagsList(), KEY_DROPPED_EVENTS_COUNT); - assertThat(droppedEvents) - .isEqualTo( - Model.KeyValue.newBuilder() - .setKey(KEY_DROPPED_EVENTS_COUNT) - .setVType(Model.ValueType.INT64) - .setVInt64(1) - .build()); - - Model.Log log = jaegerSpan.getLogs(0); - keyValue = getValue(log.getFieldsList(), KEY_LOG_EVENT); - assertThat(keyValue).isNotNull(); - assertThat(keyValue.getVStr()).isEqualTo("the log message"); - keyValue = getValue(log.getFieldsList(), "foo"); - assertThat(keyValue).isNotNull(); - assertThat(keyValue.getVStr()).isEqualTo("bar"); - - assertThat(jaegerSpan.getReferencesCount()).isEqualTo(2); - - assertHasFollowsFrom(jaegerSpan); - assertHasParent(jaegerSpan); - } - - @Test - void testProtoSpan_internal() { - long duration = 900; // ms - long startMs = System.currentTimeMillis(); - long endMs = startMs + duration; - - SpanData span = getSpanData(startMs, endMs, SpanKind.INTERNAL); - - // test - Model.Span jaegerSpan = parse(Model.Span.getDefaultInstance(), SpanMarshaler.create(span)); - Model.KeyValue keyValue = getValue(jaegerSpan.getTagsList(), KEY_SPAN_KIND); - assertThat(keyValue).isNull(); - } - - @Test - void testJaegerLogs() { - // prepare - EventData eventsData = getTimedEvent(); - - // test - LogMarshaler[] logs = LogMarshaler.createRepeated(Collections.singletonList(eventsData)); - - // verify - assertThat(logs).hasSize(1); - } - - @Test - void testJaegerLog() { - // prepare - EventData event = getTimedEvent(); - - // test - Model.Log log = parse(Model.Log.getDefaultInstance(), LogMarshaler.create(event)); - - // verify - assertThat(log.getFieldsCount()).isEqualTo(2); - - Model.KeyValue keyValue = getValue(log.getFieldsList(), KEY_LOG_EVENT); - assertThat(keyValue).isNotNull(); - assertThat(keyValue.getVStr()).isEqualTo("the log message"); - keyValue = getValue(log.getFieldsList(), "foo"); - assertThat(keyValue).isNotNull(); - assertThat(keyValue.getVStr()).isEqualTo("bar"); - keyValue = getValue(log.getFieldsList(), KEY_EVENT_DROPPED_ATTRIBUTES_COUNT); - assertThat(keyValue).isNull(); - - // verify dropped_attributes_count - event = getTimedEvent(3); - log = parse(Model.Log.getDefaultInstance(), LogMarshaler.create(event)); - keyValue = getValue(log.getFieldsList(), KEY_EVENT_DROPPED_ATTRIBUTES_COUNT); - assertThat(keyValue).isNotNull(); - assertThat(keyValue.getVInt64()).isEqualTo(2); - } - - @Test - void testKeyValue() { - // test - Model.KeyValue kvB = - parse( - Model.KeyValue.getDefaultInstance(), - KeyValueMarshaler.create(booleanKey("valueB"), true)); - Model.KeyValue kvD = - parse( - Model.KeyValue.getDefaultInstance(), KeyValueMarshaler.create(doubleKey("valueD"), 1.)); - Model.KeyValue kvI = - parse(Model.KeyValue.getDefaultInstance(), KeyValueMarshaler.create(longKey("valueI"), 2L)); - Model.KeyValue kvS = - parse( - Model.KeyValue.getDefaultInstance(), - KeyValueMarshaler.create(stringKey("valueS"), "foobar")); - Model.KeyValue kvArrayB = - parse( - Model.KeyValue.getDefaultInstance(), - KeyValueMarshaler.create(booleanArrayKey("valueArrayB"), Arrays.asList(true, false))); - Model.KeyValue kvArrayD = - parse( - Model.KeyValue.getDefaultInstance(), - KeyValueMarshaler.create(doubleArrayKey("valueArrayD"), Arrays.asList(1.2345, 6.789))); - Model.KeyValue kvArrayI = - parse( - Model.KeyValue.getDefaultInstance(), - KeyValueMarshaler.create(longArrayKey("valueArrayI"), Arrays.asList(12345L, 67890L))); - Model.KeyValue kvArrayS = - parse( - Model.KeyValue.getDefaultInstance(), - KeyValueMarshaler.create( - stringArrayKey("valueArrayS"), Arrays.asList("foobar", "barfoo"))); - - // verify - assertThat(kvB.getVBool()).isTrue(); - assertThat(kvB.getVType()).isEqualTo(Model.ValueType.BOOL); - assertThat(kvD.getVFloat64()).isEqualTo(1.); - assertThat(kvD.getVType()).isEqualTo(Model.ValueType.FLOAT64); - assertThat(kvI.getVInt64()).isEqualTo(2); - assertThat(kvI.getVType()).isEqualTo(Model.ValueType.INT64); - assertThat(kvS.getVStr()).isEqualTo("foobar"); - assertThat(kvS.getVStrBytes().toStringUtf8()).isEqualTo("foobar"); - assertThat(kvS.getVType()).isEqualTo(Model.ValueType.STRING); - assertThat(kvArrayB.getVStr()).isEqualTo("[true,false]"); - assertThat(kvArrayB.getVStrBytes().toStringUtf8()).isEqualTo("[true,false]"); - assertThat(kvArrayB.getVType()).isEqualTo(Model.ValueType.STRING); - assertThat(kvArrayD.getVStr()).isEqualTo("[1.2345,6.789]"); - assertThat(kvArrayD.getVStrBytes().toStringUtf8()).isEqualTo("[1.2345,6.789]"); - assertThat(kvArrayD.getVType()).isEqualTo(Model.ValueType.STRING); - assertThat(kvArrayI.getVStr()).isEqualTo("[12345,67890]"); - assertThat(kvArrayI.getVStrBytes().toStringUtf8()).isEqualTo("[12345,67890]"); - assertThat(kvArrayI.getVType()).isEqualTo(Model.ValueType.STRING); - assertThat(kvArrayS.getVStr()).isEqualTo("[\"foobar\",\"barfoo\"]"); - assertThat(kvArrayS.getVStrBytes().toStringUtf8()).isEqualTo("[\"foobar\",\"barfoo\"]"); - assertThat(kvArrayS.getVType()).isEqualTo(Model.ValueType.STRING); - } - - @Test - void testSpanRefs() { - // prepare - LinkData link = - LinkData.create(createSpanContext("00000000000000000000000000cba123", "0000000000fed456")); - - // test - List spanRefs = - SpanRefMarshaler.createRepeated(Collections.singletonList(link)); - - // verify - assertThat(spanRefs).hasSize(1); // the actual span ref is tested in another test - } - - @Test - void testSpanRef() { - // prepare - LinkData link = LinkData.create(createSpanContext(TRACE_ID, SPAN_ID)); - - // test - Model.SpanRef spanRef = - parse(Model.SpanRef.getDefaultInstance(), SpanRefMarshaler.create(link)); - - // verify - assertThat(SpanId.fromBytes(spanRef.getSpanId().toByteArray())).isEqualTo(SPAN_ID); - assertThat(TraceId.fromBytes(spanRef.getTraceId().toByteArray())).isEqualTo(TRACE_ID); - assertThat(spanRef.getRefType()).isEqualTo(Model.SpanRefType.FOLLOWS_FROM); - } - - @Test - void testStatusNotUnset() { - long startMs = System.currentTimeMillis(); - long endMs = startMs + 900; - SpanData span = - TestSpanData.builder() - .setHasEnded(true) - .setSpanContext(createSpanContext(TRACE_ID, SPAN_ID)) - .setName("GET /api/endpoint") - .setStartEpochNanos(TimeUnit.MILLISECONDS.toNanos(startMs)) - .setEndEpochNanos(TimeUnit.MILLISECONDS.toNanos(endMs)) - .setKind(SpanKind.SERVER) - .setStatus(StatusData.error()) - .setTotalRecordedEvents(0) - .setTotalRecordedLinks(0) - .build(); - - assertThat(SpanMarshaler.create(span)).isNotNull(); - } - - @Test - void testSpanError() { - Attributes attributes = - Attributes.of( - stringKey("error.type"), - this.getClass().getName(), - stringKey("error.message"), - "server error"); - long startMs = System.currentTimeMillis(); - long endMs = startMs + 900; - SpanData span = - TestSpanData.builder() - .setHasEnded(true) - .setSpanContext(createSpanContext(TRACE_ID, SPAN_ID)) - .setName("GET /api/endpoint") - .setStartEpochNanos(TimeUnit.MILLISECONDS.toNanos(startMs)) - .setEndEpochNanos(TimeUnit.MILLISECONDS.toNanos(endMs)) - .setKind(SpanKind.SERVER) - .setStatus(StatusData.error()) - .setAttributes(attributes) - .setTotalRecordedEvents(0) - .setTotalRecordedLinks(0) - .build(); - - Model.Span jaegerSpan = parse(Model.Span.getDefaultInstance(), SpanMarshaler.create(span)); - Model.KeyValue errorType = getValue(jaegerSpan.getTagsList(), "error.type"); - assertThat(errorType).isNotNull(); - assertThat(errorType.getVStr()).isEqualTo(this.getClass().getName()); - Model.KeyValue error = getValue(jaegerSpan.getTagsList(), "error"); - assertThat(error).isNotNull(); - assertThat(error.getVBool()).isTrue(); - } - - private static EventData getTimedEvent() { - return getTimedEvent(-1); - } - - private static EventData getTimedEvent(int totalAttributeCount) { - long epochNanos = TimeUnit.MILLISECONDS.toNanos(System.currentTimeMillis()); - Attributes attributes = Attributes.of(stringKey("foo"), "bar"); - if (totalAttributeCount <= 0) { - totalAttributeCount = attributes.size(); - } - return EventData.create(epochNanos, "the log message", attributes, totalAttributeCount); - } - - private static SpanData getSpanData(long startMs, long endMs, SpanKind kind) { - return getSpanData(startMs, endMs, kind, 1); - } - - private static SpanData getSpanData( - long startMs, long endMs, SpanKind kind, int totalRecordedEvents) { - Attributes attributes = Attributes.of(booleanKey("valueB"), true); - - LinkData link = LinkData.create(createSpanContext(LINK_TRACE_ID, LINK_SPAN_ID), attributes); - - return TestSpanData.builder() - .setHasEnded(true) - .setSpanContext(createSpanContext(TRACE_ID, SPAN_ID)) - .setParentSpanContext( - SpanContext.create( - TRACE_ID, PARENT_SPAN_ID, TraceFlags.getDefault(), TraceState.getDefault())) - .setName("GET /api/endpoint") - .setStartEpochNanos(TimeUnit.MILLISECONDS.toNanos(startMs)) - .setEndEpochNanos(TimeUnit.MILLISECONDS.toNanos(endMs)) - .setAttributes(Attributes.of(booleanKey("valueB"), true)) - .setTotalAttributeCount(3) - .setEvents(Collections.singletonList(getTimedEvent())) - .setTotalRecordedEvents(totalRecordedEvents) - .setLinks(Collections.singletonList(link)) - .setTotalRecordedLinks(1) - .setKind(kind) - .setResource(Resource.create(Attributes.empty())) - .setStatus(StatusData.ok()) - .build(); - } - - private static SpanContext createSpanContext(String traceId, String spanId) { - return SpanContext.create(traceId, spanId, TraceFlags.getSampled(), TraceState.getDefault()); - } - - @Nullable - private static Model.KeyValue getValue(List tagsList, String s) { - for (Model.KeyValue kv : tagsList) { - if (kv.getKey().equals(s)) { - return kv; - } - } - return null; - } - - private static void assertHasFollowsFrom(Model.Span jaegerSpan) { - boolean found = false; - for (Model.SpanRef spanRef : jaegerSpan.getReferencesList()) { - if (Model.SpanRefType.FOLLOWS_FROM.equals(spanRef.getRefType())) { - assertThat(TraceId.fromBytes(spanRef.getTraceId().toByteArray())).isEqualTo(LINK_TRACE_ID); - assertThat(SpanId.fromBytes(spanRef.getSpanId().toByteArray())).isEqualTo(LINK_SPAN_ID); - found = true; - } - } - assertThat(found).withFailMessage("Should have found the follows-from reference").isTrue(); - } - - private static void assertHasParent(Model.Span jaegerSpan) { - boolean found = false; - for (Model.SpanRef spanRef : jaegerSpan.getReferencesList()) { - if (Model.SpanRefType.CHILD_OF.equals(spanRef.getRefType())) { - assertThat(TraceId.fromBytes(spanRef.getTraceId().toByteArray())).isEqualTo(TRACE_ID); - assertThat(SpanId.fromBytes(spanRef.getSpanId().toByteArray())).isEqualTo(PARENT_SPAN_ID); - found = true; - } - } - assertThat(found).withFailMessage("Should have found the parent reference").isTrue(); - } - - @SuppressWarnings("unchecked") - private static T parse(T prototype, Marshaler marshaler) { - byte[] serialized = toByteArray(marshaler); - T result; - try { - result = (T) prototype.newBuilderForType().mergeFrom(serialized).build(); - } catch (InvalidProtocolBufferException e) { - throw new UncheckedIOException(e); - } - // Our marshaler should produce the exact same length of serialized output (for example, field - // default values are not outputted), so we check that here. The output itself may have slightly - // different ordering, mostly due to the way we don't output oneof values in field order all the - // tieme. If the lengths are equal and the resulting protos are equal, the marshaling is - // guaranteed to be valid. - assertThat(result.getSerializedSize()).isEqualTo(serialized.length); - return result; - } - - private static byte[] toByteArray(Marshaler marshaler) { - ByteArrayOutputStream bos = new ByteArrayOutputStream(); - try { - marshaler.writeBinaryTo(bos); - } catch (IOException e) { - throw new UncheckedIOException(e); - } - return bos.toByteArray(); - } -} diff --git a/exporters/jaeger/src/test/java/io/opentelemetry/exporter/jaeger/internal/JaegerGrpcSpanExporterProviderTest.java b/exporters/jaeger/src/test/java/io/opentelemetry/exporter/jaeger/internal/JaegerGrpcSpanExporterProviderTest.java deleted file mode 100644 index 82ba56a2ebe..00000000000 --- a/exporters/jaeger/src/test/java/io/opentelemetry/exporter/jaeger/internal/JaegerGrpcSpanExporterProviderTest.java +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package io.opentelemetry.exporter.jaeger.internal; - -import static org.assertj.core.api.Assertions.assertThat; - -import io.opentelemetry.sdk.autoconfigure.spi.internal.DefaultConfigProperties; -import io.opentelemetry.sdk.trace.export.SpanExporter; -import java.util.Collections; -import java.util.HashMap; -import java.util.Map; -import okhttp3.HttpUrl; -import org.junit.jupiter.api.Test; - -@SuppressWarnings("deprecation") // Testing deprecated code -class JaegerGrpcSpanExporterProviderTest { - - private static final JaegerGrpcSpanExporterProvider provider = - new JaegerGrpcSpanExporterProvider(); - - @Test - void getName() { - assertThat(provider.getName()).isEqualTo("jaeger"); - } - - @Test - void createExporter_Default() { - try (SpanExporter spanExporter = - provider.createExporter(DefaultConfigProperties.createFromMap(Collections.emptyMap()))) { - assertThat(spanExporter) - .isInstanceOf(io.opentelemetry.exporter.jaeger.JaegerGrpcSpanExporter.class); - assertThat(spanExporter) - .extracting("delegate.grpcSender") - .extracting("client") - .extracting("callTimeoutMillis") - .isEqualTo(10000); - assertThat(spanExporter) - .extracting("delegate.grpcSender") - .extracting("url") - .isEqualTo( - HttpUrl.get("http://localhost:14250/jaeger.api_v2.CollectorService/PostSpans")); - } - } - - @Test - void createExporter_WithConfiguration() { - Map config = new HashMap<>(); - config.put("otel.exporter.jaeger.endpoint", "http://endpoint:8080"); - config.put("otel.exporter.jaeger.timeout", "1s"); - - try (SpanExporter spanExporter = - provider.createExporter(DefaultConfigProperties.createFromMap(config))) { - assertThat(spanExporter) - .isInstanceOf(io.opentelemetry.exporter.jaeger.JaegerGrpcSpanExporter.class); - assertThat(spanExporter) - .extracting("delegate.grpcSender") - .extracting("client") - .extracting("callTimeoutMillis") - .isEqualTo(1000); - assertThat(spanExporter) - .extracting("delegate.grpcSender") - .extracting("url") - .isEqualTo(HttpUrl.get("http://endpoint:8080/jaeger.api_v2.CollectorService/PostSpans")); - } - } -} diff --git a/exporters/jaeger/src/test/resources/logback-test.xml b/exporters/jaeger/src/test/resources/logback-test.xml deleted file mode 100644 index 0f157506f5e..00000000000 --- a/exporters/jaeger/src/test/resources/logback-test.xml +++ /dev/null @@ -1,14 +0,0 @@ - - - - - - %d{HH:mm:ss.SSS} %-5level %logger - %msg%n - - - - - - - \ No newline at end of file diff --git a/sdk-extensions/autoconfigure/build.gradle.kts b/sdk-extensions/autoconfigure/build.gradle.kts index cc47e419045..62fcd639c79 100644 --- a/sdk-extensions/autoconfigure/build.gradle.kts +++ b/sdk-extensions/autoconfigure/build.gradle.kts @@ -49,7 +49,6 @@ testing { dependencies { implementation(project(":api:events")) implementation(project(":extensions:trace-propagators")) - implementation(project(":exporters:jaeger")) implementation(project(":exporters:logging")) implementation(project(":exporters:logging-otlp")) implementation(project(":exporters:otlp:all")) diff --git a/sdk-extensions/autoconfigure/src/testFullConfig/java/io/opentelemetry/sdk/autoconfigure/SpanExporterConfigurationTest.java b/sdk-extensions/autoconfigure/src/testFullConfig/java/io/opentelemetry/sdk/autoconfigure/SpanExporterConfigurationTest.java index 86e6bf24354..340d322dfc8 100644 --- a/sdk-extensions/autoconfigure/src/testFullConfig/java/io/opentelemetry/sdk/autoconfigure/SpanExporterConfigurationTest.java +++ b/sdk-extensions/autoconfigure/src/testFullConfig/java/io/opentelemetry/sdk/autoconfigure/SpanExporterConfigurationTest.java @@ -28,14 +28,11 @@ class SpanExporterConfigurationTest { SpiHelper.create(SpanExporterConfigurationTest.class.getClassLoader()); @Test - @SuppressWarnings("deprecation") // Testing deprecated jaeger exporter void configureExporter_KnownSpiExportersOnClasspath() { NamedSpiManager spiExportersManager = SpanExporterConfiguration.spanExporterSpiManager( DefaultConfigProperties.createFromMap(Collections.emptyMap()), spiHelper); - assertThat(SpanExporterConfiguration.configureExporter("jaeger", spiExportersManager)) - .isInstanceOf(io.opentelemetry.exporter.jaeger.JaegerGrpcSpanExporter.class); assertThat(SpanExporterConfiguration.configureExporter("logging", spiExportersManager)) .isInstanceOf(LoggingSpanExporter.class); assertThat(SpanExporterConfiguration.configureExporter("logging-otlp", spiExportersManager)) diff --git a/sdk/trace/build.gradle.kts b/sdk/trace/build.gradle.kts index 2f19cea68ec..ae87071507a 100644 --- a/sdk/trace/build.gradle.kts +++ b/sdk/trace/build.gradle.kts @@ -39,7 +39,6 @@ dependencies { // dependencies. isTransitive = false } - jmh(project(":exporters:jaeger-thrift")) jmh(project(":exporters:otlp:all")) { // The opentelemetry-exporter-otlp depends on this project itself. So don't pull in // the transitive dependencies. diff --git a/sdk/trace/src/jmh/java/io/opentelemetry/sdk/trace/ExporterBenchmark.java b/sdk/trace/src/jmh/java/io/opentelemetry/sdk/trace/ExporterBenchmark.java index 28b06257911..19ec7edfdbd 100644 --- a/sdk/trace/src/jmh/java/io/opentelemetry/sdk/trace/ExporterBenchmark.java +++ b/sdk/trace/src/jmh/java/io/opentelemetry/sdk/trace/ExporterBenchmark.java @@ -38,7 +38,6 @@ public abstract static class AbstractProcessorBenchmark { private static final DockerImageName OTLP_COLLECTOR_IMAGE = DockerImageName.parse("otel/opentelemetry-collector-dev:latest"); protected static final int OTLP_PORT = 5678; - protected static final int JAEGER_PORT = 14268; private static final int HEALTH_CHECK_PORT = 13133; protected SdkSpanBuilder sdkSpanBuilder; @@ -49,7 +48,7 @@ public void setup() { // Configuring the collector test-container GenericContainer collector = new GenericContainer<>(OTLP_COLLECTOR_IMAGE) - .withExposedPorts(OTLP_PORT, HEALTH_CHECK_PORT, JAEGER_PORT) + .withExposedPorts(OTLP_PORT, HEALTH_CHECK_PORT) .waitingFor(Wait.forHttp("/").forPort(HEALTH_CHECK_PORT)) .withCopyFileToContainer( MountableFile.forClasspathResource("/otel.yaml"), "/etc/otel.yaml") @@ -92,17 +91,4 @@ protected OtlpGrpcSpanExporter createExporter(GenericContainer collector) { .build(); } } - - @SuppressWarnings("deprecation") // Benchmarking deprecated code - public static class JaegerBenchmark extends AbstractProcessorBenchmark { - @Override - protected io.opentelemetry.exporter.jaeger.thrift.JaegerThriftSpanExporter createExporter( - GenericContainer collector) { - String host = collector.getHost(); - int port = collector.getMappedPort(JAEGER_PORT); - return io.opentelemetry.exporter.jaeger.thrift.JaegerThriftSpanExporter.builder() - .setEndpoint("http://" + host + ":" + port + "/api/traces") - .build(); - } - } } diff --git a/sdk/trace/src/jmh/resources/otel.yaml b/sdk/trace/src/jmh/resources/otel.yaml index 316ff8da1ef..edd847f0c02 100644 --- a/sdk/trace/src/jmh/resources/otel.yaml +++ b/sdk/trace/src/jmh/resources/otel.yaml @@ -3,9 +3,6 @@ receivers: protocols: grpc: endpoint: 0.0.0.0:5678 - jaeger: - protocols: - thrift_http: processors: batch: @@ -20,6 +17,6 @@ service: extensions: [health_check] pipelines: traces: - receivers: [otlp, jaeger] + receivers: [otlp] processors: [batch] exporters: [logging] diff --git a/settings.gradle.kts b/settings.gradle.kts index 73b53ac9612..e54353813b3 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -36,9 +36,6 @@ include(":exporters:common") include(":exporters:sender:grpc-managed-channel") include(":exporters:sender:jdk") include(":exporters:sender:okhttp") -include(":exporters:jaeger") -include(":exporters:jaeger-proto") -include(":exporters:jaeger-thrift") include(":exporters:logging") include(":exporters:logging-otlp") include(":exporters:otlp:all") From 0641844059290aea2e2eeb4bf87aa74c98703337 Mon Sep 17 00:00:00 2001 From: Asaf Mesika Date: Sat, 13 Jan 2024 00:52:54 +0200 Subject: [PATCH 194/901] Memory Mode: Adding 2nd part support for synchronous instruments - exponential histogram (#6058) Co-authored-by: jack-berg <34418638+jack-berg@users.noreply.github.com> --- .../internal/marshal/MarshalerUtil.java | 26 ++ .../exporter/internal/marshal/Serializer.java | 28 ++ .../ExponentialHistogramBucketsMarshaler.java | 24 +- .../metrics/MetricsRequestMarshalerTest.java | 102 +++++++ .../internal/DynamicPrimitiveLongList.java | 146 +++++++++++ .../DynamicPrimitiveLongListTest.java | 132 ++++++++++ .../aggregator/HistogramAggregationParam.java | 8 +- .../aggregator/AggregatorFactory.java | 8 +- ...leBase2ExponentialHistogramAggregator.java | 140 +++++++--- ...oubleBase2ExponentialHistogramBuckets.java | 59 ++++- .../EmptyExponentialHistogramBuckets.java | 34 +++ .../MutableExponentialHistogramBuckets.java | 102 +++++++ .../MutableExponentialHistogramPointData.java | 248 ++++++++++++++++++ .../sdk/metrics/internal/package-info.java | 10 + .../state/AsynchronousMetricStorage.java | 5 +- .../state/SynchronousMetricStorage.java | 3 +- .../Base2ExponentialHistogramAggregation.java | 8 +- .../internal/view/DefaultAggregation.java | 7 +- .../internal/view/DropAggregation.java | 5 +- .../ExplicitBucketHistogramAggregation.java | 5 +- .../internal/view/LastValueAggregation.java | 5 +- .../metrics/internal/view/SumAggregation.java | 5 +- ...se2ExponentialHistogramAggregatorTest.java | 192 +++++++++++--- ...eBase2ExponentialHistogramBucketsTest.java | 123 +++++++-- ...utableExponentialHistogramBucketsTest.java | 46 ++++ ...ableExponentialHistogramPointDataTest.java | 114 ++++++++ .../state/SynchronousMetricStorageTest.java | 9 +- ...e2ExponentialHistogramAggregationTest.java | 4 +- 28 files changed, 1472 insertions(+), 126 deletions(-) create mode 100644 sdk/common/src/main/java/io/opentelemetry/sdk/internal/DynamicPrimitiveLongList.java create mode 100644 sdk/common/src/test/java/io/opentelemetry/sdk/internal/DynamicPrimitiveLongListTest.java create mode 100644 sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/data/EmptyExponentialHistogramBuckets.java create mode 100644 sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/data/MutableExponentialHistogramBuckets.java create mode 100644 sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/data/MutableExponentialHistogramPointData.java create mode 100644 sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/package-info.java create mode 100644 sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/internal/data/MutableExponentialHistogramBucketsTest.java create mode 100644 sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/internal/data/MutableExponentialHistogramPointDataTest.java diff --git a/exporters/common/src/main/java/io/opentelemetry/exporter/internal/marshal/MarshalerUtil.java b/exporters/common/src/main/java/io/opentelemetry/exporter/internal/marshal/MarshalerUtil.java index e0f4c6f25f7..39f0584f4e4 100644 --- a/exporters/common/src/main/java/io/opentelemetry/exporter/internal/marshal/MarshalerUtil.java +++ b/exporters/common/src/main/java/io/opentelemetry/exporter/internal/marshal/MarshalerUtil.java @@ -8,6 +8,7 @@ import io.opentelemetry.api.trace.SpanId; import io.opentelemetry.api.trace.TraceId; import io.opentelemetry.sdk.common.InstrumentationScopeInfo; +import io.opentelemetry.sdk.internal.DynamicPrimitiveLongList; import io.opentelemetry.sdk.resources.Resource; import java.io.ByteArrayOutputStream; import java.io.IOException; @@ -128,6 +129,31 @@ public static int sizeRepeatedUInt64(ProtoFieldInfo field, long[] values) { return field.getTagSize() + CodedOutputStream.computeUInt32SizeNoTag(payloadSize) + payloadSize; } + /** + * Returns the size of a repeated uint64 field. + * + *

    Packed repeated fields contain the tag, an integer representing the incoming payload size, + * and an actual payload of repeated varints. + * + *

    NOTE: This method has the same logic as {@link #sizeRepeatedUInt64(ProtoFieldInfo, long[])} + * )} but instead of using a primitive array it uses {@link DynamicPrimitiveLongList} to avoid + * boxing/unboxing + */ + public static int sizeRepeatedUInt64(ProtoFieldInfo field, DynamicPrimitiveLongList values) { + if (values.isEmpty()) { + return 0; + } + + int payloadSize = 0; + for (int i = 0; i < values.size(); i++) { + long v = values.getLong(i); + payloadSize += CodedOutputStream.computeUInt64SizeNoTag(v); + } + + // tag size + payload indicator size + actual payload size + return field.getTagSize() + CodedOutputStream.computeUInt32SizeNoTag(payloadSize) + payloadSize; + } + /** Returns the size of a repeated double field. */ public static int sizeRepeatedDouble(ProtoFieldInfo field, List values) { // Same as fixed64. diff --git a/exporters/common/src/main/java/io/opentelemetry/exporter/internal/marshal/Serializer.java b/exporters/common/src/main/java/io/opentelemetry/exporter/internal/marshal/Serializer.java index 622201579a9..7382c2cfac6 100644 --- a/exporters/common/src/main/java/io/opentelemetry/exporter/internal/marshal/Serializer.java +++ b/exporters/common/src/main/java/io/opentelemetry/exporter/internal/marshal/Serializer.java @@ -5,6 +5,7 @@ package io.opentelemetry.exporter.internal.marshal; +import io.opentelemetry.sdk.internal.DynamicPrimitiveLongList; import java.io.IOException; import java.util.List; import javax.annotation.Nullable; @@ -191,6 +192,7 @@ public void serializeMessage(ProtoFieldInfo field, Marshaler message) throws IOE writeEndMessage(); } + @SuppressWarnings("SameParameterValue") protected abstract void writeStartRepeatedPrimitive( ProtoFieldInfo field, int protoSizePerElement, int numElements) throws IOException; @@ -243,6 +245,32 @@ public void serializeRepeatedUInt64(ProtoFieldInfo field, long[] values) throws writeEndRepeatedVarint(); } + /** + * Serializes a {@code repeated uint64} field. + * + *

    NOTE: This is the same as {@link #serializeRepeatedUInt64(ProtoFieldInfo, long[])} but + * instead of taking a primitive array it takes a {@link DynamicPrimitiveLongList} as input. + */ + public void serializeRepeatedUInt64(ProtoFieldInfo field, DynamicPrimitiveLongList values) + throws IOException { + if (values.isEmpty()) { + return; + } + + int payloadSize = 0; + for (int i = 0; i < values.size(); i++) { + long v = values.getLong(i); + payloadSize += CodedOutputStream.computeUInt64SizeNoTag(v); + } + + writeStartRepeatedVarint(field, payloadSize); + for (int i = 0; i < values.size(); i++) { + long value = values.getLong(i); + writeUInt64Value(value); + } + writeEndRepeatedVarint(); + } + /** Serializes a {@code repeated double} field. */ public void serializeRepeatedDouble(ProtoFieldInfo field, List values) throws IOException { diff --git a/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/metrics/ExponentialHistogramBucketsMarshaler.java b/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/metrics/ExponentialHistogramBucketsMarshaler.java index 54bb047398c..1f5affce3c0 100644 --- a/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/metrics/ExponentialHistogramBucketsMarshaler.java +++ b/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/metrics/ExponentialHistogramBucketsMarshaler.java @@ -9,6 +9,7 @@ import io.opentelemetry.exporter.internal.marshal.MarshalerWithSize; import io.opentelemetry.exporter.internal.marshal.Serializer; import io.opentelemetry.proto.metrics.v1.internal.ExponentialHistogramDataPoint; +import io.opentelemetry.sdk.internal.DynamicPrimitiveLongList; import io.opentelemetry.sdk.internal.PrimitiveLongList; import io.opentelemetry.sdk.metrics.data.ExponentialHistogramBuckets; import java.io.IOException; @@ -35,16 +36,29 @@ private ExponentialHistogramBucketsMarshaler(int offset, List counts) { @Override protected void writeTo(Serializer output) throws IOException { output.serializeSInt32(ExponentialHistogramDataPoint.Buckets.OFFSET, offset); - output.serializeRepeatedUInt64( - ExponentialHistogramDataPoint.Buckets.BUCKET_COUNTS, PrimitiveLongList.toArray(counts)); + if (counts instanceof DynamicPrimitiveLongList) { + output.serializeRepeatedUInt64( + ExponentialHistogramDataPoint.Buckets.BUCKET_COUNTS, (DynamicPrimitiveLongList) counts); + } else { + output.serializeRepeatedUInt64( + ExponentialHistogramDataPoint.Buckets.BUCKET_COUNTS, PrimitiveLongList.toArray(counts)); + } } private static int calculateSize(int offset, List counts) { int size = 0; size += MarshalerUtil.sizeSInt32(ExponentialHistogramDataPoint.Buckets.OFFSET, offset); - size += - MarshalerUtil.sizeRepeatedUInt64( - ExponentialHistogramDataPoint.Buckets.BUCKET_COUNTS, PrimitiveLongList.toArray(counts)); + if (counts instanceof DynamicPrimitiveLongList) { + size += + MarshalerUtil.sizeRepeatedUInt64( + ExponentialHistogramDataPoint.Buckets.BUCKET_COUNTS, + (DynamicPrimitiveLongList) counts); + } else { + size += + MarshalerUtil.sizeRepeatedUInt64( + ExponentialHistogramDataPoint.Buckets.BUCKET_COUNTS, + PrimitiveLongList.toArray(counts)); + } return size; } } diff --git a/exporters/otlp/common/src/test/java/io/opentelemetry/exporter/internal/otlp/metrics/MetricsRequestMarshalerTest.java b/exporters/otlp/common/src/test/java/io/opentelemetry/exporter/internal/otlp/metrics/MetricsRequestMarshalerTest.java index fc92bb29cc9..2e0de0ac239 100644 --- a/exporters/otlp/common/src/test/java/io/opentelemetry/exporter/internal/otlp/metrics/MetricsRequestMarshalerTest.java +++ b/exporters/otlp/common/src/test/java/io/opentelemetry/exporter/internal/otlp/metrics/MetricsRequestMarshalerTest.java @@ -40,6 +40,7 @@ import io.opentelemetry.proto.metrics.v1.Summary; import io.opentelemetry.proto.metrics.v1.SummaryDataPoint; import io.opentelemetry.sdk.common.InstrumentationScopeInfo; +import io.opentelemetry.sdk.internal.DynamicPrimitiveLongList; import io.opentelemetry.sdk.metrics.data.AggregationTemporality; import io.opentelemetry.sdk.metrics.data.ExponentialHistogramPointData; import io.opentelemetry.sdk.metrics.data.HistogramPointData; @@ -61,6 +62,8 @@ import io.opentelemetry.sdk.metrics.internal.data.ImmutableSummaryData; import io.opentelemetry.sdk.metrics.internal.data.ImmutableSummaryPointData; import io.opentelemetry.sdk.metrics.internal.data.ImmutableValueAtQuantile; +import io.opentelemetry.sdk.metrics.internal.data.MutableExponentialHistogramBuckets; +import io.opentelemetry.sdk.metrics.internal.data.MutableExponentialHistogramPointData; import io.opentelemetry.sdk.resources.Resource; import java.io.ByteArrayOutputStream; import java.io.IOException; @@ -508,6 +511,105 @@ void exponentialHistogramDataPoints() { .build()); } + @SuppressWarnings("PointlessArithmeticExpression") + @Test + void exponentialHistogramReusableDataPoints() { + assertThat( + toExponentialHistogramDataPoints( + ImmutableList.of( + new MutableExponentialHistogramPointData() + .set( + 0, + 123.4, + 1, + /* hasMin= */ false, + 0, + /* hasMax= */ false, + 0, + new MutableExponentialHistogramBuckets() + .set(0, 0, 0, DynamicPrimitiveLongList.empty()), + new MutableExponentialHistogramBuckets() + .set(0, 0, 0, DynamicPrimitiveLongList.empty()), + 123, + 456, + Attributes.empty(), + Collections.emptyList()), + new MutableExponentialHistogramPointData() + .set( + 0, + 123.4, + 1, + /* hasMin= */ true, + 3.3, + /* hasMax= */ true, + 80.1, + new MutableExponentialHistogramBuckets() + .set(0, 1, 1 + 0 + 2, DynamicPrimitiveLongList.of(1L, 0L, 2L)), + new MutableExponentialHistogramBuckets() + .set(0, 0, 0, DynamicPrimitiveLongList.empty()), + 123, + 456, + Attributes.of(stringKey("key"), "value"), + ImmutableList.of( + ImmutableDoubleExemplarData.create( + Attributes.of(stringKey("test"), "value"), + 2, + SpanContext.create( + "00000000000000000000000000000001", + "0000000000000002", + TraceFlags.getDefault(), + TraceState.getDefault()), + 1.5)))))) + .containsExactly( + ExponentialHistogramDataPoint.newBuilder() + .setStartTimeUnixNano(123) + .setTimeUnixNano(456) + .setCount(1) + .setScale(0) + .setSum(123.4) + .setZeroCount(1) + .setPositive( + ExponentialHistogramDataPoint.Buckets.newBuilder().setOffset(0)) // no buckets + .setNegative( + ExponentialHistogramDataPoint.Buckets.newBuilder().setOffset(0)) // no buckets + .build(), + ExponentialHistogramDataPoint.newBuilder() + .setStartTimeUnixNano(123) + .setTimeUnixNano(456) + .setCount(4) // Counts in positive, negative, and zero count. + .addAllAttributes( + singletonList( + KeyValue.newBuilder().setKey("key").setValue(stringValue("value")).build())) + .setScale(0) + .setSum(123.4) + .setMin(3.3) + .setMax(80.1) + .setZeroCount(1) + .setPositive( + ExponentialHistogramDataPoint.Buckets.newBuilder() + .setOffset(1) + .addBucketCounts(1) + .addBucketCounts(0) + .addBucketCounts(2)) + .setNegative( + ExponentialHistogramDataPoint.Buckets.newBuilder().setOffset(0)) // no buckets + .addExemplars( + Exemplar.newBuilder() + .setTimeUnixNano(2) + .addFilteredAttributes( + KeyValue.newBuilder() + .setKey("test") + .setValue(stringValue("value")) + .build()) + .setSpanId(ByteString.copyFrom(new byte[] {0, 0, 0, 0, 0, 0, 0, 2})) + .setTraceId( + ByteString.copyFrom( + new byte[] {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1})) + .setAsDouble(1.5) + .build()) + .build()); + } + @Test void toProtoMetric_monotonic() { assertThat( diff --git a/sdk/common/src/main/java/io/opentelemetry/sdk/internal/DynamicPrimitiveLongList.java b/sdk/common/src/main/java/io/opentelemetry/sdk/internal/DynamicPrimitiveLongList.java new file mode 100644 index 00000000000..e7cf95d9e29 --- /dev/null +++ b/sdk/common/src/main/java/io/opentelemetry/sdk/internal/DynamicPrimitiveLongList.java @@ -0,0 +1,146 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.sdk.internal; + +import java.util.AbstractList; + +/** + * A resizable list for storing primitive `long` values. + * + *

    This class implements a dynamically resizable list specifically for primitive long values. The + * values are stored in a chain of arrays (named sub-array), so it can grow efficiently, by adding + * more sub-arrays per its defined size. The backing array also helps avoid auto-boxing and helps + * provide access to values as primitives without boxing. + * + *

    The list is designed to minimize memory allocations, by: + * + *

      + *
    1. Adding sub-arrays and not creating new arrays and copying. + *
    2. When the size is changing to a smaller size, arrays are not removed. + *
    + * + *

    Supported {@code List} methods: + * + *

      + *
    • {@link #get(int)} - Retrieves the element at the specified position in this list as a + * {@code Long} object. + *
    • {@link #set(int, Long)} - Replaces the element at the specified position in this list with + * the specified {@code Long} object. + *
    • {@link #size()} - Returns the number of elements in this list. + *
    + * + *

    Additional utility methods: + * + *

      + *
    • {@link #getLong(int)} - Retrieves the element at the specified position in this list as a + * primitive long. + *
    • {@link #setLong(int, long)} - Replaces the element at the specified position in this list + * with the specified primitive long element. + *
    • {@link #resizeAndClear(int)} - Resizes the list to the specified size, resetting all + * elements to zero. + *
    + * + *

    This class is an internal part of the OpenTelemetry SDK and is not intended for public use. + * Its API is unstable and subject to change. + * + *

    This class is not thread-safe. + */ +public class DynamicPrimitiveLongList extends AbstractList { + + private static final int DEFAULT_SUBARRAY_CAPACITY = 10; + private final int subarrayCapacity; + private long[][] arrays; + private int size; + private int arrayCount; + + public static DynamicPrimitiveLongList of(long... values) { + DynamicPrimitiveLongList list = new DynamicPrimitiveLongList(); + list.resizeAndClear(values.length); + for (int i = 0; i < values.length; i++) { + list.setLong(i, values[i]); + } + return list; + } + + public static DynamicPrimitiveLongList empty() { + return new DynamicPrimitiveLongList(); + } + + DynamicPrimitiveLongList() { + this(DEFAULT_SUBARRAY_CAPACITY); + } + + DynamicPrimitiveLongList(int subarrayCapacity) { + if (subarrayCapacity <= 0) { + throw new IllegalArgumentException("Subarray capacity must be positive"); + } + this.subarrayCapacity = subarrayCapacity; + arrays = new long[0][subarrayCapacity]; + arrayCount = 0; + size = 0; + } + + @Override + public Long get(int index) { + return getLong(index); + } + + public long getLong(int index) { + rangeCheck(index); + return arrays[index / subarrayCapacity][index % subarrayCapacity]; + } + + @Override + public Long set(int index, Long element) { + return setLong(index, element); + } + + public long setLong(int index, long element) { + rangeCheck(index); + long oldValue = arrays[index / subarrayCapacity][index % subarrayCapacity]; + arrays[index / subarrayCapacity][index % subarrayCapacity] = element; + return oldValue; + } + + @Override + public int size() { + return size; + } + + public void resizeAndClear(int newSize) { + if (newSize < 0) { + throw new IllegalArgumentException("New size must be non-negative"); + } + ensureCapacity(newSize); + size = newSize; + for (int i = 0; i < newSize; i++) { + setLong(i, 0); + } + } + + private void ensureCapacity(int minCapacity) { + // A faster way to do ceil(minCapacity/subArrayCapacity) + int requiredArrays = (minCapacity + subarrayCapacity - 1) / subarrayCapacity; + + if (requiredArrays > arrayCount) { + arrays = java.util.Arrays.copyOf(arrays, /* newLength= */ requiredArrays); + for (int i = arrayCount; i < requiredArrays; i++) { + arrays[i] = new long[subarrayCapacity]; + } + arrayCount = requiredArrays; + } + } + + private void rangeCheck(int index) { + if (index < 0 || index >= size) { + throw new IndexOutOfBoundsException(outOfBoundsMsg(index)); + } + } + + private String outOfBoundsMsg(int index) { + return "Index: " + index + ", Size: " + size; + } +} diff --git a/sdk/common/src/test/java/io/opentelemetry/sdk/internal/DynamicPrimitiveLongListTest.java b/sdk/common/src/test/java/io/opentelemetry/sdk/internal/DynamicPrimitiveLongListTest.java new file mode 100644 index 00000000000..a5f7bf50f2a --- /dev/null +++ b/sdk/common/src/test/java/io/opentelemetry/sdk/internal/DynamicPrimitiveLongListTest.java @@ -0,0 +1,132 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.sdk.internal; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; + +import org.junit.jupiter.api.Test; + +class DynamicPrimitiveLongListTest { + + @Test + void subArrayCapacityMustBePositive() { + assertThatThrownBy( + () -> { + int subArrayCapacity = 0; + new DynamicPrimitiveLongList(subArrayCapacity); + }) + .isInstanceOf(IllegalArgumentException.class); + + assertThatThrownBy( + () -> { + int subArrayCapacity = -2; + new DynamicPrimitiveLongList(subArrayCapacity); + }) + .isInstanceOf(IllegalArgumentException.class); + } + + @Test + void newListIsEmpty() { + DynamicPrimitiveLongList list = new DynamicPrimitiveLongList(); + assertThat(list).isEmpty(); + assertThatThrownBy(() -> list.getLong(0)).isInstanceOf(IndexOutOfBoundsException.class); + } + + @Test + void resizeListAndSetElement() { + DynamicPrimitiveLongList list = new DynamicPrimitiveLongList(); + list.resizeAndClear(5); + list.setLong(3, 10L); + + for (int i = 0; i < 5; i++) { + if (i == 3) { + assertThat(list.getLong(i)).isEqualTo(10L); + } else { + assertThat(list.getLong(i)).isEqualTo(0L); + } + } + } + + @Test + void resizeAndFillThenResizeSmallerAndCheck() { + DynamicPrimitiveLongList list = new DynamicPrimitiveLongList(); + list.resizeAndClear(6); + + for (int i = 0; i < 6; i++) { + list.setLong(i, i + 1); + } + + list.resizeAndClear(3); + + for (int i = 0; i < 3; i++) { + assertThat(list.getLong(i)).isEqualTo(0L); + } + + assertThatThrownBy(() -> list.getLong(4)).isInstanceOf(IndexOutOfBoundsException.class); + + for (int i = 0; i < 3; i++) { + list.setLong(i, i + 10); + assertThat(list.getLong(i)).isEqualTo(i + 10); + } + } + + @Test + void resizeToNegativeNumber() { + assertThatThrownBy(() -> DynamicPrimitiveLongList.of(0, 10, 20).resizeAndClear(-2)) + .isInstanceOf(IllegalArgumentException.class); + } + + @Test + void resizeAndFillThenResizeLargerAndCheck() { + DynamicPrimitiveLongList list = new DynamicPrimitiveLongList(); + list.resizeAndClear(6); + + for (int i = 0; i < 6; i++) { + list.setLong(i, i + 1); + } + + list.resizeAndClear(8); + + for (int i = 0; i < 8; i++) { + assertThat(list.getLong(i)).isEqualTo(0L); + } + + assertThatThrownBy(() -> list.getLong(8)).isInstanceOf(IndexOutOfBoundsException.class); + } + + @Test + void of() { + DynamicPrimitiveLongList list = DynamicPrimitiveLongList.of(1, 4, 5, 6); + assertThat(list.getLong(0)).isEqualTo(1); + assertThat(list.getLong(1)).isEqualTo(4); + assertThat(list.getLong(2)).isEqualTo(5); + assertThat(list.getLong(3)).isEqualTo(6); + + list = DynamicPrimitiveLongList.of(); + assertThat(list).isEmpty(); + } + + @Test + void empty() { + DynamicPrimitiveLongList list = DynamicPrimitiveLongList.empty(); + assertThat(list).isEmpty(); + + // I can still add elements + list.resizeAndClear(1); + list.set(0, 10L); + assertThat(list.getLong(0)).isEqualTo(10L); + } + + @Test + void set() { + DynamicPrimitiveLongList list = DynamicPrimitiveLongList.of(0, 10, 20); + assertThat(list.get(1)).isEqualTo(10L); + + list.set(1, 100L); + assertThat(list.get(1)).isEqualTo(100L); + } +} diff --git a/sdk/metrics/src/jmh/java/io/opentelemetry/sdk/metrics/internal/aggregator/HistogramAggregationParam.java b/sdk/metrics/src/jmh/java/io/opentelemetry/sdk/metrics/internal/aggregator/HistogramAggregationParam.java index ddece4dbee2..efb8bfdc89c 100644 --- a/sdk/metrics/src/jmh/java/io/opentelemetry/sdk/metrics/internal/aggregator/HistogramAggregationParam.java +++ b/sdk/metrics/src/jmh/java/io/opentelemetry/sdk/metrics/internal/aggregator/HistogramAggregationParam.java @@ -5,6 +5,8 @@ package io.opentelemetry.sdk.metrics.internal.aggregator; +import static io.opentelemetry.sdk.common.export.MemoryMode.IMMUTABLE_DATA; + import io.opentelemetry.sdk.metrics.internal.exemplar.ExemplarReservoir; import java.util.Collections; @@ -21,9 +23,11 @@ public enum HistogramAggregationParam { ExplicitBucketHistogramUtils.createBoundaryArray(Collections.emptyList()), ExemplarReservoir::doubleNoSamples)), EXPONENTIAL_SMALL_CIRCULAR_BUFFER( - new DoubleBase2ExponentialHistogramAggregator(ExemplarReservoir::doubleNoSamples, 20, 0)), + new DoubleBase2ExponentialHistogramAggregator( + ExemplarReservoir::doubleNoSamples, 20, 0, IMMUTABLE_DATA)), EXPONENTIAL_CIRCULAR_BUFFER( - new DoubleBase2ExponentialHistogramAggregator(ExemplarReservoir::doubleNoSamples, 160, 0)); + new DoubleBase2ExponentialHistogramAggregator( + ExemplarReservoir::doubleNoSamples, 160, 0, IMMUTABLE_DATA)); private final Aggregator aggregator; diff --git a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/aggregator/AggregatorFactory.java b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/aggregator/AggregatorFactory.java index 9802256b3b1..071df0fca81 100644 --- a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/aggregator/AggregatorFactory.java +++ b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/aggregator/AggregatorFactory.java @@ -5,6 +5,7 @@ package io.opentelemetry.sdk.metrics.internal.aggregator; +import io.opentelemetry.sdk.common.export.MemoryMode; import io.opentelemetry.sdk.metrics.data.ExemplarData; import io.opentelemetry.sdk.metrics.data.PointData; import io.opentelemetry.sdk.metrics.internal.descriptor.InstrumentDescriptor; @@ -26,15 +27,18 @@ public interface AggregatorFactory { * @param instrumentDescriptor the descriptor of the {@code Instrument} that will record * measurements. * @param exemplarFilter the filter on which measurements should turn into exemplars + * @param memoryMode The {@link MemoryMode} the aggregator will use * @return a new {@link Aggregator}. {@link Aggregator#drop()} indicates no measurements should be * recorded. */ Aggregator createAggregator( - InstrumentDescriptor instrumentDescriptor, ExemplarFilter exemplarFilter); + InstrumentDescriptor instrumentDescriptor, + ExemplarFilter exemplarFilter, + MemoryMode memoryMode); /** * Determine if the {@link Aggregator} produced by {@link #createAggregator(InstrumentDescriptor, - * ExemplarFilter)} is compatible with the {@code instrumentDescriptor}. + * ExemplarFilter, MemoryMode)} is compatible with the {@code instrumentDescriptor}. */ boolean isCompatibleWithInstrument(InstrumentDescriptor instrumentDescriptor); } diff --git a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/aggregator/DoubleBase2ExponentialHistogramAggregator.java b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/aggregator/DoubleBase2ExponentialHistogramAggregator.java index 35f8289441e..18b5b60ee4b 100644 --- a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/aggregator/DoubleBase2ExponentialHistogramAggregator.java +++ b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/aggregator/DoubleBase2ExponentialHistogramAggregator.java @@ -5,25 +5,26 @@ package io.opentelemetry.sdk.metrics.internal.aggregator; -import com.google.auto.value.AutoValue; import io.opentelemetry.api.common.Attributes; import io.opentelemetry.sdk.common.InstrumentationScopeInfo; +import io.opentelemetry.sdk.common.export.MemoryMode; +import io.opentelemetry.sdk.internal.DynamicPrimitiveLongList; import io.opentelemetry.sdk.metrics.data.AggregationTemporality; import io.opentelemetry.sdk.metrics.data.DoubleExemplarData; import io.opentelemetry.sdk.metrics.data.ExponentialHistogramBuckets; import io.opentelemetry.sdk.metrics.data.ExponentialHistogramPointData; import io.opentelemetry.sdk.metrics.data.MetricData; +import io.opentelemetry.sdk.metrics.internal.data.EmptyExponentialHistogramBuckets; import io.opentelemetry.sdk.metrics.internal.data.ImmutableExponentialHistogramData; import io.opentelemetry.sdk.metrics.internal.data.ImmutableExponentialHistogramPointData; import io.opentelemetry.sdk.metrics.internal.data.ImmutableMetricData; +import io.opentelemetry.sdk.metrics.internal.data.MutableExponentialHistogramBuckets; +import io.opentelemetry.sdk.metrics.internal.data.MutableExponentialHistogramPointData; import io.opentelemetry.sdk.metrics.internal.descriptor.MetricDescriptor; import io.opentelemetry.sdk.metrics.internal.exemplar.ExemplarReservoir; import io.opentelemetry.sdk.resources.Resource; import java.util.Collection; -import java.util.Collections; import java.util.List; -import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; import java.util.function.Supplier; import javax.annotation.Nullable; @@ -39,6 +40,7 @@ public final class DoubleBase2ExponentialHistogramAggregator private final Supplier> reservoirSupplier; private final int maxBuckets; private final int maxScale; + private final MemoryMode memoryMode; /** * Constructs an exponential histogram aggregator. @@ -48,15 +50,17 @@ public final class DoubleBase2ExponentialHistogramAggregator public DoubleBase2ExponentialHistogramAggregator( Supplier> reservoirSupplier, int maxBuckets, - int maxScale) { + int maxScale, + MemoryMode memoryMode) { this.reservoirSupplier = reservoirSupplier; this.maxBuckets = maxBuckets; this.maxScale = maxScale; + this.memoryMode = memoryMode; } @Override public AggregatorHandle createHandle() { - return new Handle(reservoirSupplier.get(), maxBuckets, maxScale); + return new Handle(reservoirSupplier.get(), maxBuckets, maxScale, memoryMode); } @Override @@ -87,8 +91,16 @@ static final class Handle private double max; private long count; private int currentScale; + private final MemoryMode memoryMode; - Handle(ExemplarReservoir reservoir, int maxBuckets, int maxScale) { + // Used only when MemoryMode = REUSABLE_DATA + @Nullable private final MutableExponentialHistogramPointData reusablePoint; + + Handle( + ExemplarReservoir reservoir, + int maxBuckets, + int maxScale, + MemoryMode memoryMode) { super(reservoir); this.maxBuckets = maxBuckets; this.maxScale = maxScale; @@ -98,6 +110,11 @@ static final class Handle this.max = -1; this.count = 0; this.currentScale = maxScale; + this.reusablePoint = + (memoryMode == MemoryMode.REUSABLE_DATA) + ? new MutableExponentialHistogramPointData() + : null; + this.memoryMode = memoryMode; } @Override @@ -107,21 +124,46 @@ protected synchronized ExponentialHistogramPointData doAggregateThenMaybeReset( Attributes attributes, List exemplars, boolean reset) { - ExponentialHistogramPointData point = - ImmutableExponentialHistogramPointData.create( - currentScale, - sum, - zeroCount, - this.count > 0, - this.min, - this.count > 0, - this.max, - resolveBuckets(this.positiveBuckets, currentScale, reset), - resolveBuckets(this.negativeBuckets, currentScale, reset), - startEpochNanos, - epochNanos, - attributes, - exemplars); + + ExponentialHistogramPointData point; + if (reusablePoint == null) { + point = + ImmutableExponentialHistogramPointData.create( + currentScale, + sum, + zeroCount, + this.count > 0, + this.min, + this.count > 0, + this.max, + resolveBuckets( + this.positiveBuckets, currentScale, reset, /* reusableBuckets= */ null), + resolveBuckets( + this.negativeBuckets, currentScale, reset, /* reusableBuckets= */ null), + startEpochNanos, + epochNanos, + attributes, + exemplars); + } else /* REUSABLE_DATA */ { + point = + reusablePoint.set( + currentScale, + sum, + zeroCount, + this.count > 0, + this.min, + this.count > 0, + this.max, + resolveBuckets( + this.positiveBuckets, currentScale, reset, reusablePoint.getPositiveBuckets()), + resolveBuckets( + this.negativeBuckets, currentScale, reset, reusablePoint.getNegativeBuckets()), + startEpochNanos, + epochNanos, + attributes, + exemplars); + } + if (reset) { this.sum = 0; this.zeroCount = 0; @@ -134,11 +176,38 @@ protected synchronized ExponentialHistogramPointData doAggregateThenMaybeReset( } private ExponentialHistogramBuckets resolveBuckets( - @Nullable DoubleBase2ExponentialHistogramBuckets buckets, int scale, boolean reset) { + @Nullable DoubleBase2ExponentialHistogramBuckets buckets, + int scale, + boolean reset, + @Nullable ExponentialHistogramBuckets reusableBuckets) { if (buckets == null) { return EmptyExponentialHistogramBuckets.get(scale); } - ExponentialHistogramBuckets copy = buckets.copy(); + + ExponentialHistogramBuckets copy; + if (reusableBuckets == null) { + copy = buckets.copy(); + } else { + MutableExponentialHistogramBuckets mutableExponentialHistogramBuckets; + if (reusableBuckets instanceof MutableExponentialHistogramBuckets) { + mutableExponentialHistogramBuckets = (MutableExponentialHistogramBuckets) reusableBuckets; + } else /* EmptyExponentialHistogramBuckets */ { + mutableExponentialHistogramBuckets = new MutableExponentialHistogramBuckets(); + } + + DynamicPrimitiveLongList reusableBucketCountsList = + mutableExponentialHistogramBuckets.getReusableBucketCountsList(); + buckets.getBucketCountsIntoReusableList(reusableBucketCountsList); + + mutableExponentialHistogramBuckets.set( + buckets.getScale(), + buckets.getOffset(), + buckets.getTotalCount(), + reusableBucketCountsList); + + copy = mutableExponentialHistogramBuckets; + } + if (reset) { buckets.clear(maxScale); } @@ -166,13 +235,15 @@ protected synchronized void doRecordDouble(double value) { } else if (c > 0) { // Initialize positive buckets at current scale, if needed if (positiveBuckets == null) { - positiveBuckets = new DoubleBase2ExponentialHistogramBuckets(currentScale, maxBuckets); + positiveBuckets = + new DoubleBase2ExponentialHistogramBuckets(currentScale, maxBuckets, memoryMode); } buckets = positiveBuckets; } else { // Initialize negative buckets at current scale, if needed if (negativeBuckets == null) { - negativeBuckets = new DoubleBase2ExponentialHistogramBuckets(currentScale, maxBuckets); + negativeBuckets = + new DoubleBase2ExponentialHistogramBuckets(currentScale, maxBuckets, memoryMode); } buckets = negativeBuckets; } @@ -206,21 +277,4 @@ void downScale(int by) { } } } - - @AutoValue - abstract static class EmptyExponentialHistogramBuckets implements ExponentialHistogramBuckets { - - private static final Map ZERO_BUCKETS = - new ConcurrentHashMap<>(); - - EmptyExponentialHistogramBuckets() {} - - static ExponentialHistogramBuckets get(int scale) { - return ZERO_BUCKETS.computeIfAbsent( - scale, - scale1 -> - new AutoValue_DoubleBase2ExponentialHistogramAggregator_EmptyExponentialHistogramBuckets( - scale1, 0, Collections.emptyList(), 0)); - } - } } diff --git a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/aggregator/DoubleBase2ExponentialHistogramBuckets.java b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/aggregator/DoubleBase2ExponentialHistogramBuckets.java index 0b66fd74a85..94659d0ecc4 100644 --- a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/aggregator/DoubleBase2ExponentialHistogramBuckets.java +++ b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/aggregator/DoubleBase2ExponentialHistogramBuckets.java @@ -5,6 +5,11 @@ package io.opentelemetry.sdk.metrics.internal.aggregator; +import static io.opentelemetry.sdk.common.export.MemoryMode.IMMUTABLE_DATA; +import static io.opentelemetry.sdk.common.export.MemoryMode.REUSABLE_DATA; + +import io.opentelemetry.sdk.common.export.MemoryMode; +import io.opentelemetry.sdk.internal.DynamicPrimitiveLongList; import io.opentelemetry.sdk.internal.PrimitiveLongList; import io.opentelemetry.sdk.metrics.data.ExponentialHistogramBuckets; import java.util.Collections; @@ -20,12 +25,17 @@ */ final class DoubleBase2ExponentialHistogramBuckets implements ExponentialHistogramBuckets { + private final MemoryMode memoryMode; private AdaptingCircularBufferCounter counts; private int scale; private Base2ExponentialHistogramIndexer base2ExponentialHistogramIndexer; private long totalCount; - DoubleBase2ExponentialHistogramBuckets(int scale, int maxBuckets) { + // Only used when memory mode is REUSABLE_DATA + @Nullable private AdaptingCircularBufferCounter reusableCounts; + + DoubleBase2ExponentialHistogramBuckets(int scale, int maxBuckets, MemoryMode memoryMode) { + this.memoryMode = memoryMode; this.counts = new AdaptingCircularBufferCounter(maxBuckets); this.scale = scale; this.base2ExponentialHistogramIndexer = Base2ExponentialHistogramIndexer.get(this.scale); @@ -38,6 +48,8 @@ final class DoubleBase2ExponentialHistogramBuckets implements ExponentialHistogr this.scale = buckets.scale; this.base2ExponentialHistogramIndexer = buckets.base2ExponentialHistogramIndexer; this.totalCount = buckets.totalCount; + this.memoryMode = buckets.memoryMode; + this.reusableCounts = buckets.reusableCounts; } /** Returns a copy of this bucket. */ @@ -90,6 +102,31 @@ public List getBucketCounts() { return PrimitiveLongList.wrap(countsArr); } + /** + * Fills the given reusable list with the bucket counts. + * + *

    NOTE: This is the same as {@link #getBucketCounts()} but instead of returning a List with + * the values is fill the values into {@code reusableLongList} + * + * @param reusableLongList The list to fill with the bucket counts + */ + void getBucketCountsIntoReusableList(DynamicPrimitiveLongList reusableLongList) { + if (counts.isEmpty()) { + reusableLongList.resizeAndClear(0); + return; + } + + int length = counts.getIndexEnd() - counts.getIndexStart() + 1; + + if (reusableLongList.size() != length) { + reusableLongList.resizeAndClear(length); + } + + for (int i = 0; i < length; i++) { + reusableLongList.setLong(i, counts.get(i + counts.getIndexStart())); + } + } + @Override public long getTotalCount() { return totalCount; @@ -107,7 +144,16 @@ void downscale(int by) { // We want to preserve other optimisations here as well, e.g. integer size. // Instead of creating a new counter, we copy the existing one (for bucket size // optimisations), and clear the values before writing the new ones. - AdaptingCircularBufferCounter newCounts = new AdaptingCircularBufferCounter(counts); + AdaptingCircularBufferCounter newCounts; + if (memoryMode == IMMUTABLE_DATA) { + newCounts = new AdaptingCircularBufferCounter(counts); + } else { + if (reusableCounts == null) { + reusableCounts = new AdaptingCircularBufferCounter(counts); + } + newCounts = reusableCounts; + } + newCounts.clear(); for (int i = counts.getIndexStart(); i <= counts.getIndexEnd(); i++) { @@ -119,7 +165,14 @@ void downscale(int by) { } } } - this.counts = newCounts; + + if (memoryMode == REUSABLE_DATA) { + AdaptingCircularBufferCounter existingCounts = this.counts; + this.counts = newCounts; + reusableCounts = existingCounts; + } else { + this.counts = newCounts; + } } this.scale = this.scale - by; diff --git a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/data/EmptyExponentialHistogramBuckets.java b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/data/EmptyExponentialHistogramBuckets.java new file mode 100644 index 00000000000..afcbddb52c5 --- /dev/null +++ b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/data/EmptyExponentialHistogramBuckets.java @@ -0,0 +1,34 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.sdk.metrics.internal.data; + +import com.google.auto.value.AutoValue; +import io.opentelemetry.sdk.metrics.data.ExponentialHistogramBuckets; +import java.util.Collections; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +/** + * An empty {@link ExponentialHistogramBuckets} + * + *

    This class is internal and is hence not for public use. Its APIs are unstable and can change + * at any time. + */ +@AutoValue +public abstract class EmptyExponentialHistogramBuckets implements ExponentialHistogramBuckets { + + private static final Map ZERO_BUCKETS = + new ConcurrentHashMap<>(); + + EmptyExponentialHistogramBuckets() {} + + public static ExponentialHistogramBuckets get(int scale) { + return ZERO_BUCKETS.computeIfAbsent( + scale, + scale1 -> + new AutoValue_EmptyExponentialHistogramBuckets(scale1, 0, Collections.emptyList(), 0)); + } +} diff --git a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/data/MutableExponentialHistogramBuckets.java b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/data/MutableExponentialHistogramBuckets.java new file mode 100644 index 00000000000..9c9f815426d --- /dev/null +++ b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/data/MutableExponentialHistogramBuckets.java @@ -0,0 +1,102 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.sdk.metrics.internal.data; + +import io.opentelemetry.sdk.internal.DynamicPrimitiveLongList; +import io.opentelemetry.sdk.metrics.data.ExponentialHistogramBuckets; +import java.util.List; +import java.util.Objects; + +/** + * A mutable {@link ExponentialHistogramBuckets} + * + *

    This class is internal and is hence not for public use. Its APIs are unstable and can change + * at any time. + * + *

    This class is not thread-safe. + */ +public final class MutableExponentialHistogramBuckets implements ExponentialHistogramBuckets { + + private int scale; + private int offset; + private long totalCount; + private DynamicPrimitiveLongList bucketCounts = DynamicPrimitiveLongList.empty(); + + @Override + public int getScale() { + return scale; + } + + @Override + public int getOffset() { + return offset; + } + + @Override + public List getBucketCounts() { + return bucketCounts; + } + + public DynamicPrimitiveLongList getReusableBucketCountsList() { + return bucketCounts; + } + + @Override + public long getTotalCount() { + return totalCount; + } + + public MutableExponentialHistogramBuckets set( + int scale, int offset, long totalCount, DynamicPrimitiveLongList bucketCounts) { + this.scale = scale; + this.offset = offset; + this.totalCount = totalCount; + this.bucketCounts = bucketCounts; + + return this; + } + + @Override + public String toString() { + return "MutableExponentialHistogramBuckets{" + + "scale=" + + scale + + ", " + + "offset=" + + offset + + ", " + + "bucketCounts=" + + bucketCounts + + ", " + + "totalCount=" + + totalCount + + "}"; + } + + @Override + public boolean equals(Object o) { + if (o == this) { + return true; + } + if (o instanceof MutableExponentialHistogramBuckets) { + MutableExponentialHistogramBuckets that = (MutableExponentialHistogramBuckets) o; + return this.scale == that.getScale() + && this.offset == that.getOffset() + && this.totalCount == that.getTotalCount() + && Objects.equals(this.bucketCounts, that.bucketCounts); + } + return false; + } + + @Override + public int hashCode() { + int result = scale; + result = 31 * result + offset; + result = 31 * result + (int) (totalCount ^ (totalCount >>> 32)); + result = 31 * result + (bucketCounts != null ? bucketCounts.hashCode() : 0); + return result; + } +} diff --git a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/data/MutableExponentialHistogramPointData.java b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/data/MutableExponentialHistogramPointData.java new file mode 100644 index 00000000000..c32565af087 --- /dev/null +++ b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/data/MutableExponentialHistogramPointData.java @@ -0,0 +1,248 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.sdk.metrics.internal.data; + +import io.opentelemetry.api.common.Attributes; +import io.opentelemetry.sdk.metrics.data.DoubleExemplarData; +import io.opentelemetry.sdk.metrics.data.ExponentialHistogramBuckets; +import io.opentelemetry.sdk.metrics.data.ExponentialHistogramPointData; +import java.util.Collections; +import java.util.List; + +/** + * A mutable {@link ExponentialHistogramPointData} + * + *

    This class is internal and is hence not for public use. Its APIs are unstable and can change + * at any time. + * + *

    This class is not thread-safe. + */ +public final class MutableExponentialHistogramPointData implements ExponentialHistogramPointData { + + private long startEpochNanos; + private long epochNanos; + private Attributes attributes = Attributes.empty(); + private int scale; + private double sum; + private long count; + private long zeroCount; + private boolean hasMin; + private double min; + private boolean hasMax; + private double max; + private ExponentialHistogramBuckets positiveBuckets = EmptyExponentialHistogramBuckets.get(0); + private ExponentialHistogramBuckets negativeBuckets = EmptyExponentialHistogramBuckets.get(0); + private List exemplars = Collections.emptyList(); + + @Override + public int getScale() { + return scale; + } + + @Override + public double getSum() { + return sum; + } + + @Override + public long getCount() { + return count; + } + + @Override + public long getZeroCount() { + return zeroCount; + } + + @Override + public boolean hasMin() { + return hasMin; + } + + @Override + public double getMin() { + return min; + } + + @Override + public boolean hasMax() { + return hasMax; + } + + @Override + public double getMax() { + return max; + } + + @Override + public ExponentialHistogramBuckets getPositiveBuckets() { + return positiveBuckets; + } + + @Override + public ExponentialHistogramBuckets getNegativeBuckets() { + return negativeBuckets; + } + + @Override + public long getStartEpochNanos() { + return startEpochNanos; + } + + @Override + public long getEpochNanos() { + return epochNanos; + } + + @Override + public Attributes getAttributes() { + return attributes; + } + + @Override + public List getExemplars() { + return exemplars; + } + + @SuppressWarnings("TooManyParameters") + public ExponentialHistogramPointData set( + int scale, + double sum, + long zeroCount, + boolean hasMin, + double min, + boolean hasMax, + double max, + ExponentialHistogramBuckets positiveBuckets, + ExponentialHistogramBuckets negativeBuckets, + long startEpochNanos, + long epochNanos, + Attributes attributes, + List exemplars) { + this.count = zeroCount + positiveBuckets.getTotalCount() + negativeBuckets.getTotalCount(); + this.scale = scale; + this.sum = sum; + this.zeroCount = zeroCount; + this.hasMin = hasMin; + this.min = min; + this.hasMax = hasMax; + this.max = max; + this.positiveBuckets = positiveBuckets; + this.negativeBuckets = negativeBuckets; + this.startEpochNanos = startEpochNanos; + this.epochNanos = epochNanos; + this.attributes = attributes; + this.exemplars = exemplars; + + return this; + } + + @Override + public String toString() { + return "MutableExponentialHistogramPointData{" + + "startEpochNanos=" + + startEpochNanos + + ", " + + "epochNanos=" + + epochNanos + + ", " + + "attributes=" + + attributes + + ", " + + "scale=" + + scale + + ", " + + "sum=" + + sum + + ", " + + "count=" + + count + + ", " + + "zeroCount=" + + zeroCount + + ", " + + "hasMin=" + + hasMin + + ", " + + "min=" + + min + + ", " + + "hasMax=" + + hasMax + + ", " + + "max=" + + max + + ", " + + "positiveBuckets=" + + positiveBuckets + + ", " + + "negativeBuckets=" + + negativeBuckets + + ", " + + "exemplars=" + + exemplars + + "}"; + } + + @Override + public boolean equals(Object o) { + if (o == this) { + return true; + } + if (o instanceof MutableExponentialHistogramPointData) { + MutableExponentialHistogramPointData that = (MutableExponentialHistogramPointData) o; + return this.startEpochNanos == that.startEpochNanos + && this.epochNanos == that.epochNanos + && this.attributes.equals(that.attributes) + && this.scale == that.scale + && Double.doubleToLongBits(this.sum) == Double.doubleToLongBits(that.sum) + && this.count == that.count + && this.zeroCount == that.zeroCount + && this.hasMin == that.hasMin + && Double.doubleToLongBits(this.min) == Double.doubleToLongBits(that.min) + && this.hasMax == that.hasMax + && Double.doubleToLongBits(this.max) == Double.doubleToLongBits(that.max) + && this.positiveBuckets.equals(that.positiveBuckets) + && this.negativeBuckets.equals(that.negativeBuckets) + && this.exemplars.equals(that.exemplars); + } + return false; + } + + @Override + public int hashCode() { + int hash = 1; + hash *= 1000003; + hash ^= (int) ((startEpochNanos >>> 32) ^ startEpochNanos); + hash *= 1000003; + hash ^= (int) ((epochNanos >>> 32) ^ epochNanos); + hash *= 1000003; + hash ^= attributes.hashCode(); + hash *= 1000003; + hash ^= scale; + hash *= 1000003; + hash ^= (int) ((Double.doubleToLongBits(sum) >>> 32) ^ Double.doubleToLongBits(sum)); + hash *= 1000003; + hash ^= (int) ((count >>> 32) ^ count); + hash *= 1000003; + hash ^= (int) ((zeroCount >>> 32) ^ zeroCount); + hash *= 1000003; + hash ^= hasMin ? 1231 : 1237; + hash *= 1000003; + hash ^= (int) ((Double.doubleToLongBits(min) >>> 32) ^ Double.doubleToLongBits(min)); + hash *= 1000003; + hash ^= hasMax ? 1231 : 1237; + hash *= 1000003; + hash ^= (int) ((Double.doubleToLongBits(max) >>> 32) ^ Double.doubleToLongBits(max)); + hash *= 1000003; + hash ^= positiveBuckets.hashCode(); + hash *= 1000003; + hash ^= negativeBuckets.hashCode(); + hash *= 1000003; + hash ^= exemplars.hashCode(); + return hash; + } +} diff --git a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/package-info.java b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/package-info.java new file mode 100644 index 00000000000..13b7ee33253 --- /dev/null +++ b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/package-info.java @@ -0,0 +1,10 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +/** Internal SDK implementation classes. */ +@ParametersAreNonnullByDefault +package io.opentelemetry.sdk.metrics.internal; + +import javax.annotation.ParametersAreNonnullByDefault; diff --git a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/state/AsynchronousMetricStorage.java b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/state/AsynchronousMetricStorage.java index 4da3d653207..328710144da 100644 --- a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/state/AsynchronousMetricStorage.java +++ b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/state/AsynchronousMetricStorage.java @@ -110,7 +110,10 @@ static AsynchronousMetricStorage aggregator = ((AggregatorFactory) view.getAggregation()) - .createAggregator(instrumentDescriptor, ExemplarFilter.alwaysOff()); + .createAggregator( + instrumentDescriptor, + ExemplarFilter.alwaysOff(), + registeredReader.getReader().getMemoryMode()); return new AsynchronousMetricStorage<>( registeredReader, metricDescriptor, diff --git a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/state/SynchronousMetricStorage.java b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/state/SynchronousMetricStorage.java index 3b821367343..f743c26cbc7 100644 --- a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/state/SynchronousMetricStorage.java +++ b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/state/SynchronousMetricStorage.java @@ -46,7 +46,8 @@ static SynchronousMetricStorage cr MetricDescriptor.create(view, registeredView.getViewSourceInfo(), instrumentDescriptor); Aggregator aggregator = ((AggregatorFactory) view.getAggregation()) - .createAggregator(instrumentDescriptor, exemplarFilter); + .createAggregator( + instrumentDescriptor, exemplarFilter, registeredReader.getReader().getMemoryMode()); // We won't be storing this metric. if (Aggregator.drop() == aggregator) { return empty(); diff --git a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/view/Base2ExponentialHistogramAggregation.java b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/view/Base2ExponentialHistogramAggregation.java index 287ff589ea6..a4facefca7a 100644 --- a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/view/Base2ExponentialHistogramAggregation.java +++ b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/view/Base2ExponentialHistogramAggregation.java @@ -8,6 +8,7 @@ import static io.opentelemetry.api.internal.Utils.checkArgument; import io.opentelemetry.sdk.common.Clock; +import io.opentelemetry.sdk.common.export.MemoryMode; import io.opentelemetry.sdk.internal.RandomSupplier; import io.opentelemetry.sdk.metrics.Aggregation; import io.opentelemetry.sdk.metrics.data.ExemplarData; @@ -66,7 +67,9 @@ public static Aggregation create(int maxBuckets, int maxScale) { @Override @SuppressWarnings("unchecked") public Aggregator createAggregator( - InstrumentDescriptor instrumentDescriptor, ExemplarFilter exemplarFilter) { + InstrumentDescriptor instrumentDescriptor, + ExemplarFilter exemplarFilter, + MemoryMode memoryMode) { return (Aggregator) new DoubleBase2ExponentialHistogramAggregator( () -> @@ -78,7 +81,8 @@ public Aggregator createAggr Runtime.getRuntime().availableProcessors(), RandomSupplier.platformDefault()))), maxBuckets, - maxScale); + maxScale, + memoryMode); } @Override diff --git a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/view/DefaultAggregation.java b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/view/DefaultAggregation.java index 798c9ea11b4..bbcecc08e1d 100644 --- a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/view/DefaultAggregation.java +++ b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/view/DefaultAggregation.java @@ -5,6 +5,7 @@ package io.opentelemetry.sdk.metrics.internal.view; +import io.opentelemetry.sdk.common.export.MemoryMode; import io.opentelemetry.sdk.internal.ThrottlingLogger; import io.opentelemetry.sdk.metrics.Aggregation; import io.opentelemetry.sdk.metrics.data.ExemplarData; @@ -57,9 +58,11 @@ private static Aggregation resolve(InstrumentDescriptor instrument, boolean with @Override public Aggregator createAggregator( - InstrumentDescriptor instrumentDescriptor, ExemplarFilter exemplarFilter) { + InstrumentDescriptor instrumentDescriptor, + ExemplarFilter exemplarFilter, + MemoryMode memoryMode) { return ((AggregatorFactory) resolve(instrumentDescriptor, /* withAdvice= */ true)) - .createAggregator(instrumentDescriptor, exemplarFilter); + .createAggregator(instrumentDescriptor, exemplarFilter, memoryMode); } @Override diff --git a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/view/DropAggregation.java b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/view/DropAggregation.java index df02ce003db..2b27938c20a 100644 --- a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/view/DropAggregation.java +++ b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/view/DropAggregation.java @@ -5,6 +5,7 @@ package io.opentelemetry.sdk.metrics.internal.view; +import io.opentelemetry.sdk.common.export.MemoryMode; import io.opentelemetry.sdk.metrics.Aggregation; import io.opentelemetry.sdk.metrics.data.ExemplarData; import io.opentelemetry.sdk.metrics.data.PointData; @@ -32,7 +33,9 @@ private DropAggregation() {} @Override @SuppressWarnings("unchecked") public Aggregator createAggregator( - InstrumentDescriptor instrumentDescriptor, ExemplarFilter exemplarFilter) { + InstrumentDescriptor instrumentDescriptor, + ExemplarFilter exemplarFilter, + MemoryMode memoryMode) { return (Aggregator) Aggregator.drop(); } diff --git a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/view/ExplicitBucketHistogramAggregation.java b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/view/ExplicitBucketHistogramAggregation.java index 1ad32b698ba..3d87878efa4 100644 --- a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/view/ExplicitBucketHistogramAggregation.java +++ b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/view/ExplicitBucketHistogramAggregation.java @@ -6,6 +6,7 @@ package io.opentelemetry.sdk.metrics.internal.view; import io.opentelemetry.sdk.common.Clock; +import io.opentelemetry.sdk.common.export.MemoryMode; import io.opentelemetry.sdk.metrics.Aggregation; import io.opentelemetry.sdk.metrics.data.ExemplarData; import io.opentelemetry.sdk.metrics.data.PointData; @@ -50,7 +51,9 @@ private ExplicitBucketHistogramAggregation(List bucketBoundaries) { @Override @SuppressWarnings("unchecked") public Aggregator createAggregator( - InstrumentDescriptor instrumentDescriptor, ExemplarFilter exemplarFilter) { + InstrumentDescriptor instrumentDescriptor, + ExemplarFilter exemplarFilter, + MemoryMode memoryMode) { return (Aggregator) new DoubleExplicitBucketHistogramAggregator( bucketBoundaryArray, diff --git a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/view/LastValueAggregation.java b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/view/LastValueAggregation.java index 5f6039532e0..5a7579f3bf6 100644 --- a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/view/LastValueAggregation.java +++ b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/view/LastValueAggregation.java @@ -5,6 +5,7 @@ package io.opentelemetry.sdk.metrics.internal.view; +import io.opentelemetry.sdk.common.export.MemoryMode; import io.opentelemetry.sdk.metrics.Aggregation; import io.opentelemetry.sdk.metrics.InstrumentType; import io.opentelemetry.sdk.metrics.data.ExemplarData; @@ -36,7 +37,9 @@ private LastValueAggregation() {} @Override @SuppressWarnings("unchecked") public Aggregator createAggregator( - InstrumentDescriptor instrumentDescriptor, ExemplarFilter exemplarFilter) { + InstrumentDescriptor instrumentDescriptor, + ExemplarFilter exemplarFilter, + MemoryMode memoryMode) { // For the initial version we do not sample exemplars on gauges. switch (instrumentDescriptor.getValueType()) { diff --git a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/view/SumAggregation.java b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/view/SumAggregation.java index b689d9f58f1..a23b0bc4d7e 100644 --- a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/view/SumAggregation.java +++ b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/view/SumAggregation.java @@ -6,6 +6,7 @@ package io.opentelemetry.sdk.metrics.internal.view; import io.opentelemetry.sdk.common.Clock; +import io.opentelemetry.sdk.common.export.MemoryMode; import io.opentelemetry.sdk.internal.RandomSupplier; import io.opentelemetry.sdk.metrics.Aggregation; import io.opentelemetry.sdk.metrics.data.DoubleExemplarData; @@ -39,7 +40,9 @@ private SumAggregation() {} @Override @SuppressWarnings("unchecked") public Aggregator createAggregator( - InstrumentDescriptor instrumentDescriptor, ExemplarFilter exemplarFilter) { + InstrumentDescriptor instrumentDescriptor, + ExemplarFilter exemplarFilter, + MemoryMode memoryMode) { switch (instrumentDescriptor.getValueType()) { case LONG: { diff --git a/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/internal/aggregator/DoubleBase2ExponentialHistogramAggregatorTest.java b/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/internal/aggregator/DoubleBase2ExponentialHistogramAggregatorTest.java index cc405c5d8b1..e774939dd4c 100644 --- a/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/internal/aggregator/DoubleBase2ExponentialHistogramAggregatorTest.java +++ b/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/internal/aggregator/DoubleBase2ExponentialHistogramAggregatorTest.java @@ -14,16 +14,22 @@ import io.opentelemetry.api.trace.TraceState; import io.opentelemetry.context.Context; import io.opentelemetry.sdk.common.InstrumentationScopeInfo; +import io.opentelemetry.sdk.common.export.MemoryMode; import io.opentelemetry.sdk.metrics.data.AggregationTemporality; import io.opentelemetry.sdk.metrics.data.DoubleExemplarData; import io.opentelemetry.sdk.metrics.data.ExponentialHistogramBuckets; import io.opentelemetry.sdk.metrics.data.ExponentialHistogramPointData; import io.opentelemetry.sdk.metrics.data.MetricData; import io.opentelemetry.sdk.metrics.data.MetricDataType; +import io.opentelemetry.sdk.metrics.internal.data.EmptyExponentialHistogramBuckets; import io.opentelemetry.sdk.metrics.internal.data.ImmutableDoubleExemplarData; +import io.opentelemetry.sdk.metrics.internal.data.ImmutableExponentialHistogramPointData; +import io.opentelemetry.sdk.metrics.internal.data.MutableExponentialHistogramBuckets; +import io.opentelemetry.sdk.metrics.internal.data.MutableExponentialHistogramPointData; import io.opentelemetry.sdk.metrics.internal.descriptor.MetricDescriptor; import io.opentelemetry.sdk.metrics.internal.exemplar.ExemplarReservoir; import io.opentelemetry.sdk.resources.Resource; +import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.List; @@ -38,6 +44,7 @@ import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.EnumSource; import org.junit.jupiter.params.provider.MethodSource; import org.mockito.Mock; import org.mockito.Mockito; @@ -47,10 +54,9 @@ class DoubleBase2ExponentialHistogramAggregatorTest { @Mock ExemplarReservoir reservoir; + private DoubleBase2ExponentialHistogramAggregator aggregator; private static final int MAX_SCALE = 20; - private static final DoubleBase2ExponentialHistogramAggregator aggregator = - new DoubleBase2ExponentialHistogramAggregator(ExemplarReservoir::doubleNoSamples, 160, 20); private static final Resource RESOURCE = Resource.getDefault(); private static final InstrumentationScopeInfo INSTRUMENTATION_SCOPE_INFO = InstrumentationScopeInfo.empty(); @@ -58,10 +64,16 @@ class DoubleBase2ExponentialHistogramAggregatorTest { MetricDescriptor.create("name", "description", "unit"); private static Stream provideAggregator() { - return Stream.of( - aggregator, - new DoubleBase2ExponentialHistogramAggregator( - ExemplarReservoir::doubleNoSamples, 160, MAX_SCALE)); + List parameters = new ArrayList<>(); + for (MemoryMode memoryMode : MemoryMode.values()) { + parameters.add( + new DoubleBase2ExponentialHistogramAggregator( + ExemplarReservoir::doubleNoSamples, 160, 20, memoryMode)); + parameters.add( + new DoubleBase2ExponentialHistogramAggregator( + ExemplarReservoir::doubleNoSamples, 160, MAX_SCALE, memoryMode)); + } + return parameters.stream(); } private static int valueToIndex(int scale, double value) { @@ -69,26 +81,34 @@ private static int valueToIndex(int scale, double value) { return (int) Math.ceil(Math.log(value) * scaleFactor) - 1; } - @Test - void createHandle() { + private void initialize(MemoryMode memoryMode) { + aggregator = + new DoubleBase2ExponentialHistogramAggregator( + ExemplarReservoir::doubleNoSamples, 160, 20, memoryMode); + } + + @ParameterizedTest + @EnumSource(MemoryMode.class) + void createHandle(MemoryMode memoryMode) { + initialize(memoryMode); + AggregatorHandle handle = aggregator.createHandle(); assertThat(handle).isInstanceOf(DoubleBase2ExponentialHistogramAggregator.Handle.class); ExponentialHistogramPointData point = ((DoubleBase2ExponentialHistogramAggregator.Handle) handle) .doAggregateThenMaybeReset( 0, 1, Attributes.empty(), Collections.emptyList(), /* reset= */ true); - assertThat(point.getPositiveBuckets()) - .isInstanceOf( - DoubleBase2ExponentialHistogramAggregator.EmptyExponentialHistogramBuckets.class); + assertThat(point.getPositiveBuckets()).isInstanceOf(EmptyExponentialHistogramBuckets.class); assertThat(point.getPositiveBuckets().getScale()).isEqualTo(MAX_SCALE); - assertThat(point.getNegativeBuckets()) - .isInstanceOf( - DoubleBase2ExponentialHistogramAggregator.EmptyExponentialHistogramBuckets.class); + assertThat(point.getNegativeBuckets()).isInstanceOf(EmptyExponentialHistogramBuckets.class); assertThat(point.getNegativeBuckets().getScale()).isEqualTo(MAX_SCALE); } - @Test - void testRecordings() { + @ParameterizedTest + @EnumSource(MemoryMode.class) + void testRecordings(MemoryMode memoryMode) { + initialize(memoryMode); + AggregatorHandle aggregatorHandle = aggregator.createHandle(); aggregatorHandle.recordDouble(0.5); @@ -130,11 +150,14 @@ void testRecordings() { assertThat(negativeCounts.get(valueToIndex(expectedScale, 1.0) - negOffset)).isEqualTo(1); } - @Test - void testInvalidRecording() { + @ParameterizedTest + @EnumSource(MemoryMode.class) + void testInvalidRecording(MemoryMode memoryMode) { + initialize(memoryMode); + AggregatorHandle aggregatorHandle = aggregator.createHandle(); - // Non finite recordings should be ignored + // Non-finite recordings should be ignored aggregatorHandle.recordDouble(Double.POSITIVE_INFINITY); aggregatorHandle.recordDouble(Double.NEGATIVE_INFINITY); aggregatorHandle.recordDouble(Double.NaN); @@ -192,10 +215,11 @@ void testRecordingsAtLimits(DoubleBase2ExponentialHistogramAggregator aggregator .isEqualTo(Double.POSITIVE_INFINITY); } - @Test - void aggregateThenMaybeReset_WithExemplars() { + @ParameterizedTest + @EnumSource(MemoryMode.class) + void aggregateThenMaybeReset_WithExemplars(MemoryMode memoryMode) { DoubleBase2ExponentialHistogramAggregator agg = - new DoubleBase2ExponentialHistogramAggregator(() -> reservoir, 160, MAX_SCALE); + new DoubleBase2ExponentialHistogramAggregator(() -> reservoir, 160, MAX_SCALE, memoryMode); Attributes attributes = Attributes.builder().put("test", "value").build(); DoubleExemplarData exemplar = @@ -223,8 +247,11 @@ void aggregateThenMaybeReset_WithExemplars() { .isEqualTo(exemplars); } - @Test - void aggregateThenMaybeReset() { + @ParameterizedTest + @EnumSource(MemoryMode.class) + void aggregateThenMaybeReset(MemoryMode memoryMode) { + initialize(memoryMode); + AggregatorHandle aggregatorHandle = aggregator.createHandle(); @@ -238,8 +265,11 @@ void aggregateThenMaybeReset() { .isEqualTo(Collections.singletonList(1L)); } - @Test - void testInsert1M() { + @ParameterizedTest + @EnumSource(MemoryMode.class) + void testInsert1M(MemoryMode memoryMode) { + initialize(memoryMode); + AggregatorHandle handle = aggregator.createHandle(); @@ -261,8 +291,11 @@ void testInsert1M() { assertThat(point.getPositiveBuckets().getTotalCount()).isEqualTo(n); } - @Test - void testDownScale() { + @ParameterizedTest + @EnumSource(MemoryMode.class) + void testDownScale(MemoryMode memoryMode) { + initialize(memoryMode); + DoubleBase2ExponentialHistogramAggregator.Handle handle = (DoubleBase2ExponentialHistogramAggregator.Handle) aggregator.createHandle(); // record a measurement to initialize positive buckets @@ -289,8 +322,9 @@ void testDownScale() { assertThat(buckets.getTotalCount()).isEqualTo(5); } - @Test - void testToMetricData() { + @ParameterizedTest + @EnumSource(MemoryMode.class) + void testToMetricData(MemoryMode memoryMode) { Attributes attributes = Attributes.builder().put("test", "value").build(); DoubleExemplarData exemplar = ImmutableDoubleExemplarData.create( @@ -310,7 +344,8 @@ void testToMetricData() { Mockito.when(reservoirSupplier.get()).thenReturn(reservoir); DoubleBase2ExponentialHistogramAggregator cumulativeAggregator = - new DoubleBase2ExponentialHistogramAggregator(reservoirSupplier, 160, MAX_SCALE); + new DoubleBase2ExponentialHistogramAggregator( + reservoirSupplier, 160, MAX_SCALE, memoryMode); AggregatorHandle aggregatorHandle = cumulativeAggregator.createHandle(); @@ -373,8 +408,11 @@ void testToMetricData() { .isEqualTo(AggregationTemporality.DELTA); } - @Test - void testMultithreadedUpdates() throws InterruptedException { + @ParameterizedTest + @EnumSource(MemoryMode.class) + void testMultithreadedUpdates(MemoryMode memoryMode) throws InterruptedException { + initialize(memoryMode); + AggregatorHandle aggregatorHandle = aggregator.createHandle(); ImmutableList updates = ImmutableList.of(0D, 0.1D, -0.1D, 1D, -1D, 100D); @@ -440,4 +478,92 @@ void testMultithreadedUpdates() throws InterruptedException { valueToIndex(point.getScale(), 1) - point.getPositiveBuckets().getOffset())) .isEqualTo(numberOfUpdates); } + + @Test + public void verifyMutableDataUsedInReusableDataMemoryMode() { + initialize(MemoryMode.REUSABLE_DATA); + + DoubleBase2ExponentialHistogramAggregator.Handle handle = + (DoubleBase2ExponentialHistogramAggregator.Handle) aggregator.createHandle(); + + // record a measurement to initialize positive buckets + handle.recordDouble(0.5); + // record a measurement to initialize negative buckets + handle.recordDouble(-13.2); + + ExponentialHistogramPointData point = + Objects.requireNonNull( + handle.aggregateThenMaybeReset(0, 1, Attributes.empty(), /* reset= */ false)); + + assertThat(point).isInstanceOf(MutableExponentialHistogramPointData.class); + assertThat(point.getPositiveBuckets()).isInstanceOf(MutableExponentialHistogramBuckets.class); + assertThat(point.getNegativeBuckets()).isInstanceOf(MutableExponentialHistogramBuckets.class); + assertThat(point.getPositiveBuckets().getBucketCounts()).isNotEmpty(); + assertThat(point.getNegativeBuckets().getBucketCounts()).isNotEmpty(); + + handle.recordDouble(0.6); + handle.recordDouble(-16.3); + + ExponentialHistogramPointData secondAggregatePoint = + Objects.requireNonNull( + handle.aggregateThenMaybeReset(1, 2, Attributes.empty(), /* reset= */ false)); + + // Mutable point should be reused across collections. + assertThat(secondAggregatePoint).isSameAs(point); + } + + @Test + public void verifyImmutableDataUsedInImmutableDataMemoryMode() { + initialize(MemoryMode.IMMUTABLE_DATA); + + DoubleBase2ExponentialHistogramAggregator.Handle handle = + (DoubleBase2ExponentialHistogramAggregator.Handle) aggregator.createHandle(); + + // record a measurement to initialize positive buckets + handle.recordDouble(0.5); + // record a measurement to initialize negative buckets + handle.recordDouble(-13.2); + + ExponentialHistogramPointData point = + Objects.requireNonNull( + handle.aggregateThenMaybeReset(0, 1, Attributes.empty(), /* reset= */ false)); + + assertThat(point).isInstanceOf(ImmutableExponentialHistogramPointData.class); + assertThat(point.getPositiveBuckets()) + .isInstanceOf(DoubleBase2ExponentialHistogramBuckets.class); + assertThat(point.getNegativeBuckets()) + .isInstanceOf(DoubleBase2ExponentialHistogramBuckets.class); + } + + @Test + public void reusablePoint_emptyFirstThenRecordAndCheck() { + initialize(MemoryMode.REUSABLE_DATA); + + DoubleBase2ExponentialHistogramAggregator.Handle handle = + (DoubleBase2ExponentialHistogramAggregator.Handle) aggregator.createHandle(); + + // Let's create a point without buckets + ExponentialHistogramPointData point = + Objects.requireNonNull( + handle.aggregateThenMaybeReset(0, 1, Attributes.empty(), /* reset= */ false)); + + assertThat(point).isInstanceOf(MutableExponentialHistogramPointData.class); + assertThat(point.getPositiveBuckets()).isInstanceOf(EmptyExponentialHistogramBuckets.class); + assertThat(point.getNegativeBuckets()).isInstanceOf(EmptyExponentialHistogramBuckets.class); + + // record a measurement to initialize positive buckets + handle.recordDouble(0.5); + // record a measurement to initialize negative buckets + handle.recordDouble(-13.2); + + point = + Objects.requireNonNull( + handle.aggregateThenMaybeReset(0, 1, Attributes.empty(), /* reset= */ false)); + + assertThat(point).isInstanceOf(MutableExponentialHistogramPointData.class); + assertThat(point.getPositiveBuckets()).isInstanceOf(MutableExponentialHistogramBuckets.class); + assertThat(point.getNegativeBuckets()).isInstanceOf(MutableExponentialHistogramBuckets.class); + assertThat(point.getPositiveBuckets().getBucketCounts()).isNotEmpty(); + assertThat(point.getNegativeBuckets().getBucketCounts()).isNotEmpty(); + } } diff --git a/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/internal/aggregator/DoubleBase2ExponentialHistogramBucketsTest.java b/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/internal/aggregator/DoubleBase2ExponentialHistogramBucketsTest.java index b839892da80..fa6bcc255f4 100644 --- a/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/internal/aggregator/DoubleBase2ExponentialHistogramBucketsTest.java +++ b/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/internal/aggregator/DoubleBase2ExponentialHistogramBucketsTest.java @@ -8,9 +8,13 @@ import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; +import io.opentelemetry.sdk.common.export.MemoryMode; +import io.opentelemetry.sdk.internal.DynamicPrimitiveLongList; import java.util.Arrays; import java.util.Collections; import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.EnumSource; /** * These are extra test cases for buckets. Much of this class is already tested via more complex @@ -18,11 +22,12 @@ */ class DoubleBase2ExponentialHistogramBucketsTest { - @Test - void record_Valid() { + @ParameterizedTest + @EnumSource(MemoryMode.class) + void record_Valid(MemoryMode memoryMode) { // Can only effectively test recording of one value here due to downscaling required. // More complex recording/downscaling operations are tested in the aggregator. - DoubleBase2ExponentialHistogramBuckets b = newBuckets(); + DoubleBase2ExponentialHistogramBuckets b = newBuckets(memoryMode); b.record(1); b.record(1); b.record(1); @@ -30,15 +35,17 @@ void record_Valid() { assertThat(b.getBucketCounts()).isEqualTo(Collections.singletonList(3L)); } - @Test - void record_Zero_Throws() { - DoubleBase2ExponentialHistogramBuckets b = newBuckets(); + @ParameterizedTest + @EnumSource(MemoryMode.class) + void record_Zero_Throws(MemoryMode memoryMode) { + DoubleBase2ExponentialHistogramBuckets b = newBuckets(memoryMode); assertThatThrownBy(() -> b.record(0)).isInstanceOf(IllegalStateException.class); } - @Test - void downscale_Valid() { - DoubleBase2ExponentialHistogramBuckets b = newBuckets(); + @ParameterizedTest + @EnumSource(MemoryMode.class) + void downscale_Valid(MemoryMode memoryMode) { + DoubleBase2ExponentialHistogramBuckets b = newBuckets(memoryMode); b.downscale(20); // scale of zero is easy to reason with without a calculator b.record(1); b.record(2); @@ -49,16 +56,18 @@ void downscale_Valid() { assertThat(b.getOffset()).isEqualTo(-1); } - @Test - void downscale_NegativeIncrement_Throws() { - DoubleBase2ExponentialHistogramBuckets b = newBuckets(); + @ParameterizedTest + @EnumSource(MemoryMode.class) + void downscale_NegativeIncrement_Throws(MemoryMode memoryMode) { + DoubleBase2ExponentialHistogramBuckets b = newBuckets(memoryMode); assertThatThrownBy(() -> b.downscale(-1)).isInstanceOf(IllegalStateException.class); } - @Test - void equalsAndHashCode() { - DoubleBase2ExponentialHistogramBuckets a = newBuckets(); - DoubleBase2ExponentialHistogramBuckets b = newBuckets(); + @ParameterizedTest + @EnumSource(MemoryMode.class) + void equalsAndHashCode(MemoryMode memoryMode) { + DoubleBase2ExponentialHistogramBuckets a = newBuckets(memoryMode); + DoubleBase2ExponentialHistogramBuckets b = newBuckets(memoryMode); assertThat(a).isNotNull(); assertThat(b).isEqualTo(a); @@ -76,9 +85,9 @@ void equalsAndHashCode() { assertThat(a).hasSameHashCodeAs(b); // Now we start to play with altering offset, but having same effective counts. - DoubleBase2ExponentialHistogramBuckets empty = newBuckets(); + DoubleBase2ExponentialHistogramBuckets empty = newBuckets(memoryMode); empty.downscale(20); - DoubleBase2ExponentialHistogramBuckets c = newBuckets(); + DoubleBase2ExponentialHistogramBuckets c = newBuckets(memoryMode); c.downscale(20); assertThat(c.record(1)).isTrue(); // Record can fail if scale is not set correctly. @@ -86,17 +95,85 @@ void equalsAndHashCode() { assertThat(c.getTotalCount()).isEqualTo(2); } - @Test - void toString_Valid() { + @ParameterizedTest + @EnumSource(MemoryMode.class) + void toString_Valid(MemoryMode memoryMode) { // Note this test may break once difference implementations for counts are developed since // the counts may have different toStrings(). - DoubleBase2ExponentialHistogramBuckets b = newBuckets(); + DoubleBase2ExponentialHistogramBuckets b = newBuckets(memoryMode); b.record(1); assertThat(b.toString()) .isEqualTo("DoubleExponentialHistogramBuckets{scale: 20, offset: -1, counts: {-1=1} }"); } - private static DoubleBase2ExponentialHistogramBuckets newBuckets() { - return new DoubleBase2ExponentialHistogramBuckets(20, 160); + @Test + void testGetBucketCountsWithReusableList() { + // Can only effectively test recording of one value here due to downscaling required. + // More complex recording/downscaling operations are tested in the aggregator. + DoubleBase2ExponentialHistogramBuckets b = newBuckets(MemoryMode.REUSABLE_DATA); + b.record(1); + b.record(1); + b.record(1); + assertThat(b.getBucketCounts()).isEqualTo(Collections.singletonList(3L)); + + DynamicPrimitiveLongList bucketCounts = DynamicPrimitiveLongList.empty(); + b.getBucketCountsIntoReusableList(bucketCounts); + assertThat(bucketCounts).isEqualTo(Collections.singletonList(3L)); + } + + @Test + public void testGetBucketCountsWithReusableListWithEmptyCounts() { + // Can only effectively test recording of one value here due to downscaling required. + // More complex recording/downscaling operations are tested in the aggregator. + DoubleBase2ExponentialHistogramBuckets b = newBuckets(MemoryMode.REUSABLE_DATA); + assertThat(b.getBucketCounts()).isEmpty(); + + DynamicPrimitiveLongList bucketCounts = DynamicPrimitiveLongList.empty(); + b.getBucketCountsIntoReusableList(bucketCounts); + assertThat(bucketCounts).isEmpty(); + } + + @Test + public void testDownScaleReusableCountIsOkWhenUsedForSecondTime() { + DoubleBase2ExponentialHistogramBuckets immutableDataBasedBuckets = + newBuckets(MemoryMode.IMMUTABLE_DATA); + immutableDataBasedBuckets.record(0.5); + immutableDataBasedBuckets.record(1); + immutableDataBasedBuckets.record(10); + immutableDataBasedBuckets.downscale( + 2); // scale of zero is easy to reason with without a calculator + + DoubleBase2ExponentialHistogramBuckets reusableDataBasedBuckets = + newBuckets(MemoryMode.REUSABLE_DATA); + reusableDataBasedBuckets.record(0.5); + reusableDataBasedBuckets.record(1); + reusableDataBasedBuckets.record(10); + reusableDataBasedBuckets.downscale( + 2); // scale of zero is easy to reason with without a calculator + + assertThat(immutableDataBasedBuckets.getScale()).isEqualTo(reusableDataBasedBuckets.getScale()); + assertThat(immutableDataBasedBuckets.getTotalCount()) + .isEqualTo(reusableDataBasedBuckets.getTotalCount()); + assertThat(immutableDataBasedBuckets.getBucketCounts()) + .isEqualTo(reusableDataBasedBuckets.getBucketCounts()); + assertThat(immutableDataBasedBuckets.getOffset()) + .isEqualTo(reusableDataBasedBuckets.getOffset()); + + immutableDataBasedBuckets.downscale( + 3); // scale of zero is easy to reason with without a calculator + reusableDataBasedBuckets.downscale( + 3); // scale of zero is easy to reason with without a calculator + + assertThat(immutableDataBasedBuckets.getScale()).isEqualTo(reusableDataBasedBuckets.getScale()); + assertThat(immutableDataBasedBuckets.getTotalCount()) + .isEqualTo(reusableDataBasedBuckets.getTotalCount()); + assertThat(immutableDataBasedBuckets.getBucketCounts()) + .isEqualTo(reusableDataBasedBuckets.getBucketCounts()); + assertThat(immutableDataBasedBuckets.getOffset()) + .isEqualTo(reusableDataBasedBuckets.getOffset()); + } + + private static DoubleBase2ExponentialHistogramBuckets newBuckets(MemoryMode memoryMode) { + return new DoubleBase2ExponentialHistogramBuckets(20, 160, memoryMode); } } diff --git a/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/internal/data/MutableExponentialHistogramBucketsTest.java b/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/internal/data/MutableExponentialHistogramBucketsTest.java new file mode 100644 index 00000000000..067f34a54c7 --- /dev/null +++ b/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/internal/data/MutableExponentialHistogramBucketsTest.java @@ -0,0 +1,46 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.sdk.metrics.internal.data; + +import static org.assertj.core.api.Assertions.assertThat; + +import io.opentelemetry.sdk.internal.DynamicPrimitiveLongList; +import org.junit.jupiter.api.Test; + +class MutableExponentialHistogramBucketsTest { + + @Test + void testSanity() { + MutableExponentialHistogramBuckets buckets = new MutableExponentialHistogramBuckets(); + assertThat(buckets.getScale()).isEqualTo(0); + assertThat(buckets.getOffset()).isEqualTo(0); + assertThat(buckets.getTotalCount()).isEqualTo(0); + assertThat(buckets.getBucketCounts()).isEmpty(); + assertThat(buckets.getReusableBucketCountsList()).isEmpty(); + + DynamicPrimitiveLongList bucketCounts = DynamicPrimitiveLongList.of(1, 2, 3); + buckets.set(1, 2, 3, bucketCounts); + + assertThat(buckets.getScale()).isEqualTo(1); + assertThat(buckets.getOffset()).isEqualTo(2); + assertThat(buckets.getTotalCount()).isEqualTo(3); + assertThat(buckets.getBucketCounts()).containsExactly(1L, 2L, 3L); + assertThat(buckets.getReusableBucketCountsList()).containsExactly(1L, 2L, 3L); + + assertThat(buckets.toString()) + .isEqualTo( + "MutableExponentialHistogramBuckets{scale=1, offset=2, bucketCounts=[1, 2, 3], totalCount=3}"); + + MutableExponentialHistogramBuckets sameBuckets = new MutableExponentialHistogramBuckets(); + sameBuckets.set(1, 2, 3, DynamicPrimitiveLongList.of(1, 2, 3)); + assertThat(sameBuckets).isEqualTo(buckets); + assertThat(sameBuckets.hashCode()).isEqualTo(buckets.hashCode()); + + sameBuckets.set(1, 2, 3, DynamicPrimitiveLongList.of(1, 20, 3)); + assertThat(sameBuckets).isNotEqualTo(buckets); + assertThat(sameBuckets.hashCode()).isNotEqualTo(buckets.hashCode()); + } +} diff --git a/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/internal/data/MutableExponentialHistogramPointDataTest.java b/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/internal/data/MutableExponentialHistogramPointDataTest.java new file mode 100644 index 00000000000..0cd56aa6f72 --- /dev/null +++ b/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/internal/data/MutableExponentialHistogramPointDataTest.java @@ -0,0 +1,114 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.sdk.metrics.internal.data; + +import static org.assertj.core.api.Assertions.assertThat; + +import io.opentelemetry.api.common.AttributeKey; +import io.opentelemetry.api.common.Attributes; +import io.opentelemetry.sdk.internal.DynamicPrimitiveLongList; +import java.util.Collections; +import org.junit.jupiter.api.Test; + +class MutableExponentialHistogramPointDataTest { + + @Test + public void testSanity() { + MutableExponentialHistogramPointData pointData = new MutableExponentialHistogramPointData(); + assertThat(pointData.getSum()).isEqualTo(0); + assertThat(pointData.getCount()).isEqualTo(0); + assertThat(pointData.getPositiveBuckets().getTotalCount()).isEqualTo(0); + assertThat(pointData.getNegativeBuckets().getTotalCount()).isEqualTo(0); + assertThat(pointData.getExemplars()).isEmpty(); + + MutableExponentialHistogramBuckets positiveBuckets = new MutableExponentialHistogramBuckets(); + positiveBuckets.set( + /* scale= */ 1, /* offset= */ 2, /* totalCount= */ 3, DynamicPrimitiveLongList.of(1, 2, 3)); + MutableExponentialHistogramBuckets negativeBuckets = new MutableExponentialHistogramBuckets(); + negativeBuckets.set(10, 20, 30, DynamicPrimitiveLongList.of(50, 60, 70)); + + pointData.set( + /* scale= */ 1, + /* sum= */ 2, + /* zeroCount= */ 10, + /* hasMin= */ true, + /* min= */ 100, + /* hasMax= */ true, + /* max= */ 1000, + positiveBuckets, + negativeBuckets, + /* startEpochNanos= */ 10, + /* epochNanos= */ 20, + Attributes.of(AttributeKey.stringKey("foo"), "bar"), + Collections.emptyList()); + + assertThat(pointData.getSum()).isEqualTo(2); + assertThat(pointData.getCount()).isEqualTo(10 + 30 + 3); + assertThat(pointData.getAttributes().get(AttributeKey.stringKey("foo"))).isEqualTo("bar"); + assertThat(pointData.getAttributes().size()).isEqualTo(1); + assertThat(pointData.getScale()).isEqualTo(1); + assertThat(pointData.getZeroCount()).isEqualTo(10); + assertThat(pointData.hasMin()).isTrue(); + assertThat(pointData.getMin()).isEqualTo(100); + assertThat(pointData.hasMax()).isTrue(); + assertThat(pointData.getMax()).isEqualTo(1000); + assertThat(pointData.getPositiveBuckets().getTotalCount()).isEqualTo(3); + assertThat(pointData.getNegativeBuckets().getTotalCount()).isEqualTo(30); + assertThat(pointData.getPositiveBuckets().getBucketCounts()).containsExactly(1L, 2L, 3L); + assertThat(pointData.getNegativeBuckets().getBucketCounts()).containsExactly(50L, 60L, 70L); + assertThat(pointData.getStartEpochNanos()).isEqualTo(10); + assertThat(pointData.getEpochNanos()).isEqualTo(20); + assertThat(pointData.getExemplars()).isEmpty(); + + assertThat(pointData.toString()) + .isEqualTo( + "MutableExponentialHistogramPointData{startEpochNanos=10, epochNanos=20, " + + "attributes={foo=\"bar\"}, scale=1, sum=2.0, count=43, zeroCount=10, hasMin=true, " + + "min=100.0, hasMax=true, max=1000.0, " + + "positiveBuckets=MutableExponentialHistogramBuckets{scale=1, offset=2, " + + "bucketCounts=[1, 2, 3], totalCount=3}, " + + "negativeBuckets=MutableExponentialHistogramBuckets{scale=10, offset=20, " + + "bucketCounts=[50, 60, 70], totalCount=30}, exemplars=[]}"); + + MutableExponentialHistogramPointData samePointData = new MutableExponentialHistogramPointData(); + samePointData.set( + /* scale= */ 1, + /* sum= */ 2, + /* zeroCount= */ 10, + /* hasMin= */ true, + /* min= */ 100, + /* hasMax= */ true, + /* max= */ 1000, + positiveBuckets, + negativeBuckets, + /* startEpochNanos= */ 10, + /* epochNanos= */ 20, + Attributes.of(AttributeKey.stringKey("foo"), "bar"), + Collections.emptyList()); + assertThat(samePointData).isEqualTo(pointData); + assertThat(samePointData.hashCode()).isEqualTo(pointData.hashCode()); + + MutableExponentialHistogramPointData differentPointData = + new MutableExponentialHistogramPointData(); + differentPointData.set( + /* scale= */ 1, + /* sum= */ 2, + /* zeroCount= */ 10000000, + /* hasMin= */ true, + /* min= */ 100, + /* hasMax= */ true, + /* max= */ 1000, + positiveBuckets, + negativeBuckets, + /* startEpochNanos= */ 10, + /* epochNanos= */ 20, + Attributes.of(AttributeKey.stringKey("foo"), "bar"), + Collections.emptyList()); + + assertThat(differentPointData).isNotEqualTo(pointData); + assertThat(differentPointData.hashCode()).isNotEqualTo(pointData.hashCode()); + } +} diff --git a/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/internal/state/SynchronousMetricStorageTest.java b/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/internal/state/SynchronousMetricStorageTest.java index 2d548acc169..0117af20b59 100644 --- a/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/internal/state/SynchronousMetricStorageTest.java +++ b/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/internal/state/SynchronousMetricStorageTest.java @@ -5,6 +5,7 @@ package io.opentelemetry.sdk.metrics.internal.state; +import static io.opentelemetry.sdk.common.export.MemoryMode.IMMUTABLE_DATA; import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.assertThat; import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.attributeEntry; import static org.mockito.Mockito.never; @@ -103,7 +104,7 @@ private void initialize(MemoryMode memoryMode) { aggregator = spy( ((AggregatorFactory) Aggregation.sum()) - .createAggregator(DESCRIPTOR, ExemplarFilter.alwaysOff())); + .createAggregator(DESCRIPTOR, ExemplarFilter.alwaysOff(), memoryMode)); } @ParameterizedTest @@ -205,7 +206,7 @@ void recordAndCollect_CumulativeDoesNotReset(MemoryMode memoryMode) { @Test void recordAndCollect_DeltaResets_ImmutableData() { - initialize(MemoryMode.IMMUTABLE_DATA); + initialize(IMMUTABLE_DATA); DefaultSynchronousMetricStorage storage = new DefaultSynchronousMetricStorage<>( @@ -423,7 +424,7 @@ void recordAndCollect_CumulativeAtLimit(MemoryMode memoryMode) { @Test void recordAndCollect_DeltaAtLimit_ImmutableDataMemoryMode() { - initialize(MemoryMode.IMMUTABLE_DATA); + initialize(IMMUTABLE_DATA); DefaultSynchronousMetricStorage storage = new DefaultSynchronousMetricStorage<>( @@ -798,7 +799,7 @@ private static Stream concurrentStressTestArguments() { for (MemoryMode memoryMode : MemoryMode.values()) { Aggregator aggregator = ((AggregatorFactory) Aggregation.sum()) - .createAggregator(DESCRIPTOR, ExemplarFilter.alwaysOff()); + .createAggregator(DESCRIPTOR, ExemplarFilter.alwaysOff(), memoryMode); argumentsList.add( Arguments.of( diff --git a/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/internal/view/Base2ExponentialHistogramAggregationTest.java b/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/internal/view/Base2ExponentialHistogramAggregationTest.java index 1d02a33619d..0479baafde3 100644 --- a/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/internal/view/Base2ExponentialHistogramAggregationTest.java +++ b/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/internal/view/Base2ExponentialHistogramAggregationTest.java @@ -9,6 +9,7 @@ import static org.assertj.core.api.Assertions.assertThatThrownBy; import io.opentelemetry.api.common.Attributes; +import io.opentelemetry.sdk.common.export.MemoryMode; import io.opentelemetry.sdk.metrics.Aggregation; import io.opentelemetry.sdk.metrics.InstrumentType; import io.opentelemetry.sdk.metrics.InstrumentValueType; @@ -56,7 +57,8 @@ void minimumBucketsCanAccommodateMaxRange() { InstrumentType.HISTOGRAM, InstrumentValueType.DOUBLE, Advice.empty()), - ExemplarFilter.alwaysOff()); + ExemplarFilter.alwaysOff(), + MemoryMode.IMMUTABLE_DATA); AggregatorHandle handle = aggregator.createHandle(); // Record max range From 208118af1841fa6019300f086510009584f4fea9 Mon Sep 17 00:00:00 2001 From: Crypt Keeper <64215+codefromthecrypt@users.noreply.github.com> Date: Sat, 13 Jan 2024 07:02:11 +0800 Subject: [PATCH 195/901] Update dependency io.zipkin.reporter2:zipkin-reporter-bom to 3.1.1 (#6129) Signed-off-by: Adrian Cole --- dependencyManagement/build.gradle.kts | 2 +- .../opentelemetry-exporter-zipkin.txt | 6 +- .../exporter/zipkin/BytesEncoderAdapter.java | 58 +++++++++++++++ .../exporter/zipkin/ZipkinSpanExporter.java | 6 +- .../zipkin/ZipkinSpanExporterBuilder.java | 19 ++++- .../zipkin/BytesEncoderAdapterTest.java | 70 +++++++++++++++++++ .../ZipkinSpanExporterEndToEndHttpTest.java | 6 +- .../zipkin/ZipkinSpanExporterTest.java | 37 ++++++++-- 8 files changed, 189 insertions(+), 15 deletions(-) create mode 100644 exporters/zipkin/src/main/java/io/opentelemetry/exporter/zipkin/BytesEncoderAdapter.java create mode 100644 exporters/zipkin/src/test/java/io/opentelemetry/exporter/zipkin/BytesEncoderAdapterTest.java diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index eb8501ba9a9..d4c4ca11de3 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -16,8 +16,8 @@ val DEPENDENCY_BOMS = listOf( "com.squareup.okio:okio-bom:3.7.0", // applies to transitive dependencies of okhttp "io.grpc:grpc-bom:1.60.1", "io.netty:netty-bom:4.1.104.Final", + "io.zipkin.reporter2:zipkin-reporter-bom:3.1.1", "io.zipkin.brave:brave-bom:5.17.0", - "io.zipkin.reporter2:zipkin-reporter-bom:2.17.1", "org.assertj:assertj-bom:3.25.1", "org.junit:junit-bom:5.10.1", "org.testcontainers:testcontainers-bom:1.19.3", diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-zipkin.txt b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-zipkin.txt index df26146497b..73d401a04b9 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-zipkin.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-zipkin.txt @@ -1,2 +1,6 @@ Comparing source compatibility of against -No changes. \ No newline at end of file +*** MODIFIED CLASS: PUBLIC FINAL io.opentelemetry.exporter.zipkin.ZipkinSpanExporterBuilder (not serializable) + === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 + === UNCHANGED METHOD: PUBLIC io.opentelemetry.exporter.zipkin.ZipkinSpanExporterBuilder setEncoder(zipkin2.codec.BytesEncoder) + +++ NEW ANNOTATION: java.lang.Deprecated + +++ NEW METHOD: PUBLIC(+) io.opentelemetry.exporter.zipkin.ZipkinSpanExporterBuilder setEncoder(zipkin2.reporter.BytesEncoder) diff --git a/exporters/zipkin/src/main/java/io/opentelemetry/exporter/zipkin/BytesEncoderAdapter.java b/exporters/zipkin/src/main/java/io/opentelemetry/exporter/zipkin/BytesEncoderAdapter.java new file mode 100644 index 00000000000..8605eacd936 --- /dev/null +++ b/exporters/zipkin/src/main/java/io/opentelemetry/exporter/zipkin/BytesEncoderAdapter.java @@ -0,0 +1,58 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.exporter.zipkin; + +import zipkin2.Span; +import zipkin2.reporter.BytesEncoder; +import zipkin2.reporter.Encoding; + +/** + * This supports the deprecated method {@link + * ZipkinSpanExporterBuilder#setEncoder(zipkin2.codec.BytesEncoder)}. + */ +final class BytesEncoderAdapter implements BytesEncoder { + private final zipkin2.codec.BytesEncoder delegate; + private final Encoding encoding; + + @SuppressWarnings("deprecation") // we have to use the deprecated thrift encoding to return it + BytesEncoderAdapter(zipkin2.codec.BytesEncoder delegate) { + this.delegate = delegate; + switch (delegate.encoding()) { + case JSON: + this.encoding = Encoding.JSON; + break; + case PROTO3: + this.encoding = Encoding.PROTO3; + break; + case THRIFT: + this.encoding = Encoding.THRIFT; + break; + default: + // Only possible if zipkin2 adds an encoding besides above, which is very unlikely. + throw new UnsupportedOperationException("unsupported encoding " + delegate.encoding()); + } + } + + @Override + public Encoding encoding() { + return encoding; + } + + @Override + public int sizeInBytes(Span span) { + return delegate.sizeInBytes(span); + } + + @Override + public byte[] encode(Span span) { + return delegate.encode(span); + } + + @Override + public String toString() { + return delegate.toString(); + } +} diff --git a/exporters/zipkin/src/main/java/io/opentelemetry/exporter/zipkin/ZipkinSpanExporter.java b/exporters/zipkin/src/main/java/io/opentelemetry/exporter/zipkin/ZipkinSpanExporter.java index 37d8c1fd022..840e53b58de 100644 --- a/exporters/zipkin/src/main/java/io/opentelemetry/exporter/zipkin/ZipkinSpanExporter.java +++ b/exporters/zipkin/src/main/java/io/opentelemetry/exporter/zipkin/ZipkinSpanExporter.java @@ -19,10 +19,10 @@ import java.util.function.Supplier; import java.util.logging.Level; import java.util.logging.Logger; -import zipkin2.Callback; import zipkin2.Span; -import zipkin2.codec.BytesEncoder; -import zipkin2.codec.Encoding; +import zipkin2.reporter.BytesEncoder; +import zipkin2.reporter.Callback; +import zipkin2.reporter.Encoding; import zipkin2.reporter.Sender; /** diff --git a/exporters/zipkin/src/main/java/io/opentelemetry/exporter/zipkin/ZipkinSpanExporterBuilder.java b/exporters/zipkin/src/main/java/io/opentelemetry/exporter/zipkin/ZipkinSpanExporterBuilder.java index 2691c700954..ad19cbc8d33 100644 --- a/exporters/zipkin/src/main/java/io/opentelemetry/exporter/zipkin/ZipkinSpanExporterBuilder.java +++ b/exporters/zipkin/src/main/java/io/opentelemetry/exporter/zipkin/ZipkinSpanExporterBuilder.java @@ -17,9 +17,9 @@ import java.util.function.Supplier; import javax.annotation.Nullable; import zipkin2.Span; -import zipkin2.codec.BytesEncoder; -import zipkin2.codec.SpanBytesEncoder; +import zipkin2.reporter.BytesEncoder; import zipkin2.reporter.Sender; +import zipkin2.reporter.SpanBytesEncoder; import zipkin2.reporter.okhttp3.OkHttpSender; /** Builder class for {@link ZipkinSpanExporter}. */ @@ -49,6 +49,21 @@ public ZipkinSpanExporterBuilder setSender(Sender sender) { return this; } + /** + * Sets the {@link zipkin2.codec.BytesEncoder}, which controls the format used by the {@link + * Sender}. Defaults to the {@link zipkin2.codec.SpanBytesEncoder#JSON_V2}. + * + * @param encoder the {@code BytesEncoder} to use. + * @return this. + * @see zipkin2.codec.SpanBytesEncoder + * @deprecated Use {@link #setEncoder(BytesEncoder)} instead. + */ + @Deprecated + public ZipkinSpanExporterBuilder setEncoder(zipkin2.codec.BytesEncoder encoder) { + requireNonNull(encoder, "encoder"); + return setEncoder(new BytesEncoderAdapter(encoder)); + } + /** * Sets the {@link BytesEncoder}, which controls the format used by the {@link Sender}. Defaults * to the {@link SpanBytesEncoder#JSON_V2}. diff --git a/exporters/zipkin/src/test/java/io/opentelemetry/exporter/zipkin/BytesEncoderAdapterTest.java b/exporters/zipkin/src/test/java/io/opentelemetry/exporter/zipkin/BytesEncoderAdapterTest.java new file mode 100644 index 00000000000..24b16eb3a06 --- /dev/null +++ b/exporters/zipkin/src/test/java/io/opentelemetry/exporter/zipkin/BytesEncoderAdapterTest.java @@ -0,0 +1,70 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.exporter.zipkin; + +import static io.opentelemetry.exporter.zipkin.ZipkinTestUtil.PARENT_SPAN_ID; +import static io.opentelemetry.exporter.zipkin.ZipkinTestUtil.SPAN_ID; +import static io.opentelemetry.exporter.zipkin.ZipkinTestUtil.TRACE_ID; +import static org.assertj.core.api.Assertions.assertThat; + +import org.junit.jupiter.api.Test; +import zipkin2.Endpoint; +import zipkin2.Span; +import zipkin2.reporter.Encoding; +import zipkin2.reporter.SpanBytesEncoder; + +class BytesEncoderAdapterTest { + + /** Contains {@link Span#localEndpoint()} to ensure would be encoded differently. */ + private final Span testSpan = + Span.newBuilder() + .traceId(TRACE_ID) + .parentId(PARENT_SPAN_ID) + .id(SPAN_ID) + .localEndpoint(Endpoint.newBuilder().serviceName("test").build()) + .build(); + + @Test + void testJsonV2() { + BytesEncoderAdapter adapter = new BytesEncoderAdapter(zipkin2.codec.SpanBytesEncoder.JSON_V2); + assertThat(adapter.encoding()).isEqualTo(Encoding.JSON); + assertThat(adapter.encode(testSpan)).isEqualTo(SpanBytesEncoder.JSON_V2.encode(testSpan)); + assertThat(adapter.sizeInBytes(testSpan)) + .isEqualTo(SpanBytesEncoder.JSON_V2.sizeInBytes(testSpan)); + assertThat(adapter).hasToString(SpanBytesEncoder.JSON_V2.toString()); + } + + @Test + void testProtobuf() { + BytesEncoderAdapter adapter = new BytesEncoderAdapter(zipkin2.codec.SpanBytesEncoder.PROTO3); + assertThat(adapter.encoding()).isEqualTo(Encoding.PROTO3); + assertThat(adapter.encode(testSpan)).isEqualTo(SpanBytesEncoder.PROTO3.encode(testSpan)); + assertThat(adapter.sizeInBytes(testSpan)) + .isEqualTo(SpanBytesEncoder.PROTO3.sizeInBytes(testSpan)); + assertThat(adapter).hasToString(SpanBytesEncoder.PROTO3.toString()); + } + + @Test + @SuppressWarnings("deprecation") // we have to use the deprecated thrift encoding to test it + void testThrift() { + BytesEncoderAdapter adapter = new BytesEncoderAdapter(zipkin2.codec.SpanBytesEncoder.THRIFT); + assertThat(adapter.encoding()).isEqualTo(Encoding.THRIFT); + assertThat(adapter.encode(testSpan)).isEqualTo(SpanBytesEncoder.THRIFT.encode(testSpan)); + assertThat(adapter.sizeInBytes(testSpan)) + .isEqualTo(SpanBytesEncoder.THRIFT.sizeInBytes(testSpan)); + assertThat(adapter).hasToString(SpanBytesEncoder.THRIFT.toString()); + } + + @Test + void testJsonV1() { + BytesEncoderAdapter adapter = new BytesEncoderAdapter(zipkin2.codec.SpanBytesEncoder.JSON_V1); + assertThat(adapter.encoding()).isEqualTo(Encoding.JSON); + assertThat(adapter.encode(testSpan)).isEqualTo(SpanBytesEncoder.JSON_V1.encode(testSpan)); + assertThat(adapter.sizeInBytes(testSpan)) + .isEqualTo(SpanBytesEncoder.JSON_V1.sizeInBytes(testSpan)); + assertThat(adapter).hasToString(SpanBytesEncoder.JSON_V1.toString()); + } +} diff --git a/exporters/zipkin/src/test/java/io/opentelemetry/exporter/zipkin/ZipkinSpanExporterEndToEndHttpTest.java b/exporters/zipkin/src/test/java/io/opentelemetry/exporter/zipkin/ZipkinSpanExporterEndToEndHttpTest.java index c7d23af452f..c55d2c01c67 100644 --- a/exporters/zipkin/src/test/java/io/opentelemetry/exporter/zipkin/ZipkinSpanExporterEndToEndHttpTest.java +++ b/exporters/zipkin/src/test/java/io/opentelemetry/exporter/zipkin/ZipkinSpanExporterEndToEndHttpTest.java @@ -44,9 +44,9 @@ import org.testcontainers.junit.jupiter.Testcontainers; import zipkin2.Endpoint; import zipkin2.Span; -import zipkin2.codec.Encoding; import zipkin2.codec.SpanBytesDecoder; -import zipkin2.codec.SpanBytesEncoder; +import zipkin2.reporter.Encoding; +import zipkin2.reporter.SpanBytesEncoder; import zipkin2.reporter.okhttp3.OkHttpSender; @Testcontainers(disabledWithoutDocker = true) @@ -82,7 +82,7 @@ class ZipkinSpanExporterEndToEndHttpTest { @Container public static final GenericContainer zipkinContainer = - new GenericContainer<>("ghcr.io/openzipkin/zipkin:2.23") + new GenericContainer<>("ghcr.io/openzipkin/zipkin:2.27") .withExposedPorts(ZIPKIN_API_PORT) .waitingFor(Wait.forHttp("/health").forPort(ZIPKIN_API_PORT)); diff --git a/exporters/zipkin/src/test/java/io/opentelemetry/exporter/zipkin/ZipkinSpanExporterTest.java b/exporters/zipkin/src/test/java/io/opentelemetry/exporter/zipkin/ZipkinSpanExporterTest.java index 263edadad53..38e4534c71a 100644 --- a/exporters/zipkin/src/test/java/io/opentelemetry/exporter/zipkin/ZipkinSpanExporterTest.java +++ b/exporters/zipkin/src/test/java/io/opentelemetry/exporter/zipkin/ZipkinSpanExporterTest.java @@ -29,11 +29,13 @@ import org.junit.jupiter.api.extension.RegisterExtension; import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; -import zipkin2.Call; -import zipkin2.Callback; import zipkin2.Span; -import zipkin2.codec.SpanBytesEncoder; +import zipkin2.reporter.BytesEncoder; +import zipkin2.reporter.Call; +import zipkin2.reporter.Callback; +import zipkin2.reporter.Encoding; import zipkin2.reporter.Sender; +import zipkin2.reporter.SpanBytesEncoder; @ExtendWith(MockitoExtension.class) class ZipkinSpanExporterTest { @@ -144,7 +146,8 @@ void testShutdown() throws IOException { } @Test - @SuppressWarnings("PreferJavaTimeOverload") + @SuppressWarnings({"PreferJavaTimeOverload", "deprecation"}) + // we have to use the deprecated setEncoder overload to test it void invalidConfig() { assertThatThrownBy(() -> ZipkinSpanExporter.builder().setReadTimeout(-1, TimeUnit.MILLISECONDS)) .isInstanceOf(IllegalArgumentException.class) @@ -170,9 +173,33 @@ void invalidConfig() { .isInstanceOf(NullPointerException.class) .hasMessage("sender"); - assertThatThrownBy(() -> ZipkinSpanExporter.builder().setEncoder(null)) + assertThatThrownBy( + () -> ZipkinSpanExporter.builder().setEncoder((zipkin2.codec.BytesEncoder) null)) .isInstanceOf(NullPointerException.class) .hasMessage("encoder"); + + assertThatThrownBy(() -> ZipkinSpanExporter.builder().setEncoder((BytesEncoder) null)) + .isInstanceOf(NullPointerException.class) + .hasMessage("encoder"); + } + + @Test + void encoderProtobuf() { + @SuppressWarnings("deprecation") // we have to use the deprecated setEncoderto test it + ZipkinSpanExporter exporter = + ZipkinSpanExporter.builder().setEncoder(zipkin2.codec.SpanBytesEncoder.PROTO3).build(); + try { + assertThat(exporter).extracting("encoder.encoding").isEqualTo(Encoding.PROTO3); + } finally { + exporter.shutdown(); + } + + exporter = ZipkinSpanExporter.builder().setEncoder(SpanBytesEncoder.PROTO3).build(); + try { + assertThat(exporter).extracting("encoder").isEqualTo(SpanBytesEncoder.PROTO3); + } finally { + exporter.shutdown(); + } } @Test From dbaba2fd9168bb413d233942e533fada2b2c761e Mon Sep 17 00:00:00 2001 From: jack-berg <34418638+jack-berg@users.noreply.github.com> Date: Fri, 12 Jan 2024 17:15:46 -0600 Subject: [PATCH 196/901] Post release 1.34.1 (#6146) --- README.md | 68 +++++++++---------- .../1.34.1_vs_1.34.0/opentelemetry-api.txt | 2 + .../opentelemetry-context.txt | 2 + .../opentelemetry-exporter-common.txt | 2 + .../opentelemetry-exporter-jaeger-thrift.txt | 2 + .../opentelemetry-exporter-jaeger.txt | 2 + .../opentelemetry-exporter-logging-otlp.txt | 2 + .../opentelemetry-exporter-logging.txt | 2 + .../opentelemetry-exporter-otlp-common.txt | 2 + .../opentelemetry-exporter-otlp.txt | 2 + ...y-exporter-sender-grpc-managed-channel.txt | 2 + .../opentelemetry-exporter-sender-okhttp.txt | 2 + .../opentelemetry-exporter-zipkin.txt | 2 + .../opentelemetry-extension-kotlin.txt | 2 + ...ntelemetry-extension-trace-propagators.txt | 2 + .../opentelemetry-opentracing-shim.txt | 2 + .../opentelemetry-sdk-common.txt | 2 + ...emetry-sdk-extension-autoconfigure-spi.txt | 2 + ...ntelemetry-sdk-extension-autoconfigure.txt | 2 + ...ry-sdk-extension-jaeger-remote-sampler.txt | 2 + .../opentelemetry-sdk-logs.txt | 2 + .../opentelemetry-sdk-metrics.txt | 2 + .../opentelemetry-sdk-testing.txt | 2 + .../opentelemetry-sdk-trace.txt | 2 + .../1.34.1_vs_1.34.0/opentelemetry-sdk.txt | 2 + 25 files changed, 82 insertions(+), 34 deletions(-) create mode 100644 docs/apidiffs/1.34.1_vs_1.34.0/opentelemetry-api.txt create mode 100644 docs/apidiffs/1.34.1_vs_1.34.0/opentelemetry-context.txt create mode 100644 docs/apidiffs/1.34.1_vs_1.34.0/opentelemetry-exporter-common.txt create mode 100644 docs/apidiffs/1.34.1_vs_1.34.0/opentelemetry-exporter-jaeger-thrift.txt create mode 100644 docs/apidiffs/1.34.1_vs_1.34.0/opentelemetry-exporter-jaeger.txt create mode 100644 docs/apidiffs/1.34.1_vs_1.34.0/opentelemetry-exporter-logging-otlp.txt create mode 100644 docs/apidiffs/1.34.1_vs_1.34.0/opentelemetry-exporter-logging.txt create mode 100644 docs/apidiffs/1.34.1_vs_1.34.0/opentelemetry-exporter-otlp-common.txt create mode 100644 docs/apidiffs/1.34.1_vs_1.34.0/opentelemetry-exporter-otlp.txt create mode 100644 docs/apidiffs/1.34.1_vs_1.34.0/opentelemetry-exporter-sender-grpc-managed-channel.txt create mode 100644 docs/apidiffs/1.34.1_vs_1.34.0/opentelemetry-exporter-sender-okhttp.txt create mode 100644 docs/apidiffs/1.34.1_vs_1.34.0/opentelemetry-exporter-zipkin.txt create mode 100644 docs/apidiffs/1.34.1_vs_1.34.0/opentelemetry-extension-kotlin.txt create mode 100644 docs/apidiffs/1.34.1_vs_1.34.0/opentelemetry-extension-trace-propagators.txt create mode 100644 docs/apidiffs/1.34.1_vs_1.34.0/opentelemetry-opentracing-shim.txt create mode 100644 docs/apidiffs/1.34.1_vs_1.34.0/opentelemetry-sdk-common.txt create mode 100644 docs/apidiffs/1.34.1_vs_1.34.0/opentelemetry-sdk-extension-autoconfigure-spi.txt create mode 100644 docs/apidiffs/1.34.1_vs_1.34.0/opentelemetry-sdk-extension-autoconfigure.txt create mode 100644 docs/apidiffs/1.34.1_vs_1.34.0/opentelemetry-sdk-extension-jaeger-remote-sampler.txt create mode 100644 docs/apidiffs/1.34.1_vs_1.34.0/opentelemetry-sdk-logs.txt create mode 100644 docs/apidiffs/1.34.1_vs_1.34.0/opentelemetry-sdk-metrics.txt create mode 100644 docs/apidiffs/1.34.1_vs_1.34.0/opentelemetry-sdk-testing.txt create mode 100644 docs/apidiffs/1.34.1_vs_1.34.0/opentelemetry-sdk-trace.txt create mode 100644 docs/apidiffs/1.34.1_vs_1.34.0/opentelemetry-sdk.txt diff --git a/README.md b/README.md index f273a554485..6ec11fd890b 100644 --- a/README.md +++ b/README.md @@ -102,7 +102,7 @@ dependency versions in sync. io.opentelemetry opentelemetry-bom - 1.34.0 + 1.34.1 pom import @@ -121,7 +121,7 @@ dependency versions in sync. ```groovy dependencies { - implementation platform("io.opentelemetry:opentelemetry-bom:1.34.0") + implementation platform("io.opentelemetry:opentelemetry-bom:1.34.1") implementation('io.opentelemetry:opentelemetry-api') } ``` @@ -130,8 +130,8 @@ Note that if you want to use any artifacts that have not fully stabilized yet (s ```groovy dependencies { - implementation platform("io.opentelemetry:opentelemetry-bom:1.34.0") - implementation platform('io.opentelemetry:opentelemetry-bom-alpha:1.34.0-alpha') + implementation platform("io.opentelemetry:opentelemetry-bom:1.34.1") + implementation platform('io.opentelemetry:opentelemetry-bom-alpha:1.34.1-alpha') implementation('io.opentelemetry:opentelemetry-api') implementation('io.opentelemetry:opentelemetry-exporter-prometheus') @@ -227,67 +227,67 @@ dependency as follows, replacing `{{artifact-id}}` with the value from the "Arti | Component | Description | Artifact ID | Version | Javadoc | |----------------------------------------------|----------------------------------------|---------------------------|-------------------------------------------------------------|---------| -| [Bill of Materials (BOM)](./bom) | Bill of materials for stable artifacts | `opentelemetry-bom` | 1.34.0 | N/A | -| [Alpha Bill of Materials (BOM)](./bom-alpha) | Bill of materials for alpha artifacts | `opentelemetry-bom-alpha` | 1.34.0-alpha | N/A | +| [Bill of Materials (BOM)](./bom) | Bill of materials for stable artifacts | `opentelemetry-bom` | 1.34.1 | N/A | +| [Alpha Bill of Materials (BOM)](./bom-alpha) | Bill of materials for alpha artifacts | `opentelemetry-bom-alpha` | 1.34.1-alpha | N/A | ### API | Component | Description | Artifact ID | Version | Javadoc | |-----------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|----------------------------|-------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------| -| [API](./api/all) | OpenTelemetry API, including metrics, traces, baggage, context | `opentelemetry-api` | 1.34.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-api.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-api) | -| [Events API](./api/events) | OpenTelemetry Event API for emitting events. | `opentelemetry-api-events` | 1.34.0-alpha | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-api-events.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-api-events) | -| [Context API](./context) | OpenTelemetry context API | `opentelemetry-context` | 1.34.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-context.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-context) | +| [API](./api/all) | OpenTelemetry API, including metrics, traces, baggage, context | `opentelemetry-api` | 1.34.1 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-api.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-api) | +| [Events API](./api/events) | OpenTelemetry Event API for emitting events. | `opentelemetry-api-events` | 1.34.1-alpha | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-api-events.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-api-events) | +| [Context API](./context) | OpenTelemetry context API | `opentelemetry-context` | 1.34.1 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-context.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-context) | ### API Extensions | Component | Description | Artifact ID | Version | Javadoc | |---------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|---------------------------------------------|-------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| [Kotlin Extension](./extensions/kotlin) | Context extension for coroutines | `opentelemetry-extension-kotlin` | 1.34.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-extension-kotlin.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-extension-kotlin) | -| [Trace Propagators Extension](./extensions/trace-propagators) | Trace propagators, including B3, Jaeger, OT Trace | `opentelemetry-extension-trace-propagators` | 1.34.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-extension-trace-propagators.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-extension-trace-propagators) | -| [Incubator Extension](./extensions/incubator) | API incubator, including pass through propagator, and extended tracer | `opentelemetry-extension-incubator` | 1.34.0-alpha | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-extension-incubator.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-extension-incubator) | +| [Kotlin Extension](./extensions/kotlin) | Context extension for coroutines | `opentelemetry-extension-kotlin` | 1.34.1 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-extension-kotlin.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-extension-kotlin) | +| [Trace Propagators Extension](./extensions/trace-propagators) | Trace propagators, including B3, Jaeger, OT Trace | `opentelemetry-extension-trace-propagators` | 1.34.1 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-extension-trace-propagators.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-extension-trace-propagators) | +| [Incubator Extension](./extensions/incubator) | API incubator, including pass through propagator, and extended tracer | `opentelemetry-extension-incubator` | 1.34.1-alpha | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-extension-incubator.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-extension-incubator) | ### SDK | Component | Description | Artifact ID | Version | Javadoc | |------------------------------|--------------------------------------------------------|-----------------------------|---------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| [SDK](./sdk/all) | OpenTelemetry SDK, including metrics, traces, and logs | `opentelemetry-sdk` | 1.34.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk) | -| [Metrics SDK](./sdk/metrics) | OpenTelemetry metrics SDK | `opentelemetry-sdk-metrics` | 1.34.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-metrics.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-metrics) | -| [Trace SDK](./sdk/trace) | OpenTelemetry trace SDK | `opentelemetry-sdk-trace` | 1.34.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-trace.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-trace) | -| [Log SDK](./sdk/logs) | OpenTelemetry log SDK | `opentelemetry-sdk-logs` | 1.34.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-logs.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-logs) | -| [SDK Common](./sdk/common) | Shared SDK components | `opentelemetry-sdk-common` | 1.34.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-common.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-common) | -| [SDK Testing](./sdk/testing) | Components for testing OpenTelemetry instrumentation | `opentelemetry-sdk-testing` | 1.34.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-testing.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-testing) | +| [SDK](./sdk/all) | OpenTelemetry SDK, including metrics, traces, and logs | `opentelemetry-sdk` | 1.34.1 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk) | +| [Metrics SDK](./sdk/metrics) | OpenTelemetry metrics SDK | `opentelemetry-sdk-metrics` | 1.34.1 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-metrics.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-metrics) | +| [Trace SDK](./sdk/trace) | OpenTelemetry trace SDK | `opentelemetry-sdk-trace` | 1.34.1 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-trace.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-trace) | +| [Log SDK](./sdk/logs) | OpenTelemetry log SDK | `opentelemetry-sdk-logs` | 1.34.1 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-logs.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-logs) | +| [SDK Common](./sdk/common) | Shared SDK components | `opentelemetry-sdk-common` | 1.34.1 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-common.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-common) | +| [SDK Testing](./sdk/testing) | Components for testing OpenTelemetry instrumentation | `opentelemetry-sdk-testing` | 1.34.1 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-testing.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-testing) | ### SDK Exporters | Component | Description | Artifact ID | Version | Javadoc | |-----------------------------------------------------------------------|------------------------------------------------------------------------------|------------------------------------------------------|-------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| [OTLP Exporters](./exporters/otlp/all) | OTLP gRPC & HTTP exporters, including traces, metrics, and logs | `opentelemetry-exporter-otlp` | 1.34.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-otlp.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-otlp) | -| [OTLP Logging Exporters](./exporters/logging-otlp) | Logging exporters in OTLP JSON encoding, including traces, metrics, and logs | `opentelemetry-exporter-logging-otlp` | 1.34.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-logging-otlp.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-logging-otlp) | -| [OTLP Common](./exporters/otlp/common) | Shared OTLP components (internal) | `opentelemetry-exporter-otlp-common` | 1.34.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-otlp-common.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-otlp-common) | -| [Logging Exporter](./exporters/logging) | Logging exporters, including metrics, traces, and logs | `opentelemetry-exporter-logging` | 1.34.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-logging.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-logging) | -| [Zipkin Exporter](./exporters/zipkin) | Zipkin trace exporter | `opentelemetry-exporter-zipkin` | 1.34.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-zipkin.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-zipkin) | -| [Prometheus Exporter](./exporters/prometheus) | Prometheus metric exporter | `opentelemetry-exporter-prometheus` | 1.34.0-alpha | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-prometheus.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-prometheus) | -| [Exporter Common](./exporters/common) | Shared exporter components (internal) | `opentelemetry-exporter-common` | 1.34.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-common.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-common) | -| [OkHttp Sender](./exporters/sender/okhttp) | OkHttp implementation of HttpSender (internal) | `opentelemetry-exporter-sender-okhttp` | 1.34.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-sender-okhttp.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-sender-okhttp) | -| [JDK Sender](./exporters/sender/okhttp) | Java 11+ native HttpClient implementation of HttpSender (internal) | `opentelemetry-exporter-sender-jdk` | 1.34.0-alpha | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-sender-jdk.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-sender-jdk) | | -| [gRPC ManagedChannel Sender](./exporters/sender/grpc-managed-channel) | gRPC ManagedChannel implementation of GrpcSender (internal) | `opentelemetry-exporter-sender-grpc-managed-channel` | 1.34.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-sender-grpc-managed-channel.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-sender-grpc-managed-channel) | | +| [OTLP Exporters](./exporters/otlp/all) | OTLP gRPC & HTTP exporters, including traces, metrics, and logs | `opentelemetry-exporter-otlp` | 1.34.1 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-otlp.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-otlp) | +| [OTLP Logging Exporters](./exporters/logging-otlp) | Logging exporters in OTLP JSON encoding, including traces, metrics, and logs | `opentelemetry-exporter-logging-otlp` | 1.34.1 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-logging-otlp.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-logging-otlp) | +| [OTLP Common](./exporters/otlp/common) | Shared OTLP components (internal) | `opentelemetry-exporter-otlp-common` | 1.34.1 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-otlp-common.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-otlp-common) | +| [Logging Exporter](./exporters/logging) | Logging exporters, including metrics, traces, and logs | `opentelemetry-exporter-logging` | 1.34.1 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-logging.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-logging) | +| [Zipkin Exporter](./exporters/zipkin) | Zipkin trace exporter | `opentelemetry-exporter-zipkin` | 1.34.1 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-zipkin.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-zipkin) | +| [Prometheus Exporter](./exporters/prometheus) | Prometheus metric exporter | `opentelemetry-exporter-prometheus` | 1.34.1-alpha | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-prometheus.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-prometheus) | +| [Exporter Common](./exporters/common) | Shared exporter components (internal) | `opentelemetry-exporter-common` | 1.34.1 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-common.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-common) | +| [OkHttp Sender](./exporters/sender/okhttp) | OkHttp implementation of HttpSender (internal) | `opentelemetry-exporter-sender-okhttp` | 1.34.1 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-sender-okhttp.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-sender-okhttp) | +| [JDK Sender](./exporters/sender/okhttp) | Java 11+ native HttpClient implementation of HttpSender (internal) | `opentelemetry-exporter-sender-jdk` | 1.34.1-alpha | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-sender-jdk.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-sender-jdk) | | +| [gRPC ManagedChannel Sender](./exporters/sender/grpc-managed-channel) | gRPC ManagedChannel implementation of GrpcSender (internal) | `opentelemetry-exporter-sender-grpc-managed-channel` | 1.34.1 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-sender-grpc-managed-channel.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-sender-grpc-managed-channel) | | ### SDK Extensions | Component | Description | Artifact ID | Version | Javadoc | |-------------------------------------------------------------------------------|------------------------------------------------------------------------------------|-----------------------------------------------------|-------------------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| [SDK Autoconfigure](./sdk-extensions/autoconfigure) | Autoconfigure OpenTelemetry SDK from env vars, system properties, and SPI | `opentelemetry-sdk-extension-autoconfigure` | 1.34.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-extension-autoconfigure.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-extension-autoconfigure) | -| [SDK Autoconfigure SPI](./sdk-extensions/autoconfigure-spi) | Service Provider Interface (SPI) definitions for autoconfigure | `opentelemetry-sdk-extension-autoconfigure-spi` | 1.34.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-extension-autoconfigure-spi.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-extension-autoconfigure-spi) | -| [SDK Jaeger Remote Sampler Extension](./sdk-extensions/jaeger-remote-sampler) | Sampler which obtains sampling configuration from remote Jaeger server | `opentelemetry-sdk-extension-jaeger-remote-sampler` | 1.34.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-extension-jaeger-remote-sampler.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-extension-jaeger-remote-sampler) | -| [SDK Incubator](./sdk-extensions/incubator) | SDK incubator, including YAML based view configuration, LeakDetectingSpanProcessor | `opentelemetry-sdk-extension-incubator` | 1.34.0-alpha | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-extension-incubator.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-extension-incubator) | +| [SDK Autoconfigure](./sdk-extensions/autoconfigure) | Autoconfigure OpenTelemetry SDK from env vars, system properties, and SPI | `opentelemetry-sdk-extension-autoconfigure` | 1.34.1 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-extension-autoconfigure.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-extension-autoconfigure) | +| [SDK Autoconfigure SPI](./sdk-extensions/autoconfigure-spi) | Service Provider Interface (SPI) definitions for autoconfigure | `opentelemetry-sdk-extension-autoconfigure-spi` | 1.34.1 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-extension-autoconfigure-spi.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-extension-autoconfigure-spi) | +| [SDK Jaeger Remote Sampler Extension](./sdk-extensions/jaeger-remote-sampler) | Sampler which obtains sampling configuration from remote Jaeger server | `opentelemetry-sdk-extension-jaeger-remote-sampler` | 1.34.1 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-extension-jaeger-remote-sampler.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-extension-jaeger-remote-sampler) | +| [SDK Incubator](./sdk-extensions/incubator) | SDK incubator, including YAML based view configuration, LeakDetectingSpanProcessor | `opentelemetry-sdk-extension-incubator` | 1.34.1-alpha | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-extension-incubator.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-extension-incubator) | ### Shims | Component | Description | Artifact ID | Version | Javadoc | |----------------------------------------|--------------------------------------------------------------|----------------------------------|-------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| [OpenCensus Shim](./opencensus-shim) | Bridge opencensus metrics into the OpenTelemetry metrics SDK | `opentelemetry-opencensus-shim` | 1.34.0-alpha | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-opencensus-shim.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-opencensus-shim) | -| [OpenTracing Shim](./opentracing-shim) | Bridge opentracing spans into the OpenTelemetry trace API | `opentelemetry-opentracing-shim` | 1.34.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-opentracing-shim.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-opentracing-shim) | +| [OpenCensus Shim](./opencensus-shim) | Bridge opencensus metrics into the OpenTelemetry metrics SDK | `opentelemetry-opencensus-shim` | 1.34.1-alpha | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-opencensus-shim.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-opencensus-shim) | +| [OpenTracing Shim](./opentracing-shim) | Bridge opentracing spans into the OpenTelemetry trace API | `opentelemetry-opentracing-shim` | 1.34.1 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-opentracing-shim.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-opentracing-shim) | ## Contributing diff --git a/docs/apidiffs/1.34.1_vs_1.34.0/opentelemetry-api.txt b/docs/apidiffs/1.34.1_vs_1.34.0/opentelemetry-api.txt new file mode 100644 index 00000000000..df26146497b --- /dev/null +++ b/docs/apidiffs/1.34.1_vs_1.34.0/opentelemetry-api.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of against +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.34.1_vs_1.34.0/opentelemetry-context.txt b/docs/apidiffs/1.34.1_vs_1.34.0/opentelemetry-context.txt new file mode 100644 index 00000000000..df26146497b --- /dev/null +++ b/docs/apidiffs/1.34.1_vs_1.34.0/opentelemetry-context.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of against +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.34.1_vs_1.34.0/opentelemetry-exporter-common.txt b/docs/apidiffs/1.34.1_vs_1.34.0/opentelemetry-exporter-common.txt new file mode 100644 index 00000000000..df26146497b --- /dev/null +++ b/docs/apidiffs/1.34.1_vs_1.34.0/opentelemetry-exporter-common.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of against +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.34.1_vs_1.34.0/opentelemetry-exporter-jaeger-thrift.txt b/docs/apidiffs/1.34.1_vs_1.34.0/opentelemetry-exporter-jaeger-thrift.txt new file mode 100644 index 00000000000..df26146497b --- /dev/null +++ b/docs/apidiffs/1.34.1_vs_1.34.0/opentelemetry-exporter-jaeger-thrift.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of against +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.34.1_vs_1.34.0/opentelemetry-exporter-jaeger.txt b/docs/apidiffs/1.34.1_vs_1.34.0/opentelemetry-exporter-jaeger.txt new file mode 100644 index 00000000000..df26146497b --- /dev/null +++ b/docs/apidiffs/1.34.1_vs_1.34.0/opentelemetry-exporter-jaeger.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of against +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.34.1_vs_1.34.0/opentelemetry-exporter-logging-otlp.txt b/docs/apidiffs/1.34.1_vs_1.34.0/opentelemetry-exporter-logging-otlp.txt new file mode 100644 index 00000000000..df26146497b --- /dev/null +++ b/docs/apidiffs/1.34.1_vs_1.34.0/opentelemetry-exporter-logging-otlp.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of against +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.34.1_vs_1.34.0/opentelemetry-exporter-logging.txt b/docs/apidiffs/1.34.1_vs_1.34.0/opentelemetry-exporter-logging.txt new file mode 100644 index 00000000000..df26146497b --- /dev/null +++ b/docs/apidiffs/1.34.1_vs_1.34.0/opentelemetry-exporter-logging.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of against +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.34.1_vs_1.34.0/opentelemetry-exporter-otlp-common.txt b/docs/apidiffs/1.34.1_vs_1.34.0/opentelemetry-exporter-otlp-common.txt new file mode 100644 index 00000000000..df26146497b --- /dev/null +++ b/docs/apidiffs/1.34.1_vs_1.34.0/opentelemetry-exporter-otlp-common.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of against +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.34.1_vs_1.34.0/opentelemetry-exporter-otlp.txt b/docs/apidiffs/1.34.1_vs_1.34.0/opentelemetry-exporter-otlp.txt new file mode 100644 index 00000000000..df26146497b --- /dev/null +++ b/docs/apidiffs/1.34.1_vs_1.34.0/opentelemetry-exporter-otlp.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of against +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.34.1_vs_1.34.0/opentelemetry-exporter-sender-grpc-managed-channel.txt b/docs/apidiffs/1.34.1_vs_1.34.0/opentelemetry-exporter-sender-grpc-managed-channel.txt new file mode 100644 index 00000000000..df26146497b --- /dev/null +++ b/docs/apidiffs/1.34.1_vs_1.34.0/opentelemetry-exporter-sender-grpc-managed-channel.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of against +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.34.1_vs_1.34.0/opentelemetry-exporter-sender-okhttp.txt b/docs/apidiffs/1.34.1_vs_1.34.0/opentelemetry-exporter-sender-okhttp.txt new file mode 100644 index 00000000000..df26146497b --- /dev/null +++ b/docs/apidiffs/1.34.1_vs_1.34.0/opentelemetry-exporter-sender-okhttp.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of against +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.34.1_vs_1.34.0/opentelemetry-exporter-zipkin.txt b/docs/apidiffs/1.34.1_vs_1.34.0/opentelemetry-exporter-zipkin.txt new file mode 100644 index 00000000000..df26146497b --- /dev/null +++ b/docs/apidiffs/1.34.1_vs_1.34.0/opentelemetry-exporter-zipkin.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of against +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.34.1_vs_1.34.0/opentelemetry-extension-kotlin.txt b/docs/apidiffs/1.34.1_vs_1.34.0/opentelemetry-extension-kotlin.txt new file mode 100644 index 00000000000..df26146497b --- /dev/null +++ b/docs/apidiffs/1.34.1_vs_1.34.0/opentelemetry-extension-kotlin.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of against +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.34.1_vs_1.34.0/opentelemetry-extension-trace-propagators.txt b/docs/apidiffs/1.34.1_vs_1.34.0/opentelemetry-extension-trace-propagators.txt new file mode 100644 index 00000000000..df26146497b --- /dev/null +++ b/docs/apidiffs/1.34.1_vs_1.34.0/opentelemetry-extension-trace-propagators.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of against +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.34.1_vs_1.34.0/opentelemetry-opentracing-shim.txt b/docs/apidiffs/1.34.1_vs_1.34.0/opentelemetry-opentracing-shim.txt new file mode 100644 index 00000000000..df26146497b --- /dev/null +++ b/docs/apidiffs/1.34.1_vs_1.34.0/opentelemetry-opentracing-shim.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of against +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.34.1_vs_1.34.0/opentelemetry-sdk-common.txt b/docs/apidiffs/1.34.1_vs_1.34.0/opentelemetry-sdk-common.txt new file mode 100644 index 00000000000..df26146497b --- /dev/null +++ b/docs/apidiffs/1.34.1_vs_1.34.0/opentelemetry-sdk-common.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of against +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.34.1_vs_1.34.0/opentelemetry-sdk-extension-autoconfigure-spi.txt b/docs/apidiffs/1.34.1_vs_1.34.0/opentelemetry-sdk-extension-autoconfigure-spi.txt new file mode 100644 index 00000000000..df26146497b --- /dev/null +++ b/docs/apidiffs/1.34.1_vs_1.34.0/opentelemetry-sdk-extension-autoconfigure-spi.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of against +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.34.1_vs_1.34.0/opentelemetry-sdk-extension-autoconfigure.txt b/docs/apidiffs/1.34.1_vs_1.34.0/opentelemetry-sdk-extension-autoconfigure.txt new file mode 100644 index 00000000000..df26146497b --- /dev/null +++ b/docs/apidiffs/1.34.1_vs_1.34.0/opentelemetry-sdk-extension-autoconfigure.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of against +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.34.1_vs_1.34.0/opentelemetry-sdk-extension-jaeger-remote-sampler.txt b/docs/apidiffs/1.34.1_vs_1.34.0/opentelemetry-sdk-extension-jaeger-remote-sampler.txt new file mode 100644 index 00000000000..df26146497b --- /dev/null +++ b/docs/apidiffs/1.34.1_vs_1.34.0/opentelemetry-sdk-extension-jaeger-remote-sampler.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of against +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.34.1_vs_1.34.0/opentelemetry-sdk-logs.txt b/docs/apidiffs/1.34.1_vs_1.34.0/opentelemetry-sdk-logs.txt new file mode 100644 index 00000000000..df26146497b --- /dev/null +++ b/docs/apidiffs/1.34.1_vs_1.34.0/opentelemetry-sdk-logs.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of against +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.34.1_vs_1.34.0/opentelemetry-sdk-metrics.txt b/docs/apidiffs/1.34.1_vs_1.34.0/opentelemetry-sdk-metrics.txt new file mode 100644 index 00000000000..df26146497b --- /dev/null +++ b/docs/apidiffs/1.34.1_vs_1.34.0/opentelemetry-sdk-metrics.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of against +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.34.1_vs_1.34.0/opentelemetry-sdk-testing.txt b/docs/apidiffs/1.34.1_vs_1.34.0/opentelemetry-sdk-testing.txt new file mode 100644 index 00000000000..df26146497b --- /dev/null +++ b/docs/apidiffs/1.34.1_vs_1.34.0/opentelemetry-sdk-testing.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of against +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.34.1_vs_1.34.0/opentelemetry-sdk-trace.txt b/docs/apidiffs/1.34.1_vs_1.34.0/opentelemetry-sdk-trace.txt new file mode 100644 index 00000000000..df26146497b --- /dev/null +++ b/docs/apidiffs/1.34.1_vs_1.34.0/opentelemetry-sdk-trace.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of against +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.34.1_vs_1.34.0/opentelemetry-sdk.txt b/docs/apidiffs/1.34.1_vs_1.34.0/opentelemetry-sdk.txt new file mode 100644 index 00000000000..df26146497b --- /dev/null +++ b/docs/apidiffs/1.34.1_vs_1.34.0/opentelemetry-sdk.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of against +No changes. \ No newline at end of file From 491de708e19dfe3b1957747e7d93de97fda520fe Mon Sep 17 00:00:00 2001 From: Crypt Keeper <64215+codefromthecrypt@users.noreply.github.com> Date: Tue, 16 Jan 2024 13:22:24 -0800 Subject: [PATCH 197/901] fixes link drift in sonatype (#6152) Signed-off-by: Adrian Cole --- RELEASING.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/RELEASING.md b/RELEASING.md index f0a2f7da67f..6c707cf43b3 100644 --- a/RELEASING.md +++ b/RELEASING.md @@ -83,8 +83,8 @@ The following credentials are required for publishing (and automatically set in * `SONATYPE_USER` and `SONATYPE_KEY`: Sonatype username and password. * Each maintainer will have their own set of Sonotype credentials with permission to publish to the `io.opentelemetry` group prefix. - * Request [publishing permissions](https://central.sonatype.org/publish/manage-permissions/) by - commenting on [OSSRH-63768](https://issues.sonatype.org/browse/OSSRH-63768) with confirmation + * [Register to publish](https://central.sonatype.org/register/central-portal/#and-publishing-is-easy) + and comment on [OSSRH-63768](https://issues.sonatype.org/browse/OSSRH-63768) with confirmation from another maintainer. * To obtain `SONATYPE_USER` and `SONATYPE_KEY` for your account, login to [oss.sonatype.org](https://oss.sonatype.org/) and navigate to Profile -> User Token -> Access From 6a79e6f32caf7a73e3456a623c3e7fb2bcc2f776 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 17 Jan 2024 15:47:17 -0600 Subject: [PATCH 198/901] Update slf4j monorepo to v2.0.11 (#6155) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- dependencyManagement/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index d4c4ca11de3..b6a238231ef 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -29,7 +29,7 @@ val errorProneVersion = "2.24.1" val jmhVersion = "1.37" // Mockito 5.x.x requires Java 11 https://github.com/mockito/mockito/releases/tag/v5.0.0 val mockitoVersion = "4.11.0" -val slf4jVersion = "2.0.10" +val slf4jVersion = "2.0.11" val opencensusVersion = "0.31.1" val prometheusClientVersion = "0.16.0" From 870a6bf25691fad134cd52d2fd84867a6535d765 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 17 Jan 2024 15:47:37 -0600 Subject: [PATCH 199/901] Update dependency org.owasp:dependency-check-gradle to v9.0.9 (#6126) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- buildSrc/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts index a3b5d22de27..1bc654268f3 100644 --- a/buildSrc/build.gradle.kts +++ b/buildSrc/build.gradle.kts @@ -58,7 +58,7 @@ dependencies { implementation("net.ltgt.gradle:gradle-errorprone-plugin:3.1.0") implementation("net.ltgt.gradle:gradle-nullaway-plugin:1.6.0") implementation("org.jetbrains.kotlin:kotlin-gradle-plugin:1.9.22") - implementation("org.owasp:dependency-check-gradle:9.0.7") + implementation("org.owasp:dependency-check-gradle:9.0.9") implementation("ru.vyarus:gradle-animalsniffer-plugin:1.7.1") } From 9faf11b605ac986742741f117a78913711224fe8 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 17 Jan 2024 15:47:58 -0600 Subject: [PATCH 200/901] Update dependency com.google.api.grpc:proto-google-common-protos to v2.30.0 (#6122) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- dependencyManagement/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index b6a238231ef..faa2b951552 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -55,7 +55,7 @@ val DEPENDENCIES = listOf( "io.prometheus:simpleclient_httpserver:${prometheusClientVersion}", "javax.annotation:javax.annotation-api:1.3.2", "com.github.stefanbirkner:system-rules:1.19.0", - "com.google.api.grpc:proto-google-common-protos:2.29.0", + "com.google.api.grpc:proto-google-common-protos:2.30.0", "com.google.code.findbugs:jsr305:3.0.2", "com.google.guava:guava-beta-checker:1.0", "com.sun.net.httpserver:http:20070405", From c5ca491dd6fe1807e548123506cc76e59d1d09fc Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 17 Jan 2024 15:52:47 -0600 Subject: [PATCH 201/901] Update dependency com.uber.nullaway:nullaway to v0.10.21 (#6150) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- dependencyManagement/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index faa2b951552..e4dc9d0f533 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -60,7 +60,7 @@ val DEPENDENCIES = listOf( "com.google.guava:guava-beta-checker:1.0", "com.sun.net.httpserver:http:20070405", "com.tngtech.archunit:archunit-junit5:1.2.1", - "com.uber.nullaway:nullaway:0.10.19", + "com.uber.nullaway:nullaway:0.10.21", "edu.berkeley.cs.jqf:jqf-fuzz:1.7", // jqf-fuzz version 1.8+ requires Java 11+ "eu.rekawek.toxiproxy:toxiproxy-java:2.1.7", "io.github.netmikey.logunit:logunit-jul:2.0.0", From f0d6c82337fb0979ecec7ced1bbee37745e97415 Mon Sep 17 00:00:00 2001 From: Crypt Keeper <64215+codefromthecrypt@users.noreply.github.com> Date: Wed, 17 Jan 2024 13:54:42 -0800 Subject: [PATCH 202/901] Update dependency io.zipkin.brave:brave-bom to 6.0.0 (#6131) Signed-off-by: Adrian Cole Co-authored-by: jack-berg <34418638+jack-berg@users.noreply.github.com> --- dependencyManagement/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index e4dc9d0f533..91f797d89a9 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -16,8 +16,8 @@ val DEPENDENCY_BOMS = listOf( "com.squareup.okio:okio-bom:3.7.0", // applies to transitive dependencies of okhttp "io.grpc:grpc-bom:1.60.1", "io.netty:netty-bom:4.1.104.Final", + "io.zipkin.brave:brave-bom:6.0.0", "io.zipkin.reporter2:zipkin-reporter-bom:3.1.1", - "io.zipkin.brave:brave-bom:5.17.0", "org.assertj:assertj-bom:3.25.1", "org.junit:junit-bom:5.10.1", "org.testcontainers:testcontainers-bom:1.19.3", From 496965e1b4d0a22a5148efcca41cbbb7f18051e5 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 17 Jan 2024 15:56:06 -0600 Subject: [PATCH 203/901] Update dependency com.google.protobuf:protobuf-bom to v3.25.2 (#6137) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- dependencyManagement/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index 91f797d89a9..f8183cb9208 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -10,7 +10,7 @@ rootProject.extra["versions"] = dependencyVersions val DEPENDENCY_BOMS = listOf( "com.fasterxml.jackson:jackson-bom:2.16.1", "com.google.guava:guava-bom:33.0.0-jre", - "com.google.protobuf:protobuf-bom:3.25.1", + "com.google.protobuf:protobuf-bom:3.25.2", "com.linecorp.armeria:armeria-bom:1.26.4", "com.squareup.okhttp3:okhttp-bom:4.12.0", "com.squareup.okio:okio-bom:3.7.0", // applies to transitive dependencies of okhttp From 2f69bec4288308cd2d0cff541faa2b9566db39ca Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 17 Jan 2024 16:14:18 -0600 Subject: [PATCH 204/901] Update spotless packages to v6.24.0 (#6162) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- buildSrc/build.gradle.kts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts index 1bc654268f3..58d58bf22fc 100644 --- a/buildSrc/build.gradle.kts +++ b/buildSrc/build.gradle.kts @@ -2,7 +2,7 @@ plugins { `kotlin-dsl` // When updating, update below in dependencies too - id("com.diffplug.spotless") version "6.23.3" + id("com.diffplug.spotless") version "6.24.0" } if (!JavaVersion.current().isCompatibleWith(JavaVersion.VERSION_17)) { @@ -45,7 +45,7 @@ dependencies { implementation(enforcedPlatform("com.squareup.wire:wire-bom:4.9.3")) implementation("com.google.auto.value:auto-value-annotations:1.10.4") // When updating, update above in plugins too - implementation("com.diffplug.spotless:spotless-plugin-gradle:6.23.3") + implementation("com.diffplug.spotless:spotless-plugin-gradle:6.24.0") // Needed for japicmp but not automatically brought in for some reason. implementation("com.google.guava:guava:33.0.0-jre") implementation("com.squareup:javapoet:1.13.0") From e337bd732ef32aed38bd13c587b3a28cece46287 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 17 Jan 2024 16:54:40 -0600 Subject: [PATCH 205/901] Update dependency nl.jqno.equalsverifier:equalsverifier to v3.15.6 (#6133) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- dependencyManagement/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index f8183cb9208..1582280f341 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -71,7 +71,7 @@ val DEPENDENCIES = listOf( "io.opentracing:opentracing-noop:0.33.0", "io.prometheus:prometheus-metrics-exporter-httpserver:1.1.0", "junit:junit:4.13.2", - "nl.jqno.equalsverifier:equalsverifier:3.15.5", + "nl.jqno.equalsverifier:equalsverifier:3.15.6", "org.awaitility:awaitility:4.2.0", "org.bouncycastle:bcpkix-jdk15on:1.70", "org.codehaus.mojo:animal-sniffer-annotations:1.23", From 4407ee72d626449dba7baecc86ef8c444322a0c6 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 17 Jan 2024 16:54:58 -0600 Subject: [PATCH 206/901] Update dependency io.netty:netty-bom to v4.1.105.Final (#6154) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- dependencyManagement/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index 1582280f341..9eaa4bdf229 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -15,7 +15,7 @@ val DEPENDENCY_BOMS = listOf( "com.squareup.okhttp3:okhttp-bom:4.12.0", "com.squareup.okio:okio-bom:3.7.0", // applies to transitive dependencies of okhttp "io.grpc:grpc-bom:1.60.1", - "io.netty:netty-bom:4.1.104.Final", + "io.netty:netty-bom:4.1.105.Final", "io.zipkin.brave:brave-bom:6.0.0", "io.zipkin.reporter2:zipkin-reporter-bom:3.1.1", "org.assertj:assertj-bom:3.25.1", From 16d6e0e00abf12d43e310bccac4aba402fc49c8a Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 18 Jan 2024 15:38:42 -0600 Subject: [PATCH 207/901] Update dependency io.grpc:grpc-bom to v1.61.0 (#6161) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- dependencyManagement/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index 9eaa4bdf229..708efcdd686 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -14,7 +14,7 @@ val DEPENDENCY_BOMS = listOf( "com.linecorp.armeria:armeria-bom:1.26.4", "com.squareup.okhttp3:okhttp-bom:4.12.0", "com.squareup.okio:okio-bom:3.7.0", // applies to transitive dependencies of okhttp - "io.grpc:grpc-bom:1.60.1", + "io.grpc:grpc-bom:1.61.0", "io.netty:netty-bom:4.1.105.Final", "io.zipkin.brave:brave-bom:6.0.0", "io.zipkin.reporter2:zipkin-reporter-bom:3.1.1", From ede6a81a17298938ac8d7b4d836c17a7f4dec268 Mon Sep 17 00:00:00 2001 From: jack-berg <34418638+jack-berg@users.noreply.github.com> Date: Thu, 18 Jan 2024 16:06:08 -0600 Subject: [PATCH 208/901] Stop including old artifacts in bom (#6157) --- VERSIONING.md | 3 +- all/build.gradle.kts | 13 ---- .../all/FallbackArtifactsTest.java | 68 ------------------- bom/build.gradle.kts | 9 --- .../opentelemetry/gradle/OtelBomExtension.kt | 9 --- .../kotlin/otel.bom-conventions.gradle.kts | 7 -- 6 files changed, 1 insertion(+), 108 deletions(-) delete mode 100644 all/src/test/java/io/opentelemetry/all/FallbackArtifactsTest.java diff --git a/VERSIONING.md b/VERSIONING.md index d0bf9a79148..ad599963e02 100644 --- a/VERSIONING.md +++ b/VERSIONING.md @@ -53,8 +53,7 @@ new artifact which requires adding the new artifact to dependency declarations. On rare occasions we may deprecate an entire stable artifact, with the intent of stopping functional changes or enhancements. In these situations we may stop publishing additional `MINOR` or `MAJOR` versions of the artifact. However, if necessary, we'll publish security fixes via `PATCH` releases. -Despite stopping publishing, new versions of the BOM will continue to reference the last published -version of the artifact, and the API of the last published version will remain stable. +The API of the last published version will remain stable. As a user, if you always depend on the latest version of the BOM for a given `MAJOR` version, and you do not use classes in the `internal` package (which you MUST NOT do), you can be assured that diff --git a/all/build.gradle.kts b/all/build.gradle.kts index 874c93ae1c6..2cd16981fbb 100644 --- a/all/build.gradle.kts +++ b/all/build.gradle.kts @@ -45,19 +45,6 @@ dependencies { } } - // For testing BOM references to artifacts that were previously published - testImplementation(platform(project(":bom"))) - // The io.grpc.grpc-* dependencies are transitive dependencies of opentelemetry-exporter-jaeger-proto - // which must be provided by the user - testImplementation("io.opentelemetry:opentelemetry-exporter-jaeger-proto") - testImplementation("io.grpc:grpc-api") - testImplementation("io.grpc:grpc-protobuf") - testImplementation("io.grpc:grpc-stub") - testImplementation("io.opentelemetry:opentelemetry-extension-annotations") - testImplementation("io.opentelemetry:opentelemetry-extension-aws") - testImplementation("io.opentelemetry:opentelemetry-sdk-extension-resources") - testImplementation("io.opentelemetry:opentelemetry-sdk-extension-aws") - testImplementation("com.tngtech.archunit:archunit-junit5") } diff --git a/all/src/test/java/io/opentelemetry/all/FallbackArtifactsTest.java b/all/src/test/java/io/opentelemetry/all/FallbackArtifactsTest.java deleted file mode 100644 index eebe961e292..00000000000 --- a/all/src/test/java/io/opentelemetry/all/FallbackArtifactsTest.java +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package io.opentelemetry.all; - -import org.assertj.core.api.Assertions; -import org.junit.jupiter.api.Test; - -/** - * This test asserts that artifacts which are no longer published continue to be referenced in - * {@code opentelemetry-bom}. - */ -class FallbackArtifactsTest { - - @Test - void exporterJaegerProto() { - classAvailable("io.opentelemetry.exporter.jaeger.proto.api_v2.Collector"); - classAvailable("io.opentelemetry.exporter.jaeger.proto.api_v2.CollectorServiceGrpc"); - classAvailable("io.opentelemetry.exporter.jaeger.proto.api_v2.Model"); - } - - @Test - void extensionAnnotations() { - classAvailable("io.opentelemetry.extension.annotations.WithSpan"); - classAvailable("io.opentelemetry.extension.annotations.SpanAttribute"); - } - - @Test - void sdkExtensionResources() { - classAvailable("io.opentelemetry.sdk.extension.resources.ContainerResource"); - classAvailable("io.opentelemetry.sdk.extension.resources.ContainerResourceProvider"); - classAvailable("io.opentelemetry.sdk.extension.resources.HostResource"); - classAvailable("io.opentelemetry.sdk.extension.resources.HostResourceProvider"); - classAvailable("io.opentelemetry.sdk.extension.resources.OsResource"); - classAvailable("io.opentelemetry.sdk.extension.resources.OsResourceProvider"); - classAvailable("io.opentelemetry.sdk.extension.resources.ProcessResource"); - classAvailable("io.opentelemetry.sdk.extension.resources.ProcessResourceProvider"); - classAvailable("io.opentelemetry.sdk.extension.resources.ProcessRuntimeResource"); - classAvailable("io.opentelemetry.sdk.extension.resources.ProcessRuntimeResourceProvider"); - } - - @Test - void sdkExtensionAws() { - classAvailable("io.opentelemetry.sdk.extension.aws.resource.BeanstalkResource"); - classAvailable("io.opentelemetry.sdk.extension.aws.resource.BeanstalkResourceProvider"); - classAvailable("io.opentelemetry.sdk.extension.aws.resource.Ec2Resource"); - classAvailable("io.opentelemetry.sdk.extension.aws.resource.Ec2ResourceProvider"); - classAvailable("io.opentelemetry.sdk.extension.aws.resource.EcsResource"); - classAvailable("io.opentelemetry.sdk.extension.aws.resource.EcsResourceProvider"); - classAvailable("io.opentelemetry.sdk.extension.aws.resource.EksResource"); - classAvailable("io.opentelemetry.sdk.extension.aws.resource.EksResourceProvider"); - classAvailable("io.opentelemetry.sdk.extension.aws.resource.LambdaResource"); - classAvailable("io.opentelemetry.sdk.extension.aws.resource.LambdaResourceProvider"); - classAvailable("io.opentelemetry.sdk.extension.aws.trace.AwsXrayIdGenerator"); - } - - @Test - void extensionAws() { - classAvailable("io.opentelemetry.extension.aws.AwsConfigurablePropagator"); - classAvailable("io.opentelemetry.extension.aws.AwsXrayPropagator"); - } - - private static void classAvailable(String fqcn) { - Assertions.assertThatCode(() -> Class.forName(fqcn)).doesNotThrowAnyException(); - } -} diff --git a/bom/build.gradle.kts b/bom/build.gradle.kts index 3b977ff1263..50d8dc950a1 100644 --- a/bom/build.gradle.kts +++ b/bom/build.gradle.kts @@ -7,12 +7,3 @@ group = "io.opentelemetry" base.archivesName.set("opentelemetry-bom") otelBom.projectFilter.set { !it.hasProperty("otel.release") } - -// Artifacts that were previously published and included in the BOM for backwards compatibility -otelBom.addFallback("opentelemetry-exporter-jaeger-proto", "1.17.0") -otelBom.addFallback("opentelemetry-extension-annotations", "1.18.0") -otelBom.addFallback("opentelemetry-sdk-extension-resources", "1.19.0") -otelBom.addFallback("opentelemetry-sdk-extension-aws", "1.19.0") -otelBom.addFallback("opentelemetry-extension-aws", "1.20.1") -// NOTE: opentelemetry-exporter-jaeger and opentelemetry-exporter-jaeger-thift are omitted because -// they contain dependencies on internal classes, which may have breaking API changes preventing compilation. diff --git a/buildSrc/src/main/kotlin/io/opentelemetry/gradle/OtelBomExtension.kt b/buildSrc/src/main/kotlin/io/opentelemetry/gradle/OtelBomExtension.kt index a3ba9e47f3a..5857b99808b 100644 --- a/buildSrc/src/main/kotlin/io/opentelemetry/gradle/OtelBomExtension.kt +++ b/buildSrc/src/main/kotlin/io/opentelemetry/gradle/OtelBomExtension.kt @@ -11,13 +11,4 @@ import java.util.function.Predicate abstract class OtelBomExtension { abstract val projectFilter: Property> - val additionalDependencies: MutableSet = hashSetOf() - - fun addFallback(artifactId: String, version: String) { - this.additionalDependencies.add("io.opentelemetry:" + artifactId + ":" + version) - } - - fun addExtra(groupId: String, artifactId: String, version: String) { - this.additionalDependencies.add(groupId + ":" + artifactId + ":" + version) - } } diff --git a/buildSrc/src/main/kotlin/otel.bom-conventions.gradle.kts b/buildSrc/src/main/kotlin/otel.bom-conventions.gradle.kts index c9e7973b7f2..43674ccc6e5 100644 --- a/buildSrc/src/main/kotlin/otel.bom-conventions.gradle.kts +++ b/buildSrc/src/main/kotlin/otel.bom-conventions.gradle.kts @@ -61,11 +61,4 @@ afterEvaluate { } } } - otelBom.additionalDependencies.forEach { dependency -> - dependencies { - constraints { - api(dependency) - } - } - } } From e4b31cea3de13db7262540457e598282f56d9978 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 19 Jan 2024 11:00:10 -0600 Subject: [PATCH 209/901] Update dependency io.netty:netty-bom to v4.1.106.Final (#6166) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- dependencyManagement/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index 708efcdd686..2a3f624b116 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -15,7 +15,7 @@ val DEPENDENCY_BOMS = listOf( "com.squareup.okhttp3:okhttp-bom:4.12.0", "com.squareup.okio:okio-bom:3.7.0", // applies to transitive dependencies of okhttp "io.grpc:grpc-bom:1.61.0", - "io.netty:netty-bom:4.1.105.Final", + "io.netty:netty-bom:4.1.106.Final", "io.zipkin.brave:brave-bom:6.0.0", "io.zipkin.reporter2:zipkin-reporter-bom:3.1.1", "org.assertj:assertj-bom:3.25.1", From ee6c9867d736af7359003e0b2f61ebf082e6fe3e Mon Sep 17 00:00:00 2001 From: jack-berg <34418638+jack-berg@users.noreply.github.com> Date: Tue, 23 Jan 2024 16:57:45 -0600 Subject: [PATCH 210/901] Align file configuration with latest changes to spec (#6088) --- ...AutoConfiguredOpenTelemetrySdkBuilder.java | 7 +- sdk-extensions/incubator/README.md | 20 +++++ .../fileconfig/ConfigurationFactory.java | 73 ---------------- ...tionReader.java => FileConfiguration.java} | 83 +++++++++++++++++-- ....java => FileConfigurationCreateTest.java} | 26 ++---- ...t.java => FileConfigurationParseTest.java} | 61 ++++++++------ .../fileconfig/MetricReaderFactoryTest.java | 2 +- 7 files changed, 143 insertions(+), 129 deletions(-) delete mode 100644 sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/ConfigurationFactory.java rename sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/{ConfigurationReader.java => FileConfiguration.java} (59%) rename sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/{ConfigurationFactoryTest.java => FileConfigurationCreateTest.java} (84%) rename sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/{ConfigurationReaderTest.java => FileConfigurationParseTest.java} (91%) diff --git a/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/AutoConfiguredOpenTelemetrySdkBuilder.java b/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/AutoConfiguredOpenTelemetrySdkBuilder.java index 05935556aba..8e332c2a2b7 100644 --- a/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/AutoConfiguredOpenTelemetrySdkBuilder.java +++ b/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/AutoConfiguredOpenTelemetrySdkBuilder.java @@ -492,10 +492,9 @@ private static AutoConfiguredOpenTelemetrySdk maybeConfigureFromFile(ConfigPrope } try { Class configurationFactory = - Class.forName("io.opentelemetry.sdk.extension.incubator.fileconfig.ConfigurationFactory"); - Method parseAndInterpret = - configurationFactory.getMethod("parseAndInterpret", InputStream.class); - OpenTelemetrySdk sdk = (OpenTelemetrySdk) parseAndInterpret.invoke(null, fis); + Class.forName("io.opentelemetry.sdk.extension.incubator.fileconfig.FileConfiguration"); + Method parseAndCreate = configurationFactory.getMethod("parseAndCreate", InputStream.class); + OpenTelemetrySdk sdk = (OpenTelemetrySdk) parseAndCreate.invoke(null, fis); // Note: can't access file configuration resource without reflection so setting a dummy // resource return AutoConfiguredOpenTelemetrySdk.create(sdk, Resource.getDefault(), config); diff --git a/sdk-extensions/incubator/README.md b/sdk-extensions/incubator/README.md index 64cc8a7d932..8301d01f3f5 100644 --- a/sdk-extensions/incubator/README.md +++ b/sdk-extensions/incubator/README.md @@ -2,6 +2,26 @@ This artifact contains experimental code related to the trace and metric SDKs. +## File Configuration + +Allows for YAML based file configuration of `OpenTelemetrySdk` as defined in the [specification](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/configuration/file-configuration.md). + +Usage: + +```shell +File yamlConfigFile = new File("/path/to/config.yaml"); +OpenTelemetrySdk openTelemetrySdk; +try (FileInputStream yamlConfigFileInputStream = new FileInputStream("/path/to/config.yaml")) { + openTelemetrySdk = FileConfiguration.parseAndCreate(yamlConfigFileInputStream); +} +// ...proceed with application after successful initialization of OpenTelemetrySdk +``` + +Notes: +* Environment variable substitution is supported as [defined in the spec](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/configuration/file-configuration.md#environment-variable-substitution) +* Currently, there is no support for the SPIs defined in [opentelemetry-sdk-extension-autoconfigure-spi](../autoconfigure-spi). Only built in samplers, processors, exporters, etc can be configured. +* You can use file configuration with [autoconfigure](https://github.com/open-telemetry/opentelemetry-java/tree/main/sdk-extensions/autoconfigure#file-configuration) to specify a configuration file via environment variable, e.g. `OTEL_CONFIG_FILE=/path/to/config.yaml`. + ## View File Configuration Adds support for file based YAML configuration of Metric SDK Views. diff --git a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/ConfigurationFactory.java b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/ConfigurationFactory.java deleted file mode 100644 index 9c51f00af9a..00000000000 --- a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/ConfigurationFactory.java +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package io.opentelemetry.sdk.extension.incubator.fileconfig; - -import io.opentelemetry.sdk.OpenTelemetrySdk; -import io.opentelemetry.sdk.autoconfigure.internal.SpiHelper; -import io.opentelemetry.sdk.autoconfigure.spi.ConfigurationException; -import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.OpenTelemetryConfiguration; -import java.io.Closeable; -import java.io.IOException; -import java.io.InputStream; -import java.util.ArrayList; -import java.util.List; -import java.util.logging.Logger; - -/** - * Parses YAML configuration files conforming to the schema in open-telemetry/opentelemetry-configuration - * to a {@link OpenTelemetryConfiguration} in-memory representation. Interprets the in-memory - * representation to produce an {@link OpenTelemetrySdk}. - * - * @see #parseAndInterpret(InputStream) - */ -public final class ConfigurationFactory { - - private static final Logger logger = Logger.getLogger(ConfigurationFactory.class.getName()); - - private ConfigurationFactory() {} - - /** - * Parse the {@code inputStream} YAML to {@link OpenTelemetryConfiguration} and interpret the - * model to create {@link OpenTelemetrySdk} instance corresponding to the configuration. - * - *

    Before parsing, environment variable substitution is performed as described in {@link - * ConfigurationReader.EnvSubstitutionConstructor}. - * - * @param inputStream the configuration YAML - * @return the {@link OpenTelemetrySdk} - */ - public static OpenTelemetrySdk parseAndInterpret(InputStream inputStream) { - OpenTelemetryConfiguration model; - try { - model = ConfigurationReader.parse(inputStream); - } catch (RuntimeException e) { - throw new ConfigurationException("Unable to parse inputStream", e); - } - - List closeables = new ArrayList<>(); - try { - return OpenTelemetryConfigurationFactory.getInstance() - .create(model, SpiHelper.create(ConfigurationFactory.class.getClassLoader()), closeables); - } catch (RuntimeException e) { - logger.info( - "Error encountered interpreting configuration. Closing partially configured components."); - for (Closeable closeable : closeables) { - try { - logger.fine("Closing " + closeable.getClass().getName()); - closeable.close(); - } catch (IOException ex) { - logger.warning( - "Error closing " + closeable.getClass().getName() + ": " + ex.getMessage()); - } - } - if (e instanceof ConfigurationException) { - throw e; - } - throw new ConfigurationException("Unexpected configuration error", e); - } - } -} diff --git a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/ConfigurationReader.java b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/FileConfiguration.java similarity index 59% rename from sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/ConfigurationReader.java rename to sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/FileConfiguration.java index 731bfee1770..061185c630d 100644 --- a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/ConfigurationReader.java +++ b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/FileConfiguration.java @@ -8,9 +8,17 @@ import com.fasterxml.jackson.annotation.JsonSetter; import com.fasterxml.jackson.annotation.Nulls; import com.fasterxml.jackson.databind.ObjectMapper; +import io.opentelemetry.sdk.OpenTelemetrySdk; +import io.opentelemetry.sdk.autoconfigure.internal.SpiHelper; +import io.opentelemetry.sdk.autoconfigure.spi.ConfigurationException; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.OpenTelemetryConfiguration; +import java.io.Closeable; +import java.io.IOException; import java.io.InputStream; +import java.util.ArrayList; +import java.util.List; import java.util.Map; +import java.util.logging.Logger; import java.util.regex.MatchResult; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -20,10 +28,17 @@ import org.snakeyaml.engine.v2.nodes.MappingNode; import org.yaml.snakeyaml.Yaml; -final class ConfigurationReader { +/** + * Configure {@link OpenTelemetrySdk} from YAML configuration files conforming to the schema in open-telemetry/opentelemetry-configuration. + * + * @see #parseAndCreate(InputStream) + */ +public final class FileConfiguration { + private static final Logger logger = Logger.getLogger(FileConfiguration.class.getName()); private static final Pattern ENV_VARIABLE_REFERENCE = - Pattern.compile("\\$\\{env:([a-zA-Z_]+[a-zA-Z0-9_]*)}"); + Pattern.compile("\\$\\{([a-zA-Z_][a-zA-Z0-9_]*)}"); private static final ObjectMapper MAPPER; @@ -40,16 +55,67 @@ final class ConfigurationReader { MAPPER.configOverride(Boolean.class).setSetterInfo(JsonSetter.Value.forValueNulls(Nulls.SET)); } - private ConfigurationReader() {} + private FileConfiguration() {} + + /** + * Combines {@link #parse(InputStream)} and {@link #create(OpenTelemetryConfiguration)}. + * + * @throws ConfigurationException if unable to parse or interpret + */ + public static OpenTelemetrySdk parseAndCreate(InputStream inputStream) { + OpenTelemetryConfiguration configurationModel = parse(inputStream); + return create(configurationModel); + } + + /** + * Interpret the {@code configurationModel} to create {@link OpenTelemetrySdk} instance + * corresponding to the configuration. + * + * @param configurationModel the configuration model + * @return the {@link OpenTelemetrySdk} + * @throws ConfigurationException if unable to interpret + */ + public static OpenTelemetrySdk create(OpenTelemetryConfiguration configurationModel) { + List closeables = new ArrayList<>(); + try { + return OpenTelemetryConfigurationFactory.getInstance() + .create( + configurationModel, + SpiHelper.create(FileConfiguration.class.getClassLoader()), + closeables); + } catch (RuntimeException e) { + logger.info( + "Error encountered interpreting configuration model. Closing partially configured components."); + for (Closeable closeable : closeables) { + try { + logger.fine("Closing " + closeable.getClass().getName()); + closeable.close(); + } catch (IOException ex) { + logger.warning( + "Error closing " + closeable.getClass().getName() + ": " + ex.getMessage()); + } + } + if (e instanceof ConfigurationException) { + throw e; + } + throw new ConfigurationException("Unexpected configuration error", e); + } + } /** * Parse the {@code configuration} YAML and return the {@link OpenTelemetryConfiguration}. * *

    Before parsing, environment variable substitution is performed as described in {@link * EnvSubstitutionConstructor}. + * + * @throws ConfigurationException if unable to parse */ - static OpenTelemetryConfiguration parse(InputStream configuration) { - return parse(configuration, System.getenv()); + public static OpenTelemetryConfiguration parse(InputStream configuration) { + try { + return parse(configuration, System.getenv()); + } catch (RuntimeException e) { + throw new ConfigurationException("Unable to parse configuration input stream", e); + } } // Visible for testing @@ -59,6 +125,7 @@ static OpenTelemetryConfiguration parse( return MAPPER.convertValue(yamlObj, OpenTelemetryConfiguration.class); } + // Visible for testing static Object loadYaml(InputStream inputStream, Map environmentVariables) { LoadSettings settings = LoadSettings.builder().build(); Load yaml = new Load(settings, new EnvSubstitutionConstructor(settings, environmentVariables)); @@ -68,15 +135,15 @@ static Object loadYaml(InputStream inputStream, Map environmentV /** * {@link StandardConstructor} which substitutes environment variables. * - *

    Environment variables follow the syntax {@code ${env:VARIABLE}}, where {@code VARIABLE} is - * an environment variable matching the regular expression {@code [a-zA-Z_]+[a-zA-Z0-9_]*}. + *

    Environment variables follow the syntax {@code ${VARIABLE}}, where {@code VARIABLE} is an + * environment variable matching the regular expression {@code [a-zA-Z_]+[a-zA-Z0-9_]*}. * *

    Environment variable substitution only takes place on scalar values of maps. References to * environment variables in keys or sets are ignored. * *

    If a referenced environment variable is not defined, it is replaced with {@code ""}. */ - static final class EnvSubstitutionConstructor extends StandardConstructor { + private static final class EnvSubstitutionConstructor extends StandardConstructor { // Yaml is not thread safe but this instance is always used on the same thread private final Yaml yaml = new Yaml(); diff --git a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/ConfigurationFactoryTest.java b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/FileConfigurationCreateTest.java similarity index 84% rename from sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/ConfigurationFactoryTest.java rename to sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/FileConfigurationCreateTest.java index 2054e967987..7699752b109 100644 --- a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/ConfigurationFactoryTest.java +++ b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/FileConfigurationCreateTest.java @@ -28,7 +28,7 @@ import org.junit.jupiter.api.io.TempDir; import org.slf4j.event.Level; -class ConfigurationFactoryTest { +class FileConfigurationCreateTest { @RegisterExtension static final SelfSignedCertificateExtension serverTls = new SelfSignedCertificateExtension(); @@ -40,25 +40,15 @@ class ConfigurationFactoryTest { @RegisterExtension LogCapturer logCapturer = - LogCapturer.create().captureForLogger(ConfigurationFactory.class.getName(), Level.TRACE); - - @Test - void parseAndInterpret_BadInputStream() { - assertThatThrownBy( - () -> - ConfigurationFactory.parseAndInterpret( - new ByteArrayInputStream("foo".getBytes(StandardCharsets.UTF_8)))) - .isInstanceOf(ConfigurationException.class) - .hasMessage("Unable to parse inputStream"); - } + LogCapturer.create().captureForLogger(FileConfiguration.class.getName(), Level.TRACE); /** * Verify each example in open-telemetry/opentelemetry-configuration/examples - * can pass {@link ConfigurationFactory#parseAndInterpret(InputStream)}. + * can pass {@link FileConfiguration#parseAndCreate(InputStream)}. */ @Test - void parseAndInterpret_Examples(@TempDir Path tempDir) + void parseAndCreate_Examples(@TempDir Path tempDir) throws IOException, CertificateEncodingException { // Write certificates to temp files String certificatePath = @@ -101,14 +91,14 @@ void parseAndInterpret_Examples(@TempDir Path tempDir) new ByteArrayInputStream(rewrittenExampleContent.getBytes(StandardCharsets.UTF_8)); // Verify that file can be parsed and interpreted without error - assertThatCode(() -> cleanup.addCloseable(ConfigurationFactory.parseAndInterpret(is))) + assertThatCode(() -> cleanup.addCloseable(FileConfiguration.parseAndCreate(is))) .as("Example file: " + example.getName()) .doesNotThrowAnyException(); } } @Test - void parseAndInterpret_Exception_CleansUpPartials() { + void parseAndCreate_Exception_CleansUpPartials() { // Trigger an exception after some components have been configured by adding a valid batch // exporter with OTLP exporter, following by invalid batch exporter which references invalid // exporter "foo". @@ -125,12 +115,12 @@ void parseAndInterpret_Exception_CleansUpPartials() { assertThatThrownBy( () -> - ConfigurationFactory.parseAndInterpret( + FileConfiguration.parseAndCreate( new ByteArrayInputStream(yaml.getBytes(StandardCharsets.UTF_8)))) .isInstanceOf(ConfigurationException.class) .hasMessage("Unrecognized log record exporter(s): [foo]"); logCapturer.assertContains( - "Error encountered interpreting configuration. Closing partially configured components."); + "Error encountered interpreting configuration model. Closing partially configured components."); logCapturer.assertContains( "Closing io.opentelemetry.exporter.otlp.logs.OtlpGrpcLogRecordExporter"); logCapturer.assertContains("Closing io.opentelemetry.sdk.logs.export.BatchLogRecordProcessor"); diff --git a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/ConfigurationReaderTest.java b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/FileConfigurationParseTest.java similarity index 91% rename from sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/ConfigurationReaderTest.java rename to sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/FileConfigurationParseTest.java index 3a1e81c4073..8b0674109b8 100644 --- a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/ConfigurationReaderTest.java +++ b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/FileConfigurationParseTest.java @@ -6,7 +6,9 @@ package io.opentelemetry.sdk.extension.incubator.fileconfig; import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; +import io.opentelemetry.sdk.autoconfigure.spi.ConfigurationException; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.Aggregation; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.AlwaysOff; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.AlwaysOn; @@ -60,7 +62,17 @@ import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.MethodSource; -class ConfigurationReaderTest { +class FileConfigurationParseTest { + + @Test + void parse_BadInputStream() { + assertThatThrownBy( + () -> + FileConfiguration.parseAndCreate( + new ByteArrayInputStream("foo".getBytes(StandardCharsets.UTF_8)))) + .isInstanceOf(ConfigurationException.class) + .hasMessage("Unable to parse configuration input stream"); + } @Test void parse_KitchenSinkExampleFile() throws IOException { @@ -257,7 +269,7 @@ void parse_KitchenSinkExampleFile() throws IOException { try (FileInputStream configExampleFile = new FileInputStream(System.getenv("CONFIG_EXAMPLE_DIR") + "/kitchen-sink.yaml")) { - OpenTelemetryConfiguration config = ConfigurationReader.parse(configExampleFile); + OpenTelemetryConfiguration config = FileConfiguration.parse(configExampleFile); // General config assertThat(config.getFileFormat()).isEqualTo("0.1"); @@ -306,7 +318,7 @@ void parse_nullValuesParsedToEmptyObjects() { + " aggregation:\n" + " drop: {}\n"; OpenTelemetryConfiguration objectPlaceholderModel = - ConfigurationReader.parse( + FileConfiguration.parse( new ByteArrayInputStream(objectPlaceholderString.getBytes(StandardCharsets.UTF_8))); String noOjbectPlaceholderString = @@ -324,7 +336,7 @@ void parse_nullValuesParsedToEmptyObjects() { + " aggregation:\n" + " drop:\n"; OpenTelemetryConfiguration noObjectPlaceholderModel = - ConfigurationReader.parse( + FileConfiguration.parse( new ByteArrayInputStream(noOjbectPlaceholderString.getBytes(StandardCharsets.UTF_8))); SpanExporter exporter = @@ -358,7 +370,7 @@ void parse_nullBoxedPrimitivesParsedToNull() { + " ratio:\n"; // Double OpenTelemetryConfiguration model = - ConfigurationReader.parse(new ByteArrayInputStream(yaml.getBytes(StandardCharsets.UTF_8))); + FileConfiguration.parse(new ByteArrayInputStream(yaml.getBytes(StandardCharsets.UTF_8))); assertThat(model.getFileFormat()).isNull(); assertThat(model.getDisabled()).isNull(); @@ -386,7 +398,7 @@ void envSubstituteAndLoadYaml(String rawYaml, Object expectedYamlResult) { environmentVariables.put("FLOAT", "1.1"); Object yaml = - ConfigurationReader.loadYaml( + FileConfiguration.loadYaml( new ByteArrayInputStream(rawYaml.getBytes(StandardCharsets.UTF_8)), environmentVariables); assertThat(yaml).isEqualTo(expectedYamlResult); @@ -396,32 +408,31 @@ void envSubstituteAndLoadYaml(String rawYaml, Object expectedYamlResult) { private static java.util.stream.Stream envVarSubstitutionArgs() { return java.util.stream.Stream.of( // Simple cases - Arguments.of("key1: ${env:STR_1}\n", mapOf(entry("key1", "value1"))), - Arguments.of("key1: ${env:BOOL}\n", mapOf(entry("key1", true))), - Arguments.of("key1: ${env:INT}\n", mapOf(entry("key1", 1))), - Arguments.of("key1: ${env:FLOAT}\n", mapOf(entry("key1", 1.1))), + Arguments.of("key1: ${STR_1}\n", mapOf(entry("key1", "value1"))), + Arguments.of("key1: ${BOOL}\n", mapOf(entry("key1", true))), + Arguments.of("key1: ${INT}\n", mapOf(entry("key1", 1))), + Arguments.of("key1: ${FLOAT}\n", mapOf(entry("key1", 1.1))), Arguments.of( - "key1: ${env:STR_1}\n" + "key2: value2\n", + "key1: ${STR_1}\n" + "key2: value2\n", mapOf(entry("key1", "value1"), entry("key2", "value2"))), Arguments.of( - "key1: ${env:STR_1} value1\n" + "key2: value2\n", + "key1: ${STR_1} value1\n" + "key2: value2\n", mapOf(entry("key1", "value1 value1"), entry("key2", "value2"))), // Multiple environment variables referenced - Arguments.of("key1: ${env:STR_1}${env:STR_2}\n", mapOf(entry("key1", "value1value2"))), - Arguments.of("key1: ${env:STR_1} ${env:STR_2}\n", mapOf(entry("key1", "value1 value2"))), + Arguments.of("key1: ${STR_1}${STR_2}\n", mapOf(entry("key1", "value1value2"))), + Arguments.of("key1: ${STR_1} ${STR_2}\n", mapOf(entry("key1", "value1 value2"))), // Undefined environment variable - Arguments.of("key1: ${env:STR_3}\n", mapOf(entry("key1", null))), - Arguments.of("key1: ${env:STR_1} ${env:STR_3}\n", mapOf(entry("key1", "value1"))), + Arguments.of("key1: ${STR_3}\n", mapOf(entry("key1", null))), + Arguments.of("key1: ${STR_1} ${STR_3}\n", mapOf(entry("key1", "value1"))), // Environment variable keys must match pattern: [a-zA-Z_]+[a-zA-Z0-9_]* - Arguments.of("key1: ${env:VAR&}\n", mapOf(entry("key1", "${env:VAR&}"))), + Arguments.of("key1: ${VAR&}\n", mapOf(entry("key1", "${VAR&}"))), // Environment variable substitution only takes place in scalar values of maps - Arguments.of("${env:STR_1}: value1\n", mapOf(entry("${env:STR_1}", "value1"))), + Arguments.of("${STR_1}: value1\n", mapOf(entry("${STR_1}", "value1"))), Arguments.of( - "key1:\n ${env:STR_1}: value1\n", - mapOf(entry("key1", mapOf(entry("${env:STR_1}", "value1"))))), + "key1:\n ${STR_1}: value1\n", + mapOf(entry("key1", mapOf(entry("${STR_1}", "value1"))))), Arguments.of( - "key1:\n - ${env:STR_1}\n", - mapOf(entry("key1", Collections.singletonList("${env:STR_1}"))))); + "key1:\n - ${STR_1}\n", mapOf(entry("key1", Collections.singletonList("${STR_1}"))))); } private static Map.Entry entry(K key, @Nullable V value) { @@ -446,15 +457,15 @@ void read_WithEnvironmentVariables() { + " - batch:\n" + " exporter:\n" + " otlp:\n" - + " endpoint: ${env:OTEL_EXPORTER_OTLP_ENDPOINT}\n" + + " endpoint: ${OTEL_EXPORTER_OTLP_ENDPOINT}\n" + " - batch:\n" + " exporter:\n" + " otlp:\n" - + " endpoint: \"${env:UNSET_ENV_VAR}\"\n"; + + " endpoint: \"${UNSET_ENV_VAR}\"\n"; Map envVars = new HashMap<>(); envVars.put("OTEL_EXPORTER_OTLP_ENDPOINT", "http://collector:4317"); OpenTelemetryConfiguration model = - ConfigurationReader.parse( + FileConfiguration.parse( new ByteArrayInputStream(yaml.getBytes(StandardCharsets.UTF_8)), envVars); assertThat(model) .isEqualTo( diff --git a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/MetricReaderFactoryTest.java b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/MetricReaderFactoryTest.java index ae1dfceedb4..64da70549a1 100644 --- a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/MetricReaderFactoryTest.java +++ b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/MetricReaderFactoryTest.java @@ -44,7 +44,7 @@ class MetricReaderFactoryTest { @RegisterExtension LogCapturer logCapturer = - LogCapturer.create().captureForLogger(ConfigurationFactory.class.getName()); + LogCapturer.create().captureForLogger(FileConfiguration.class.getName()); private SpiHelper spiHelper = SpiHelper.create(MetricReaderFactoryTest.class.getClassLoader()); From 0e4986a0736b799038c80a5c856fc320fa028001 Mon Sep 17 00:00:00 2001 From: Crypt Keeper <64215+codefromthecrypt@users.noreply.github.com> Date: Thu, 25 Jan 2024 06:52:57 +0800 Subject: [PATCH 211/901] Update dependency io.zipkin.reporter2:zipkin-reporter-bom to v3.2.1 (#6151) Signed-off-by: Adrian Cole Co-authored-by: jack-berg <34418638+jack-berg@users.noreply.github.com> --- dependencyManagement/build.gradle.kts | 2 +- .../opentelemetry-exporter-zipkin.txt | 3 ++ .../exporter/zipkin/ZipkinSpanExporter.java | 35 ++++++------------ .../zipkin/ZipkinSpanExporterBuilder.java | 33 ++++++++++++----- .../ZipkinSpanExporterEndToEndHttpTest.java | 5 ++- .../zipkin/ZipkinSpanExporterTest.java | 37 +++++-------------- 6 files changed, 54 insertions(+), 61 deletions(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index 2a3f624b116..f85dbbb5681 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -17,7 +17,7 @@ val DEPENDENCY_BOMS = listOf( "io.grpc:grpc-bom:1.61.0", "io.netty:netty-bom:4.1.106.Final", "io.zipkin.brave:brave-bom:6.0.0", - "io.zipkin.reporter2:zipkin-reporter-bom:3.1.1", + "io.zipkin.reporter2:zipkin-reporter-bom:3.2.1", "org.assertj:assertj-bom:3.25.1", "org.junit:junit-bom:5.10.1", "org.testcontainers:testcontainers-bom:1.19.3", diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-zipkin.txt b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-zipkin.txt index 73d401a04b9..b941adbcdd2 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-zipkin.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-zipkin.txt @@ -4,3 +4,6 @@ Comparing source compatibility of against === UNCHANGED METHOD: PUBLIC io.opentelemetry.exporter.zipkin.ZipkinSpanExporterBuilder setEncoder(zipkin2.codec.BytesEncoder) +++ NEW ANNOTATION: java.lang.Deprecated +++ NEW METHOD: PUBLIC(+) io.opentelemetry.exporter.zipkin.ZipkinSpanExporterBuilder setEncoder(zipkin2.reporter.BytesEncoder) + === UNCHANGED METHOD: PUBLIC io.opentelemetry.exporter.zipkin.ZipkinSpanExporterBuilder setSender(zipkin2.reporter.Sender) + +++ NEW ANNOTATION: java.lang.Deprecated + +++ NEW METHOD: PUBLIC(+) io.opentelemetry.exporter.zipkin.ZipkinSpanExporterBuilder setSender(zipkin2.reporter.BytesMessageSender) diff --git a/exporters/zipkin/src/main/java/io/opentelemetry/exporter/zipkin/ZipkinSpanExporter.java b/exporters/zipkin/src/main/java/io/opentelemetry/exporter/zipkin/ZipkinSpanExporter.java index 840e53b58de..c92f70db3f5 100644 --- a/exporters/zipkin/src/main/java/io/opentelemetry/exporter/zipkin/ZipkinSpanExporter.java +++ b/exporters/zipkin/src/main/java/io/opentelemetry/exporter/zipkin/ZipkinSpanExporter.java @@ -21,9 +21,8 @@ import java.util.logging.Logger; import zipkin2.Span; import zipkin2.reporter.BytesEncoder; -import zipkin2.reporter.Callback; +import zipkin2.reporter.BytesMessageSender; import zipkin2.reporter.Encoding; -import zipkin2.reporter.Sender; /** * This class was based on the encoder; - private final Sender sender; + private final BytesMessageSender sender; private final ExporterMetrics exporterMetrics; private final OtelToZipkinSpanTransformer transformer; @@ -48,7 +47,7 @@ public final class ZipkinSpanExporter implements SpanExporter { ZipkinSpanExporter( ZipkinSpanExporterBuilder builder, BytesEncoder encoder, - Sender sender, + BytesMessageSender sender, Supplier meterProviderSupplier, OtelToZipkinSpanTransformer transformer) { this.builder = builder; @@ -76,25 +75,15 @@ public CompletableResultCode export(Collection spanDataList) { encodedSpans.add(encoder.encode(zipkinSpan)); } - CompletableResultCode result = new CompletableResultCode(); - sender - .sendSpans(encodedSpans) - .enqueue( - new Callback() { - @Override - public void onSuccess(Void value) { - exporterMetrics.addSuccess(numItems); - result.succeed(); - } - - @Override - public void onError(Throwable t) { - exporterMetrics.addFailed(numItems); - logger.log(Level.WARNING, "Failed to export spans", t); - result.fail(); - } - }); - return result; + try { + sender.send(encodedSpans); + exporterMetrics.addSuccess(numItems); + return CompletableResultCode.ofSuccess(); + } catch (IOException | RuntimeException t) { + exporterMetrics.addFailed(numItems); + logger.log(Level.WARNING, "Failed to export spans", t); + return CompletableResultCode.ofFailure(); + } } @Override diff --git a/exporters/zipkin/src/main/java/io/opentelemetry/exporter/zipkin/ZipkinSpanExporterBuilder.java b/exporters/zipkin/src/main/java/io/opentelemetry/exporter/zipkin/ZipkinSpanExporterBuilder.java index ad19cbc8d33..e73e4f73474 100644 --- a/exporters/zipkin/src/main/java/io/opentelemetry/exporter/zipkin/ZipkinSpanExporterBuilder.java +++ b/exporters/zipkin/src/main/java/io/opentelemetry/exporter/zipkin/ZipkinSpanExporterBuilder.java @@ -18,7 +18,7 @@ import javax.annotation.Nullable; import zipkin2.Span; import zipkin2.reporter.BytesEncoder; -import zipkin2.reporter.Sender; +import zipkin2.reporter.BytesMessageSender; import zipkin2.reporter.SpanBytesEncoder; import zipkin2.reporter.okhttp3.OkHttpSender; @@ -26,7 +26,7 @@ public final class ZipkinSpanExporterBuilder { private BytesEncoder encoder = SpanBytesEncoder.JSON_V2; private Supplier localIpAddressSupplier = LocalInetAddressSupplier.getInstance(); - @Nullable private Sender sender; + @Nullable private BytesMessageSender sender; private String endpoint = ZipkinSpanExporter.DEFAULT_ENDPOINT; // compression is enabled by default, because this is the default of OkHttpSender, // which is created when no custom sender is set (see OkHttpSender.Builder) @@ -38,12 +38,27 @@ public final class ZipkinSpanExporterBuilder { * Sets the Zipkin sender. Implements the client side of the span transport. An {@link * OkHttpSender} is a good default. * - *

    The {@link Sender#close()} method will be called when the exporter is shut down. + *

    The {@link BytesMessageSender#close()} method will be called when the exporter is shut down. * * @param sender the Zipkin sender implementation. * @return this. + * @deprecated Use {@link #setSender(BytesMessageSender)} insteead. */ - public ZipkinSpanExporterBuilder setSender(Sender sender) { + @Deprecated + public ZipkinSpanExporterBuilder setSender(zipkin2.reporter.Sender sender) { + return setSender((BytesMessageSender) sender); + } + + /** + * Sets the Zipkin sender. Implements the client side of the span transport. An {@link + * OkHttpSender} is a good default. + * + *

    The {@link BytesMessageSender#close()} method will be called when the exporter is shut down. + * + * @param sender the Zipkin sender implementation. + * @return this. + */ + public ZipkinSpanExporterBuilder setSender(BytesMessageSender sender) { requireNonNull(sender, "sender"); this.sender = sender; return this; @@ -51,7 +66,7 @@ public ZipkinSpanExporterBuilder setSender(Sender sender) { /** * Sets the {@link zipkin2.codec.BytesEncoder}, which controls the format used by the {@link - * Sender}. Defaults to the {@link zipkin2.codec.SpanBytesEncoder#JSON_V2}. + * BytesMessageSender}. Defaults to the {@link zipkin2.codec.SpanBytesEncoder#JSON_V2}. * * @param encoder the {@code BytesEncoder} to use. * @return this. @@ -65,8 +80,8 @@ public ZipkinSpanExporterBuilder setEncoder(zipkin2.codec.BytesEncoder enc } /** - * Sets the {@link BytesEncoder}, which controls the format used by the {@link Sender}. Defaults - * to the {@link SpanBytesEncoder#JSON_V2}. + * Sets the {@link BytesEncoder}, which controls the format used by the {@link + * BytesMessageSender}. Defaults to the {@link SpanBytesEncoder#JSON_V2}. * * @param encoder the {@code BytesEncoder} to use. * @return this. @@ -114,7 +129,7 @@ public ZipkinSpanExporterBuilder setEndpoint(String endpoint) { * supported compression methods include "gzip" and "none". * *

    The compression method is ignored when a custom Zipkin sender is set via {@link - * #setSender(Sender)}. + * #setSender(BytesMessageSender)}. * * @param compressionMethod The compression method, ex. "gzip". * @return this. @@ -189,7 +204,7 @@ String toString(boolean includePrefixAndSuffix) { * @return a {@code ZipkinSpanExporter}. */ public ZipkinSpanExporter build() { - Sender sender = this.sender; + BytesMessageSender sender = this.sender; if (sender == null) { sender = OkHttpSender.newBuilder() diff --git a/exporters/zipkin/src/test/java/io/opentelemetry/exporter/zipkin/ZipkinSpanExporterEndToEndHttpTest.java b/exporters/zipkin/src/test/java/io/opentelemetry/exporter/zipkin/ZipkinSpanExporterEndToEndHttpTest.java index c55d2c01c67..4ad9bdfb106 100644 --- a/exporters/zipkin/src/test/java/io/opentelemetry/exporter/zipkin/ZipkinSpanExporterEndToEndHttpTest.java +++ b/exporters/zipkin/src/test/java/io/opentelemetry/exporter/zipkin/ZipkinSpanExporterEndToEndHttpTest.java @@ -45,6 +45,7 @@ import zipkin2.Endpoint; import zipkin2.Span; import zipkin2.codec.SpanBytesDecoder; +import zipkin2.reporter.BytesMessageSender; import zipkin2.reporter.Encoding; import zipkin2.reporter.SpanBytesEncoder; import zipkin2.reporter.okhttp3.OkHttpSender; @@ -175,8 +176,10 @@ void testExportFailedAsWrongEncoderUsed() { private static ZipkinSpanExporter buildZipkinExporter( String endpoint, Encoding encoding, SpanBytesEncoder encoder, MeterProvider meterProvider) { + BytesMessageSender sender = + OkHttpSender.newBuilder().endpoint(endpoint).encoding(encoding).build(); return ZipkinSpanExporter.builder() - .setSender(OkHttpSender.newBuilder().endpoint(endpoint).encoding(encoding).build()) + .setSender(sender) .setEncoder(encoder) .setMeterProvider(meterProvider) .setLocalIpAddressSupplier(() -> localIp) diff --git a/exporters/zipkin/src/test/java/io/opentelemetry/exporter/zipkin/ZipkinSpanExporterTest.java b/exporters/zipkin/src/test/java/io/opentelemetry/exporter/zipkin/ZipkinSpanExporterTest.java index 38e4534c71a..2917cfbefe6 100644 --- a/exporters/zipkin/src/test/java/io/opentelemetry/exporter/zipkin/ZipkinSpanExporterTest.java +++ b/exporters/zipkin/src/test/java/io/opentelemetry/exporter/zipkin/ZipkinSpanExporterTest.java @@ -9,8 +9,7 @@ import static io.opentelemetry.exporter.zipkin.ZipkinTestUtil.zipkinSpanBuilder; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.Mockito.doAnswer; +import static org.mockito.Mockito.doThrow; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @@ -31,18 +30,15 @@ import org.mockito.junit.jupiter.MockitoExtension; import zipkin2.Span; import zipkin2.reporter.BytesEncoder; -import zipkin2.reporter.Call; -import zipkin2.reporter.Callback; +import zipkin2.reporter.BytesMessageSender; import zipkin2.reporter.Encoding; -import zipkin2.reporter.Sender; import zipkin2.reporter.SpanBytesEncoder; @ExtendWith(MockitoExtension.class) class ZipkinSpanExporterTest { - @Mock private Sender mockSender; + @Mock private BytesMessageSender mockSender; @Mock private SpanBytesEncoder mockEncoder; - @Mock private Call mockZipkinCall; @Mock private OtelToZipkinSpanTransformer mockTransformer; @Mock private InetAddress localIp; @@ -50,7 +46,7 @@ class ZipkinSpanExporterTest { LogCapturer logs = LogCapturer.create().captureForType(ZipkinSpanExporter.class); @Test - void testExport() { + void testExport() throws IOException { TestSpanData testSpanData = spanBuilder().build(); ZipkinSpanExporter zipkinSpanExporter = @@ -68,25 +64,18 @@ void testExport() { .build(); when(mockTransformer.generateSpan(testSpanData)).thenReturn(zipkinSpan); when(mockEncoder.encode(zipkinSpan)).thenReturn(someBytes); - when(mockSender.sendSpans(Collections.singletonList(someBytes))).thenReturn(mockZipkinCall); - doAnswer( - invocation -> { - Callback callback = invocation.getArgument(0); - callback.onSuccess(null); - return null; - }) - .when(mockZipkinCall) - .enqueue(any()); CompletableResultCode resultCode = zipkinSpanExporter.export(Collections.singleton(testSpanData)); assertThat(resultCode.isSuccess()).isTrue(); + + verify(mockSender).send(Collections.singletonList(someBytes)); } @Test @SuppressLogger(ZipkinSpanExporter.class) - void testExport_failed() { + void testExport_failed() throws IOException { TestSpanData testSpanData = spanBuilder().build(); ZipkinSpanExporter zipkinSpanExporter = @@ -104,20 +93,14 @@ void testExport_failed() { .build(); when(mockTransformer.generateSpan(testSpanData)).thenReturn(zipkinSpan); when(mockEncoder.encode(zipkinSpan)).thenReturn(someBytes); - when(mockSender.sendSpans(Collections.singletonList(someBytes))).thenReturn(mockZipkinCall); - doAnswer( - invocation -> { - Callback callback = invocation.getArgument(0); - callback.onError(new IOException()); - return null; - }) - .when(mockZipkinCall) - .enqueue(any()); + doThrow(new IOException()).when(mockSender).send(Collections.singletonList(someBytes)); CompletableResultCode resultCode = zipkinSpanExporter.export(Collections.singleton(testSpanData)); assertThat(resultCode.isSuccess()).isFalse(); + + verify(mockSender).send(Collections.singletonList(someBytes)); } @Test From 737dfef4e62225158017c0767f0b4ffc25b7f1b6 Mon Sep 17 00:00:00 2001 From: Asaf Mesika Date: Thu, 25 Jan 2024 17:23:59 +0200 Subject: [PATCH 212/901] Memory Mode: Adding 3rd and last part support for synchronous instruments - exponential histogram (#6136) Co-authored-by: jack-berg <34418638+jack-berg@users.noreply.github.com> --- ...InstrumentGarbageCollectionBenchmark.java} | 40 +++++----- ...rumentGarbageCollectionBenchmarkTest.java} | 71 +++++++++++------- .../internal/state/ProfileBenchmark.java | 75 +++++++++++++++++++ .../internal/state/TestInstrumentType.java | 50 +++++++++++++ .../state/tester/AsyncCounterTester.java | 51 +++++++++++++ .../tester/ExponentialHistogramTester.java | 57 ++++++++++++++ .../Base2ExponentialHistogramIndexer.java | 2 +- 7 files changed, 299 insertions(+), 47 deletions(-) rename sdk/metrics/src/jmhBasedTest/java/io/opentelemetry/sdk/metrics/internal/state/{AsynchronousMetricStorageGarbageCollectionBenchmark.java => InstrumentGarbageCollectionBenchmark.java} (77%) rename sdk/metrics/src/jmhBasedTest/java/io/opentelemetry/sdk/metrics/internal/state/{AsynchronousMetricStorageGarbageCollectionBenchmarkTest.java => InstrumentGarbageCollectionBenchmarkTest.java} (51%) create mode 100644 sdk/metrics/src/jmhBasedTest/java/io/opentelemetry/sdk/metrics/internal/state/ProfileBenchmark.java create mode 100644 sdk/metrics/src/jmhBasedTest/java/io/opentelemetry/sdk/metrics/internal/state/TestInstrumentType.java create mode 100644 sdk/metrics/src/jmhBasedTest/java/io/opentelemetry/sdk/metrics/internal/state/tester/AsyncCounterTester.java create mode 100644 sdk/metrics/src/jmhBasedTest/java/io/opentelemetry/sdk/metrics/internal/state/tester/ExponentialHistogramTester.java diff --git a/sdk/metrics/src/jmhBasedTest/java/io/opentelemetry/sdk/metrics/internal/state/AsynchronousMetricStorageGarbageCollectionBenchmark.java b/sdk/metrics/src/jmhBasedTest/java/io/opentelemetry/sdk/metrics/internal/state/InstrumentGarbageCollectionBenchmark.java similarity index 77% rename from sdk/metrics/src/jmhBasedTest/java/io/opentelemetry/sdk/metrics/internal/state/AsynchronousMetricStorageGarbageCollectionBenchmark.java rename to sdk/metrics/src/jmhBasedTest/java/io/opentelemetry/sdk/metrics/internal/state/InstrumentGarbageCollectionBenchmark.java index b1d845773dd..f9056a6e6e0 100644 --- a/sdk/metrics/src/jmhBasedTest/java/io/opentelemetry/sdk/metrics/internal/state/AsynchronousMetricStorageGarbageCollectionBenchmark.java +++ b/sdk/metrics/src/jmhBasedTest/java/io/opentelemetry/sdk/metrics/internal/state/InstrumentGarbageCollectionBenchmark.java @@ -7,13 +7,14 @@ import io.opentelemetry.api.common.Attributes; import io.opentelemetry.sdk.common.export.MemoryMode; -import io.opentelemetry.sdk.metrics.Aggregation; import io.opentelemetry.sdk.metrics.SdkMeterProvider; import io.opentelemetry.sdk.metrics.SdkMeterProviderBuilder; import io.opentelemetry.sdk.metrics.data.AggregationTemporality; import io.opentelemetry.sdk.metrics.export.PeriodicMetricReader; import io.opentelemetry.sdk.metrics.internal.SdkMeterProviderUtil; import io.opentelemetry.sdk.metrics.internal.exemplar.ExemplarFilter; +import io.opentelemetry.sdk.metrics.internal.state.TestInstrumentType.InstrumentTester; +import io.opentelemetry.sdk.metrics.internal.state.TestInstrumentType.TestInstrumentsState; import java.time.Duration; import java.util.List; import java.util.Random; @@ -33,8 +34,8 @@ import org.openjdk.jmh.annotations.Warmup; /** - * Run this through {@link AsynchronousMetricStorageGarbageCollectionBenchmarkTest}, as it runs it - * embedded with the GC profiler which what this test designed for (No need for command line run) + * Run this through {@link InstrumentGarbageCollectionBenchmarkTest}, as it runs it embedded with + * the GC profiler which what this test designed for (No need for command line run) * *

    This test creates 10 asynchronous counters (any asynchronous instrument will do as the code * path is almost the same for all async instrument types), and 1000 attribute sets. Each time the @@ -51,37 +52,41 @@ */ @BenchmarkMode(Mode.SingleShotTime) @OutputTimeUnit(TimeUnit.NANOSECONDS) -@Measurement(iterations = 20, batchSize = 100) +@Measurement(iterations = 10, batchSize = 10) @Warmup(iterations = 10, batchSize = 10) @Fork(1) -public class AsynchronousMetricStorageGarbageCollectionBenchmark { +public class InstrumentGarbageCollectionBenchmark { @State(value = Scope.Benchmark) - @SuppressWarnings("SystemOut") public static class ThreadState { private final int cardinality; - private final int countersCount; + private final int instrumentCount; + @Param public TestInstrumentType testInstrumentType; @Param public AggregationTemporality aggregationTemporality; @Param public MemoryMode memoryMode; SdkMeterProvider sdkMeterProvider; private final Random random = new Random(); List attributesList; + private TestInstrumentsState testInstrumentsState; + private InstrumentTester instrumentTester; /** Creates a ThreadState. */ @SuppressWarnings("unused") public ThreadState() { cardinality = 1000; - countersCount = 10; + instrumentCount = 10; } @SuppressWarnings("SpellCheckingInspection") @Setup public void setup() { + instrumentTester = testInstrumentType.createInstrumentTester(); PeriodicMetricReader metricReader = PeriodicMetricReader.builder( // Configure an exporter that configures the temporality and aggregation // for the test case, but otherwise drops the data on export - new NoopMetricExporter(aggregationTemporality, Aggregation.sum(), memoryMode)) + new NoopMetricExporter( + aggregationTemporality, instrumentTester.testedAggregation(), memoryMode)) // Effectively disable periodic reading so reading is only done on #flush() .setInterval(Duration.ofSeconds(Integer.MAX_VALUE)) .build(); @@ -95,18 +100,9 @@ public void setup() { SdkMeterProviderUtil.setExemplarFilter(builder, ExemplarFilter.alwaysOff()); sdkMeterProvider = builder.build(); - for (int i = 0; i < countersCount; i++) { - sdkMeterProvider - .get("meter") - .counterBuilder("counter" + i) - .buildWithCallback( - observableLongMeasurement -> { - for (int j = 0; j < attributesList.size(); j++) { - Attributes attributes = attributesList.get(j); - observableLongMeasurement.record(random.nextInt(10_000), attributes); - } - }); - } + testInstrumentsState = + instrumentTester.buildInstruments( + instrumentCount, sdkMeterProvider, attributesList, random); } @TearDown @@ -123,6 +119,8 @@ public void tearDown() { @Benchmark @Threads(value = 1) public void recordAndCollect(ThreadState threadState) { + threadState.instrumentTester.recordValuesInInstruments( + threadState.testInstrumentsState, threadState.attributesList, threadState.random); threadState.sdkMeterProvider.forceFlush().join(10, TimeUnit.SECONDS); } } diff --git a/sdk/metrics/src/jmhBasedTest/java/io/opentelemetry/sdk/metrics/internal/state/AsynchronousMetricStorageGarbageCollectionBenchmarkTest.java b/sdk/metrics/src/jmhBasedTest/java/io/opentelemetry/sdk/metrics/internal/state/InstrumentGarbageCollectionBenchmarkTest.java similarity index 51% rename from sdk/metrics/src/jmhBasedTest/java/io/opentelemetry/sdk/metrics/internal/state/AsynchronousMetricStorageGarbageCollectionBenchmarkTest.java rename to sdk/metrics/src/jmhBasedTest/java/io/opentelemetry/sdk/metrics/internal/state/InstrumentGarbageCollectionBenchmarkTest.java index a5b5f5cc5d2..de1733b0ad8 100644 --- a/sdk/metrics/src/jmhBasedTest/java/io/opentelemetry/sdk/metrics/internal/state/AsynchronousMetricStorageGarbageCollectionBenchmarkTest.java +++ b/sdk/metrics/src/jmhBasedTest/java/io/opentelemetry/sdk/metrics/internal/state/InstrumentGarbageCollectionBenchmarkTest.java @@ -26,17 +26,17 @@ import org.openjdk.jmh.runner.options.Options; import org.openjdk.jmh.runner.options.OptionsBuilder; -public class AsynchronousMetricStorageGarbageCollectionBenchmarkTest { +public class InstrumentGarbageCollectionBenchmarkTest { /** - * This test validates that in {@link MemoryMode#REUSABLE_DATA}, {@link - * AsynchronousMetricStorage#collect(Resource, InstrumentationScopeInfo, long, long)} barely - * allocates memory which is then subsequently garbage collected. It is done so comparatively to - * {@link MemoryMode#IMMUTABLE_DATA}, + * This test validates that in {@link MemoryMode#REUSABLE_DATA}, any {@link + * MetricStorage#collect(Resource, InstrumentationScopeInfo, long, long)} barely allocates memory + * which is then subsequently garbage collected. It is done so comparatively to {@link + * MemoryMode#IMMUTABLE_DATA}, * - *

    It runs the JMH test {@link AsynchronousMetricStorageGarbageCollectionBenchmark} with GC - * profiler, and measures for each parameter combination the garbage collector normalized rate - * (bytes allocated per Operation). + *

    It runs the JMH test {@link InstrumentGarbageCollectionBenchmark} with GC profiler, and + * measures for each parameter combination the garbage collector normalized rate (bytes allocated + * per Operation). * *

    Memory allocations can be hidden even at an innocent foreach loop on a collection, which * under the hood allocates an internal object O(N) times. Someone can accidentally refactor such @@ -52,11 +52,11 @@ public void normalizedAllocationRateTest() throws RunnerException { "true".equals(System.getenv("CI")), "This test should only run in GitHub CI since it's long"); - // Runs AsynchronousMetricStorageMemoryProfilingBenchmark + // Runs InstrumentGarbageCollectionBenchmark // with garbage collection profiler Options opt = new OptionsBuilder() - .include(AsynchronousMetricStorageGarbageCollectionBenchmark.class.getSimpleName()) + .include(InstrumentGarbageCollectionBenchmark.class.getSimpleName()) .addProfiler("gc") .shouldFailOnError(true) .jvmArgs("-Xmx1500m") @@ -64,15 +64,17 @@ public void normalizedAllocationRateTest() throws RunnerException { Collection results = new Runner(opt).run(); // Collect the normalized GC allocation rate per parameters combination - Map> resultMap = new HashMap<>(); + Map testInstrumentTypeResultsMap = new HashMap<>(); for (RunResult result : results) { for (BenchmarkResult benchmarkResult : result.getBenchmarkResults()) { BenchmarkParams benchmarkParams = benchmarkResult.getParams(); String memoryMode = benchmarkParams.getParam("memoryMode"); String aggregationTemporality = benchmarkParams.getParam("aggregationTemporality"); + String testInstrumentType = benchmarkParams.getParam("testInstrumentType"); assertThat(memoryMode).isNotNull(); assertThat(aggregationTemporality).isNotNull(); + assertThat(testInstrumentType).isNotNull(); Map secondaryResults = benchmarkResult.getSecondaryResults(); Result allocRateNorm = secondaryResults.get("gc.alloc.rate.norm"); @@ -80,27 +82,46 @@ public void normalizedAllocationRateTest() throws RunnerException { .describedAs("Allocation rate in secondary results: %s", secondaryResults) .isNotNull(); - resultMap + testInstrumentTypeResultsMap + .computeIfAbsent(testInstrumentType, k -> new TestInstrumentTypeResults()) + .aggregationTemporalityToMemoryModeResult .computeIfAbsent(aggregationTemporality, k -> new HashMap<>()) .put(memoryMode, allocRateNorm.getScore()); } } - assertThat(resultMap).hasSameSizeAs(AggregationTemporality.values()); + testInstrumentTypeResultsMap.forEach( + (testInstrumentType, testInstrumentTypeResults) -> { + Map> resultMap = + testInstrumentTypeResults.aggregationTemporalityToMemoryModeResult; + assertThat(resultMap).hasSameSizeAs(AggregationTemporality.values()); - // Asserts that reusable data GC allocation rate is a tiny fraction of immutable data - // GC allocation rate - resultMap.forEach( - (aggregationTemporality, memoryModeToAllocRateMap) -> { - Double immutableDataAllocRate = - memoryModeToAllocRateMap.get(MemoryMode.IMMUTABLE_DATA.toString()); - Double reusableDataAllocRate = - memoryModeToAllocRateMap.get(MemoryMode.REUSABLE_DATA.toString()); + // Asserts that reusable data GC allocation rate is a tiny fraction of immutable data + // GC allocation rate + resultMap.forEach( + (aggregationTemporality, memoryModeToAllocRateMap) -> { + Double immutableDataAllocRate = + memoryModeToAllocRateMap.get(MemoryMode.IMMUTABLE_DATA.toString()); + Double reusableDataAllocRate = + memoryModeToAllocRateMap.get(MemoryMode.REUSABLE_DATA.toString()); - assertThat(immutableDataAllocRate).isNotNull().isNotZero(); - assertThat(reusableDataAllocRate).isNotNull().isNotZero(); - assertThat(100 - (reusableDataAllocRate / immutableDataAllocRate) * 100) - .isCloseTo(99.8, Offset.offset(2.0)); + assertThat(immutableDataAllocRate).isNotNull().isNotZero(); + assertThat(reusableDataAllocRate).isNotNull().isNotZero(); + + // If this test suddenly fails for you this means you have changed the code in a way + // that allocates more memory than before. You can find out where, by running + // ProfileBenchmark class and looking at the flame graph. Make sure to + // set the parameters according to where it failed for. + assertThat(100 - (reusableDataAllocRate / immutableDataAllocRate) * 100) + .describedAs( + "Aggregation temporality = %s, testInstrumentType = %s", + aggregationTemporality, testInstrumentType) + .isCloseTo(99.8, Offset.offset(2.0)); + }); }); } + + static class TestInstrumentTypeResults { + Map> aggregationTemporalityToMemoryModeResult = new HashMap<>(); + } } diff --git a/sdk/metrics/src/jmhBasedTest/java/io/opentelemetry/sdk/metrics/internal/state/ProfileBenchmark.java b/sdk/metrics/src/jmhBasedTest/java/io/opentelemetry/sdk/metrics/internal/state/ProfileBenchmark.java new file mode 100644 index 00000000000..b79fbc36e09 --- /dev/null +++ b/sdk/metrics/src/jmhBasedTest/java/io/opentelemetry/sdk/metrics/internal/state/ProfileBenchmark.java @@ -0,0 +1,75 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.sdk.metrics.internal.state; + +import io.opentelemetry.sdk.common.export.MemoryMode; +import io.opentelemetry.sdk.metrics.data.AggregationTemporality; + +/** + * This benchmark class is used to see memory allocation flame graphs for a single run. + * + *

    Steps: + * + *

      + *
    1. Follow download instructions for async-profiler, located at this location + *
    2. Assuming you have extracted it at /tmp/async-profiler-2.9-macos, add the following to your + * JVM arguments of your run configuration: + *
      + *       -agentpath:/tmp/async-profiler-2.9-macos/build/libasyncProfiler.so=start,event=alloc,flamegraph,file=/tmp/profiled_data.html
      + *       
      + *
    3. Tune the parameters as you see fit (They are marked below with "Parameters") + *
    4. Run the class (its main function) + *
    5. Open /tmp/profiled_data.html with your browser + *
    6. Use the flame graph to see where the allocations are happening the most and fix + *
    7. Run {@link InstrumentGarbageCollectionBenchmark} and see if it passes now + *
    8. If not, repeat + *
    + */ +public class ProfileBenchmark { + + private ProfileBenchmark() {} + + public static void main(String[] args) { + // Parameters + AggregationTemporality aggregationTemporality = AggregationTemporality.DELTA; + MemoryMode memoryMode = MemoryMode.REUSABLE_DATA; + TestInstrumentType testInstrumentType = TestInstrumentType.EXPONENTIAL_HISTOGRAM; + + InstrumentGarbageCollectionBenchmark.ThreadState benchmarkSetup = + new InstrumentGarbageCollectionBenchmark.ThreadState(); + + benchmarkSetup.aggregationTemporality = aggregationTemporality; + benchmarkSetup.memoryMode = memoryMode; + benchmarkSetup.testInstrumentType = testInstrumentType; + + InstrumentGarbageCollectionBenchmark benchmark = new InstrumentGarbageCollectionBenchmark(); + + benchmarkSetup.setup(); + + warmup(benchmark, benchmarkSetup); + + // This is divided explicitly to two methods so you can focus on `measure` in the flame graph + // when trying to decrease the allocations + measure(benchmark, benchmarkSetup); + } + + public static void warmup( + InstrumentGarbageCollectionBenchmark benchmark, + InstrumentGarbageCollectionBenchmark.ThreadState benchmarkSetup) { + for (int i = 0; i < 10; i++) { + benchmark.recordAndCollect(benchmarkSetup); + } + } + + public static void measure( + InstrumentGarbageCollectionBenchmark benchmark, + InstrumentGarbageCollectionBenchmark.ThreadState benchmarkSetup) { + for (int i = 0; i < 200; i++) { + benchmark.recordAndCollect(benchmarkSetup); + } + } +} diff --git a/sdk/metrics/src/jmhBasedTest/java/io/opentelemetry/sdk/metrics/internal/state/TestInstrumentType.java b/sdk/metrics/src/jmhBasedTest/java/io/opentelemetry/sdk/metrics/internal/state/TestInstrumentType.java new file mode 100644 index 00000000000..6514146a6cb --- /dev/null +++ b/sdk/metrics/src/jmhBasedTest/java/io/opentelemetry/sdk/metrics/internal/state/TestInstrumentType.java @@ -0,0 +1,50 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.sdk.metrics.internal.state; + +import io.opentelemetry.api.common.Attributes; +import io.opentelemetry.sdk.metrics.Aggregation; +import io.opentelemetry.sdk.metrics.SdkMeterProvider; +import io.opentelemetry.sdk.metrics.internal.state.tester.AsyncCounterTester; +import io.opentelemetry.sdk.metrics.internal.state.tester.ExponentialHistogramTester; +import java.util.List; +import java.util.Random; + +public enum TestInstrumentType { + ASYNC_COUNTER() { + @Override + InstrumentTester createInstrumentTester() { + return new AsyncCounterTester(); + } + }, + EXPONENTIAL_HISTOGRAM() { + @Override + InstrumentTester createInstrumentTester() { + return new ExponentialHistogramTester(); + } + }; + + abstract InstrumentTester createInstrumentTester(); + + TestInstrumentType() {} + + public interface InstrumentTester { + Aggregation testedAggregation(); + + TestInstrumentsState buildInstruments( + double instrumentCount, + SdkMeterProvider sdkMeterProvider, + List attributesList, + Random random); + + void recordValuesInInstruments( + TestInstrumentsState testInstrumentsState, List attributesList, Random random); + } + + public interface TestInstrumentsState {} + + public static class EmptyInstrumentsState implements TestInstrumentsState {} +} diff --git a/sdk/metrics/src/jmhBasedTest/java/io/opentelemetry/sdk/metrics/internal/state/tester/AsyncCounterTester.java b/sdk/metrics/src/jmhBasedTest/java/io/opentelemetry/sdk/metrics/internal/state/tester/AsyncCounterTester.java new file mode 100644 index 00000000000..f926fb343b6 --- /dev/null +++ b/sdk/metrics/src/jmhBasedTest/java/io/opentelemetry/sdk/metrics/internal/state/tester/AsyncCounterTester.java @@ -0,0 +1,51 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.sdk.metrics.internal.state.tester; + +import io.opentelemetry.api.common.Attributes; +import io.opentelemetry.sdk.metrics.Aggregation; +import io.opentelemetry.sdk.metrics.SdkMeterProvider; +import io.opentelemetry.sdk.metrics.internal.state.TestInstrumentType; +import io.opentelemetry.sdk.metrics.internal.state.TestInstrumentType.EmptyInstrumentsState; +import java.util.List; +import java.util.Random; + +public class AsyncCounterTester implements TestInstrumentType.InstrumentTester { + @Override + public Aggregation testedAggregation() { + return Aggregation.sum(); + } + + @SuppressWarnings("ForLoopReplaceableByForEach") // This is for GC sensitivity testing: no streams + @Override + public TestInstrumentType.TestInstrumentsState buildInstruments( + double instrumentCount, + SdkMeterProvider sdkMeterProvider, + List attributesList, + Random random) { + for (int i = 0; i < instrumentCount; i++) { + sdkMeterProvider + .get("meter") + .counterBuilder("counter" + i) + .buildWithCallback( + observableLongMeasurement -> { + for (int j = 0; j < attributesList.size(); j++) { + Attributes attributes = attributesList.get(j); + observableLongMeasurement.record(random.nextInt(10_000), attributes); + } + }); + } + return new EmptyInstrumentsState(); + } + + @Override + public void recordValuesInInstruments( + TestInstrumentType.TestInstrumentsState testInstrumentsState, + List attributesList, + Random random) { + // No need, all done via the callbacks + } +} diff --git a/sdk/metrics/src/jmhBasedTest/java/io/opentelemetry/sdk/metrics/internal/state/tester/ExponentialHistogramTester.java b/sdk/metrics/src/jmhBasedTest/java/io/opentelemetry/sdk/metrics/internal/state/tester/ExponentialHistogramTester.java new file mode 100644 index 00000000000..6cca5a35bd4 --- /dev/null +++ b/sdk/metrics/src/jmhBasedTest/java/io/opentelemetry/sdk/metrics/internal/state/tester/ExponentialHistogramTester.java @@ -0,0 +1,57 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.sdk.metrics.internal.state.tester; + +import io.opentelemetry.api.common.Attributes; +import io.opentelemetry.api.metrics.DoubleHistogram; +import io.opentelemetry.sdk.metrics.Aggregation; +import io.opentelemetry.sdk.metrics.SdkMeterProvider; +import io.opentelemetry.sdk.metrics.internal.state.TestInstrumentType; +import io.opentelemetry.sdk.metrics.internal.state.TestInstrumentType.InstrumentTester; +import java.util.List; +import java.util.Random; + +public class ExponentialHistogramTester implements InstrumentTester { + + static class ExponentialHistogramState implements TestInstrumentType.TestInstrumentsState { + DoubleHistogram doubleHistogram; + } + + private static final int measurementsPerAttributeSet = 1_000; + + @Override + public Aggregation testedAggregation() { + return Aggregation.base2ExponentialBucketHistogram(); + } + + @Override + public TestInstrumentType.TestInstrumentsState buildInstruments( + double instrumentCount, + SdkMeterProvider sdkMeterProvider, + List attributesList, + Random random) { + ExponentialHistogramState state = new ExponentialHistogramState(); + state.doubleHistogram = sdkMeterProvider.get("meter").histogramBuilder("testhistogram").build(); + return state; + } + + @SuppressWarnings("ForLoopReplaceableByForEach") // This is for GC sensitivity testing: no streams + @Override + public void recordValuesInInstruments( + TestInstrumentType.TestInstrumentsState testInstrumentsState, + List attributesList, + Random random) { + + ExponentialHistogramState state = (ExponentialHistogramState) testInstrumentsState; + + for (int j = 0; j < attributesList.size(); j++) { + Attributes attributes = attributesList.get(j); + for (int i = 0; i < measurementsPerAttributeSet; i++) { + state.doubleHistogram.record(random.nextInt(10_000), attributes); + } + } + } +} diff --git a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/aggregator/Base2ExponentialHistogramIndexer.java b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/aggregator/Base2ExponentialHistogramIndexer.java index 749cba883ae..a0b1acb52a4 100644 --- a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/aggregator/Base2ExponentialHistogramIndexer.java +++ b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/aggregator/Base2ExponentialHistogramIndexer.java @@ -43,7 +43,7 @@ private Base2ExponentialHistogramIndexer(int scale) { /** Get an indexer for the given scale. Indexers are cached and reused for performance. */ static Base2ExponentialHistogramIndexer get(int scale) { - return cache.computeIfAbsent(scale, unused -> new Base2ExponentialHistogramIndexer(scale)); + return cache.computeIfAbsent(scale, Base2ExponentialHistogramIndexer::new); } /** From 8d1cad2ae13200e4fffbefc6e8e38d8e40479657 Mon Sep 17 00:00:00 2001 From: Asaf Mesika Date: Thu, 25 Jan 2024 20:18:28 +0200 Subject: [PATCH 213/901] Memory mode: Adding support for synchronous instruments - explicit histogram (#6153) Co-authored-by: jack-berg <34418638+jack-berg@users.noreply.github.com> --- .../internal/DynamicPrimitiveLongList.java | 4 + .../aggregator/HistogramAggregationParam.java | 6 +- .../internal/state/ProfileBenchmark.java | 2 +- .../internal/state/TestInstrumentType.java | 7 + .../tester/ExplicitBucketHistogramTester.java | 62 +++++ ...ubleExplicitBucketHistogramAggregator.java | 64 +++-- .../data/HistogramPointDataValidations.java | 35 +++ .../data/ImmutableHistogramPointData.java | 21 +- .../data/MutableHistogramPointData.java | 249 ++++++++++++++++++ .../ExplicitBucketHistogramAggregation.java | 3 +- .../metrics/internal/view/package-info.java | 10 + ...ExplicitBucketHistogramAggregatorTest.java | 86 ++++-- .../data/MutableHistogramPointDataTest.java | 165 ++++++++++++ 13 files changed, 659 insertions(+), 55 deletions(-) create mode 100644 sdk/metrics/src/jmhBasedTest/java/io/opentelemetry/sdk/metrics/internal/state/tester/ExplicitBucketHistogramTester.java create mode 100644 sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/data/HistogramPointDataValidations.java create mode 100644 sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/data/MutableHistogramPointData.java create mode 100644 sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/view/package-info.java create mode 100644 sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/internal/data/MutableHistogramPointDataTest.java diff --git a/sdk/common/src/main/java/io/opentelemetry/sdk/internal/DynamicPrimitiveLongList.java b/sdk/common/src/main/java/io/opentelemetry/sdk/internal/DynamicPrimitiveLongList.java index e7cf95d9e29..e2bd0412391 100644 --- a/sdk/common/src/main/java/io/opentelemetry/sdk/internal/DynamicPrimitiveLongList.java +++ b/sdk/common/src/main/java/io/opentelemetry/sdk/internal/DynamicPrimitiveLongList.java @@ -65,6 +65,10 @@ public static DynamicPrimitiveLongList of(long... values) { return list; } + public static DynamicPrimitiveLongList ofSubArrayCapacity(int subarrayCapacity) { + return new DynamicPrimitiveLongList(subarrayCapacity); + } + public static DynamicPrimitiveLongList empty() { return new DynamicPrimitiveLongList(); } diff --git a/sdk/metrics/src/jmh/java/io/opentelemetry/sdk/metrics/internal/aggregator/HistogramAggregationParam.java b/sdk/metrics/src/jmh/java/io/opentelemetry/sdk/metrics/internal/aggregator/HistogramAggregationParam.java index efb8bfdc89c..162794f52d8 100644 --- a/sdk/metrics/src/jmh/java/io/opentelemetry/sdk/metrics/internal/aggregator/HistogramAggregationParam.java +++ b/sdk/metrics/src/jmh/java/io/opentelemetry/sdk/metrics/internal/aggregator/HistogramAggregationParam.java @@ -17,11 +17,13 @@ public enum HistogramAggregationParam { new DoubleExplicitBucketHistogramAggregator( ExplicitBucketHistogramUtils.createBoundaryArray( ExplicitBucketHistogramUtils.DEFAULT_HISTOGRAM_BUCKET_BOUNDARIES), - ExemplarReservoir::doubleNoSamples)), + ExemplarReservoir::doubleNoSamples, + IMMUTABLE_DATA)), EXPLICIT_SINGLE_BUCKET( new DoubleExplicitBucketHistogramAggregator( ExplicitBucketHistogramUtils.createBoundaryArray(Collections.emptyList()), - ExemplarReservoir::doubleNoSamples)), + ExemplarReservoir::doubleNoSamples, + IMMUTABLE_DATA)), EXPONENTIAL_SMALL_CIRCULAR_BUFFER( new DoubleBase2ExponentialHistogramAggregator( ExemplarReservoir::doubleNoSamples, 20, 0, IMMUTABLE_DATA)), diff --git a/sdk/metrics/src/jmhBasedTest/java/io/opentelemetry/sdk/metrics/internal/state/ProfileBenchmark.java b/sdk/metrics/src/jmhBasedTest/java/io/opentelemetry/sdk/metrics/internal/state/ProfileBenchmark.java index b79fbc36e09..26f4588582b 100644 --- a/sdk/metrics/src/jmhBasedTest/java/io/opentelemetry/sdk/metrics/internal/state/ProfileBenchmark.java +++ b/sdk/metrics/src/jmhBasedTest/java/io/opentelemetry/sdk/metrics/internal/state/ProfileBenchmark.java @@ -37,7 +37,7 @@ public static void main(String[] args) { // Parameters AggregationTemporality aggregationTemporality = AggregationTemporality.DELTA; MemoryMode memoryMode = MemoryMode.REUSABLE_DATA; - TestInstrumentType testInstrumentType = TestInstrumentType.EXPONENTIAL_HISTOGRAM; + TestInstrumentType testInstrumentType = TestInstrumentType.EXPLICIT_BUCKET; InstrumentGarbageCollectionBenchmark.ThreadState benchmarkSetup = new InstrumentGarbageCollectionBenchmark.ThreadState(); diff --git a/sdk/metrics/src/jmhBasedTest/java/io/opentelemetry/sdk/metrics/internal/state/TestInstrumentType.java b/sdk/metrics/src/jmhBasedTest/java/io/opentelemetry/sdk/metrics/internal/state/TestInstrumentType.java index 6514146a6cb..9f799d72894 100644 --- a/sdk/metrics/src/jmhBasedTest/java/io/opentelemetry/sdk/metrics/internal/state/TestInstrumentType.java +++ b/sdk/metrics/src/jmhBasedTest/java/io/opentelemetry/sdk/metrics/internal/state/TestInstrumentType.java @@ -9,6 +9,7 @@ import io.opentelemetry.sdk.metrics.Aggregation; import io.opentelemetry.sdk.metrics.SdkMeterProvider; import io.opentelemetry.sdk.metrics.internal.state.tester.AsyncCounterTester; +import io.opentelemetry.sdk.metrics.internal.state.tester.ExplicitBucketHistogramTester; import io.opentelemetry.sdk.metrics.internal.state.tester.ExponentialHistogramTester; import java.util.List; import java.util.Random; @@ -25,6 +26,12 @@ InstrumentTester createInstrumentTester() { InstrumentTester createInstrumentTester() { return new ExponentialHistogramTester(); } + }, + EXPLICIT_BUCKET() { + @Override + InstrumentTester createInstrumentTester() { + return new ExplicitBucketHistogramTester(); + } }; abstract InstrumentTester createInstrumentTester(); diff --git a/sdk/metrics/src/jmhBasedTest/java/io/opentelemetry/sdk/metrics/internal/state/tester/ExplicitBucketHistogramTester.java b/sdk/metrics/src/jmhBasedTest/java/io/opentelemetry/sdk/metrics/internal/state/tester/ExplicitBucketHistogramTester.java new file mode 100644 index 00000000000..64ef6ca970d --- /dev/null +++ b/sdk/metrics/src/jmhBasedTest/java/io/opentelemetry/sdk/metrics/internal/state/tester/ExplicitBucketHistogramTester.java @@ -0,0 +1,62 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.sdk.metrics.internal.state.tester; + +import io.opentelemetry.api.common.Attributes; +import io.opentelemetry.api.metrics.DoubleHistogram; +import io.opentelemetry.sdk.metrics.Aggregation; +import io.opentelemetry.sdk.metrics.SdkMeterProvider; +import io.opentelemetry.sdk.metrics.internal.aggregator.ExplicitBucketHistogramUtils; +import io.opentelemetry.sdk.metrics.internal.state.TestInstrumentType.InstrumentTester; +import io.opentelemetry.sdk.metrics.internal.state.TestInstrumentType.TestInstrumentsState; +import java.util.List; +import java.util.Random; + +public class ExplicitBucketHistogramTester implements InstrumentTester { + + static class ExplicitHistogramState implements TestInstrumentsState { + public double maxBucketValue; + DoubleHistogram doubleHistogram; + } + + private static final int measurementsPerAttributeSet = 1_000; + + @Override + public Aggregation testedAggregation() { + return Aggregation.explicitBucketHistogram(); + } + + @Override + public TestInstrumentsState buildInstruments( + double instrumentCount, + SdkMeterProvider sdkMeterProvider, + List attributesList, + Random random) { + ExplicitHistogramState state = new ExplicitHistogramState(); + state.doubleHistogram = + sdkMeterProvider.get("meter").histogramBuilder("test.explicit.histogram").build(); + state.maxBucketValue = + ExplicitBucketHistogramUtils.DEFAULT_HISTOGRAM_BUCKET_BOUNDARIES.get( + ExplicitBucketHistogramUtils.DEFAULT_HISTOGRAM_BUCKET_BOUNDARIES.size() - 1); + return state; + } + + @SuppressWarnings("ForLoopReplaceableByForEach") // This is for GC sensitivity testing: no streams + @Override + public void recordValuesInInstruments( + TestInstrumentsState testInstrumentsState, List attributesList, Random random) { + + ExplicitHistogramState state = (ExplicitHistogramState) testInstrumentsState; + + for (int j = 0; j < attributesList.size(); j++) { + Attributes attributes = attributesList.get(j); + for (int i = 0; i < measurementsPerAttributeSet; i++) { + state.doubleHistogram.record( + random.nextInt(Double.valueOf(state.maxBucketValue * 1.1).intValue()), attributes); + } + } + } +} diff --git a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/aggregator/DoubleExplicitBucketHistogramAggregator.java b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/aggregator/DoubleExplicitBucketHistogramAggregator.java index e011351cd50..40850a8bd97 100644 --- a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/aggregator/DoubleExplicitBucketHistogramAggregator.java +++ b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/aggregator/DoubleExplicitBucketHistogramAggregator.java @@ -8,6 +8,7 @@ import io.opentelemetry.api.common.Attributes; import io.opentelemetry.api.internal.GuardedBy; import io.opentelemetry.sdk.common.InstrumentationScopeInfo; +import io.opentelemetry.sdk.common.export.MemoryMode; import io.opentelemetry.sdk.internal.PrimitiveLongList; import io.opentelemetry.sdk.metrics.data.AggregationTemporality; import io.opentelemetry.sdk.metrics.data.DoubleExemplarData; @@ -16,6 +17,7 @@ import io.opentelemetry.sdk.metrics.internal.data.ImmutableHistogramData; import io.opentelemetry.sdk.metrics.internal.data.ImmutableHistogramPointData; import io.opentelemetry.sdk.metrics.internal.data.ImmutableMetricData; +import io.opentelemetry.sdk.metrics.internal.data.MutableHistogramPointData; import io.opentelemetry.sdk.metrics.internal.descriptor.MetricDescriptor; import io.opentelemetry.sdk.metrics.internal.exemplar.ExemplarReservoir; import io.opentelemetry.sdk.resources.Resource; @@ -26,6 +28,7 @@ import java.util.List; import java.util.concurrent.locks.ReentrantLock; import java.util.function.Supplier; +import javax.annotation.Nullable; /** * Aggregator that generates explicit bucket histograms. @@ -36,6 +39,7 @@ public final class DoubleExplicitBucketHistogramAggregator implements Aggregator { private final double[] boundaries; + private final MemoryMode memoryMode; // a cache for converting to MetricData private final List boundaryList; @@ -47,10 +51,14 @@ public final class DoubleExplicitBucketHistogramAggregator * * @param boundaries Bucket boundaries, in-order. * @param reservoirSupplier Supplier of exemplar reservoirs per-stream. + * @param memoryMode The {@link MemoryMode} to use in this aggregator. */ public DoubleExplicitBucketHistogramAggregator( - double[] boundaries, Supplier> reservoirSupplier) { + double[] boundaries, + Supplier> reservoirSupplier, + MemoryMode memoryMode) { this.boundaries = boundaries; + this.memoryMode = memoryMode; List boundaryList = new ArrayList<>(this.boundaries.length); for (double v : this.boundaries) { @@ -62,7 +70,7 @@ public DoubleExplicitBucketHistogramAggregator( @Override public AggregatorHandle createHandle() { - return new Handle(this.boundaryList, this.boundaries, reservoirSupplier.get()); + return new Handle(this.boundaryList, this.boundaries, reservoirSupplier.get(), memoryMode); } @Override @@ -104,10 +112,14 @@ static final class Handle extends AggregatorHandle boundaryList, double[] boundaries, - ExemplarReservoir reservoir) { + ExemplarReservoir reservoir, + MemoryMode memoryMode) { super(reservoir); this.boundaryList = boundaryList; this.boundaries = boundaries; @@ -116,6 +128,9 @@ static final class Handle extends AggregatorHandle 0, - this.min, - this.count > 0, - this.max, - boundaryList, - PrimitiveLongList.wrap(Arrays.copyOf(counts, counts.length)), - exemplars); + HistogramPointData pointData; + if (reusablePoint == null) { + pointData = + ImmutableHistogramPointData.create( + startEpochNanos, + epochNanos, + attributes, + sum, + this.count > 0, + this.min, + this.count > 0, + this.max, + boundaryList, + PrimitiveLongList.wrap(Arrays.copyOf(counts, counts.length)), + exemplars); + } else /* REUSABLE_DATA */ { + pointData = + reusablePoint.set( + startEpochNanos, + epochNanos, + attributes, + sum, + this.count > 0, + this.min, + this.count > 0, + this.max, + boundaryList, + counts, + exemplars); + } if (reset) { this.sum = 0; this.min = Double.MAX_VALUE; diff --git a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/data/HistogramPointDataValidations.java b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/data/HistogramPointDataValidations.java new file mode 100644 index 00000000000..02534dd138f --- /dev/null +++ b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/data/HistogramPointDataValidations.java @@ -0,0 +1,35 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.sdk.metrics.internal.data; + +import io.opentelemetry.sdk.metrics.data.HistogramPointData; +import java.util.List; + +/** + * Validations for {@link HistogramPointData}. + * + *

    This class is internal and is hence not for public use. Its APIs are unstable and can change + * at any time. + */ +final class HistogramPointDataValidations { + + private HistogramPointDataValidations() {} + + static void validateIsStrictlyIncreasing(List xs) { + for (int i = 0; i < xs.size() - 1; i++) { + if (xs.get(i).compareTo(xs.get(i + 1)) >= 0) { + throw new IllegalArgumentException("invalid boundaries: " + xs); + } + } + } + + static void validateFiniteBoundaries(List boundaries) { + if (!boundaries.isEmpty() + && (boundaries.get(0).isInfinite() || boundaries.get(boundaries.size() - 1).isInfinite())) { + throw new IllegalArgumentException("invalid boundaries: contains explicit +/-Inf"); + } + } +} diff --git a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/data/ImmutableHistogramPointData.java b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/data/ImmutableHistogramPointData.java index 1a07c708983..49b56b7d780 100644 --- a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/data/ImmutableHistogramPointData.java +++ b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/data/ImmutableHistogramPointData.java @@ -5,6 +5,9 @@ package io.opentelemetry.sdk.metrics.internal.data; +import static io.opentelemetry.sdk.metrics.internal.data.HistogramPointDataValidations.validateFiniteBoundaries; +import static io.opentelemetry.sdk.metrics.internal.data.HistogramPointDataValidations.validateIsStrictlyIncreasing; + import com.google.auto.value.AutoValue; import io.opentelemetry.api.common.Attributes; import io.opentelemetry.sdk.internal.PrimitiveLongList; @@ -85,13 +88,8 @@ public static ImmutableHistogramPointData create( + " instead of " + counts.size()); } - if (!isStrictlyIncreasing(boundaries)) { - throw new IllegalArgumentException("invalid boundaries: " + boundaries); - } - if (!boundaries.isEmpty() - && (boundaries.get(0).isInfinite() || boundaries.get(boundaries.size() - 1).isInfinite())) { - throw new IllegalArgumentException("invalid boundaries: contains explicit +/-Inf"); - } + validateIsStrictlyIncreasing(boundaries); + validateFiniteBoundaries(boundaries); long totalCount = 0; for (long c : PrimitiveLongList.toArray(counts)) { @@ -113,13 +111,4 @@ public static ImmutableHistogramPointData create( } ImmutableHistogramPointData() {} - - private static boolean isStrictlyIncreasing(List xs) { - for (int i = 0; i < xs.size() - 1; i++) { - if (xs.get(i).compareTo(xs.get(i + 1)) >= 0) { - return false; - } - } - return true; - } } diff --git a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/data/MutableHistogramPointData.java b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/data/MutableHistogramPointData.java new file mode 100644 index 00000000000..3c6e65c799c --- /dev/null +++ b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/data/MutableHistogramPointData.java @@ -0,0 +1,249 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.sdk.metrics.internal.data; + +import static io.opentelemetry.sdk.metrics.internal.data.HistogramPointDataValidations.validateFiniteBoundaries; +import static io.opentelemetry.sdk.metrics.internal.data.HistogramPointDataValidations.validateIsStrictlyIncreasing; + +import io.opentelemetry.api.common.Attributes; +import io.opentelemetry.sdk.internal.DynamicPrimitiveLongList; +import io.opentelemetry.sdk.metrics.data.DoubleExemplarData; +import io.opentelemetry.sdk.metrics.data.HistogramPointData; +import java.util.Collections; +import java.util.List; + +/** + * A mutable {@link HistogramPointData} + * + *

    This class is internal and is hence not for public use. Its APIs are unstable and can change + * at any time. + * + *

    This class is not thread-safe. + */ +public final class MutableHistogramPointData implements HistogramPointData { + private long startEpochNanos; + private long epochNanos; + private Attributes attributes = Attributes.empty(); + private double sum; + private long count; + private boolean hasMin; + private double min; + private boolean hasMax; + private double max; + private List boundaries = Collections.emptyList(); + private final DynamicPrimitiveLongList counts; + private List exemplars = Collections.emptyList(); + + public MutableHistogramPointData(int buckets) { + this.counts = DynamicPrimitiveLongList.ofSubArrayCapacity(buckets); + this.counts.resizeAndClear(buckets); + } + + @SuppressWarnings({"TooManyParameters", "ForLoopReplaceableByForEach"}) + public MutableHistogramPointData set( + long startEpochNanos, + long epochNanos, + Attributes attributes, + double sum, + boolean hasMin, + double min, + boolean hasMax, + double max, + List boundaries, + long[] counts, + List exemplars) { + + if (this.counts.size() != boundaries.size() + 1) { + throw new IllegalArgumentException( + "invalid boundaries: size should be " + + (this.counts.size() - 1) + + " but was " + + boundaries.size()); + } + if (this.counts.size() != counts.length) { + throw new IllegalArgumentException( + "invalid counts: size should be " + this.counts.size() + " but was " + counts.length); + } + validateIsStrictlyIncreasing(boundaries); + validateFiniteBoundaries(boundaries); + + long totalCount = 0; + for (int i = 0; i < counts.length; i++) { + totalCount += counts[i]; + } + + this.startEpochNanos = startEpochNanos; + this.epochNanos = epochNanos; + this.attributes = attributes; + this.sum = sum; + this.count = totalCount; + this.hasMin = hasMin; + this.min = min; + this.hasMax = hasMax; + this.max = max; + this.boundaries = boundaries; + for (int i = 0; i < counts.length; i++) { + this.counts.setLong(i, counts[i]); + } + this.exemplars = exemplars; + + return this; + } + + @Override + public long getStartEpochNanos() { + return startEpochNanos; + } + + @Override + public long getEpochNanos() { + return epochNanos; + } + + @Override + public Attributes getAttributes() { + return attributes; + } + + @Override + public double getSum() { + return sum; + } + + @Override + public long getCount() { + return count; + } + + @Override + public boolean hasMin() { + return hasMin; + } + + @Override + public double getMin() { + return min; + } + + @Override + public boolean hasMax() { + return hasMax; + } + + @Override + public double getMax() { + return max; + } + + @Override + public List getBoundaries() { + return boundaries; + } + + @Override + public List getCounts() { + return counts; + } + + @Override + public List getExemplars() { + return exemplars; + } + + @Override + public String toString() { + return "MutableHistogramPointData{" + + "startEpochNanos=" + + startEpochNanos + + ", " + + "epochNanos=" + + epochNanos + + ", " + + "attributes=" + + attributes + + ", " + + "sum=" + + sum + + ", " + + "count=" + + count + + ", " + + "hasMin=" + + hasMin + + ", " + + "min=" + + min + + ", " + + "hasMax=" + + hasMax + + ", " + + "max=" + + max + + ", " + + "boundaries=" + + boundaries + + ", " + + "counts=" + + counts + + ", " + + "exemplars=" + + exemplars + + "}"; + } + + @Override + public boolean equals(Object o) { + if (o == this) { + return true; + } + if (o instanceof HistogramPointData) { + HistogramPointData that = (HistogramPointData) o; + return this.startEpochNanos == that.getStartEpochNanos() + && this.epochNanos == that.getEpochNanos() + && this.attributes.equals(that.getAttributes()) + && Double.doubleToLongBits(this.sum) == Double.doubleToLongBits(that.getSum()) + && this.count == that.getCount() + && this.hasMin == that.hasMin() + && Double.doubleToLongBits(this.min) == Double.doubleToLongBits(that.getMin()) + && this.hasMax == that.hasMax() + && Double.doubleToLongBits(this.max) == Double.doubleToLongBits(that.getMax()) + && this.boundaries.equals(that.getBoundaries()) + && this.counts.equals(that.getCounts()) + && this.exemplars.equals(that.getExemplars()); + } + return false; + } + + @Override + public int hashCode() { + int hashcode = 1; + hashcode *= 1000003; + hashcode ^= (int) ((startEpochNanos >>> 32) ^ startEpochNanos); + hashcode *= 1000003; + hashcode ^= (int) ((epochNanos >>> 32) ^ epochNanos); + hashcode *= 1000003; + hashcode ^= attributes.hashCode(); + hashcode *= 1000003; + hashcode ^= (int) ((Double.doubleToLongBits(sum) >>> 32) ^ Double.doubleToLongBits(sum)); + hashcode *= 1000003; + hashcode ^= (int) ((count >>> 32) ^ count); + hashcode *= 1000003; + hashcode ^= hasMin ? 1231 : 1237; + hashcode *= 1000003; + hashcode ^= (int) ((Double.doubleToLongBits(min) >>> 32) ^ Double.doubleToLongBits(min)); + hashcode *= 1000003; + hashcode ^= hasMax ? 1231 : 1237; + hashcode *= 1000003; + hashcode ^= (int) ((Double.doubleToLongBits(max) >>> 32) ^ Double.doubleToLongBits(max)); + hashcode *= 1000003; + hashcode ^= boundaries.hashCode(); + hashcode *= 1000003; + hashcode ^= counts.hashCode(); + hashcode *= 1000003; + hashcode ^= exemplars.hashCode(); + return hashcode; + } +} diff --git a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/view/ExplicitBucketHistogramAggregation.java b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/view/ExplicitBucketHistogramAggregation.java index 3d87878efa4..e452d02792d 100644 --- a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/view/ExplicitBucketHistogramAggregation.java +++ b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/view/ExplicitBucketHistogramAggregation.java @@ -62,7 +62,8 @@ public Aggregator createAggr exemplarFilter, ExemplarReservoir.longToDouble( ExemplarReservoir.histogramBucketReservoir( - Clock.getDefault(), bucketBoundaries)))); + Clock.getDefault(), bucketBoundaries))), + memoryMode); } @Override diff --git a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/view/package-info.java b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/view/package-info.java new file mode 100644 index 00000000000..2cd6165107b --- /dev/null +++ b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/view/package-info.java @@ -0,0 +1,10 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +/** View related internal classes. */ +@ParametersAreNonnullByDefault +package io.opentelemetry.sdk.metrics.internal.view; + +import javax.annotation.ParametersAreNonnullByDefault; diff --git a/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/internal/aggregator/DoubleExplicitBucketHistogramAggregatorTest.java b/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/internal/aggregator/DoubleExplicitBucketHistogramAggregatorTest.java index 440e70b3970..f10787c7197 100644 --- a/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/internal/aggregator/DoubleExplicitBucketHistogramAggregatorTest.java +++ b/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/internal/aggregator/DoubleExplicitBucketHistogramAggregatorTest.java @@ -14,6 +14,7 @@ import io.opentelemetry.api.trace.TraceState; import io.opentelemetry.context.Context; import io.opentelemetry.sdk.common.InstrumentationScopeInfo; +import io.opentelemetry.sdk.common.export.MemoryMode; import io.opentelemetry.sdk.metrics.data.AggregationTemporality; import io.opentelemetry.sdk.metrics.data.DoubleExemplarData; import io.opentelemetry.sdk.metrics.data.HistogramPointData; @@ -21,6 +22,7 @@ import io.opentelemetry.sdk.metrics.data.MetricDataType; import io.opentelemetry.sdk.metrics.internal.data.ImmutableDoubleExemplarData; import io.opentelemetry.sdk.metrics.internal.data.ImmutableHistogramPointData; +import io.opentelemetry.sdk.metrics.internal.data.MutableHistogramPointData; import io.opentelemetry.sdk.metrics.internal.descriptor.MetricDescriptor; import io.opentelemetry.sdk.metrics.internal.exemplar.ExemplarReservoir; import io.opentelemetry.sdk.resources.Resource; @@ -34,6 +36,8 @@ import java.util.stream.DoubleStream; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.EnumSource; import org.mockito.Mock; import org.mockito.Mockito; import org.mockito.junit.jupiter.MockitoExtension; @@ -51,17 +55,26 @@ class DoubleExplicitBucketHistogramAggregatorTest { InstrumentationScopeInfo.empty(); private static final MetricDescriptor METRIC_DESCRIPTOR = MetricDescriptor.create("name", "description", "unit"); - private static final DoubleExplicitBucketHistogramAggregator aggregator = - new DoubleExplicitBucketHistogramAggregator(boundaries, ExemplarReservoir::doubleNoSamples); + private DoubleExplicitBucketHistogramAggregator aggregator; - @Test - void createHandle() { + private void init(MemoryMode memoryMode) { + aggregator = + new DoubleExplicitBucketHistogramAggregator( + boundaries, ExemplarReservoir::doubleNoSamples, memoryMode); + } + + @ParameterizedTest + @EnumSource(MemoryMode.class) + void createHandle(MemoryMode memoryMode) { + init(memoryMode); assertThat(aggregator.createHandle()) .isInstanceOf(DoubleExplicitBucketHistogramAggregator.Handle.class); } - @Test - void testRecordings() { + @ParameterizedTest + @EnumSource(MemoryMode.class) + void testRecordings(MemoryMode memoryMode) { + init(memoryMode); AggregatorHandle aggregatorHandle = aggregator.createHandle(); aggregatorHandle.recordLong(20); @@ -84,8 +97,9 @@ void testRecordings() { Arrays.asList(1L, 1L, 1L, 1L))); } - @Test - void aggregateThenMaybeReset_WithExemplars() { + @ParameterizedTest + @EnumSource(MemoryMode.class) + void aggregateThenMaybeReset_WithExemplars(MemoryMode memoryMode) { Attributes attributes = Attributes.builder().put("test", "value").build(); DoubleExemplarData exemplar = ImmutableDoubleExemplarData.create( @@ -100,7 +114,7 @@ void aggregateThenMaybeReset_WithExemplars() { List exemplars = Collections.singletonList(exemplar); Mockito.when(reservoir.collectAndReset(Attributes.empty())).thenReturn(exemplars); DoubleExplicitBucketHistogramAggregator aggregator = - new DoubleExplicitBucketHistogramAggregator(boundaries, () -> reservoir); + new DoubleExplicitBucketHistogramAggregator(boundaries, () -> reservoir, memoryMode); AggregatorHandle aggregatorHandle = aggregator.createHandle(); aggregatorHandle.recordDouble(0, attributes, Context.root()); @@ -121,8 +135,10 @@ void aggregateThenMaybeReset_WithExemplars() { exemplars)); } - @Test - void aggregateThenMaybeReset() { + @ParameterizedTest + @EnumSource(MemoryMode.class) + void aggregateThenMaybeReset(MemoryMode memoryMode) { + init(memoryMode); AggregatorHandle aggregatorHandle = aggregator.createHandle(); @@ -159,8 +175,10 @@ void aggregateThenMaybeReset() { Arrays.asList(1L, 0L, 0L, 0L))); } - @Test - void toMetricData() { + @ParameterizedTest + @EnumSource(MemoryMode.class) + void toMetricData(MemoryMode memoryMode) { + init(memoryMode); AggregatorHandle aggregatorHandle = aggregator.createHandle(); aggregatorHandle.recordLong(10); @@ -180,8 +198,10 @@ void toMetricData() { .isEqualTo(AggregationTemporality.DELTA); } - @Test - void toMetricDataWithExemplars() { + @ParameterizedTest + @EnumSource(MemoryMode.class) + void toMetricDataWithExemplars(MemoryMode memoryMode) { + init(memoryMode); Attributes attributes = Attributes.builder().put("test", "value").build(); DoubleExemplarData exemplar = ImmutableDoubleExemplarData.create( @@ -226,8 +246,10 @@ void toMetricDataWithExemplars() { .hasExemplars(exemplar))); } - @Test - void testHistogramCounts() { + @ParameterizedTest + @EnumSource(MemoryMode.class) + void testHistogramCounts(MemoryMode memoryMode) { + init(memoryMode); AggregatorHandle aggregatorHandle = aggregator.createHandle(); aggregatorHandle.recordDouble(1.1); @@ -237,8 +259,10 @@ void testHistogramCounts() { assertThat(point.getCounts().size()).isEqualTo(boundaries.length + 1); } - @Test - void testMultithreadedUpdates() throws InterruptedException { + @ParameterizedTest + @EnumSource(MemoryMode.class) + void testMultithreadedUpdates(MemoryMode memoryMode) throws InterruptedException { + init(memoryMode); AggregatorHandle aggregatorHandle = aggregator.createHandle(); ImmutableList updates = ImmutableList.of(1L, 2L, 3L, 5L, 7L, 11L, 13L, 17L, 19L, 23L); @@ -278,4 +302,28 @@ void testMultithreadedUpdates() throws InterruptedException { boundariesList, Arrays.asList(50000L, 50000L, 0L, 0L))); } + + @Test + void testReusableDataMemoryMode() { + init(MemoryMode.REUSABLE_DATA); + AggregatorHandle aggregatorHandle = + aggregator.createHandle(); + aggregatorHandle.recordLong(10); + aggregatorHandle.recordLong(20); + aggregatorHandle.recordLong(30); + aggregatorHandle.recordLong(40); + + HistogramPointData pointData = + aggregatorHandle.aggregateThenMaybeReset(0, 1, Attributes.empty(), /* reset= */ false); + assertThat(pointData).isExactlyInstanceOf(MutableHistogramPointData.class); + + aggregatorHandle.recordLong(10); + aggregatorHandle.recordLong(20); + + HistogramPointData anotherPointData = + aggregatorHandle.aggregateThenMaybeReset(0, 1, Attributes.empty(), /* reset= */ false); + + // The point data instance should be reused + assertThat(anotherPointData).isSameAs(pointData); + } } diff --git a/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/internal/data/MutableHistogramPointDataTest.java b/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/internal/data/MutableHistogramPointDataTest.java new file mode 100644 index 00000000000..1a8e4d1e0b1 --- /dev/null +++ b/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/internal/data/MutableHistogramPointDataTest.java @@ -0,0 +1,165 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.sdk.metrics.internal.data; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.AssertionsForClassTypes.assertThatThrownBy; + +import io.opentelemetry.api.common.AttributeKey; +import io.opentelemetry.api.common.Attributes; +import java.util.Arrays; +import java.util.Collections; +import org.junit.jupiter.api.Test; + +public class MutableHistogramPointDataTest { + + @Test + void testSanity() { + MutableHistogramPointData pointData = new MutableHistogramPointData(10); + assertThat(pointData.getSum()).isEqualTo(0); + assertThat(pointData.getCount()).isEqualTo(0); + assertThat(pointData.getBoundaries()).isEmpty(); + assertThat(pointData.getCounts().size()).isEqualTo(10); + assertThat(pointData.getExemplars()).isEmpty(); + + pointData.set( + /* startEpochNanos= */ 10, + /* epochNanos= */ 20, + Attributes.of(AttributeKey.stringKey("foo"), "bar"), + /* sum= */ 2, + /* hasMin= */ true, + /* min= */ 100, + /* hasMax= */ true, + /* max= */ 1000, + /* boundaries= */ Arrays.asList(1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0), + /* counts= */ new long[] {10, 20, 30, 40, 50, 60, 70, 80, 90, 100}, + Collections.emptyList()); + + assertThat(pointData.getSum()).isEqualTo(2); + assertThat(pointData.getCount()).isEqualTo(10 + 20 + 30 + 40 + 50 + 60 + 70 + 80 + 90 + 100); + assertThat(pointData.getAttributes().get(AttributeKey.stringKey("foo"))).isEqualTo("bar"); + assertThat(pointData.getAttributes().size()).isEqualTo(1); + assertThat(pointData.getBoundaries()) + .containsExactly(1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0); + assertThat(pointData.getCounts().toArray()) + .containsExactly(10L, 20L, 30L, 40L, 50L, 60L, 70L, 80L, 90L, 100L); + assertThat(pointData.getStartEpochNanos()).isEqualTo(10); + assertThat(pointData.getEpochNanos()).isEqualTo(20); + + assertThat(pointData.hasMin()).isTrue(); + assertThat(pointData.getMin()).isEqualTo(100); + assertThat(pointData.hasMax()).isTrue(); + assertThat(pointData.getMax()).isEqualTo(1000); + assertThat(pointData.getExemplars()).isEmpty(); + assertThat(pointData.toString()) + .isEqualTo( + "MutableHistogramPointData{startEpochNanos=10, " + + "epochNanos=20, " + + "attributes={foo=\"bar\"}, " + + "sum=2.0, " + + "count=550, " + + "hasMin=true, " + + "min=100.0, " + + "hasMax=true, " + + "max=1000.0, " + + "boundaries=[1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0], " + + "counts=[10, 20, 30, 40, 50, 60, 70, 80, 90, 100], " + + "exemplars=[]}"); + + MutableHistogramPointData anotherPointData = new MutableHistogramPointData(10); + // Same values + anotherPointData.set( + /* startEpochNanos= */ 10, + /* epochNanos= */ 20, + Attributes.of(AttributeKey.stringKey("foo"), "bar"), + /* sum= */ 2, + /* hasMin= */ true, + /* min= */ 100, + /* hasMax= */ true, + /* max= */ 1000, + /* boundaries= */ Arrays.asList(1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0), + /* counts= */ new long[] {10, 20, 30, 40, 50, 60, 70, 80, 90, 100}, + Collections.emptyList()); + assertThat(anotherPointData).isEqualTo(pointData); + assertThat(anotherPointData.hashCode()).isEqualTo(pointData.hashCode()); + + // Same values but different sum + anotherPointData.set( + /* startEpochNanos= */ 10, + /* epochNanos= */ 20, + Attributes.of(AttributeKey.stringKey("foo"), "bar"), + /* sum= */ 20000, + /* hasMin= */ true, + /* min= */ 100, + /* hasMax= */ true, + /* max= */ 1000, + /* boundaries= */ Arrays.asList(1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0), + /* counts= */ new long[] {10, 20, 30, 40, 50, 60, 70, 80, 90, 100}, + Collections.emptyList()); + assertThat(anotherPointData).isNotEqualTo(pointData); + assertThat(anotherPointData.hashCode()).isNotEqualTo(pointData.hashCode()); + } + + @Test() + void testBoundaries() { + MutableHistogramPointData pointData = new MutableHistogramPointData(10); + assertThatThrownBy( + () -> + pointData.set( + /* startEpochNanos= */ 10, + /* epochNanos= */ 20, + Attributes.of(AttributeKey.stringKey("foo"), "bar"), + /* sum= */ 2, + /* hasMin= */ true, + /* min= */ 100, + /* hasMax= */ true, + /* max= */ 1000, + /* boundaries= */ Arrays.asList(1.0, 2.0, 3.0, 4.0), + /* counts= */ new long[] {10, 20, 30, 40, 50, 60, 70, 80, 90, 100}, + Collections.emptyList())) + .isInstanceOf(IllegalArgumentException.class) + .hasMessage("invalid boundaries: size should be 9 but was 4"); + + assertThatThrownBy( + () -> + pointData.set( + /* startEpochNanos= */ 10, + /* epochNanos= */ 20, + Attributes.of(AttributeKey.stringKey("foo"), "bar"), + /* sum= */ 2, + /* hasMin= */ true, + /* min= */ 100, + /* hasMax= */ true, + /* max= */ 1000, + /* boundaries= */ Arrays.asList( + 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, Double.POSITIVE_INFINITY), + /* counts= */ new long[] {10, 20, 30, 40, 50, 60, 70, 80, 90, 100}, + Collections.emptyList())) + .isInstanceOf(IllegalArgumentException.class) + .hasMessage("invalid boundaries: contains explicit +/-Inf"); + } + + @Test + void testCounts() { + MutableHistogramPointData pointData = new MutableHistogramPointData(10); + assertThatThrownBy( + () -> + pointData.set( + /* startEpochNanos= */ 10, + /* epochNanos= */ 20, + Attributes.of(AttributeKey.stringKey("foo"), "bar"), + /* sum= */ 2, + /* hasMin= */ true, + /* min= */ 100, + /* hasMax= */ true, + /* max= */ 1000, + /* boundaries= */ Arrays.asList(1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0), + /* counts= */ new long[] {10, 20, 30, 40, 50, 60}, + Collections.emptyList())) + .isInstanceOf(IllegalArgumentException.class) + .hasMessage("invalid counts: size should be 10 but was 6"); + } +} From c8a968a99b1f8a3dc71ce0be17b9749a3c9176ec Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 25 Jan 2024 17:36:09 -0600 Subject: [PATCH 214/901] Update dependency org.testcontainers:testcontainers-bom to v1.19.4 (#6174) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- dependencyManagement/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index f85dbbb5681..33a8e0283c4 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -20,7 +20,7 @@ val DEPENDENCY_BOMS = listOf( "io.zipkin.reporter2:zipkin-reporter-bom:3.2.1", "org.assertj:assertj-bom:3.25.1", "org.junit:junit-bom:5.10.1", - "org.testcontainers:testcontainers-bom:1.19.3", + "org.testcontainers:testcontainers-bom:1.19.4", "org.snakeyaml:snakeyaml-engine:2.7" ) From 91a5dd9e8a347455423b9cc672d4653e95792b2b Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 25 Jan 2024 17:36:21 -0600 Subject: [PATCH 215/901] Update dependency org.assertj:assertj-bom to v3.25.2 (#6172) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- dependencyManagement/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index 33a8e0283c4..a795ce2033a 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -18,7 +18,7 @@ val DEPENDENCY_BOMS = listOf( "io.netty:netty-bom:4.1.106.Final", "io.zipkin.brave:brave-bom:6.0.0", "io.zipkin.reporter2:zipkin-reporter-bom:3.2.1", - "org.assertj:assertj-bom:3.25.1", + "org.assertj:assertj-bom:3.25.2", "org.junit:junit-bom:5.10.1", "org.testcontainers:testcontainers-bom:1.19.4", "org.snakeyaml:snakeyaml-engine:2.7" From 4657255d7b63dce9aa96aa6bf23b8e62df254edf Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 26 Jan 2024 10:08:24 -0600 Subject: [PATCH 216/901] Update spotless packages to v6.25.0 (#6169) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- buildSrc/build.gradle.kts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts index 58d58bf22fc..fc87bebf13b 100644 --- a/buildSrc/build.gradle.kts +++ b/buildSrc/build.gradle.kts @@ -2,7 +2,7 @@ plugins { `kotlin-dsl` // When updating, update below in dependencies too - id("com.diffplug.spotless") version "6.24.0" + id("com.diffplug.spotless") version "6.25.0" } if (!JavaVersion.current().isCompatibleWith(JavaVersion.VERSION_17)) { @@ -45,7 +45,7 @@ dependencies { implementation(enforcedPlatform("com.squareup.wire:wire-bom:4.9.3")) implementation("com.google.auto.value:auto-value-annotations:1.10.4") // When updating, update above in plugins too - implementation("com.diffplug.spotless:spotless-plugin-gradle:6.24.0") + implementation("com.diffplug.spotless:spotless-plugin-gradle:6.25.0") // Needed for japicmp but not automatically brought in for some reason. implementation("com.google.guava:guava:33.0.0-jre") implementation("com.squareup:javapoet:1.13.0") From 4a66431280b1749f39efdac4edbc801f7f1b3405 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 26 Jan 2024 10:42:03 -0600 Subject: [PATCH 217/901] Update dependency com.google.api.grpc:proto-google-common-protos to v2.32.0 (#6165) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- dependencyManagement/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index a795ce2033a..cd4df145817 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -55,7 +55,7 @@ val DEPENDENCIES = listOf( "io.prometheus:simpleclient_httpserver:${prometheusClientVersion}", "javax.annotation:javax.annotation-api:1.3.2", "com.github.stefanbirkner:system-rules:1.19.0", - "com.google.api.grpc:proto-google-common-protos:2.30.0", + "com.google.api.grpc:proto-google-common-protos:2.32.0", "com.google.code.findbugs:jsr305:3.0.2", "com.google.guava:guava-beta-checker:1.0", "com.sun.net.httpserver:http:20070405", From 90e2fb4e38a936400c80d6f0026afacf597169bb Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 26 Jan 2024 10:42:21 -0600 Subject: [PATCH 218/901] Update dependency com.squareup.wire:wire-bom to v4.9.4 (#6176) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- buildSrc/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts index fc87bebf13b..dc767a75152 100644 --- a/buildSrc/build.gradle.kts +++ b/buildSrc/build.gradle.kts @@ -42,7 +42,7 @@ repositories { } dependencies { - implementation(enforcedPlatform("com.squareup.wire:wire-bom:4.9.3")) + implementation(enforcedPlatform("com.squareup.wire:wire-bom:4.9.4")) implementation("com.google.auto.value:auto-value-annotations:1.10.4") // When updating, update above in plugins too implementation("com.diffplug.spotless:spotless-plugin-gradle:6.25.0") From f123d789097d714ed94f76d98e87985067a7b301 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 26 Jan 2024 10:57:54 -0600 Subject: [PATCH 219/901] Update plugin com.gradle.enterprise to v3.16.2 (#6175) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- settings.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/settings.gradle.kts b/settings.gradle.kts index e54353813b3..1b0892e1a76 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -1,7 +1,7 @@ pluginManagement { plugins { id("com.github.johnrengelman.shadow") version "8.1.1" - id("com.gradle.enterprise") version "3.16.1" + id("com.gradle.enterprise") version "3.16.2" id("de.undercouch.download") version "5.5.0" id("org.jsonschema2pojo") version "1.2.1" id("io.github.gradle-nexus.publish-plugin") version "1.3.0" From 196905916c539c375023f2e85efef12e128c2274 Mon Sep 17 00:00:00 2001 From: jason plumb <75337021+breedx-splk@users.noreply.github.com> Date: Wed, 31 Jan 2024 07:45:28 -0800 Subject: [PATCH 220/901] Include trace flags in otlp marshaller (#6167) --- dependencyManagement/build.gradle.kts | 2 +- .../internal/marshal/MarshalerUtil.java | 5 +++ .../exporter/internal/marshal/Serializer.java | 8 ++++ .../internal/otlp/logs/LogMarshaler.java | 9 +---- .../otlp/traces/SpanLinkMarshaler.java | 15 +++++++- .../internal/otlp/traces/SpanMarshaler.java | 17 +++++++-- .../traces/TraceRequestMarshalerTest.java | 38 +++++++++++-------- 7 files changed, 65 insertions(+), 29 deletions(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index cd4df145817..2a25afbe09a 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -65,7 +65,7 @@ val DEPENDENCIES = listOf( "eu.rekawek.toxiproxy:toxiproxy-java:2.1.7", "io.github.netmikey.logunit:logunit-jul:2.0.0", "io.jaegertracing:jaeger-client:1.8.1", - "io.opentelemetry.proto:opentelemetry-proto:1.0.0-alpha", + "io.opentelemetry.proto:opentelemetry-proto:1.1.0-alpha", "io.opentelemetry.contrib:opentelemetry-aws-xray-propagator:1.29.0-alpha", "io.opentracing:opentracing-api:0.33.0", "io.opentracing:opentracing-noop:0.33.0", diff --git a/exporters/common/src/main/java/io/opentelemetry/exporter/internal/marshal/MarshalerUtil.java b/exporters/common/src/main/java/io/opentelemetry/exporter/internal/marshal/MarshalerUtil.java index 39f0584f4e4..5abd24925a5 100644 --- a/exporters/common/src/main/java/io/opentelemetry/exporter/internal/marshal/MarshalerUtil.java +++ b/exporters/common/src/main/java/io/opentelemetry/exporter/internal/marshal/MarshalerUtil.java @@ -257,6 +257,11 @@ public static int sizeFixed64Optional(ProtoFieldInfo field, long value) { return field.getTagSize() + CodedOutputStream.computeFixed64SizeNoTag(value); } + /** Returns the size of a byte field when propagated to a fixed32. */ + public static int sizeByteAsFixed32(ProtoFieldInfo field, byte message) { + return sizeFixed32(field, ((int) message) & 0xff); + } + /** Returns the size of a fixed32 field. */ public static int sizeFixed32(ProtoFieldInfo field, int message) { if (message == 0L) { diff --git a/exporters/common/src/main/java/io/opentelemetry/exporter/internal/marshal/Serializer.java b/exporters/common/src/main/java/io/opentelemetry/exporter/internal/marshal/Serializer.java index 7382c2cfac6..ba182316add 100644 --- a/exporters/common/src/main/java/io/opentelemetry/exporter/internal/marshal/Serializer.java +++ b/exporters/common/src/main/java/io/opentelemetry/exporter/internal/marshal/Serializer.java @@ -128,6 +128,14 @@ public void serializeFixed64Optional(ProtoFieldInfo field, long value) throws IO protected abstract void writeUInt64Value(long value) throws IOException; + /** + * Serializes a byte as a protobuf {@code fixed32} field. Ensures that there is no sign + * propagation if the high bit in the byte is set. + */ + public void serializeByteAsFixed32(ProtoFieldInfo field, byte value) throws IOException { + serializeFixed32(field, ((int) value) & 0xff); + } + /** Serializes a protobuf {@code fixed32} field. */ public void serializeFixed32(ProtoFieldInfo field, int value) throws IOException { if (value == 0) { diff --git a/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/logs/LogMarshaler.java b/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/logs/LogMarshaler.java index 863b27b6442..911cadf2d84 100644 --- a/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/logs/LogMarshaler.java +++ b/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/logs/LogMarshaler.java @@ -125,7 +125,7 @@ protected void writeTo(Serializer output) throws IOException { output.serializeRepeatedMessage(LogRecord.ATTRIBUTES, attributeMarshalers); output.serializeUInt32(LogRecord.DROPPED_ATTRIBUTES_COUNT, droppedAttributesCount); - output.serializeFixed32(LogRecord.FLAGS, toUnsignedInt(traceFlags.asByte())); + output.serializeByteAsFixed32(LogRecord.FLAGS, traceFlags.asByte()); output.serializeTraceId(LogRecord.TRACE_ID, traceId); output.serializeSpanId(LogRecord.SPAN_ID, spanId); } @@ -155,7 +155,7 @@ private static int calculateSize( size += MarshalerUtil.sizeRepeatedMessage(LogRecord.ATTRIBUTES, attributeMarshalers); size += MarshalerUtil.sizeUInt32(LogRecord.DROPPED_ATTRIBUTES_COUNT, droppedAttributesCount); - size += MarshalerUtil.sizeFixed32(LogRecord.FLAGS, toUnsignedInt(traceFlags.asByte())); + size += MarshalerUtil.sizeByteAsFixed32(LogRecord.FLAGS, traceFlags.asByte()); size += MarshalerUtil.sizeTraceId(LogRecord.TRACE_ID, traceId); size += MarshalerUtil.sizeSpanId(LogRecord.SPAN_ID, spanId); return size; @@ -218,9 +218,4 @@ static ProtoEnumInfo toProtoSeverityNumber(Severity severity) { // NB: Should not be possible with aligned versions. return SeverityNumber.SEVERITY_NUMBER_UNSPECIFIED; } - - /** Vendored {@link Byte#toUnsignedInt(byte)} to support Android. */ - private static int toUnsignedInt(byte x) { - return ((int) x) & 0xff; - } } diff --git a/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/traces/SpanLinkMarshaler.java b/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/traces/SpanLinkMarshaler.java index 6f08b257dce..6adcac370e1 100644 --- a/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/traces/SpanLinkMarshaler.java +++ b/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/traces/SpanLinkMarshaler.java @@ -7,6 +7,7 @@ import static io.opentelemetry.api.trace.propagation.internal.W3CTraceContextEncoding.encodeTraceState; +import io.opentelemetry.api.trace.TraceFlags; import io.opentelemetry.api.trace.TraceState; import io.opentelemetry.exporter.internal.marshal.MarshalerUtil; import io.opentelemetry.exporter.internal.marshal.MarshalerWithSize; @@ -26,6 +27,7 @@ final class SpanLinkMarshaler extends MarshalerWithSize { private final byte[] traceStateUtf8; private final KeyValueMarshaler[] attributeMarshalers; private final int droppedAttributesCount; + private final TraceFlags traceFlags; static SpanLinkMarshaler[] createRepeated(List links) { if (links.isEmpty()) { @@ -51,6 +53,7 @@ static SpanLinkMarshaler create(LinkData link) { return new SpanLinkMarshaler( link.getSpanContext().getTraceId(), link.getSpanContext().getSpanId(), + link.getSpanContext().getTraceFlags(), traceStateUtf8, KeyValueMarshaler.createForAttributes(link.getAttributes()), link.getTotalAttributeCount() - link.getAttributes().size()); @@ -59,14 +62,21 @@ static SpanLinkMarshaler create(LinkData link) { private SpanLinkMarshaler( String traceId, String spanId, + TraceFlags traceFlags, byte[] traceStateUtf8, KeyValueMarshaler[] attributeMarshalers, int droppedAttributesCount) { super( calculateSize( - traceId, spanId, traceStateUtf8, attributeMarshalers, droppedAttributesCount)); + traceId, + spanId, + traceFlags, + traceStateUtf8, + attributeMarshalers, + droppedAttributesCount)); this.traceId = traceId; this.spanId = spanId; + this.traceFlags = traceFlags; this.traceStateUtf8 = traceStateUtf8; this.attributeMarshalers = attributeMarshalers; this.droppedAttributesCount = droppedAttributesCount; @@ -79,11 +89,13 @@ public void writeTo(Serializer output) throws IOException { output.serializeString(Span.Link.TRACE_STATE, traceStateUtf8); output.serializeRepeatedMessage(Span.Link.ATTRIBUTES, attributeMarshalers); output.serializeUInt32(Span.Link.DROPPED_ATTRIBUTES_COUNT, droppedAttributesCount); + output.serializeByteAsFixed32(Span.Link.FLAGS, traceFlags.asByte()); } private static int calculateSize( String traceId, String spanId, + TraceFlags flags, byte[] traceStateUtf8, KeyValueMarshaler[] attributeMarshalers, int droppedAttributesCount) { @@ -93,6 +105,7 @@ private static int calculateSize( size += MarshalerUtil.sizeBytes(Span.Link.TRACE_STATE, traceStateUtf8); size += MarshalerUtil.sizeRepeatedMessage(Span.Link.ATTRIBUTES, attributeMarshalers); size += MarshalerUtil.sizeUInt32(Span.Link.DROPPED_ATTRIBUTES_COUNT, droppedAttributesCount); + size += MarshalerUtil.sizeByteAsFixed32(Span.Link.FLAGS, flags.asByte()); return size; } } diff --git a/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/traces/SpanMarshaler.java b/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/traces/SpanMarshaler.java index 7eae7c7b25c..e2e83c0f129 100644 --- a/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/traces/SpanMarshaler.java +++ b/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/traces/SpanMarshaler.java @@ -8,6 +8,7 @@ import static io.opentelemetry.api.trace.propagation.internal.W3CTraceContextEncoding.encodeTraceState; import io.opentelemetry.api.trace.SpanKind; +import io.opentelemetry.api.trace.TraceFlags; import io.opentelemetry.api.trace.TraceState; import io.opentelemetry.exporter.internal.marshal.MarshalerUtil; import io.opentelemetry.exporter.internal.marshal.MarshalerWithSize; @@ -37,6 +38,7 @@ final class SpanMarshaler extends MarshalerWithSize { private final SpanLinkMarshaler[] spanLinkMarshalers; private final int droppedLinksCount; private final SpanStatusMarshaler spanStatusMarshaler; + private final TraceFlags flags; // Because SpanMarshaler is always part of a repeated field, it cannot return "null". static SpanMarshaler create(SpanData spanData) { @@ -72,7 +74,8 @@ static SpanMarshaler create(SpanData spanData) { spanData.getTotalRecordedEvents() - spanData.getEvents().size(), spanLinkMarshalers, spanData.getTotalRecordedLinks() - spanData.getLinks().size(), - SpanStatusMarshaler.create(spanData.getStatus())); + SpanStatusMarshaler.create(spanData.getStatus()), + spanData.getSpanContext().getTraceFlags()); } private SpanMarshaler( @@ -90,7 +93,8 @@ private SpanMarshaler( int droppedEventsCount, SpanLinkMarshaler[] spanLinkMarshalers, int droppedLinksCount, - SpanStatusMarshaler spanStatusMarshaler) { + SpanStatusMarshaler spanStatusMarshaler, + TraceFlags flags) { super( calculateSize( traceId, @@ -107,7 +111,8 @@ private SpanMarshaler( droppedEventsCount, spanLinkMarshalers, droppedLinksCount, - spanStatusMarshaler)); + spanStatusMarshaler, + flags)); this.traceId = traceId; this.spanId = spanId; this.traceStateUtf8 = traceStateUtf8; @@ -123,6 +128,7 @@ private SpanMarshaler( this.spanLinkMarshalers = spanLinkMarshalers; this.droppedLinksCount = droppedLinksCount; this.spanStatusMarshaler = spanStatusMarshaler; + this.flags = flags; } @Override @@ -148,6 +154,7 @@ public void writeTo(Serializer output) throws IOException { output.serializeUInt32(Span.DROPPED_LINKS_COUNT, droppedLinksCount); output.serializeMessage(Span.STATUS, spanStatusMarshaler); + output.serializeByteAsFixed32(Span.FLAGS, flags.asByte()); } private static int calculateSize( @@ -165,7 +172,8 @@ private static int calculateSize( int droppedEventsCount, SpanLinkMarshaler[] spanLinkMarshalers, int droppedLinksCount, - SpanStatusMarshaler spanStatusMarshaler) { + SpanStatusMarshaler spanStatusMarshaler, + TraceFlags flags) { int size = 0; size += MarshalerUtil.sizeTraceId(Span.TRACE_ID, traceId); size += MarshalerUtil.sizeSpanId(Span.SPAN_ID, spanId); @@ -188,6 +196,7 @@ private static int calculateSize( size += MarshalerUtil.sizeUInt32(Span.DROPPED_LINKS_COUNT, droppedLinksCount); size += MarshalerUtil.sizeMessage(Span.STATUS, spanStatusMarshaler); + size += MarshalerUtil.sizeByteAsFixed32(Span.FLAGS, flags.asByte()); return size; } diff --git a/exporters/otlp/common/src/test/java/io/opentelemetry/exporter/internal/otlp/traces/TraceRequestMarshalerTest.java b/exporters/otlp/common/src/test/java/io/opentelemetry/exporter/internal/otlp/traces/TraceRequestMarshalerTest.java index c9e9b1d3fc2..6bc17a22109 100644 --- a/exporters/otlp/common/src/test/java/io/opentelemetry/exporter/internal/otlp/traces/TraceRequestMarshalerTest.java +++ b/exporters/otlp/common/src/test/java/io/opentelemetry/exporter/internal/otlp/traces/TraceRequestMarshalerTest.java @@ -112,7 +112,7 @@ void toProtoResourceSpans() { @Test void toProtoSpan() { - Span span = + Span protoSpan = parse( Span.getDefaultInstance(), SpanMarshaler.create( @@ -145,15 +145,17 @@ void toProtoSpan() { .setStatus(StatusData.ok()) .build())); - assertThat(span.getTraceId().toByteArray()).isEqualTo(TRACE_ID_BYTES); - assertThat(span.getSpanId().toByteArray()).isEqualTo(SPAN_ID_BYTES); - assertThat(span.getTraceState()).isEqualTo(TRACE_STATE_VALUE); - assertThat(span.getParentSpanId().toByteArray()).isEqualTo(new byte[] {}); - assertThat(span.getName()).isEqualTo("GET /api/endpoint"); - assertThat(span.getKind()).isEqualTo(SPAN_KIND_SERVER); - assertThat(span.getStartTimeUnixNano()).isEqualTo(12345); - assertThat(span.getEndTimeUnixNano()).isEqualTo(12349); - assertThat(span.getAttributesList()) + assertThat(protoSpan.getTraceId().toByteArray()).isEqualTo(TRACE_ID_BYTES); + assertThat(protoSpan.getSpanId().toByteArray()).isEqualTo(SPAN_ID_BYTES); + assertThat(protoSpan.getFlags()) + .isEqualTo(((int) SPAN_CONTEXT.getTraceFlags().asByte()) & 0x00ff); + assertThat(protoSpan.getTraceState()).isEqualTo(TRACE_STATE_VALUE); + assertThat(protoSpan.getParentSpanId().toByteArray()).isEqualTo(new byte[] {}); + assertThat(protoSpan.getName()).isEqualTo("GET /api/endpoint"); + assertThat(protoSpan.getKind()).isEqualTo(SPAN_KIND_SERVER); + assertThat(protoSpan.getStartTimeUnixNano()).isEqualTo(12345); + assertThat(protoSpan.getEndTimeUnixNano()).isEqualTo(12349); + assertThat(protoSpan.getAttributesList()) .containsOnly( KeyValue.newBuilder() .setKey("key") @@ -215,20 +217,22 @@ void toProtoSpan() { .build()) .build()) .build()); - assertThat(span.getDroppedAttributesCount()).isEqualTo(1); - assertThat(span.getEventsList()) + assertThat(protoSpan.getDroppedAttributesCount()).isEqualTo(1); + assertThat(protoSpan.getEventsList()) .containsExactly( Span.Event.newBuilder().setTimeUnixNano(12347).setName("my_event").build()); - assertThat(span.getDroppedEventsCount()).isEqualTo(2); // 3 - 1 - assertThat(span.getLinksList()) + assertThat(protoSpan.getDroppedEventsCount()).isEqualTo(2); // 3 - 1 + assertThat(protoSpan.getLinksList()) .containsExactly( Span.Link.newBuilder() .setTraceId(ByteString.copyFrom(TRACE_ID_BYTES)) .setSpanId(ByteString.copyFrom(SPAN_ID_BYTES)) + .setFlags(SPAN_CONTEXT.getTraceFlags().asByte()) .setTraceState(encodeTraceState(SPAN_CONTEXT.getTraceState())) .build()); - assertThat(span.getDroppedLinksCount()).isEqualTo(1); // 2 - 1 - assertThat(span.getStatus()).isEqualTo(Status.newBuilder().setCode(STATUS_CODE_OK).build()); + assertThat(protoSpan.getDroppedLinksCount()).isEqualTo(1); // 2 - 1 + assertThat(protoSpan.getStatus()) + .isEqualTo(Status.newBuilder().setCode(STATUS_CODE_OK).build()); } @Test @@ -314,6 +318,7 @@ void toProtoSpanLink_WithoutAttributes() { Span.Link.newBuilder() .setTraceId(ByteString.copyFrom(TRACE_ID_BYTES)) .setSpanId(ByteString.copyFrom(SPAN_ID_BYTES)) + .setFlags(SPAN_CONTEXT.getTraceFlags().asByte()) .setTraceState(TRACE_STATE_VALUE) .build()); } @@ -330,6 +335,7 @@ void toProtoSpanLink_WithAttributes() { Span.Link.newBuilder() .setTraceId(ByteString.copyFrom(TRACE_ID_BYTES)) .setSpanId(ByteString.copyFrom(SPAN_ID_BYTES)) + .setFlags(SPAN_CONTEXT.getTraceFlags().asByte()) .setTraceState(TRACE_STATE_VALUE) .addAttributes( KeyValue.newBuilder() From 0aa223dcaf0e7d4fd1f854ec3dd99f1e12d5163d Mon Sep 17 00:00:00 2001 From: Asaf Mesika Date: Wed, 31 Jan 2024 17:47:00 +0200 Subject: [PATCH 221/901] Memory mode: Adding support for synchronous instruments - Counter (#6182) --- ...trumentGarbageCollectionBenchmarkTest.java | 6 +- .../internal/state/TestInstrumentType.java | 55 +++++---- .../state/tester/DoubleSumTester.java | 58 +++++++++ .../internal/state/tester/LongSumTester.java | 58 +++++++++ .../aggregator/DoubleSumAggregator.java | 25 +++- .../aggregator/LongSumAggregator.java | 25 +++- .../internal/data/MutableDoublePointData.java | 14 +-- .../MutableExponentialHistogramBuckets.java | 6 +- .../MutableExponentialHistogramPointData.java | 32 ++--- .../internal/data/MutableLongPointData.java | 14 +-- .../metrics/internal/view/SumAggregation.java | 6 +- .../aggregator/DoubleSumAggregatorTest.java | 111 ++++++++++++------ .../aggregator/LongSumAggregatorTest.java | 110 +++++++++++------ 13 files changed, 386 insertions(+), 134 deletions(-) create mode 100644 sdk/metrics/src/jmhBasedTest/java/io/opentelemetry/sdk/metrics/internal/state/tester/DoubleSumTester.java create mode 100644 sdk/metrics/src/jmhBasedTest/java/io/opentelemetry/sdk/metrics/internal/state/tester/LongSumTester.java diff --git a/sdk/metrics/src/jmhBasedTest/java/io/opentelemetry/sdk/metrics/internal/state/InstrumentGarbageCollectionBenchmarkTest.java b/sdk/metrics/src/jmhBasedTest/java/io/opentelemetry/sdk/metrics/internal/state/InstrumentGarbageCollectionBenchmarkTest.java index de1733b0ad8..63de98ef5f3 100644 --- a/sdk/metrics/src/jmhBasedTest/java/io/opentelemetry/sdk/metrics/internal/state/InstrumentGarbageCollectionBenchmarkTest.java +++ b/sdk/metrics/src/jmhBasedTest/java/io/opentelemetry/sdk/metrics/internal/state/InstrumentGarbageCollectionBenchmarkTest.java @@ -108,6 +108,10 @@ public void normalizedAllocationRateTest() throws RunnerException { assertThat(immutableDataAllocRate).isNotNull().isNotZero(); assertThat(reusableDataAllocRate).isNotNull().isNotZero(); + float dataAllocRateReductionPercentage = + TestInstrumentType.valueOf(testInstrumentType) + .getDataAllocRateReductionPercentage(); + // If this test suddenly fails for you this means you have changed the code in a way // that allocates more memory than before. You can find out where, by running // ProfileBenchmark class and looking at the flame graph. Make sure to @@ -116,7 +120,7 @@ public void normalizedAllocationRateTest() throws RunnerException { .describedAs( "Aggregation temporality = %s, testInstrumentType = %s", aggregationTemporality, testInstrumentType) - .isCloseTo(99.8, Offset.offset(2.0)); + .isCloseTo(dataAllocRateReductionPercentage, Offset.offset(2.0)); }); }); } diff --git a/sdk/metrics/src/jmhBasedTest/java/io/opentelemetry/sdk/metrics/internal/state/TestInstrumentType.java b/sdk/metrics/src/jmhBasedTest/java/io/opentelemetry/sdk/metrics/internal/state/TestInstrumentType.java index 9f799d72894..1cf082699be 100644 --- a/sdk/metrics/src/jmhBasedTest/java/io/opentelemetry/sdk/metrics/internal/state/TestInstrumentType.java +++ b/sdk/metrics/src/jmhBasedTest/java/io/opentelemetry/sdk/metrics/internal/state/TestInstrumentType.java @@ -9,34 +9,45 @@ import io.opentelemetry.sdk.metrics.Aggregation; import io.opentelemetry.sdk.metrics.SdkMeterProvider; import io.opentelemetry.sdk.metrics.internal.state.tester.AsyncCounterTester; +import io.opentelemetry.sdk.metrics.internal.state.tester.DoubleSumTester; import io.opentelemetry.sdk.metrics.internal.state.tester.ExplicitBucketHistogramTester; import io.opentelemetry.sdk.metrics.internal.state.tester.ExponentialHistogramTester; +import io.opentelemetry.sdk.metrics.internal.state.tester.LongSumTester; import java.util.List; import java.util.Random; +import java.util.function.Supplier; +@SuppressWarnings("ImmutableEnumChecker") public enum TestInstrumentType { - ASYNC_COUNTER() { - @Override - InstrumentTester createInstrumentTester() { - return new AsyncCounterTester(); - } - }, - EXPONENTIAL_HISTOGRAM() { - @Override - InstrumentTester createInstrumentTester() { - return new ExponentialHistogramTester(); - } - }, - EXPLICIT_BUCKET() { - @Override - InstrumentTester createInstrumentTester() { - return new ExplicitBucketHistogramTester(); - } - }; - - abstract InstrumentTester createInstrumentTester(); - - TestInstrumentType() {} + ASYNC_COUNTER(AsyncCounterTester::new), + EXPONENTIAL_HISTOGRAM(ExponentialHistogramTester::new), + EXPLICIT_BUCKET(ExplicitBucketHistogramTester::new), + LONG_SUM(LongSumTester::new, /* dataAllocRateReductionPercentage= */ 97.3f), + DOUBLE_SUM(DoubleSumTester::new, /* dataAllocRateReductionPercentage= */ 97.3f); + + private final Supplier instrumentTesterInitializer; + private final float dataAllocRateReductionPercentage; + + TestInstrumentType(Supplier instrumentTesterInitializer) { + this.dataAllocRateReductionPercentage = 99.8f; // default + this.instrumentTesterInitializer = instrumentTesterInitializer; + } + + // Some instruments have different reduction percentage. + TestInstrumentType( + Supplier instrumentTesterInitializer, + float dataAllocRateReductionPercentage) { + this.instrumentTesterInitializer = instrumentTesterInitializer; + this.dataAllocRateReductionPercentage = dataAllocRateReductionPercentage; + } + + float getDataAllocRateReductionPercentage() { + return dataAllocRateReductionPercentage; + } + + InstrumentTester createInstrumentTester() { + return instrumentTesterInitializer.get(); + } public interface InstrumentTester { Aggregation testedAggregation(); diff --git a/sdk/metrics/src/jmhBasedTest/java/io/opentelemetry/sdk/metrics/internal/state/tester/DoubleSumTester.java b/sdk/metrics/src/jmhBasedTest/java/io/opentelemetry/sdk/metrics/internal/state/tester/DoubleSumTester.java new file mode 100644 index 00000000000..47cf4e4023e --- /dev/null +++ b/sdk/metrics/src/jmhBasedTest/java/io/opentelemetry/sdk/metrics/internal/state/tester/DoubleSumTester.java @@ -0,0 +1,58 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.sdk.metrics.internal.state.tester; + +import io.opentelemetry.api.common.Attributes; +import io.opentelemetry.api.metrics.DoubleCounter; +import io.opentelemetry.api.metrics.Meter; +import io.opentelemetry.sdk.metrics.Aggregation; +import io.opentelemetry.sdk.metrics.SdkMeterProvider; +import io.opentelemetry.sdk.metrics.internal.state.TestInstrumentType; +import java.util.List; +import java.util.Random; + +public class DoubleSumTester implements TestInstrumentType.InstrumentTester { + private static final int measurementsPerAttributeSet = 1_000; + + static class DoubleSumState implements TestInstrumentType.TestInstrumentsState { + DoubleCounter doubleCounter; + } + + @Override + public Aggregation testedAggregation() { + return Aggregation.sum(); + } + + @Override + public TestInstrumentType.TestInstrumentsState buildInstruments( + double instrumentCount, + SdkMeterProvider sdkMeterProvider, + List attributesList, + Random random) { + DoubleSumState doubleSumState = new DoubleSumState(); + + Meter meter = sdkMeterProvider.meterBuilder("meter").build(); + doubleSumState.doubleCounter = meter.counterBuilder("test.double.sum").ofDoubles().build(); + + return doubleSumState; + } + + @SuppressWarnings("ForLoopReplaceableByForEach") // This is for GC sensitivity testing: no streams + @Override + public void recordValuesInInstruments( + TestInstrumentType.TestInstrumentsState testInstrumentsState, + List attributesList, + Random random) { + DoubleSumState state = (DoubleSumState) testInstrumentsState; + + for (int j = 0; j < attributesList.size(); j++) { + Attributes attributes = attributesList.get(j); + for (int i = 0; i < measurementsPerAttributeSet; i++) { + state.doubleCounter.add(1.2f, attributes); + } + } + } +} diff --git a/sdk/metrics/src/jmhBasedTest/java/io/opentelemetry/sdk/metrics/internal/state/tester/LongSumTester.java b/sdk/metrics/src/jmhBasedTest/java/io/opentelemetry/sdk/metrics/internal/state/tester/LongSumTester.java new file mode 100644 index 00000000000..2477020633e --- /dev/null +++ b/sdk/metrics/src/jmhBasedTest/java/io/opentelemetry/sdk/metrics/internal/state/tester/LongSumTester.java @@ -0,0 +1,58 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.sdk.metrics.internal.state.tester; + +import io.opentelemetry.api.common.Attributes; +import io.opentelemetry.api.metrics.LongCounter; +import io.opentelemetry.api.metrics.Meter; +import io.opentelemetry.sdk.metrics.Aggregation; +import io.opentelemetry.sdk.metrics.SdkMeterProvider; +import io.opentelemetry.sdk.metrics.internal.state.TestInstrumentType; +import java.util.List; +import java.util.Random; + +public class LongSumTester implements TestInstrumentType.InstrumentTester { + private static final int measurementsPerAttributeSet = 1_000; + + static class LongSumState implements TestInstrumentType.TestInstrumentsState { + LongCounter longCounter; + } + + @Override + public Aggregation testedAggregation() { + return Aggregation.sum(); + } + + @Override + public TestInstrumentType.TestInstrumentsState buildInstruments( + double instrumentCount, + SdkMeterProvider sdkMeterProvider, + List attributesList, + Random random) { + LongSumState longSumState = new LongSumState(); + + Meter meter = sdkMeterProvider.meterBuilder("meter").build(); + longSumState.longCounter = meter.counterBuilder("test.long.sum").build(); + + return longSumState; + } + + @SuppressWarnings("ForLoopReplaceableByForEach") // This is for GC sensitivity testing: no streams + @Override + public void recordValuesInInstruments( + TestInstrumentType.TestInstrumentsState testInstrumentsState, + List attributesList, + Random random) { + LongSumState state = (LongSumState) testInstrumentsState; + + for (int j = 0; j < attributesList.size(); j++) { + Attributes attributes = attributesList.get(j); + for (int i = 0; i < measurementsPerAttributeSet; i++) { + state.longCounter.add(1, attributes); + } + } + } +} diff --git a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/aggregator/DoubleSumAggregator.java b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/aggregator/DoubleSumAggregator.java index c88217114c7..17f02f85208 100644 --- a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/aggregator/DoubleSumAggregator.java +++ b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/aggregator/DoubleSumAggregator.java @@ -7,6 +7,7 @@ import io.opentelemetry.api.common.Attributes; import io.opentelemetry.sdk.common.InstrumentationScopeInfo; +import io.opentelemetry.sdk.common.export.MemoryMode; import io.opentelemetry.sdk.metrics.data.AggregationTemporality; import io.opentelemetry.sdk.metrics.data.DoubleExemplarData; import io.opentelemetry.sdk.metrics.data.DoublePointData; @@ -25,6 +26,7 @@ import java.util.Collection; import java.util.List; import java.util.function.Supplier; +import javax.annotation.Nullable; /** * Sum aggregator that keeps values as {@code double}s. @@ -35,24 +37,28 @@ public final class DoubleSumAggregator extends AbstractSumAggregator { private final Supplier> reservoirSupplier; + private final MemoryMode memoryMode; /** * Constructs a sum aggregator. * * @param instrumentDescriptor The instrument being recorded, used to compute monotonicity. * @param reservoirSupplier Supplier of exemplar reservoirs per-stream. + * @param memoryMode The memory mode to use. */ public DoubleSumAggregator( InstrumentDescriptor instrumentDescriptor, - Supplier> reservoirSupplier) { + Supplier> reservoirSupplier, + MemoryMode memoryMode) { super(instrumentDescriptor); this.reservoirSupplier = reservoirSupplier; + this.memoryMode = memoryMode; } @Override public AggregatorHandle createHandle() { - return new Handle(reservoirSupplier.get()); + return new Handle(reservoirSupplier.get(), memoryMode); } @Override @@ -124,8 +130,12 @@ public MetricData toMetricData( static final class Handle extends AggregatorHandle { private final DoubleAdder current = AdderUtil.createDoubleAdder(); - Handle(ExemplarReservoir exemplarReservoir) { + // Only used if memoryMode == MemoryMode.REUSABLE_DATA + @Nullable private final MutableDoublePointData reusablePoint; + + Handle(ExemplarReservoir exemplarReservoir, MemoryMode memoryMode) { super(exemplarReservoir); + reusablePoint = memoryMode == MemoryMode.REUSABLE_DATA ? new MutableDoublePointData() : null; } @Override @@ -136,8 +146,13 @@ protected DoublePointData doAggregateThenMaybeReset( List exemplars, boolean reset) { double value = reset ? this.current.sumThenReset() : this.current.sum(); - return ImmutableDoublePointData.create( - startEpochNanos, epochNanos, attributes, value, exemplars); + if (reusablePoint != null) { + reusablePoint.set(startEpochNanos, epochNanos, attributes, value, exemplars); + return reusablePoint; + } else { + return ImmutableDoublePointData.create( + startEpochNanos, epochNanos, attributes, value, exemplars); + } } @Override diff --git a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/aggregator/LongSumAggregator.java b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/aggregator/LongSumAggregator.java index 131c82ce3e9..cfd23c0cf97 100644 --- a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/aggregator/LongSumAggregator.java +++ b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/aggregator/LongSumAggregator.java @@ -7,6 +7,7 @@ import io.opentelemetry.api.common.Attributes; import io.opentelemetry.sdk.common.InstrumentationScopeInfo; +import io.opentelemetry.sdk.common.export.MemoryMode; import io.opentelemetry.sdk.metrics.data.AggregationTemporality; import io.opentelemetry.sdk.metrics.data.LongExemplarData; import io.opentelemetry.sdk.metrics.data.LongPointData; @@ -25,6 +26,7 @@ import java.util.Collection; import java.util.List; import java.util.function.Supplier; +import javax.annotation.Nullable; /** * Sum aggregator that keeps values as {@code long}s. @@ -36,17 +38,20 @@ public final class LongSumAggregator extends AbstractSumAggregator { private final Supplier> reservoirSupplier; + private final MemoryMode memoryMode; public LongSumAggregator( InstrumentDescriptor instrumentDescriptor, - Supplier> reservoirSupplier) { + Supplier> reservoirSupplier, + MemoryMode memoryMode) { super(instrumentDescriptor); this.reservoirSupplier = reservoirSupplier; + this.memoryMode = memoryMode; } @Override public AggregatorHandle createHandle() { - return new Handle(reservoirSupplier.get()); + return new Handle(reservoirSupplier.get(), memoryMode); } @Override @@ -118,8 +123,13 @@ public MetricData toMetricData( static final class Handle extends AggregatorHandle { private final LongAdder current = AdderUtil.createLongAdder(); - Handle(ExemplarReservoir exemplarReservoir) { + // Only used if memoryMode == MemoryMode.REUSABLE_DATA + @Nullable private final MutableLongPointData reusablePointData; + + Handle(ExemplarReservoir exemplarReservoir, MemoryMode memoryMode) { super(exemplarReservoir); + reusablePointData = + memoryMode == MemoryMode.REUSABLE_DATA ? new MutableLongPointData() : null; } @Override @@ -130,8 +140,13 @@ protected LongPointData doAggregateThenMaybeReset( List exemplars, boolean reset) { long value = reset ? this.current.sumThenReset() : this.current.sum(); - return ImmutableLongPointData.create( - startEpochNanos, epochNanos, attributes, value, exemplars); + if (reusablePointData != null) { + reusablePointData.set(startEpochNanos, epochNanos, attributes, value, exemplars); + return reusablePointData; + } else { + return ImmutableLongPointData.create( + startEpochNanos, epochNanos, attributes, value, exemplars); + } } @Override diff --git a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/data/MutableDoublePointData.java b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/data/MutableDoublePointData.java index fb412e6f2a8..1f19c3911ae 100644 --- a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/data/MutableDoublePointData.java +++ b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/data/MutableDoublePointData.java @@ -93,15 +93,15 @@ public boolean equals(Object o) { if (this == o) { return true; } - if (o == null || !(o instanceof MutableDoublePointData)) { + if (!(o instanceof DoublePointData)) { return false; } - MutableDoublePointData pointData = (MutableDoublePointData) o; - return startEpochNanos == pointData.startEpochNanos - && epochNanos == pointData.epochNanos - && Double.doubleToLongBits(value) == Double.doubleToLongBits(pointData.value) - && Objects.equals(attributes, pointData.attributes) - && Objects.equals(exemplars, pointData.exemplars); + DoublePointData pointData = (DoublePointData) o; + return startEpochNanos == pointData.getStartEpochNanos() + && epochNanos == pointData.getEpochNanos() + && Double.doubleToLongBits(value) == Double.doubleToLongBits(pointData.getValue()) + && Objects.equals(attributes, pointData.getAttributes()) + && Objects.equals(exemplars, pointData.getExemplars()); } @Override diff --git a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/data/MutableExponentialHistogramBuckets.java b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/data/MutableExponentialHistogramBuckets.java index 9c9f815426d..9554d4722ea 100644 --- a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/data/MutableExponentialHistogramBuckets.java +++ b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/data/MutableExponentialHistogramBuckets.java @@ -81,12 +81,12 @@ public boolean equals(Object o) { if (o == this) { return true; } - if (o instanceof MutableExponentialHistogramBuckets) { - MutableExponentialHistogramBuckets that = (MutableExponentialHistogramBuckets) o; + if (o instanceof ExponentialHistogramBuckets) { + ExponentialHistogramBuckets that = (ExponentialHistogramBuckets) o; return this.scale == that.getScale() && this.offset == that.getOffset() && this.totalCount == that.getTotalCount() - && Objects.equals(this.bucketCounts, that.bucketCounts); + && Objects.equals(this.bucketCounts, that.getBucketCounts()); } return false; } diff --git a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/data/MutableExponentialHistogramPointData.java b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/data/MutableExponentialHistogramPointData.java index c32565af087..bccc7a9abe1 100644 --- a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/data/MutableExponentialHistogramPointData.java +++ b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/data/MutableExponentialHistogramPointData.java @@ -192,22 +192,22 @@ public boolean equals(Object o) { if (o == this) { return true; } - if (o instanceof MutableExponentialHistogramPointData) { - MutableExponentialHistogramPointData that = (MutableExponentialHistogramPointData) o; - return this.startEpochNanos == that.startEpochNanos - && this.epochNanos == that.epochNanos - && this.attributes.equals(that.attributes) - && this.scale == that.scale - && Double.doubleToLongBits(this.sum) == Double.doubleToLongBits(that.sum) - && this.count == that.count - && this.zeroCount == that.zeroCount - && this.hasMin == that.hasMin - && Double.doubleToLongBits(this.min) == Double.doubleToLongBits(that.min) - && this.hasMax == that.hasMax - && Double.doubleToLongBits(this.max) == Double.doubleToLongBits(that.max) - && this.positiveBuckets.equals(that.positiveBuckets) - && this.negativeBuckets.equals(that.negativeBuckets) - && this.exemplars.equals(that.exemplars); + if (o instanceof ExponentialHistogramPointData) { + ExponentialHistogramPointData that = (ExponentialHistogramPointData) o; + return this.startEpochNanos == that.getStartEpochNanos() + && this.epochNanos == that.getEpochNanos() + && this.attributes.equals(that.getAttributes()) + && this.scale == that.getScale() + && Double.doubleToLongBits(this.sum) == Double.doubleToLongBits(that.getSum()) + && this.count == that.getCount() + && this.zeroCount == that.getZeroCount() + && this.hasMin == that.hasMin() + && Double.doubleToLongBits(this.min) == Double.doubleToLongBits(that.getMin()) + && this.hasMax == that.hasMax() + && Double.doubleToLongBits(this.max) == Double.doubleToLongBits(that.getMax()) + && this.positiveBuckets.equals(that.getPositiveBuckets()) + && this.negativeBuckets.equals(that.getNegativeBuckets()) + && this.exemplars.equals(that.getExemplars()); } return false; } diff --git a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/data/MutableLongPointData.java b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/data/MutableLongPointData.java index 179accaf486..679a9e4902f 100644 --- a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/data/MutableLongPointData.java +++ b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/data/MutableLongPointData.java @@ -91,15 +91,15 @@ public boolean equals(Object o) { if (this == o) { return true; } - if (o == null || !(o instanceof MutableLongPointData)) { + if (!(o instanceof LongPointData)) { return false; } - MutableLongPointData that = (MutableLongPointData) o; - return value == that.value - && startEpochNanos == that.startEpochNanos - && epochNanos == that.epochNanos - && Objects.equals(attributes, that.attributes) - && Objects.equals(exemplars, that.exemplars); + LongPointData that = (LongPointData) o; + return value == that.getValue() + && startEpochNanos == that.getStartEpochNanos() + && epochNanos == that.getEpochNanos() + && Objects.equals(attributes, that.getAttributes()) + && Objects.equals(exemplars, that.getExemplars()); } @Override diff --git a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/view/SumAggregation.java b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/view/SumAggregation.java index a23b0bc4d7e..7ca1294666b 100644 --- a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/view/SumAggregation.java +++ b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/view/SumAggregation.java @@ -54,7 +54,8 @@ public Aggregator createAggr Clock.getDefault(), Runtime.getRuntime().availableProcessors(), RandomSupplier.platformDefault())); - return (Aggregator) new LongSumAggregator(instrumentDescriptor, reservoirFactory); + return (Aggregator) + new LongSumAggregator(instrumentDescriptor, reservoirFactory, memoryMode); } case DOUBLE: { @@ -66,7 +67,8 @@ public Aggregator createAggr Clock.getDefault(), Runtime.getRuntime().availableProcessors(), RandomSupplier.platformDefault())); - return (Aggregator) new DoubleSumAggregator(instrumentDescriptor, reservoirFactory); + return (Aggregator) + new DoubleSumAggregator(instrumentDescriptor, reservoirFactory, memoryMode); } } throw new IllegalArgumentException("Invalid instrument value type"); diff --git a/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/internal/aggregator/DoubleSumAggregatorTest.java b/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/internal/aggregator/DoubleSumAggregatorTest.java index edd1f0fc077..6b4715dd729 100644 --- a/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/internal/aggregator/DoubleSumAggregatorTest.java +++ b/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/internal/aggregator/DoubleSumAggregatorTest.java @@ -6,7 +6,6 @@ package io.opentelemetry.sdk.metrics.internal.aggregator; import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.assertThat; -import static org.assertj.core.api.Assertions.assertThat; import io.opentelemetry.api.common.AttributeKey; import io.opentelemetry.api.common.Attributes; @@ -15,6 +14,7 @@ import io.opentelemetry.api.trace.TraceState; import io.opentelemetry.context.Context; import io.opentelemetry.sdk.common.InstrumentationScopeInfo; +import io.opentelemetry.sdk.common.export.MemoryMode; import io.opentelemetry.sdk.metrics.InstrumentType; import io.opentelemetry.sdk.metrics.InstrumentValueType; import io.opentelemetry.sdk.metrics.data.AggregationTemporality; @@ -33,6 +33,8 @@ import java.util.List; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.EnumSource; import org.mockito.Mock; import org.mockito.Mockito; import org.mockito.junit.jupiter.MockitoExtension; @@ -48,24 +50,33 @@ class DoubleSumAggregatorTest { private static final MetricDescriptor metricDescriptor = MetricDescriptor.create("name", "description", "unit"); - private static final DoubleSumAggregator aggregator = - new DoubleSumAggregator( - InstrumentDescriptor.create( - "instrument_name", - "instrument_description", - "instrument_unit", - InstrumentType.COUNTER, - InstrumentValueType.DOUBLE, - Advice.empty()), - ExemplarReservoir::doubleNoSamples); + private DoubleSumAggregator aggregator; - @Test - void createHandle() { + private void init(MemoryMode memoryMode) { + aggregator = + new DoubleSumAggregator( + InstrumentDescriptor.create( + "instrument_name", + "instrument_description", + "instrument_unit", + InstrumentType.COUNTER, + InstrumentValueType.DOUBLE, + Advice.empty()), + ExemplarReservoir::doubleNoSamples, + memoryMode); + } + + @ParameterizedTest + @EnumSource(MemoryMode.class) + void createHandle(MemoryMode memoryMode) { + init(memoryMode); assertThat(aggregator.createHandle()).isInstanceOf(DoubleSumAggregator.Handle.class); } - @Test - void multipleRecords() { + @ParameterizedTest + @EnumSource(MemoryMode.class) + void multipleRecords(MemoryMode memoryMode) { + init(memoryMode); AggregatorHandle aggregatorHandle = aggregator.createHandle(); aggregatorHandle.recordDouble(12.1); @@ -80,8 +91,10 @@ void multipleRecords() { .isEqualTo(12.1 * 5); } - @Test - void multipleRecords_WithNegatives() { + @ParameterizedTest + @EnumSource(MemoryMode.class) + void multipleRecords_WithNegatives(MemoryMode memoryMode) { + init(memoryMode); AggregatorHandle aggregatorHandle = aggregator.createHandle(); aggregatorHandle.recordDouble(12); @@ -97,8 +110,10 @@ void multipleRecords_WithNegatives() { .isEqualTo(14); } - @Test - void aggregateThenMaybeReset() { + @ParameterizedTest + @EnumSource(MemoryMode.class) + void aggregateThenMaybeReset(MemoryMode memoryMode) { + init(memoryMode); AggregatorHandle aggregatorHandle = aggregator.createHandle(); @@ -119,8 +134,9 @@ void aggregateThenMaybeReset() { .isEqualTo(-13); } - @Test - void aggregateThenMaybeReset_WithExemplars() { + @ParameterizedTest + @EnumSource(MemoryMode.class) + void aggregateThenMaybeReset_WithExemplars(MemoryMode memoryMode) { Attributes attributes = Attributes.builder().put("test", "value").build(); DoubleExemplarData exemplar = ImmutableDoubleExemplarData.create( @@ -143,7 +159,8 @@ void aggregateThenMaybeReset_WithExemplars() { InstrumentType.COUNTER, InstrumentValueType.DOUBLE, Advice.empty()), - () -> reservoir); + () -> reservoir, + memoryMode); AggregatorHandle aggregatorHandle = aggregator.createHandle(); aggregatorHandle.recordDouble(0, attributes, Context.root()); @@ -152,8 +169,9 @@ void aggregateThenMaybeReset_WithExemplars() { .isEqualTo(ImmutableDoublePointData.create(0, 1, Attributes.empty(), 0, exemplars)); } - @Test - void mergeAndDiff() { + @ParameterizedTest + @EnumSource(MemoryMode.class) + void mergeAndDiff(MemoryMode memoryMode) { Attributes attributes = Attributes.builder().put("test", "value").build(); DoubleExemplarData exemplar = ImmutableDoubleExemplarData.create( @@ -177,7 +195,8 @@ void mergeAndDiff() { instrumentType, InstrumentValueType.LONG, Advice.empty()), - ExemplarReservoir::doubleNoSamples); + ExemplarReservoir::doubleNoSamples, + memoryMode); DoublePointData diffed = aggregator.diff( @@ -193,8 +212,10 @@ void mergeAndDiff() { } } - @Test - void diffInPlace() { + @ParameterizedTest + @EnumSource(MemoryMode.class) + void diffInPlace(MemoryMode memoryMode) { + init(memoryMode); Attributes attributes = Attributes.builder().put("test", "value").build(); DoubleExemplarData exemplar = ImmutableDoubleExemplarData.create( @@ -235,8 +256,10 @@ void diffInPlace() { assertThat(previous.getExemplars()).isEqualTo(exemplars); } - @Test - void copyPoint() { + @ParameterizedTest + @EnumSource(MemoryMode.class) + void copyPoint(MemoryMode memoryMode) { + init(memoryMode); MutableDoublePointData pointData = (MutableDoublePointData) aggregator.createReusablePoint(); Attributes attributes = Attributes.of(AttributeKey.longKey("test"), 100L); @@ -278,8 +301,10 @@ void copyPoint() { assertThat(toPointData.getExemplars()).isEqualTo(pointData.getExemplars()); } - @Test - void toMetricData() { + @ParameterizedTest + @EnumSource(MemoryMode.class) + void toMetricData(MemoryMode memoryMode) { + init(memoryMode); AggregatorHandle aggregatorHandle = aggregator.createHandle(); aggregatorHandle.recordDouble(10); @@ -310,8 +335,10 @@ void toMetricData() { .hasValue(10))); } - @Test - void toMetricDataWithExemplars() { + @ParameterizedTest + @EnumSource(MemoryMode.class) + void toMetricDataWithExemplars(MemoryMode memoryMode) { + init(memoryMode); Attributes attributes = Attributes.builder().put("test", "value").build(); DoubleExemplarData exemplar = ImmutableDoubleExemplarData.create( @@ -335,4 +362,22 @@ void toMetricDataWithExemplars() { .hasDoubleSumSatisfying( sum -> sum.hasPointsSatisfying(point -> point.hasValue(1).hasExemplars(exemplar))); } + + @Test + void sameObjectReturnedOnReusableDataMemoryMode() { + init(MemoryMode.REUSABLE_DATA); + AggregatorHandle aggregatorHandle = + aggregator.createHandle(); + aggregatorHandle.recordDouble(1.0); + + DoublePointData firstCollection = + aggregatorHandle.aggregateThenMaybeReset(0, 1, Attributes.empty(), /* reset= */ false); + + aggregatorHandle.recordDouble(1.0); + DoublePointData secondCollection = + aggregatorHandle.aggregateThenMaybeReset(0, 1, Attributes.empty(), /* reset= */ false); + + // Should be same object since we are in REUSABLE_DATA mode. + assertThat(firstCollection).isSameAs(secondCollection); + } } diff --git a/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/internal/aggregator/LongSumAggregatorTest.java b/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/internal/aggregator/LongSumAggregatorTest.java index 11b98233b07..5ec6f4be28d 100644 --- a/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/internal/aggregator/LongSumAggregatorTest.java +++ b/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/internal/aggregator/LongSumAggregatorTest.java @@ -6,7 +6,6 @@ package io.opentelemetry.sdk.metrics.internal.aggregator; import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.assertThat; -import static org.assertj.core.api.Assertions.assertThat; import io.opentelemetry.api.common.AttributeKey; import io.opentelemetry.api.common.Attributes; @@ -15,6 +14,7 @@ import io.opentelemetry.api.trace.TraceState; import io.opentelemetry.context.Context; import io.opentelemetry.sdk.common.InstrumentationScopeInfo; +import io.opentelemetry.sdk.common.export.MemoryMode; import io.opentelemetry.sdk.metrics.InstrumentType; import io.opentelemetry.sdk.metrics.InstrumentValueType; import io.opentelemetry.sdk.metrics.data.AggregationTemporality; @@ -33,6 +33,8 @@ import java.util.List; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.EnumSource; import org.mockito.Mock; import org.mockito.Mockito; import org.mockito.junit.jupiter.MockitoExtension; @@ -47,24 +49,33 @@ class LongSumAggregatorTest { private static final InstrumentationScopeInfo library = InstrumentationScopeInfo.empty(); private static final MetricDescriptor metricDescriptor = MetricDescriptor.create("name", "description", "unit"); - private static final LongSumAggregator aggregator = - new LongSumAggregator( - InstrumentDescriptor.create( - "instrument_name", - "instrument_description", - "instrument_unit", - InstrumentType.COUNTER, - InstrumentValueType.LONG, - Advice.empty()), - ExemplarReservoir::longNoSamples); + private LongSumAggregator aggregator; - @Test - void createHandle() { + private void init(MemoryMode memoryMode) { + aggregator = + new LongSumAggregator( + InstrumentDescriptor.create( + "instrument_name", + "instrument_description", + "instrument_unit", + InstrumentType.COUNTER, + InstrumentValueType.LONG, + Advice.empty()), + ExemplarReservoir::longNoSamples, + memoryMode); + } + + @ParameterizedTest + @EnumSource(MemoryMode.class) + void createHandle(MemoryMode memoryMode) { + init(memoryMode); assertThat(aggregator.createHandle()).isInstanceOf(LongSumAggregator.Handle.class); } - @Test - void multipleRecords() { + @ParameterizedTest + @EnumSource(MemoryMode.class) + void multipleRecords(MemoryMode memoryMode) { + init(memoryMode); AggregatorHandle aggregatorHandle = aggregator.createHandle(); aggregatorHandle.recordLong(12); aggregatorHandle.recordLong(12); @@ -78,8 +89,10 @@ void multipleRecords() { .isEqualTo(12 * 5); } - @Test - void multipleRecords_WithNegatives() { + @ParameterizedTest + @EnumSource(MemoryMode.class) + void multipleRecords_WithNegatives(MemoryMode memoryMode) { + init(memoryMode); AggregatorHandle aggregatorHandle = aggregator.createHandle(); aggregatorHandle.recordLong(12); aggregatorHandle.recordLong(12); @@ -94,8 +107,10 @@ void multipleRecords_WithNegatives() { .isEqualTo(14); } - @Test - void aggregateThenMaybeReset() { + @ParameterizedTest + @EnumSource(MemoryMode.class) + void aggregateThenMaybeReset(MemoryMode memoryMode) { + init(memoryMode); AggregatorHandle aggregatorHandle = aggregator.createHandle(); aggregatorHandle.recordLong(13); @@ -115,8 +130,9 @@ void aggregateThenMaybeReset() { .isEqualTo(-13); } - @Test - void aggregateThenMaybeReset_WithExemplars() { + @ParameterizedTest + @EnumSource(MemoryMode.class) + void aggregateThenMaybeReset_WithExemplars(MemoryMode memoryMode) { Attributes attributes = Attributes.builder().put("test", "value").build(); LongExemplarData exemplar = ImmutableLongExemplarData.create( @@ -139,7 +155,8 @@ void aggregateThenMaybeReset_WithExemplars() { InstrumentType.COUNTER, InstrumentValueType.LONG, Advice.empty()), - () -> reservoir); + () -> reservoir, + memoryMode); AggregatorHandle aggregatorHandle = aggregator.createHandle(); aggregatorHandle.recordLong(0, attributes, Context.root()); assertThat( @@ -147,8 +164,9 @@ void aggregateThenMaybeReset_WithExemplars() { .isEqualTo(ImmutableLongPointData.create(0, 1, Attributes.empty(), 0, exemplars)); } - @Test - void mergeAndDiff() { + @ParameterizedTest + @EnumSource(MemoryMode.class) + void mergeAndDiff(MemoryMode memoryMode) { LongExemplarData exemplar = ImmutableLongExemplarData.create( Attributes.empty(), @@ -171,7 +189,8 @@ void mergeAndDiff() { instrumentType, InstrumentValueType.LONG, Advice.empty()), - ExemplarReservoir::longNoSamples); + ExemplarReservoir::longNoSamples, + memoryMode); LongPointData diffed = aggregator.diff( @@ -187,8 +206,10 @@ void mergeAndDiff() { } } - @Test - void diffInPlace() { + @ParameterizedTest + @EnumSource(MemoryMode.class) + void diffInPlace(MemoryMode memoryMode) { + init(memoryMode); Attributes attributes = Attributes.builder().put("test", "value").build(); LongExemplarData exemplar = ImmutableLongExemplarData.create( @@ -229,8 +250,10 @@ void diffInPlace() { assertThat(previous.getExemplars()).isEqualTo(current.getExemplars()); } - @Test - void copyPoint() { + @ParameterizedTest + @EnumSource(MemoryMode.class) + void copyPoint(MemoryMode memoryMode) { + init(memoryMode); MutableLongPointData pointData = (MutableLongPointData) aggregator.createReusablePoint(); Attributes attributes = Attributes.of(AttributeKey.longKey("test"), 100L); @@ -272,8 +295,10 @@ void copyPoint() { assertThat(toPointData.getExemplars()).isEqualTo(pointData.getExemplars()); } - @Test - void toMetricData() { + @ParameterizedTest + @EnumSource(MemoryMode.class) + void toMetricData(MemoryMode memoryMode) { + init(memoryMode); AggregatorHandle aggregatorHandle = aggregator.createHandle(); aggregatorHandle.recordLong(10); @@ -303,8 +328,10 @@ void toMetricData() { .hasValue(10))); } - @Test - void toMetricDataWithExemplars() { + @ParameterizedTest + @EnumSource(MemoryMode.class) + void toMetricDataWithExemplars(MemoryMode memoryMode) { + init(memoryMode); Attributes attributes = Attributes.builder().put("test", "value").build(); LongExemplarData exemplar = ImmutableLongExemplarData.create( @@ -329,4 +356,21 @@ void toMetricDataWithExemplars() { .hasLongSumSatisfying( sum -> sum.hasPointsSatisfying(point -> point.hasValue(1).hasExemplars(exemplar))); } + + @Test + void sameObjectReturnedOnReusableDataMemoryMode() { + init(MemoryMode.REUSABLE_DATA); + AggregatorHandle aggregatorHandle = aggregator.createHandle(); + + aggregatorHandle.recordLong(1L); + LongPointData firstCollection = + aggregatorHandle.aggregateThenMaybeReset(0, 1, Attributes.empty(), /* reset= */ false); + + aggregatorHandle.recordLong(1L); + LongPointData secondCollection = + aggregatorHandle.aggregateThenMaybeReset(0, 1, Attributes.empty(), /* reset= */ false); + + // Should be same object since we are in REUSABLE_DATA mode. + assertThat(firstCollection).isSameAs(secondCollection); + } } From 8684882c06b91600ce52baaaefe1242f34aa45b8 Mon Sep 17 00:00:00 2001 From: jack-berg <34418638+jack-berg@users.noreply.github.com> Date: Wed, 31 Jan 2024 10:59:48 -0600 Subject: [PATCH 222/901] Add Compressor SPI support to OtlpGrpc{Signal}Exporters (#6103) --- .../internal/compression/CompressorUtil.java | 28 +++++++-------- .../internal/grpc/GrpcExporterBuilder.java | 16 +++++---- .../internal/grpc/GrpcSenderProvider.java | 3 +- .../reflect-config.json | 4 +++ .../grpc/GrpcExporterBuilderTest.java | 15 ++++---- .../otlp/trace/OltpExporterBenchmark.java | 2 +- .../OtlpHttpLogRecordExporterBuilder.java | 21 ++++------- .../OtlpHttpMetricExporterBuilder.java | 21 ++++------- .../trace/OtlpHttpSpanExporterBuilder.java | 21 ++++------- .../OtlpGrpcLogRecordExporterBuilder.java | 14 ++++---- .../OtlpGrpcMetricExporterBuilder.java | 14 ++++---- .../trace/OtlpGrpcSpanExporterBuilder.java | 14 ++++---- .../AbstractGrpcTelemetryExporterTest.java | 35 ++++++++++++++----- .../internal/UpstreamGrpcSenderProvider.java | 27 ++++++++++++-- .../okhttp/internal/GrpcRequestBody.java | 17 ++++----- .../okhttp/internal/OkHttpGrpcSender.java | 13 +++---- .../internal/OkHttpGrpcSenderProvider.java | 5 +-- .../internal/OkHttpGrpcSuppressionTest.java | 2 +- .../jaeger/sampler/OkHttpGrpcService.java | 2 +- 19 files changed, 156 insertions(+), 118 deletions(-) diff --git a/exporters/common/src/main/java/io/opentelemetry/exporter/internal/compression/CompressorUtil.java b/exporters/common/src/main/java/io/opentelemetry/exporter/internal/compression/CompressorUtil.java index 6a777f759ba..9748ea508ad 100644 --- a/exporters/common/src/main/java/io/opentelemetry/exporter/internal/compression/CompressorUtil.java +++ b/exporters/common/src/main/java/io/opentelemetry/exporter/internal/compression/CompressorUtil.java @@ -5,11 +5,14 @@ package io.opentelemetry.exporter.internal.compression; -import java.util.Collections; +import static io.opentelemetry.api.internal.Utils.checkArgument; +import static java.util.stream.Collectors.joining; + import java.util.HashMap; import java.util.Map; import java.util.ServiceLoader; import java.util.Set; +import javax.annotation.Nullable; /** * Utilities for resolving SPI {@link Compressor}s. @@ -25,23 +28,20 @@ public final class CompressorUtil { private CompressorUtil() {} - /** Get list of loaded compressors, named according to {@link Compressor#getEncoding()}. */ - public static Set supportedCompressors() { - return Collections.unmodifiableSet(compressorRegistry.keySet()); - } - /** - * Resolve the {@link Compressor} with the {@link Compressor#getEncoding()} equal to the {@code - * encoding}. + * Validate that the {@code compressionMethod} is "none" or matches a registered compressor. * + * @return {@code null} if {@code compressionMethod} is "none" or the registered compressor * @throws IllegalArgumentException if no match is found */ - public static Compressor resolveCompressor(String encoding) { - Compressor compressor = compressorRegistry.get(encoding); - if (compressor == null) { - throw new IllegalArgumentException( - "Could not resolve compressor for encoding \"" + encoding + "\"."); - } + @Nullable + public static Compressor validateAndResolveCompressor(String compressionMethod) { + Set supportedEncodings = compressorRegistry.keySet(); + Compressor compressor = compressorRegistry.get(compressionMethod); + checkArgument( + "none".equals(compressionMethod) || compressor != null, + "Unsupported compressionMethod. Compression method must be \"none\" or one of: " + + supportedEncodings.stream().collect(joining(",", "[", "]"))); return compressor; } diff --git a/exporters/common/src/main/java/io/opentelemetry/exporter/internal/grpc/GrpcExporterBuilder.java b/exporters/common/src/main/java/io/opentelemetry/exporter/internal/grpc/GrpcExporterBuilder.java index bef1db06224..df9bb403099 100644 --- a/exporters/common/src/main/java/io/opentelemetry/exporter/internal/grpc/GrpcExporterBuilder.java +++ b/exporters/common/src/main/java/io/opentelemetry/exporter/internal/grpc/GrpcExporterBuilder.java @@ -12,6 +12,7 @@ import io.opentelemetry.api.metrics.MeterProvider; import io.opentelemetry.exporter.internal.ExporterBuilderUtil; import io.opentelemetry.exporter.internal.TlsConfigHelper; +import io.opentelemetry.exporter.internal.compression.Compressor; import io.opentelemetry.exporter.internal.marshal.Marshaler; import io.opentelemetry.sdk.common.export.RetryPolicy; import java.net.URI; @@ -21,6 +22,7 @@ import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Optional; import java.util.ServiceLoader; import java.util.StringJoiner; import java.util.concurrent.TimeUnit; @@ -51,7 +53,7 @@ public class GrpcExporterBuilder { private long timeoutNanos; private URI endpoint; - private boolean compressionEnabled = false; + @Nullable private Compressor compressor; private final Map constantHeaders = new HashMap<>(); private Supplier> headerSupplier = Collections::emptyMap; private TlsConfigHelper tlsConfigHelper = new TlsConfigHelper(); @@ -95,8 +97,8 @@ public GrpcExporterBuilder setEndpoint(String endpoint) { return this; } - public GrpcExporterBuilder setCompression(String compressionMethod) { - this.compressionEnabled = compressionMethod.equals("gzip"); + public GrpcExporterBuilder setCompression(@Nullable Compressor compressor) { + this.compressor = compressor; return this; } @@ -150,7 +152,7 @@ public GrpcExporterBuilder copy() { copy.timeoutNanos = timeoutNanos; copy.endpoint = endpoint; - copy.compressionEnabled = compressionEnabled; + copy.compressor = compressor; copy.constantHeaders.putAll(constantHeaders); copy.headerSupplier = headerSupplier; copy.tlsConfigHelper = tlsConfigHelper.copy(); @@ -189,7 +191,7 @@ public GrpcExporter build() { grpcSenderProvider.createSender( endpoint, grpcEndpointPath, - compressionEnabled, + compressor, timeoutNanos, headerSupplier, grpcChannel, @@ -212,7 +214,9 @@ public String toString(boolean includePrefixAndSuffix) { joiner.add("endpoint=" + endpoint.toString()); joiner.add("endpointPath=" + grpcEndpointPath); joiner.add("timeoutNanos=" + timeoutNanos); - joiner.add("compressionEnabled=" + compressionEnabled); + joiner.add( + "compressorEncoding=" + + Optional.ofNullable(compressor).map(Compressor::getEncoding).orElse(null)); StringJoiner headersJoiner = new StringJoiner(", ", "Headers{", "}"); constantHeaders.forEach((key, value) -> headersJoiner.add(key + "=OBFUSCATED")); Map headers = headerSupplier.get(); diff --git a/exporters/common/src/main/java/io/opentelemetry/exporter/internal/grpc/GrpcSenderProvider.java b/exporters/common/src/main/java/io/opentelemetry/exporter/internal/grpc/GrpcSenderProvider.java index c8c584f6e58..e7618e9bfaf 100644 --- a/exporters/common/src/main/java/io/opentelemetry/exporter/internal/grpc/GrpcSenderProvider.java +++ b/exporters/common/src/main/java/io/opentelemetry/exporter/internal/grpc/GrpcSenderProvider.java @@ -6,6 +6,7 @@ package io.opentelemetry.exporter.internal.grpc; import io.grpc.Channel; +import io.opentelemetry.exporter.internal.compression.Compressor; import io.opentelemetry.exporter.internal.marshal.Marshaler; import io.opentelemetry.sdk.common.export.RetryPolicy; import java.net.URI; @@ -31,7 +32,7 @@ public interface GrpcSenderProvider { GrpcSender createSender( URI endpoint, String endpointPath, - boolean compressionEnabled, + @Nullable Compressor compressor, long timeoutNanos, Supplier>> headersSupplier, @Nullable Object managedChannel, diff --git a/exporters/common/src/main/resources/META-INF/native-image/io.opentelemetry.opentelemetry-exporter-common/reflect-config.json b/exporters/common/src/main/resources/META-INF/native-image/io.opentelemetry.opentelemetry-exporter-common/reflect-config.json index 033ccf44f0c..1d93899460b 100644 --- a/exporters/common/src/main/resources/META-INF/native-image/io.opentelemetry.opentelemetry-exporter-common/reflect-config.json +++ b/exporters/common/src/main/resources/META-INF/native-image/io.opentelemetry.opentelemetry-exporter-common/reflect-config.json @@ -6,5 +6,9 @@ { "name":"io.opentelemetry.sdk.common.export.RetryPolicy", "queryAllDeclaredMethods":true + }, + { + "name":"io.opentelemetry.exporter.internal.compression.Compressor", + "queryAllDeclaredMethods":true } ] diff --git a/exporters/common/src/test/java/io/opentelemetry/exporter/internal/grpc/GrpcExporterBuilderTest.java b/exporters/common/src/test/java/io/opentelemetry/exporter/internal/grpc/GrpcExporterBuilderTest.java index dcf1ea64387..e562729ae1d 100644 --- a/exporters/common/src/test/java/io/opentelemetry/exporter/internal/grpc/GrpcExporterBuilderTest.java +++ b/exporters/common/src/test/java/io/opentelemetry/exporter/internal/grpc/GrpcExporterBuilderTest.java @@ -7,6 +7,7 @@ import static org.assertj.core.api.Assertions.assertThat; +import io.opentelemetry.exporter.internal.compression.GzipCompressor; import io.opentelemetry.exporter.internal.marshal.Marshaler; import java.net.URI; import org.junit.jupiter.api.BeforeEach; @@ -25,27 +26,27 @@ void setUp() { @Test void compressionDefault() { - assertThat(builder).extracting("compressionEnabled").isEqualTo(false); + assertThat(builder).extracting("compressor").isNull(); } @Test void compressionNone() { - builder.setCompression("none"); + builder.setCompression(null); - assertThat(builder).extracting("compressionEnabled").isEqualTo(false); + assertThat(builder).extracting("compressor").isNull(); } @Test void compressionGzip() { - builder.setCompression("gzip"); + builder.setCompression(GzipCompressor.getInstance()); - assertThat(builder).extracting("compressionEnabled").isEqualTo(true); + assertThat(builder).extracting("compressor").isEqualTo(GzipCompressor.getInstance()); } @Test void compressionEnabledAndDisabled() { - builder.setCompression("gzip").setCompression("none"); + builder.setCompression(GzipCompressor.getInstance()).setCompression(null); - assertThat(builder).extracting("compressionEnabled").isEqualTo(false); + assertThat(builder).extracting("compressor").isNull(); } } diff --git a/exporters/otlp/all/src/jmh/java/io/opentelemetry/exporter/otlp/trace/OltpExporterBenchmark.java b/exporters/otlp/all/src/jmh/java/io/opentelemetry/exporter/otlp/trace/OltpExporterBenchmark.java index ef620333474..dd8ca40dba2 100644 --- a/exporters/otlp/all/src/jmh/java/io/opentelemetry/exporter/otlp/trace/OltpExporterBenchmark.java +++ b/exporters/otlp/all/src/jmh/java/io/opentelemetry/exporter/otlp/trace/OltpExporterBenchmark.java @@ -98,7 +98,7 @@ public void setUp() { URI.create("http://localhost:" + server.activeLocalPort()) .resolve(OtlpGrpcSpanExporterBuilder.GRPC_ENDPOINT_PATH) .toString(), - /* compressionEnabled= */ false, + null, 10, Collections::emptyMap, null, diff --git a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/logs/OtlpHttpLogRecordExporterBuilder.java b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/logs/OtlpHttpLogRecordExporterBuilder.java index 5861cd15832..0b6253336b8 100644 --- a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/logs/OtlpHttpLogRecordExporterBuilder.java +++ b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/logs/OtlpHttpLogRecordExporterBuilder.java @@ -7,10 +7,11 @@ import static io.opentelemetry.api.internal.Utils.checkArgument; import static java.util.Objects.requireNonNull; -import static java.util.stream.Collectors.joining; import io.opentelemetry.api.GlobalOpenTelemetry; import io.opentelemetry.api.metrics.MeterProvider; +import io.opentelemetry.exporter.internal.compression.Compressor; +import io.opentelemetry.exporter.internal.compression.CompressorProvider; import io.opentelemetry.exporter.internal.compression.CompressorUtil; import io.opentelemetry.exporter.internal.http.HttpExporterBuilder; import io.opentelemetry.exporter.internal.otlp.logs.LogsRequestMarshaler; @@ -18,7 +19,6 @@ import io.opentelemetry.sdk.common.export.RetryPolicy; import java.time.Duration; import java.util.Map; -import java.util.Set; import java.util.concurrent.TimeUnit; import java.util.function.Supplier; import javax.net.ssl.SSLContext; @@ -99,21 +99,14 @@ public OtlpHttpLogRecordExporterBuilder setEndpoint(String endpoint) { } /** - * Sets the method used to compress payloads. If unset, compression is disabled. Currently - * supported compression methods include "gzip" and "none". + * Sets the method used to compress payloads. If unset, compression is disabled. Compression + * method "gzip" and "none" are supported out of the box. Support for additional compression + * methods is available by implementing {@link Compressor} and {@link CompressorProvider}. */ public OtlpHttpLogRecordExporterBuilder setCompression(String compressionMethod) { requireNonNull(compressionMethod, "compressionMethod"); - if (compressionMethod.equals("none")) { - delegate.setCompression(null); - return this; - } - Set supportedCompressionMethods = CompressorUtil.supportedCompressors(); - checkArgument( - supportedCompressionMethods.contains(compressionMethod), - "Unsupported compressionMethod. Compression method must be \"none\" or one of: " - + supportedCompressionMethods.stream().collect(joining(",", "[", "]"))); - delegate.setCompression(CompressorUtil.resolveCompressor(compressionMethod)); + Compressor compressor = CompressorUtil.validateAndResolveCompressor(compressionMethod); + delegate.setCompression(compressor); return this; } diff --git a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/metrics/OtlpHttpMetricExporterBuilder.java b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/metrics/OtlpHttpMetricExporterBuilder.java index 9f97d7b3f9e..d4b2e57df88 100644 --- a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/metrics/OtlpHttpMetricExporterBuilder.java +++ b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/metrics/OtlpHttpMetricExporterBuilder.java @@ -7,9 +7,10 @@ import static io.opentelemetry.api.internal.Utils.checkArgument; import static java.util.Objects.requireNonNull; -import static java.util.stream.Collectors.joining; import io.opentelemetry.api.metrics.MeterProvider; +import io.opentelemetry.exporter.internal.compression.Compressor; +import io.opentelemetry.exporter.internal.compression.CompressorProvider; import io.opentelemetry.exporter.internal.compression.CompressorUtil; import io.opentelemetry.exporter.internal.http.HttpExporterBuilder; import io.opentelemetry.exporter.internal.otlp.metrics.MetricsRequestMarshaler; @@ -21,7 +22,6 @@ import io.opentelemetry.sdk.metrics.export.MetricExporter; import java.time.Duration; import java.util.Map; -import java.util.Set; import java.util.concurrent.TimeUnit; import java.util.function.Supplier; import javax.net.ssl.SSLContext; @@ -111,21 +111,14 @@ public OtlpHttpMetricExporterBuilder setEndpoint(String endpoint) { } /** - * Sets the method used to compress payloads. If unset, compression is disabled. Currently - * supported compression methods include "gzip" and "none". + * Sets the method used to compress payloads. If unset, compression is disabled. Compression + * method "gzip" and "none" are supported out of the box. Support for additional compression + * methods is available by implementing {@link Compressor} and {@link CompressorProvider}. */ public OtlpHttpMetricExporterBuilder setCompression(String compressionMethod) { requireNonNull(compressionMethod, "compressionMethod"); - if (compressionMethod.equals("none")) { - delegate.setCompression(null); - return this; - } - Set supportedCompressionMethods = CompressorUtil.supportedCompressors(); - checkArgument( - supportedCompressionMethods.contains(compressionMethod), - "Unsupported compressionMethod. Compression method must be \"none\" or one of: " - + supportedCompressionMethods.stream().collect(joining(",", "[", "]"))); - delegate.setCompression(CompressorUtil.resolveCompressor(compressionMethod)); + Compressor compressor = CompressorUtil.validateAndResolveCompressor(compressionMethod); + delegate.setCompression(compressor); return this; } diff --git a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/trace/OtlpHttpSpanExporterBuilder.java b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/trace/OtlpHttpSpanExporterBuilder.java index ed5975aa4b2..c7e3549428a 100644 --- a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/trace/OtlpHttpSpanExporterBuilder.java +++ b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/trace/OtlpHttpSpanExporterBuilder.java @@ -7,10 +7,11 @@ import static io.opentelemetry.api.internal.Utils.checkArgument; import static java.util.Objects.requireNonNull; -import static java.util.stream.Collectors.joining; import io.opentelemetry.api.GlobalOpenTelemetry; import io.opentelemetry.api.metrics.MeterProvider; +import io.opentelemetry.exporter.internal.compression.Compressor; +import io.opentelemetry.exporter.internal.compression.CompressorProvider; import io.opentelemetry.exporter.internal.compression.CompressorUtil; import io.opentelemetry.exporter.internal.http.HttpExporterBuilder; import io.opentelemetry.exporter.internal.otlp.traces.TraceRequestMarshaler; @@ -18,7 +19,6 @@ import io.opentelemetry.sdk.common.export.RetryPolicy; import java.time.Duration; import java.util.Map; -import java.util.Set; import java.util.concurrent.TimeUnit; import java.util.function.Supplier; import javax.net.ssl.SSLContext; @@ -99,21 +99,14 @@ public OtlpHttpSpanExporterBuilder setEndpoint(String endpoint) { } /** - * Sets the method used to compress payloads. If unset, compression is disabled. Currently - * supported compression methods include "gzip" and "none". + * Sets the method used to compress payloads. If unset, compression is disabled. Compression + * method "gzip" and "none" are supported out of the box. Support for additional compression + * methods is available by implementing {@link Compressor} and {@link CompressorProvider}. */ public OtlpHttpSpanExporterBuilder setCompression(String compressionMethod) { requireNonNull(compressionMethod, "compressionMethod"); - if (compressionMethod.equals("none")) { - delegate.setCompression(null); - return this; - } - Set supportedCompressionMethods = CompressorUtil.supportedCompressors(); - checkArgument( - supportedCompressionMethods.contains(compressionMethod), - "Unsupported compressionMethod. Compression method must be \"none\" or one of: " - + supportedCompressionMethods.stream().collect(joining(",", "[", "]"))); - delegate.setCompression(CompressorUtil.resolveCompressor(compressionMethod)); + Compressor compressor = CompressorUtil.validateAndResolveCompressor(compressionMethod); + delegate.setCompression(compressor); return this; } diff --git a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/logs/OtlpGrpcLogRecordExporterBuilder.java b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/logs/OtlpGrpcLogRecordExporterBuilder.java index b04014fc729..3a50b3e1d1c 100644 --- a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/logs/OtlpGrpcLogRecordExporterBuilder.java +++ b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/logs/OtlpGrpcLogRecordExporterBuilder.java @@ -11,6 +11,9 @@ import io.grpc.ManagedChannel; import io.opentelemetry.api.GlobalOpenTelemetry; import io.opentelemetry.api.metrics.MeterProvider; +import io.opentelemetry.exporter.internal.compression.Compressor; +import io.opentelemetry.exporter.internal.compression.CompressorProvider; +import io.opentelemetry.exporter.internal.compression.CompressorUtil; import io.opentelemetry.exporter.internal.grpc.GrpcExporterBuilder; import io.opentelemetry.exporter.internal.otlp.logs.LogsRequestMarshaler; import io.opentelemetry.exporter.otlp.internal.OtlpUserAgent; @@ -109,15 +112,14 @@ public OtlpGrpcLogRecordExporterBuilder setEndpoint(String endpoint) { } /** - * Sets the method used to compress payloads. If unset, compression is disabled. Currently - * supported compression methods include "gzip" and "none". + * Sets the method used to compress payloads. If unset, compression is disabled. Compression + * method "gzip" and "none" are supported out of the box. Support for additional compression + * methods is available by implementing {@link Compressor} and {@link CompressorProvider}. */ public OtlpGrpcLogRecordExporterBuilder setCompression(String compressionMethod) { requireNonNull(compressionMethod, "compressionMethod"); - checkArgument( - compressionMethod.equals("gzip") || compressionMethod.equals("none"), - "Unsupported compression method. Supported compression methods include: gzip, none."); - delegate.setCompression(compressionMethod); + Compressor compressor = CompressorUtil.validateAndResolveCompressor(compressionMethod); + delegate.setCompression(compressor); return this; } diff --git a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/metrics/OtlpGrpcMetricExporterBuilder.java b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/metrics/OtlpGrpcMetricExporterBuilder.java index 43a0dbdcc41..302eee845ed 100644 --- a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/metrics/OtlpGrpcMetricExporterBuilder.java +++ b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/metrics/OtlpGrpcMetricExporterBuilder.java @@ -10,6 +10,9 @@ import io.grpc.ManagedChannel; import io.opentelemetry.api.metrics.MeterProvider; +import io.opentelemetry.exporter.internal.compression.Compressor; +import io.opentelemetry.exporter.internal.compression.CompressorProvider; +import io.opentelemetry.exporter.internal.compression.CompressorUtil; import io.opentelemetry.exporter.internal.grpc.GrpcExporterBuilder; import io.opentelemetry.exporter.internal.otlp.metrics.MetricsRequestMarshaler; import io.opentelemetry.exporter.otlp.internal.OtlpUserAgent; @@ -121,15 +124,14 @@ public OtlpGrpcMetricExporterBuilder setEndpoint(String endpoint) { } /** - * Sets the method used to compress payloads. If unset, compression is disabled. Currently - * supported compression methods include "gzip" and "none". + * Sets the method used to compress payloads. If unset, compression is disabled. Compression + * method "gzip" and "none" are supported out of the box. Support for additional compression + * methods is available by implementing {@link Compressor} and {@link CompressorProvider}. */ public OtlpGrpcMetricExporterBuilder setCompression(String compressionMethod) { requireNonNull(compressionMethod, "compressionMethod"); - checkArgument( - compressionMethod.equals("gzip") || compressionMethod.equals("none"), - "Unsupported compression method. Supported compression methods include: gzip, none."); - delegate.setCompression(compressionMethod); + Compressor compressor = CompressorUtil.validateAndResolveCompressor(compressionMethod); + delegate.setCompression(compressor); return this; } diff --git a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/trace/OtlpGrpcSpanExporterBuilder.java b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/trace/OtlpGrpcSpanExporterBuilder.java index 884a8dea172..cac7cd5cb85 100644 --- a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/trace/OtlpGrpcSpanExporterBuilder.java +++ b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/trace/OtlpGrpcSpanExporterBuilder.java @@ -11,6 +11,9 @@ import io.grpc.ManagedChannel; import io.opentelemetry.api.GlobalOpenTelemetry; import io.opentelemetry.api.metrics.MeterProvider; +import io.opentelemetry.exporter.internal.compression.Compressor; +import io.opentelemetry.exporter.internal.compression.CompressorProvider; +import io.opentelemetry.exporter.internal.compression.CompressorUtil; import io.opentelemetry.exporter.internal.grpc.GrpcExporterBuilder; import io.opentelemetry.exporter.internal.otlp.traces.TraceRequestMarshaler; import io.opentelemetry.exporter.otlp.internal.OtlpUserAgent; @@ -105,15 +108,14 @@ public OtlpGrpcSpanExporterBuilder setEndpoint(String endpoint) { } /** - * Sets the method used to compress payloads. If unset, compression is disabled. Currently - * supported compression methods include "gzip" and "none". + * Sets the method used to compress payloads. If unset, compression is disabled. Compression + * method "gzip" and "none" are supported out of the box. Support for additional compression + * methods is available by implementing {@link Compressor} and {@link CompressorProvider}. */ public OtlpGrpcSpanExporterBuilder setCompression(String compressionMethod) { requireNonNull(compressionMethod, "compressionMethod"); - checkArgument( - compressionMethod.equals("gzip") || compressionMethod.equals("none"), - "Unsupported compression method. Supported compression methods include: gzip, none."); - delegate.setCompression(compressionMethod); + Compressor compressor = CompressorUtil.validateAndResolveCompressor(compressionMethod); + delegate.setCompression(compressor); return this; } diff --git a/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/AbstractGrpcTelemetryExporterTest.java b/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/AbstractGrpcTelemetryExporterTest.java index 0b3d79a2690..f3310eb36d8 100644 --- a/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/AbstractGrpcTelemetryExporterTest.java +++ b/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/AbstractGrpcTelemetryExporterTest.java @@ -26,9 +26,11 @@ import io.github.netmikey.logunit.api.LogCapturer; import io.grpc.ManagedChannel; import io.opentelemetry.exporter.internal.TlsUtil; +import io.opentelemetry.exporter.internal.compression.GzipCompressor; import io.opentelemetry.exporter.internal.grpc.GrpcExporter; import io.opentelemetry.exporter.internal.grpc.MarshalerServiceStub; import io.opentelemetry.exporter.internal.marshal.Marshaler; +import io.opentelemetry.exporter.otlp.testing.internal.compressor.Base64Compressor; import io.opentelemetry.internal.testing.slf4j.SuppressLogger; import io.opentelemetry.proto.collector.logs.v1.ExportLogsServiceRequest; import io.opentelemetry.proto.collector.logs.v1.ExportLogsServiceResponse; @@ -272,9 +274,7 @@ void compressionWithNone() { assumeThat(exporter.unwrap()) .extracting("delegate.grpcSender") .matches(sender -> sender.getClass().getSimpleName().equals("OkHttpGrpcSender")); - assertThat(exporter.unwrap()) - .extracting("delegate.grpcSender.compressionEnabled") - .isEqualTo(false); + assertThat(exporter.unwrap()).extracting("delegate.grpcSender.compressor").isNull(); } finally { exporter.shutdown(); } @@ -290,8 +290,25 @@ void compressionWithGzip() { .extracting("delegate.grpcSender") .matches(sender -> sender.getClass().getSimpleName().equals("OkHttpGrpcSender")); assertThat(exporter.unwrap()) - .extracting("delegate.grpcSender.compressionEnabled") - .isEqualTo(true); + .extracting("delegate.grpcSender.compressor") + .isEqualTo(GzipCompressor.getInstance()); + } finally { + exporter.shutdown(); + } + } + + @Test + void compressionWithSpiCompressor() { + TelemetryExporter exporter = + exporterBuilder().setEndpoint(server.httpUri().toString()).setCompression("base64").build(); + try { + // UpstreamGrpcSender doesn't support compression, so we skip the assertion + assumeThat(exporter.unwrap()) + .extracting("delegate.grpcSender") + .matches(sender -> sender.getClass().getSimpleName().equals("OkHttpGrpcSender")); + assertThat(exporter.unwrap()) + .extracting("delegate.grpcSender.compressor") + .isEqualTo(Base64Compressor.getInstance()); } finally { exporter.shutdown(); } @@ -703,6 +720,8 @@ void validConfig() { .doesNotThrowAnyException(); assertThatCode(() -> exporterBuilder().setCompression("gzip")).doesNotThrowAnyException(); + // SPI compressor available for this test but not packaged with OTLP exporter + assertThatCode(() -> exporterBuilder().setCompression("base64")).doesNotThrowAnyException(); assertThatCode(() -> exporterBuilder().setCompression("none")).doesNotThrowAnyException(); assertThatCode(() -> exporterBuilder().addHeader("foo", "bar").addHeader("baz", "qux")) @@ -745,7 +764,7 @@ void invalidConfig() { assertThatThrownBy(() -> exporterBuilder().setCompression("foo")) .isInstanceOf(IllegalArgumentException.class) .hasMessage( - "Unsupported compression method. Supported compression methods include: gzip, none."); + "Unsupported compressionMethod. Compression method must be \"none\" or one of: [base64,gzip]"); } @Test @@ -821,7 +840,7 @@ void stringRepresentation() throws IOException, CertificateEncodingException { + "timeoutNanos=" + TimeUnit.SECONDS.toNanos(10) + ", " - + "compressionEnabled=false, " + + "compressorEncoding=null, " + "headers=Headers\\{User-Agent=OBFUSCATED\\}" + ".*" // Maybe additional grpcChannel field + "\\}"); @@ -858,7 +877,7 @@ void stringRepresentation() throws IOException, CertificateEncodingException { + "timeoutNanos=" + TimeUnit.SECONDS.toNanos(5) + ", " - + "compressionEnabled=true, " + + "compressorEncoding=gzip, " + "headers=Headers\\{.*foo=OBFUSCATED.*\\}, " + "retryPolicy=RetryPolicy\\{maxAttempts=2, initialBackoff=PT0\\.05S, maxBackoff=PT3S, backoffMultiplier=1\\.3\\}" + ".*" // Maybe additional grpcChannel field diff --git a/exporters/sender/grpc-managed-channel/src/main/java/io/opentelemetry/exporter/sender/grpc/managedchannel/internal/UpstreamGrpcSenderProvider.java b/exporters/sender/grpc-managed-channel/src/main/java/io/opentelemetry/exporter/sender/grpc/managedchannel/internal/UpstreamGrpcSenderProvider.java index a4effdbd09c..880d288417e 100644 --- a/exporters/sender/grpc-managed-channel/src/main/java/io/opentelemetry/exporter/sender/grpc/managedchannel/internal/UpstreamGrpcSenderProvider.java +++ b/exporters/sender/grpc-managed-channel/src/main/java/io/opentelemetry/exporter/sender/grpc/managedchannel/internal/UpstreamGrpcSenderProvider.java @@ -7,13 +7,17 @@ import io.grpc.Channel; import io.grpc.Codec; +import io.grpc.CompressorRegistry; import io.grpc.ManagedChannel; import io.grpc.ManagedChannelBuilder; +import io.opentelemetry.exporter.internal.compression.Compressor; import io.opentelemetry.exporter.internal.grpc.GrpcSender; import io.opentelemetry.exporter.internal.grpc.GrpcSenderProvider; import io.opentelemetry.exporter.internal.grpc.MarshalerServiceStub; import io.opentelemetry.exporter.internal.marshal.Marshaler; import io.opentelemetry.sdk.common.export.RetryPolicy; +import java.io.IOException; +import java.io.OutputStream; import java.net.URI; import java.util.List; import java.util.Map; @@ -35,7 +39,7 @@ public class UpstreamGrpcSenderProvider implements GrpcSenderProvider { public GrpcSender createSender( URI endpoint, String endpointPath, - boolean compressionEnabled, + @Nullable Compressor compressor, long timeoutNanos, Supplier>> headersSupplier, @Nullable Object managedChannel, @@ -60,12 +64,29 @@ public GrpcSender createSender( } } - Codec codec = compressionEnabled ? new Codec.Gzip() : Codec.Identity.NONE; + String compression = Codec.Identity.NONE.getMessageEncoding(); + if (compressor != null) { + CompressorRegistry.getDefaultInstance() + .register( + new io.grpc.Compressor() { + @Override + public String getMessageEncoding() { + return compressor.getEncoding(); + } + + @Override + public OutputStream compress(OutputStream os) throws IOException { + return compressor.compress(os); + } + }); + compression = compressor.getEncoding(); + } + MarshalerServiceStub stub = stubFactory .get() .apply((Channel) managedChannel, authorityOverride) - .withCompression(codec.getMessageEncoding()); + .withCompression(compression); return new UpstreamGrpcSender<>(stub, shutdownChannel, timeoutNanos, headersSupplier); } diff --git a/exporters/sender/okhttp/src/main/java/io/opentelemetry/exporter/sender/okhttp/internal/GrpcRequestBody.java b/exporters/sender/okhttp/src/main/java/io/opentelemetry/exporter/sender/okhttp/internal/GrpcRequestBody.java index ca9191360db..7baa5c4dce0 100644 --- a/exporters/sender/okhttp/src/main/java/io/opentelemetry/exporter/sender/okhttp/internal/GrpcRequestBody.java +++ b/exporters/sender/okhttp/src/main/java/io/opentelemetry/exporter/sender/okhttp/internal/GrpcRequestBody.java @@ -5,6 +5,7 @@ package io.opentelemetry.exporter.sender.okhttp.internal; +import io.opentelemetry.exporter.internal.compression.Compressor; import io.opentelemetry.exporter.internal.marshal.Marshaler; import java.io.IOException; import javax.annotation.Nullable; @@ -12,7 +13,6 @@ import okhttp3.RequestBody; import okio.Buffer; import okio.BufferedSink; -import okio.GzipSink; import okio.Okio; /** @@ -33,15 +33,15 @@ public final class GrpcRequestBody extends RequestBody { private final Marshaler marshaler; private final int messageSize; private final int contentLength; - private final boolean compressed; + @Nullable private final Compressor compressor; /** Creates a new {@link GrpcRequestBody}. */ - public GrpcRequestBody(Marshaler marshaler, boolean compressed) { + public GrpcRequestBody(Marshaler marshaler, @Nullable Compressor compressor) { this.marshaler = marshaler; - this.compressed = compressed; + this.compressor = compressor; messageSize = marshaler.getBinarySerializedSize(); - if (compressed) { + if (compressor != null) { // Content length not known since we want to compress on the I/O thread. contentLength = -1; } else { @@ -62,14 +62,15 @@ public long contentLength() { @Override public void writeTo(BufferedSink sink) throws IOException { - if (!compressed) { + if (compressor == null) { sink.writeByte(UNCOMPRESSED_FLAG); sink.writeInt(messageSize); marshaler.writeBinaryTo(sink.outputStream()); } else { try (Buffer compressedBody = new Buffer()) { - try (BufferedSink gzipSink = Okio.buffer(new GzipSink(compressedBody))) { - marshaler.writeBinaryTo(gzipSink.outputStream()); + try (BufferedSink compressedSink = + Okio.buffer(Okio.sink(compressor.compress(compressedBody.outputStream())))) { + marshaler.writeBinaryTo(compressedSink.outputStream()); } sink.writeByte(COMPRESSED_FLAG); int compressedBytes = (int) compressedBody.size(); diff --git a/exporters/sender/okhttp/src/main/java/io/opentelemetry/exporter/sender/okhttp/internal/OkHttpGrpcSender.java b/exporters/sender/okhttp/src/main/java/io/opentelemetry/exporter/sender/okhttp/internal/OkHttpGrpcSender.java index 24ade7fae5a..477b3fdda59 100644 --- a/exporters/sender/okhttp/src/main/java/io/opentelemetry/exporter/sender/okhttp/internal/OkHttpGrpcSender.java +++ b/exporters/sender/okhttp/src/main/java/io/opentelemetry/exporter/sender/okhttp/internal/OkHttpGrpcSender.java @@ -25,6 +25,7 @@ import io.opentelemetry.exporter.internal.InstrumentationUtil; import io.opentelemetry.exporter.internal.RetryUtil; +import io.opentelemetry.exporter.internal.compression.Compressor; import io.opentelemetry.exporter.internal.grpc.GrpcExporterUtil; import io.opentelemetry.exporter.internal.grpc.GrpcResponse; import io.opentelemetry.exporter.internal.grpc.GrpcSender; @@ -67,12 +68,12 @@ public final class OkHttpGrpcSender implements GrpcSender>> headersSupplier; - private final boolean compressionEnabled; + @Nullable private final Compressor compressor; /** Creates a new {@link OkHttpGrpcSender}. */ public OkHttpGrpcSender( String endpoint, - boolean compressionEnabled, + @Nullable Compressor compressor, long timeoutNanos, Supplier>> headersSupplier, @Nullable RetryPolicy retryPolicy, @@ -97,7 +98,7 @@ public OkHttpGrpcSender( this.client = clientBuilder.build(); this.headersSupplier = headersSupplier; this.url = HttpUrl.get(endpoint); - this.compressionEnabled = compressionEnabled; + this.compressor = compressor; } @Override @@ -110,10 +111,10 @@ public void send(T request, Runnable onSuccess, BiConsumer values.forEach(value -> requestBuilder.addHeader(key, value))); } requestBuilder.addHeader("te", "trailers"); - if (compressionEnabled) { - requestBuilder.addHeader("grpc-encoding", "gzip"); + if (compressor != null) { + requestBuilder.addHeader("grpc-encoding", compressor.getEncoding()); } - RequestBody requestBody = new GrpcRequestBody(request, compressionEnabled); + RequestBody requestBody = new GrpcRequestBody(request, compressor); requestBuilder.post(requestBody); InstrumentationUtil.suppressInstrumentation( diff --git a/exporters/sender/okhttp/src/main/java/io/opentelemetry/exporter/sender/okhttp/internal/OkHttpGrpcSenderProvider.java b/exporters/sender/okhttp/src/main/java/io/opentelemetry/exporter/sender/okhttp/internal/OkHttpGrpcSenderProvider.java index 6ac663495b0..affaf09be68 100644 --- a/exporters/sender/okhttp/src/main/java/io/opentelemetry/exporter/sender/okhttp/internal/OkHttpGrpcSenderProvider.java +++ b/exporters/sender/okhttp/src/main/java/io/opentelemetry/exporter/sender/okhttp/internal/OkHttpGrpcSenderProvider.java @@ -6,6 +6,7 @@ package io.opentelemetry.exporter.sender.okhttp.internal; import io.grpc.Channel; +import io.opentelemetry.exporter.internal.compression.Compressor; import io.opentelemetry.exporter.internal.grpc.GrpcSender; import io.opentelemetry.exporter.internal.grpc.GrpcSenderProvider; import io.opentelemetry.exporter.internal.grpc.MarshalerServiceStub; @@ -32,7 +33,7 @@ public class OkHttpGrpcSenderProvider implements GrpcSenderProvider { public GrpcSender createSender( URI endpoint, String endpointPath, - boolean compressionEnabled, + @Nullable Compressor compressor, long timeoutNanos, Supplier>> headersSupplier, @Nullable Object managedChannel, @@ -42,7 +43,7 @@ public GrpcSender createSender( @Nullable X509TrustManager trustManager) { return new OkHttpGrpcSender<>( endpoint.resolve(endpointPath).toString(), - compressionEnabled, + compressor, timeoutNanos, headersSupplier, retryPolicy, diff --git a/exporters/sender/okhttp/src/test/java/io/opentelemetry/exporter/sender/okhttp/internal/OkHttpGrpcSuppressionTest.java b/exporters/sender/okhttp/src/test/java/io/opentelemetry/exporter/sender/okhttp/internal/OkHttpGrpcSuppressionTest.java index 482eadc1bd4..fcedd3bc25f 100644 --- a/exporters/sender/okhttp/src/test/java/io/opentelemetry/exporter/sender/okhttp/internal/OkHttpGrpcSuppressionTest.java +++ b/exporters/sender/okhttp/src/test/java/io/opentelemetry/exporter/sender/okhttp/internal/OkHttpGrpcSuppressionTest.java @@ -21,7 +21,7 @@ void send(OkHttpGrpcSender sender, Runnable onSuccess, Runnable @Override OkHttpGrpcSender createSender(String endpoint) { return new OkHttpGrpcSender<>( - "https://localhost", false, 10L, Collections::emptyMap, null, null, null); + "https://localhost", null, 10L, Collections::emptyMap, null, null, null); } protected static class DummyMarshaler extends MarshalerWithSize { diff --git a/sdk-extensions/jaeger-remote-sampler/src/main/java/io/opentelemetry/sdk/extension/trace/jaeger/sampler/OkHttpGrpcService.java b/sdk-extensions/jaeger-remote-sampler/src/main/java/io/opentelemetry/sdk/extension/trace/jaeger/sampler/OkHttpGrpcService.java index 02cc43869cb..ca1455ad3f3 100644 --- a/sdk-extensions/jaeger-remote-sampler/src/main/java/io/opentelemetry/sdk/extension/trace/jaeger/sampler/OkHttpGrpcService.java +++ b/sdk-extensions/jaeger-remote-sampler/src/main/java/io/opentelemetry/sdk/extension/trace/jaeger/sampler/OkHttpGrpcService.java @@ -53,7 +53,7 @@ public SamplingStrategyResponseUnMarshaler execute( SamplingStrategyResponseUnMarshaler responseUnmarshaller) { Request.Builder requestBuilder = new Request.Builder().url(url).headers(headers); - RequestBody requestBody = new GrpcRequestBody(exportRequest, false); + RequestBody requestBody = new GrpcRequestBody(exportRequest, null); requestBuilder.post(requestBody); try { From ecbd1f9d3d8d131588dec983c1fe8474bb3808e1 Mon Sep 17 00:00:00 2001 From: Gregor Zeitlinger Date: Thu, 1 Feb 2024 22:00:56 +0100 Subject: [PATCH 223/901] header values are be expected to be W3C baggage encoded (#6164) Co-authored-by: jack-berg <34418638+jack-berg@users.noreply.github.com> Co-authored-by: Jack Berg --- .../otlp/internal/OtlpConfigUtil.java | 14 +++++++++++++- .../OtlpSpanExporterProviderTest.java | 19 +++++++++++++++++-- 2 files changed, 30 insertions(+), 3 deletions(-) diff --git a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/OtlpConfigUtil.java b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/OtlpConfigUtil.java index 1602cdd246b..da02c32dee5 100644 --- a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/OtlpConfigUtil.java +++ b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/OtlpConfigUtil.java @@ -21,6 +21,8 @@ import java.io.RandomAccessFile; import java.net.MalformedURLException; import java.net.URL; +import java.net.URLDecoder; +import java.nio.charset.StandardCharsets; import java.time.Duration; import java.util.Locale; import java.util.Map; @@ -89,7 +91,17 @@ public static void configureOtlpExporterBuilder( if (headers.isEmpty()) { headers = config.getMap("otel.exporter.otlp.headers"); } - headers.forEach(addHeader); + for (Map.Entry entry : headers.entrySet()) { + String key = entry.getKey(); + String value = entry.getValue(); + try { + // headers are encoded as URL - see + // https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/protocol/exporter.md#specifying-headers-via-environment-variables + addHeader.accept(key, URLDecoder.decode(value, StandardCharsets.UTF_8.displayName())); + } catch (Exception e) { + throw new ConfigurationException("Cannot decode header value: " + value, e); + } + } String compression = config.getString("otel.exporter.otlp." + dataType + ".compression"); if (compression == null) { diff --git a/exporters/otlp/all/src/test/java/io/opentelemetry/exporter/otlp/internal/OtlpSpanExporterProviderTest.java b/exporters/otlp/all/src/test/java/io/opentelemetry/exporter/otlp/internal/OtlpSpanExporterProviderTest.java index 7d83c3104f8..1918408e75b 100644 --- a/exporters/otlp/all/src/test/java/io/opentelemetry/exporter/otlp/internal/OtlpSpanExporterProviderTest.java +++ b/exporters/otlp/all/src/test/java/io/opentelemetry/exporter/otlp/internal/OtlpSpanExporterProviderTest.java @@ -29,6 +29,7 @@ import java.util.Collections; import java.util.HashMap; import java.util.Map; +import org.assertj.core.api.Assertions; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; @@ -219,7 +220,8 @@ void createExporter_HttpWithGeneralConfiguration() throws CertificateEncodingExc config.put("otel.exporter.otlp.certificate", certificatePath); config.put("otel.exporter.otlp.client.key", clientKeyPath); config.put("otel.exporter.otlp.client.certificate", clientCertificatePath); - config.put("otel.exporter.otlp.headers", "header-key=header-value"); + config.put( + "otel.exporter.otlp.headers", "header-key1=header%20value1,header-key2=header value2"); config.put("otel.exporter.otlp.compression", "gzip"); config.put("otel.exporter.otlp.timeout", "15s"); config.put("otel.experimental.exporter.otlp.retry.enabled", "true"); @@ -229,7 +231,8 @@ void createExporter_HttpWithGeneralConfiguration() throws CertificateEncodingExc assertThat(exporter).isInstanceOf(OtlpHttpSpanExporter.class); verify(httpBuilder, times(1)).build(); verify(httpBuilder).setEndpoint("https://localhost:443/v1/traces"); - verify(httpBuilder).addHeader("header-key", "header-value"); + verify(httpBuilder).addHeader("header-key1", "header value1"); + verify(httpBuilder).addHeader("header-key2", "header value2"); verify(httpBuilder).setCompression("gzip"); verify(httpBuilder).setTimeout(Duration.ofSeconds(15)); verify(httpBuilder).setTrustedCertificates(serverTls.certificate().getEncoded()); @@ -274,4 +277,16 @@ void createExporter_HttpWithSignalConfiguration() throws CertificateEncodingExce } Mockito.verifyNoInteractions(grpcBuilder); } + + @Test + void createExporter_decodingError() { + Assertions.assertThatThrownBy( + () -> { + provider.createExporter( + DefaultConfigProperties.createFromMap( + Collections.singletonMap("otel.exporter.otlp.headers", "header-key=%-1"))); + }) + .isInstanceOf(ConfigurationException.class) + .hasMessage("Cannot decode header value: %-1"); + } } From 6b613ddd364b0b09e8477319bb8e267760837782 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 1 Feb 2024 15:01:31 -0600 Subject: [PATCH 224/901] Update dependency com.google.api.grpc:proto-google-common-protos to v2.33.0 (#6184) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- dependencyManagement/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index 2a25afbe09a..8839550b318 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -55,7 +55,7 @@ val DEPENDENCIES = listOf( "io.prometheus:simpleclient_httpserver:${prometheusClientVersion}", "javax.annotation:javax.annotation-api:1.3.2", "com.github.stefanbirkner:system-rules:1.19.0", - "com.google.api.grpc:proto-google-common-protos:2.32.0", + "com.google.api.grpc:proto-google-common-protos:2.33.0", "com.google.code.findbugs:jsr305:3.0.2", "com.google.guava:guava-beta-checker:1.0", "com.sun.net.httpserver:http:20070405", From 697ae617bee06c91ab325bcfe1a806e3c2007a4f Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 1 Feb 2024 15:01:52 -0600 Subject: [PATCH 225/901] Update gradle/wrapper-validation-action action to v2 (#6185) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/gradle-wrapper-validation.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/gradle-wrapper-validation.yml b/.github/workflows/gradle-wrapper-validation.yml index b42e7b96b2c..ecd00499b24 100644 --- a/.github/workflows/gradle-wrapper-validation.yml +++ b/.github/workflows/gradle-wrapper-validation.yml @@ -13,4 +13,4 @@ jobs: steps: - uses: actions/checkout@v4 - - uses: gradle/wrapper-validation-action@v1.1.0 + - uses: gradle/wrapper-validation-action@v2.0.0 From c91f3f427e27e6ae257e214ddcd6f47e65976299 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 1 Feb 2024 15:02:12 -0600 Subject: [PATCH 226/901] Update dependency com.linecorp.armeria:armeria-bom to v1.27.0 (#6181) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- dependencyManagement/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index 8839550b318..d41ea9d93e6 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -11,7 +11,7 @@ val DEPENDENCY_BOMS = listOf( "com.fasterxml.jackson:jackson-bom:2.16.1", "com.google.guava:guava-bom:33.0.0-jre", "com.google.protobuf:protobuf-bom:3.25.2", - "com.linecorp.armeria:armeria-bom:1.26.4", + "com.linecorp.armeria:armeria-bom:1.27.0", "com.squareup.okhttp3:okhttp-bom:4.12.0", "com.squareup.okio:okio-bom:3.7.0", // applies to transitive dependencies of okhttp "io.grpc:grpc-bom:1.61.0", From 4f9b7314f21d2d01867c6c04bd06158ba1334e12 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 1 Feb 2024 15:02:26 -0600 Subject: [PATCH 227/901] Update dependency com.uber.nullaway:nullaway to v0.10.22 (#6180) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- dependencyManagement/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index d41ea9d93e6..f34959a844d 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -60,7 +60,7 @@ val DEPENDENCIES = listOf( "com.google.guava:guava-beta-checker:1.0", "com.sun.net.httpserver:http:20070405", "com.tngtech.archunit:archunit-junit5:1.2.1", - "com.uber.nullaway:nullaway:0.10.21", + "com.uber.nullaway:nullaway:0.10.22", "edu.berkeley.cs.jqf:jqf-fuzz:1.7", // jqf-fuzz version 1.8+ requires Java 11+ "eu.rekawek.toxiproxy:toxiproxy-java:2.1.7", "io.github.netmikey.logunit:logunit-jul:2.0.0", From 8e2a99a67d8da79f1987a959f7771e2a4ca9685a Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 1 Feb 2024 15:02:53 -0600 Subject: [PATCH 228/901] Update dependency com.squareup.wire:wire-bom to v4.9.5 (#6177) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- buildSrc/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts index dc767a75152..e908c85ecac 100644 --- a/buildSrc/build.gradle.kts +++ b/buildSrc/build.gradle.kts @@ -42,7 +42,7 @@ repositories { } dependencies { - implementation(enforcedPlatform("com.squareup.wire:wire-bom:4.9.4")) + implementation(enforcedPlatform("com.squareup.wire:wire-bom:4.9.5")) implementation("com.google.auto.value:auto-value-annotations:1.10.4") // When updating, update above in plugins too implementation("com.diffplug.spotless:spotless-plugin-gradle:6.25.0") From e9266c8575c01724a27a37b669389bec762af4fb Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 1 Feb 2024 15:03:06 -0600 Subject: [PATCH 229/901] Update dependency checkstyle to v10.13.0 (#6178) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- buildSrc/src/main/kotlin/otel.java-conventions.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/buildSrc/src/main/kotlin/otel.java-conventions.gradle.kts b/buildSrc/src/main/kotlin/otel.java-conventions.gradle.kts index 7dd9d091f67..0d2582b2e78 100644 --- a/buildSrc/src/main/kotlin/otel.java-conventions.gradle.kts +++ b/buildSrc/src/main/kotlin/otel.java-conventions.gradle.kts @@ -35,7 +35,7 @@ java { checkstyle { configDirectory.set(file("$rootDir/buildscripts/")) - toolVersion = "10.12.7" + toolVersion = "10.13.0" isIgnoreFailures = false configProperties["rootDir"] = rootDir } From eba8b847e904d1d5b3c4641d517ecd9359287131 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 3 Feb 2024 20:49:18 -0800 Subject: [PATCH 230/901] Update dependency io.grpc:grpc-bom to v1.61.1 (#6190) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- dependencyManagement/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index f34959a844d..a2c57832535 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -14,7 +14,7 @@ val DEPENDENCY_BOMS = listOf( "com.linecorp.armeria:armeria-bom:1.27.0", "com.squareup.okhttp3:okhttp-bom:4.12.0", "com.squareup.okio:okio-bom:3.7.0", // applies to transitive dependencies of okhttp - "io.grpc:grpc-bom:1.61.0", + "io.grpc:grpc-bom:1.61.1", "io.netty:netty-bom:4.1.106.Final", "io.zipkin.brave:brave-bom:6.0.0", "io.zipkin.reporter2:zipkin-reporter-bom:3.2.1", From 2d74bf263a703a739ffb6a23179089cd12b52cb3 Mon Sep 17 00:00:00 2001 From: jack-berg <34418638+jack-berg@users.noreply.github.com> Date: Mon, 5 Feb 2024 17:44:17 -0600 Subject: [PATCH 231/901] Define CODECOV token (#6186) --- .github/workflows/build.yml | 2 ++ RELEASING.md | 5 ++++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 210f70e2ff7..9b46b0565a2 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -77,6 +77,8 @@ jobs: - uses: codecov/codecov-action@v3 if: ${{ matrix.coverage }} + env: + CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} - uses: actions/upload-artifact@v4 if: ${{ matrix.coverage }} diff --git a/RELEASING.md b/RELEASING.md index 6c707cf43b3..cf9c0ebc197 100644 --- a/RELEASING.md +++ b/RELEASING.md @@ -77,7 +77,7 @@ Create a PR against the main branch with the changes. ## Credentials -The following credentials are required for publishing (and automatically set in Github Actions): +The following credentials are required for building or publishing (and automatically set in Github Actions): * `GPG_PRIVATE_KEY` and `GPG_PASSWORD`: GPG private key and password for signing. * `SONATYPE_USER` and `SONATYPE_KEY`: Sonatype username and password. @@ -89,6 +89,9 @@ The following credentials are required for publishing (and automatically set in * To obtain `SONATYPE_USER` and `SONATYPE_KEY` for your account, login to [oss.sonatype.org](https://oss.sonatype.org/) and navigate to Profile -> User Token -> Access User Token. +* `CODECOV_TOKEN`: Token used for uploading codecov reports. Each maintainer can obtain their own + credential from codecov as + described [here](https://docs.codecov.com/docs/adding-the-codecov-token#github-actions). Additionally, credentials are stored with maintainers via the [OpenTelemetry 1Password](https://opentelemetry.1password.com/signin) account. The following From 3e7302e742227d4526b765621a933d748012c906 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 5 Feb 2024 17:44:38 -0600 Subject: [PATCH 232/901] Update codecov/codecov-action action to v4 (#6183) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 9b46b0565a2..df503314f90 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -75,7 +75,7 @@ jobs: exit 1 fi - - uses: codecov/codecov-action@v3 + - uses: codecov/codecov-action@v4 if: ${{ matrix.coverage }} env: CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} From bae5718191bff429494b55833e2113b2b9427615 Mon Sep 17 00:00:00 2001 From: jack-berg <34418638+jack-berg@users.noreply.github.com> Date: Wed, 7 Feb 2024 13:04:52 -0600 Subject: [PATCH 233/901] Add Span#addLink, for adding link after span start (#6084) Co-authored-by: John Watson --- .../incubator/trace/ExtendedSpan.java | 56 ++++++++++ .../opencensusshim/DelegatingSpanTest.java | 65 ++++------- sdk/trace/build.gradle.kts | 2 + .../io/opentelemetry/sdk/trace/SdkSpan.java | 70 +++++++++--- .../sdk/trace/SdkSpanBuilder.java | 5 +- .../opentelemetry/sdk/trace/SpanWrapper.java | 6 +- .../opentelemetry/sdk/trace/SdkSpanTest.java | 103 +++++++++++++++++- 7 files changed, 243 insertions(+), 64 deletions(-) create mode 100644 extensions/incubator/src/main/java/io/opentelemetry/extension/incubator/trace/ExtendedSpan.java diff --git a/extensions/incubator/src/main/java/io/opentelemetry/extension/incubator/trace/ExtendedSpan.java b/extensions/incubator/src/main/java/io/opentelemetry/extension/incubator/trace/ExtendedSpan.java new file mode 100644 index 00000000000..33b39258b6d --- /dev/null +++ b/extensions/incubator/src/main/java/io/opentelemetry/extension/incubator/trace/ExtendedSpan.java @@ -0,0 +1,56 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.extension.incubator.trace; + +import io.opentelemetry.api.common.Attributes; +import io.opentelemetry.api.trace.Span; +import io.opentelemetry.api.trace.SpanBuilder; +import io.opentelemetry.api.trace.SpanContext; + +/** Extended {@link Span} with experimental APIs. */ +public interface ExtendedSpan extends Span { + + /** + * Adds a link to this {@code Span}. + * + *

    Links are used to link {@link Span}s in different traces. Used (for example) in batching + * operations, where a single batch handler processes multiple requests from different traces or + * the same trace. + * + *

    Implementations may ignore calls with an {@linkplain SpanContext#isValid() invalid span + * context}. + * + *

    Callers should prefer to add links before starting the span via {@link + * SpanBuilder#addLink(SpanContext)} if possible. + * + * @param spanContext the context of the linked {@code Span}. + * @return this. + */ + default Span addLink(SpanContext spanContext) { + return addLink(spanContext, Attributes.empty()); + } + + /** + * Adds a link to this {@code Span}. + * + *

    Links are used to link {@link Span}s in different traces. Used (for example) in batching + * operations, where a single batch handler processes multiple requests from different traces or + * the same trace. + * + *

    Implementations may ignore calls with an {@linkplain SpanContext#isValid() invalid span + * context}. + * + *

    Callers should prefer to add links before starting the span via {@link + * SpanBuilder#addLink(SpanContext, Attributes)} if possible. + * + * @param spanContext the context of the linked {@code Span}. + * @param attributes the attributes of the {@code Link}. + * @return this. + */ + default Span addLink(SpanContext spanContext, Attributes attributes) { + return this; + } +} diff --git a/opencensus-shim/src/test/java/io/opentelemetry/opencensusshim/DelegatingSpanTest.java b/opencensus-shim/src/test/java/io/opentelemetry/opencensusshim/DelegatingSpanTest.java index 88b63c019bb..a8f69082ee9 100644 --- a/opencensus-shim/src/test/java/io/opentelemetry/opencensusshim/DelegatingSpanTest.java +++ b/opencensus-shim/src/test/java/io/opentelemetry/opencensusshim/DelegatingSpanTest.java @@ -8,12 +8,18 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.Mockito.times; +import io.opentelemetry.api.common.AttributeKey; +import io.opentelemetry.api.common.Attributes; import io.opentelemetry.api.trace.Span; +import io.opentelemetry.api.trace.StatusCode; +import io.opentelemetry.context.Context; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.lang.reflect.Modifier; +import java.time.Instant; import java.util.Arrays; import java.util.List; +import java.util.concurrent.TimeUnit; import java.util.stream.Collectors; import java.util.stream.Stream; import org.junit.jupiter.api.Test; @@ -80,64 +86,33 @@ static List allInterfaceMethods(Class clazz) { static Stream delegateMethodsProvider() { return Stream.of( Arguments.of("end", new Class[] {}, times(1)), - Arguments.of( - "end", new Class[] {long.class, java.util.concurrent.TimeUnit.class}, times(1)), - Arguments.of("end", new Class[] {java.time.Instant.class}, times(1)), + Arguments.of("end", new Class[] {long.class, TimeUnit.class}, times(1)), + Arguments.of("end", new Class[] {Instant.class}, times(1)), Arguments.of("setAttribute", new Class[] {String.class, String.class}, times(1)), - Arguments.of( - "setAttribute", - new Class[] {io.opentelemetry.api.common.AttributeKey.class, int.class}, - times(1)), - Arguments.of( - "setAttribute", - new Class[] {io.opentelemetry.api.common.AttributeKey.class, Object.class}, - times(1)), + Arguments.of("setAttribute", new Class[] {AttributeKey.class, int.class}, times(1)), + Arguments.of("setAttribute", new Class[] {AttributeKey.class, Object.class}, times(1)), Arguments.of("setAttribute", new Class[] {String.class, long.class}, times(1)), Arguments.of("setAttribute", new Class[] {String.class, double.class}, times(1)), Arguments.of("setAttribute", new Class[] {String.class, boolean.class}, times(1)), Arguments.of( - "recordException", - new Class[] {Throwable.class, io.opentelemetry.api.common.Attributes.class}, - times(1)), + "recordException", new Class[] {Throwable.class, Attributes.class}, times(1)), Arguments.of("recordException", new Class[] {Throwable.class}, times(1)), - Arguments.of( - "setAllAttributes", - new Class[] {io.opentelemetry.api.common.Attributes.class}, - times(1)), + Arguments.of("setAllAttributes", new Class[] {Attributes.class}, times(1)), Arguments.of("updateName", new Class[] {String.class}, times(1)), + Arguments.of("storeInContext", new Class[] {Context.class}, times(1)), + Arguments.of("addEvent", new Class[] {String.class, Instant.class}, times(1)), Arguments.of( - "storeInContext", new Class[] {io.opentelemetry.context.Context.class}, times(1)), - Arguments.of("addEvent", new Class[] {String.class, java.time.Instant.class}, times(1)), + "addEvent", new Class[] {String.class, long.class, TimeUnit.class}, times(1)), Arguments.of( - "addEvent", - new Class[] {String.class, long.class, java.util.concurrent.TimeUnit.class}, - times(1)), - Arguments.of( - "addEvent", - new Class[] { - String.class, io.opentelemetry.api.common.Attributes.class, java.time.Instant.class - }, - times(1)), + "addEvent", new Class[] {String.class, Attributes.class, Instant.class}, times(1)), Arguments.of("addEvent", new Class[] {String.class}, times(1)), Arguments.of( "addEvent", - new Class[] { - String.class, - io.opentelemetry.api.common.Attributes.class, - long.class, - java.util.concurrent.TimeUnit.class - }, + new Class[] {String.class, Attributes.class, long.class, TimeUnit.class}, times(1)), - Arguments.of( - "addEvent", - new Class[] {String.class, io.opentelemetry.api.common.Attributes.class}, - times(1)), - Arguments.of( - "setStatus", - new Class[] {io.opentelemetry.api.trace.StatusCode.class, String.class}, - times(1)), - Arguments.of( - "setStatus", new Class[] {io.opentelemetry.api.trace.StatusCode.class}, times(1)), + Arguments.of("addEvent", new Class[] {String.class, Attributes.class}, times(1)), + Arguments.of("setStatus", new Class[] {StatusCode.class, String.class}, times(1)), + Arguments.of("setStatus", new Class[] {StatusCode.class}, times(1)), // // special cases // diff --git a/sdk/trace/build.gradle.kts b/sdk/trace/build.gradle.kts index ae87071507a..90c41b3b748 100644 --- a/sdk/trace/build.gradle.kts +++ b/sdk/trace/build.gradle.kts @@ -22,6 +22,8 @@ dependencies { api(project(":api:all")) api(project(":sdk:common")) + implementation(project(":extensions:incubator")) + compileOnly(project(":sdk:trace-shaded-deps")) annotationProcessor("com.google.auto.value:auto-value") diff --git a/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/SdkSpan.java b/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/SdkSpan.java index 70608e35a32..7f095ddd916 100644 --- a/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/SdkSpan.java +++ b/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/SdkSpan.java @@ -13,6 +13,7 @@ import io.opentelemetry.api.trace.SpanKind; import io.opentelemetry.api.trace.StatusCode; import io.opentelemetry.context.Context; +import io.opentelemetry.extension.incubator.trace.ExtendedSpan; import io.opentelemetry.sdk.common.Clock; import io.opentelemetry.sdk.common.InstrumentationScopeInfo; import io.opentelemetry.sdk.internal.AttributeUtil; @@ -35,7 +36,7 @@ /** Implementation for the {@link Span} class that records trace events. */ @ThreadSafe -final class SdkSpan implements ReadWriteSpan { +final class SdkSpan implements ReadWriteSpan, ExtendedSpan { private static final Logger logger = Logger.getLogger(SdkSpan.class.getName()); @@ -47,11 +48,6 @@ final class SdkSpan implements ReadWriteSpan { private final SpanContext parentSpanContext; // Handler called when the span starts and ends. private final SpanProcessor spanProcessor; - // The displayed name of the span. - // List of recorded links to parent and child spans. - private final List links; - // Number of links recorded. - private final int totalRecordedLinks; // The kind of the span. private final SpanKind kind; // The clock used to get the time. @@ -81,6 +77,16 @@ final class SdkSpan implements ReadWriteSpan { @GuardedBy("lock") private int totalRecordedEvents = 0; + // The displayed name of the span. + // List of recorded links to parent and child spans. + @GuardedBy("lock") + @Nullable + List links; + + // Number of links recorded. + @GuardedBy("lock") + private int totalRecordedLinks; + // The status of the span. @GuardedBy("lock") private StatusData status = StatusData.unset(); @@ -104,7 +110,7 @@ private SdkSpan( AnchoredClock clock, Resource resource, @Nullable AttributesMap attributes, - List links, + @Nullable List links, int totalRecordedLinks, long startEpochNanos) { this.context = context; @@ -151,7 +157,7 @@ static SdkSpan startSpan( Clock tracerClock, Resource resource, @Nullable AttributesMap attributes, - List links, + @Nullable List links, int totalRecordedLinks, long userStartEpochNanos) { boolean createdAnchoredClock; @@ -206,11 +212,12 @@ public SpanData toSpanData() { synchronized (lock) { return SpanWrapper.create( this, - links, + getImmutableLinks(), getImmutableTimedEvents(), getImmutableAttributes(), (attributes == null) ? 0 : attributes.getTotalAddedValues(), totalRecordedEvents, + totalRecordedLinks, status, name, endEpochNanos, @@ -428,6 +435,37 @@ public ReadWriteSpan updateName(String name) { return this; } + @Override + public Span addLink(SpanContext spanContext, Attributes attributes) { + if (spanContext == null || !spanContext.isValid()) { + return this; + } + if (attributes == null) { + attributes = Attributes.empty(); + } + LinkData link = + LinkData.create( + spanContext, + AttributeUtil.applyAttributesLimit( + attributes, + spanLimits.getMaxNumberOfAttributesPerLink(), + spanLimits.getMaxAttributeValueLength())); + synchronized (lock) { + if (hasEnded) { + logger.log(Level.FINE, "Calling addLink() on an ended Span."); + return this; + } + if (links == null) { + links = new ArrayList<>(spanLimits.getMaxNumberOfLinks()); + } + if (links.size() < spanLimits.getMaxNumberOfLinks()) { + links.add(link); + } + totalRecordedLinks++; + } + return this; + } + @Override public void end() { endInternal(clock.now()); @@ -475,10 +513,6 @@ long getStartEpochNanos() { return startEpochNanos; } - int getTotalRecordedLinks() { - return totalRecordedLinks; - } - @GuardedBy("lock") private List getImmutableTimedEvents() { if (events.isEmpty()) { @@ -508,6 +542,14 @@ private Attributes getImmutableAttributes() { return attributes.immutableCopy(); } + @GuardedBy("lock") + private List getImmutableLinks() { + if (links == null || links.isEmpty()) { + return Collections.emptyList(); + } + return Collections.unmodifiableList(links); + } + @Override public String toString() { String name; @@ -515,12 +557,14 @@ public String toString() { String status; long totalRecordedEvents; long endEpochNanos; + long totalRecordedLinks; synchronized (lock) { name = this.name; attributes = String.valueOf(this.attributes); status = String.valueOf(this.status); totalRecordedEvents = this.totalRecordedEvents; endEpochNanos = this.endEpochNanos; + totalRecordedLinks = this.totalRecordedLinks; } return "SdkSpan{traceId=" + context.getTraceId() diff --git a/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/SdkSpanBuilder.java b/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/SdkSpanBuilder.java index 4d6fca7fe41..fa823fa179a 100644 --- a/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/SdkSpanBuilder.java +++ b/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/SdkSpanBuilder.java @@ -179,8 +179,9 @@ public Span startSpan() { // New child span. traceId = parentSpanContext.getTraceId(); } + List currentLinks = links; List immutableLinks = - links == null ? Collections.emptyList() : Collections.unmodifiableList(links); + currentLinks == null ? Collections.emptyList() : Collections.unmodifiableList(currentLinks); // Avoid any possibility to modify the links list by adding links to the Builder after the // startSpan is called. If that happens all the links will be added in a new list. links = null; @@ -228,7 +229,7 @@ public Span startSpan() { tracerSharedState.getClock(), tracerSharedState.getResource(), recordedAttributes, - immutableLinks, + currentLinks, totalNumberOfLinksAdded, startEpochNanos); } diff --git a/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/SpanWrapper.java b/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/SpanWrapper.java index 962601b1d58..f0d148af5c2 100644 --- a/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/SpanWrapper.java +++ b/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/SpanWrapper.java @@ -43,6 +43,8 @@ abstract class SpanWrapper implements SpanData { abstract int totalRecordedEvents(); + abstract int totalRecordedLinks(); + abstract StatusData status(); abstract String name(); @@ -62,6 +64,7 @@ static SpanWrapper create( Attributes attributes, int totalAttributeCount, int totalRecordedEvents, + int totalRecordedLinks, StatusData status, String name, long endEpochNanos, @@ -73,6 +76,7 @@ static SpanWrapper create( attributes, totalAttributeCount, totalRecordedEvents, + totalRecordedLinks, status, name, endEpochNanos, @@ -158,7 +162,7 @@ public int getTotalRecordedEvents() { @Override public int getTotalRecordedLinks() { - return delegate().getTotalRecordedLinks(); + return totalRecordedLinks(); } @Override diff --git a/sdk/trace/src/test/java/io/opentelemetry/sdk/trace/SdkSpanTest.java b/sdk/trace/src/test/java/io/opentelemetry/sdk/trace/SdkSpanTest.java index d117a7b2e82..db75f189e06 100644 --- a/sdk/trace/src/test/java/io/opentelemetry/sdk/trace/SdkSpanTest.java +++ b/sdk/trace/src/test/java/io/opentelemetry/sdk/trace/SdkSpanTest.java @@ -15,6 +15,7 @@ import static io.opentelemetry.api.common.AttributeKey.stringKey; import static java.util.stream.Collectors.joining; import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatCode; import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.never; @@ -32,6 +33,7 @@ import io.opentelemetry.api.trace.TraceFlags; import io.opentelemetry.api.trace.TraceState; import io.opentelemetry.context.Context; +import io.opentelemetry.extension.incubator.trace.ExtendedSpan; import io.opentelemetry.sdk.common.InstrumentationScopeInfo; import io.opentelemetry.sdk.internal.AttributesMap; import io.opentelemetry.sdk.internal.InstrumentationScopeUtil; @@ -46,6 +48,7 @@ import java.io.StringWriter; import java.time.Duration; import java.time.Instant; +import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.HashMap; @@ -801,6 +804,99 @@ void eventAttributeLength() { } } + @Test + void addLink() { + int maxLinks = 3; + int maxNumberOfAttributes = 4; + int maxAttributeLength = 5; + SdkSpan span = + createTestSpan( + SpanKind.INTERNAL, + SpanLimits.builder() + .setMaxNumberOfLinks(maxLinks) + .setMaxNumberOfAttributesPerLink(maxNumberOfAttributes) + .setMaxAttributeValueLength(maxAttributeLength) + .build(), + parentSpanId, + null, + null); + try { + ExtendedSpan span1 = createTestSpan(SpanKind.INTERNAL); + ExtendedSpan span2 = createTestSpan(SpanKind.INTERNAL); + ExtendedSpan span3 = createTestSpan(SpanKind.INTERNAL); + ExtendedSpan span4 = createTestSpan(SpanKind.INTERNAL); + + span.addLink(span1.getSpanContext()); + + Attributes span2LinkAttributes = + Attributes.builder() + .put("key1", true) + .put("key2", true) + .put("key3", true) + .put( + "key4", + IntStream.range(0, maxAttributeLength + 1).mapToObj(i -> "a").collect(joining())) + .build(); + span.addLink(span2.getSpanContext(), span2LinkAttributes); + + Attributes span3LinkAttributes = + Attributes.builder() + .put("key1", true) + .put("key2", true) + .put("key3", true) + .put("key4", true) + .put("key5", true) + .build(); + span.addLink(span3.getSpanContext(), span3LinkAttributes); + + span.addLink(span4.getSpanContext()); + + SpanData spanData = span.toSpanData(); + // 1 link added during span construction via createTestSpan, 4 links added after span start + assertThat(spanData.getTotalRecordedLinks()).isEqualTo(4); + assertThat(spanData.getLinks()) + .satisfiesExactly( + link -> { + assertThat(link.getSpanContext()).isEqualTo(span1.getSpanContext()); + assertThat(link.getAttributes()).isEqualTo(Attributes.empty()); + }, + link -> { + assertThat(link.getSpanContext()).isEqualTo(span2.getSpanContext()); + assertThat(link.getAttributes()) + .isEqualTo( + Attributes.builder() + .put("key1", true) + .put("key2", true) + .put("key3", true) + // Should be truncated to max attribute length + .put( + "key4", + IntStream.range(0, maxAttributeLength) + .mapToObj(i -> "a") + .collect(joining())) + .build()); + }, + link -> { + assertThat(link.getSpanContext()).isEqualTo(span2.getSpanContext()); + // The 5th attribute key should be omitted due to attribute limits. Can't predict + // which of the 5 is dropped. + assertThat(link.getAttributes().size()).isEqualTo(4); + }); + } finally { + span.end(); + } + } + + @Test + void addLink_InvalidArgs() { + ExtendedSpan span = createTestSpan(SpanKind.INTERNAL); + assertThatCode(() -> span.addLink(null)).doesNotThrowAnyException(); + assertThatCode(() -> span.addLink(SpanContext.getInvalid())).doesNotThrowAnyException(); + assertThatCode(() -> span.addLink(null, null)).doesNotThrowAnyException(); + assertThatCode(() -> span.addLink(SpanContext.getInvalid(), Attributes.empty())) + .doesNotThrowAnyException(); + } + @Test void droppingAttributes() { int maxNumberOfAttributes = 8; @@ -1120,7 +1216,8 @@ private SdkSpan createTestSpan( SpanLimits config, @Nullable String parentSpanId, @Nullable AttributesMap attributes, - List links) { + @Nullable List links) { + List linksCopy = links == null ? new ArrayList<>() : new ArrayList<>(links); SdkSpan span = SdkSpan.startSpan( @@ -1139,8 +1236,8 @@ private SdkSpan createTestSpan( testClock, resource, attributes, - links, - 1, + linksCopy, + linksCopy.size(), 0); Mockito.verify(spanProcessor, Mockito.times(1)).onStart(Context.root(), span); return span; From 9e6d4a8dc3ad097bc24c092e46fc025eec5d209e Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 7 Feb 2024 13:05:08 -0600 Subject: [PATCH 234/901] Update dependency org.jctools:jctools-core to v4.0.3 (#6203) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- dependencyManagement/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index a2c57832535..ebc67e6b3a4 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -75,7 +75,7 @@ val DEPENDENCIES = listOf( "org.awaitility:awaitility:4.2.0", "org.bouncycastle:bcpkix-jdk15on:1.70", "org.codehaus.mojo:animal-sniffer-annotations:1.23", - "org.jctools:jctools-core:4.0.2", + "org.jctools:jctools-core:4.0.3", "org.junit-pioneer:junit-pioneer:1.9.1", "org.skyscreamer:jsonassert:1.5.1", "com.android.tools:desugar_jdk_libs:2.0.4", From 715fbd678a56354bc322997ed7f8bc4bab71fc5b Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 7 Feb 2024 13:05:24 -0600 Subject: [PATCH 235/901] Update dependency com.linecorp.armeria:armeria-bom to v1.27.1 (#6202) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- dependencyManagement/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index ebc67e6b3a4..87d71f49f68 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -11,7 +11,7 @@ val DEPENDENCY_BOMS = listOf( "com.fasterxml.jackson:jackson-bom:2.16.1", "com.google.guava:guava-bom:33.0.0-jre", "com.google.protobuf:protobuf-bom:3.25.2", - "com.linecorp.armeria:armeria-bom:1.27.0", + "com.linecorp.armeria:armeria-bom:1.27.1", "com.squareup.okhttp3:okhttp-bom:4.12.0", "com.squareup.okio:okio-bom:3.7.0", // applies to transitive dependencies of okhttp "io.grpc:grpc-bom:1.61.1", From 001fa1cd38622de76bc6636ed9fa096d5b8b65ba Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 7 Feb 2024 13:05:55 -0600 Subject: [PATCH 236/901] Update slf4j monorepo to v2.0.12 (#6199) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- dependencyManagement/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index 87d71f49f68..aa5f690f105 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -29,7 +29,7 @@ val errorProneVersion = "2.24.1" val jmhVersion = "1.37" // Mockito 5.x.x requires Java 11 https://github.com/mockito/mockito/releases/tag/v5.0.0 val mockitoVersion = "4.11.0" -val slf4jVersion = "2.0.11" +val slf4jVersion = "2.0.12" val opencensusVersion = "0.31.1" val prometheusClientVersion = "0.16.0" From 63b39e37e995bba4bb50efcd4e24c1eb25d25d55 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 7 Feb 2024 13:06:10 -0600 Subject: [PATCH 237/901] Update dependency org.assertj:assertj-bom to v3.25.3 (#6193) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- dependencyManagement/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index aa5f690f105..3d24f45d18d 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -18,7 +18,7 @@ val DEPENDENCY_BOMS = listOf( "io.netty:netty-bom:4.1.106.Final", "io.zipkin.brave:brave-bom:6.0.0", "io.zipkin.reporter2:zipkin-reporter-bom:3.2.1", - "org.assertj:assertj-bom:3.25.2", + "org.assertj:assertj-bom:3.25.3", "org.junit:junit-bom:5.10.1", "org.testcontainers:testcontainers-bom:1.19.4", "org.snakeyaml:snakeyaml-engine:2.7" From 3265f3289de680d931f07e4aa32857acf569468d Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 7 Feb 2024 15:46:59 -0600 Subject: [PATCH 238/901] Update gradle/wrapper-validation-action action to v2.1.0 (#6200) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/gradle-wrapper-validation.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/gradle-wrapper-validation.yml b/.github/workflows/gradle-wrapper-validation.yml index ecd00499b24..81d19137a52 100644 --- a/.github/workflows/gradle-wrapper-validation.yml +++ b/.github/workflows/gradle-wrapper-validation.yml @@ -13,4 +13,4 @@ jobs: steps: - uses: actions/checkout@v4 - - uses: gradle/wrapper-validation-action@v2.0.0 + - uses: gradle/wrapper-validation-action@v2.1.0 From 82bf8c36235d017db1ef1ab2e3a91e573038aaf0 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 7 Feb 2024 15:47:28 -0600 Subject: [PATCH 239/901] Update dependency org.junit:junit-bom to v5.10.2 (#6192) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- dependencyManagement/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index 3d24f45d18d..764a568c040 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -19,7 +19,7 @@ val DEPENDENCY_BOMS = listOf( "io.zipkin.brave:brave-bom:6.0.0", "io.zipkin.reporter2:zipkin-reporter-bom:3.2.1", "org.assertj:assertj-bom:3.25.3", - "org.junit:junit-bom:5.10.1", + "org.junit:junit-bom:5.10.2", "org.testcontainers:testcontainers-bom:1.19.4", "org.snakeyaml:snakeyaml-engine:2.7" ) From fe7a1c58f8360bbffbb5b5a1cf73212c48d39793 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 7 Feb 2024 15:47:46 -0600 Subject: [PATCH 240/901] Update dependency com.squareup.wire:wire-bom to v4.9.6 (#6189) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- buildSrc/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts index e908c85ecac..8674e542401 100644 --- a/buildSrc/build.gradle.kts +++ b/buildSrc/build.gradle.kts @@ -42,7 +42,7 @@ repositories { } dependencies { - implementation(enforcedPlatform("com.squareup.wire:wire-bom:4.9.5")) + implementation(enforcedPlatform("com.squareup.wire:wire-bom:4.9.6")) implementation("com.google.auto.value:auto-value-annotations:1.10.4") // When updating, update above in plugins too implementation("com.diffplug.spotless:spotless-plugin-gradle:6.25.0") From b8b804b68bf8ae6aa49d9f83bcb89875a2684090 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 7 Feb 2024 15:48:56 -0600 Subject: [PATCH 241/901] Update plugin org.graalvm.buildtools.native to v0.10.0 (#6188) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- settings.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/settings.gradle.kts b/settings.gradle.kts index 1b0892e1a76..15dc2e65a1c 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -5,7 +5,7 @@ pluginManagement { id("de.undercouch.download") version "5.5.0" id("org.jsonschema2pojo") version "1.2.1" id("io.github.gradle-nexus.publish-plugin") version "1.3.0" - id("org.graalvm.buildtools.native") version "0.9.28" + id("org.graalvm.buildtools.native") version "0.10.0" } } From c12bb736caeebd945e5df30852e84c8e4c9d2789 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 7 Feb 2024 15:49:10 -0600 Subject: [PATCH 242/901] Update dependency gradle to v8.6 (#6191) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- gradle/wrapper/gradle-wrapper.properties | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index db8c3baafe3..4baf5a11d45 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,7 +1,7 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionSha256Sum=9d926787066a081739e8200858338b4a69e837c3a821a33aca9db09dd4a41026 -distributionUrl=https\://services.gradle.org/distributions/gradle-8.5-bin.zip +distributionSha256Sum=9631d53cf3e74bfa726893aee1f8994fee4e060c401335946dba2156f440f24c +distributionUrl=https\://services.gradle.org/distributions/gradle-8.6-bin.zip networkTimeout=10000 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME From c12779d960918fdf7881a6d81d215e51e509ebd7 Mon Sep 17 00:00:00 2001 From: Asaf Mesika Date: Thu, 8 Feb 2024 17:29:16 +0200 Subject: [PATCH 243/901] Memory mode: Adding support for synchronous instruments - Last Value aggregation (#6196) --- .../internal/state/ProfileBenchmark.java | 2 +- .../internal/state/TestInstrumentType.java | 6 +- .../state/tester/DoubleLastValueTester.java | 50 ++++++++++++ .../state/tester/LongLastValueTester.java | 51 ++++++++++++ .../aggregator/DoubleLastValueAggregator.java | 27 +++++-- .../aggregator/LongLastValueAggregator.java | 29 +++++-- .../internal/view/LastValueAggregation.java | 6 +- .../DoubleLastValueAggregatorTest.java | 80 +++++++++++++++---- .../LongLastValueAggregatorTest.java | 69 ++++++++++++---- 9 files changed, 275 insertions(+), 45 deletions(-) create mode 100644 sdk/metrics/src/jmhBasedTest/java/io/opentelemetry/sdk/metrics/internal/state/tester/DoubleLastValueTester.java create mode 100644 sdk/metrics/src/jmhBasedTest/java/io/opentelemetry/sdk/metrics/internal/state/tester/LongLastValueTester.java diff --git a/sdk/metrics/src/jmhBasedTest/java/io/opentelemetry/sdk/metrics/internal/state/ProfileBenchmark.java b/sdk/metrics/src/jmhBasedTest/java/io/opentelemetry/sdk/metrics/internal/state/ProfileBenchmark.java index 26f4588582b..2d091bfd725 100644 --- a/sdk/metrics/src/jmhBasedTest/java/io/opentelemetry/sdk/metrics/internal/state/ProfileBenchmark.java +++ b/sdk/metrics/src/jmhBasedTest/java/io/opentelemetry/sdk/metrics/internal/state/ProfileBenchmark.java @@ -37,7 +37,7 @@ public static void main(String[] args) { // Parameters AggregationTemporality aggregationTemporality = AggregationTemporality.DELTA; MemoryMode memoryMode = MemoryMode.REUSABLE_DATA; - TestInstrumentType testInstrumentType = TestInstrumentType.EXPLICIT_BUCKET; + TestInstrumentType testInstrumentType = TestInstrumentType.DOUBLE_LAST_VALUE; InstrumentGarbageCollectionBenchmark.ThreadState benchmarkSetup = new InstrumentGarbageCollectionBenchmark.ThreadState(); diff --git a/sdk/metrics/src/jmhBasedTest/java/io/opentelemetry/sdk/metrics/internal/state/TestInstrumentType.java b/sdk/metrics/src/jmhBasedTest/java/io/opentelemetry/sdk/metrics/internal/state/TestInstrumentType.java index 1cf082699be..98cc39a6657 100644 --- a/sdk/metrics/src/jmhBasedTest/java/io/opentelemetry/sdk/metrics/internal/state/TestInstrumentType.java +++ b/sdk/metrics/src/jmhBasedTest/java/io/opentelemetry/sdk/metrics/internal/state/TestInstrumentType.java @@ -9,9 +9,11 @@ import io.opentelemetry.sdk.metrics.Aggregation; import io.opentelemetry.sdk.metrics.SdkMeterProvider; import io.opentelemetry.sdk.metrics.internal.state.tester.AsyncCounterTester; +import io.opentelemetry.sdk.metrics.internal.state.tester.DoubleLastValueTester; import io.opentelemetry.sdk.metrics.internal.state.tester.DoubleSumTester; import io.opentelemetry.sdk.metrics.internal.state.tester.ExplicitBucketHistogramTester; import io.opentelemetry.sdk.metrics.internal.state.tester.ExponentialHistogramTester; +import io.opentelemetry.sdk.metrics.internal.state.tester.LongLastValueTester; import io.opentelemetry.sdk.metrics.internal.state.tester.LongSumTester; import java.util.List; import java.util.Random; @@ -23,7 +25,9 @@ public enum TestInstrumentType { EXPONENTIAL_HISTOGRAM(ExponentialHistogramTester::new), EXPLICIT_BUCKET(ExplicitBucketHistogramTester::new), LONG_SUM(LongSumTester::new, /* dataAllocRateReductionPercentage= */ 97.3f), - DOUBLE_SUM(DoubleSumTester::new, /* dataAllocRateReductionPercentage= */ 97.3f); + DOUBLE_SUM(DoubleSumTester::new, /* dataAllocRateReductionPercentage= */ 97.3f), + LONG_LAST_VALUE(LongLastValueTester::new, /* dataAllocRateReductionPercentage= */ 97.3f), + DOUBLE_LAST_VALUE(DoubleLastValueTester::new, /* dataAllocRateReductionPercentage= */ 97.3f); private final Supplier instrumentTesterInitializer; private final float dataAllocRateReductionPercentage; diff --git a/sdk/metrics/src/jmhBasedTest/java/io/opentelemetry/sdk/metrics/internal/state/tester/DoubleLastValueTester.java b/sdk/metrics/src/jmhBasedTest/java/io/opentelemetry/sdk/metrics/internal/state/tester/DoubleLastValueTester.java new file mode 100644 index 00000000000..c9144ad2c1a --- /dev/null +++ b/sdk/metrics/src/jmhBasedTest/java/io/opentelemetry/sdk/metrics/internal/state/tester/DoubleLastValueTester.java @@ -0,0 +1,50 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.sdk.metrics.internal.state.tester; + +import io.opentelemetry.api.common.Attributes; +import io.opentelemetry.api.metrics.Meter; +import io.opentelemetry.sdk.metrics.Aggregation; +import io.opentelemetry.sdk.metrics.SdkMeterProvider; +import io.opentelemetry.sdk.metrics.internal.state.TestInstrumentType; +import java.util.List; +import java.util.Random; + +public class DoubleLastValueTester implements TestInstrumentType.InstrumentTester { + + @Override + public Aggregation testedAggregation() { + return Aggregation.lastValue(); + } + + @SuppressWarnings("ForLoopReplaceableByForEach") // This is for GC sensitivity testing: no streams + @Override + public TestInstrumentType.TestInstrumentsState buildInstruments( + double instrumentCount, + SdkMeterProvider sdkMeterProvider, + List attributesList, + Random random) { + Meter meter = sdkMeterProvider.meterBuilder("meter").build(); + meter + .gaugeBuilder("test.double.last.value") + .buildWithCallback( + observableDoubleMeasurement -> { + for (int j = 0; j < attributesList.size(); j++) { + observableDoubleMeasurement.record(1.2f, attributesList.get(j)); + } + }); + + return new TestInstrumentType.EmptyInstrumentsState(); + } + + @Override + public void recordValuesInInstruments( + TestInstrumentType.TestInstrumentsState testInstrumentsState, + List attributesList, + Random random) { + // Recording is done by the callback define above + } +} diff --git a/sdk/metrics/src/jmhBasedTest/java/io/opentelemetry/sdk/metrics/internal/state/tester/LongLastValueTester.java b/sdk/metrics/src/jmhBasedTest/java/io/opentelemetry/sdk/metrics/internal/state/tester/LongLastValueTester.java new file mode 100644 index 00000000000..c766f74e290 --- /dev/null +++ b/sdk/metrics/src/jmhBasedTest/java/io/opentelemetry/sdk/metrics/internal/state/tester/LongLastValueTester.java @@ -0,0 +1,51 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.sdk.metrics.internal.state.tester; + +import io.opentelemetry.api.common.Attributes; +import io.opentelemetry.api.metrics.Meter; +import io.opentelemetry.sdk.metrics.Aggregation; +import io.opentelemetry.sdk.metrics.SdkMeterProvider; +import io.opentelemetry.sdk.metrics.internal.state.TestInstrumentType; +import java.util.List; +import java.util.Random; + +public class LongLastValueTester implements TestInstrumentType.InstrumentTester { + + @Override + public Aggregation testedAggregation() { + return Aggregation.lastValue(); + } + + @SuppressWarnings({"ForLoopReplaceableByForEach", "resource"}) + @Override + public TestInstrumentType.TestInstrumentsState buildInstruments( + double instrumentCount, + SdkMeterProvider sdkMeterProvider, + List attributesList, + Random random) { + Meter meter = sdkMeterProvider.meterBuilder("meter").build(); + meter + .gaugeBuilder("test.long.last.value") + .ofLongs() + .buildWithCallback( + observableLongMeasurement -> { + for (int j = 0; j < attributesList.size(); j++) { + observableLongMeasurement.record(1, attributesList.get(j)); + } + }); + + return new TestInstrumentType.EmptyInstrumentsState(); + } + + @Override + public void recordValuesInInstruments( + TestInstrumentType.TestInstrumentsState testInstrumentsState, + List attributesList, + Random random) { + // Recording is done by the callback define above + } +} diff --git a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/aggregator/DoubleLastValueAggregator.java b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/aggregator/DoubleLastValueAggregator.java index 8f0a622e3af..2063cb212d7 100644 --- a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/aggregator/DoubleLastValueAggregator.java +++ b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/aggregator/DoubleLastValueAggregator.java @@ -7,6 +7,7 @@ import io.opentelemetry.api.common.Attributes; import io.opentelemetry.sdk.common.InstrumentationScopeInfo; +import io.opentelemetry.sdk.common.export.MemoryMode; import io.opentelemetry.sdk.metrics.data.AggregationTemporality; import io.opentelemetry.sdk.metrics.data.DoubleExemplarData; import io.opentelemetry.sdk.metrics.data.DoublePointData; @@ -42,15 +43,17 @@ public final class DoubleLastValueAggregator implements Aggregator { private final Supplier> reservoirSupplier; + private final MemoryMode memoryMode; public DoubleLastValueAggregator( - Supplier> reservoirSupplier) { + Supplier> reservoirSupplier, MemoryMode memoryMode) { this.reservoirSupplier = reservoirSupplier; + this.memoryMode = memoryMode; } @Override public AggregatorHandle createHandle() { - return new Handle(reservoirSupplier.get()); + return new Handle(reservoirSupplier.get(), memoryMode); } @Override @@ -114,8 +117,16 @@ static final class Handle extends AggregatorHandle current = new AtomicReference<>(DEFAULT_VALUE); - private Handle(ExemplarReservoir reservoir) { + // Only used when memoryMode is REUSABLE_DATA + @Nullable private final MutableDoublePointData reusablePoint; + + private Handle(ExemplarReservoir reservoir, MemoryMode memoryMode) { super(reservoir); + if (memoryMode == MemoryMode.REUSABLE_DATA) { + reusablePoint = new MutableDoublePointData(); + } else { + reusablePoint = null; + } } @Override @@ -126,8 +137,14 @@ protected DoublePointData doAggregateThenMaybeReset( List exemplars, boolean reset) { Double value = reset ? this.current.getAndSet(DEFAULT_VALUE) : this.current.get(); - return ImmutableDoublePointData.create( - startEpochNanos, epochNanos, attributes, Objects.requireNonNull(value), exemplars); + if (reusablePoint != null) { + reusablePoint.set( + startEpochNanos, epochNanos, attributes, Objects.requireNonNull(value), exemplars); + return reusablePoint; + } else { + return ImmutableDoublePointData.create( + startEpochNanos, epochNanos, attributes, Objects.requireNonNull(value), exemplars); + } } @Override diff --git a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/aggregator/LongLastValueAggregator.java b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/aggregator/LongLastValueAggregator.java index 5b3064822c9..27422733c43 100644 --- a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/aggregator/LongLastValueAggregator.java +++ b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/aggregator/LongLastValueAggregator.java @@ -7,6 +7,7 @@ import io.opentelemetry.api.common.Attributes; import io.opentelemetry.sdk.common.InstrumentationScopeInfo; +import io.opentelemetry.sdk.common.export.MemoryMode; import io.opentelemetry.sdk.metrics.data.AggregationTemporality; import io.opentelemetry.sdk.metrics.data.LongExemplarData; import io.opentelemetry.sdk.metrics.data.LongPointData; @@ -39,14 +40,17 @@ */ public final class LongLastValueAggregator implements Aggregator { private final Supplier> reservoirSupplier; + private final MemoryMode memoryMode; - public LongLastValueAggregator(Supplier> reservoirSupplier) { + public LongLastValueAggregator( + Supplier> reservoirSupplier, MemoryMode memoryMode) { this.reservoirSupplier = reservoirSupplier; + this.memoryMode = memoryMode; } @Override public AggregatorHandle createHandle() { - return new Handle(reservoirSupplier.get()); + return new Handle(reservoirSupplier.get(), memoryMode); } @Override @@ -109,8 +113,16 @@ static final class Handle extends AggregatorHandle current = new AtomicReference<>(DEFAULT_VALUE); - Handle(ExemplarReservoir exemplarReservoir) { + // Only used when memoryMode is REUSABLE_DATA + @Nullable private final MutableLongPointData reusablePoint; + + Handle(ExemplarReservoir exemplarReservoir, MemoryMode memoryMode) { super(exemplarReservoir); + if (memoryMode == MemoryMode.REUSABLE_DATA) { + reusablePoint = new MutableLongPointData(); + } else { + reusablePoint = null; + } } @Override @@ -121,8 +133,15 @@ protected LongPointData doAggregateThenMaybeReset( List exemplars, boolean reset) { Long value = reset ? this.current.getAndSet(DEFAULT_VALUE) : this.current.get(); - return ImmutableLongPointData.create( - startEpochNanos, epochNanos, attributes, Objects.requireNonNull(value), exemplars); + + if (reusablePoint != null) { + reusablePoint.set( + startEpochNanos, epochNanos, attributes, Objects.requireNonNull(value), exemplars); + return reusablePoint; + } else { + return ImmutableLongPointData.create( + startEpochNanos, epochNanos, attributes, Objects.requireNonNull(value), exemplars); + } } @Override diff --git a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/view/LastValueAggregation.java b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/view/LastValueAggregation.java index 5a7579f3bf6..7dac6c6241d 100644 --- a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/view/LastValueAggregation.java +++ b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/view/LastValueAggregation.java @@ -44,9 +44,11 @@ public Aggregator createAggr // For the initial version we do not sample exemplars on gauges. switch (instrumentDescriptor.getValueType()) { case LONG: - return (Aggregator) new LongLastValueAggregator(ExemplarReservoir::longNoSamples); + return (Aggregator) + new LongLastValueAggregator(ExemplarReservoir::longNoSamples, memoryMode); case DOUBLE: - return (Aggregator) new DoubleLastValueAggregator(ExemplarReservoir::doubleNoSamples); + return (Aggregator) + new DoubleLastValueAggregator(ExemplarReservoir::doubleNoSamples, memoryMode); } throw new IllegalArgumentException("Invalid instrument value type"); } diff --git a/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/internal/aggregator/DoubleLastValueAggregatorTest.java b/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/internal/aggregator/DoubleLastValueAggregatorTest.java index 5f7a276e1e9..b28a8e4879c 100644 --- a/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/internal/aggregator/DoubleLastValueAggregatorTest.java +++ b/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/internal/aggregator/DoubleLastValueAggregatorTest.java @@ -6,7 +6,6 @@ package io.opentelemetry.sdk.metrics.internal.aggregator; import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.assertThat; -import static org.assertj.core.api.Assertions.assertThat; import io.opentelemetry.api.common.AttributeKey; import io.opentelemetry.api.common.Attributes; @@ -14,6 +13,7 @@ import io.opentelemetry.api.trace.TraceFlags; import io.opentelemetry.api.trace.TraceState; import io.opentelemetry.sdk.common.InstrumentationScopeInfo; +import io.opentelemetry.sdk.common.export.MemoryMode; import io.opentelemetry.sdk.metrics.data.AggregationTemporality; import io.opentelemetry.sdk.metrics.data.DoubleExemplarData; import io.opentelemetry.sdk.metrics.data.DoublePointData; @@ -27,6 +27,8 @@ import java.util.Collections; import java.util.List; import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.EnumSource; /** Unit tests for {@link AggregatorHandle}. */ class DoubleLastValueAggregatorTest { @@ -35,16 +37,24 @@ class DoubleLastValueAggregatorTest { InstrumentationScopeInfo.empty(); private static final MetricDescriptor METRIC_DESCRIPTOR = MetricDescriptor.create("name", "description", "unit"); - private static final DoubleLastValueAggregator aggregator = - new DoubleLastValueAggregator(ExemplarReservoir::doubleNoSamples); + private DoubleLastValueAggregator aggregator; - @Test - void createHandle() { + private void init(MemoryMode memoryMode) { + aggregator = new DoubleLastValueAggregator(ExemplarReservoir::doubleNoSamples, memoryMode); + } + + @ParameterizedTest + @EnumSource(MemoryMode.class) + void createHandle(MemoryMode memoryMode) { + init(memoryMode); assertThat(aggregator.createHandle()).isInstanceOf(DoubleLastValueAggregator.Handle.class); } - @Test - void multipleRecords() { + @ParameterizedTest + @EnumSource(MemoryMode.class) + void multipleRecords(MemoryMode memoryMode) { + init(memoryMode); + AggregatorHandle aggregatorHandle = aggregator.createHandle(); aggregatorHandle.recordDouble(12.1); @@ -62,8 +72,11 @@ void multipleRecords() { .isEqualTo(14.1); } - @Test - void aggregateThenMaybeReset() { + @ParameterizedTest + @EnumSource(MemoryMode.class) + void aggregateThenMaybeReset(MemoryMode memoryMode) { + init(memoryMode); + AggregatorHandle aggregatorHandle = aggregator.createHandle(); @@ -82,8 +95,11 @@ void aggregateThenMaybeReset() { .isEqualTo(12.1); } - @Test - void diff() { + @ParameterizedTest + @EnumSource(MemoryMode.class) + void diff(MemoryMode memoryMode) { + init(memoryMode); + Attributes attributes = Attributes.builder().put("test", "value").build(); DoubleExemplarData exemplar = ImmutableDoubleExemplarData.create( @@ -116,8 +132,11 @@ void diff() { .isEqualTo(ImmutableDoublePointData.create(0, 1, Attributes.empty(), 2, exemplars)); } - @Test - void diffInPlace() { + @ParameterizedTest + @EnumSource(MemoryMode.class) + void diffInPlace(MemoryMode memoryMode) { + init(memoryMode); + Attributes attributes = Attributes.builder().put("test", "value").build(); DoubleExemplarData exemplar = ImmutableDoubleExemplarData.create( @@ -158,8 +177,11 @@ void diffInPlace() { assertThat(previous.getExemplars()).isEqualTo(exemplars); } - @Test - void copyPoint() { + @ParameterizedTest + @EnumSource(MemoryMode.class) + void copyPoint(MemoryMode memoryMode) { + init(memoryMode); + MutableDoublePointData pointData = (MutableDoublePointData) aggregator.createReusablePoint(); Attributes attributes = Attributes.of(AttributeKey.longKey("test"), 100L); @@ -201,8 +223,11 @@ void copyPoint() { assertThat(toPointData.getExemplars()).isEqualTo(pointData.getExemplars()); } - @Test - void toMetricData() { + @ParameterizedTest + @EnumSource(MemoryMode.class) + void toMetricData(MemoryMode memoryMode) { + init(memoryMode); + AggregatorHandle aggregatorHandle = aggregator.createHandle(); aggregatorHandle.recordDouble(10); @@ -230,4 +255,25 @@ void toMetricData() { .hasEpochNanos(100) .hasValue(10))); } + + @Test + void testReusableDataOnCollect() { + init(MemoryMode.REUSABLE_DATA); + AggregatorHandle handle = aggregator.createHandle(); + handle.recordDouble(1); + DoublePointData pointData = + handle.aggregateThenMaybeReset(0, 10, Attributes.empty(), /* reset= */ false); + + handle.recordDouble(1); + DoublePointData pointData2 = + handle.aggregateThenMaybeReset(0, 10, Attributes.empty(), /* reset= */ false); + + assertThat(pointData).isSameAs(pointData2); + + handle.recordDouble(1); + DoublePointData pointDataWithReset = + handle.aggregateThenMaybeReset(0, 10, Attributes.empty(), /* reset= */ true); + + assertThat(pointData).isSameAs(pointDataWithReset); + } } diff --git a/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/internal/aggregator/LongLastValueAggregatorTest.java b/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/internal/aggregator/LongLastValueAggregatorTest.java index 0ac5104898f..b9dfc386156 100644 --- a/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/internal/aggregator/LongLastValueAggregatorTest.java +++ b/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/internal/aggregator/LongLastValueAggregatorTest.java @@ -13,6 +13,7 @@ import io.opentelemetry.api.trace.TraceFlags; import io.opentelemetry.api.trace.TraceState; import io.opentelemetry.sdk.common.InstrumentationScopeInfo; +import io.opentelemetry.sdk.common.export.MemoryMode; import io.opentelemetry.sdk.metrics.data.AggregationTemporality; import io.opentelemetry.sdk.metrics.data.LongExemplarData; import io.opentelemetry.sdk.metrics.data.LongPointData; @@ -28,6 +29,8 @@ import java.util.Collections; import java.util.List; import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.EnumSource; /** Unit tests for {@link LongLastValueAggregator}. */ class LongLastValueAggregatorTest { @@ -36,16 +39,23 @@ class LongLastValueAggregatorTest { InstrumentationScopeInfo.empty(); private static final MetricDescriptor METRIC_DESCRIPTOR = MetricDescriptor.create("name", "description", "unit"); - private static final LongLastValueAggregator aggregator = - new LongLastValueAggregator(ExemplarReservoir::longNoSamples); + private LongLastValueAggregator aggregator; - @Test - void createHandle() { + private void init(MemoryMode memoryMode) { + aggregator = new LongLastValueAggregator(ExemplarReservoir::longNoSamples, memoryMode); + } + + @ParameterizedTest + @EnumSource(MemoryMode.class) + void createHandle(MemoryMode memoryMode) { + init(memoryMode); assertThat(aggregator.createHandle()).isInstanceOf(LongLastValueAggregator.Handle.class); } - @Test - void multipleRecords() { + @ParameterizedTest + @EnumSource(MemoryMode.class) + void multipleRecords(MemoryMode memoryMode) { + init(memoryMode); AggregatorHandle aggregatorHandle = aggregator.createHandle(); aggregatorHandle.recordLong(12); assertThat( @@ -62,8 +72,10 @@ void multipleRecords() { .isEqualTo(14L); } - @Test - void aggregateThenMaybeReset() { + @ParameterizedTest + @EnumSource(MemoryMode.class) + void aggregateThenMaybeReset(MemoryMode memoryMode) { + init(memoryMode); AggregatorHandle aggregatorHandle = aggregator.createHandle(); aggregatorHandle.recordLong(13); @@ -81,8 +93,11 @@ void aggregateThenMaybeReset() { .isEqualTo(12L); } - @Test - void diffInPlace() { + @ParameterizedTest + @EnumSource(MemoryMode.class) + void diffInPlace(MemoryMode memoryMode) { + init(memoryMode); + Attributes attributes = Attributes.builder().put("test", "value").build(); LongExemplarData exemplar = ImmutableLongExemplarData.create( @@ -123,8 +138,11 @@ void diffInPlace() { assertThat(previous.getExemplars()).isEqualTo(exemplars); } - @Test - void copyPoint() { + @ParameterizedTest + @EnumSource(MemoryMode.class) + void copyPoint(MemoryMode memoryMode) { + init(memoryMode); + MutableLongPointData pointData = (MutableLongPointData) aggregator.createReusablePoint(); Attributes attributes = Attributes.of(AttributeKey.longKey("test"), 100L); @@ -166,8 +184,11 @@ void copyPoint() { assertThat(toPointData.getExemplars()).isEqualTo(pointData.getExemplars()); } - @Test - void toMetricData() { + @ParameterizedTest + @EnumSource(MemoryMode.class) + void toMetricData(MemoryMode memoryMode) { + init(memoryMode); + AggregatorHandle aggregatorHandle = aggregator.createHandle(); aggregatorHandle.recordLong(10); @@ -192,4 +213,24 @@ void toMetricData() { Collections.singletonList( ImmutableLongPointData.create(2, 100, Attributes.empty(), 10))))); } + + @Test + void testReusablePointOnCollect() { + init(MemoryMode.REUSABLE_DATA); + AggregatorHandle handle = aggregator.createHandle(); + handle.recordLong(1); + LongPointData pointData = + handle.aggregateThenMaybeReset(0, 10, Attributes.empty(), /* reset= */ false); + + handle.recordLong(1); + LongPointData pointData2 = + handle.aggregateThenMaybeReset(0, 10, Attributes.empty(), /* reset= */ false); + + assertThat(pointData).isSameAs(pointData2); + + LongPointData pointDataWithReset = + handle.aggregateThenMaybeReset(0, 10, Attributes.empty(), /* reset= */ true); + + assertThat(pointData).isSameAs(pointDataWithReset); + } } From c0b73f5218d3b0867c01d07a456d311da6f09a20 Mon Sep 17 00:00:00 2001 From: Austin Pederson Date: Thu, 8 Feb 2024 11:46:28 -0800 Subject: [PATCH 244/901] #6207 Ensure Span Status Cannot Be Updated After StatusCode.OK Is Set (#6209) --- .../main/java/io/opentelemetry/sdk/trace/SdkSpan.java | 3 +++ .../java/io/opentelemetry/sdk/trace/SdkSpanTest.java | 11 +++++++++++ 2 files changed, 14 insertions(+) diff --git a/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/SdkSpan.java b/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/SdkSpan.java index 7f095ddd916..fec835b17ff 100644 --- a/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/SdkSpan.java +++ b/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/SdkSpan.java @@ -394,6 +394,9 @@ public ReadWriteSpan setStatus(StatusCode statusCode, @Nullable String descripti if (hasEnded) { logger.log(Level.FINE, "Calling setStatus() on an ended Span."); return this; + } else if (this.status.getStatusCode() == StatusCode.OK) { + logger.log(Level.FINE, "Calling setStatus() on a Span that is already set to OK."); + return this; } this.status = StatusData.create(statusCode, description); } diff --git a/sdk/trace/src/test/java/io/opentelemetry/sdk/trace/SdkSpanTest.java b/sdk/trace/src/test/java/io/opentelemetry/sdk/trace/SdkSpanTest.java index db75f189e06..df7a6ba1c02 100644 --- a/sdk/trace/src/test/java/io/opentelemetry/sdk/trace/SdkSpanTest.java +++ b/sdk/trace/src/test/java/io/opentelemetry/sdk/trace/SdkSpanTest.java @@ -1178,6 +1178,17 @@ void onStartOnEndNotRequired() { verify(spanProcessor, never()).onEnd(any()); } + @Test + void setStatusCannotOverrideStatusOK() { + SdkSpan testSpan = createTestRootSpan(); + testSpan.setStatus(StatusCode.OK); + assertThat(testSpan.toSpanData().getStatus().getStatusCode()).isEqualTo(StatusCode.OK); + testSpan.setStatus(StatusCode.ERROR); + assertThat(testSpan.toSpanData().getStatus().getStatusCode()).isEqualTo(StatusCode.OK); + testSpan.setStatus(StatusCode.UNSET); + assertThat(testSpan.toSpanData().getStatus().getStatusCode()).isEqualTo(StatusCode.OK); + } + private SdkSpan createTestSpanWithAttributes(Map attributes) { SpanLimits spanLimits = SpanLimits.getDefault(); AttributesMap attributesMap = From 988dccaa5e0a86b3413029c9f04e9ee9e3370be0 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 8 Feb 2024 16:08:53 -0600 Subject: [PATCH 245/901] Update dependency org.testcontainers:testcontainers-bom to v1.19.5 (#6212) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- dependencyManagement/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index 764a568c040..245817a5ab7 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -20,7 +20,7 @@ val DEPENDENCY_BOMS = listOf( "io.zipkin.reporter2:zipkin-reporter-bom:3.2.1", "org.assertj:assertj-bom:3.25.3", "org.junit:junit-bom:5.10.2", - "org.testcontainers:testcontainers-bom:1.19.4", + "org.testcontainers:testcontainers-bom:1.19.5", "org.snakeyaml:snakeyaml-engine:2.7" ) From a5d20654014a190ea6b58de45a17623a8d2dc30a Mon Sep 17 00:00:00 2001 From: Asaf Mesika Date: Fri, 9 Feb 2024 00:09:13 +0200 Subject: [PATCH 246/901] Allow Prometheus exporter to add resource attributes to metric attributes (#6179) --- .../prometheus/Otel2PrometheusConverter.java | 191 +++++++++---- .../prometheus/PrometheusHttpServer.java | 7 +- .../PrometheusHttpServerBuilder.java | 27 +- .../prometheus/PrometheusMetricReader.java | 11 +- .../PrometheusMetricReaderProvider.java | 1 + .../Otel2PrometheusConverterTest.java | 256 +++++++++++++++++- .../exporter/prometheus/Predicates.java | 24 ++ .../prometheus/PrometheusHttpServerTest.java | 47 ++++ .../PrometheusMetricReaderTest.java | 92 +++++-- sdk-extensions/autoconfigure/README.md | 10 +- 10 files changed, 563 insertions(+), 103 deletions(-) create mode 100644 exporters/prometheus/src/test/java/io/opentelemetry/exporter/prometheus/Predicates.java diff --git a/exporters/prometheus/src/main/java/io/opentelemetry/exporter/prometheus/Otel2PrometheusConverter.java b/exporters/prometheus/src/main/java/io/opentelemetry/exporter/prometheus/Otel2PrometheusConverter.java index 820f1f64d6a..3b601328ac7 100644 --- a/exporters/prometheus/src/main/java/io/opentelemetry/exporter/prometheus/Otel2PrometheusConverter.java +++ b/exporters/prometheus/src/main/java/io/opentelemetry/exporter/prometheus/Otel2PrometheusConverter.java @@ -7,7 +7,9 @@ import static io.prometheus.metrics.model.snapshots.PrometheusNaming.sanitizeLabelName; import static io.prometheus.metrics.model.snapshots.PrometheusNaming.sanitizeMetricName; +import static java.util.Objects.requireNonNull; +import io.opentelemetry.api.common.AttributeKey; import io.opentelemetry.api.common.Attributes; import io.opentelemetry.api.trace.SpanContext; import io.opentelemetry.sdk.common.InstrumentationScopeInfo; @@ -58,9 +60,12 @@ import java.util.Locale; import java.util.Map; import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.TimeUnit; +import java.util.function.Predicate; import java.util.logging.Level; import java.util.logging.Logger; +import java.util.stream.Collectors; import javax.annotation.Nullable; /** Convert OpenTelemetry {@link MetricData} to Prometheus {@link MetricSnapshots}. */ @@ -68,19 +73,36 @@ final class Otel2PrometheusConverter { private static final Logger LOGGER = Logger.getLogger(Otel2PrometheusConverter.class.getName()); private static final ThrottlingLogger THROTTLING_LOGGER = new ThrottlingLogger(LOGGER); - private final boolean otelScopeEnabled; private static final String OTEL_SCOPE_NAME = "otel_scope_name"; private static final String OTEL_SCOPE_VERSION = "otel_scope_version"; private static final long NANOS_PER_MILLISECOND = TimeUnit.MILLISECONDS.toNanos(1); + static final int MAX_CACHE_SIZE = 10; + + private final boolean otelScopeEnabled; + @Nullable private final Predicate allowedResourceAttributesFilter; + + /** + * Used only if addResourceAttributesAsLabels is true. Once the cache reaches {@link + * #MAX_CACHE_SIZE}, it is cleared to protect against unbounded conversion over time. + */ + private final Map>> resourceAttributesToAllowedKeysCache; /** * Constructor with feature flag parameter. * * @param otelScopeEnabled enable generation of the OpenTelemetry instrumentation scope info * metric and labels. + * @param allowedResourceAttributesFilter if not {@code null}, resource attributes with keys + * matching this predicate will be added as labels on each exported metric */ - Otel2PrometheusConverter(boolean otelScopeEnabled) { + Otel2PrometheusConverter( + boolean otelScopeEnabled, @Nullable Predicate allowedResourceAttributesFilter) { this.otelScopeEnabled = otelScopeEnabled; + this.allowedResourceAttributesFilter = allowedResourceAttributesFilter; + this.resourceAttributesToAllowedKeysCache = + allowedResourceAttributesFilter != null + ? new ConcurrentHashMap<>() + : Collections.emptyMap(); } MetricSnapshots convert(@Nullable Collection metricDataCollection) { @@ -122,33 +144,40 @@ private MetricSnapshot convert(MetricData metricData) { InstrumentationScopeInfo scope = metricData.getInstrumentationScopeInfo(); switch (metricData.getType()) { case LONG_GAUGE: - return convertLongGauge(metadata, scope, metricData.getLongGaugeData().getPoints()); + return convertLongGauge( + metadata, scope, metricData.getLongGaugeData().getPoints(), metricData.getResource()); case DOUBLE_GAUGE: - return convertDoubleGauge(metadata, scope, metricData.getDoubleGaugeData().getPoints()); + return convertDoubleGauge( + metadata, scope, metricData.getDoubleGaugeData().getPoints(), metricData.getResource()); case LONG_SUM: SumData longSumData = metricData.getLongSumData(); if (longSumData.getAggregationTemporality() == AggregationTemporality.DELTA) { return null; } else if (longSumData.isMonotonic()) { - return convertLongCounter(metadata, scope, longSumData.getPoints()); + return convertLongCounter( + metadata, scope, longSumData.getPoints(), metricData.getResource()); } else { - return convertLongGauge(metadata, scope, longSumData.getPoints()); + return convertLongGauge( + metadata, scope, longSumData.getPoints(), metricData.getResource()); } case DOUBLE_SUM: SumData doubleSumData = metricData.getDoubleSumData(); if (doubleSumData.getAggregationTemporality() == AggregationTemporality.DELTA) { return null; } else if (doubleSumData.isMonotonic()) { - return convertDoubleCounter(metadata, scope, doubleSumData.getPoints()); + return convertDoubleCounter( + metadata, scope, doubleSumData.getPoints(), metricData.getResource()); } else { - return convertDoubleGauge(metadata, scope, doubleSumData.getPoints()); + return convertDoubleGauge( + metadata, scope, doubleSumData.getPoints(), metricData.getResource()); } case HISTOGRAM: HistogramData histogramData = metricData.getHistogramData(); if (histogramData.getAggregationTemporality() == AggregationTemporality.DELTA) { return null; } else { - return convertHistogram(metadata, scope, histogramData.getPoints()); + return convertHistogram( + metadata, scope, histogramData.getPoints(), metricData.getResource()); } case EXPONENTIAL_HISTOGRAM: ExponentialHistogramData exponentialHistogramData = @@ -156,10 +185,12 @@ private MetricSnapshot convert(MetricData metricData) { if (exponentialHistogramData.getAggregationTemporality() == AggregationTemporality.DELTA) { return null; } else { - return convertExponentialHistogram(metadata, scope, exponentialHistogramData.getPoints()); + return convertExponentialHistogram( + metadata, scope, exponentialHistogramData.getPoints(), metricData.getResource()); } case SUMMARY: - return convertSummary(metadata, scope, metricData.getSummaryData().getPoints()); + return convertSummary( + metadata, scope, metricData.getSummaryData().getPoints(), metricData.getResource()); } return null; } @@ -167,13 +198,14 @@ private MetricSnapshot convert(MetricData metricData) { private GaugeSnapshot convertLongGauge( MetricMetadata metadata, InstrumentationScopeInfo scope, - Collection dataPoints) { + Collection dataPoints, + Resource resource) { List data = new ArrayList<>(dataPoints.size()); for (LongPointData longData : dataPoints) { data.add( new GaugeDataPointSnapshot( (double) longData.getValue(), - convertAttributes(scope, longData.getAttributes()), + convertAttributes(resource, scope, longData.getAttributes()), convertLongExemplar(longData.getExemplars()))); } return new GaugeSnapshot(metadata, data); @@ -182,13 +214,14 @@ private GaugeSnapshot convertLongGauge( private CounterSnapshot convertLongCounter( MetricMetadata metadata, InstrumentationScopeInfo scope, - Collection dataPoints) { + Collection dataPoints, + Resource resource) { List data = new ArrayList<>(dataPoints.size()); for (LongPointData longData : dataPoints) { data.add( new CounterDataPointSnapshot( (double) longData.getValue(), - convertAttributes(scope, longData.getAttributes()), + convertAttributes(resource, scope, longData.getAttributes()), convertLongExemplar(longData.getExemplars()), longData.getStartEpochNanos() / NANOS_PER_MILLISECOND)); } @@ -198,13 +231,14 @@ private CounterSnapshot convertLongCounter( private GaugeSnapshot convertDoubleGauge( MetricMetadata metadata, InstrumentationScopeInfo scope, - Collection dataPoints) { + Collection dataPoints, + Resource resource) { List data = new ArrayList<>(dataPoints.size()); for (DoublePointData doubleData : dataPoints) { data.add( new GaugeDataPointSnapshot( doubleData.getValue(), - convertAttributes(scope, doubleData.getAttributes()), + convertAttributes(resource, scope, doubleData.getAttributes()), convertDoubleExemplar(doubleData.getExemplars()))); } return new GaugeSnapshot(metadata, data); @@ -213,13 +247,14 @@ private GaugeSnapshot convertDoubleGauge( private CounterSnapshot convertDoubleCounter( MetricMetadata metadata, InstrumentationScopeInfo scope, - Collection dataPoints) { + Collection dataPoints, + Resource resource) { List data = new ArrayList<>(dataPoints.size()); for (DoublePointData doubleData : dataPoints) { data.add( new CounterDataPointSnapshot( doubleData.getValue(), - convertAttributes(scope, doubleData.getAttributes()), + convertAttributes(resource, scope, doubleData.getAttributes()), convertDoubleExemplar(doubleData.getExemplars()), doubleData.getStartEpochNanos() / NANOS_PER_MILLISECOND)); } @@ -229,7 +264,8 @@ private CounterSnapshot convertDoubleCounter( private HistogramSnapshot convertHistogram( MetricMetadata metadata, InstrumentationScopeInfo scope, - Collection dataPoints) { + Collection dataPoints, + Resource resource) { List data = new ArrayList<>(dataPoints.size()); for (HistogramPointData histogramData : dataPoints) { List boundaries = new ArrayList<>(histogramData.getBoundaries().size() + 1); @@ -239,7 +275,7 @@ private HistogramSnapshot convertHistogram( new HistogramDataPointSnapshot( ClassicHistogramBuckets.of(boundaries, histogramData.getCounts()), histogramData.getSum(), - convertAttributes(scope, histogramData.getAttributes()), + convertAttributes(resource, scope, histogramData.getAttributes()), convertDoubleExemplars(histogramData.getExemplars()), histogramData.getStartEpochNanos() / NANOS_PER_MILLISECOND)); } @@ -250,7 +286,8 @@ private HistogramSnapshot convertHistogram( private HistogramSnapshot convertExponentialHistogram( MetricMetadata metadata, InstrumentationScopeInfo scope, - Collection dataPoints) { + Collection dataPoints, + Resource resource) { List data = new ArrayList<>(dataPoints.size()); for (ExponentialHistogramPointData histogramData : dataPoints) { int scale = histogramData.getScale(); @@ -274,7 +311,7 @@ private HistogramSnapshot convertExponentialHistogram( convertExponentialHistogramBuckets(histogramData.getPositiveBuckets(), scaleDown), convertExponentialHistogramBuckets(histogramData.getNegativeBuckets(), scaleDown), histogramData.getSum(), - convertAttributes(scope, histogramData.getAttributes()), + convertAttributes(resource, scope, histogramData.getAttributes()), convertDoubleExemplars(histogramData.getExemplars()), histogramData.getStartEpochNanos() / NANOS_PER_MILLISECOND)); } @@ -309,7 +346,8 @@ private static NativeHistogramBuckets convertExponentialHistogramBuckets( private SummarySnapshot convertSummary( MetricMetadata metadata, InstrumentationScopeInfo scope, - Collection dataPoints) { + Collection dataPoints, + Resource resource) { List data = new ArrayList<>(dataPoints.size()); for (SummaryPointData summaryData : dataPoints) { data.add( @@ -317,7 +355,7 @@ private SummarySnapshot convertSummary( summaryData.getCount(), summaryData.getSum(), convertQuantiles(summaryData.getValues()), - convertAttributes(scope, summaryData.getAttributes()), + convertAttributes(resource, scope, summaryData.getAttributes()), Exemplars.EMPTY, // Exemplars for Summaries not implemented yet. summaryData.getStartEpochNanos() / NANOS_PER_MILLISECOND)); } @@ -368,7 +406,8 @@ private Exemplar convertExemplar(double value, ExemplarData exemplar) { return new Exemplar( value, convertAttributes( - null, + null, // resource attributes are only copied for point's attributes + null, // scope attributes are only needed for point's attributes exemplar.getFilteredAttributes(), "trace_id", spanContext.getTraceId(), @@ -378,7 +417,10 @@ private Exemplar convertExemplar(double value, ExemplarData exemplar) { } else { return new Exemplar( value, - convertAttributes(null, exemplar.getFilteredAttributes()), + convertAttributes( + null, // resource attributes are only copied for point's attributes + null, // scope attributes are only needed for point's attributes + exemplar.getFilteredAttributes()), exemplar.getEpochNanos() / NANOS_PER_MILLISECOND); } } @@ -387,14 +429,22 @@ private InfoSnapshot makeTargetInfo(Resource resource) { return new InfoSnapshot( new MetricMetadata("target"), Collections.singletonList( - new InfoDataPointSnapshot(convertAttributes(null, resource.getAttributes())))); + new InfoDataPointSnapshot( + convertAttributes( + null, // resource attributes are only copied for point's attributes + null, // scope attributes are only needed for point's attributes + resource.getAttributes())))); } private InfoSnapshot makeScopeInfo(Set scopes) { List prometheusScopeInfos = new ArrayList<>(scopes.size()); for (InstrumentationScopeInfo scope : scopes) { prometheusScopeInfos.add( - new InfoDataPointSnapshot(convertAttributes(scope, scope.getAttributes()))); + new InfoDataPointSnapshot( + convertAttributes( + null, // resource attributes are only copied for point's attributes + scope, + scope.getAttributes()))); } return new InfoSnapshot(new MetricMetadata("otel_scope"), prometheusScopeInfos); } @@ -402,47 +452,86 @@ private InfoSnapshot makeScopeInfo(Set scopes) { /** * Convert OpenTelemetry attributes to Prometheus labels. * + * @param resource optional resource (attributes) to be converted. * @param scope will be converted to {@code otel_scope_*} labels if {@code otelScopeEnabled} is * {@code true}. * @param attributes the attributes to be converted. * @param additionalAttributes optional list of key/value pairs, may be empty. */ + @SuppressWarnings({"rawtypes", "unchecked"}) private Labels convertAttributes( + @Nullable Resource resource, @Nullable InstrumentationScopeInfo scope, Attributes attributes, String... additionalAttributes) { - int numberOfScopeAttributes = 0; - if (otelScopeEnabled && scope != null) { - numberOfScopeAttributes = scope.getVersion() == null ? 1 : 2; - } - String[] names = - new String[attributes.size() + numberOfScopeAttributes + additionalAttributes.length / 2]; - String[] values = new String[names.length]; - int[] pos = new int[] {0}; // using an array because we want to increment in a forEach() lambda. + + List> allowedAttributeKeys = + allowedResourceAttributesFilter != null + ? filterAllowedResourceAttributeKeys(resource) + : Collections.emptyList(); + + Map labelNameToValue = new HashMap<>(); attributes.forEach( - (key, value) -> { - names[pos[0]] = sanitizeLabelName(key.getKey()); - values[pos[0]] = value.toString(); - pos[0]++; - }); + (key, value) -> labelNameToValue.put(sanitizeLabelName(key.getKey()), value.toString())); + for (int i = 0; i < additionalAttributes.length; i += 2) { - names[pos[0]] = additionalAttributes[i]; - values[pos[0]] = additionalAttributes[i + 1]; - pos[0]++; + labelNameToValue.putIfAbsent( + requireNonNull(additionalAttributes[i]), additionalAttributes[i + 1]); } + if (otelScopeEnabled && scope != null) { - names[pos[0]] = OTEL_SCOPE_NAME; - values[pos[0]] = scope.getName(); - pos[0]++; + labelNameToValue.putIfAbsent(OTEL_SCOPE_NAME, scope.getName()); if (scope.getVersion() != null) { - names[pos[0]] = OTEL_SCOPE_VERSION; - values[pos[0]] = scope.getVersion(); - pos[0]++; + labelNameToValue.putIfAbsent(OTEL_SCOPE_VERSION, scope.getVersion()); } } + + if (resource != null) { + Attributes resourceAttributes = resource.getAttributes(); + for (AttributeKey attributeKey : allowedAttributeKeys) { + Object attributeValue = resourceAttributes.get(attributeKey); + if (attributeValue != null) { + labelNameToValue.putIfAbsent( + sanitizeLabelName(attributeKey.getKey()), attributeValue.toString()); + } + } + } + + String[] names = new String[labelNameToValue.size()]; + String[] values = new String[labelNameToValue.size()]; + int[] pos = new int[] {0}; + labelNameToValue.forEach( + (name, value) -> { + names[pos[0]] = name; + values[pos[0]] = value; + pos[0] += 1; + }); + return Labels.of(names, values); } + private List> filterAllowedResourceAttributeKeys(@Nullable Resource resource) { + requireNonNull( + allowedResourceAttributesFilter, + "This method should only be called when allowedResourceAttributesFilter is not null."); + if (resource == null) { + return Collections.emptyList(); + } + + List> allowedAttributeKeys = + resourceAttributesToAllowedKeysCache.computeIfAbsent( + resource.getAttributes(), + resourceAttributes -> + resourceAttributes.asMap().keySet().stream() + .filter(o -> allowedResourceAttributesFilter.test(o.getKey())) + .collect(Collectors.toList())); + + if (resourceAttributesToAllowedKeysCache.size() > MAX_CACHE_SIZE) { + resourceAttributesToAllowedKeysCache.clear(); + } + return allowedAttributeKeys; + } + private static MetricMetadata convertMetadata(MetricData metricData) { String name = sanitizeMetricName(metricData.getName()); String help = metricData.getDescription(); diff --git a/exporters/prometheus/src/main/java/io/opentelemetry/exporter/prometheus/PrometheusHttpServer.java b/exporters/prometheus/src/main/java/io/opentelemetry/exporter/prometheus/PrometheusHttpServer.java index 6b89884e6b7..9024fe4f97b 100644 --- a/exporters/prometheus/src/main/java/io/opentelemetry/exporter/prometheus/PrometheusHttpServer.java +++ b/exporters/prometheus/src/main/java/io/opentelemetry/exporter/prometheus/PrometheusHttpServer.java @@ -23,6 +23,7 @@ import java.net.InetSocketAddress; import java.util.concurrent.ExecutorService; import java.util.concurrent.TimeUnit; +import java.util.function.Predicate; import javax.annotation.Nullable; /** @@ -55,8 +56,10 @@ public static PrometheusHttpServerBuilder builder() { int port, @Nullable ExecutorService executor, PrometheusRegistry prometheusRegistry, - boolean otelScopeEnabled) { - this.prometheusMetricReader = new PrometheusMetricReader(otelScopeEnabled); + boolean otelScopeEnabled, + @Nullable Predicate allowedResourceAttributesFilter) { + this.prometheusMetricReader = + new PrometheusMetricReader(otelScopeEnabled, allowedResourceAttributesFilter); this.host = host; this.prometheusRegistry = prometheusRegistry; prometheusRegistry.register(prometheusMetricReader); diff --git a/exporters/prometheus/src/main/java/io/opentelemetry/exporter/prometheus/PrometheusHttpServerBuilder.java b/exporters/prometheus/src/main/java/io/opentelemetry/exporter/prometheus/PrometheusHttpServerBuilder.java index 975091a93b5..9c4594411f5 100644 --- a/exporters/prometheus/src/main/java/io/opentelemetry/exporter/prometheus/PrometheusHttpServerBuilder.java +++ b/exporters/prometheus/src/main/java/io/opentelemetry/exporter/prometheus/PrometheusHttpServerBuilder.java @@ -10,6 +10,7 @@ import io.prometheus.metrics.model.registry.PrometheusRegistry; import java.util.concurrent.ExecutorService; +import java.util.function.Predicate; import javax.annotation.Nullable; /** A builder for {@link PrometheusHttpServer}. */ @@ -22,7 +23,7 @@ public final class PrometheusHttpServerBuilder { private int port = DEFAULT_PORT; private PrometheusRegistry prometheusRegistry = new PrometheusRegistry(); private boolean otelScopeEnabled = true; - + @Nullable private Predicate allowedResourceAttributesFilter; @Nullable private ExecutorService executor; /** Sets the host to bind to. If unset, defaults to {@value #DEFAULT_HOST}. */ @@ -60,12 +61,34 @@ public PrometheusHttpServerBuilder setOtelScopeEnabled(boolean otelScopeEnabled) return this; } + /** + * Set if the resource attributes should be added as labels on each exported metric. + * + *

    If set, resource attributes will be added as labels on each exported metric if their key + * tests positive (true) when passed through {@code resourceAttributesFilter}. + * + * @param resourceAttributesFilter a predicate that returns true if the resource attribute should + * be added as a label on each exported metric. The predicates input is the resource attribute + * key. + */ + public PrometheusHttpServerBuilder setAllowedResourceAttributesFilter( + Predicate resourceAttributesFilter) { + this.allowedResourceAttributesFilter = requireNonNull(resourceAttributesFilter); + return this; + } + /** * Returns a new {@link PrometheusHttpServer} with the configuration of this builder which can be * registered with a {@link io.opentelemetry.sdk.metrics.SdkMeterProvider}. */ public PrometheusHttpServer build() { - return new PrometheusHttpServer(host, port, executor, prometheusRegistry, otelScopeEnabled); + return new PrometheusHttpServer( + host, + port, + executor, + prometheusRegistry, + otelScopeEnabled, + allowedResourceAttributesFilter); } PrometheusHttpServerBuilder() {} diff --git a/exporters/prometheus/src/main/java/io/opentelemetry/exporter/prometheus/PrometheusMetricReader.java b/exporters/prometheus/src/main/java/io/opentelemetry/exporter/prometheus/PrometheusMetricReader.java index 02ac63e4d81..b51c83ab6f7 100644 --- a/exporters/prometheus/src/main/java/io/opentelemetry/exporter/prometheus/PrometheusMetricReader.java +++ b/exporters/prometheus/src/main/java/io/opentelemetry/exporter/prometheus/PrometheusMetricReader.java @@ -12,6 +12,8 @@ import io.opentelemetry.sdk.metrics.export.MetricReader; import io.prometheus.metrics.model.registry.MultiCollector; import io.prometheus.metrics.model.snapshots.MetricSnapshots; +import java.util.function.Predicate; +import javax.annotation.Nullable; /** * This is the bridge between Prometheus and OpenTelemetry. @@ -26,9 +28,12 @@ public class PrometheusMetricReader implements MetricReader, MultiCollector { private volatile CollectionRegistration collectionRegistration = CollectionRegistration.noop(); private final Otel2PrometheusConverter converter; - /** See {@link Otel2PrometheusConverter#Otel2PrometheusConverter(boolean)}. */ - public PrometheusMetricReader(boolean otelScopeEnabled) { - this.converter = new Otel2PrometheusConverter(otelScopeEnabled); + // TODO: refactor to public static create or builder pattern to align with project style + /** See {@link Otel2PrometheusConverter#Otel2PrometheusConverter(boolean, Predicate)}. */ + public PrometheusMetricReader( + boolean otelScopeEnabled, @Nullable Predicate allowedResourceAttributesFilter) { + this.converter = + new Otel2PrometheusConverter(otelScopeEnabled, allowedResourceAttributesFilter); } @Override diff --git a/exporters/prometheus/src/main/java/io/opentelemetry/exporter/prometheus/internal/PrometheusMetricReaderProvider.java b/exporters/prometheus/src/main/java/io/opentelemetry/exporter/prometheus/internal/PrometheusMetricReaderProvider.java index 062dd1e7ccd..d7393dabf8b 100644 --- a/exporters/prometheus/src/main/java/io/opentelemetry/exporter/prometheus/internal/PrometheusMetricReaderProvider.java +++ b/exporters/prometheus/src/main/java/io/opentelemetry/exporter/prometheus/internal/PrometheusMetricReaderProvider.java @@ -31,6 +31,7 @@ public MetricReader createMetricReader(ConfigProperties config) { if (host != null) { prometheusBuilder.setHost(host); } + return prometheusBuilder.build(); } diff --git a/exporters/prometheus/src/test/java/io/opentelemetry/exporter/prometheus/Otel2PrometheusConverterTest.java b/exporters/prometheus/src/test/java/io/opentelemetry/exporter/prometheus/Otel2PrometheusConverterTest.java index 6347d781498..33729f7ac8d 100644 --- a/exporters/prometheus/src/test/java/io/opentelemetry/exporter/prometheus/Otel2PrometheusConverterTest.java +++ b/exporters/prometheus/src/test/java/io/opentelemetry/exporter/prometheus/Otel2PrometheusConverterTest.java @@ -5,6 +5,7 @@ package io.opentelemetry.exporter.prometheus; +import static io.opentelemetry.api.common.AttributeKey.stringKey; import static org.assertj.core.api.Assertions.assertThat; import io.opentelemetry.api.common.Attributes; @@ -12,6 +13,10 @@ import io.opentelemetry.sdk.metrics.data.AggregationTemporality; import io.opentelemetry.sdk.metrics.data.MetricData; import io.opentelemetry.sdk.metrics.data.MetricDataType; +import io.opentelemetry.sdk.metrics.internal.data.ImmutableDoublePointData; +import io.opentelemetry.sdk.metrics.internal.data.ImmutableExponentialHistogramBuckets; +import io.opentelemetry.sdk.metrics.internal.data.ImmutableExponentialHistogramData; +import io.opentelemetry.sdk.metrics.internal.data.ImmutableExponentialHistogramPointData; import io.opentelemetry.sdk.metrics.internal.data.ImmutableGaugeData; import io.opentelemetry.sdk.metrics.internal.data.ImmutableHistogramData; import io.opentelemetry.sdk.metrics.internal.data.ImmutableHistogramPointData; @@ -26,11 +31,18 @@ import java.io.ByteArrayOutputStream; import java.io.IOException; import java.nio.charset.StandardCharsets; +import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; +import java.util.List; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.function.Predicate; import java.util.regex.Matcher; import java.util.regex.Pattern; +import java.util.stream.Collectors; import java.util.stream.Stream; +import javax.annotation.Nullable; +import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.MethodSource; @@ -41,17 +53,18 @@ class Otel2PrometheusConverterTest { Pattern.compile( "# HELP (?.*)\n# TYPE (?.*)\n(?.*)\\{otel_scope_name=\"scope\"}(.|\\n)*"); - private final Otel2PrometheusConverter converter = new Otel2PrometheusConverter(true); + private final Otel2PrometheusConverter converter = + new Otel2PrometheusConverter(true, /* allowedResourceAttributesFilter= */ null); @ParameterizedTest @MethodSource("metricMetadataArgs") void metricMetadata( MetricData metricData, String expectedType, String expectedHelp, String expectedMetricName) throws IOException { - ByteArrayOutputStream baos = new ByteArrayOutputStream(); + ByteArrayOutputStream out = new ByteArrayOutputStream(); MetricSnapshots snapshots = converter.convert(Collections.singletonList(metricData)); - ExpositionFormats.init().getPrometheusTextFormatWriter().write(baos, snapshots); - String expositionFormat = new String(baos.toByteArray(), StandardCharsets.UTF_8); + ExpositionFormats.init().getPrometheusTextFormatWriter().write(out, snapshots); + String expositionFormat = new String(out.toByteArray(), StandardCharsets.UTF_8); // Uncomment to debug exposition format output // System.out.println(expositionFormat); @@ -65,6 +78,98 @@ void metricMetadata( assertThat(matcher.group("metricName")).isEqualTo(expectedMetricName); } + @ParameterizedTest + @MethodSource("resourceAttributesAdditionArgs") + void resourceAttributesAddition( + MetricData metricData, + @Nullable Predicate allowedResourceAttributesFilter, + String metricName, + String expectedMetricLabels) + throws IOException { + + Otel2PrometheusConverter converter = + new Otel2PrometheusConverter(true, allowedResourceAttributesFilter); + + ByteArrayOutputStream out = new ByteArrayOutputStream(); + MetricSnapshots snapshots = converter.convert(Collections.singletonList(metricData)); + ExpositionFormats.init().getPrometheusTextFormatWriter().write(out, snapshots); + String expositionFormat = new String(out.toByteArray(), StandardCharsets.UTF_8); + + // extract the only metric line + List metricLines = + Arrays.stream(expositionFormat.split("\n")) + .filter(line -> line.startsWith(metricName)) + .collect(Collectors.toList()); + assertThat(metricLines).hasSize(1); + String metricLine = metricLines.get(0); + + String metricLabels = + metricLine.substring(metricLine.indexOf("{") + 1, metricLine.indexOf("}")); + assertThat(metricLabels).isEqualTo(expectedMetricLabels); + } + + private static Stream resourceAttributesAdditionArgs() { + List arguments = new ArrayList<>(); + + for (MetricDataType metricDataType : MetricDataType.values()) { + // Check that resource attributes are added as labels, according to allowed pattern + arguments.add( + Arguments.of( + createSampleMetricData( + "my.metric", + "units", + metricDataType, + Attributes.of(stringKey("foo1"), "bar1", stringKey("foo2"), "bar2"), + Resource.create( + Attributes.of( + stringKey("host"), "localhost", stringKey("cluster"), "mycluster"))), + /* allowedResourceAttributesFilter= */ Predicates.startsWith("clu"), + metricDataType == MetricDataType.SUMMARY + || metricDataType == MetricDataType.HISTOGRAM + || metricDataType == MetricDataType.EXPONENTIAL_HISTOGRAM + ? "my_metric_units_count" + : "my_metric_units", + + // "cluster" attribute is added (due to reg expr specified) and only it + "cluster=\"mycluster\",foo1=\"bar1\",foo2=\"bar2\",otel_scope_name=\"scope\"")); + } + + // Resource attributes which also exists in the metric labels are not added twice + arguments.add( + Arguments.of( + createSampleMetricData( + "my.metric", + "units", + MetricDataType.LONG_SUM, + Attributes.of(stringKey("cluster"), "mycluster2", stringKey("foo2"), "bar2"), + Resource.create( + Attributes.of( + stringKey("host"), "localhost", stringKey("cluster"), "mycluster"))), + /* allowedResourceAttributesFilter= */ Predicates.startsWith("clu"), + "my_metric_units", + + // "cluster" attribute is present only once and the value is taken + // from the metric attributes and not the resource attributes + "cluster=\"mycluster2\",foo2=\"bar2\",otel_scope_name=\"scope\"")); + + // Empty attributes + arguments.add( + Arguments.of( + createSampleMetricData( + "my.metric", + "units", + MetricDataType.LONG_SUM, + Attributes.empty(), + Resource.create( + Attributes.of( + stringKey("host"), "localhost", stringKey("cluster"), "mycluster"))), + /* allowedResourceAttributesFilter= */ Predicates.startsWith("clu"), + "my_metric_units", + "cluster=\"mycluster\",otel_scope_name=\"scope\"")); + + return arguments.stream(); + } + private static Stream metricMetadataArgs() { return Stream.of( // the unity unit "1" is translated to "ratio" @@ -160,12 +265,30 @@ private static Stream metricMetadataArgs() { "_metric_name_bytes_count")); } + static MetricData createSampleMetricData( + String metricName, Resource resource, Attributes attributes) { + return createSampleMetricData( + metricName, "unit", MetricDataType.LONG_SUM, attributes, resource); + } + static MetricData createSampleMetricData( String metricName, String metricUnit, MetricDataType metricDataType) { + return createSampleMetricData(metricName, metricUnit, metricDataType, null, null); + } + + static MetricData createSampleMetricData( + String metricName, + String metricUnit, + MetricDataType metricDataType, + @Nullable Attributes attributes, + @Nullable Resource resource) { + Attributes attributesToUse = attributes == null ? Attributes.empty() : attributes; + Resource resourceToUse = resource == null ? Resource.getDefault() : resource; + switch (metricDataType) { case SUMMARY: return ImmutableMetricData.createDoubleSummary( - Resource.getDefault(), + resourceToUse, InstrumentationScopeInfo.create("scope"), metricName, "description", @@ -173,10 +296,22 @@ static MetricData createSampleMetricData( ImmutableSummaryData.create( Collections.singletonList( ImmutableSummaryPointData.create( - 0, 1, Attributes.empty(), 1, 1, Collections.emptyList())))); + 0, 1, attributesToUse, 1, 1, Collections.emptyList())))); case LONG_SUM: return ImmutableMetricData.createLongSum( - Resource.getDefault(), + resourceToUse, + InstrumentationScopeInfo.create("scope"), + metricName, + "description", + metricUnit, + ImmutableSumData.create( + true, + AggregationTemporality.CUMULATIVE, + Collections.singletonList( + ImmutableLongPointData.create(0, 1, attributesToUse, 1L)))); + case DOUBLE_SUM: + return ImmutableMetricData.createDoubleSum( + resourceToUse, InstrumentationScopeInfo.create("scope"), metricName, "description", @@ -185,20 +320,30 @@ static MetricData createSampleMetricData( true, AggregationTemporality.CUMULATIVE, Collections.singletonList( - ImmutableLongPointData.create(0, 1, Attributes.empty(), 1L)))); + ImmutableDoublePointData.create(0, 1, attributesToUse, 1.0)))); case LONG_GAUGE: return ImmutableMetricData.createLongGauge( - Resource.getDefault(), + resourceToUse, InstrumentationScopeInfo.create("scope"), metricName, "description", metricUnit, ImmutableGaugeData.create( Collections.singletonList( - ImmutableLongPointData.create(0, 1, Attributes.empty(), 1L)))); + ImmutableLongPointData.create(0, 1, attributesToUse, 1L)))); + case DOUBLE_GAUGE: + return ImmutableMetricData.createDoubleGauge( + resourceToUse, + InstrumentationScopeInfo.create("scope"), + metricName, + "description", + metricUnit, + ImmutableGaugeData.create( + Collections.singletonList( + ImmutableDoublePointData.create(0, 1, attributesToUse, 1.0f)))); case HISTOGRAM: return ImmutableMetricData.createDoubleHistogram( - Resource.getDefault(), + resourceToUse, InstrumentationScopeInfo.create("scope"), metricName, "description", @@ -209,7 +354,7 @@ static MetricData createSampleMetricData( ImmutableHistogramPointData.create( 0, 1, - Attributes.empty(), + attributesToUse, 1, false, -1, @@ -217,8 +362,91 @@ static MetricData createSampleMetricData( -1, Collections.singletonList(1.0), Arrays.asList(0L, 1L))))); - default: - throw new IllegalArgumentException("Unsupported metric data type: " + metricDataType); + case EXPONENTIAL_HISTOGRAM: + return ImmutableMetricData.createExponentialHistogram( + resourceToUse, + InstrumentationScopeInfo.create("scope"), + metricName, + "description", + metricUnit, + ImmutableExponentialHistogramData.create( + AggregationTemporality.CUMULATIVE, + Collections.singletonList( + ImmutableExponentialHistogramPointData.create( + 0, + 1, + 5, + false, + 1, + false, + 1, + ImmutableExponentialHistogramBuckets.create( + 2, 5, Arrays.asList(1L, 2L, 3L, 4L, 5L)), + ImmutableExponentialHistogramBuckets.create( + 2, 5, Arrays.asList(1L, 2L, 3L, 4L, 5L)), + 0, + 10, + attributesToUse, + Collections.emptyList())))); + } + + throw new IllegalArgumentException("Unsupported metric data type: " + metricDataType); + } + + @Test + void validateCacheIsBounded() { + AtomicInteger predicateCalledCount = new AtomicInteger(); + Predicate countPredicate = + s -> { + predicateCalledCount.addAndGet(1); + return true; + }; + + Otel2PrometheusConverter otel2PrometheusConverter = + new Otel2PrometheusConverter(true, /* allowedResourceAttributesFilter= */ countPredicate); + + // Create 20 different metric data objects with 2 different resource attributes; + Resource resource1 = Resource.builder().put("cluster", "cluster1").build(); + Resource resource2 = Resource.builder().put("cluster", "cluster2").build(); + + List metricDataList = new ArrayList<>(); + for (int i = 0; i < 10; i++) { + Attributes attributes = Attributes.of(stringKey("foo" + i), "bar" + i); + metricDataList.add(createSampleMetricData("metric1", resource1, attributes)); + metricDataList.add(createSampleMetricData("metric2", resource2, attributes)); } + + otel2PrometheusConverter.convert(metricDataList); + + // The predicate should be called only once for each resource attribute, and we have + // 2 unique resources, each with 1 attribute, so 2. + assertThat(predicateCalledCount.get()).isEqualTo(2); + + metricDataList.clear(); + + // Create 20 different metric data objects with 20 different resource attributes; + // This should cause the cache to be full, and then subsequently cleared + for (int i = 0; i < Otel2PrometheusConverter.MAX_CACHE_SIZE; i++) { + Attributes attributes = Attributes.of(stringKey("foo" + i), "bar" + i); + Resource resource = Resource.builder().put("cluster", "different-cluster" + i).build(); + metricDataList.add(createSampleMetricData("metric1", resource, attributes)); + metricDataList.add(createSampleMetricData("metric2", resource, attributes)); + } + otel2PrometheusConverter.convert(metricDataList); + + // Now lets put metrics with the same resource attributes as before + metricDataList.clear(); + predicateCalledCount.set(0); + for (int i = 0; i < 10; i++) { + Attributes attributes = Attributes.of(stringKey("foo" + i), "bar" + i); + metricDataList.add(createSampleMetricData("metric1", resource1, attributes)); + metricDataList.add(createSampleMetricData("metric2", resource2, attributes)); + } + otel2PrometheusConverter.convert(metricDataList); + + // If the cache was unbounded, the predicate should be 0, since it's all in the cache, + // but if the cache was cleared, it used the predicate for each resource, since it as if + // it never saw those resources before. + assertThat(predicateCalledCount.get()).isEqualTo(2); } } diff --git a/exporters/prometheus/src/test/java/io/opentelemetry/exporter/prometheus/Predicates.java b/exporters/prometheus/src/test/java/io/opentelemetry/exporter/prometheus/Predicates.java new file mode 100644 index 00000000000..8fdcc75c6c4 --- /dev/null +++ b/exporters/prometheus/src/test/java/io/opentelemetry/exporter/prometheus/Predicates.java @@ -0,0 +1,24 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.exporter.prometheus; + +import java.util.function.Predicate; + +public final class Predicates { + + static final Predicate ALLOW_ALL = attributeKey -> true; + + private Predicates() {} + + @SuppressWarnings("SameParameterValue") + static Predicate startsWith(String prefix) { + return attributeKey -> attributeKey.startsWith(prefix); + } + + public static Predicate is(String value) { + return attributeKey -> attributeKey.equals(value); + } +} diff --git a/exporters/prometheus/src/test/java/io/opentelemetry/exporter/prometheus/PrometheusHttpServerTest.java b/exporters/prometheus/src/test/java/io/opentelemetry/exporter/prometheus/PrometheusHttpServerTest.java index d899dddd122..93842d78a26 100644 --- a/exporters/prometheus/src/test/java/io/opentelemetry/exporter/prometheus/PrometheusHttpServerTest.java +++ b/exporters/prometheus/src/test/java/io/opentelemetry/exporter/prometheus/PrometheusHttpServerTest.java @@ -94,6 +94,7 @@ static void tearDown() { prometheusServer.shutdown(); } + @SuppressWarnings("DataFlowIssue") @Test void invalidConfig() { assertThatThrownBy(() -> PrometheusHttpServer.builder().setPort(-1)) @@ -155,6 +156,7 @@ void fetchOpenMetrics() { + "# EOF\n"); } + @SuppressWarnings("ConcatenationWithEmptyString") @Test void fetchFiltered() { AggregatedHttpResponse response = @@ -175,6 +177,7 @@ void fetchFiltered() { + "target_info{kr=\"vr\"} 1\n"); } + @SuppressWarnings("resource") @Test void fetchPrometheusCompressed() throws IOException { WebClient client = @@ -201,6 +204,7 @@ void fetchPrometheusCompressed() throws IOException { + "target_info{kr=\"vr\"} 1\n"); } + @SuppressWarnings("resource") @Test void fetchHead() { AggregatedHttpResponse response = client.head("/").aggregate().join(); @@ -313,6 +317,49 @@ void customExecutor() throws IOException { } } + @Test + void addResourceAttributesWorks() { + WebClient testClient; + try (PrometheusHttpServer testPrometheusServer = + PrometheusHttpServer.builder() + .setHost("localhost") + .setPort(0) + .setAllowedResourceAttributesFilter(Predicates.ALLOW_ALL) + .build()) { + testPrometheusServer.register( + new CollectionRegistration() { + @Override + public Collection collectAllMetrics() { + return metricData.get(); + } + }); + + testClient = + WebClient.builder("http://localhost:" + testPrometheusServer.getAddress().getPort()) + .decorator(RetryingClient.newDecorator(RetryRule.failsafe())) + .build(); + + AggregatedHttpResponse response = testClient.get("/metrics").aggregate().join(); + assertThat(response.status()).isEqualTo(HttpStatus.OK); + assertThat(response.headers().get(HttpHeaderNames.CONTENT_TYPE)) + .isEqualTo("text/plain; version=0.0.4; charset=utf-8"); + assertThat(response.contentUtf8()) + .isEqualTo( + "# HELP grpc_name_unit_total long_description\n" + + "# TYPE grpc_name_unit_total counter\n" + + // Note the added resource attributes as labels + + "grpc_name_unit_total{kp=\"vp\",kr=\"vr\",otel_scope_name=\"grpc\",otel_scope_version=\"version\"} 5.0\n" + + "# HELP http_name_unit_total double_description\n" + + "# TYPE http_name_unit_total counter\n" + + // Note the added resource attributes as labels + + "http_name_unit_total{kp=\"vp\",kr=\"vr\",otel_scope_name=\"http\",otel_scope_version=\"version\"} 3.5\n" + + "# TYPE target_info gauge\n" + + "target_info{kr=\"vr\"} 1\n"); + } + } + private static List generateTestData() { return ImmutableList.of( ImmutableMetricData.createLongSum( diff --git a/exporters/prometheus/src/test/java/io/opentelemetry/exporter/prometheus/PrometheusMetricReaderTest.java b/exporters/prometheus/src/test/java/io/opentelemetry/exporter/prometheus/PrometheusMetricReaderTest.java index 95a22379ef9..1e978a60d43 100644 --- a/exporters/prometheus/src/test/java/io/opentelemetry/exporter/prometheus/PrometheusMetricReaderTest.java +++ b/exporters/prometheus/src/test/java/io/opentelemetry/exporter/prometheus/PrometheusMetricReaderTest.java @@ -45,6 +45,7 @@ import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; +@SuppressWarnings({"resource", "ConcatenationWithEmptyString"}) class PrometheusMetricReaderTest { private final TestClock testClock = TestClock.create(); @@ -53,11 +54,12 @@ class PrometheusMetricReaderTest { private Meter meter; private Tracer tracer; + @SuppressWarnings("resource") @BeforeEach void setUp() { this.testClock.setTime(Instant.ofEpochMilli((System.currentTimeMillis() / 100) * 100)); this.createdTimestamp = convertTimestamp(testClock.now()); - this.reader = new PrometheusMetricReader(true); + this.reader = new PrometheusMetricReader(true, /* allowedResourceAttributesFilter= */ null); this.meter = SdkMeterProvider.builder() .setClock(testClock) @@ -85,13 +87,13 @@ void longCounterComplete() throws IOException { .setUnit("By") .build(); Span span1 = tracer.spanBuilder("test").startSpan(); - try (Scope scope = span1.makeCurrent()) { + try (Scope ignored = span1.makeCurrent()) { counter.add(3, Attributes.builder().put("animal", "bear").build()); } finally { span1.end(); } Span span2 = tracer.spanBuilder("test").startSpan(); - try (Scope scope = span2.makeCurrent()) { + try (Scope ignored = span2.makeCurrent()) { counter.add(2, Attributes.builder().put("animal", "mouse").build()); } finally { span2.end(); @@ -109,13 +111,13 @@ void doubleCounterComplete() throws IOException { .ofDoubles() .build(); Span span1 = tracer.spanBuilder("test").startSpan(); - try (Scope scope = span1.makeCurrent()) { + try (Scope ignored = span1.makeCurrent()) { counter.add(3.0, Attributes.builder().put("animal", "bear").build()); } finally { span1.end(); } Span span2 = tracer.spanBuilder("test").startSpan(); - try (Scope scope = span2.makeCurrent()) { + try (Scope ignored = span2.makeCurrent()) { counter.add(2.0, Attributes.builder().put("animal", "mouse").build()); } finally { span2.end(); @@ -189,13 +191,13 @@ void longUpDownCounterComplete() throws IOException { .setUnit("By") .build(); Span span1 = tracer.spanBuilder("test").startSpan(); - try (Scope scope = span1.makeCurrent()) { + try (Scope ignored = span1.makeCurrent()) { counter.add(3, Attributes.builder().put("animal", "bear").build()); } finally { span1.end(); } Span span2 = tracer.spanBuilder("test").startSpan(); - try (Scope scope = span2.makeCurrent()) { + try (Scope ignored = span2.makeCurrent()) { counter.add(2, Attributes.builder().put("animal", "mouse").build()); } finally { span2.end(); @@ -213,13 +215,13 @@ void doubleUpDownCounterComplete() throws IOException { .ofDoubles() .build(); Span span1 = tracer.spanBuilder("test").startSpan(); - try (Scope scope = span1.makeCurrent()) { + try (Scope ignored = span1.makeCurrent()) { counter.add(3.0, Attributes.builder().put("animal", "bear").build()); } finally { span1.end(); } Span span2 = tracer.spanBuilder("test").startSpan(); - try (Scope scope = span2.makeCurrent()) { + try (Scope ignored = span2.makeCurrent()) { counter.add(2.0, Attributes.builder().put("animal", "mouse").build()); } finally { span2.end(); @@ -351,19 +353,19 @@ void longHistogramComplete() throws IOException { .ofLongs() .build(); Span span1 = tracer.spanBuilder("test").startSpan(); - try (Scope scope = span1.makeCurrent()) { + try (Scope ignored = span1.makeCurrent()) { histogram.record(173, Attributes.builder().put("animal", "bear").build()); } finally { span1.end(); } Span span2 = tracer.spanBuilder("test").startSpan(); - try (Scope scope = span2.makeCurrent()) { + try (Scope ignored = span2.makeCurrent()) { histogram.record(400, Attributes.builder().put("animal", "bear").build()); } finally { span1.end(); } Span span3 = tracer.spanBuilder("test").startSpan(); - try (Scope scope = span3.makeCurrent()) { + try (Scope ignored = span3.makeCurrent()) { histogram.record(204, Attributes.builder().put("animal", "mouse").build()); } finally { span3.end(); @@ -380,19 +382,19 @@ void doubleHistogramComplete() throws IOException { .setUnit("By") .build(); Span span1 = tracer.spanBuilder("test").startSpan(); - try (Scope scope = span1.makeCurrent()) { + try (Scope ignored = span1.makeCurrent()) { histogram.record(173.0, Attributes.builder().put("animal", "bear").build()); } finally { span1.end(); } Span span2 = tracer.spanBuilder("test").startSpan(); - try (Scope scope = span2.makeCurrent()) { + try (Scope ignored = span2.makeCurrent()) { histogram.record(400.0, Attributes.builder().put("animal", "bear").build()); } finally { span1.end(); } Span span3 = tracer.spanBuilder("test").startSpan(); - try (Scope scope = span3.makeCurrent()) { + try (Scope ignored = span3.makeCurrent()) { histogram.record(204.0, Attributes.builder().put("animal", "mouse").build()); } finally { span3.end(); @@ -518,7 +520,7 @@ private void assertHistogramMinimal(MetricSnapshots snapshots) throws IOExceptio @Test @Disabled("disabled until #6010 is fixed") - void exponentialLongHistogramComplete() throws IOException { + void exponentialLongHistogramComplete() { LongHistogram histogram = meter .histogramBuilder("my.exponential.histogram") @@ -527,14 +529,14 @@ void exponentialLongHistogramComplete() throws IOException { .ofLongs() .build(); Span span1 = tracer.spanBuilder("test").startSpan(); - try (Scope scope = span1.makeCurrent()) { + try (Scope ignored = span1.makeCurrent()) { histogram.record(7, Attributes.builder().put("animal", "bear").build()); } finally { span1.end(); } histogram.record(0, Attributes.builder().put("animal", "bear").build()); Span span2 = tracer.spanBuilder("test").startSpan(); - try (Scope scope = span2.makeCurrent()) { + try (Scope ignored = span2.makeCurrent()) { histogram.record(3, Attributes.builder().put("animal", "mouse").build()); } finally { span2.end(); @@ -543,7 +545,7 @@ void exponentialLongHistogramComplete() throws IOException { } @Test - void exponentialDoubleHistogramComplete() throws IOException { + void exponentialDoubleHistogramComplete() { DoubleHistogram histogram = meter .histogramBuilder("my.exponential.histogram") @@ -551,14 +553,14 @@ void exponentialDoubleHistogramComplete() throws IOException { .setUnit("By") .build(); Span span1 = tracer.spanBuilder("test").startSpan(); - try (Scope scope = span1.makeCurrent()) { + try (Scope ignored = span1.makeCurrent()) { histogram.record(7.0, Attributes.builder().put("animal", "bear").build()); } finally { span1.end(); } histogram.record(0.0, Attributes.builder().put("animal", "bear").build()); Span span2 = tracer.spanBuilder("test").startSpan(); - try (Scope scope = span2.makeCurrent()) { + try (Scope ignored = span2.makeCurrent()) { histogram.record(3.0, Attributes.builder().put("animal", "mouse").build()); } finally { span2.end(); @@ -690,14 +692,14 @@ private static void assertExponentialHistogramComplete( } @Test - void exponentialLongHistogramMinimal() throws IOException { + void exponentialLongHistogramMinimal() { LongHistogram histogram = meter.histogramBuilder("my.exponential.histogram").ofLongs().build(); histogram.record(1, Attributes.builder().put("animal", "bear").build()); assertExponentialHistogramMinimal(reader.collect()); } @Test - void exponentialDoubleHistogramMinimal() throws IOException { + void exponentialDoubleHistogramMinimal() { DoubleHistogram histogram = meter.histogramBuilder("my.exponential.histogram").build(); histogram.record(1.0, Attributes.builder().put("animal", "bear").build()); assertExponentialHistogramMinimal(reader.collect()); @@ -763,7 +765,8 @@ void exponentialHistogramBucketConversion() { for (int i = 0; i < 100_000; i++) { int otelScale = random.nextInt(24) - 4; int prometheusScale = Math.min(otelScale, 8); - PrometheusMetricReader reader = new PrometheusMetricReader(true); + PrometheusMetricReader reader = + new PrometheusMetricReader(true, /* allowedResourceAttributesFilter= */ null); Meter meter = SdkMeterProvider.builder() .registerMetricReader(reader) @@ -798,7 +801,7 @@ void exponentialHistogramBucketConversion() { } @Test - void exponentialLongHistogramScaleDown() throws IOException { + void exponentialLongHistogramScaleDown() { // The following histogram will have the default scale, which is 20. DoubleHistogram histogram = meter.histogramBuilder("my.exponential.histogram").build(); double base = Math.pow(2, Math.pow(2, -20)); @@ -1015,7 +1018,8 @@ void otelScopeComplete() throws IOException { @Test void otelScopeDisabled() throws IOException { - PrometheusMetricReader reader = new PrometheusMetricReader(false); + PrometheusMetricReader reader = + new PrometheusMetricReader(false, /* allowedResourceAttributesFilter= */ null); Meter meter = SdkMeterProvider.builder() .setClock(testClock) @@ -1041,6 +1045,42 @@ void otelScopeDisabled() throws IOException { assertThat(toOpenMetrics(reader.collect())).isEqualTo(expected); } + @SuppressWarnings("resource") + @Test + void addResourceAttributesWorks() throws IOException { + PrometheusMetricReader reader = + new PrometheusMetricReader( + true, /* allowedResourceAttributesFilter= */ Predicates.is("cluster")); + Meter meter = + SdkMeterProvider.builder() + .setClock(testClock) + .registerMetricReader(reader) + .setResource( + Resource.getDefault().toBuilder() + .put("cluster", "my.cluster") + .put("telemetry.sdk.version", "1.x.x") + .build()) + .build() + .meterBuilder("test-scope") + .setInstrumentationVersion("a.b.c") + .build(); + LongCounter counter = meter.counterBuilder("test.count").build(); + counter.add(1); + String expected = + "" + + "# TYPE target info\n" + + "target_info{cluster=\"my.cluster\",service_name=\"unknown_service:java\",telemetry_sdk_language=\"java\",telemetry_sdk_name=\"opentelemetry\",telemetry_sdk_version=\"1.x.x\"} 1\n" + + "# TYPE test_count counter\n" + + // In both those metrics we expect the "cluster" label to exist + + "test_count_total{cluster=\"my.cluster\",otel_scope_name=\"test-scope\",otel_scope_version=\"a.b.c\"} 1.0\n" + + "test_count_created{cluster=\"my.cluster\",otel_scope_name=\"test-scope\",otel_scope_version=\"a.b.c\"} " + + createdTimestamp + + "\n" + + "# EOF\n"; + assertThat(toOpenMetrics(reader.collect())).isEqualTo(expected); + } + /** * Unfortunately there is no easy way to use {@link TestClock} for Exemplar timestamps. Test if * {@code expected} equals {@code actual} but {@code } matches arbitrary timestamps. diff --git a/sdk-extensions/autoconfigure/README.md b/sdk-extensions/autoconfigure/README.md index a5ae3413f28..fdd3855b82d 100644 --- a/sdk-extensions/autoconfigure/README.md +++ b/sdk-extensions/autoconfigure/README.md @@ -329,11 +329,11 @@ The following exporters are only available for the metric signal. See [exporters The [Prometheus](https://github.com/prometheus/docs/blob/master/content/docs/instrumenting/exposition_formats.md) exporter. -| System property | Environment variable | Description | -|----------------------------------|----------------------------------|------------------------------------------------------------------------------------| -| otel.metrics.exporter=prometheus | OTEL_METRICS_EXPORTER=prometheus | Select the Prometheus exporter | -| otel.exporter.prometheus.port | OTEL_EXPORTER_PROMETHEUS_PORT | The local port used to bind the prometheus metric server. Default is `9464`. | -| otel.exporter.prometheus.host | OTEL_EXPORTER_PROMETHEUS_HOST | The local address used to bind the prometheus metric server. Default is `0.0.0.0`. | +| System property | Environment variable | Description | +|---------------------------------------------------------|---------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------| +| otel.metrics.exporter=prometheus | OTEL_METRICS_EXPORTER=prometheus | Select the Prometheus exporter | +| otel.exporter.prometheus.port | OTEL_EXPORTER_PROMETHEUS_PORT | The local port used to bind the prometheus metric server. Default is `9464`. | +| otel.exporter.prometheus.host | OTEL_EXPORTER_PROMETHEUS_HOST | The local address used to bind the prometheus metric server. Default is `0.0.0.0`. | Note that this is a pull exporter - it opens up a server on the local process listening on the specified host and port, which a Prometheus server scrapes from. From e9e1feeae0d9b7e04a02e316a9294d96cf250fe7 Mon Sep 17 00:00:00 2001 From: jack-berg <34418638+jack-berg@users.noreply.github.com> Date: Fri, 9 Feb 2024 07:59:03 -0600 Subject: [PATCH 247/901] Prepare 1.35.0 release (#6213) Co-authored-by: Trask Stalnaker --- CHANGELOG.md | 73 +++++++++++++++++++ .../zipkin/ZipkinSpanExporterBuilder.java | 2 + 2 files changed, 75 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3fece48b3b4..ab9d09b9394 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,79 @@ ## Unreleased +**NOTE:** The `opentelemetry-exporter-jaeger` and `opentelemetry-exporter-jaeger-thift` artifacts +have stopped being published. Jaeger +has [native support for OTLP](https://opentelemetry.io/blog/2022/jaeger-native-otlp/), and users +should export to jaeger +using [OTLP](https://opentelemetry.io/docs/instrumentation/java/exporters/#otlp-dependencies) +instead. + +### API + +#### Incubator + +* Add Span#addLink, for adding a link after span start + ([#6084](https://github.com/open-telemetry/opentelemetry-java/pull/6084)) + +### SDK + +#### Traces + +* Bugfix: Ensure span status cannot be updated after set to StatusCode.OK + ([#6209](https://github.com/open-telemetry/opentelemetry-java/pull/6209) + +#### Metrics + +* Reusable memory Mode: Adding support for exponential histogram aggregation + ([#6058](https://github.com/open-telemetry/opentelemetry-java/pull/6058), + [#6136](https://github.com/open-telemetry/opentelemetry-java/pull/6136)) +* Reusable memory mode: Adding support for explicit histogram aggregation + ([#6153](https://github.com/open-telemetry/opentelemetry-java/pull/6153)) +* Reusable memory mode: Adding support for sum aggregation + ([#6182](https://github.com/open-telemetry/opentelemetry-java/pull/6182)) +* Reusable memory mode: Adding support for last value aggregation + ([#6196](https://github.com/open-telemetry/opentelemetry-java/pull/6196)) + +#### Exporters + +* Recreate / fix graal issue detecting RetryPolicy class + ([#6139](https://github.com/open-telemetry/opentelemetry-java/pull/6139), + [#6134](https://github.com/open-telemetry/opentelemetry-java/pull/6134)) +* Restore prometheus metric name mapper tests, fix regressions + ([#6138](https://github.com/open-telemetry/opentelemetry-java/pull/6138)) +* WARNING: Remove jaeger exporters + ([#6119](https://github.com/open-telemetry/opentelemetry-java/pull/6119)) +* Update dependency `io.zipkin.reporter2:zipkin-reporter-bom` to 3.2.1. + Note: `ZipkinSpanExporterBuilder#setEncoder(zipkin2.codec.BytesEncoder)` has been deprecated in + favor of `ZipkinSpanExporterBuilder#setEncoder(zipkin2.reporter.BytesEncoder)`. + `ZipkinSpanExporterBuilder#setSender(zipkin2.reporter.Sender)` has been deprecated in favor + of `ZipkinSpanExporterBuilder#setSender(zipkin2.reporter.BytesMessageSender)`. + ([#6129](https://github.com/open-telemetry/opentelemetry-java/pull/6129), + [#6151](https://github.com/open-telemetry/opentelemetry-java/pull/6151)) +* Include trace flags in otlp marshaller + ([#6167](https://github.com/open-telemetry/opentelemetry-java/pull/6167)) +* Add Compressor SPI support to OtlpGrpc{Signal}Exporters + ([#6103](https://github.com/open-telemetry/opentelemetry-java/pull/6103)) +* Allow Prometheus exporter to add resource attributes to metric attributes + ([#6179](https://github.com/open-telemetry/opentelemetry-java/pull/6179)) + +#### Extension + +* Autoconfigure accepts encoded header values for OTLP exporters + ([#6164](https://github.com/open-telemetry/opentelemetry-java/pull/6164)) + +#### Incubator + +* Align file configuration with latest changes to spec + ([#6088](https://github.com/open-telemetry/opentelemetry-java/pull/6088)) + +### Tooling + +* Stop including old artifacts in bom + ([#6157](https://github.com/open-telemetry/opentelemetry-java/pull/6157)) +* Define CODECOV token + ([#6186](https://github.com/open-telemetry/opentelemetry-java/pull/6186)) + ## Version 1.34.1 (2024-01-11) * Fix prometheus exporter regressions diff --git a/exporters/zipkin/src/main/java/io/opentelemetry/exporter/zipkin/ZipkinSpanExporterBuilder.java b/exporters/zipkin/src/main/java/io/opentelemetry/exporter/zipkin/ZipkinSpanExporterBuilder.java index e73e4f73474..d13f1d4a825 100644 --- a/exporters/zipkin/src/main/java/io/opentelemetry/exporter/zipkin/ZipkinSpanExporterBuilder.java +++ b/exporters/zipkin/src/main/java/io/opentelemetry/exporter/zipkin/ZipkinSpanExporterBuilder.java @@ -57,6 +57,7 @@ public ZipkinSpanExporterBuilder setSender(zipkin2.reporter.Sender sender) { * * @param sender the Zipkin sender implementation. * @return this. + * @since 1.35.0 */ public ZipkinSpanExporterBuilder setSender(BytesMessageSender sender) { requireNonNull(sender, "sender"); @@ -86,6 +87,7 @@ public ZipkinSpanExporterBuilder setEncoder(zipkin2.codec.BytesEncoder enc * @param encoder the {@code BytesEncoder} to use. * @return this. * @see SpanBytesEncoder + * @since 1.35.0 */ public ZipkinSpanExporterBuilder setEncoder(BytesEncoder encoder) { requireNonNull(encoder, "encoder"); From 695ed5350b2ef218c38087a627549f4de7b86c22 Mon Sep 17 00:00:00 2001 From: OpenTelemetry Bot <107717825+opentelemetrybot@users.noreply.github.com> Date: Fri, 9 Feb 2024 16:56:03 +0100 Subject: [PATCH 248/901] Update version to 1.36.0 (#6216) --- CHANGELOG.md | 2 ++ version.gradle.kts | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ab9d09b9394..24107bd6685 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,8 @@ ## Unreleased +## Version 1.35.0 (2024-02-09) + **NOTE:** The `opentelemetry-exporter-jaeger` and `opentelemetry-exporter-jaeger-thift` artifacts have stopped being published. Jaeger has [native support for OTLP](https://opentelemetry.io/blog/2022/jaeger-native-otlp/), and users diff --git a/version.gradle.kts b/version.gradle.kts index 7201568cbc2..2626983ff72 100644 --- a/version.gradle.kts +++ b/version.gradle.kts @@ -1,7 +1,7 @@ val snapshot = true allprojects { - var ver = "1.35.0" + var ver = "1.36.0" val release = findProperty("otel.release") if (release != null) { ver += "-" + release From 0e84508905a9e84ff15fd98444483499c9953b2e Mon Sep 17 00:00:00 2001 From: Asaf Mesika Date: Mon, 12 Feb 2024 17:35:03 +0200 Subject: [PATCH 249/901] Fix flaky InstrumentGarbageCollectionBenchmarkTest (#6221) --- .github/workflows/build.yml | 3 ++ .../opentelemetry-exporter-zipkin.txt | 9 +----- ...trumentGarbageCollectionBenchmarkTest.java | 21 +++++++------ .../internal/state/TestInstrumentType.java | 31 ++++++++++++++++--- 4 files changed, 42 insertions(+), 22 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index df503314f90..ef324dfb6b1 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -32,6 +32,7 @@ jobs: - os: ubuntu-20.04 test-java-version: 17 coverage: true + jmh-based-tests: true steps: - uses: actions/checkout@v4 @@ -58,6 +59,8 @@ jobs: -Porg.gradle.java.installations.paths=${{ steps.setup-java-test.outputs.path }},${{ steps.setup-java.outputs.path }} env: GRADLE_ENTERPRISE_ACCESS_KEY: ${{ secrets.GRADLE_ENTERPRISE_ACCESS_KEY }} + # JMH-based tests run only if this environment variable is set to true + RUN_JMH_BASED_TESTS: ${{ matrix.jmh-based-tests }} - name: Check for diff # The jApiCmp diff compares current to latest, which isn't appropriate for release branches diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-zipkin.txt b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-zipkin.txt index b941adbcdd2..df26146497b 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-zipkin.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-zipkin.txt @@ -1,9 +1,2 @@ Comparing source compatibility of against -*** MODIFIED CLASS: PUBLIC FINAL io.opentelemetry.exporter.zipkin.ZipkinSpanExporterBuilder (not serializable) - === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 - === UNCHANGED METHOD: PUBLIC io.opentelemetry.exporter.zipkin.ZipkinSpanExporterBuilder setEncoder(zipkin2.codec.BytesEncoder) - +++ NEW ANNOTATION: java.lang.Deprecated - +++ NEW METHOD: PUBLIC(+) io.opentelemetry.exporter.zipkin.ZipkinSpanExporterBuilder setEncoder(zipkin2.reporter.BytesEncoder) - === UNCHANGED METHOD: PUBLIC io.opentelemetry.exporter.zipkin.ZipkinSpanExporterBuilder setSender(zipkin2.reporter.Sender) - +++ NEW ANNOTATION: java.lang.Deprecated - +++ NEW METHOD: PUBLIC(+) io.opentelemetry.exporter.zipkin.ZipkinSpanExporterBuilder setSender(zipkin2.reporter.BytesMessageSender) +No changes. \ No newline at end of file diff --git a/sdk/metrics/src/jmhBasedTest/java/io/opentelemetry/sdk/metrics/internal/state/InstrumentGarbageCollectionBenchmarkTest.java b/sdk/metrics/src/jmhBasedTest/java/io/opentelemetry/sdk/metrics/internal/state/InstrumentGarbageCollectionBenchmarkTest.java index 63de98ef5f3..6fba53e86cd 100644 --- a/sdk/metrics/src/jmhBasedTest/java/io/opentelemetry/sdk/metrics/internal/state/InstrumentGarbageCollectionBenchmarkTest.java +++ b/sdk/metrics/src/jmhBasedTest/java/io/opentelemetry/sdk/metrics/internal/state/InstrumentGarbageCollectionBenchmarkTest.java @@ -45,11 +45,12 @@ public class InstrumentGarbageCollectionBenchmarkTest { @SuppressWarnings("rawtypes") @Test public void normalizedAllocationRateTest() throws RunnerException { - // GitHub CI has an environment variable (CI=true). We can use it to skip - // this test since it's a lengthy one (roughly 10 seconds) and have it running - // only in GitHub CI + // OTel GitHub CI Workflow (see .github/) sets an environment variable + // (RUN_JMH_BASED_TESTS=true). + // We set it only there since it's a lengthy test (roughly 2.5min) + // and we want to run it only in CI. Assumptions.assumeTrue( - "true".equals(System.getenv("CI")), + "true".equals(System.getenv("RUN_JMH_BASED_TESTS")), "This test should only run in GitHub CI since it's long"); // Runs InstrumentGarbageCollectionBenchmark @@ -91,7 +92,7 @@ public void normalizedAllocationRateTest() throws RunnerException { } testInstrumentTypeResultsMap.forEach( - (testInstrumentType, testInstrumentTypeResults) -> { + (testInstrumentTypeString, testInstrumentTypeResults) -> { Map> resultMap = testInstrumentTypeResults.aggregationTemporalityToMemoryModeResult; assertThat(resultMap).hasSameSizeAs(AggregationTemporality.values()); @@ -108,9 +109,11 @@ public void normalizedAllocationRateTest() throws RunnerException { assertThat(immutableDataAllocRate).isNotNull().isNotZero(); assertThat(reusableDataAllocRate).isNotNull().isNotZero(); + TestInstrumentType testInstrumentType = + TestInstrumentType.valueOf(testInstrumentTypeString); float dataAllocRateReductionPercentage = - TestInstrumentType.valueOf(testInstrumentType) - .getDataAllocRateReductionPercentage(); + testInstrumentType.getDataAllocRateReductionPercentage(); + double allowedOffset = testInstrumentType.getAllowedPercentOffset(); // If this test suddenly fails for you this means you have changed the code in a way // that allocates more memory than before. You can find out where, by running @@ -119,8 +122,8 @@ public void normalizedAllocationRateTest() throws RunnerException { assertThat(100 - (reusableDataAllocRate / immutableDataAllocRate) * 100) .describedAs( "Aggregation temporality = %s, testInstrumentType = %s", - aggregationTemporality, testInstrumentType) - .isCloseTo(dataAllocRateReductionPercentage, Offset.offset(2.0)); + aggregationTemporality, testInstrumentTypeString) + .isCloseTo(dataAllocRateReductionPercentage, Offset.offset(allowedOffset)); }); }); } diff --git a/sdk/metrics/src/jmhBasedTest/java/io/opentelemetry/sdk/metrics/internal/state/TestInstrumentType.java b/sdk/metrics/src/jmhBasedTest/java/io/opentelemetry/sdk/metrics/internal/state/TestInstrumentType.java index 98cc39a6657..5a462fd94c8 100644 --- a/sdk/metrics/src/jmhBasedTest/java/io/opentelemetry/sdk/metrics/internal/state/TestInstrumentType.java +++ b/sdk/metrics/src/jmhBasedTest/java/io/opentelemetry/sdk/metrics/internal/state/TestInstrumentType.java @@ -24,31 +24,52 @@ public enum TestInstrumentType { ASYNC_COUNTER(AsyncCounterTester::new), EXPONENTIAL_HISTOGRAM(ExponentialHistogramTester::new), EXPLICIT_BUCKET(ExplicitBucketHistogramTester::new), - LONG_SUM(LongSumTester::new, /* dataAllocRateReductionPercentage= */ 97.3f), - DOUBLE_SUM(DoubleSumTester::new, /* dataAllocRateReductionPercentage= */ 97.3f), - LONG_LAST_VALUE(LongLastValueTester::new, /* dataAllocRateReductionPercentage= */ 97.3f), - DOUBLE_LAST_VALUE(DoubleLastValueTester::new, /* dataAllocRateReductionPercentage= */ 97.3f); + LONG_SUM( + LongSumTester::new, + /* dataAllocRateReductionPercentage= */ 97.3f, + /* allowedPercentOffset= */ 4.0f), + DOUBLE_SUM( + DoubleSumTester::new, + /* dataAllocRateReductionPercentage= */ 97.3f, + /* allowedPercentOffset= */ 2.0f), + LONG_LAST_VALUE( + LongLastValueTester::new, + /* dataAllocRateReductionPercentage= */ 97.3f, + /* allowedPercentOffset= */ 4.0f), + DOUBLE_LAST_VALUE( + DoubleLastValueTester::new, + /* dataAllocRateReductionPercentage= */ 97.3f, + /* allowedPercentOffset= */ 4.0f); private final Supplier instrumentTesterInitializer; private final float dataAllocRateReductionPercentage; + private final double allowedPercentOffset; + @SuppressWarnings("unused") TestInstrumentType(Supplier instrumentTesterInitializer) { this.dataAllocRateReductionPercentage = 99.8f; // default this.instrumentTesterInitializer = instrumentTesterInitializer; + this.allowedPercentOffset = 2.0f; } // Some instruments have different reduction percentage. TestInstrumentType( Supplier instrumentTesterInitializer, - float dataAllocRateReductionPercentage) { + float dataAllocRateReductionPercentage, + float allowedPercentOffset) { this.instrumentTesterInitializer = instrumentTesterInitializer; this.dataAllocRateReductionPercentage = dataAllocRateReductionPercentage; + this.allowedPercentOffset = allowedPercentOffset; } float getDataAllocRateReductionPercentage() { return dataAllocRateReductionPercentage; } + public double getAllowedPercentOffset() { + return allowedPercentOffset; + } + InstrumentTester createInstrumentTester() { return instrumentTesterInitializer.get(); } From 48d41d3a5aa27ff8e5e4033ef0c8c3ba0e53f683 Mon Sep 17 00:00:00 2001 From: jack-berg <34418638+jack-berg@users.noreply.github.com> Date: Mon, 12 Feb 2024 10:15:12 -0600 Subject: [PATCH 250/901] Update docs post 1.35.0 release (#6218) --- README.md | 72 +++++++++---------- .../1.35.0_vs_1.34.1/opentelemetry-api.txt | 2 + .../opentelemetry-context.txt | 2 + .../opentelemetry-exporter-common.txt | 2 + .../opentelemetry-exporter-logging-otlp.txt | 2 + .../opentelemetry-exporter-logging.txt | 2 + .../opentelemetry-exporter-otlp-common.txt | 2 + .../opentelemetry-exporter-otlp.txt | 2 + ...y-exporter-sender-grpc-managed-channel.txt | 2 + .../opentelemetry-exporter-sender-okhttp.txt | 2 + .../opentelemetry-exporter-zipkin.txt | 9 +++ .../opentelemetry-extension-kotlin.txt | 2 + ...ntelemetry-extension-trace-propagators.txt | 2 + .../opentelemetry-opentracing-shim.txt | 2 + .../opentelemetry-sdk-common.txt | 2 + ...emetry-sdk-extension-autoconfigure-spi.txt | 2 + ...ntelemetry-sdk-extension-autoconfigure.txt | 2 + ...ry-sdk-extension-jaeger-remote-sampler.txt | 2 + .../opentelemetry-sdk-logs.txt | 2 + .../opentelemetry-sdk-metrics.txt | 2 + .../opentelemetry-sdk-testing.txt | 2 + .../opentelemetry-sdk-trace.txt | 2 + .../1.35.0_vs_1.34.1/opentelemetry-sdk.txt | 2 + 23 files changed, 87 insertions(+), 36 deletions(-) create mode 100644 docs/apidiffs/1.35.0_vs_1.34.1/opentelemetry-api.txt create mode 100644 docs/apidiffs/1.35.0_vs_1.34.1/opentelemetry-context.txt create mode 100644 docs/apidiffs/1.35.0_vs_1.34.1/opentelemetry-exporter-common.txt create mode 100644 docs/apidiffs/1.35.0_vs_1.34.1/opentelemetry-exporter-logging-otlp.txt create mode 100644 docs/apidiffs/1.35.0_vs_1.34.1/opentelemetry-exporter-logging.txt create mode 100644 docs/apidiffs/1.35.0_vs_1.34.1/opentelemetry-exporter-otlp-common.txt create mode 100644 docs/apidiffs/1.35.0_vs_1.34.1/opentelemetry-exporter-otlp.txt create mode 100644 docs/apidiffs/1.35.0_vs_1.34.1/opentelemetry-exporter-sender-grpc-managed-channel.txt create mode 100644 docs/apidiffs/1.35.0_vs_1.34.1/opentelemetry-exporter-sender-okhttp.txt create mode 100644 docs/apidiffs/1.35.0_vs_1.34.1/opentelemetry-exporter-zipkin.txt create mode 100644 docs/apidiffs/1.35.0_vs_1.34.1/opentelemetry-extension-kotlin.txt create mode 100644 docs/apidiffs/1.35.0_vs_1.34.1/opentelemetry-extension-trace-propagators.txt create mode 100644 docs/apidiffs/1.35.0_vs_1.34.1/opentelemetry-opentracing-shim.txt create mode 100644 docs/apidiffs/1.35.0_vs_1.34.1/opentelemetry-sdk-common.txt create mode 100644 docs/apidiffs/1.35.0_vs_1.34.1/opentelemetry-sdk-extension-autoconfigure-spi.txt create mode 100644 docs/apidiffs/1.35.0_vs_1.34.1/opentelemetry-sdk-extension-autoconfigure.txt create mode 100644 docs/apidiffs/1.35.0_vs_1.34.1/opentelemetry-sdk-extension-jaeger-remote-sampler.txt create mode 100644 docs/apidiffs/1.35.0_vs_1.34.1/opentelemetry-sdk-logs.txt create mode 100644 docs/apidiffs/1.35.0_vs_1.34.1/opentelemetry-sdk-metrics.txt create mode 100644 docs/apidiffs/1.35.0_vs_1.34.1/opentelemetry-sdk-testing.txt create mode 100644 docs/apidiffs/1.35.0_vs_1.34.1/opentelemetry-sdk-trace.txt create mode 100644 docs/apidiffs/1.35.0_vs_1.34.1/opentelemetry-sdk.txt diff --git a/README.md b/README.md index 6ec11fd890b..219c9ebf905 100644 --- a/README.md +++ b/README.md @@ -102,7 +102,7 @@ dependency versions in sync. io.opentelemetry opentelemetry-bom - 1.34.1 + 1.35.0 pom import @@ -121,7 +121,7 @@ dependency versions in sync. ```groovy dependencies { - implementation platform("io.opentelemetry:opentelemetry-bom:1.34.1") + implementation platform("io.opentelemetry:opentelemetry-bom:1.35.0") implementation('io.opentelemetry:opentelemetry-api') } ``` @@ -130,8 +130,8 @@ Note that if you want to use any artifacts that have not fully stabilized yet (s ```groovy dependencies { - implementation platform("io.opentelemetry:opentelemetry-bom:1.34.1") - implementation platform('io.opentelemetry:opentelemetry-bom-alpha:1.34.1-alpha') + implementation platform("io.opentelemetry:opentelemetry-bom:1.35.0") + implementation platform('io.opentelemetry:opentelemetry-bom-alpha:1.35.0-alpha') implementation('io.opentelemetry:opentelemetry-api') implementation('io.opentelemetry:opentelemetry-exporter-prometheus') @@ -159,7 +159,7 @@ We strongly recommend using our published BOM to keep all dependency versions in io.opentelemetry opentelemetry-bom - 1.35.0-SNAPSHOT + 1.36.0-SNAPSHOT pom import @@ -182,7 +182,7 @@ repositories { } dependencies { - implementation platform("io.opentelemetry:opentelemetry-bom:1.35.0-SNAPSHOT") + implementation platform("io.opentelemetry:opentelemetry-bom:1.36.0-SNAPSHOT") implementation('io.opentelemetry:opentelemetry-api') } ``` @@ -227,67 +227,67 @@ dependency as follows, replacing `{{artifact-id}}` with the value from the "Arti | Component | Description | Artifact ID | Version | Javadoc | |----------------------------------------------|----------------------------------------|---------------------------|-------------------------------------------------------------|---------| -| [Bill of Materials (BOM)](./bom) | Bill of materials for stable artifacts | `opentelemetry-bom` | 1.34.1 | N/A | -| [Alpha Bill of Materials (BOM)](./bom-alpha) | Bill of materials for alpha artifacts | `opentelemetry-bom-alpha` | 1.34.1-alpha | N/A | +| [Bill of Materials (BOM)](./bom) | Bill of materials for stable artifacts | `opentelemetry-bom` | 1.35.0 | N/A | +| [Alpha Bill of Materials (BOM)](./bom-alpha) | Bill of materials for alpha artifacts | `opentelemetry-bom-alpha` | 1.35.0-alpha | N/A | ### API | Component | Description | Artifact ID | Version | Javadoc | |-----------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|----------------------------|-------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------| -| [API](./api/all) | OpenTelemetry API, including metrics, traces, baggage, context | `opentelemetry-api` | 1.34.1 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-api.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-api) | -| [Events API](./api/events) | OpenTelemetry Event API for emitting events. | `opentelemetry-api-events` | 1.34.1-alpha | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-api-events.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-api-events) | -| [Context API](./context) | OpenTelemetry context API | `opentelemetry-context` | 1.34.1 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-context.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-context) | +| [API](./api/all) | OpenTelemetry API, including metrics, traces, baggage, context | `opentelemetry-api` | 1.35.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-api.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-api) | +| [Events API](./api/events) | OpenTelemetry Event API for emitting events. | `opentelemetry-api-events` | 1.35.0-alpha | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-api-events.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-api-events) | +| [Context API](./context) | OpenTelemetry context API | `opentelemetry-context` | 1.35.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-context.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-context) | ### API Extensions | Component | Description | Artifact ID | Version | Javadoc | |---------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|---------------------------------------------|-------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| [Kotlin Extension](./extensions/kotlin) | Context extension for coroutines | `opentelemetry-extension-kotlin` | 1.34.1 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-extension-kotlin.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-extension-kotlin) | -| [Trace Propagators Extension](./extensions/trace-propagators) | Trace propagators, including B3, Jaeger, OT Trace | `opentelemetry-extension-trace-propagators` | 1.34.1 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-extension-trace-propagators.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-extension-trace-propagators) | -| [Incubator Extension](./extensions/incubator) | API incubator, including pass through propagator, and extended tracer | `opentelemetry-extension-incubator` | 1.34.1-alpha | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-extension-incubator.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-extension-incubator) | +| [Kotlin Extension](./extensions/kotlin) | Context extension for coroutines | `opentelemetry-extension-kotlin` | 1.35.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-extension-kotlin.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-extension-kotlin) | +| [Trace Propagators Extension](./extensions/trace-propagators) | Trace propagators, including B3, Jaeger, OT Trace | `opentelemetry-extension-trace-propagators` | 1.35.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-extension-trace-propagators.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-extension-trace-propagators) | +| [Incubator Extension](./extensions/incubator) | API incubator, including pass through propagator, and extended tracer | `opentelemetry-extension-incubator` | 1.35.0-alpha | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-extension-incubator.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-extension-incubator) | ### SDK | Component | Description | Artifact ID | Version | Javadoc | |------------------------------|--------------------------------------------------------|-----------------------------|---------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| [SDK](./sdk/all) | OpenTelemetry SDK, including metrics, traces, and logs | `opentelemetry-sdk` | 1.34.1 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk) | -| [Metrics SDK](./sdk/metrics) | OpenTelemetry metrics SDK | `opentelemetry-sdk-metrics` | 1.34.1 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-metrics.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-metrics) | -| [Trace SDK](./sdk/trace) | OpenTelemetry trace SDK | `opentelemetry-sdk-trace` | 1.34.1 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-trace.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-trace) | -| [Log SDK](./sdk/logs) | OpenTelemetry log SDK | `opentelemetry-sdk-logs` | 1.34.1 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-logs.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-logs) | -| [SDK Common](./sdk/common) | Shared SDK components | `opentelemetry-sdk-common` | 1.34.1 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-common.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-common) | -| [SDK Testing](./sdk/testing) | Components for testing OpenTelemetry instrumentation | `opentelemetry-sdk-testing` | 1.34.1 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-testing.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-testing) | +| [SDK](./sdk/all) | OpenTelemetry SDK, including metrics, traces, and logs | `opentelemetry-sdk` | 1.35.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk) | +| [Metrics SDK](./sdk/metrics) | OpenTelemetry metrics SDK | `opentelemetry-sdk-metrics` | 1.35.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-metrics.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-metrics) | +| [Trace SDK](./sdk/trace) | OpenTelemetry trace SDK | `opentelemetry-sdk-trace` | 1.35.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-trace.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-trace) | +| [Log SDK](./sdk/logs) | OpenTelemetry log SDK | `opentelemetry-sdk-logs` | 1.35.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-logs.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-logs) | +| [SDK Common](./sdk/common) | Shared SDK components | `opentelemetry-sdk-common` | 1.35.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-common.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-common) | +| [SDK Testing](./sdk/testing) | Components for testing OpenTelemetry instrumentation | `opentelemetry-sdk-testing` | 1.35.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-testing.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-testing) | ### SDK Exporters | Component | Description | Artifact ID | Version | Javadoc | |-----------------------------------------------------------------------|------------------------------------------------------------------------------|------------------------------------------------------|-------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| [OTLP Exporters](./exporters/otlp/all) | OTLP gRPC & HTTP exporters, including traces, metrics, and logs | `opentelemetry-exporter-otlp` | 1.34.1 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-otlp.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-otlp) | -| [OTLP Logging Exporters](./exporters/logging-otlp) | Logging exporters in OTLP JSON encoding, including traces, metrics, and logs | `opentelemetry-exporter-logging-otlp` | 1.34.1 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-logging-otlp.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-logging-otlp) | -| [OTLP Common](./exporters/otlp/common) | Shared OTLP components (internal) | `opentelemetry-exporter-otlp-common` | 1.34.1 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-otlp-common.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-otlp-common) | -| [Logging Exporter](./exporters/logging) | Logging exporters, including metrics, traces, and logs | `opentelemetry-exporter-logging` | 1.34.1 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-logging.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-logging) | -| [Zipkin Exporter](./exporters/zipkin) | Zipkin trace exporter | `opentelemetry-exporter-zipkin` | 1.34.1 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-zipkin.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-zipkin) | -| [Prometheus Exporter](./exporters/prometheus) | Prometheus metric exporter | `opentelemetry-exporter-prometheus` | 1.34.1-alpha | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-prometheus.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-prometheus) | -| [Exporter Common](./exporters/common) | Shared exporter components (internal) | `opentelemetry-exporter-common` | 1.34.1 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-common.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-common) | -| [OkHttp Sender](./exporters/sender/okhttp) | OkHttp implementation of HttpSender (internal) | `opentelemetry-exporter-sender-okhttp` | 1.34.1 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-sender-okhttp.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-sender-okhttp) | -| [JDK Sender](./exporters/sender/okhttp) | Java 11+ native HttpClient implementation of HttpSender (internal) | `opentelemetry-exporter-sender-jdk` | 1.34.1-alpha | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-sender-jdk.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-sender-jdk) | | -| [gRPC ManagedChannel Sender](./exporters/sender/grpc-managed-channel) | gRPC ManagedChannel implementation of GrpcSender (internal) | `opentelemetry-exporter-sender-grpc-managed-channel` | 1.34.1 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-sender-grpc-managed-channel.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-sender-grpc-managed-channel) | | +| [OTLP Exporters](./exporters/otlp/all) | OTLP gRPC & HTTP exporters, including traces, metrics, and logs | `opentelemetry-exporter-otlp` | 1.35.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-otlp.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-otlp) | +| [OTLP Logging Exporters](./exporters/logging-otlp) | Logging exporters in OTLP JSON encoding, including traces, metrics, and logs | `opentelemetry-exporter-logging-otlp` | 1.35.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-logging-otlp.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-logging-otlp) | +| [OTLP Common](./exporters/otlp/common) | Shared OTLP components (internal) | `opentelemetry-exporter-otlp-common` | 1.35.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-otlp-common.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-otlp-common) | +| [Logging Exporter](./exporters/logging) | Logging exporters, including metrics, traces, and logs | `opentelemetry-exporter-logging` | 1.35.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-logging.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-logging) | +| [Zipkin Exporter](./exporters/zipkin) | Zipkin trace exporter | `opentelemetry-exporter-zipkin` | 1.35.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-zipkin.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-zipkin) | +| [Prometheus Exporter](./exporters/prometheus) | Prometheus metric exporter | `opentelemetry-exporter-prometheus` | 1.35.0-alpha | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-prometheus.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-prometheus) | +| [Exporter Common](./exporters/common) | Shared exporter components (internal) | `opentelemetry-exporter-common` | 1.35.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-common.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-common) | +| [OkHttp Sender](./exporters/sender/okhttp) | OkHttp implementation of HttpSender (internal) | `opentelemetry-exporter-sender-okhttp` | 1.35.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-sender-okhttp.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-sender-okhttp) | +| [JDK Sender](./exporters/sender/okhttp) | Java 11+ native HttpClient implementation of HttpSender (internal) | `opentelemetry-exporter-sender-jdk` | 1.35.0-alpha | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-sender-jdk.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-sender-jdk) | | +| [gRPC ManagedChannel Sender](./exporters/sender/grpc-managed-channel) | gRPC ManagedChannel implementation of GrpcSender (internal) | `opentelemetry-exporter-sender-grpc-managed-channel` | 1.35.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-sender-grpc-managed-channel.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-sender-grpc-managed-channel) | | ### SDK Extensions | Component | Description | Artifact ID | Version | Javadoc | |-------------------------------------------------------------------------------|------------------------------------------------------------------------------------|-----------------------------------------------------|-------------------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| [SDK Autoconfigure](./sdk-extensions/autoconfigure) | Autoconfigure OpenTelemetry SDK from env vars, system properties, and SPI | `opentelemetry-sdk-extension-autoconfigure` | 1.34.1 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-extension-autoconfigure.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-extension-autoconfigure) | -| [SDK Autoconfigure SPI](./sdk-extensions/autoconfigure-spi) | Service Provider Interface (SPI) definitions for autoconfigure | `opentelemetry-sdk-extension-autoconfigure-spi` | 1.34.1 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-extension-autoconfigure-spi.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-extension-autoconfigure-spi) | -| [SDK Jaeger Remote Sampler Extension](./sdk-extensions/jaeger-remote-sampler) | Sampler which obtains sampling configuration from remote Jaeger server | `opentelemetry-sdk-extension-jaeger-remote-sampler` | 1.34.1 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-extension-jaeger-remote-sampler.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-extension-jaeger-remote-sampler) | -| [SDK Incubator](./sdk-extensions/incubator) | SDK incubator, including YAML based view configuration, LeakDetectingSpanProcessor | `opentelemetry-sdk-extension-incubator` | 1.34.1-alpha | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-extension-incubator.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-extension-incubator) | +| [SDK Autoconfigure](./sdk-extensions/autoconfigure) | Autoconfigure OpenTelemetry SDK from env vars, system properties, and SPI | `opentelemetry-sdk-extension-autoconfigure` | 1.35.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-extension-autoconfigure.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-extension-autoconfigure) | +| [SDK Autoconfigure SPI](./sdk-extensions/autoconfigure-spi) | Service Provider Interface (SPI) definitions for autoconfigure | `opentelemetry-sdk-extension-autoconfigure-spi` | 1.35.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-extension-autoconfigure-spi.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-extension-autoconfigure-spi) | +| [SDK Jaeger Remote Sampler Extension](./sdk-extensions/jaeger-remote-sampler) | Sampler which obtains sampling configuration from remote Jaeger server | `opentelemetry-sdk-extension-jaeger-remote-sampler` | 1.35.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-extension-jaeger-remote-sampler.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-extension-jaeger-remote-sampler) | +| [SDK Incubator](./sdk-extensions/incubator) | SDK incubator, including YAML based view configuration, LeakDetectingSpanProcessor | `opentelemetry-sdk-extension-incubator` | 1.35.0-alpha | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-extension-incubator.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-extension-incubator) | ### Shims | Component | Description | Artifact ID | Version | Javadoc | |----------------------------------------|--------------------------------------------------------------|----------------------------------|-------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| [OpenCensus Shim](./opencensus-shim) | Bridge opencensus metrics into the OpenTelemetry metrics SDK | `opentelemetry-opencensus-shim` | 1.34.1-alpha | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-opencensus-shim.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-opencensus-shim) | -| [OpenTracing Shim](./opentracing-shim) | Bridge opentracing spans into the OpenTelemetry trace API | `opentelemetry-opentracing-shim` | 1.34.1 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-opentracing-shim.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-opentracing-shim) | +| [OpenCensus Shim](./opencensus-shim) | Bridge opencensus metrics into the OpenTelemetry metrics SDK | `opentelemetry-opencensus-shim` | 1.35.0-alpha | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-opencensus-shim.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-opencensus-shim) | +| [OpenTracing Shim](./opentracing-shim) | Bridge opentracing spans into the OpenTelemetry trace API | `opentelemetry-opentracing-shim` | 1.35.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-opentracing-shim.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-opentracing-shim) | ## Contributing diff --git a/docs/apidiffs/1.35.0_vs_1.34.1/opentelemetry-api.txt b/docs/apidiffs/1.35.0_vs_1.34.1/opentelemetry-api.txt new file mode 100644 index 00000000000..df26146497b --- /dev/null +++ b/docs/apidiffs/1.35.0_vs_1.34.1/opentelemetry-api.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of against +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.35.0_vs_1.34.1/opentelemetry-context.txt b/docs/apidiffs/1.35.0_vs_1.34.1/opentelemetry-context.txt new file mode 100644 index 00000000000..df26146497b --- /dev/null +++ b/docs/apidiffs/1.35.0_vs_1.34.1/opentelemetry-context.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of against +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.35.0_vs_1.34.1/opentelemetry-exporter-common.txt b/docs/apidiffs/1.35.0_vs_1.34.1/opentelemetry-exporter-common.txt new file mode 100644 index 00000000000..df26146497b --- /dev/null +++ b/docs/apidiffs/1.35.0_vs_1.34.1/opentelemetry-exporter-common.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of against +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.35.0_vs_1.34.1/opentelemetry-exporter-logging-otlp.txt b/docs/apidiffs/1.35.0_vs_1.34.1/opentelemetry-exporter-logging-otlp.txt new file mode 100644 index 00000000000..df26146497b --- /dev/null +++ b/docs/apidiffs/1.35.0_vs_1.34.1/opentelemetry-exporter-logging-otlp.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of against +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.35.0_vs_1.34.1/opentelemetry-exporter-logging.txt b/docs/apidiffs/1.35.0_vs_1.34.1/opentelemetry-exporter-logging.txt new file mode 100644 index 00000000000..df26146497b --- /dev/null +++ b/docs/apidiffs/1.35.0_vs_1.34.1/opentelemetry-exporter-logging.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of against +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.35.0_vs_1.34.1/opentelemetry-exporter-otlp-common.txt b/docs/apidiffs/1.35.0_vs_1.34.1/opentelemetry-exporter-otlp-common.txt new file mode 100644 index 00000000000..df26146497b --- /dev/null +++ b/docs/apidiffs/1.35.0_vs_1.34.1/opentelemetry-exporter-otlp-common.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of against +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.35.0_vs_1.34.1/opentelemetry-exporter-otlp.txt b/docs/apidiffs/1.35.0_vs_1.34.1/opentelemetry-exporter-otlp.txt new file mode 100644 index 00000000000..df26146497b --- /dev/null +++ b/docs/apidiffs/1.35.0_vs_1.34.1/opentelemetry-exporter-otlp.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of against +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.35.0_vs_1.34.1/opentelemetry-exporter-sender-grpc-managed-channel.txt b/docs/apidiffs/1.35.0_vs_1.34.1/opentelemetry-exporter-sender-grpc-managed-channel.txt new file mode 100644 index 00000000000..df26146497b --- /dev/null +++ b/docs/apidiffs/1.35.0_vs_1.34.1/opentelemetry-exporter-sender-grpc-managed-channel.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of against +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.35.0_vs_1.34.1/opentelemetry-exporter-sender-okhttp.txt b/docs/apidiffs/1.35.0_vs_1.34.1/opentelemetry-exporter-sender-okhttp.txt new file mode 100644 index 00000000000..df26146497b --- /dev/null +++ b/docs/apidiffs/1.35.0_vs_1.34.1/opentelemetry-exporter-sender-okhttp.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of against +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.35.0_vs_1.34.1/opentelemetry-exporter-zipkin.txt b/docs/apidiffs/1.35.0_vs_1.34.1/opentelemetry-exporter-zipkin.txt new file mode 100644 index 00000000000..479860c48b0 --- /dev/null +++ b/docs/apidiffs/1.35.0_vs_1.34.1/opentelemetry-exporter-zipkin.txt @@ -0,0 +1,9 @@ +Comparing source compatibility of against +*** MODIFIED CLASS: PUBLIC FINAL io.opentelemetry.exporter.zipkin.ZipkinSpanExporterBuilder (not serializable) + === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 + === UNCHANGED METHOD: PUBLIC io.opentelemetry.exporter.zipkin.ZipkinSpanExporterBuilder setEncoder(zipkin2.codec.BytesEncoder) + +++ NEW ANNOTATION: java.lang.Deprecated + +++ NEW METHOD: PUBLIC(+) io.opentelemetry.exporter.zipkin.ZipkinSpanExporterBuilder setEncoder(zipkin2.reporter.BytesEncoder) + === UNCHANGED METHOD: PUBLIC io.opentelemetry.exporter.zipkin.ZipkinSpanExporterBuilder setSender(zipkin2.reporter.Sender) + +++ NEW ANNOTATION: java.lang.Deprecated + +++ NEW METHOD: PUBLIC(+) io.opentelemetry.exporter.zipkin.ZipkinSpanExporterBuilder setSender(zipkin2.reporter.BytesMessageSender) diff --git a/docs/apidiffs/1.35.0_vs_1.34.1/opentelemetry-extension-kotlin.txt b/docs/apidiffs/1.35.0_vs_1.34.1/opentelemetry-extension-kotlin.txt new file mode 100644 index 00000000000..df26146497b --- /dev/null +++ b/docs/apidiffs/1.35.0_vs_1.34.1/opentelemetry-extension-kotlin.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of against +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.35.0_vs_1.34.1/opentelemetry-extension-trace-propagators.txt b/docs/apidiffs/1.35.0_vs_1.34.1/opentelemetry-extension-trace-propagators.txt new file mode 100644 index 00000000000..df26146497b --- /dev/null +++ b/docs/apidiffs/1.35.0_vs_1.34.1/opentelemetry-extension-trace-propagators.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of against +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.35.0_vs_1.34.1/opentelemetry-opentracing-shim.txt b/docs/apidiffs/1.35.0_vs_1.34.1/opentelemetry-opentracing-shim.txt new file mode 100644 index 00000000000..df26146497b --- /dev/null +++ b/docs/apidiffs/1.35.0_vs_1.34.1/opentelemetry-opentracing-shim.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of against +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.35.0_vs_1.34.1/opentelemetry-sdk-common.txt b/docs/apidiffs/1.35.0_vs_1.34.1/opentelemetry-sdk-common.txt new file mode 100644 index 00000000000..df26146497b --- /dev/null +++ b/docs/apidiffs/1.35.0_vs_1.34.1/opentelemetry-sdk-common.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of against +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.35.0_vs_1.34.1/opentelemetry-sdk-extension-autoconfigure-spi.txt b/docs/apidiffs/1.35.0_vs_1.34.1/opentelemetry-sdk-extension-autoconfigure-spi.txt new file mode 100644 index 00000000000..df26146497b --- /dev/null +++ b/docs/apidiffs/1.35.0_vs_1.34.1/opentelemetry-sdk-extension-autoconfigure-spi.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of against +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.35.0_vs_1.34.1/opentelemetry-sdk-extension-autoconfigure.txt b/docs/apidiffs/1.35.0_vs_1.34.1/opentelemetry-sdk-extension-autoconfigure.txt new file mode 100644 index 00000000000..df26146497b --- /dev/null +++ b/docs/apidiffs/1.35.0_vs_1.34.1/opentelemetry-sdk-extension-autoconfigure.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of against +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.35.0_vs_1.34.1/opentelemetry-sdk-extension-jaeger-remote-sampler.txt b/docs/apidiffs/1.35.0_vs_1.34.1/opentelemetry-sdk-extension-jaeger-remote-sampler.txt new file mode 100644 index 00000000000..df26146497b --- /dev/null +++ b/docs/apidiffs/1.35.0_vs_1.34.1/opentelemetry-sdk-extension-jaeger-remote-sampler.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of against +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.35.0_vs_1.34.1/opentelemetry-sdk-logs.txt b/docs/apidiffs/1.35.0_vs_1.34.1/opentelemetry-sdk-logs.txt new file mode 100644 index 00000000000..df26146497b --- /dev/null +++ b/docs/apidiffs/1.35.0_vs_1.34.1/opentelemetry-sdk-logs.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of against +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.35.0_vs_1.34.1/opentelemetry-sdk-metrics.txt b/docs/apidiffs/1.35.0_vs_1.34.1/opentelemetry-sdk-metrics.txt new file mode 100644 index 00000000000..df26146497b --- /dev/null +++ b/docs/apidiffs/1.35.0_vs_1.34.1/opentelemetry-sdk-metrics.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of against +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.35.0_vs_1.34.1/opentelemetry-sdk-testing.txt b/docs/apidiffs/1.35.0_vs_1.34.1/opentelemetry-sdk-testing.txt new file mode 100644 index 00000000000..df26146497b --- /dev/null +++ b/docs/apidiffs/1.35.0_vs_1.34.1/opentelemetry-sdk-testing.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of against +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.35.0_vs_1.34.1/opentelemetry-sdk-trace.txt b/docs/apidiffs/1.35.0_vs_1.34.1/opentelemetry-sdk-trace.txt new file mode 100644 index 00000000000..df26146497b --- /dev/null +++ b/docs/apidiffs/1.35.0_vs_1.34.1/opentelemetry-sdk-trace.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of against +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.35.0_vs_1.34.1/opentelemetry-sdk.txt b/docs/apidiffs/1.35.0_vs_1.34.1/opentelemetry-sdk.txt new file mode 100644 index 00000000000..df26146497b --- /dev/null +++ b/docs/apidiffs/1.35.0_vs_1.34.1/opentelemetry-sdk.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of against +No changes. \ No newline at end of file From a903fa849f242eb708c77e443f2b92f61db3c268 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 17 Feb 2024 09:18:06 -0600 Subject: [PATCH 251/901] Update errorProneVersion to v2.25.0 (#6236) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- dependencyManagement/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index 245817a5ab7..f4e2ed13554 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -25,7 +25,7 @@ val DEPENDENCY_BOMS = listOf( ) val autoValueVersion = "1.10.4" -val errorProneVersion = "2.24.1" +val errorProneVersion = "2.25.0" val jmhVersion = "1.37" // Mockito 5.x.x requires Java 11 https://github.com/mockito/mockito/releases/tag/v5.0.0 val mockitoVersion = "4.11.0" From 82e4354be94775f6baccc2dfbf31036b119706c6 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 17 Feb 2024 09:18:22 -0600 Subject: [PATCH 252/901] Update dependency com.google.protobuf:protobuf-bom to v3.25.3 (#6234) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- dependencyManagement/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index f4e2ed13554..f590684e340 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -10,7 +10,7 @@ rootProject.extra["versions"] = dependencyVersions val DEPENDENCY_BOMS = listOf( "com.fasterxml.jackson:jackson-bom:2.16.1", "com.google.guava:guava-bom:33.0.0-jre", - "com.google.protobuf:protobuf-bom:3.25.2", + "com.google.protobuf:protobuf-bom:3.25.3", "com.linecorp.armeria:armeria-bom:1.27.1", "com.squareup.okhttp3:okhttp-bom:4.12.0", "com.squareup.okio:okio-bom:3.7.0", // applies to transitive dependencies of okhttp From 620a26485968009c15b6ba8e4b58220c20cd4d18 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 17 Feb 2024 09:18:40 -0600 Subject: [PATCH 253/901] Update dependency com.uber.nullaway:nullaway to v0.10.23 (#6232) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- dependencyManagement/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index f590684e340..204f8f3cb1d 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -60,7 +60,7 @@ val DEPENDENCIES = listOf( "com.google.guava:guava-beta-checker:1.0", "com.sun.net.httpserver:http:20070405", "com.tngtech.archunit:archunit-junit5:1.2.1", - "com.uber.nullaway:nullaway:0.10.22", + "com.uber.nullaway:nullaway:0.10.23", "edu.berkeley.cs.jqf:jqf-fuzz:1.7", // jqf-fuzz version 1.8+ requires Java 11+ "eu.rekawek.toxiproxy:toxiproxy-java:2.1.7", "io.github.netmikey.logunit:logunit-jul:2.0.0", From f2b92832eb9a5159168b3ef307682c122cfc39b2 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 17 Feb 2024 09:19:02 -0600 Subject: [PATCH 254/901] Update dependency com.google.api.grpc:proto-google-common-protos to v2.34.0 (#6229) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- dependencyManagement/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index 204f8f3cb1d..ac5758d0983 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -55,7 +55,7 @@ val DEPENDENCIES = listOf( "io.prometheus:simpleclient_httpserver:${prometheusClientVersion}", "javax.annotation:javax.annotation-api:1.3.2", "com.github.stefanbirkner:system-rules:1.19.0", - "com.google.api.grpc:proto-google-common-protos:2.33.0", + "com.google.api.grpc:proto-google-common-protos:2.34.0", "com.google.code.findbugs:jsr305:3.0.2", "com.google.guava:guava-beta-checker:1.0", "com.sun.net.httpserver:http:20070405", From 11391d8b1ad9d936148d8ffb592a9d8eb4698b45 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 17 Feb 2024 09:20:39 -0600 Subject: [PATCH 255/901] Update dependency com.squareup.wire:wire-bom to v4.9.7 (#6223) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- buildSrc/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts index 8674e542401..31f4cbccf92 100644 --- a/buildSrc/build.gradle.kts +++ b/buildSrc/build.gradle.kts @@ -42,7 +42,7 @@ repositories { } dependencies { - implementation(enforcedPlatform("com.squareup.wire:wire-bom:4.9.6")) + implementation(enforcedPlatform("com.squareup.wire:wire-bom:4.9.7")) implementation("com.google.auto.value:auto-value-annotations:1.10.4") // When updating, update above in plugins too implementation("com.diffplug.spotless:spotless-plugin-gradle:6.25.0") From 046baf9ca94924e5c6c3a47e7437675a49d7a82f Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 17 Feb 2024 09:20:56 -0600 Subject: [PATCH 256/901] Update dependency com.squareup.okio:okio-bom to v3.8.0 (#6219) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- dependencyManagement/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index ac5758d0983..d2077c0ecde 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -13,7 +13,7 @@ val DEPENDENCY_BOMS = listOf( "com.google.protobuf:protobuf-bom:3.25.3", "com.linecorp.armeria:armeria-bom:1.27.1", "com.squareup.okhttp3:okhttp-bom:4.12.0", - "com.squareup.okio:okio-bom:3.7.0", // applies to transitive dependencies of okhttp + "com.squareup.okio:okio-bom:3.8.0", // applies to transitive dependencies of okhttp "io.grpc:grpc-bom:1.61.1", "io.netty:netty-bom:4.1.106.Final", "io.zipkin.brave:brave-bom:6.0.0", From b0ec50575e4c42edafcd4295635afb01c9622563 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 17 Feb 2024 09:21:08 -0600 Subject: [PATCH 257/901] Update gradle/wrapper-validation-action action to v2.1.1 (#6220) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/gradle-wrapper-validation.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/gradle-wrapper-validation.yml b/.github/workflows/gradle-wrapper-validation.yml index 81d19137a52..d4aee174fab 100644 --- a/.github/workflows/gradle-wrapper-validation.yml +++ b/.github/workflows/gradle-wrapper-validation.yml @@ -13,4 +13,4 @@ jobs: steps: - uses: actions/checkout@v4 - - uses: gradle/wrapper-validation-action@v2.1.0 + - uses: gradle/wrapper-validation-action@v2.1.1 From 47a390076f3de4325c48459fcc4d9da7ee8dde71 Mon Sep 17 00:00:00 2001 From: jack-berg <34418638+jack-berg@users.noreply.github.com> Date: Sat, 17 Feb 2024 09:33:48 -0600 Subject: [PATCH 258/901] Fix omission in readme overview (#6120) --- README.md | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 219c9ebf905..1f1c18332ce 100644 --- a/README.md +++ b/README.md @@ -46,10 +46,12 @@ OpenTelemetry is the merging of OpenCensus and OpenTracing into a single project This project contains the following top level components: * [OpenTelemetry API](api/): - * [stable apis](api/all/src/main/java/io/opentelemetry/api/) including `Tracer`, `Span`, `SpanContext`, `Meter`, and `Baggage` - * [context api](context/src/main/java/io/opentelemetry/context/) The OpenTelemetry Context implementation. -* [extensions](extensions/) define additional API extensions, which are not part of the core API. + * [stable apis](api/all) including `Tracer`, `Span`, `SpanContext`, `Meter`, and `Baggage`. + * [context api](context/) The OpenTelemetry Context implementation. + * [experimental apis](api/events) including `Events`. +* [extensions](extensions/) define additional API extensions not part of the core API, including propagators and experimental extension APIs. * [sdk](sdk/) defines the implementation of the OpenTelemetry API. +* [exporters](exporters/) trace, metric, and log exporters for the SDK. * [sdk-extensions](sdk-extensions/) defines additional SDK extensions, which are not part of the core SDK. * [OpenTracing shim](opentracing-shim/) defines a bridge layer from OpenTracing to the OpenTelemetry API. * [OpenCensus shim](opencensus-shim/) defines a bridge layer from OpenCensus to the OpenTelemetry API. From 2dfbc242f7b9f066a224f8a60ed82d18b55476c7 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 17 Feb 2024 09:43:40 -0600 Subject: [PATCH 259/901] Update gradle/gradle-build-action action to v3 (#6238) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/benchmark-tags.yml | 2 +- .github/workflows/benchmark.yml | 2 +- .github/workflows/build.yml | 4 ++-- .github/workflows/codeql-daily.yml | 2 +- .github/workflows/owasp-dependency-check-daily.yml | 2 +- .github/workflows/release.yml | 2 +- 6 files changed, 7 insertions(+), 7 deletions(-) diff --git a/.github/workflows/benchmark-tags.yml b/.github/workflows/benchmark-tags.yml index d10653a48a6..f1b91acf252 100644 --- a/.github/workflows/benchmark-tags.yml +++ b/.github/workflows/benchmark-tags.yml @@ -50,7 +50,7 @@ jobs: distribution: temurin java-version: 17 - - uses: gradle/gradle-build-action@v2 + - uses: gradle/gradle-build-action@v3 with: arguments: | jmhJar diff --git a/.github/workflows/benchmark.yml b/.github/workflows/benchmark.yml index bb23f7fea17..e5f6ff19dbd 100644 --- a/.github/workflows/benchmark.yml +++ b/.github/workflows/benchmark.yml @@ -20,7 +20,7 @@ jobs: distribution: temurin java-version: 17 - - uses: gradle/gradle-build-action@v2 + - uses: gradle/gradle-build-action@v3 with: arguments: | jmhJar diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index ef324dfb6b1..a4e5b19ec97 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -50,7 +50,7 @@ jobs: distribution: temurin java-version: 17 - - uses: gradle/gradle-build-action@v2 + - uses: gradle/gradle-build-action@v3 with: arguments: | build @@ -123,7 +123,7 @@ jobs: distribution: temurin java-version: 17 - - uses: gradle/gradle-build-action@v2 + - uses: gradle/gradle-build-action@v3 # skipping release branches because the versions in those branches are not snapshots # (also this skips pull requests) if: ${{ github.ref_name == 'main' && github.repository == 'open-telemetry/opentelemetry-java' }} diff --git a/.github/workflows/codeql-daily.yml b/.github/workflows/codeql-daily.yml index 9aef4c78c47..065704888f7 100644 --- a/.github/workflows/codeql-daily.yml +++ b/.github/workflows/codeql-daily.yml @@ -27,7 +27,7 @@ jobs: # see https://github.com/github/codeql-action/issues/1555#issuecomment-1452228433 tools: latest - - uses: gradle/gradle-build-action@v2 + - uses: gradle/gradle-build-action@v3 with: # skipping build cache is needed so that all modules will be analyzed arguments: assemble --no-build-cache diff --git a/.github/workflows/owasp-dependency-check-daily.yml b/.github/workflows/owasp-dependency-check-daily.yml index c5a8f292df7..9adaf80948d 100644 --- a/.github/workflows/owasp-dependency-check-daily.yml +++ b/.github/workflows/owasp-dependency-check-daily.yml @@ -19,7 +19,7 @@ jobs: distribution: temurin java-version: 17 - - uses: gradle/gradle-build-action@v2 + - uses: gradle/gradle-build-action@v3 with: arguments: "dependencyCheckAnalyze" diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 66e7cf0bd3a..815bc4d5afc 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -22,7 +22,7 @@ jobs: java-version: 17 - name: Build and publish artifacts - uses: gradle/gradle-build-action@v2 + uses: gradle/gradle-build-action@v3 with: arguments: assemble publishToSonatype closeAndReleaseSonatypeStagingRepository env: From 5eaf4b290ebf3f703d138fe8c636b040608d54f4 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 17 Feb 2024 09:46:25 -0600 Subject: [PATCH 260/901] Update dependency net.ltgt.gradle:gradle-nullaway-plugin to v2 (#6237) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- buildSrc/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts index 31f4cbccf92..26728dc9d43 100644 --- a/buildSrc/build.gradle.kts +++ b/buildSrc/build.gradle.kts @@ -56,7 +56,7 @@ dependencies { implementation("me.champeau.gradle:japicmp-gradle-plugin:0.4.2") implementation("me.champeau.jmh:jmh-gradle-plugin:0.7.2") implementation("net.ltgt.gradle:gradle-errorprone-plugin:3.1.0") - implementation("net.ltgt.gradle:gradle-nullaway-plugin:1.6.0") + implementation("net.ltgt.gradle:gradle-nullaway-plugin:2.0.0") implementation("org.jetbrains.kotlin:kotlin-gradle-plugin:1.9.22") implementation("org.owasp:dependency-check-gradle:9.0.9") implementation("ru.vyarus:gradle-animalsniffer-plugin:1.7.1") From 77bb43942281ca2a5531ee6ef5fb6648505dc6a0 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 20 Feb 2024 16:24:03 -0600 Subject: [PATCH 261/901] Update dependency io.zipkin.reporter2:zipkin-reporter-bom to v3.3.0 (#6230) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Co-authored-by: Jack Berg --- dependencyManagement/build.gradle.kts | 2 +- .../exporter/zipkin/ZipkinSpanExporterTest.java | 8 ++++---- .../zipkin/internal/ZipkinSpanExporterProviderTest.java | 7 ++++--- 3 files changed, 9 insertions(+), 8 deletions(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index d2077c0ecde..135a6e6f9d7 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -17,7 +17,7 @@ val DEPENDENCY_BOMS = listOf( "io.grpc:grpc-bom:1.61.1", "io.netty:netty-bom:4.1.106.Final", "io.zipkin.brave:brave-bom:6.0.0", - "io.zipkin.reporter2:zipkin-reporter-bom:3.2.1", + "io.zipkin.reporter2:zipkin-reporter-bom:3.3.0", "org.assertj:assertj-bom:3.25.3", "org.junit:junit-bom:5.10.2", "org.testcontainers:testcontainers-bom:1.19.5", diff --git a/exporters/zipkin/src/test/java/io/opentelemetry/exporter/zipkin/ZipkinSpanExporterTest.java b/exporters/zipkin/src/test/java/io/opentelemetry/exporter/zipkin/ZipkinSpanExporterTest.java index 2917cfbefe6..673855d4a8c 100644 --- a/exporters/zipkin/src/test/java/io/opentelemetry/exporter/zipkin/ZipkinSpanExporterTest.java +++ b/exporters/zipkin/src/test/java/io/opentelemetry/exporter/zipkin/ZipkinSpanExporterTest.java @@ -189,7 +189,7 @@ void encoderProtobuf() { void compressionDefault() { ZipkinSpanExporter exporter = ZipkinSpanExporter.builder().build(); try { - assertThat(exporter).extracting("sender.compressionEnabled").isEqualTo(true); + assertThat(exporter).extracting("sender.delegate.compressionEnabled").isEqualTo(true); } finally { exporter.shutdown(); } @@ -199,7 +199,7 @@ void compressionDefault() { void compressionNone() { ZipkinSpanExporter exporter = ZipkinSpanExporter.builder().setCompression("none").build(); try { - assertThat(exporter).extracting("sender.compressionEnabled").isEqualTo(false); + assertThat(exporter).extracting("sender.delegate.compressionEnabled").isEqualTo(false); } finally { exporter.shutdown(); } @@ -209,7 +209,7 @@ void compressionNone() { void compressionGzip() { ZipkinSpanExporter exporter = ZipkinSpanExporter.builder().setCompression("gzip").build(); try { - assertThat(exporter).extracting("sender.compressionEnabled").isEqualTo(true); + assertThat(exporter).extracting("sender.delegate.compressionEnabled").isEqualTo(true); } finally { exporter.shutdown(); } @@ -220,7 +220,7 @@ void compressionEnabledAndDisabled() { ZipkinSpanExporter exporter = ZipkinSpanExporter.builder().setCompression("gzip").setCompression("none").build(); try { - assertThat(exporter).extracting("sender.compressionEnabled").isEqualTo(false); + assertThat(exporter).extracting("sender.delegate.compressionEnabled").isEqualTo(false); } finally { exporter.shutdown(); } diff --git a/exporters/zipkin/src/test/java/io/opentelemetry/exporter/zipkin/internal/ZipkinSpanExporterProviderTest.java b/exporters/zipkin/src/test/java/io/opentelemetry/exporter/zipkin/internal/ZipkinSpanExporterProviderTest.java index a0ad9a0a787..289fa1f7709 100644 --- a/exporters/zipkin/src/test/java/io/opentelemetry/exporter/zipkin/internal/ZipkinSpanExporterProviderTest.java +++ b/exporters/zipkin/src/test/java/io/opentelemetry/exporter/zipkin/internal/ZipkinSpanExporterProviderTest.java @@ -13,7 +13,6 @@ import java.util.Collections; import java.util.HashMap; import java.util.Map; -import okhttp3.HttpUrl; import org.junit.jupiter.api.Test; class ZipkinSpanExporterProviderTest { @@ -32,13 +31,14 @@ void createExporter_Default() { assertThat(spanExporter).isInstanceOf(ZipkinSpanExporter.class); assertThat(spanExporter) .extracting("sender") + .extracting("delegate") .extracting("client") .extracting("readTimeoutMillis") .isEqualTo(10_000); assertThat(spanExporter) .extracting("sender") .extracting("endpoint") - .isEqualTo(HttpUrl.get("http://localhost:9411/api/v2/spans")); + .isEqualTo("http://localhost:9411/api/v2/spans"); } } @@ -53,13 +53,14 @@ void createExporter_WithConfiguration() { assertThat(spanExporter).isInstanceOf(ZipkinSpanExporter.class); assertThat(spanExporter) .extracting("sender") + .extracting("delegate") .extracting("client") .extracting("readTimeoutMillis") .isEqualTo(1000); assertThat(spanExporter) .extracting("sender") .extracting("endpoint") - .isEqualTo(HttpUrl.get("http://localhost:8080/spans")); + .isEqualTo("http://localhost:8080/spans"); } } } From 01ff943683ad9d5684a0bc2bd6b60fe929d6736f Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 23 Feb 2024 18:46:48 -0800 Subject: [PATCH 262/901] Update dependency io.zipkin.brave:brave-bom to v6.0.1 (#6228) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- dependencyManagement/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index 135a6e6f9d7..26ead15db3e 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -16,7 +16,7 @@ val DEPENDENCY_BOMS = listOf( "com.squareup.okio:okio-bom:3.8.0", // applies to transitive dependencies of okhttp "io.grpc:grpc-bom:1.61.1", "io.netty:netty-bom:4.1.106.Final", - "io.zipkin.brave:brave-bom:6.0.0", + "io.zipkin.brave:brave-bom:6.0.1", "io.zipkin.reporter2:zipkin-reporter-bom:3.3.0", "org.assertj:assertj-bom:3.25.3", "org.junit:junit-bom:5.10.2", From 31fc7d0f770774ac0abf4cfc5f7aca8015a364d9 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 23 Feb 2024 18:47:17 -0800 Subject: [PATCH 263/901] Update dependency nl.jqno.equalsverifier:equalsverifier to v3.15.7 (#6246) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- dependencyManagement/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index 26ead15db3e..080a449e763 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -71,7 +71,7 @@ val DEPENDENCIES = listOf( "io.opentracing:opentracing-noop:0.33.0", "io.prometheus:prometheus-metrics-exporter-httpserver:1.1.0", "junit:junit:4.13.2", - "nl.jqno.equalsverifier:equalsverifier:3.15.6", + "nl.jqno.equalsverifier:equalsverifier:3.15.7", "org.awaitility:awaitility:4.2.0", "org.bouncycastle:bcpkix-jdk15on:1.70", "org.codehaus.mojo:animal-sniffer-annotations:1.23", From 8e298b9b13017969c2dbf17dbcfb2e99f4e263fb Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 23 Feb 2024 18:48:07 -0800 Subject: [PATCH 264/901] Update dependency org.testcontainers:testcontainers-bom to v1.19.6 (#6242) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- dependencyManagement/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index 080a449e763..36b640a26fc 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -20,7 +20,7 @@ val DEPENDENCY_BOMS = listOf( "io.zipkin.reporter2:zipkin-reporter-bom:3.3.0", "org.assertj:assertj-bom:3.25.3", "org.junit:junit-bom:5.10.2", - "org.testcontainers:testcontainers-bom:1.19.5", + "org.testcontainers:testcontainers-bom:1.19.6", "org.snakeyaml:snakeyaml-engine:2.7" ) From dec4e9b583f4faaf9797435cc1dccb7899d0159f Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 23 Feb 2024 18:48:19 -0800 Subject: [PATCH 265/901] Update plugin org.graalvm.buildtools.native to v0.10.1 (#6239) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- settings.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/settings.gradle.kts b/settings.gradle.kts index 15dc2e65a1c..66af6e31c49 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -5,7 +5,7 @@ pluginManagement { id("de.undercouch.download") version "5.5.0" id("org.jsonschema2pojo") version "1.2.1" id("io.github.gradle-nexus.publish-plugin") version "1.3.0" - id("org.graalvm.buildtools.native") version "0.10.0" + id("org.graalvm.buildtools.native") version "0.10.1" } } From 4eb05c7c007ded16acc7fb234252ba4d16aa6641 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 23 Feb 2024 19:51:21 -0800 Subject: [PATCH 266/901] Update dependency io.netty:netty-bom to v4.1.107.Final (#6227) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- dependencyManagement/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index 36b640a26fc..655f3ec10d2 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -15,7 +15,7 @@ val DEPENDENCY_BOMS = listOf( "com.squareup.okhttp3:okhttp-bom:4.12.0", "com.squareup.okio:okio-bom:3.8.0", // applies to transitive dependencies of okhttp "io.grpc:grpc-bom:1.61.1", - "io.netty:netty-bom:4.1.106.Final", + "io.netty:netty-bom:4.1.107.Final", "io.zipkin.brave:brave-bom:6.0.1", "io.zipkin.reporter2:zipkin-reporter-bom:3.3.0", "org.assertj:assertj-bom:3.25.3", From 96fe54fc16a85fd0a10c0d824679291d06941bab Mon Sep 17 00:00:00 2001 From: John Bley Date: Fri, 23 Feb 2024 22:51:41 -0500 Subject: [PATCH 267/901] Fault in SdkSpan.events (#6244) Co-authored-by: John Watson --- .../main/java/io/opentelemetry/sdk/trace/SdkSpan.java | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/SdkSpan.java b/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/SdkSpan.java index fec835b17ff..a6b28043d29 100644 --- a/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/SdkSpan.java +++ b/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/SdkSpan.java @@ -71,7 +71,8 @@ final class SdkSpan implements ReadWriteSpan, ExtendedSpan { // List of recorded events. @GuardedBy("lock") - private final List events; + @Nullable + private List events; // Number of events recorded. @GuardedBy("lock") @@ -126,7 +127,6 @@ private SdkSpan( this.clock = clock; this.startEpochNanos = startEpochNanos; this.attributes = attributes; - this.events = new ArrayList<>(); this.spanLimits = spanLimits; } @@ -378,6 +378,9 @@ private void addTimedEvent(EventData timedEvent) { logger.log(Level.FINE, "Calling addEvent() on an ended Span."); return; } + if (events == null) { + events = new ArrayList<>(); + } if (events.size() < spanLimits.getMaxNumberOfEvents()) { events.add(timedEvent); } @@ -518,7 +521,7 @@ long getStartEpochNanos() { @GuardedBy("lock") private List getImmutableTimedEvents() { - if (events.isEmpty()) { + if (events == null) { return Collections.emptyList(); } From 1d4a2f4a503244244197b1c3ab38b9b2f3237d50 Mon Sep 17 00:00:00 2001 From: jack-berg <34418638+jack-berg@users.noreply.github.com> Date: Fri, 23 Feb 2024 22:26:32 -0600 Subject: [PATCH 268/901] Add connectTimeout configuration option OtlpGrpc{Signal}Exporters (#6079) --- .../opentelemetry-exporter-otlp.txt | 13 ++++++- .../internal/grpc/GrpcExporterBuilder.java | 11 ++++++ .../internal/grpc/GrpcSenderProvider.java | 1 + .../otlp/trace/OltpExporterBenchmark.java | 1 + .../OtlpGrpcLogRecordExporterBuilder.java | 20 +++++++++++ .../OtlpGrpcMetricExporterBuilder.java | 20 +++++++++++ .../trace/OtlpGrpcSpanExporterBuilder.java | 20 +++++++++++ .../AbstractGrpcTelemetryExporterTest.java | 34 +++++++++++++++++++ .../GrpcLogRecordExporterBuilderWrapper.java | 3 +- .../GrpcMetricExporterBuilderWrapper.java | 3 +- .../GrpcSpanExporterBuilderWrapper.java | 3 +- .../internal/UpstreamGrpcSenderProvider.java | 1 + .../okhttp/internal/OkHttpGrpcSender.java | 4 ++- .../internal/OkHttpGrpcSenderProvider.java | 2 ++ .../internal/OkHttpGrpcSuppressionTest.java | 2 +- 15 files changed, 132 insertions(+), 6 deletions(-) diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-otlp.txt b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-otlp.txt index df26146497b..f5f51eb6e25 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-otlp.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-otlp.txt @@ -1,2 +1,13 @@ Comparing source compatibility of against -No changes. \ No newline at end of file +*** MODIFIED CLASS: PUBLIC FINAL io.opentelemetry.exporter.otlp.logs.OtlpGrpcLogRecordExporterBuilder (not serializable) + === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 + +++ NEW METHOD: PUBLIC(+) io.opentelemetry.exporter.otlp.logs.OtlpGrpcLogRecordExporterBuilder setConnectTimeout(long, java.util.concurrent.TimeUnit) + +++ NEW METHOD: PUBLIC(+) io.opentelemetry.exporter.otlp.logs.OtlpGrpcLogRecordExporterBuilder setConnectTimeout(java.time.Duration) +*** MODIFIED CLASS: PUBLIC FINAL io.opentelemetry.exporter.otlp.metrics.OtlpGrpcMetricExporterBuilder (not serializable) + === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 + +++ NEW METHOD: PUBLIC(+) io.opentelemetry.exporter.otlp.metrics.OtlpGrpcMetricExporterBuilder setConnectTimeout(long, java.util.concurrent.TimeUnit) + +++ NEW METHOD: PUBLIC(+) io.opentelemetry.exporter.otlp.metrics.OtlpGrpcMetricExporterBuilder setConnectTimeout(java.time.Duration) +*** MODIFIED CLASS: PUBLIC FINAL io.opentelemetry.exporter.otlp.trace.OtlpGrpcSpanExporterBuilder (not serializable) + === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 + +++ NEW METHOD: PUBLIC(+) io.opentelemetry.exporter.otlp.trace.OtlpGrpcSpanExporterBuilder setConnectTimeout(long, java.util.concurrent.TimeUnit) + +++ NEW METHOD: PUBLIC(+) io.opentelemetry.exporter.otlp.trace.OtlpGrpcSpanExporterBuilder setConnectTimeout(java.time.Duration) diff --git a/exporters/common/src/main/java/io/opentelemetry/exporter/internal/grpc/GrpcExporterBuilder.java b/exporters/common/src/main/java/io/opentelemetry/exporter/internal/grpc/GrpcExporterBuilder.java index df9bb403099..ad0b8c86aaf 100644 --- a/exporters/common/src/main/java/io/opentelemetry/exporter/internal/grpc/GrpcExporterBuilder.java +++ b/exporters/common/src/main/java/io/opentelemetry/exporter/internal/grpc/GrpcExporterBuilder.java @@ -43,6 +43,8 @@ @SuppressWarnings("JavadocMethod") public class GrpcExporterBuilder { + public static final long DEFAULT_CONNECT_TIMEOUT_SECS = 10; + private static final Logger LOGGER = Logger.getLogger(GrpcExporterBuilder.class.getName()); private final String exporterName; @@ -52,6 +54,7 @@ public class GrpcExporterBuilder { grpcStubFactory; private long timeoutNanos; + private long connectTimeoutNanos = TimeUnit.SECONDS.toNanos(DEFAULT_CONNECT_TIMEOUT_SECS); private URI endpoint; @Nullable private Compressor compressor; private final Map constantHeaders = new HashMap<>(); @@ -92,6 +95,11 @@ public GrpcExporterBuilder setTimeout(Duration timeout) { return setTimeout(timeout.toNanos(), TimeUnit.NANOSECONDS); } + public GrpcExporterBuilder setConnectTimeout(long timeout, TimeUnit unit) { + connectTimeoutNanos = unit.toNanos(timeout); + return this; + } + public GrpcExporterBuilder setEndpoint(String endpoint) { this.endpoint = ExporterBuilderUtil.validateEndpoint(endpoint); return this; @@ -151,6 +159,7 @@ public GrpcExporterBuilder copy() { grpcEndpointPath); copy.timeoutNanos = timeoutNanos; + copy.connectTimeoutNanos = connectTimeoutNanos; copy.endpoint = endpoint; copy.compressor = compressor; copy.constantHeaders.putAll(constantHeaders); @@ -193,6 +202,7 @@ public GrpcExporter build() { grpcEndpointPath, compressor, timeoutNanos, + connectTimeoutNanos, headerSupplier, grpcChannel, grpcStubFactory, @@ -214,6 +224,7 @@ public String toString(boolean includePrefixAndSuffix) { joiner.add("endpoint=" + endpoint.toString()); joiner.add("endpointPath=" + grpcEndpointPath); joiner.add("timeoutNanos=" + timeoutNanos); + joiner.add("connectTimeoutNanos=" + connectTimeoutNanos); joiner.add( "compressorEncoding=" + Optional.ofNullable(compressor).map(Compressor::getEncoding).orElse(null)); diff --git a/exporters/common/src/main/java/io/opentelemetry/exporter/internal/grpc/GrpcSenderProvider.java b/exporters/common/src/main/java/io/opentelemetry/exporter/internal/grpc/GrpcSenderProvider.java index e7618e9bfaf..48f0e927d26 100644 --- a/exporters/common/src/main/java/io/opentelemetry/exporter/internal/grpc/GrpcSenderProvider.java +++ b/exporters/common/src/main/java/io/opentelemetry/exporter/internal/grpc/GrpcSenderProvider.java @@ -34,6 +34,7 @@ GrpcSender createSender( String endpointPath, @Nullable Compressor compressor, long timeoutNanos, + long connectTimeoutNanos, Supplier>> headersSupplier, @Nullable Object managedChannel, Supplier>> stubFactory, diff --git a/exporters/otlp/all/src/jmh/java/io/opentelemetry/exporter/otlp/trace/OltpExporterBenchmark.java b/exporters/otlp/all/src/jmh/java/io/opentelemetry/exporter/otlp/trace/OltpExporterBenchmark.java index dd8ca40dba2..ba6492547c7 100644 --- a/exporters/otlp/all/src/jmh/java/io/opentelemetry/exporter/otlp/trace/OltpExporterBenchmark.java +++ b/exporters/otlp/all/src/jmh/java/io/opentelemetry/exporter/otlp/trace/OltpExporterBenchmark.java @@ -100,6 +100,7 @@ public void setUp() { .toString(), null, 10, + 10, Collections::emptyMap, null, null, diff --git a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/logs/OtlpGrpcLogRecordExporterBuilder.java b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/logs/OtlpGrpcLogRecordExporterBuilder.java index 3a50b3e1d1c..9b6cee82912 100644 --- a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/logs/OtlpGrpcLogRecordExporterBuilder.java +++ b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/logs/OtlpGrpcLogRecordExporterBuilder.java @@ -101,6 +101,26 @@ public OtlpGrpcLogRecordExporterBuilder setTimeout(Duration timeout) { return this; } + /** + * Sets the maximum time to wait for new connections to be established. If unset, defaults to + * {@value GrpcExporterBuilder#DEFAULT_CONNECT_TIMEOUT_SECS}s. + */ + public OtlpGrpcLogRecordExporterBuilder setConnectTimeout(long timeout, TimeUnit unit) { + requireNonNull(unit, "unit"); + checkArgument(timeout >= 0, "timeout must be non-negative"); + delegate.setConnectTimeout(timeout, unit); + return this; + } + + /** + * Sets the maximum time to wait for new connections to be established. If unset, defaults to + * {@value GrpcExporterBuilder#DEFAULT_CONNECT_TIMEOUT_SECS}s. + */ + public OtlpGrpcLogRecordExporterBuilder setConnectTimeout(Duration timeout) { + requireNonNull(timeout, "timeout"); + return setConnectTimeout(timeout.toNanos(), TimeUnit.NANOSECONDS); + } + /** * Sets the OTLP endpoint to connect to. If unset, defaults to {@value DEFAULT_ENDPOINT_URL}. The * endpoint must start with either http:// or https://. diff --git a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/metrics/OtlpGrpcMetricExporterBuilder.java b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/metrics/OtlpGrpcMetricExporterBuilder.java index 302eee845ed..4b2ebd22254 100644 --- a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/metrics/OtlpGrpcMetricExporterBuilder.java +++ b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/metrics/OtlpGrpcMetricExporterBuilder.java @@ -113,6 +113,26 @@ public OtlpGrpcMetricExporterBuilder setTimeout(Duration timeout) { return this; } + /** + * Sets the maximum time to wait for new connections to be established. If unset, defaults to + * {@value GrpcExporterBuilder#DEFAULT_CONNECT_TIMEOUT_SECS}s. + */ + public OtlpGrpcMetricExporterBuilder setConnectTimeout(long timeout, TimeUnit unit) { + requireNonNull(unit, "unit"); + checkArgument(timeout >= 0, "timeout must be non-negative"); + delegate.setConnectTimeout(timeout, unit); + return this; + } + + /** + * Sets the maximum time to wait for new connections to be established. If unset, defaults to + * {@value GrpcExporterBuilder#DEFAULT_CONNECT_TIMEOUT_SECS}s. + */ + public OtlpGrpcMetricExporterBuilder setConnectTimeout(Duration timeout) { + requireNonNull(timeout, "timeout"); + return setConnectTimeout(timeout.toNanos(), TimeUnit.NANOSECONDS); + } + /** * Sets the OTLP endpoint to connect to. If unset, defaults to {@value DEFAULT_ENDPOINT_URL}. The * endpoint must start with either http:// or https://. diff --git a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/trace/OtlpGrpcSpanExporterBuilder.java b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/trace/OtlpGrpcSpanExporterBuilder.java index cac7cd5cb85..b04f4195d55 100644 --- a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/trace/OtlpGrpcSpanExporterBuilder.java +++ b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/trace/OtlpGrpcSpanExporterBuilder.java @@ -97,6 +97,26 @@ public OtlpGrpcSpanExporterBuilder setTimeout(Duration timeout) { return this; } + /** + * Sets the maximum time to wait for new connections to be established. If unset, defaults to + * {@value GrpcExporterBuilder#DEFAULT_CONNECT_TIMEOUT_SECS}s. + */ + public OtlpGrpcSpanExporterBuilder setConnectTimeout(long timeout, TimeUnit unit) { + requireNonNull(unit, "unit"); + checkArgument(timeout >= 0, "timeout must be non-negative"); + delegate.setConnectTimeout(timeout, unit); + return this; + } + + /** + * Sets the maximum time to wait for new connections to be established. If unset, defaults to + * {@value GrpcExporterBuilder#DEFAULT_CONNECT_TIMEOUT_SECS}s. + */ + public OtlpGrpcSpanExporterBuilder setConnectTimeout(Duration timeout) { + requireNonNull(timeout, "timeout"); + return setConnectTimeout(timeout.toNanos(), TimeUnit.NANOSECONDS); + } + /** * Sets the OTLP endpoint to connect to. If unset, defaults to {@value DEFAULT_ENDPOINT_URL}. The * endpoint must start with either http:// or https://. diff --git a/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/AbstractGrpcTelemetryExporterTest.java b/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/AbstractGrpcTelemetryExporterTest.java index f3310eb36d8..c9106353a6e 100644 --- a/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/AbstractGrpcTelemetryExporterTest.java +++ b/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/AbstractGrpcTelemetryExporterTest.java @@ -456,6 +456,33 @@ public Stream provideArguments(ExtensionContext context) th } } + @Test + @SuppressLogger(GrpcExporter.class) + void connectTimeout() { + // UpstreamGrpcSender doesn't support connectTimeout, so we skip the test + assumeThat(exporter.unwrap()) + .extracting("delegate.grpcSender") + .matches(sender -> sender.getClass().getSimpleName().equals("OkHttpGrpcSender")); + + TelemetryExporter exporter = + exporterBuilder() + // Connecting to a non-routable IP address to trigger connection error + .setEndpoint("http://10.255.255.1") + .setConnectTimeout(Duration.ofMillis(1)) + .build(); + try { + long startTimeMillis = System.currentTimeMillis(); + CompletableResultCode result = + exporter.export(Collections.singletonList(generateFakeTelemetry())); + assertThat(result.join(10, TimeUnit.SECONDS).isSuccess()).isFalse(); + // Assert that the export request fails well before the default connect timeout of 10s + assertThat(System.currentTimeMillis() - startTimeMillis) + .isLessThan(TimeUnit.SECONDS.toMillis(1)); + } finally { + exporter.shutdown(); + } + } + @Test void deadlineSetPerExport() throws InterruptedException { TelemetryExporter exporter = @@ -840,6 +867,9 @@ void stringRepresentation() throws IOException, CertificateEncodingException { + "timeoutNanos=" + TimeUnit.SECONDS.toNanos(10) + ", " + + "connectTimeoutNanos=" + + TimeUnit.SECONDS.toNanos(10) + + ", " + "compressorEncoding=null, " + "headers=Headers\\{User-Agent=OBFUSCATED\\}" + ".*" // Maybe additional grpcChannel field @@ -851,6 +881,7 @@ void stringRepresentation() throws IOException, CertificateEncodingException { telemetryExporter = exporterBuilder() .setTimeout(Duration.ofSeconds(5)) + .setConnectTimeout(Duration.ofSeconds(4)) .setEndpoint("http://example:4317") .setCompression("gzip") .addHeader("foo", "bar") @@ -877,6 +908,9 @@ void stringRepresentation() throws IOException, CertificateEncodingException { + "timeoutNanos=" + TimeUnit.SECONDS.toNanos(5) + ", " + + "connectTimeoutNanos=" + + TimeUnit.SECONDS.toNanos(4) + + ", " + "compressorEncoding=gzip, " + "headers=Headers\\{.*foo=OBFUSCATED.*\\}, " + "retryPolicy=RetryPolicy\\{maxAttempts=2, initialBackoff=PT0\\.05S, maxBackoff=PT3S, backoffMultiplier=1\\.3\\}" diff --git a/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/GrpcLogRecordExporterBuilderWrapper.java b/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/GrpcLogRecordExporterBuilderWrapper.java index 5495a9d6bcd..60e616e7838 100644 --- a/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/GrpcLogRecordExporterBuilderWrapper.java +++ b/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/GrpcLogRecordExporterBuilderWrapper.java @@ -49,7 +49,8 @@ public TelemetryExporterBuilder setConnectTimeout(long timeout, T @Override public TelemetryExporterBuilder setConnectTimeout(Duration timeout) { - throw new UnsupportedOperationException(); + builder.setConnectTimeout(timeout); + return this; } @Override diff --git a/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/GrpcMetricExporterBuilderWrapper.java b/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/GrpcMetricExporterBuilderWrapper.java index ff9a53a7ca5..6d1f2365512 100644 --- a/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/GrpcMetricExporterBuilderWrapper.java +++ b/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/GrpcMetricExporterBuilderWrapper.java @@ -49,7 +49,8 @@ public TelemetryExporterBuilder setConnectTimeout(long timeout, Time @Override public TelemetryExporterBuilder setConnectTimeout(Duration timeout) { - throw new UnsupportedOperationException(); + builder.setConnectTimeout(timeout); + return this; } @Override diff --git a/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/GrpcSpanExporterBuilderWrapper.java b/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/GrpcSpanExporterBuilderWrapper.java index 59068809909..871eb559deb 100644 --- a/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/GrpcSpanExporterBuilderWrapper.java +++ b/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/GrpcSpanExporterBuilderWrapper.java @@ -50,7 +50,8 @@ public TelemetryExporterBuilder setConnectTimeout(long timeout, TimeUn @Override public TelemetryExporterBuilder setConnectTimeout(Duration timeout) { - throw new UnsupportedOperationException(); + builder.setConnectTimeout(timeout); + return this; } @Override diff --git a/exporters/sender/grpc-managed-channel/src/main/java/io/opentelemetry/exporter/sender/grpc/managedchannel/internal/UpstreamGrpcSenderProvider.java b/exporters/sender/grpc-managed-channel/src/main/java/io/opentelemetry/exporter/sender/grpc/managedchannel/internal/UpstreamGrpcSenderProvider.java index 880d288417e..d07bc4ed614 100644 --- a/exporters/sender/grpc-managed-channel/src/main/java/io/opentelemetry/exporter/sender/grpc/managedchannel/internal/UpstreamGrpcSenderProvider.java +++ b/exporters/sender/grpc-managed-channel/src/main/java/io/opentelemetry/exporter/sender/grpc/managedchannel/internal/UpstreamGrpcSenderProvider.java @@ -41,6 +41,7 @@ public GrpcSender createSender( String endpointPath, @Nullable Compressor compressor, long timeoutNanos, + long connectTimeoutNanos, Supplier>> headersSupplier, @Nullable Object managedChannel, Supplier>> stubFactory, diff --git a/exporters/sender/okhttp/src/main/java/io/opentelemetry/exporter/sender/okhttp/internal/OkHttpGrpcSender.java b/exporters/sender/okhttp/src/main/java/io/opentelemetry/exporter/sender/okhttp/internal/OkHttpGrpcSender.java index 477b3fdda59..3c5cb153e12 100644 --- a/exporters/sender/okhttp/src/main/java/io/opentelemetry/exporter/sender/okhttp/internal/OkHttpGrpcSender.java +++ b/exporters/sender/okhttp/src/main/java/io/opentelemetry/exporter/sender/okhttp/internal/OkHttpGrpcSender.java @@ -75,6 +75,7 @@ public OkHttpGrpcSender( String endpoint, @Nullable Compressor compressor, long timeoutNanos, + long connectTimeoutNanos, Supplier>> headersSupplier, @Nullable RetryPolicy retryPolicy, @Nullable SSLContext sslContext, @@ -82,7 +83,8 @@ public OkHttpGrpcSender( OkHttpClient.Builder clientBuilder = new OkHttpClient.Builder() .dispatcher(OkHttpUtil.newDispatcher()) - .callTimeout(Duration.ofNanos(timeoutNanos)); + .callTimeout(Duration.ofNanos(timeoutNanos)) + .connectTimeout(Duration.ofNanos(connectTimeoutNanos)); if (retryPolicy != null) { clientBuilder.addInterceptor( new RetryInterceptor(retryPolicy, OkHttpGrpcSender::isRetryable)); diff --git a/exporters/sender/okhttp/src/main/java/io/opentelemetry/exporter/sender/okhttp/internal/OkHttpGrpcSenderProvider.java b/exporters/sender/okhttp/src/main/java/io/opentelemetry/exporter/sender/okhttp/internal/OkHttpGrpcSenderProvider.java index affaf09be68..b6595ee2866 100644 --- a/exporters/sender/okhttp/src/main/java/io/opentelemetry/exporter/sender/okhttp/internal/OkHttpGrpcSenderProvider.java +++ b/exporters/sender/okhttp/src/main/java/io/opentelemetry/exporter/sender/okhttp/internal/OkHttpGrpcSenderProvider.java @@ -35,6 +35,7 @@ public GrpcSender createSender( String endpointPath, @Nullable Compressor compressor, long timeoutNanos, + long connectTimeoutNanos, Supplier>> headersSupplier, @Nullable Object managedChannel, Supplier>> stubFactory, @@ -45,6 +46,7 @@ public GrpcSender createSender( endpoint.resolve(endpointPath).toString(), compressor, timeoutNanos, + connectTimeoutNanos, headersSupplier, retryPolicy, sslContext, diff --git a/exporters/sender/okhttp/src/test/java/io/opentelemetry/exporter/sender/okhttp/internal/OkHttpGrpcSuppressionTest.java b/exporters/sender/okhttp/src/test/java/io/opentelemetry/exporter/sender/okhttp/internal/OkHttpGrpcSuppressionTest.java index fcedd3bc25f..7b0ec48020a 100644 --- a/exporters/sender/okhttp/src/test/java/io/opentelemetry/exporter/sender/okhttp/internal/OkHttpGrpcSuppressionTest.java +++ b/exporters/sender/okhttp/src/test/java/io/opentelemetry/exporter/sender/okhttp/internal/OkHttpGrpcSuppressionTest.java @@ -21,7 +21,7 @@ void send(OkHttpGrpcSender sender, Runnable onSuccess, Runnable @Override OkHttpGrpcSender createSender(String endpoint) { return new OkHttpGrpcSender<>( - "https://localhost", null, 10L, Collections::emptyMap, null, null, null); + "https://localhost", null, 10L, 10L, Collections::emptyMap, null, null, null); } protected static class DummyMarshaler extends MarshalerWithSize { From 6afb816f9eccf2524dcb7dc080a92dc97186f251 Mon Sep 17 00:00:00 2001 From: jason plumb <75337021+breedx-splk@users.noreply.github.com> Date: Wed, 28 Feb 2024 14:53:34 -0800 Subject: [PATCH 269/901] Add note about draft PRs to CONTRIBUTING.md (#6247) --- CONTRIBUTING.md | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index eb879a169ba..4d1de54157b 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -8,7 +8,7 @@ requirements and recommendations. If you want to add new features or change behavior, please make sure your changes follow the [OpenTelemetry Specification](https://github.com/open-telemetry/opentelemetry-specification). -Otherwise, file an issue or submit a PR to the specification repo first. +Otherwise, file an issue or submit a pull request (PR) to the specification repo first. Make sure to review the projects [license](LICENSE) and sign the [CNCF CLA](https://identity.linuxfoundation.org/projects/cncf). A signed CLA will be enforced by an @@ -61,6 +61,14 @@ After you submit a PR, it will be reviewed by the project maintainers and approv maintainers need to review a particular PR, but merging to the base branch is authorized to restricted members (administrators). +### Draft PRs + +Draft PRs are welcome, especially when exploring new ideas or experimenting with a hypothesis. +However, draft PRs may not receive the same degree of attention, feedback, or scrutiny unless +requested directly. In order to help keep the PR backlog maintainable, drafts older than 6 months +will be closed by the project maintainers. This should not be interpreted as a rejection. Closed +PRs may be reopened by the author when time or interest allows. + ## Project Scope `opentelemetry-java` is one of several repositories which comprise the OpenTelemetry Java ecosystem, From 62a4810145eec10abda6b023a70f7e9252ca217c Mon Sep 17 00:00:00 2001 From: Asaf Mesika Date: Thu, 29 Feb 2024 16:59:58 +0200 Subject: [PATCH 270/901] Added MetricReader customizer for AutoConfiguredOpenTelemetrySdkBuilder (#6231) --- ...emetry-sdk-extension-autoconfigure-spi.txt | 4 +- ...ntelemetry-sdk-extension-autoconfigure.txt | 4 +- .../spi/AutoConfigurationCustomizer.java | 14 ++++++ sdk-extensions/autoconfigure/build.gradle.kts | 1 + ...AutoConfiguredOpenTelemetrySdkBuilder.java | 24 ++++++++- .../MeterProviderConfiguration.java | 14 +++++- .../MetricExporterConfiguration.java | 17 ++++++- .../MeterProviderConfigurationTest.java | 1 + .../AutoConfiguredOpenTelemetrySdkTest.java | 23 +++++++++ .../ConfigurableMetricExporterTest.java | 14 ++++-- .../sdk/autoconfigure/FreePortFinder.java | 22 ++++++++ .../MeterProviderConfigurationTest.java | 3 ++ .../MetricExporterConfigurationTest.java | 50 ++++++++++++++++++- 13 files changed, 180 insertions(+), 11 deletions(-) create mode 100644 sdk-extensions/autoconfigure/src/testFullConfig/java/io/opentelemetry/sdk/autoconfigure/FreePortFinder.java diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-extension-autoconfigure-spi.txt b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-extension-autoconfigure-spi.txt index df26146497b..c464bbdd2e2 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-extension-autoconfigure-spi.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-extension-autoconfigure-spi.txt @@ -1,2 +1,4 @@ Comparing source compatibility of against -No changes. \ No newline at end of file +*** MODIFIED INTERFACE: PUBLIC ABSTRACT io.opentelemetry.sdk.autoconfigure.spi.AutoConfigurationCustomizer (not serializable) + === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 + +++ NEW METHOD: PUBLIC(+) io.opentelemetry.sdk.autoconfigure.spi.AutoConfigurationCustomizer addMetricReaderCustomizer(java.util.function.BiFunction) diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-extension-autoconfigure.txt b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-extension-autoconfigure.txt index df26146497b..04f3e512be6 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-extension-autoconfigure.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-extension-autoconfigure.txt @@ -1,2 +1,4 @@ Comparing source compatibility of against -No changes. \ No newline at end of file +*** MODIFIED CLASS: PUBLIC FINAL io.opentelemetry.sdk.autoconfigure.AutoConfiguredOpenTelemetrySdkBuilder (not serializable) + === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 + +++ NEW METHOD: PUBLIC(+) io.opentelemetry.sdk.autoconfigure.AutoConfiguredOpenTelemetrySdkBuilder addMetricReaderCustomizer(java.util.function.BiFunction) diff --git a/sdk-extensions/autoconfigure-spi/src/main/java/io/opentelemetry/sdk/autoconfigure/spi/AutoConfigurationCustomizer.java b/sdk-extensions/autoconfigure-spi/src/main/java/io/opentelemetry/sdk/autoconfigure/spi/AutoConfigurationCustomizer.java index 03edca120bc..d64ec24f49d 100644 --- a/sdk-extensions/autoconfigure-spi/src/main/java/io/opentelemetry/sdk/autoconfigure/spi/AutoConfigurationCustomizer.java +++ b/sdk-extensions/autoconfigure-spi/src/main/java/io/opentelemetry/sdk/autoconfigure/spi/AutoConfigurationCustomizer.java @@ -11,6 +11,7 @@ import io.opentelemetry.sdk.logs.export.LogRecordExporter; import io.opentelemetry.sdk.metrics.SdkMeterProviderBuilder; import io.opentelemetry.sdk.metrics.export.MetricExporter; +import io.opentelemetry.sdk.metrics.export.MetricReader; import io.opentelemetry.sdk.resources.Resource; import io.opentelemetry.sdk.trace.SdkTracerProviderBuilder; import io.opentelemetry.sdk.trace.SpanProcessor; @@ -150,12 +151,25 @@ default AutoConfigurationCustomizer addMeterProviderCustomizer( * *

    Multiple calls will execute the customizers in order. */ + @SuppressWarnings("UnusedReturnValue") default AutoConfigurationCustomizer addMetricExporterCustomizer( BiFunction exporterCustomizer) { return this; } + /** + * Adds a {@link BiFunction} to invoke with the autoconfigured {@link MetricReader} to allow + * customization. The return value of the {@link BiFunction} will replace the passed-in argument. + * + *

    Multiple calls will execute the customizers in order. + */ + @SuppressWarnings("UnusedReturnValue") + default AutoConfigurationCustomizer addMetricReaderCustomizer( + BiFunction readerCustomizer) { + return this; + } + /** * Adds a {@link BiFunction} to invoke the with the {@link SdkLoggerProviderBuilder} to allow * customization. The return value of the {@link BiFunction} will replace the passed-in argument. diff --git a/sdk-extensions/autoconfigure/build.gradle.kts b/sdk-extensions/autoconfigure/build.gradle.kts index 62fcd639c79..04fbde232fc 100644 --- a/sdk-extensions/autoconfigure/build.gradle.kts +++ b/sdk-extensions/autoconfigure/build.gradle.kts @@ -53,6 +53,7 @@ testing { implementation(project(":exporters:logging-otlp")) implementation(project(":exporters:otlp:all")) implementation(project(":exporters:prometheus")) + implementation("io.prometheus:prometheus-metrics-exporter-httpserver") implementation(project(":exporters:zipkin")) implementation(project(":sdk:testing")) implementation(project(":sdk:trace-shaded-deps")) diff --git a/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/AutoConfiguredOpenTelemetrySdkBuilder.java b/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/AutoConfiguredOpenTelemetrySdkBuilder.java index 8e332c2a2b7..ac9d39a2a71 100644 --- a/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/AutoConfiguredOpenTelemetrySdkBuilder.java +++ b/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/AutoConfiguredOpenTelemetrySdkBuilder.java @@ -28,6 +28,7 @@ import io.opentelemetry.sdk.metrics.SdkMeterProvider; import io.opentelemetry.sdk.metrics.SdkMeterProviderBuilder; import io.opentelemetry.sdk.metrics.export.MetricExporter; +import io.opentelemetry.sdk.metrics.export.MetricReader; import io.opentelemetry.sdk.resources.Resource; import io.opentelemetry.sdk.trace.SdkTracerProvider; import io.opentelemetry.sdk.trace.SdkTracerProviderBuilder; @@ -83,6 +84,8 @@ public final class AutoConfiguredOpenTelemetrySdkBuilder implements AutoConfigur meterProviderCustomizer = (a, unused) -> a; private BiFunction metricExporterCustomizer = (a, unused) -> a; + private BiFunction + metricReaderCustomizer = (a, unused) -> a; private BiFunction loggerProviderCustomizer = (a, unused) -> a; @@ -283,6 +286,20 @@ public AutoConfiguredOpenTelemetrySdkBuilder addMetricExporterCustomizer( return this; } + /** + * Adds a {@link BiFunction} to invoke with the autoconfigured {@link MetricReader} to allow + * customization. The return value of the {@link BiFunction} will replace the passed-in argument. + * + *

    Multiple calls will execute the customizers in order. + */ + @Override + public AutoConfiguredOpenTelemetrySdkBuilder addMetricReaderCustomizer( + BiFunction readerCustomizer) { + requireNonNull(readerCustomizer, "readerCustomizer"); + this.metricReaderCustomizer = mergeCustomizer(this.metricReaderCustomizer, readerCustomizer); + return this; + } + /** * Adds a {@link BiFunction} to invoke the with the {@link SdkLoggerProviderBuilder} to allow * customization. The return value of the {@link BiFunction} will replace the passed-in argument. @@ -406,7 +423,12 @@ public AutoConfiguredOpenTelemetrySdk build() { SdkMeterProviderBuilder meterProviderBuilder = SdkMeterProvider.builder(); meterProviderBuilder.setResource(resource); MeterProviderConfiguration.configureMeterProvider( - meterProviderBuilder, config, spiHelper, metricExporterCustomizer, closeables); + meterProviderBuilder, + config, + spiHelper, + metricReaderCustomizer, + metricExporterCustomizer, + closeables); meterProviderBuilder = meterProviderCustomizer.apply(meterProviderBuilder, config); SdkMeterProvider meterProvider = meterProviderBuilder.build(); closeables.add(meterProvider); diff --git a/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/MeterProviderConfiguration.java b/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/MeterProviderConfiguration.java index 525dc54974a..3689161b906 100644 --- a/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/MeterProviderConfiguration.java +++ b/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/MeterProviderConfiguration.java @@ -29,6 +29,8 @@ static void configureMeterProvider( SdkMeterProviderBuilder meterProviderBuilder, ConfigProperties config, SpiHelper spiHelper, + BiFunction + metricReaderCustomizer, BiFunction metricExporterCustomizer, List closeables) { @@ -56,7 +58,8 @@ static void configureMeterProvider( throw new ConfigurationException("otel.experimental.metrics.cardinality.limit must be >= 1"); } - configureMetricReaders(config, spiHelper, metricExporterCustomizer, closeables) + configureMetricReaders( + config, spiHelper, metricReaderCustomizer, metricExporterCustomizer, closeables) .forEach( reader -> SdkMeterProviderUtil.registerMetricReaderWithCardinalitySelector( @@ -66,6 +69,8 @@ static void configureMeterProvider( static List configureMetricReaders( ConfigProperties config, SpiHelper spiHelper, + BiFunction + metricReaderCustomizer, BiFunction metricExporterCustomizer, List closeables) { @@ -85,7 +90,12 @@ static List configureMetricReaders( .map( exporterName -> MetricExporterConfiguration.configureReader( - exporterName, config, spiHelper, metricExporterCustomizer, closeables)) + exporterName, + config, + spiHelper, + metricReaderCustomizer, + metricExporterCustomizer, + closeables)) .collect(Collectors.toList()); } diff --git a/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/MetricExporterConfiguration.java b/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/MetricExporterConfiguration.java index 2aa968a82bb..3b4a1da1658 100644 --- a/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/MetricExporterConfiguration.java +++ b/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/MetricExporterConfiguration.java @@ -42,6 +42,8 @@ static MetricReader configureReader( String name, ConfigProperties config, SpiHelper spiHelper, + BiFunction + metricReaderCustomizer, BiFunction metricExporterCustomizer, List closeables) { @@ -56,7 +58,14 @@ static MetricReader configureReader( MetricReader metricReader = configureMetricReader(name, spiMetricReadersManager); if (metricReader != null) { closeables.add(metricReader); - return metricReader; + + // Customize metric reader + MetricReader customizedMetricReader = metricReaderCustomizer.apply(metricReader, config); + if (customizedMetricReader != metricReader) { + closeables.add(customizedMetricReader); + } + + return customizedMetricReader; } // No exporter or reader with the name throw new ConfigurationException("Unrecognized value for otel.metrics.exporter: " + name); @@ -74,7 +83,11 @@ static MetricReader configureReader( .setInterval(config.getDuration("otel.metric.export.interval", DEFAULT_EXPORT_INTERVAL)) .build(); closeables.add(reader); - return reader; + MetricReader customizedMetricReader = metricReaderCustomizer.apply(reader, config); + if (customizedMetricReader != reader) { + closeables.add(customizedMetricReader); + } + return customizedMetricReader; } // Visible for testing diff --git a/sdk-extensions/autoconfigure/src/test/java/io/opentelemetry/sdk/autoconfigure/MeterProviderConfigurationTest.java b/sdk-extensions/autoconfigure/src/test/java/io/opentelemetry/sdk/autoconfigure/MeterProviderConfigurationTest.java index c501d28e3cb..900ba509d71 100644 --- a/sdk-extensions/autoconfigure/src/test/java/io/opentelemetry/sdk/autoconfigure/MeterProviderConfigurationTest.java +++ b/sdk-extensions/autoconfigure/src/test/java/io/opentelemetry/sdk/autoconfigure/MeterProviderConfigurationTest.java @@ -54,6 +54,7 @@ private static ObjectAssert assertExemplarFilter(Map a, + (a, b) -> a, new ArrayList<>()); return assertThat(builder) .extracting("exemplarFilter", as(InstanceOfAssertFactories.type(ExemplarFilter.class))); diff --git a/sdk-extensions/autoconfigure/src/testFullConfig/java/io/opentelemetry/sdk/autoconfigure/AutoConfiguredOpenTelemetrySdkTest.java b/sdk-extensions/autoconfigure/src/testFullConfig/java/io/opentelemetry/sdk/autoconfigure/AutoConfiguredOpenTelemetrySdkTest.java index 6bf5c74ccc5..f1f880441e6 100644 --- a/sdk-extensions/autoconfigure/src/testFullConfig/java/io/opentelemetry/sdk/autoconfigure/AutoConfiguredOpenTelemetrySdkTest.java +++ b/sdk-extensions/autoconfigure/src/testFullConfig/java/io/opentelemetry/sdk/autoconfigure/AutoConfiguredOpenTelemetrySdkTest.java @@ -5,12 +5,16 @@ package io.opentelemetry.sdk.autoconfigure; +import static java.util.Collections.singletonMap; import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatCode; +import com.linecorp.armeria.client.WebClient; import io.github.netmikey.logunit.api.LogCapturer; import io.opentelemetry.api.GlobalOpenTelemetry; import io.opentelemetry.api.OpenTelemetry; import io.opentelemetry.api.events.GlobalEventEmitterProvider; +import io.opentelemetry.exporter.prometheus.PrometheusHttpServer; import io.opentelemetry.sdk.OpenTelemetrySdk; import java.lang.reflect.Field; import org.junit.jupiter.api.BeforeEach; @@ -31,6 +35,25 @@ void setUp() { GlobalEventEmitterProvider.resetForTest(); } + @SuppressWarnings("ResultOfMethodCallIgnored") + @Test + void build_addMetricReaderCustomizerPrometheus() { + AutoConfiguredOpenTelemetrySdkBuilder builder = AutoConfiguredOpenTelemetrySdk.builder(); + builder.addPropertiesSupplier(() -> singletonMap("otel.metrics.exporter", "prometheus")); + + int port = FreePortFinder.getFreePort(); + builder.addMetricReaderCustomizer( + (reader, config) -> { + assertThat(reader).isInstanceOf(PrometheusHttpServer.class); + return PrometheusHttpServer.builder().setPort(port).build(); + }); + + try (OpenTelemetrySdk ignored = builder.build().getOpenTelemetrySdk()) { + WebClient client = WebClient.builder("http://localhost:" + port).build(); + assertThatCode(() -> client.get("/metrics")).doesNotThrowAnyException(); + } + } + @Test void initializeAndGet() { try (OpenTelemetrySdk sdk = AutoConfiguredOpenTelemetrySdk.initialize().getOpenTelemetrySdk()) { diff --git a/sdk-extensions/autoconfigure/src/testFullConfig/java/io/opentelemetry/sdk/autoconfigure/ConfigurableMetricExporterTest.java b/sdk-extensions/autoconfigure/src/testFullConfig/java/io/opentelemetry/sdk/autoconfigure/ConfigurableMetricExporterTest.java index 18797f0058b..bc32ebc84a4 100644 --- a/sdk-extensions/autoconfigure/src/testFullConfig/java/io/opentelemetry/sdk/autoconfigure/ConfigurableMetricExporterTest.java +++ b/sdk-extensions/autoconfigure/src/testFullConfig/java/io/opentelemetry/sdk/autoconfigure/ConfigurableMetricExporterTest.java @@ -87,7 +87,7 @@ void configureMetricReaders_multipleWithNone() { assertThatThrownBy( () -> MeterProviderConfiguration.configureMetricReaders( - config, spiHelper, (a, unused) -> a, closeables)) + config, spiHelper, (a, unused) -> a, (a, unused) -> a, closeables)) .isInstanceOf(ConfigurationException.class) .hasMessageContaining("otel.metrics.exporter contains none along with other exporters"); cleanup.addCloseables(closeables); @@ -102,7 +102,11 @@ void configureMetricReaders_defaultExporter() { List metricReaders = MeterProviderConfiguration.configureMetricReaders( - config, spiHelper, (metricExporter, unused) -> metricExporter, closeables); + config, + spiHelper, + (a, unused) -> a, + (metricExporter, unused) -> metricExporter, + closeables); cleanup.addCloseables(closeables); assertThat(metricReaders) @@ -125,7 +129,11 @@ void configureMetricReaders_multipleExporters() { List metricReaders = MeterProviderConfiguration.configureMetricReaders( - config, spiHelper, (metricExporter, unused) -> metricExporter, closeables); + config, + spiHelper, + (a, unused) -> a, + (metricExporter, unused) -> metricExporter, + closeables); cleanup.addCloseables(closeables); assertThat(metricReaders).hasSize(2).hasOnlyElementsOfType(PeriodicMetricReader.class); diff --git a/sdk-extensions/autoconfigure/src/testFullConfig/java/io/opentelemetry/sdk/autoconfigure/FreePortFinder.java b/sdk-extensions/autoconfigure/src/testFullConfig/java/io/opentelemetry/sdk/autoconfigure/FreePortFinder.java new file mode 100644 index 00000000000..92c2b7640c7 --- /dev/null +++ b/sdk-extensions/autoconfigure/src/testFullConfig/java/io/opentelemetry/sdk/autoconfigure/FreePortFinder.java @@ -0,0 +1,22 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.sdk.autoconfigure; + +import java.io.IOException; +import java.net.ServerSocket; + +final class FreePortFinder { + + static int getFreePort() { + try (ServerSocket socket = new ServerSocket(0)) { + return socket.getLocalPort(); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + + private FreePortFinder() {} +} diff --git a/sdk-extensions/autoconfigure/src/testFullConfig/java/io/opentelemetry/sdk/autoconfigure/MeterProviderConfigurationTest.java b/sdk-extensions/autoconfigure/src/testFullConfig/java/io/opentelemetry/sdk/autoconfigure/MeterProviderConfigurationTest.java index c5df15c73bb..b2062c20dd5 100644 --- a/sdk-extensions/autoconfigure/src/testFullConfig/java/io/opentelemetry/sdk/autoconfigure/MeterProviderConfigurationTest.java +++ b/sdk-extensions/autoconfigure/src/testFullConfig/java/io/opentelemetry/sdk/autoconfigure/MeterProviderConfigurationTest.java @@ -50,6 +50,7 @@ void configureMeterProvider_InvalidCardinalityLimit() { "0")), spiHelper, (a, b) -> a, + (a, b) -> a, closeables); }) .isInstanceOf(ConfigurationException.class) @@ -69,6 +70,7 @@ void configureMeterProvider_ConfiguresCardinalityLimit() { Collections.singletonMap("otel.metrics.exporter", "logging")), spiHelper, (a, b) -> a, + (a, b) -> a, closeables); cleanup.addCloseables(closeables); assertCardinalityLimit(builder, 2000); @@ -85,6 +87,7 @@ void configureMeterProvider_ConfiguresCardinalityLimit() { "100")), spiHelper, (a, b) -> a, + (a, b) -> a, closeables); cleanup.addCloseables(closeables); assertCardinalityLimit(builder, 100); diff --git a/sdk-extensions/autoconfigure/src/testFullConfig/java/io/opentelemetry/sdk/autoconfigure/MetricExporterConfigurationTest.java b/sdk-extensions/autoconfigure/src/testFullConfig/java/io/opentelemetry/sdk/autoconfigure/MetricExporterConfigurationTest.java index 6db4b23f82e..c8bd0937e63 100644 --- a/sdk-extensions/autoconfigure/src/testFullConfig/java/io/opentelemetry/sdk/autoconfigure/MetricExporterConfigurationTest.java +++ b/sdk-extensions/autoconfigure/src/testFullConfig/java/io/opentelemetry/sdk/autoconfigure/MetricExporterConfigurationTest.java @@ -5,6 +5,7 @@ package io.opentelemetry.sdk.autoconfigure; +import static org.assertj.core.api.Assertions.as; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; @@ -21,11 +22,16 @@ import io.opentelemetry.sdk.autoconfigure.spi.internal.DefaultConfigProperties; import io.opentelemetry.sdk.metrics.export.MetricExporter; import io.opentelemetry.sdk.metrics.export.MetricReader; +import io.opentelemetry.sdk.metrics.export.PeriodicMetricReader; +import io.prometheus.metrics.exporter.httpserver.HTTPServer; import java.io.Closeable; +import java.time.Duration; import java.util.ArrayList; import java.util.Collections; import java.util.List; +import java.util.function.BiFunction; import java.util.stream.Stream; +import org.assertj.core.api.InstanceOfAssertFactories; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.RegisterExtension; import org.junit.jupiter.params.ParameterizedTest; @@ -49,13 +55,55 @@ void configureReader_PrometheusOnClasspath() { MetricReader reader = MetricExporterConfiguration.configureReader( - "prometheus", CONFIG_PROPERTIES, spiHelper, (a, b) -> a, closeables); + "prometheus", CONFIG_PROPERTIES, spiHelper, (a, b) -> a, (a, b) -> a, closeables); cleanup.addCloseables(closeables); assertThat(reader).isInstanceOf(PrometheusHttpServer.class); assertThat(closeables).hasSize(1); } + @Test + void configureReader_customizeReader_prometheus() { + List closeables = new ArrayList<>(); + + int port = FreePortFinder.getFreePort(); + BiFunction readerCustomizer = + (existingReader, config) -> PrometheusHttpServer.builder().setPort(port).build(); + MetricReader reader = + MetricExporterConfiguration.configureReader( + "prometheus", CONFIG_PROPERTIES, spiHelper, readerCustomizer, (a, b) -> a, closeables); + cleanup.addCloseables(closeables); + + assertThat(reader).isInstanceOf(PrometheusHttpServer.class); + assertThat(closeables).hasSize(2); + PrometheusHttpServer prometheusHttpServer = (PrometheusHttpServer) reader; + assertThat(prometheusHttpServer) + .extracting("httpServer", as(InstanceOfAssertFactories.type(HTTPServer.class))) + .satisfies(httpServer -> assertThat(httpServer.getPort()).isEqualTo(port)); + } + + @Test + void configureReader_customizeReader_otlp() { + List closeables = new ArrayList<>(); + + BiFunction readerCustomizer = + (existingReader, config) -> + PeriodicMetricReader.builder(OtlpGrpcMetricExporter.builder().build()) + .setInterval(Duration.ofSeconds(123)) + .build(); + MetricReader reader = + MetricExporterConfiguration.configureReader( + "otlp", CONFIG_PROPERTIES, spiHelper, readerCustomizer, (a, b) -> a, closeables); + cleanup.addCloseables(closeables); + + assertThat(reader).isInstanceOf(PeriodicMetricReader.class); + assertThat(closeables).hasSize(3); + PeriodicMetricReader periodicMetricReader = (PeriodicMetricReader) reader; + assertThat(periodicMetricReader) + .extracting("intervalNanos") + .isEqualTo(Duration.ofSeconds(123).toNanos()); + } + @ParameterizedTest @MethodSource("knownExporters") void configureExporter_KnownSpiExportersOnClasspath( From 25afc3e91080ea5099cb5a6a49492c38a38c0529 Mon Sep 17 00:00:00 2001 From: Liudmila Molkova Date: Wed, 6 Mar 2024 06:40:28 -0800 Subject: [PATCH 271/901] Return AutoConfiguredOpenTelemetrySdkBuilder instead of the base type (#6248) --- CHANGELOG.md | 2 + .../otel.japicmp-conventions.gradle.kts | 61 +++++++++++++++---- ...ntelemetry-sdk-extension-autoconfigure.txt | 3 +- ...AutoConfiguredOpenTelemetrySdkBuilder.java | 2 +- 4 files changed, 55 insertions(+), 13 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 24107bd6685..47819262098 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -64,6 +64,8 @@ instead. * Autoconfigure accepts encoded header values for OTLP exporters ([#6164](https://github.com/open-telemetry/opentelemetry-java/pull/6164)) +* Return implementation type from `AutoConfiguredOpenTelemetrySdkBuilder.addLogRecordProcessorCustomizer` + ([#6248](https://github.com/open-telemetry/opentelemetry-java/pull/6248)) #### Incubator diff --git a/buildSrc/src/main/kotlin/otel.japicmp-conventions.gradle.kts b/buildSrc/src/main/kotlin/otel.japicmp-conventions.gradle.kts index c720b307486..2aa0a0f5a69 100644 --- a/buildSrc/src/main/kotlin/otel.japicmp-conventions.gradle.kts +++ b/buildSrc/src/main/kotlin/otel.japicmp-conventions.gradle.kts @@ -1,16 +1,8 @@ import com.google.auto.value.AutoValue -import japicmp.model.JApiChangeStatus -import japicmp.model.JApiClass -import japicmp.model.JApiCompatibility -import japicmp.model.JApiCompatibilityChange -import japicmp.model.JApiMethod +import japicmp.model.* import me.champeau.gradle.japicmp.JapicmpTask import me.champeau.gradle.japicmp.report.Violation -import me.champeau.gradle.japicmp.report.stdrules.AbstractRecordingSeenMembers -import me.champeau.gradle.japicmp.report.stdrules.BinaryIncompatibleRule -import me.champeau.gradle.japicmp.report.stdrules.RecordSeenMembersSetup -import me.champeau.gradle.japicmp.report.stdrules.SourceCompatibleRule -import me.champeau.gradle.japicmp.report.stdrules.UnchangedMemberRule +import me.champeau.gradle.japicmp.report.stdrules.* plugins { @@ -52,9 +44,56 @@ class AllowNewAbstractMethodOnAutovalueClasses : AbstractRecordingSeenMembers() } class SourceIncompatibleRule : AbstractRecordingSeenMembers() { + + fun ignoreAddLogRecordProcessorCustomizerReturnTypeChange(member: JApiCompatibility): Violation? { + if (member is JApiClass && + member.newClass.get().name.equals("io.opentelemetry.sdk.autoconfigure.AutoConfiguredOpenTelemetrySdkBuilder") && + member.isChangeCausedByClassElement + ) { + // member.isChangeCausedByClassElement check above + // limits source of changes to fields, methods and constructors + + for (method in member.methods) { + if (!method.isSourceCompatible()) { + // addLogRecordProcessorCustomizer method had a return type change from base to impl class, + // japicmp (correctly) doesn't consider it as a METHOD_RETURN_TYPE_CHANGED + // compatibility issue. But still thinks that something wrong. + // Since it thinks that method did not change, it reports it as class-level violation, + // and we need to suppress it, but keep other checks on. + if (method.name.equals("addLogRecordProcessorCustomizer") && + method.compatibilityChanges.isEmpty() && + method.changeStatus == JApiChangeStatus.UNCHANGED) { + return null; + } + return Violation.error(method, "Method is not source compatible: $method") + } + } + + for (field in member.fields) { + if (!field.isSourceCompatible()) { + return Violation.error(field, "Field is not source compatible: $field") + } + } + + for (constructor in member.constructors) { + if (!constructor.isSourceCompatible()) { + return Violation.error(constructor, "Constructor is not source compatible: $constructor") + } + } + } + + return Violation.error(member, "Not source compatible: $member") + } + override fun maybeAddViolation(member: JApiCompatibility): Violation? { if (!member.isSourceCompatible()) { - return Violation.error(member, "Not source compatible") + // TODO: remove after 1.36.0 is released, see https://github.com/open-telemetry/opentelemetry-java/pull/6248 + if (member.compatibilityChanges.isEmpty()) { + return ignoreAddLogRecordProcessorCustomizerReturnTypeChange(member) + } + // end of suppression + + return Violation.error(member, "Not source compatible: $member") } return null } diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-extension-autoconfigure.txt b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-extension-autoconfigure.txt index 04f3e512be6..f9bf6463d2c 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-extension-autoconfigure.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-extension-autoconfigure.txt @@ -1,4 +1,5 @@ Comparing source compatibility of against -*** MODIFIED CLASS: PUBLIC FINAL io.opentelemetry.sdk.autoconfigure.AutoConfiguredOpenTelemetrySdkBuilder (not serializable) +**** MODIFIED CLASS: PUBLIC FINAL io.opentelemetry.sdk.autoconfigure.AutoConfiguredOpenTelemetrySdkBuilder (not serializable) === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 + ===* UNCHANGED METHOD: PUBLIC SYNTHETIC (<- NON_SYNTHETIC) BRIDGE (<- NON_BRIDGE) io.opentelemetry.sdk.autoconfigure.spi.AutoConfigurationCustomizer addLogRecordProcessorCustomizer(java.util.function.BiFunction(<- )) +++ NEW METHOD: PUBLIC(+) io.opentelemetry.sdk.autoconfigure.AutoConfiguredOpenTelemetrySdkBuilder addMetricReaderCustomizer(java.util.function.BiFunction) diff --git a/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/AutoConfiguredOpenTelemetrySdkBuilder.java b/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/AutoConfiguredOpenTelemetrySdkBuilder.java index ac9d39a2a71..50604716f79 100644 --- a/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/AutoConfiguredOpenTelemetrySdkBuilder.java +++ b/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/AutoConfiguredOpenTelemetrySdkBuilder.java @@ -344,7 +344,7 @@ public AutoConfiguredOpenTelemetrySdkBuilder addLogRecordExporterCustomizer( *

    Multiple calls will execute the customizers in order. */ @Override - public AutoConfigurationCustomizer addLogRecordProcessorCustomizer( + public AutoConfiguredOpenTelemetrySdkBuilder addLogRecordProcessorCustomizer( BiFunction logRecordProcessorCustomizer) { requireNonNull(logRecordProcessorCustomizer, "logRecordProcessorCustomizer"); From 9f8ed8468a077798eeac96916a2a36e87c18f45d Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 6 Mar 2024 08:55:24 -0600 Subject: [PATCH 272/901] Update dependency com.uber.nullaway:nullaway to v0.10.24 (#6269) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- dependencyManagement/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index 655f3ec10d2..0cb136dfe63 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -60,7 +60,7 @@ val DEPENDENCIES = listOf( "com.google.guava:guava-beta-checker:1.0", "com.sun.net.httpserver:http:20070405", "com.tngtech.archunit:archunit-junit5:1.2.1", - "com.uber.nullaway:nullaway:0.10.23", + "com.uber.nullaway:nullaway:0.10.24", "edu.berkeley.cs.jqf:jqf-fuzz:1.7", // jqf-fuzz version 1.8+ requires Java 11+ "eu.rekawek.toxiproxy:toxiproxy-java:2.1.7", "io.github.netmikey.logunit:logunit-jul:2.0.0", From ff179ddc6b6a09e0c09672d25026099f3bcff905 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 6 Mar 2024 08:55:39 -0600 Subject: [PATCH 273/901] Update dependency nl.jqno.equalsverifier:equalsverifier to v3.15.8 (#6267) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- dependencyManagement/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index 0cb136dfe63..c48d3cd80b7 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -71,7 +71,7 @@ val DEPENDENCIES = listOf( "io.opentracing:opentracing-noop:0.33.0", "io.prometheus:prometheus-metrics-exporter-httpserver:1.1.0", "junit:junit:4.13.2", - "nl.jqno.equalsverifier:equalsverifier:3.15.7", + "nl.jqno.equalsverifier:equalsverifier:3.15.8", "org.awaitility:awaitility:4.2.0", "org.bouncycastle:bcpkix-jdk15on:1.70", "org.codehaus.mojo:animal-sniffer-annotations:1.23", From 12d3e0f1f0ae0542a501cce930fc742a495a04ee Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 6 Mar 2024 08:55:56 -0600 Subject: [PATCH 274/901] Update dependency io.zipkin.brave:brave-bom to v6.0.2 (#6259) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- dependencyManagement/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index c48d3cd80b7..3cadb50e2e7 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -16,7 +16,7 @@ val DEPENDENCY_BOMS = listOf( "com.squareup.okio:okio-bom:3.8.0", // applies to transitive dependencies of okhttp "io.grpc:grpc-bom:1.61.1", "io.netty:netty-bom:4.1.107.Final", - "io.zipkin.brave:brave-bom:6.0.1", + "io.zipkin.brave:brave-bom:6.0.2", "io.zipkin.reporter2:zipkin-reporter-bom:3.3.0", "org.assertj:assertj-bom:3.25.3", "org.junit:junit-bom:5.10.2", From 601d2885ff77665a8522643f77f1f30afa0e3841 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 6 Mar 2024 08:56:15 -0600 Subject: [PATCH 275/901] Update dependency com.google.api.grpc:proto-google-common-protos to v2.36.0 (#6265) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- dependencyManagement/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index 3cadb50e2e7..7581c0b4852 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -55,7 +55,7 @@ val DEPENDENCIES = listOf( "io.prometheus:simpleclient_httpserver:${prometheusClientVersion}", "javax.annotation:javax.annotation-api:1.3.2", "com.github.stefanbirkner:system-rules:1.19.0", - "com.google.api.grpc:proto-google-common-protos:2.34.0", + "com.google.api.grpc:proto-google-common-protos:2.36.0", "com.google.code.findbugs:jsr305:3.0.2", "com.google.guava:guava-beta-checker:1.0", "com.sun.net.httpserver:http:20070405", From 5ef2cb95739245b6d31d9f3084334af912f56989 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 6 Mar 2024 08:56:30 -0600 Subject: [PATCH 276/901] Update dependency checkstyle to v10.14.0 (#6261) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- buildSrc/src/main/kotlin/otel.java-conventions.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/buildSrc/src/main/kotlin/otel.java-conventions.gradle.kts b/buildSrc/src/main/kotlin/otel.java-conventions.gradle.kts index 0d2582b2e78..9a75d525dc6 100644 --- a/buildSrc/src/main/kotlin/otel.java-conventions.gradle.kts +++ b/buildSrc/src/main/kotlin/otel.java-conventions.gradle.kts @@ -35,7 +35,7 @@ java { checkstyle { configDirectory.set(file("$rootDir/buildscripts/")) - toolVersion = "10.13.0" + toolVersion = "10.14.0" isIgnoreFailures = false configProperties["rootDir"] = rootDir } From 5eeb733dbdc9b5c39ef0a51cbf91bdf9d3f4dc39 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 6 Mar 2024 08:56:48 -0600 Subject: [PATCH 277/901] Update dependency com.linecorp.armeria:armeria-bom to v1.27.2 (#6249) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- dependencyManagement/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index 7581c0b4852..0484b2cd4c0 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -11,7 +11,7 @@ val DEPENDENCY_BOMS = listOf( "com.fasterxml.jackson:jackson-bom:2.16.1", "com.google.guava:guava-bom:33.0.0-jre", "com.google.protobuf:protobuf-bom:3.25.3", - "com.linecorp.armeria:armeria-bom:1.27.1", + "com.linecorp.armeria:armeria-bom:1.27.2", "com.squareup.okhttp3:okhttp-bom:4.12.0", "com.squareup.okio:okio-bom:3.8.0", // applies to transitive dependencies of okhttp "io.grpc:grpc-bom:1.61.1", From 56c11e529e221da68a7aaaee7946247e78c2a35e Mon Sep 17 00:00:00 2001 From: Gregor Zeitlinger Date: Wed, 6 Mar 2024 15:57:52 +0100 Subject: [PATCH 278/901] add ComponentLoader to support more auto configuration scenarios (#6217) --- .../otel.japicmp-conventions.gradle.kts | 2 + ...AutoConfiguredOpenTelemetrySdkBuilder.java | 28 ++++++++++- .../TracerProviderConfiguration.java | 17 +++---- .../internal/AutoConfigureUtil.java | 36 ++++++++++++++ .../internal/ComponentLoader.java | 23 +++++++++ .../sdk/autoconfigure/internal/SpiHelper.java | 32 ++++++++----- .../AutoConfiguredOpenTelemetrySdkTest.java | 48 +++++++++++++++++++ .../autoconfigure/internal/SpiHelperTest.java | 32 ++++++------- 8 files changed, 180 insertions(+), 38 deletions(-) create mode 100644 sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/internal/ComponentLoader.java diff --git a/buildSrc/src/main/kotlin/otel.japicmp-conventions.gradle.kts b/buildSrc/src/main/kotlin/otel.japicmp-conventions.gradle.kts index 2aa0a0f5a69..3c420e1719a 100644 --- a/buildSrc/src/main/kotlin/otel.japicmp-conventions.gradle.kts +++ b/buildSrc/src/main/kotlin/otel.japicmp-conventions.gradle.kts @@ -154,6 +154,8 @@ if (!project.hasProperty("otel.release") && !project.name.startsWith("bom")) { // Reproduce defaults from https://github.com/melix/japicmp-gradle-plugin/blob/09f52739ef1fccda6b4310cf3f4b19dc97377024/src/main/java/me/champeau/gradle/japicmp/report/ViolationsGenerator.java#L130 // with some changes. val exclusions = mutableListOf() + // Generics are not detected correctly + exclusions.add("CLASS_GENERIC_TEMPLATE_CHANGED") // Allow new default methods on interfaces exclusions.add("METHOD_NEW_DEFAULT") // Allow adding default implementations for default methods diff --git a/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/AutoConfiguredOpenTelemetrySdkBuilder.java b/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/AutoConfiguredOpenTelemetrySdkBuilder.java index 50604716f79..fe9d75adae3 100644 --- a/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/AutoConfiguredOpenTelemetrySdkBuilder.java +++ b/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/AutoConfiguredOpenTelemetrySdkBuilder.java @@ -13,6 +13,7 @@ import io.opentelemetry.context.propagation.TextMapPropagator; import io.opentelemetry.sdk.OpenTelemetrySdk; import io.opentelemetry.sdk.OpenTelemetrySdkBuilder; +import io.opentelemetry.sdk.autoconfigure.internal.ComponentLoader; import io.opentelemetry.sdk.autoconfigure.internal.SpiHelper; import io.opentelemetry.sdk.autoconfigure.spi.AutoConfigurationCustomizer; import io.opentelemetry.sdk.autoconfigure.spi.AutoConfigurationCustomizerProvider; @@ -102,6 +103,9 @@ public final class AutoConfiguredOpenTelemetrySdkBuilder implements AutoConfigur private final List>> propertiesCustomizers = new ArrayList<>(); + private Function configPropertiesCustomizer = + Function.identity(); + private SpiHelper spiHelper = SpiHelper.create(AutoConfiguredOpenTelemetrySdk.class.getClassLoader()); @@ -253,6 +257,21 @@ public AutoConfiguredOpenTelemetrySdkBuilder addPropertiesCustomizer( return this; } + /** + * Adds a {@link Function} to invoke the with the {@link ConfigProperties} to allow customization. + * + *

    The argument to the function is the {@link ConfigProperties}, with the {@link + * #addPropertiesCustomizer(Function)} already applied. + * + *

    The return value of the {@link Function} replace the {@link ConfigProperties} to be used. + */ + AutoConfiguredOpenTelemetrySdkBuilder setConfigPropertiesCustomizer( + Function configPropertiesCustomizer) { + requireNonNull(configPropertiesCustomizer, "configPropertiesCustomizer"); + this.configPropertiesCustomizer = configPropertiesCustomizer; + return this; + } + /** * Adds a {@link BiFunction} to invoke the with the {@link SdkMeterProviderBuilder} to allow * customization. The return value of the {@link BiFunction} will replace the passed-in argument. @@ -385,6 +404,13 @@ public AutoConfiguredOpenTelemetrySdkBuilder setServiceClassLoader( return this; } + /** Sets the {@link ComponentLoader} to be used to load SPI implementations. */ + AutoConfiguredOpenTelemetrySdkBuilder setComponentLoader(ComponentLoader componentLoader) { + requireNonNull(componentLoader, "componentLoader"); + this.spiHelper = SpiHelper.create(componentLoader); + return this; + } + /** * Returns a new {@link AutoConfiguredOpenTelemetrySdk} holding components auto-configured using * the settings of this {@link AutoConfiguredOpenTelemetrySdkBuilder}. @@ -590,7 +616,7 @@ private ConfigProperties computeConfigProperties() { Map overrides = customizer.apply(properties); properties = properties.withOverrides(overrides); } - return properties; + return configPropertiesCustomizer.apply(properties); } // Visible for testing diff --git a/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/TracerProviderConfiguration.java b/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/TracerProviderConfiguration.java index 1241acccc8d..b2e2a3858c8 100644 --- a/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/TracerProviderConfiguration.java +++ b/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/TracerProviderConfiguration.java @@ -173,21 +173,13 @@ static Sampler configureSampler(String sampler, ConfigProperties config, SpiHelp case "always_off": return Sampler.alwaysOff(); case "traceidratio": - { - double ratio = - config.getDouble("otel.traces.sampler.arg", DEFAULT_TRACEIDRATIO_SAMPLE_RATIO); - return Sampler.traceIdRatioBased(ratio); - } + return ratioSampler(config); case PARENTBASED_ALWAYS_ON: return Sampler.parentBased(Sampler.alwaysOn()); case "parentbased_always_off": return Sampler.parentBased(Sampler.alwaysOff()); case "parentbased_traceidratio": - { - double ratio = - config.getDouble("otel.traces.sampler.arg", DEFAULT_TRACEIDRATIO_SAMPLE_RATIO); - return Sampler.parentBased(Sampler.traceIdRatioBased(ratio)); - } + return Sampler.parentBased(ratioSampler(config)); case "parentbased_jaeger_remote": Sampler jaegerRemote = spiSamplersManager.getByName("jaeger_remote"); if (jaegerRemote == null) { @@ -205,5 +197,10 @@ static Sampler configureSampler(String sampler, ConfigProperties config, SpiHelp } } + private static Sampler ratioSampler(ConfigProperties config) { + double ratio = config.getDouble("otel.traces.sampler.arg", DEFAULT_TRACEIDRATIO_SAMPLE_RATIO); + return Sampler.traceIdRatioBased(ratio); + } + private TracerProviderConfiguration() {} } diff --git a/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/internal/AutoConfigureUtil.java b/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/internal/AutoConfigureUtil.java index e77620fc49a..8a50d782031 100644 --- a/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/internal/AutoConfigureUtil.java +++ b/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/internal/AutoConfigureUtil.java @@ -6,9 +6,11 @@ package io.opentelemetry.sdk.autoconfigure.internal; import io.opentelemetry.sdk.autoconfigure.AutoConfiguredOpenTelemetrySdk; +import io.opentelemetry.sdk.autoconfigure.AutoConfiguredOpenTelemetrySdkBuilder; import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; +import java.util.function.Function; /** * This class is internal and is hence not for public use. Its APIs are unstable and can change at @@ -30,4 +32,38 @@ public static ConfigProperties getConfig( "Error calling getConfig on AutoConfiguredOpenTelemetrySdk", e); } } + + /** Sets the {@link ComponentLoader} to be used in the auto-configuration process. */ + public static AutoConfiguredOpenTelemetrySdkBuilder setComponentLoader( + AutoConfiguredOpenTelemetrySdkBuilder builder, ComponentLoader componentLoader) { + try { + Method method = + AutoConfiguredOpenTelemetrySdkBuilder.class.getDeclaredMethod( + "setComponentLoader", ComponentLoader.class); + method.setAccessible(true); + method.invoke(builder, componentLoader); + return builder; + } catch (NoSuchMethodException | InvocationTargetException | IllegalAccessException e) { + throw new IllegalStateException( + "Error calling setComponentLoader on AutoConfiguredOpenTelemetrySdkBuilder", e); + } + } + + /** Sets the {@link ConfigProperties} customizer to be used in the auto-configuration process. */ + public static AutoConfiguredOpenTelemetrySdkBuilder setConfigPropertiesCustomizer( + AutoConfiguredOpenTelemetrySdkBuilder builder, + Function customizer) { + try { + Method method = + AutoConfiguredOpenTelemetrySdkBuilder.class.getDeclaredMethod( + "setConfigPropertiesCustomizer", Function.class); + method.setAccessible(true); + method.invoke(builder, customizer); + return builder; + } catch (NoSuchMethodException | InvocationTargetException | IllegalAccessException e) { + throw new IllegalStateException( + "Error calling setConfigPropertiesCustomizer on AutoConfiguredOpenTelemetrySdkBuilder", + e); + } + } } diff --git a/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/internal/ComponentLoader.java b/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/internal/ComponentLoader.java new file mode 100644 index 00000000000..49bfc4e52f2 --- /dev/null +++ b/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/internal/ComponentLoader.java @@ -0,0 +1,23 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.sdk.autoconfigure.internal; + +/** + * A loader for components that are discovered via SPI. + * + *

    This class is internal and is hence not for public use. Its APIs are unstable and can change + * at any time. + */ +public interface ComponentLoader { + /** + * Load implementations of an SPI. + * + * @param spiClass the SPI class + * @param the SPI type + * @return iterable of SPI implementations + */ + Iterable load(Class spiClass); +} diff --git a/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/internal/SpiHelper.java b/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/internal/SpiHelper.java index 4002ce65329..d54e526d44a 100644 --- a/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/internal/SpiHelper.java +++ b/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/internal/SpiHelper.java @@ -27,20 +27,22 @@ */ public final class SpiHelper { - private final ClassLoader classLoader; - private final SpiFinder spiFinder; + private final ComponentLoader componentLoader; private final Set listeners = Collections.newSetFromMap(new IdentityHashMap<>()); - // Visible for testing - SpiHelper(ClassLoader classLoader, SpiFinder spiFinder) { - this.classLoader = classLoader; - this.spiFinder = spiFinder; + private SpiHelper(ComponentLoader componentLoader) { + this.componentLoader = componentLoader; } /** Create a {@link SpiHelper} which loads SPIs using the {@code classLoader}. */ public static SpiHelper create(ClassLoader classLoader) { - return new SpiHelper(classLoader, ServiceLoader::load); + return new SpiHelper(new ServiceLoaderComponentLoader(classLoader)); + } + + /** Create a {@link SpiHelper} which loads SPIs using the {@code componentLoader}. */ + public static SpiHelper create(ComponentLoader componentLoader) { + return new SpiHelper(componentLoader); } /** @@ -96,7 +98,7 @@ public List loadOrdered(Class spiClass) { */ public List load(Class spiClass) { List result = new ArrayList<>(); - for (T service : spiFinder.load(spiClass, classLoader)) { + for (T service : componentLoader.load(spiClass)) { maybeAddListener(service); result.add(service); } @@ -114,8 +116,16 @@ public Set getListeners() { return Collections.unmodifiableSet(listeners); } - // Visible for testing - interface SpiFinder { - Iterable load(Class spiClass, ClassLoader classLoader); + private static class ServiceLoaderComponentLoader implements ComponentLoader { + private final ClassLoader classLoader; + + private ServiceLoaderComponentLoader(ClassLoader classLoader) { + this.classLoader = classLoader; + } + + @Override + public Iterable load(Class spiClass) { + return ServiceLoader.load(spiClass, classLoader); + } } } diff --git a/sdk-extensions/autoconfigure/src/test/java/io/opentelemetry/sdk/autoconfigure/AutoConfiguredOpenTelemetrySdkTest.java b/sdk-extensions/autoconfigure/src/test/java/io/opentelemetry/sdk/autoconfigure/AutoConfiguredOpenTelemetrySdkTest.java index 01047907fca..5e8ea677c7f 100644 --- a/sdk-extensions/autoconfigure/src/test/java/io/opentelemetry/sdk/autoconfigure/AutoConfiguredOpenTelemetrySdkTest.java +++ b/sdk-extensions/autoconfigure/src/test/java/io/opentelemetry/sdk/autoconfigure/AutoConfiguredOpenTelemetrySdkTest.java @@ -20,6 +20,7 @@ import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verifyNoInteractions; +import static org.mockito.Mockito.verifyNoMoreInteractions; import static org.mockito.Mockito.when; import io.github.netmikey.logunit.api.LogCapturer; @@ -36,10 +37,14 @@ import io.opentelemetry.context.propagation.TextMapPropagator; import io.opentelemetry.internal.testing.slf4j.SuppressLogger; import io.opentelemetry.sdk.OpenTelemetrySdk; +import io.opentelemetry.sdk.autoconfigure.internal.AutoConfigureUtil; +import io.opentelemetry.sdk.autoconfigure.internal.ComponentLoader; import io.opentelemetry.sdk.autoconfigure.internal.SpiHelper; +import io.opentelemetry.sdk.autoconfigure.spi.AutoConfigurationCustomizerProvider; import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties; import io.opentelemetry.sdk.autoconfigure.spi.ConfigurationException; import io.opentelemetry.sdk.autoconfigure.spi.internal.AutoConfigureListener; +import io.opentelemetry.sdk.autoconfigure.spi.internal.DefaultConfigProperties; import io.opentelemetry.sdk.common.CompletableResultCode; import io.opentelemetry.sdk.logs.LogRecordProcessor; import io.opentelemetry.sdk.logs.SdkLoggerProvider; @@ -315,6 +320,32 @@ void builder_addSpanProcessorCustomizer() { verifyNoInteractions(spanExporter1); } + @Test + void builder_addAutoConfigurationCustomizerProviderUsingComponentLoader() { + AutoConfigurationCustomizerProvider customizerProvider = + mock(AutoConfigurationCustomizerProvider.class); + + SpiHelper spiHelper = + SpiHelper.create(AutoConfiguredOpenTelemetrySdkBuilder.class.getClassLoader()); + + AutoConfigureUtil.setComponentLoader( + builder, + new ComponentLoader() { + @SuppressWarnings("unchecked") + @Override + public Iterable load(Class spiClass) { + if (spiClass.equals(AutoConfigurationCustomizerProvider.class)) { + return Collections.singletonList((T) customizerProvider); + } + return spiHelper.load(spiClass); + } + }) + .build(); + + verify(customizerProvider).customize(any()); + verifyNoMoreInteractions(customizerProvider); + } + @Test void builder_addPropertiesSupplier() { AutoConfiguredOpenTelemetrySdk autoConfigured = @@ -356,6 +387,23 @@ void builder_addPropertiesCustomizer() { assertThat(autoConfigured.getConfig().getString("some.key")).isEqualTo("override-2"); } + @Test + void builder_setConfigPropertiesCustomizer() { + AutoConfiguredOpenTelemetrySdk autoConfigured = + AutoConfigureUtil.setConfigPropertiesCustomizer( + builder.addPropertiesCustomizer(config -> singletonMap("some-key", "defaultValue")), + config -> { + assertThat(config.getString("some-key")).isEqualTo("defaultValue"); + + Map map = new HashMap<>(singletonMap("some-key", "override")); + map.putAll(disableExportPropertySupplier().get()); + return DefaultConfigProperties.createFromMap(map); + }) + .build(); + + assertThat(autoConfigured.getConfig().getString("some.key")).isEqualTo("override"); + } + @Test void builder_addMeterProviderCustomizer() { Mockito.lenient().when(metricReader.shutdown()).thenReturn(CompletableResultCode.ofSuccess()); diff --git a/sdk-extensions/autoconfigure/src/test/java/io/opentelemetry/sdk/autoconfigure/internal/SpiHelperTest.java b/sdk-extensions/autoconfigure/src/test/java/io/opentelemetry/sdk/autoconfigure/internal/SpiHelperTest.java index a2d5c870d4b..ad7a96704e6 100644 --- a/sdk-extensions/autoconfigure/src/test/java/io/opentelemetry/sdk/autoconfigure/internal/SpiHelperTest.java +++ b/sdk-extensions/autoconfigure/src/test/java/io/opentelemetry/sdk/autoconfigure/internal/SpiHelperTest.java @@ -11,6 +11,7 @@ import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; +import static org.mockito.Mockito.spy; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @@ -28,11 +29,11 @@ public class SpiHelperTest { @Test public void canRetrieveByName() { - SpiHelper.SpiFinder mockFinder = mock(SpiHelper.SpiFinder.class); - when(mockFinder.load(any(), any())) + ComponentLoader mockLoader = spy(ComponentLoader.class); + when(mockLoader.load(any())) .thenReturn(Collections.singletonList(new SpiExampleProviderImplementation())); - SpiHelper spiHelper = new SpiHelper(SpiHelperTest.class.getClassLoader(), mockFinder); + SpiHelper spiHelper = SpiHelper.create(mockLoader); NamedSpiManager spiProvider = spiHelper.loadConfigurable( @@ -49,10 +50,10 @@ public void canRetrieveByName() { public void instantiatesImplementationsLazily() { SpiExampleProvider mockProvider = mock(SpiExampleProvider.class); when(mockProvider.getName()).thenReturn("lazy-init-example"); - SpiHelper.SpiFinder mockFinder = mock(SpiHelper.SpiFinder.class); - when(mockFinder.load(any(), any())).thenReturn(Collections.singletonList(mockProvider)); + ComponentLoader mockLoader = spy(ComponentLoader.class); + when(mockLoader.load(any())).thenReturn(Collections.singletonList(mockProvider)); - SpiHelper spiHelper = new SpiHelper(SpiHelperTest.class.getClassLoader(), mockFinder); + SpiHelper spiHelper = SpiHelper.create(mockLoader); NamedSpiManager spiProvider = spiHelper.loadConfigurable( @@ -68,11 +69,11 @@ public void instantiatesImplementationsLazily() { @Test public void onlyInstantiatesOnce() { - SpiHelper.SpiFinder mockFinder = mock(SpiHelper.SpiFinder.class); - when(mockFinder.load(any(), any())) + ComponentLoader mockLoader = mock(ComponentLoader.class); + when(mockLoader.load(any())) .thenReturn(Collections.singletonList(new SpiExampleProviderImplementation())); - SpiHelper spiHelper = new SpiHelper(SpiHelperTest.class.getClassLoader(), mockFinder); + SpiHelper spiHelper = SpiHelper.create(mockLoader); NamedSpiManager spiProvider = spiHelper.loadConfigurable( @@ -93,10 +94,10 @@ public void failureToInitializeThrows() { when(mockProvider.getName()).thenReturn("init-failure-example"); when(mockProvider.createSpiExample(any())).thenThrow(new RuntimeException()); - SpiHelper.SpiFinder mockFinder = mock(SpiHelper.SpiFinder.class); - when(mockFinder.load(any(), any())).thenReturn(Collections.singletonList(mockProvider)); + ComponentLoader mockLoader = spy(ComponentLoader.class); + when(mockLoader.load(any())).thenReturn(Collections.singletonList(mockProvider)); - SpiHelper spiHelper = new SpiHelper(SpiHelperTest.class.getClassLoader(), mockFinder); + SpiHelper spiHelper = SpiHelper.create(mockLoader); NamedSpiManager spiProvider = spiHelper.loadConfigurable( @@ -120,11 +121,10 @@ void loadsOrderedSpi() { when(spi2.order()).thenReturn(0); when(spi3.order()).thenReturn(1); - SpiHelper.SpiFinder mockFinder = mock(SpiHelper.SpiFinder.class); - when(mockFinder.load(ResourceProvider.class, SpiHelper.class.getClassLoader())) - .thenReturn(asList(spi1, spi2, spi3)); + ComponentLoader mockLoader = spy(ComponentLoader.class); + when(mockLoader.load(ResourceProvider.class)).thenReturn(asList(spi1, spi2, spi3)); - SpiHelper spiHelper = new SpiHelper(SpiHelperTest.class.getClassLoader(), mockFinder); + SpiHelper spiHelper = SpiHelper.create(mockLoader); List loadedSpi = spiHelper.loadOrdered(ResourceProvider.class); From 96bed03986217c5f8797ec5c7cab88a04f5134fe Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 6 Mar 2024 08:58:25 -0600 Subject: [PATCH 279/901] Update plugin de.undercouch.download to v5.6.0 (#6262) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- settings.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/settings.gradle.kts b/settings.gradle.kts index 66af6e31c49..2cdbc1038b1 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -2,7 +2,7 @@ pluginManagement { plugins { id("com.github.johnrengelman.shadow") version "8.1.1" id("com.gradle.enterprise") version "3.16.2" - id("de.undercouch.download") version "5.5.0" + id("de.undercouch.download") version "5.6.0" id("org.jsonschema2pojo") version "1.2.1" id("io.github.gradle-nexus.publish-plugin") version "1.3.0" id("org.graalvm.buildtools.native") version "0.10.1" From cd52950fae78c2880b5b0ed1e61672f54d41707a Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 6 Mar 2024 08:58:44 -0600 Subject: [PATCH 280/901] Update dependency io.grpc:grpc-bom to v1.62.2 (#6254) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- dependencyManagement/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index 0484b2cd4c0..5f345a37aea 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -14,7 +14,7 @@ val DEPENDENCY_BOMS = listOf( "com.linecorp.armeria:armeria-bom:1.27.2", "com.squareup.okhttp3:okhttp-bom:4.12.0", "com.squareup.okio:okio-bom:3.8.0", // applies to transitive dependencies of okhttp - "io.grpc:grpc-bom:1.61.1", + "io.grpc:grpc-bom:1.62.2", "io.netty:netty-bom:4.1.107.Final", "io.zipkin.brave:brave-bom:6.0.2", "io.zipkin.reporter2:zipkin-reporter-bom:3.3.0", From f24acbdd7fbf1f199872f54d25cf2ca2340816d6 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 6 Mar 2024 08:59:00 -0600 Subject: [PATCH 281/901] Update dependency org.testcontainers:testcontainers-bom to v1.19.7 (#6271) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- dependencyManagement/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index 5f345a37aea..69c01f9d356 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -20,7 +20,7 @@ val DEPENDENCY_BOMS = listOf( "io.zipkin.reporter2:zipkin-reporter-bom:3.3.0", "org.assertj:assertj-bom:3.25.3", "org.junit:junit-bom:5.10.2", - "org.testcontainers:testcontainers-bom:1.19.6", + "org.testcontainers:testcontainers-bom:1.19.7", "org.snakeyaml:snakeyaml-engine:2.7" ) From e41470be4366d4fadb2cf0f810441dda21ce6c5e Mon Sep 17 00:00:00 2001 From: jack-berg <34418638+jack-berg@users.noreply.github.com> Date: Thu, 7 Mar 2024 06:48:36 -0600 Subject: [PATCH 282/901] Add basic proxy configuration to OtlpHttp{Signal}Exporters (#6270) Co-authored-by: Marc Schumacher --- dependencyManagement/build.gradle.kts | 1 + .../opentelemetry-exporter-otlp.txt | 9 +++ .../opentelemetry-sdk-common.txt | 8 ++- .../internal/http/HttpExporterBuilder.java | 10 +++ .../internal/http/HttpSenderProvider.java | 2 + .../OtlpHttpLogRecordExporterBuilder.java | 8 +++ .../OtlpHttpMetricExporterBuilder.java | 8 +++ .../trace/OtlpHttpSpanExporterBuilder.java | 8 +++ .../otlp/testing-internal/build.gradle.kts | 1 + .../AbstractHttpTelemetryExporterTest.java | 38 ++++++++++ .../GrpcLogRecordExporterBuilderWrapper.java | 9 ++- .../GrpcMetricExporterBuilderWrapper.java | 9 ++- .../GrpcSpanExporterBuilderWrapper.java | 9 ++- .../HttpLogRecordExporterBuilderWrapper.java | 7 ++ .../HttpMetricExporterBuilderWrapper.java | 7 ++ .../HttpSpanExporterBuilderWrapper.java | 7 ++ ...anagedChannelTelemetryExporterBuilder.java | 7 ++ .../internal/TelemetryExporterBuilder.java | 3 + .../sender/jdk/internal/JdkHttpSender.java | 11 ++- .../jdk/internal/JdkHttpSenderProvider.java | 3 + .../jdk/internal/JdkHttpSenderTest.java | 1 + .../okhttp/internal/OkHttpHttpSender.java | 6 ++ .../internal/OkHttpHttpSenderProvider.java | 3 + .../internal/OkHttpHttpSuppressionTest.java | 1 + .../sdk/common/export/ProxyOptions.java | 71 +++++++++++++++++++ 25 files changed, 241 insertions(+), 6 deletions(-) create mode 100644 sdk/common/src/main/java/io/opentelemetry/sdk/common/export/ProxyOptions.java diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index 69c01f9d356..f136adcdc3d 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -77,6 +77,7 @@ val DEPENDENCIES = listOf( "org.codehaus.mojo:animal-sniffer-annotations:1.23", "org.jctools:jctools-core:4.0.3", "org.junit-pioneer:junit-pioneer:1.9.1", + "org.mock-server:mockserver-netty:5.15.0:shaded", "org.skyscreamer:jsonassert:1.5.1", "com.android.tools:desugar_jdk_libs:2.0.4", ) diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-otlp.txt b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-otlp.txt index f5f51eb6e25..36d0f38ffc9 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-otlp.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-otlp.txt @@ -1,4 +1,13 @@ Comparing source compatibility of against +*** MODIFIED CLASS: PUBLIC FINAL io.opentelemetry.exporter.otlp.http.logs.OtlpHttpLogRecordExporterBuilder (not serializable) + === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 + +++ NEW METHOD: PUBLIC(+) io.opentelemetry.exporter.otlp.http.logs.OtlpHttpLogRecordExporterBuilder setProxyOptions(io.opentelemetry.sdk.common.export.ProxyOptions) +*** MODIFIED CLASS: PUBLIC FINAL io.opentelemetry.exporter.otlp.http.metrics.OtlpHttpMetricExporterBuilder (not serializable) + === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 + +++ NEW METHOD: PUBLIC(+) io.opentelemetry.exporter.otlp.http.metrics.OtlpHttpMetricExporterBuilder setProxyOptions(io.opentelemetry.sdk.common.export.ProxyOptions) +*** MODIFIED CLASS: PUBLIC FINAL io.opentelemetry.exporter.otlp.http.trace.OtlpHttpSpanExporterBuilder (not serializable) + === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 + +++ NEW METHOD: PUBLIC(+) io.opentelemetry.exporter.otlp.http.trace.OtlpHttpSpanExporterBuilder setProxy(io.opentelemetry.sdk.common.export.ProxyOptions) *** MODIFIED CLASS: PUBLIC FINAL io.opentelemetry.exporter.otlp.logs.OtlpGrpcLogRecordExporterBuilder (not serializable) === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 +++ NEW METHOD: PUBLIC(+) io.opentelemetry.exporter.otlp.logs.OtlpGrpcLogRecordExporterBuilder setConnectTimeout(long, java.util.concurrent.TimeUnit) diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-common.txt b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-common.txt index df26146497b..80cfb0c6678 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-common.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-common.txt @@ -1,2 +1,8 @@ Comparing source compatibility of against -No changes. \ No newline at end of file ++++ NEW CLASS: PUBLIC(+) FINAL(+) io.opentelemetry.sdk.common.export.ProxyOptions (not serializable) + +++ CLASS FILE FORMAT VERSION: 52.0 <- n.a. + +++ NEW SUPERCLASS: java.lang.Object + +++ NEW METHOD: PUBLIC(+) STATIC(+) io.opentelemetry.sdk.common.export.ProxyOptions create(java.net.ProxySelector) + +++ NEW METHOD: PUBLIC(+) STATIC(+) io.opentelemetry.sdk.common.export.ProxyOptions create(java.net.InetSocketAddress) + +++ NEW METHOD: PUBLIC(+) java.net.ProxySelector getProxySelector() + +++ NEW METHOD: PUBLIC(+) java.lang.String toString() diff --git a/exporters/common/src/main/java/io/opentelemetry/exporter/internal/http/HttpExporterBuilder.java b/exporters/common/src/main/java/io/opentelemetry/exporter/internal/http/HttpExporterBuilder.java index 3b8275e2529..c9087185ecb 100644 --- a/exporters/common/src/main/java/io/opentelemetry/exporter/internal/http/HttpExporterBuilder.java +++ b/exporters/common/src/main/java/io/opentelemetry/exporter/internal/http/HttpExporterBuilder.java @@ -13,6 +13,7 @@ import io.opentelemetry.exporter.internal.auth.Authenticator; import io.opentelemetry.exporter.internal.compression.Compressor; import io.opentelemetry.exporter.internal.marshal.Marshaler; +import io.opentelemetry.sdk.common.export.ProxyOptions; import io.opentelemetry.sdk.common.export.RetryPolicy; import java.net.URI; import java.util.ArrayList; @@ -52,6 +53,7 @@ public final class HttpExporterBuilder { private long timeoutNanos = TimeUnit.SECONDS.toNanos(DEFAULT_TIMEOUT_SECS); @Nullable private Compressor compressor; private long connectTimeoutNanos = TimeUnit.SECONDS.toNanos(DEFAULT_CONNECT_TIMEOUT_SECS); + @Nullable private ProxyOptions proxyOptions; private boolean exportAsJson = false; private final Map constantHeaders = new HashMap<>(); private Supplier> headerSupplier = Collections::emptyMap; @@ -131,6 +133,11 @@ public HttpExporterBuilder setRetryPolicy(RetryPolicy retryPolicy) { return this; } + public HttpExporterBuilder setProxyOptions(ProxyOptions proxyOptions) { + this.proxyOptions = proxyOptions; + return this; + } + public HttpExporterBuilder exportAsJson() { this.exportAsJson = true; return this; @@ -152,6 +159,7 @@ public HttpExporterBuilder copy() { } copy.meterProviderSupplier = meterProviderSupplier; copy.authenticator = authenticator; + copy.proxyOptions = proxyOptions; return copy; } @@ -187,6 +195,7 @@ public HttpExporter build() { timeoutNanos, connectTimeoutNanos, headerSupplier, + proxyOptions, authenticator, retryPolicy, tlsConfigHelper.getSslContext(), @@ -205,6 +214,7 @@ public String toString(boolean includePrefixAndSuffix) { joiner.add("type=" + type); joiner.add("endpoint=" + endpoint); joiner.add("timeoutNanos=" + timeoutNanos); + joiner.add("proxyOptions=" + proxyOptions); joiner.add( "compressorEncoding=" + Optional.ofNullable(compressor).map(Compressor::getEncoding).orElse(null)); diff --git a/exporters/common/src/main/java/io/opentelemetry/exporter/internal/http/HttpSenderProvider.java b/exporters/common/src/main/java/io/opentelemetry/exporter/internal/http/HttpSenderProvider.java index 90259734d12..b308511eba3 100644 --- a/exporters/common/src/main/java/io/opentelemetry/exporter/internal/http/HttpSenderProvider.java +++ b/exporters/common/src/main/java/io/opentelemetry/exporter/internal/http/HttpSenderProvider.java @@ -7,6 +7,7 @@ import io.opentelemetry.exporter.internal.auth.Authenticator; import io.opentelemetry.exporter.internal.compression.Compressor; +import io.opentelemetry.sdk.common.export.ProxyOptions; import io.opentelemetry.sdk.common.export.RetryPolicy; import java.util.List; import java.util.Map; @@ -34,6 +35,7 @@ HttpSender createSender( long timeoutNanos, long connectTimeout, Supplier>> headerSupplier, + @Nullable ProxyOptions proxyOptions, @Nullable Authenticator authenticator, @Nullable RetryPolicy retryPolicy, @Nullable SSLContext sslContext, diff --git a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/logs/OtlpHttpLogRecordExporterBuilder.java b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/logs/OtlpHttpLogRecordExporterBuilder.java index 0b6253336b8..e81f290bc7e 100644 --- a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/logs/OtlpHttpLogRecordExporterBuilder.java +++ b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/logs/OtlpHttpLogRecordExporterBuilder.java @@ -16,6 +16,7 @@ import io.opentelemetry.exporter.internal.http.HttpExporterBuilder; import io.opentelemetry.exporter.internal.otlp.logs.LogsRequestMarshaler; import io.opentelemetry.exporter.otlp.internal.OtlpUserAgent; +import io.opentelemetry.sdk.common.export.ProxyOptions; import io.opentelemetry.sdk.common.export.RetryPolicy; import java.time.Duration; import java.util.Map; @@ -171,6 +172,13 @@ public OtlpHttpLogRecordExporterBuilder setRetryPolicy(RetryPolicy retryPolicy) return this; } + /** Sets the proxy options. Proxying is disabled by default. */ + public OtlpHttpLogRecordExporterBuilder setProxyOptions(ProxyOptions proxyOptions) { + requireNonNull(proxyOptions, "proxyOptions"); + delegate.setProxyOptions(proxyOptions); + return this; + } + /** * Sets the {@link MeterProvider} to use to collect metrics related to export. If not set, uses * {@link GlobalOpenTelemetry#getMeterProvider()}. diff --git a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/metrics/OtlpHttpMetricExporterBuilder.java b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/metrics/OtlpHttpMetricExporterBuilder.java index d4b2e57df88..0ccbbef0357 100644 --- a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/metrics/OtlpHttpMetricExporterBuilder.java +++ b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/metrics/OtlpHttpMetricExporterBuilder.java @@ -15,6 +15,7 @@ import io.opentelemetry.exporter.internal.http.HttpExporterBuilder; import io.opentelemetry.exporter.internal.otlp.metrics.MetricsRequestMarshaler; import io.opentelemetry.exporter.otlp.internal.OtlpUserAgent; +import io.opentelemetry.sdk.common.export.ProxyOptions; import io.opentelemetry.sdk.common.export.RetryPolicy; import io.opentelemetry.sdk.metrics.InstrumentType; import io.opentelemetry.sdk.metrics.export.AggregationTemporalitySelector; @@ -215,6 +216,13 @@ public OtlpHttpMetricExporterBuilder setRetryPolicy(RetryPolicy retryPolicy) { return this; } + /** Sets the proxy options. Proxying is disabled by default. */ + public OtlpHttpMetricExporterBuilder setProxyOptions(ProxyOptions proxyOptions) { + requireNonNull(proxyOptions, "proxyOptions"); + delegate.setProxyOptions(proxyOptions); + return this; + } + OtlpHttpMetricExporterBuilder exportAsJson() { delegate.exportAsJson(); return this; diff --git a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/trace/OtlpHttpSpanExporterBuilder.java b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/trace/OtlpHttpSpanExporterBuilder.java index c7e3549428a..a9b148739ad 100644 --- a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/trace/OtlpHttpSpanExporterBuilder.java +++ b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/trace/OtlpHttpSpanExporterBuilder.java @@ -16,6 +16,7 @@ import io.opentelemetry.exporter.internal.http.HttpExporterBuilder; import io.opentelemetry.exporter.internal.otlp.traces.TraceRequestMarshaler; import io.opentelemetry.exporter.otlp.internal.OtlpUserAgent; +import io.opentelemetry.sdk.common.export.ProxyOptions; import io.opentelemetry.sdk.common.export.RetryPolicy; import java.time.Duration; import java.util.Map; @@ -172,6 +173,13 @@ public OtlpHttpSpanExporterBuilder setRetryPolicy(RetryPolicy retryPolicy) { return this; } + /** Sets the proxy options. Proxying is disabled by default. */ + public OtlpHttpSpanExporterBuilder setProxy(ProxyOptions proxyOptions) { + requireNonNull(proxyOptions, "proxyOptions"); + delegate.setProxyOptions(proxyOptions); + return this; + } + /** * Sets the {@link MeterProvider} to use to collect metrics related to export. If not set, uses * {@link GlobalOpenTelemetry#getMeterProvider()}. diff --git a/exporters/otlp/testing-internal/build.gradle.kts b/exporters/otlp/testing-internal/build.gradle.kts index 2e491e84c13..2c7c3cc9bd8 100644 --- a/exporters/otlp/testing-internal/build.gradle.kts +++ b/exporters/otlp/testing-internal/build.gradle.kts @@ -31,6 +31,7 @@ dependencies { implementation("com.linecorp.armeria:armeria-junit5") implementation("io.github.netmikey.logunit:logunit-jul") implementation("org.assertj:assertj-core") + implementation("org.mock-server:mockserver-netty") } // Skip OWASP dependencyCheck task on test module diff --git a/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/AbstractHttpTelemetryExporterTest.java b/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/AbstractHttpTelemetryExporterTest.java index 3b903ba0c32..27d9e5f2f2a 100644 --- a/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/AbstractHttpTelemetryExporterTest.java +++ b/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/AbstractHttpTelemetryExporterTest.java @@ -39,12 +39,14 @@ import io.opentelemetry.proto.collector.trace.v1.ExportTraceServiceRequest; import io.opentelemetry.proto.collector.trace.v1.ExportTraceServiceResponse; import io.opentelemetry.sdk.common.CompletableResultCode; +import io.opentelemetry.sdk.common.export.ProxyOptions; import io.opentelemetry.sdk.common.export.RetryPolicy; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.UncheckedIOException; import java.lang.reflect.Field; +import java.net.InetSocketAddress; import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.security.cert.CertificateEncodingException; @@ -84,6 +86,7 @@ import org.junit.jupiter.params.provider.ArgumentsProvider; import org.junit.jupiter.params.provider.ArgumentsSource; import org.junit.jupiter.params.provider.ValueSource; +import org.mockserver.integration.ClientAndServer; import org.slf4j.event.Level; import org.slf4j.event.LoggingEvent; @@ -655,6 +658,39 @@ void nonRetryableError(int code) { assertThat(attempts).hasValue(1); } + @Test + void proxy() { + // configure mockserver to proxy to the local OTLP server + InetSocketAddress serverSocketAddress = server.httpSocketAddress(); + try (ClientAndServer clientAndServer = + ClientAndServer.startClientAndServer( + serverSocketAddress.getHostName(), serverSocketAddress.getPort())) { + TelemetryExporter exporter = + exporterBuilder() + // Configure exporter with server endpoint, and proxy options to route through + // mockserver proxy + .setEndpoint(server.httpUri() + path) + .setProxyOptions( + ProxyOptions.create( + InetSocketAddress.createUnresolved("localhost", clientAndServer.getPort()))) + .build(); + + try { + List telemetry = Collections.singletonList(generateFakeTelemetry()); + + assertThat(exporter.export(telemetry).join(10, TimeUnit.SECONDS).isSuccess()).isTrue(); + // assert that mock server received request + assertThat(clientAndServer.retrieveRecordedRequests(new org.mockserver.model.HttpRequest())) + .hasSize(1); + // assert that server received telemetry from proxy, and is as expected + List expectedResourceTelemetry = toProto(telemetry); + assertThat(exportedResourceTelemetry).containsExactlyElementsOf(expectedResourceTelemetry); + } finally { + exporter.shutdown(); + } + } + } + @Test @SuppressWarnings("PreferJavaTimeOverload") void validConfig() { @@ -815,6 +851,7 @@ void stringRepresentation() throws IOException, CertificateEncodingException { + "timeoutNanos=" + TimeUnit.SECONDS.toNanos(10) + ", " + + "proxyOptions=null, " + "compressorEncoding=null, " + "connectTimeoutNanos=" + TimeUnit.SECONDS.toNanos(10) @@ -855,6 +892,7 @@ void stringRepresentation() throws IOException, CertificateEncodingException { + "timeoutNanos=" + TimeUnit.SECONDS.toNanos(5) + ", " + + "proxyOptions=null, " + "compressorEncoding=gzip, " + "connectTimeoutNanos=" + TimeUnit.SECONDS.toNanos(4) diff --git a/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/GrpcLogRecordExporterBuilderWrapper.java b/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/GrpcLogRecordExporterBuilderWrapper.java index 60e616e7838..5753d4c20fb 100644 --- a/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/GrpcLogRecordExporterBuilderWrapper.java +++ b/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/GrpcLogRecordExporterBuilderWrapper.java @@ -8,6 +8,7 @@ import io.grpc.ManagedChannel; import io.opentelemetry.exporter.internal.auth.Authenticator; import io.opentelemetry.exporter.otlp.logs.OtlpGrpcLogRecordExporterBuilder; +import io.opentelemetry.sdk.common.export.ProxyOptions; import io.opentelemetry.sdk.common.export.RetryPolicy; import io.opentelemetry.sdk.logs.data.LogRecordData; import java.time.Duration; @@ -44,7 +45,8 @@ public TelemetryExporterBuilder setTimeout(Duration timeout) { @Override public TelemetryExporterBuilder setConnectTimeout(long timeout, TimeUnit unit) { - throw new UnsupportedOperationException(); + builder.setConnectTimeout(timeout, unit); + return this; } @Override @@ -103,6 +105,11 @@ public TelemetryExporterBuilder setRetryPolicy(RetryPolicy retryP return this; } + @Override + public TelemetryExporterBuilder setProxyOptions(ProxyOptions proxyOptions) { + throw new UnsupportedOperationException("ProxyOptions are not supported for gRPC"); + } + @Override @SuppressWarnings("deprecation") // testing deprecated functionality public TelemetryExporterBuilder setChannel(Object channel) { diff --git a/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/GrpcMetricExporterBuilderWrapper.java b/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/GrpcMetricExporterBuilderWrapper.java index 6d1f2365512..e6e44fab1cf 100644 --- a/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/GrpcMetricExporterBuilderWrapper.java +++ b/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/GrpcMetricExporterBuilderWrapper.java @@ -8,6 +8,7 @@ import io.grpc.ManagedChannel; import io.opentelemetry.exporter.internal.auth.Authenticator; import io.opentelemetry.exporter.otlp.metrics.OtlpGrpcMetricExporterBuilder; +import io.opentelemetry.sdk.common.export.ProxyOptions; import io.opentelemetry.sdk.common.export.RetryPolicy; import io.opentelemetry.sdk.metrics.data.MetricData; import java.time.Duration; @@ -44,7 +45,8 @@ public TelemetryExporterBuilder setTimeout(Duration timeout) { @Override public TelemetryExporterBuilder setConnectTimeout(long timeout, TimeUnit unit) { - throw new UnsupportedOperationException(); + builder.setConnectTimeout(timeout, unit); + return this; } @Override @@ -103,6 +105,11 @@ public TelemetryExporterBuilder setRetryPolicy(RetryPolicy retryPoli return this; } + @Override + public TelemetryExporterBuilder setProxyOptions(ProxyOptions proxyOptions) { + throw new UnsupportedOperationException("ProxyOptions are not supported for gRPC"); + } + @Override @SuppressWarnings("deprecation") // testing deprecated functionality public TelemetryExporterBuilder setChannel(Object channel) { diff --git a/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/GrpcSpanExporterBuilderWrapper.java b/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/GrpcSpanExporterBuilderWrapper.java index 871eb559deb..caf82b92ecf 100644 --- a/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/GrpcSpanExporterBuilderWrapper.java +++ b/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/GrpcSpanExporterBuilderWrapper.java @@ -8,6 +8,7 @@ import io.grpc.ManagedChannel; import io.opentelemetry.exporter.internal.auth.Authenticator; import io.opentelemetry.exporter.otlp.trace.OtlpGrpcSpanExporterBuilder; +import io.opentelemetry.sdk.common.export.ProxyOptions; import io.opentelemetry.sdk.common.export.RetryPolicy; import io.opentelemetry.sdk.trace.data.SpanData; import java.time.Duration; @@ -45,7 +46,8 @@ public TelemetryExporterBuilder setTimeout(Duration timeout) { @Override public TelemetryExporterBuilder setConnectTimeout(long timeout, TimeUnit unit) { - throw new UnsupportedOperationException(); + builder.setConnectTimeout(timeout, unit); + return this; } @Override @@ -104,6 +106,11 @@ public TelemetryExporterBuilder setRetryPolicy(RetryPolicy retryPolicy return this; } + @Override + public TelemetryExporterBuilder setProxyOptions(ProxyOptions proxyOptions) { + throw new UnsupportedOperationException("ProxyOptions are not supported for gRPC"); + } + @Override @SuppressWarnings("deprecation") // testing deprecated functionality public TelemetryExporterBuilder setChannel(Object channel) { diff --git a/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/HttpLogRecordExporterBuilderWrapper.java b/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/HttpLogRecordExporterBuilderWrapper.java index a849395cbcf..c08fc4ae232 100644 --- a/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/HttpLogRecordExporterBuilderWrapper.java +++ b/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/HttpLogRecordExporterBuilderWrapper.java @@ -7,6 +7,7 @@ import io.opentelemetry.exporter.internal.auth.Authenticator; import io.opentelemetry.exporter.otlp.http.logs.OtlpHttpLogRecordExporterBuilder; +import io.opentelemetry.sdk.common.export.ProxyOptions; import io.opentelemetry.sdk.common.export.RetryPolicy; import io.opentelemetry.sdk.logs.data.LogRecordData; import java.time.Duration; @@ -106,6 +107,12 @@ public TelemetryExporterBuilder setRetryPolicy(RetryPolicy retryP return this; } + @Override + public TelemetryExporterBuilder setProxyOptions(ProxyOptions proxyOptions) { + builder.setProxyOptions(proxyOptions); + return this; + } + @Override public TelemetryExporterBuilder setChannel(Object channel) { throw new UnsupportedOperationException("Not implemented"); diff --git a/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/HttpMetricExporterBuilderWrapper.java b/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/HttpMetricExporterBuilderWrapper.java index 51f5eff0b3b..9382ee247d6 100644 --- a/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/HttpMetricExporterBuilderWrapper.java +++ b/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/HttpMetricExporterBuilderWrapper.java @@ -7,6 +7,7 @@ import io.opentelemetry.exporter.internal.auth.Authenticator; import io.opentelemetry.exporter.otlp.http.metrics.OtlpHttpMetricExporterBuilder; +import io.opentelemetry.sdk.common.export.ProxyOptions; import io.opentelemetry.sdk.common.export.RetryPolicy; import io.opentelemetry.sdk.metrics.data.MetricData; import java.time.Duration; @@ -105,6 +106,12 @@ public TelemetryExporterBuilder setRetryPolicy(RetryPolicy retryPoli return this; } + @Override + public TelemetryExporterBuilder setProxyOptions(ProxyOptions proxyOptions) { + builder.setProxyOptions(proxyOptions); + return this; + } + @Override public TelemetryExporterBuilder setChannel(Object channel) { throw new UnsupportedOperationException("Not implemented"); diff --git a/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/HttpSpanExporterBuilderWrapper.java b/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/HttpSpanExporterBuilderWrapper.java index 90bc3ab00ea..8652d8a38cb 100644 --- a/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/HttpSpanExporterBuilderWrapper.java +++ b/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/HttpSpanExporterBuilderWrapper.java @@ -7,6 +7,7 @@ import io.opentelemetry.exporter.internal.auth.Authenticator; import io.opentelemetry.exporter.otlp.http.trace.OtlpHttpSpanExporterBuilder; +import io.opentelemetry.sdk.common.export.ProxyOptions; import io.opentelemetry.sdk.common.export.RetryPolicy; import io.opentelemetry.sdk.trace.data.SpanData; import java.time.Duration; @@ -105,6 +106,12 @@ public TelemetryExporterBuilder setRetryPolicy(RetryPolicy retryPolicy return this; } + @Override + public TelemetryExporterBuilder setProxyOptions(ProxyOptions proxyOptions) { + builder.setProxy(proxyOptions); + return this; + } + @Override public TelemetryExporterBuilder setChannel(Object channel) { throw new UnsupportedOperationException("Not implemented"); diff --git a/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/ManagedChannelTelemetryExporterBuilder.java b/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/ManagedChannelTelemetryExporterBuilder.java index e5545aa41bd..4a5a8b885bc 100644 --- a/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/ManagedChannelTelemetryExporterBuilder.java +++ b/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/ManagedChannelTelemetryExporterBuilder.java @@ -17,6 +17,7 @@ import io.opentelemetry.exporter.internal.grpc.ManagedChannelUtil; import io.opentelemetry.exporter.otlp.internal.OtlpUserAgent; import io.opentelemetry.sdk.common.CompletableResultCode; +import io.opentelemetry.sdk.common.export.ProxyOptions; import io.opentelemetry.sdk.common.export.RetryPolicy; import java.net.URI; import java.time.Duration; @@ -151,6 +152,12 @@ public TelemetryExporterBuilder setRetryPolicy(RetryPolicy retryPolicy) { return this; } + @Override + public TelemetryExporterBuilder setProxyOptions(ProxyOptions proxyOptions) { + delegate.setProxyOptions(proxyOptions); + return this; + } + @Override public TelemetryExporterBuilder setChannel(Object channel) { throw new UnsupportedOperationException(); diff --git a/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/TelemetryExporterBuilder.java b/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/TelemetryExporterBuilder.java index 3f0b03b2e54..4cbcc9f5c52 100644 --- a/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/TelemetryExporterBuilder.java +++ b/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/TelemetryExporterBuilder.java @@ -9,6 +9,7 @@ import io.opentelemetry.exporter.otlp.logs.OtlpGrpcLogRecordExporterBuilder; import io.opentelemetry.exporter.otlp.metrics.OtlpGrpcMetricExporterBuilder; import io.opentelemetry.exporter.otlp.trace.OtlpGrpcSpanExporterBuilder; +import io.opentelemetry.sdk.common.export.ProxyOptions; import io.opentelemetry.sdk.common.export.RetryPolicy; import io.opentelemetry.sdk.logs.data.LogRecordData; import io.opentelemetry.sdk.metrics.data.MetricData; @@ -60,6 +61,8 @@ static TelemetryExporterBuilder wrap(OtlpGrpcLogRecordExporterBui TelemetryExporterBuilder setRetryPolicy(RetryPolicy retryPolicy); + TelemetryExporterBuilder setProxyOptions(ProxyOptions proxyOptions); + TelemetryExporterBuilder setChannel(Object channel); TelemetryExporter build(); diff --git a/exporters/sender/jdk/src/main/java/io/opentelemetry/exporter/sender/jdk/internal/JdkHttpSender.java b/exporters/sender/jdk/src/main/java/io/opentelemetry/exporter/sender/jdk/internal/JdkHttpSender.java index 838e1d5e20f..22c0609e53d 100644 --- a/exporters/sender/jdk/src/main/java/io/opentelemetry/exporter/sender/jdk/internal/JdkHttpSender.java +++ b/exporters/sender/jdk/src/main/java/io/opentelemetry/exporter/sender/jdk/internal/JdkHttpSender.java @@ -9,6 +9,7 @@ import io.opentelemetry.exporter.internal.http.HttpSender; import io.opentelemetry.exporter.internal.marshal.Marshaler; import io.opentelemetry.sdk.common.CompletableResultCode; +import io.opentelemetry.sdk.common.export.ProxyOptions; import io.opentelemetry.sdk.common.export.RetryPolicy; import java.io.ByteArrayOutputStream; import java.io.IOException; @@ -94,9 +95,10 @@ public final class JdkHttpSender implements HttpSender { long connectTimeoutNanos, Supplier>> headerSupplier, @Nullable RetryPolicy retryPolicy, + @Nullable ProxyOptions proxyOptions, @Nullable SSLContext sslContext) { this( - configureClient(sslContext, connectTimeoutNanos), + configureClient(sslContext, connectTimeoutNanos, proxyOptions), endpoint, compressor, exportAsJson, @@ -107,12 +109,17 @@ public final class JdkHttpSender implements HttpSender { } private static HttpClient configureClient( - @Nullable SSLContext sslContext, long connectionTimeoutNanos) { + @Nullable SSLContext sslContext, + long connectionTimeoutNanos, + @Nullable ProxyOptions proxyOptions) { HttpClient.Builder builder = HttpClient.newBuilder().connectTimeout(Duration.ofNanos(connectionTimeoutNanos)); if (sslContext != null) { builder.sslContext(sslContext); } + if (proxyOptions != null) { + builder.proxy(proxyOptions.getProxySelector()); + } return builder.build(); } diff --git a/exporters/sender/jdk/src/main/java/io/opentelemetry/exporter/sender/jdk/internal/JdkHttpSenderProvider.java b/exporters/sender/jdk/src/main/java/io/opentelemetry/exporter/sender/jdk/internal/JdkHttpSenderProvider.java index c4c6bf071cc..8c2b44cddcb 100644 --- a/exporters/sender/jdk/src/main/java/io/opentelemetry/exporter/sender/jdk/internal/JdkHttpSenderProvider.java +++ b/exporters/sender/jdk/src/main/java/io/opentelemetry/exporter/sender/jdk/internal/JdkHttpSenderProvider.java @@ -9,6 +9,7 @@ import io.opentelemetry.exporter.internal.compression.Compressor; import io.opentelemetry.exporter.internal.http.HttpSender; import io.opentelemetry.exporter.internal.http.HttpSenderProvider; +import io.opentelemetry.sdk.common.export.ProxyOptions; import io.opentelemetry.sdk.common.export.RetryPolicy; import java.util.List; import java.util.Map; @@ -34,6 +35,7 @@ public HttpSender createSender( long timeoutNanos, long connectTimeout, Supplier>> headerSupplier, + @Nullable ProxyOptions proxyOptions, @Nullable Authenticator authenticator, @Nullable RetryPolicy retryPolicy, @Nullable SSLContext sslContext, @@ -47,6 +49,7 @@ public HttpSender createSender( connectTimeout, headerSupplier, retryPolicy, + proxyOptions, sslContext); } } diff --git a/exporters/sender/jdk/src/test/java/io/opentelemetry/exporter/sender/jdk/internal/JdkHttpSenderTest.java b/exporters/sender/jdk/src/test/java/io/opentelemetry/exporter/sender/jdk/internal/JdkHttpSenderTest.java index e4ce06f466f..79a06521c5b 100644 --- a/exporters/sender/jdk/src/test/java/io/opentelemetry/exporter/sender/jdk/internal/JdkHttpSenderTest.java +++ b/exporters/sender/jdk/src/test/java/io/opentelemetry/exporter/sender/jdk/internal/JdkHttpSenderTest.java @@ -108,6 +108,7 @@ void connectTimeout() { TimeUnit.SECONDS.toNanos(10), Collections::emptyMap, null, + null, null); assertThat(sender) diff --git a/exporters/sender/okhttp/src/main/java/io/opentelemetry/exporter/sender/okhttp/internal/OkHttpHttpSender.java b/exporters/sender/okhttp/src/main/java/io/opentelemetry/exporter/sender/okhttp/internal/OkHttpHttpSender.java index 656b9258c20..5d0c839046b 100644 --- a/exporters/sender/okhttp/src/main/java/io/opentelemetry/exporter/sender/okhttp/internal/OkHttpHttpSender.java +++ b/exporters/sender/okhttp/src/main/java/io/opentelemetry/exporter/sender/okhttp/internal/OkHttpHttpSender.java @@ -12,6 +12,7 @@ import io.opentelemetry.exporter.internal.http.HttpSender; import io.opentelemetry.exporter.internal.marshal.Marshaler; import io.opentelemetry.sdk.common.CompletableResultCode; +import io.opentelemetry.sdk.common.export.ProxyOptions; import io.opentelemetry.sdk.common.export.RetryPolicy; import java.io.IOException; import java.time.Duration; @@ -58,6 +59,7 @@ public OkHttpHttpSender( long timeoutNanos, long connectionTimeoutNanos, Supplier>> headerSupplier, + @Nullable ProxyOptions proxyOptions, @Nullable Authenticator authenticator, @Nullable RetryPolicy retryPolicy, @Nullable SSLContext sslContext, @@ -68,6 +70,10 @@ public OkHttpHttpSender( .connectTimeout(Duration.ofNanos(connectionTimeoutNanos)) .callTimeout(Duration.ofNanos(timeoutNanos)); + if (proxyOptions != null) { + builder.proxySelector(proxyOptions.getProxySelector()); + } + if (authenticator != null) { Authenticator finalAuthenticator = authenticator; // Generate and attach OkHttp Authenticator implementation diff --git a/exporters/sender/okhttp/src/main/java/io/opentelemetry/exporter/sender/okhttp/internal/OkHttpHttpSenderProvider.java b/exporters/sender/okhttp/src/main/java/io/opentelemetry/exporter/sender/okhttp/internal/OkHttpHttpSenderProvider.java index 3acad86d038..fc91030fb5c 100644 --- a/exporters/sender/okhttp/src/main/java/io/opentelemetry/exporter/sender/okhttp/internal/OkHttpHttpSenderProvider.java +++ b/exporters/sender/okhttp/src/main/java/io/opentelemetry/exporter/sender/okhttp/internal/OkHttpHttpSenderProvider.java @@ -9,6 +9,7 @@ import io.opentelemetry.exporter.internal.compression.Compressor; import io.opentelemetry.exporter.internal.http.HttpSender; import io.opentelemetry.exporter.internal.http.HttpSenderProvider; +import io.opentelemetry.sdk.common.export.ProxyOptions; import io.opentelemetry.sdk.common.export.RetryPolicy; import java.util.List; import java.util.Map; @@ -34,6 +35,7 @@ public HttpSender createSender( long timeoutNanos, long connectTimeout, Supplier>> headerSupplier, + @Nullable ProxyOptions proxyOptions, @Nullable Authenticator authenticator, @Nullable RetryPolicy retryPolicy, @Nullable SSLContext sslContext, @@ -46,6 +48,7 @@ public HttpSender createSender( timeoutNanos, connectTimeout, headerSupplier, + proxyOptions, authenticator, retryPolicy, sslContext, diff --git a/exporters/sender/okhttp/src/test/java/io/opentelemetry/exporter/sender/okhttp/internal/OkHttpHttpSuppressionTest.java b/exporters/sender/okhttp/src/test/java/io/opentelemetry/exporter/sender/okhttp/internal/OkHttpHttpSuppressionTest.java index 046dbee521a..38686c36526 100644 --- a/exporters/sender/okhttp/src/test/java/io/opentelemetry/exporter/sender/okhttp/internal/OkHttpHttpSuppressionTest.java +++ b/exporters/sender/okhttp/src/test/java/io/opentelemetry/exporter/sender/okhttp/internal/OkHttpHttpSuppressionTest.java @@ -46,6 +46,7 @@ OkHttpHttpSender createSender(String endpoint) { null, null, null, + null, null); } } diff --git a/sdk/common/src/main/java/io/opentelemetry/sdk/common/export/ProxyOptions.java b/sdk/common/src/main/java/io/opentelemetry/sdk/common/export/ProxyOptions.java new file mode 100644 index 00000000000..79ab1978b3f --- /dev/null +++ b/sdk/common/src/main/java/io/opentelemetry/sdk/common/export/ProxyOptions.java @@ -0,0 +1,71 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.sdk.common.export; + +import java.io.IOException; +import java.net.InetSocketAddress; +import java.net.Proxy; +import java.net.ProxySelector; +import java.net.SocketAddress; +import java.net.URI; +import java.util.Collections; +import java.util.List; + +/** Configuration for proxy settings. */ +public final class ProxyOptions { + private final ProxySelector proxySelector; + + private ProxyOptions(ProxySelector proxySelector) { + this.proxySelector = proxySelector; + } + + /** Create proxy options with the {@code proxySelector}. */ + public static ProxyOptions create(ProxySelector proxySelector) { + return new ProxyOptions(proxySelector); + } + + /** + * Create proxy options with a {@link ProxySelector} which always uses an {@link Proxy.Type#HTTP} + * proxy with the {@code socketAddress}. + */ + public static ProxyOptions create(InetSocketAddress socketAddress) { + return new ProxyOptions(new SimpleProxySelector(new Proxy(Proxy.Type.HTTP, socketAddress))); + } + + /** Return the {@link ProxySelector}. */ + public ProxySelector getProxySelector() { + return proxySelector; + } + + @Override + public String toString() { + return "ProxyOptions{proxySelector=" + proxySelector + "}"; + } + + private static final class SimpleProxySelector extends ProxySelector { + + private final List proxyList; + + private SimpleProxySelector(Proxy proxy) { + this.proxyList = Collections.singletonList(proxy); + } + + @Override + public List select(URI uri) { + return proxyList; + } + + @Override + public void connectFailed(URI uri, SocketAddress sa, IOException e) { + // ignore + } + + @Override + public String toString() { + return "SimpleProxySelector{proxy=" + proxyList.get(0).toString() + "}"; + } + } +} From c3ed1d5ee564fd9b530c0753ab6b80b7ae50f932 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 7 Mar 2024 06:49:27 -0600 Subject: [PATCH 283/901] Update dependency org.jetbrains.kotlin:kotlin-gradle-plugin to v1.9.23 (#6275) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- buildSrc/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts index 26728dc9d43..7e8783cccf6 100644 --- a/buildSrc/build.gradle.kts +++ b/buildSrc/build.gradle.kts @@ -57,7 +57,7 @@ dependencies { implementation("me.champeau.jmh:jmh-gradle-plugin:0.7.2") implementation("net.ltgt.gradle:gradle-errorprone-plugin:3.1.0") implementation("net.ltgt.gradle:gradle-nullaway-plugin:2.0.0") - implementation("org.jetbrains.kotlin:kotlin-gradle-plugin:1.9.22") + implementation("org.jetbrains.kotlin:kotlin-gradle-plugin:1.9.23") implementation("org.owasp:dependency-check-gradle:9.0.9") implementation("ru.vyarus:gradle-animalsniffer-plugin:1.7.1") } From f032fc670380b1b7e138e01e88f10c9e898cbe3d Mon Sep 17 00:00:00 2001 From: jack-berg <34418638+jack-berg@users.noreply.github.com> Date: Fri, 8 Mar 2024 06:44:26 -0600 Subject: [PATCH 284/901] Prepare 1.36.0 (#6276) --- CHANGELOG.md | 28 +++++++++++++++++++ .../opentelemetry-exporter-jaeger-thrift.txt | 2 -- .../opentelemetry-exporter-jaeger.txt | 2 -- .../OtlpHttpLogRecordExporterBuilder.java | 6 +++- .../OtlpHttpMetricExporterBuilder.java | 6 +++- .../trace/OtlpHttpSpanExporterBuilder.java | 6 +++- .../OtlpGrpcLogRecordExporterBuilder.java | 4 +++ .../OtlpGrpcMetricExporterBuilder.java | 4 +++ .../trace/OtlpGrpcSpanExporterBuilder.java | 4 +++ .../spi/AutoConfigurationCustomizer.java | 2 ++ .../sdk/common/export/ProxyOptions.java | 6 +++- 11 files changed, 62 insertions(+), 8 deletions(-) delete mode 100644 docs/apidiffs/current_vs_latest/opentelemetry-exporter-jaeger-thrift.txt delete mode 100644 docs/apidiffs/current_vs_latest/opentelemetry-exporter-jaeger.txt diff --git a/CHANGELOG.md b/CHANGELOG.md index 47819262098..889669cc178 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,34 @@ ## Unreleased +### SDK + +#### Traces + +* Lazily initialize the container for events in the SDK Span implementation + ([#6244](https://github.com/open-telemetry/opentelemetry-java/pull/6244)) + +#### Exporters + +* Add basic proxy configuration to OtlpHttp{Signal}Exporters + ([#6270](https://github.com/open-telemetry/opentelemetry-java/pull/6270)) +* Add connectTimeout configuration option OtlpGrpc{Signal}Exporters + ([#6079](https://github.com/open-telemetry/opentelemetry-java/pull/6079)) + +#### Extensions + +* Add ComponentLoader to autoconfigure support more scenarios + ([#6217](https://github.com/open-telemetry/opentelemetry-java/pull/6217)) +* Added MetricReader customizer for AutoConfiguredOpenTelemetrySdkBuilder + ([#6231](https://github.com/open-telemetry/opentelemetry-java/pull/6231)) +* Return AutoConfiguredOpenTelemetrySdkBuilder instead of the base type + ([#6248](https://github.com/open-telemetry/opentelemetry-java/pull/6248)) + +### Tooling + +* Add note about draft PRs to CONTRIBUTING.md + ([#6247](https://github.com/open-telemetry/opentelemetry-java/pull/6247)) + ## Version 1.35.0 (2024-02-09) **NOTE:** The `opentelemetry-exporter-jaeger` and `opentelemetry-exporter-jaeger-thift` artifacts diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-jaeger-thrift.txt b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-jaeger-thrift.txt deleted file mode 100644 index df26146497b..00000000000 --- a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-jaeger-thrift.txt +++ /dev/null @@ -1,2 +0,0 @@ -Comparing source compatibility of against -No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-jaeger.txt b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-jaeger.txt deleted file mode 100644 index df26146497b..00000000000 --- a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-jaeger.txt +++ /dev/null @@ -1,2 +0,0 @@ -Comparing source compatibility of against -No changes. \ No newline at end of file diff --git a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/logs/OtlpHttpLogRecordExporterBuilder.java b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/logs/OtlpHttpLogRecordExporterBuilder.java index e81f290bc7e..4d330c42546 100644 --- a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/logs/OtlpHttpLogRecordExporterBuilder.java +++ b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/logs/OtlpHttpLogRecordExporterBuilder.java @@ -172,7 +172,11 @@ public OtlpHttpLogRecordExporterBuilder setRetryPolicy(RetryPolicy retryPolicy) return this; } - /** Sets the proxy options. Proxying is disabled by default. */ + /** + * Sets the proxy options. Proxying is disabled by default. + * + * @since 1.36.0 + */ public OtlpHttpLogRecordExporterBuilder setProxyOptions(ProxyOptions proxyOptions) { requireNonNull(proxyOptions, "proxyOptions"); delegate.setProxyOptions(proxyOptions); diff --git a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/metrics/OtlpHttpMetricExporterBuilder.java b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/metrics/OtlpHttpMetricExporterBuilder.java index 0ccbbef0357..8fa21d1aa50 100644 --- a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/metrics/OtlpHttpMetricExporterBuilder.java +++ b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/metrics/OtlpHttpMetricExporterBuilder.java @@ -216,7 +216,11 @@ public OtlpHttpMetricExporterBuilder setRetryPolicy(RetryPolicy retryPolicy) { return this; } - /** Sets the proxy options. Proxying is disabled by default. */ + /** + * Sets the proxy options. Proxying is disabled by default. + * + * @since 1.36.0 + */ public OtlpHttpMetricExporterBuilder setProxyOptions(ProxyOptions proxyOptions) { requireNonNull(proxyOptions, "proxyOptions"); delegate.setProxyOptions(proxyOptions); diff --git a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/trace/OtlpHttpSpanExporterBuilder.java b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/trace/OtlpHttpSpanExporterBuilder.java index a9b148739ad..e5039c61907 100644 --- a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/trace/OtlpHttpSpanExporterBuilder.java +++ b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/trace/OtlpHttpSpanExporterBuilder.java @@ -173,7 +173,11 @@ public OtlpHttpSpanExporterBuilder setRetryPolicy(RetryPolicy retryPolicy) { return this; } - /** Sets the proxy options. Proxying is disabled by default. */ + /** + * Sets the proxy options. Proxying is disabled by default. + * + * @since 1.36.0 + */ public OtlpHttpSpanExporterBuilder setProxy(ProxyOptions proxyOptions) { requireNonNull(proxyOptions, "proxyOptions"); delegate.setProxyOptions(proxyOptions); diff --git a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/logs/OtlpGrpcLogRecordExporterBuilder.java b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/logs/OtlpGrpcLogRecordExporterBuilder.java index 9b6cee82912..df5f4769588 100644 --- a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/logs/OtlpGrpcLogRecordExporterBuilder.java +++ b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/logs/OtlpGrpcLogRecordExporterBuilder.java @@ -104,6 +104,8 @@ public OtlpGrpcLogRecordExporterBuilder setTimeout(Duration timeout) { /** * Sets the maximum time to wait for new connections to be established. If unset, defaults to * {@value GrpcExporterBuilder#DEFAULT_CONNECT_TIMEOUT_SECS}s. + * + * @since 1.36.0 */ public OtlpGrpcLogRecordExporterBuilder setConnectTimeout(long timeout, TimeUnit unit) { requireNonNull(unit, "unit"); @@ -115,6 +117,8 @@ public OtlpGrpcLogRecordExporterBuilder setConnectTimeout(long timeout, TimeUnit /** * Sets the maximum time to wait for new connections to be established. If unset, defaults to * {@value GrpcExporterBuilder#DEFAULT_CONNECT_TIMEOUT_SECS}s. + * + * @since 1.36.0 */ public OtlpGrpcLogRecordExporterBuilder setConnectTimeout(Duration timeout) { requireNonNull(timeout, "timeout"); diff --git a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/metrics/OtlpGrpcMetricExporterBuilder.java b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/metrics/OtlpGrpcMetricExporterBuilder.java index 4b2ebd22254..2fc86bab6bd 100644 --- a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/metrics/OtlpGrpcMetricExporterBuilder.java +++ b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/metrics/OtlpGrpcMetricExporterBuilder.java @@ -116,6 +116,8 @@ public OtlpGrpcMetricExporterBuilder setTimeout(Duration timeout) { /** * Sets the maximum time to wait for new connections to be established. If unset, defaults to * {@value GrpcExporterBuilder#DEFAULT_CONNECT_TIMEOUT_SECS}s. + * + * @since 1.36.0 */ public OtlpGrpcMetricExporterBuilder setConnectTimeout(long timeout, TimeUnit unit) { requireNonNull(unit, "unit"); @@ -127,6 +129,8 @@ public OtlpGrpcMetricExporterBuilder setConnectTimeout(long timeout, TimeUnit un /** * Sets the maximum time to wait for new connections to be established. If unset, defaults to * {@value GrpcExporterBuilder#DEFAULT_CONNECT_TIMEOUT_SECS}s. + * + * @since 1.36.0 */ public OtlpGrpcMetricExporterBuilder setConnectTimeout(Duration timeout) { requireNonNull(timeout, "timeout"); diff --git a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/trace/OtlpGrpcSpanExporterBuilder.java b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/trace/OtlpGrpcSpanExporterBuilder.java index b04f4195d55..9f48078b701 100644 --- a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/trace/OtlpGrpcSpanExporterBuilder.java +++ b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/trace/OtlpGrpcSpanExporterBuilder.java @@ -100,6 +100,8 @@ public OtlpGrpcSpanExporterBuilder setTimeout(Duration timeout) { /** * Sets the maximum time to wait for new connections to be established. If unset, defaults to * {@value GrpcExporterBuilder#DEFAULT_CONNECT_TIMEOUT_SECS}s. + * + * @since 1.36.0 */ public OtlpGrpcSpanExporterBuilder setConnectTimeout(long timeout, TimeUnit unit) { requireNonNull(unit, "unit"); @@ -111,6 +113,8 @@ public OtlpGrpcSpanExporterBuilder setConnectTimeout(long timeout, TimeUnit unit /** * Sets the maximum time to wait for new connections to be established. If unset, defaults to * {@value GrpcExporterBuilder#DEFAULT_CONNECT_TIMEOUT_SECS}s. + * + * @since 1.36.0 */ public OtlpGrpcSpanExporterBuilder setConnectTimeout(Duration timeout) { requireNonNull(timeout, "timeout"); diff --git a/sdk-extensions/autoconfigure-spi/src/main/java/io/opentelemetry/sdk/autoconfigure/spi/AutoConfigurationCustomizer.java b/sdk-extensions/autoconfigure-spi/src/main/java/io/opentelemetry/sdk/autoconfigure/spi/AutoConfigurationCustomizer.java index d64ec24f49d..7ecfa9c8dd1 100644 --- a/sdk-extensions/autoconfigure-spi/src/main/java/io/opentelemetry/sdk/autoconfigure/spi/AutoConfigurationCustomizer.java +++ b/sdk-extensions/autoconfigure-spi/src/main/java/io/opentelemetry/sdk/autoconfigure/spi/AutoConfigurationCustomizer.java @@ -163,6 +163,8 @@ default AutoConfigurationCustomizer addMetricExporterCustomizer( * customization. The return value of the {@link BiFunction} will replace the passed-in argument. * *

    Multiple calls will execute the customizers in order. + * + * @since 1.36.0 */ @SuppressWarnings("UnusedReturnValue") default AutoConfigurationCustomizer addMetricReaderCustomizer( diff --git a/sdk/common/src/main/java/io/opentelemetry/sdk/common/export/ProxyOptions.java b/sdk/common/src/main/java/io/opentelemetry/sdk/common/export/ProxyOptions.java index 79ab1978b3f..5e4ad463a92 100644 --- a/sdk/common/src/main/java/io/opentelemetry/sdk/common/export/ProxyOptions.java +++ b/sdk/common/src/main/java/io/opentelemetry/sdk/common/export/ProxyOptions.java @@ -14,7 +14,11 @@ import java.util.Collections; import java.util.List; -/** Configuration for proxy settings. */ +/** + * Configuration for proxy settings. + * + * @since 1.36.0 + */ public final class ProxyOptions { private final ProxySelector proxySelector; From 05bd972f9005ea8a3aec04d55361915ae6534822 Mon Sep 17 00:00:00 2001 From: OpenTelemetry Bot <107717825+opentelemetrybot@users.noreply.github.com> Date: Fri, 8 Mar 2024 14:03:43 +0100 Subject: [PATCH 285/901] Update version to 1.37.0 (#6279) --- CHANGELOG.md | 2 ++ version.gradle.kts | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 889669cc178..24b19d0adc6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,8 @@ ## Unreleased +## Version 1.36.0 (2024-03-08) + ### SDK #### Traces diff --git a/version.gradle.kts b/version.gradle.kts index 2626983ff72..6a6a6fa9384 100644 --- a/version.gradle.kts +++ b/version.gradle.kts @@ -1,7 +1,7 @@ val snapshot = true allprojects { - var ver = "1.36.0" + var ver = "1.37.0" val release = findProperty("otel.release") if (release != null) { ver += "-" + release From fdaf68045428639411ff6008db8baec7574c25ca Mon Sep 17 00:00:00 2001 From: jack-berg <34418638+jack-berg@users.noreply.github.com> Date: Fri, 8 Mar 2024 18:04:49 -0600 Subject: [PATCH 286/901] Post release 1.36.0 (#6280) --- README.md | 72 +++++++++---------- .../1.36.0_vs_1.35.0/opentelemetry-api.txt | 2 + .../opentelemetry-context.txt | 2 + .../opentelemetry-exporter-common.txt | 2 + .../opentelemetry-exporter-logging-otlp.txt | 2 + .../opentelemetry-exporter-logging.txt | 2 + .../opentelemetry-exporter-otlp-common.txt | 2 + .../opentelemetry-exporter-otlp.txt | 22 ++++++ ...y-exporter-sender-grpc-managed-channel.txt | 2 + .../opentelemetry-exporter-sender-okhttp.txt | 2 + .../opentelemetry-exporter-zipkin.txt | 2 + .../opentelemetry-extension-kotlin.txt | 2 + ...ntelemetry-extension-trace-propagators.txt | 2 + .../opentelemetry-opentracing-shim.txt | 2 + .../opentelemetry-sdk-common.txt | 8 +++ ...emetry-sdk-extension-autoconfigure-spi.txt | 4 ++ ...ntelemetry-sdk-extension-autoconfigure.txt | 5 ++ ...ry-sdk-extension-jaeger-remote-sampler.txt | 2 + .../opentelemetry-sdk-logs.txt | 2 + .../opentelemetry-sdk-metrics.txt | 2 + .../opentelemetry-sdk-testing.txt | 2 + .../opentelemetry-sdk-trace.txt | 2 + .../1.36.0_vs_1.35.0/opentelemetry-sdk.txt | 2 + .../opentelemetry-exporter-otlp.txt | 22 +----- .../opentelemetry-sdk-common.txt | 8 +-- ...emetry-sdk-extension-autoconfigure-spi.txt | 4 +- ...ntelemetry-sdk-extension-autoconfigure.txt | 5 +- 27 files changed, 115 insertions(+), 71 deletions(-) create mode 100644 docs/apidiffs/1.36.0_vs_1.35.0/opentelemetry-api.txt create mode 100644 docs/apidiffs/1.36.0_vs_1.35.0/opentelemetry-context.txt create mode 100644 docs/apidiffs/1.36.0_vs_1.35.0/opentelemetry-exporter-common.txt create mode 100644 docs/apidiffs/1.36.0_vs_1.35.0/opentelemetry-exporter-logging-otlp.txt create mode 100644 docs/apidiffs/1.36.0_vs_1.35.0/opentelemetry-exporter-logging.txt create mode 100644 docs/apidiffs/1.36.0_vs_1.35.0/opentelemetry-exporter-otlp-common.txt create mode 100644 docs/apidiffs/1.36.0_vs_1.35.0/opentelemetry-exporter-otlp.txt create mode 100644 docs/apidiffs/1.36.0_vs_1.35.0/opentelemetry-exporter-sender-grpc-managed-channel.txt create mode 100644 docs/apidiffs/1.36.0_vs_1.35.0/opentelemetry-exporter-sender-okhttp.txt create mode 100644 docs/apidiffs/1.36.0_vs_1.35.0/opentelemetry-exporter-zipkin.txt create mode 100644 docs/apidiffs/1.36.0_vs_1.35.0/opentelemetry-extension-kotlin.txt create mode 100644 docs/apidiffs/1.36.0_vs_1.35.0/opentelemetry-extension-trace-propagators.txt create mode 100644 docs/apidiffs/1.36.0_vs_1.35.0/opentelemetry-opentracing-shim.txt create mode 100644 docs/apidiffs/1.36.0_vs_1.35.0/opentelemetry-sdk-common.txt create mode 100644 docs/apidiffs/1.36.0_vs_1.35.0/opentelemetry-sdk-extension-autoconfigure-spi.txt create mode 100644 docs/apidiffs/1.36.0_vs_1.35.0/opentelemetry-sdk-extension-autoconfigure.txt create mode 100644 docs/apidiffs/1.36.0_vs_1.35.0/opentelemetry-sdk-extension-jaeger-remote-sampler.txt create mode 100644 docs/apidiffs/1.36.0_vs_1.35.0/opentelemetry-sdk-logs.txt create mode 100644 docs/apidiffs/1.36.0_vs_1.35.0/opentelemetry-sdk-metrics.txt create mode 100644 docs/apidiffs/1.36.0_vs_1.35.0/opentelemetry-sdk-testing.txt create mode 100644 docs/apidiffs/1.36.0_vs_1.35.0/opentelemetry-sdk-trace.txt create mode 100644 docs/apidiffs/1.36.0_vs_1.35.0/opentelemetry-sdk.txt diff --git a/README.md b/README.md index 1f1c18332ce..38090b6a1d3 100644 --- a/README.md +++ b/README.md @@ -104,7 +104,7 @@ dependency versions in sync. io.opentelemetry opentelemetry-bom - 1.35.0 + 1.36.0 pom import @@ -123,7 +123,7 @@ dependency versions in sync. ```groovy dependencies { - implementation platform("io.opentelemetry:opentelemetry-bom:1.35.0") + implementation platform("io.opentelemetry:opentelemetry-bom:1.36.0") implementation('io.opentelemetry:opentelemetry-api') } ``` @@ -132,8 +132,8 @@ Note that if you want to use any artifacts that have not fully stabilized yet (s ```groovy dependencies { - implementation platform("io.opentelemetry:opentelemetry-bom:1.35.0") - implementation platform('io.opentelemetry:opentelemetry-bom-alpha:1.35.0-alpha') + implementation platform("io.opentelemetry:opentelemetry-bom:1.36.0") + implementation platform('io.opentelemetry:opentelemetry-bom-alpha:1.36.0-alpha') implementation('io.opentelemetry:opentelemetry-api') implementation('io.opentelemetry:opentelemetry-exporter-prometheus') @@ -161,7 +161,7 @@ We strongly recommend using our published BOM to keep all dependency versions in io.opentelemetry opentelemetry-bom - 1.36.0-SNAPSHOT + 1.37.0-SNAPSHOT pom import @@ -184,7 +184,7 @@ repositories { } dependencies { - implementation platform("io.opentelemetry:opentelemetry-bom:1.36.0-SNAPSHOT") + implementation platform("io.opentelemetry:opentelemetry-bom:1.37.0-SNAPSHOT") implementation('io.opentelemetry:opentelemetry-api') } ``` @@ -229,67 +229,67 @@ dependency as follows, replacing `{{artifact-id}}` with the value from the "Arti | Component | Description | Artifact ID | Version | Javadoc | |----------------------------------------------|----------------------------------------|---------------------------|-------------------------------------------------------------|---------| -| [Bill of Materials (BOM)](./bom) | Bill of materials for stable artifacts | `opentelemetry-bom` | 1.35.0 | N/A | -| [Alpha Bill of Materials (BOM)](./bom-alpha) | Bill of materials for alpha artifacts | `opentelemetry-bom-alpha` | 1.35.0-alpha | N/A | +| [Bill of Materials (BOM)](./bom) | Bill of materials for stable artifacts | `opentelemetry-bom` | 1.36.0 | N/A | +| [Alpha Bill of Materials (BOM)](./bom-alpha) | Bill of materials for alpha artifacts | `opentelemetry-bom-alpha` | 1.36.0-alpha | N/A | ### API | Component | Description | Artifact ID | Version | Javadoc | |-----------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|----------------------------|-------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------| -| [API](./api/all) | OpenTelemetry API, including metrics, traces, baggage, context | `opentelemetry-api` | 1.35.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-api.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-api) | -| [Events API](./api/events) | OpenTelemetry Event API for emitting events. | `opentelemetry-api-events` | 1.35.0-alpha | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-api-events.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-api-events) | -| [Context API](./context) | OpenTelemetry context API | `opentelemetry-context` | 1.35.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-context.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-context) | +| [API](./api/all) | OpenTelemetry API, including metrics, traces, baggage, context | `opentelemetry-api` | 1.36.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-api.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-api) | +| [Events API](./api/events) | OpenTelemetry Event API for emitting events. | `opentelemetry-api-events` | 1.36.0-alpha | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-api-events.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-api-events) | +| [Context API](./context) | OpenTelemetry context API | `opentelemetry-context` | 1.36.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-context.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-context) | ### API Extensions | Component | Description | Artifact ID | Version | Javadoc | |---------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|---------------------------------------------|-------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| [Kotlin Extension](./extensions/kotlin) | Context extension for coroutines | `opentelemetry-extension-kotlin` | 1.35.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-extension-kotlin.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-extension-kotlin) | -| [Trace Propagators Extension](./extensions/trace-propagators) | Trace propagators, including B3, Jaeger, OT Trace | `opentelemetry-extension-trace-propagators` | 1.35.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-extension-trace-propagators.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-extension-trace-propagators) | -| [Incubator Extension](./extensions/incubator) | API incubator, including pass through propagator, and extended tracer | `opentelemetry-extension-incubator` | 1.35.0-alpha | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-extension-incubator.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-extension-incubator) | +| [Kotlin Extension](./extensions/kotlin) | Context extension for coroutines | `opentelemetry-extension-kotlin` | 1.36.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-extension-kotlin.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-extension-kotlin) | +| [Trace Propagators Extension](./extensions/trace-propagators) | Trace propagators, including B3, Jaeger, OT Trace | `opentelemetry-extension-trace-propagators` | 1.36.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-extension-trace-propagators.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-extension-trace-propagators) | +| [Incubator Extension](./extensions/incubator) | API incubator, including pass through propagator, and extended tracer | `opentelemetry-extension-incubator` | 1.36.0-alpha | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-extension-incubator.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-extension-incubator) | ### SDK | Component | Description | Artifact ID | Version | Javadoc | |------------------------------|--------------------------------------------------------|-----------------------------|---------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| [SDK](./sdk/all) | OpenTelemetry SDK, including metrics, traces, and logs | `opentelemetry-sdk` | 1.35.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk) | -| [Metrics SDK](./sdk/metrics) | OpenTelemetry metrics SDK | `opentelemetry-sdk-metrics` | 1.35.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-metrics.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-metrics) | -| [Trace SDK](./sdk/trace) | OpenTelemetry trace SDK | `opentelemetry-sdk-trace` | 1.35.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-trace.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-trace) | -| [Log SDK](./sdk/logs) | OpenTelemetry log SDK | `opentelemetry-sdk-logs` | 1.35.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-logs.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-logs) | -| [SDK Common](./sdk/common) | Shared SDK components | `opentelemetry-sdk-common` | 1.35.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-common.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-common) | -| [SDK Testing](./sdk/testing) | Components for testing OpenTelemetry instrumentation | `opentelemetry-sdk-testing` | 1.35.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-testing.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-testing) | +| [SDK](./sdk/all) | OpenTelemetry SDK, including metrics, traces, and logs | `opentelemetry-sdk` | 1.36.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk) | +| [Metrics SDK](./sdk/metrics) | OpenTelemetry metrics SDK | `opentelemetry-sdk-metrics` | 1.36.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-metrics.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-metrics) | +| [Trace SDK](./sdk/trace) | OpenTelemetry trace SDK | `opentelemetry-sdk-trace` | 1.36.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-trace.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-trace) | +| [Log SDK](./sdk/logs) | OpenTelemetry log SDK | `opentelemetry-sdk-logs` | 1.36.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-logs.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-logs) | +| [SDK Common](./sdk/common) | Shared SDK components | `opentelemetry-sdk-common` | 1.36.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-common.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-common) | +| [SDK Testing](./sdk/testing) | Components for testing OpenTelemetry instrumentation | `opentelemetry-sdk-testing` | 1.36.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-testing.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-testing) | ### SDK Exporters | Component | Description | Artifact ID | Version | Javadoc | |-----------------------------------------------------------------------|------------------------------------------------------------------------------|------------------------------------------------------|-------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| [OTLP Exporters](./exporters/otlp/all) | OTLP gRPC & HTTP exporters, including traces, metrics, and logs | `opentelemetry-exporter-otlp` | 1.35.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-otlp.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-otlp) | -| [OTLP Logging Exporters](./exporters/logging-otlp) | Logging exporters in OTLP JSON encoding, including traces, metrics, and logs | `opentelemetry-exporter-logging-otlp` | 1.35.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-logging-otlp.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-logging-otlp) | -| [OTLP Common](./exporters/otlp/common) | Shared OTLP components (internal) | `opentelemetry-exporter-otlp-common` | 1.35.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-otlp-common.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-otlp-common) | -| [Logging Exporter](./exporters/logging) | Logging exporters, including metrics, traces, and logs | `opentelemetry-exporter-logging` | 1.35.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-logging.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-logging) | -| [Zipkin Exporter](./exporters/zipkin) | Zipkin trace exporter | `opentelemetry-exporter-zipkin` | 1.35.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-zipkin.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-zipkin) | -| [Prometheus Exporter](./exporters/prometheus) | Prometheus metric exporter | `opentelemetry-exporter-prometheus` | 1.35.0-alpha | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-prometheus.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-prometheus) | -| [Exporter Common](./exporters/common) | Shared exporter components (internal) | `opentelemetry-exporter-common` | 1.35.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-common.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-common) | -| [OkHttp Sender](./exporters/sender/okhttp) | OkHttp implementation of HttpSender (internal) | `opentelemetry-exporter-sender-okhttp` | 1.35.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-sender-okhttp.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-sender-okhttp) | -| [JDK Sender](./exporters/sender/okhttp) | Java 11+ native HttpClient implementation of HttpSender (internal) | `opentelemetry-exporter-sender-jdk` | 1.35.0-alpha | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-sender-jdk.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-sender-jdk) | | -| [gRPC ManagedChannel Sender](./exporters/sender/grpc-managed-channel) | gRPC ManagedChannel implementation of GrpcSender (internal) | `opentelemetry-exporter-sender-grpc-managed-channel` | 1.35.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-sender-grpc-managed-channel.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-sender-grpc-managed-channel) | | +| [OTLP Exporters](./exporters/otlp/all) | OTLP gRPC & HTTP exporters, including traces, metrics, and logs | `opentelemetry-exporter-otlp` | 1.36.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-otlp.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-otlp) | +| [OTLP Logging Exporters](./exporters/logging-otlp) | Logging exporters in OTLP JSON encoding, including traces, metrics, and logs | `opentelemetry-exporter-logging-otlp` | 1.36.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-logging-otlp.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-logging-otlp) | +| [OTLP Common](./exporters/otlp/common) | Shared OTLP components (internal) | `opentelemetry-exporter-otlp-common` | 1.36.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-otlp-common.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-otlp-common) | +| [Logging Exporter](./exporters/logging) | Logging exporters, including metrics, traces, and logs | `opentelemetry-exporter-logging` | 1.36.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-logging.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-logging) | +| [Zipkin Exporter](./exporters/zipkin) | Zipkin trace exporter | `opentelemetry-exporter-zipkin` | 1.36.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-zipkin.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-zipkin) | +| [Prometheus Exporter](./exporters/prometheus) | Prometheus metric exporter | `opentelemetry-exporter-prometheus` | 1.36.0-alpha | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-prometheus.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-prometheus) | +| [Exporter Common](./exporters/common) | Shared exporter components (internal) | `opentelemetry-exporter-common` | 1.36.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-common.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-common) | +| [OkHttp Sender](./exporters/sender/okhttp) | OkHttp implementation of HttpSender (internal) | `opentelemetry-exporter-sender-okhttp` | 1.36.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-sender-okhttp.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-sender-okhttp) | +| [JDK Sender](./exporters/sender/okhttp) | Java 11+ native HttpClient implementation of HttpSender (internal) | `opentelemetry-exporter-sender-jdk` | 1.36.0-alpha | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-sender-jdk.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-sender-jdk) | | +| [gRPC ManagedChannel Sender](./exporters/sender/grpc-managed-channel) | gRPC ManagedChannel implementation of GrpcSender (internal) | `opentelemetry-exporter-sender-grpc-managed-channel` | 1.36.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-sender-grpc-managed-channel.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-sender-grpc-managed-channel) | | ### SDK Extensions | Component | Description | Artifact ID | Version | Javadoc | |-------------------------------------------------------------------------------|------------------------------------------------------------------------------------|-----------------------------------------------------|-------------------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| [SDK Autoconfigure](./sdk-extensions/autoconfigure) | Autoconfigure OpenTelemetry SDK from env vars, system properties, and SPI | `opentelemetry-sdk-extension-autoconfigure` | 1.35.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-extension-autoconfigure.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-extension-autoconfigure) | -| [SDK Autoconfigure SPI](./sdk-extensions/autoconfigure-spi) | Service Provider Interface (SPI) definitions for autoconfigure | `opentelemetry-sdk-extension-autoconfigure-spi` | 1.35.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-extension-autoconfigure-spi.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-extension-autoconfigure-spi) | -| [SDK Jaeger Remote Sampler Extension](./sdk-extensions/jaeger-remote-sampler) | Sampler which obtains sampling configuration from remote Jaeger server | `opentelemetry-sdk-extension-jaeger-remote-sampler` | 1.35.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-extension-jaeger-remote-sampler.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-extension-jaeger-remote-sampler) | -| [SDK Incubator](./sdk-extensions/incubator) | SDK incubator, including YAML based view configuration, LeakDetectingSpanProcessor | `opentelemetry-sdk-extension-incubator` | 1.35.0-alpha | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-extension-incubator.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-extension-incubator) | +| [SDK Autoconfigure](./sdk-extensions/autoconfigure) | Autoconfigure OpenTelemetry SDK from env vars, system properties, and SPI | `opentelemetry-sdk-extension-autoconfigure` | 1.36.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-extension-autoconfigure.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-extension-autoconfigure) | +| [SDK Autoconfigure SPI](./sdk-extensions/autoconfigure-spi) | Service Provider Interface (SPI) definitions for autoconfigure | `opentelemetry-sdk-extension-autoconfigure-spi` | 1.36.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-extension-autoconfigure-spi.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-extension-autoconfigure-spi) | +| [SDK Jaeger Remote Sampler Extension](./sdk-extensions/jaeger-remote-sampler) | Sampler which obtains sampling configuration from remote Jaeger server | `opentelemetry-sdk-extension-jaeger-remote-sampler` | 1.36.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-extension-jaeger-remote-sampler.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-extension-jaeger-remote-sampler) | +| [SDK Incubator](./sdk-extensions/incubator) | SDK incubator, including YAML based view configuration, LeakDetectingSpanProcessor | `opentelemetry-sdk-extension-incubator` | 1.36.0-alpha | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-extension-incubator.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-extension-incubator) | ### Shims | Component | Description | Artifact ID | Version | Javadoc | |----------------------------------------|--------------------------------------------------------------|----------------------------------|-------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| [OpenCensus Shim](./opencensus-shim) | Bridge opencensus metrics into the OpenTelemetry metrics SDK | `opentelemetry-opencensus-shim` | 1.35.0-alpha | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-opencensus-shim.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-opencensus-shim) | -| [OpenTracing Shim](./opentracing-shim) | Bridge opentracing spans into the OpenTelemetry trace API | `opentelemetry-opentracing-shim` | 1.35.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-opentracing-shim.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-opentracing-shim) | +| [OpenCensus Shim](./opencensus-shim) | Bridge opencensus metrics into the OpenTelemetry metrics SDK | `opentelemetry-opencensus-shim` | 1.36.0-alpha | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-opencensus-shim.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-opencensus-shim) | +| [OpenTracing Shim](./opentracing-shim) | Bridge opentracing spans into the OpenTelemetry trace API | `opentelemetry-opentracing-shim` | 1.36.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-opentracing-shim.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-opentracing-shim) | ## Contributing diff --git a/docs/apidiffs/1.36.0_vs_1.35.0/opentelemetry-api.txt b/docs/apidiffs/1.36.0_vs_1.35.0/opentelemetry-api.txt new file mode 100644 index 00000000000..df26146497b --- /dev/null +++ b/docs/apidiffs/1.36.0_vs_1.35.0/opentelemetry-api.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of against +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.36.0_vs_1.35.0/opentelemetry-context.txt b/docs/apidiffs/1.36.0_vs_1.35.0/opentelemetry-context.txt new file mode 100644 index 00000000000..df26146497b --- /dev/null +++ b/docs/apidiffs/1.36.0_vs_1.35.0/opentelemetry-context.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of against +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.36.0_vs_1.35.0/opentelemetry-exporter-common.txt b/docs/apidiffs/1.36.0_vs_1.35.0/opentelemetry-exporter-common.txt new file mode 100644 index 00000000000..df26146497b --- /dev/null +++ b/docs/apidiffs/1.36.0_vs_1.35.0/opentelemetry-exporter-common.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of against +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.36.0_vs_1.35.0/opentelemetry-exporter-logging-otlp.txt b/docs/apidiffs/1.36.0_vs_1.35.0/opentelemetry-exporter-logging-otlp.txt new file mode 100644 index 00000000000..df26146497b --- /dev/null +++ b/docs/apidiffs/1.36.0_vs_1.35.0/opentelemetry-exporter-logging-otlp.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of against +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.36.0_vs_1.35.0/opentelemetry-exporter-logging.txt b/docs/apidiffs/1.36.0_vs_1.35.0/opentelemetry-exporter-logging.txt new file mode 100644 index 00000000000..df26146497b --- /dev/null +++ b/docs/apidiffs/1.36.0_vs_1.35.0/opentelemetry-exporter-logging.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of against +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.36.0_vs_1.35.0/opentelemetry-exporter-otlp-common.txt b/docs/apidiffs/1.36.0_vs_1.35.0/opentelemetry-exporter-otlp-common.txt new file mode 100644 index 00000000000..df26146497b --- /dev/null +++ b/docs/apidiffs/1.36.0_vs_1.35.0/opentelemetry-exporter-otlp-common.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of against +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.36.0_vs_1.35.0/opentelemetry-exporter-otlp.txt b/docs/apidiffs/1.36.0_vs_1.35.0/opentelemetry-exporter-otlp.txt new file mode 100644 index 00000000000..36d0f38ffc9 --- /dev/null +++ b/docs/apidiffs/1.36.0_vs_1.35.0/opentelemetry-exporter-otlp.txt @@ -0,0 +1,22 @@ +Comparing source compatibility of against +*** MODIFIED CLASS: PUBLIC FINAL io.opentelemetry.exporter.otlp.http.logs.OtlpHttpLogRecordExporterBuilder (not serializable) + === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 + +++ NEW METHOD: PUBLIC(+) io.opentelemetry.exporter.otlp.http.logs.OtlpHttpLogRecordExporterBuilder setProxyOptions(io.opentelemetry.sdk.common.export.ProxyOptions) +*** MODIFIED CLASS: PUBLIC FINAL io.opentelemetry.exporter.otlp.http.metrics.OtlpHttpMetricExporterBuilder (not serializable) + === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 + +++ NEW METHOD: PUBLIC(+) io.opentelemetry.exporter.otlp.http.metrics.OtlpHttpMetricExporterBuilder setProxyOptions(io.opentelemetry.sdk.common.export.ProxyOptions) +*** MODIFIED CLASS: PUBLIC FINAL io.opentelemetry.exporter.otlp.http.trace.OtlpHttpSpanExporterBuilder (not serializable) + === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 + +++ NEW METHOD: PUBLIC(+) io.opentelemetry.exporter.otlp.http.trace.OtlpHttpSpanExporterBuilder setProxy(io.opentelemetry.sdk.common.export.ProxyOptions) +*** MODIFIED CLASS: PUBLIC FINAL io.opentelemetry.exporter.otlp.logs.OtlpGrpcLogRecordExporterBuilder (not serializable) + === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 + +++ NEW METHOD: PUBLIC(+) io.opentelemetry.exporter.otlp.logs.OtlpGrpcLogRecordExporterBuilder setConnectTimeout(long, java.util.concurrent.TimeUnit) + +++ NEW METHOD: PUBLIC(+) io.opentelemetry.exporter.otlp.logs.OtlpGrpcLogRecordExporterBuilder setConnectTimeout(java.time.Duration) +*** MODIFIED CLASS: PUBLIC FINAL io.opentelemetry.exporter.otlp.metrics.OtlpGrpcMetricExporterBuilder (not serializable) + === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 + +++ NEW METHOD: PUBLIC(+) io.opentelemetry.exporter.otlp.metrics.OtlpGrpcMetricExporterBuilder setConnectTimeout(long, java.util.concurrent.TimeUnit) + +++ NEW METHOD: PUBLIC(+) io.opentelemetry.exporter.otlp.metrics.OtlpGrpcMetricExporterBuilder setConnectTimeout(java.time.Duration) +*** MODIFIED CLASS: PUBLIC FINAL io.opentelemetry.exporter.otlp.trace.OtlpGrpcSpanExporterBuilder (not serializable) + === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 + +++ NEW METHOD: PUBLIC(+) io.opentelemetry.exporter.otlp.trace.OtlpGrpcSpanExporterBuilder setConnectTimeout(long, java.util.concurrent.TimeUnit) + +++ NEW METHOD: PUBLIC(+) io.opentelemetry.exporter.otlp.trace.OtlpGrpcSpanExporterBuilder setConnectTimeout(java.time.Duration) diff --git a/docs/apidiffs/1.36.0_vs_1.35.0/opentelemetry-exporter-sender-grpc-managed-channel.txt b/docs/apidiffs/1.36.0_vs_1.35.0/opentelemetry-exporter-sender-grpc-managed-channel.txt new file mode 100644 index 00000000000..df26146497b --- /dev/null +++ b/docs/apidiffs/1.36.0_vs_1.35.0/opentelemetry-exporter-sender-grpc-managed-channel.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of against +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.36.0_vs_1.35.0/opentelemetry-exporter-sender-okhttp.txt b/docs/apidiffs/1.36.0_vs_1.35.0/opentelemetry-exporter-sender-okhttp.txt new file mode 100644 index 00000000000..df26146497b --- /dev/null +++ b/docs/apidiffs/1.36.0_vs_1.35.0/opentelemetry-exporter-sender-okhttp.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of against +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.36.0_vs_1.35.0/opentelemetry-exporter-zipkin.txt b/docs/apidiffs/1.36.0_vs_1.35.0/opentelemetry-exporter-zipkin.txt new file mode 100644 index 00000000000..df26146497b --- /dev/null +++ b/docs/apidiffs/1.36.0_vs_1.35.0/opentelemetry-exporter-zipkin.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of against +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.36.0_vs_1.35.0/opentelemetry-extension-kotlin.txt b/docs/apidiffs/1.36.0_vs_1.35.0/opentelemetry-extension-kotlin.txt new file mode 100644 index 00000000000..df26146497b --- /dev/null +++ b/docs/apidiffs/1.36.0_vs_1.35.0/opentelemetry-extension-kotlin.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of against +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.36.0_vs_1.35.0/opentelemetry-extension-trace-propagators.txt b/docs/apidiffs/1.36.0_vs_1.35.0/opentelemetry-extension-trace-propagators.txt new file mode 100644 index 00000000000..df26146497b --- /dev/null +++ b/docs/apidiffs/1.36.0_vs_1.35.0/opentelemetry-extension-trace-propagators.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of against +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.36.0_vs_1.35.0/opentelemetry-opentracing-shim.txt b/docs/apidiffs/1.36.0_vs_1.35.0/opentelemetry-opentracing-shim.txt new file mode 100644 index 00000000000..df26146497b --- /dev/null +++ b/docs/apidiffs/1.36.0_vs_1.35.0/opentelemetry-opentracing-shim.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of against +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.36.0_vs_1.35.0/opentelemetry-sdk-common.txt b/docs/apidiffs/1.36.0_vs_1.35.0/opentelemetry-sdk-common.txt new file mode 100644 index 00000000000..80cfb0c6678 --- /dev/null +++ b/docs/apidiffs/1.36.0_vs_1.35.0/opentelemetry-sdk-common.txt @@ -0,0 +1,8 @@ +Comparing source compatibility of against ++++ NEW CLASS: PUBLIC(+) FINAL(+) io.opentelemetry.sdk.common.export.ProxyOptions (not serializable) + +++ CLASS FILE FORMAT VERSION: 52.0 <- n.a. + +++ NEW SUPERCLASS: java.lang.Object + +++ NEW METHOD: PUBLIC(+) STATIC(+) io.opentelemetry.sdk.common.export.ProxyOptions create(java.net.ProxySelector) + +++ NEW METHOD: PUBLIC(+) STATIC(+) io.opentelemetry.sdk.common.export.ProxyOptions create(java.net.InetSocketAddress) + +++ NEW METHOD: PUBLIC(+) java.net.ProxySelector getProxySelector() + +++ NEW METHOD: PUBLIC(+) java.lang.String toString() diff --git a/docs/apidiffs/1.36.0_vs_1.35.0/opentelemetry-sdk-extension-autoconfigure-spi.txt b/docs/apidiffs/1.36.0_vs_1.35.0/opentelemetry-sdk-extension-autoconfigure-spi.txt new file mode 100644 index 00000000000..c464bbdd2e2 --- /dev/null +++ b/docs/apidiffs/1.36.0_vs_1.35.0/opentelemetry-sdk-extension-autoconfigure-spi.txt @@ -0,0 +1,4 @@ +Comparing source compatibility of against +*** MODIFIED INTERFACE: PUBLIC ABSTRACT io.opentelemetry.sdk.autoconfigure.spi.AutoConfigurationCustomizer (not serializable) + === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 + +++ NEW METHOD: PUBLIC(+) io.opentelemetry.sdk.autoconfigure.spi.AutoConfigurationCustomizer addMetricReaderCustomizer(java.util.function.BiFunction) diff --git a/docs/apidiffs/1.36.0_vs_1.35.0/opentelemetry-sdk-extension-autoconfigure.txt b/docs/apidiffs/1.36.0_vs_1.35.0/opentelemetry-sdk-extension-autoconfigure.txt new file mode 100644 index 00000000000..f9bf6463d2c --- /dev/null +++ b/docs/apidiffs/1.36.0_vs_1.35.0/opentelemetry-sdk-extension-autoconfigure.txt @@ -0,0 +1,5 @@ +Comparing source compatibility of against +**** MODIFIED CLASS: PUBLIC FINAL io.opentelemetry.sdk.autoconfigure.AutoConfiguredOpenTelemetrySdkBuilder (not serializable) + === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 + ===* UNCHANGED METHOD: PUBLIC SYNTHETIC (<- NON_SYNTHETIC) BRIDGE (<- NON_BRIDGE) io.opentelemetry.sdk.autoconfigure.spi.AutoConfigurationCustomizer addLogRecordProcessorCustomizer(java.util.function.BiFunction(<- )) + +++ NEW METHOD: PUBLIC(+) io.opentelemetry.sdk.autoconfigure.AutoConfiguredOpenTelemetrySdkBuilder addMetricReaderCustomizer(java.util.function.BiFunction) diff --git a/docs/apidiffs/1.36.0_vs_1.35.0/opentelemetry-sdk-extension-jaeger-remote-sampler.txt b/docs/apidiffs/1.36.0_vs_1.35.0/opentelemetry-sdk-extension-jaeger-remote-sampler.txt new file mode 100644 index 00000000000..df26146497b --- /dev/null +++ b/docs/apidiffs/1.36.0_vs_1.35.0/opentelemetry-sdk-extension-jaeger-remote-sampler.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of against +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.36.0_vs_1.35.0/opentelemetry-sdk-logs.txt b/docs/apidiffs/1.36.0_vs_1.35.0/opentelemetry-sdk-logs.txt new file mode 100644 index 00000000000..df26146497b --- /dev/null +++ b/docs/apidiffs/1.36.0_vs_1.35.0/opentelemetry-sdk-logs.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of against +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.36.0_vs_1.35.0/opentelemetry-sdk-metrics.txt b/docs/apidiffs/1.36.0_vs_1.35.0/opentelemetry-sdk-metrics.txt new file mode 100644 index 00000000000..df26146497b --- /dev/null +++ b/docs/apidiffs/1.36.0_vs_1.35.0/opentelemetry-sdk-metrics.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of against +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.36.0_vs_1.35.0/opentelemetry-sdk-testing.txt b/docs/apidiffs/1.36.0_vs_1.35.0/opentelemetry-sdk-testing.txt new file mode 100644 index 00000000000..df26146497b --- /dev/null +++ b/docs/apidiffs/1.36.0_vs_1.35.0/opentelemetry-sdk-testing.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of against +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.36.0_vs_1.35.0/opentelemetry-sdk-trace.txt b/docs/apidiffs/1.36.0_vs_1.35.0/opentelemetry-sdk-trace.txt new file mode 100644 index 00000000000..df26146497b --- /dev/null +++ b/docs/apidiffs/1.36.0_vs_1.35.0/opentelemetry-sdk-trace.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of against +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.36.0_vs_1.35.0/opentelemetry-sdk.txt b/docs/apidiffs/1.36.0_vs_1.35.0/opentelemetry-sdk.txt new file mode 100644 index 00000000000..df26146497b --- /dev/null +++ b/docs/apidiffs/1.36.0_vs_1.35.0/opentelemetry-sdk.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of against +No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-otlp.txt b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-otlp.txt index 36d0f38ffc9..df26146497b 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-otlp.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-otlp.txt @@ -1,22 +1,2 @@ Comparing source compatibility of against -*** MODIFIED CLASS: PUBLIC FINAL io.opentelemetry.exporter.otlp.http.logs.OtlpHttpLogRecordExporterBuilder (not serializable) - === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 - +++ NEW METHOD: PUBLIC(+) io.opentelemetry.exporter.otlp.http.logs.OtlpHttpLogRecordExporterBuilder setProxyOptions(io.opentelemetry.sdk.common.export.ProxyOptions) -*** MODIFIED CLASS: PUBLIC FINAL io.opentelemetry.exporter.otlp.http.metrics.OtlpHttpMetricExporterBuilder (not serializable) - === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 - +++ NEW METHOD: PUBLIC(+) io.opentelemetry.exporter.otlp.http.metrics.OtlpHttpMetricExporterBuilder setProxyOptions(io.opentelemetry.sdk.common.export.ProxyOptions) -*** MODIFIED CLASS: PUBLIC FINAL io.opentelemetry.exporter.otlp.http.trace.OtlpHttpSpanExporterBuilder (not serializable) - === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 - +++ NEW METHOD: PUBLIC(+) io.opentelemetry.exporter.otlp.http.trace.OtlpHttpSpanExporterBuilder setProxy(io.opentelemetry.sdk.common.export.ProxyOptions) -*** MODIFIED CLASS: PUBLIC FINAL io.opentelemetry.exporter.otlp.logs.OtlpGrpcLogRecordExporterBuilder (not serializable) - === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 - +++ NEW METHOD: PUBLIC(+) io.opentelemetry.exporter.otlp.logs.OtlpGrpcLogRecordExporterBuilder setConnectTimeout(long, java.util.concurrent.TimeUnit) - +++ NEW METHOD: PUBLIC(+) io.opentelemetry.exporter.otlp.logs.OtlpGrpcLogRecordExporterBuilder setConnectTimeout(java.time.Duration) -*** MODIFIED CLASS: PUBLIC FINAL io.opentelemetry.exporter.otlp.metrics.OtlpGrpcMetricExporterBuilder (not serializable) - === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 - +++ NEW METHOD: PUBLIC(+) io.opentelemetry.exporter.otlp.metrics.OtlpGrpcMetricExporterBuilder setConnectTimeout(long, java.util.concurrent.TimeUnit) - +++ NEW METHOD: PUBLIC(+) io.opentelemetry.exporter.otlp.metrics.OtlpGrpcMetricExporterBuilder setConnectTimeout(java.time.Duration) -*** MODIFIED CLASS: PUBLIC FINAL io.opentelemetry.exporter.otlp.trace.OtlpGrpcSpanExporterBuilder (not serializable) - === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 - +++ NEW METHOD: PUBLIC(+) io.opentelemetry.exporter.otlp.trace.OtlpGrpcSpanExporterBuilder setConnectTimeout(long, java.util.concurrent.TimeUnit) - +++ NEW METHOD: PUBLIC(+) io.opentelemetry.exporter.otlp.trace.OtlpGrpcSpanExporterBuilder setConnectTimeout(java.time.Duration) +No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-common.txt b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-common.txt index 80cfb0c6678..df26146497b 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-common.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-common.txt @@ -1,8 +1,2 @@ Comparing source compatibility of against -+++ NEW CLASS: PUBLIC(+) FINAL(+) io.opentelemetry.sdk.common.export.ProxyOptions (not serializable) - +++ CLASS FILE FORMAT VERSION: 52.0 <- n.a. - +++ NEW SUPERCLASS: java.lang.Object - +++ NEW METHOD: PUBLIC(+) STATIC(+) io.opentelemetry.sdk.common.export.ProxyOptions create(java.net.ProxySelector) - +++ NEW METHOD: PUBLIC(+) STATIC(+) io.opentelemetry.sdk.common.export.ProxyOptions create(java.net.InetSocketAddress) - +++ NEW METHOD: PUBLIC(+) java.net.ProxySelector getProxySelector() - +++ NEW METHOD: PUBLIC(+) java.lang.String toString() +No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-extension-autoconfigure-spi.txt b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-extension-autoconfigure-spi.txt index c464bbdd2e2..df26146497b 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-extension-autoconfigure-spi.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-extension-autoconfigure-spi.txt @@ -1,4 +1,2 @@ Comparing source compatibility of against -*** MODIFIED INTERFACE: PUBLIC ABSTRACT io.opentelemetry.sdk.autoconfigure.spi.AutoConfigurationCustomizer (not serializable) - === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 - +++ NEW METHOD: PUBLIC(+) io.opentelemetry.sdk.autoconfigure.spi.AutoConfigurationCustomizer addMetricReaderCustomizer(java.util.function.BiFunction) +No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-extension-autoconfigure.txt b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-extension-autoconfigure.txt index f9bf6463d2c..df26146497b 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-extension-autoconfigure.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-extension-autoconfigure.txt @@ -1,5 +1,2 @@ Comparing source compatibility of against -**** MODIFIED CLASS: PUBLIC FINAL io.opentelemetry.sdk.autoconfigure.AutoConfiguredOpenTelemetrySdkBuilder (not serializable) - === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 - ===* UNCHANGED METHOD: PUBLIC SYNTHETIC (<- NON_SYNTHETIC) BRIDGE (<- NON_BRIDGE) io.opentelemetry.sdk.autoconfigure.spi.AutoConfigurationCustomizer addLogRecordProcessorCustomizer(java.util.function.BiFunction(<- )) - +++ NEW METHOD: PUBLIC(+) io.opentelemetry.sdk.autoconfigure.AutoConfiguredOpenTelemetrySdkBuilder addMetricReaderCustomizer(java.util.function.BiFunction) +No changes. \ No newline at end of file From a7423f66760c76f2ab20c4c63ec5859ccb704c77 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 9 Mar 2024 16:45:08 -0800 Subject: [PATCH 287/901] Update dependency com.fasterxml.jackson:jackson-bom to v2.16.2 (#6281) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- dependencyManagement/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index f136adcdc3d..28868b7bbb0 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -8,7 +8,7 @@ val dependencyVersions = hashMapOf() rootProject.extra["versions"] = dependencyVersions val DEPENDENCY_BOMS = listOf( - "com.fasterxml.jackson:jackson-bom:2.16.1", + "com.fasterxml.jackson:jackson-bom:2.16.2", "com.google.guava:guava-bom:33.0.0-jre", "com.google.protobuf:protobuf-bom:3.25.3", "com.linecorp.armeria:armeria-bom:1.27.2", From 97609a9bdde95afe64e42fa6cca98fc6364fc4a5 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 11 Mar 2024 13:04:03 -0700 Subject: [PATCH 288/901] Update dependency checkstyle to v10.14.1 (#6283) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- buildSrc/src/main/kotlin/otel.java-conventions.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/buildSrc/src/main/kotlin/otel.java-conventions.gradle.kts b/buildSrc/src/main/kotlin/otel.java-conventions.gradle.kts index 9a75d525dc6..0a2ecb5154d 100644 --- a/buildSrc/src/main/kotlin/otel.java-conventions.gradle.kts +++ b/buildSrc/src/main/kotlin/otel.java-conventions.gradle.kts @@ -35,7 +35,7 @@ java { checkstyle { configDirectory.set(file("$rootDir/buildscripts/")) - toolVersion = "10.14.0" + toolVersion = "10.14.1" isIgnoreFailures = false configProperties["rootDir"] = rootDir } From 7655192df504d28da2d2013f2fc49ec44ef6202e Mon Sep 17 00:00:00 2001 From: jack-berg <34418638+jack-berg@users.noreply.github.com> Date: Tue, 12 Mar 2024 09:43:19 -0500 Subject: [PATCH 289/901] Add autoconfigure console alias for logging exporter (#6027) --- .../ConsoleLogRecordExporterProvider.java | 30 +++++++++++++++++++ .../ConsoleMetricExporterProvider.java | 29 ++++++++++++++++++ .../internal/ConsoleSpanExporterProvider.java | 29 ++++++++++++++++++ .../LoggingLogRecordExporterProvider.java | 7 ++++- .../LoggingMetricExporterProvider.java | 6 +++- .../internal/LoggingSpanExporterProvider.java | 6 +++- ...logs.ConfigurableLogRecordExporterProvider | 1 + ...metrics.ConfigurableMetricExporterProvider | 1 + ...pi.traces.ConfigurableSpanExporterProvider | 1 + sdk-extensions/autoconfigure/README.md | 11 +++++-- .../LogRecordExporterConfiguration.java | 1 + .../LoggerProviderConfiguration.java | 16 ++++++---- .../MetricExporterConfiguration.java | 1 + .../SpanExporterConfiguration.java | 1 + .../TracerProviderConfiguration.java | 15 ++++++---- .../ConfigurableSpanExporterTest.java | 16 ++++++---- .../LogRecordExporterConfigurationTest.java | 2 ++ .../LoggerProviderConfigurationTest.java | 30 +++++++++++-------- .../SpanExporterConfigurationTest.java | 2 ++ 19 files changed, 172 insertions(+), 33 deletions(-) create mode 100644 exporters/logging/src/main/java/io/opentelemetry/exporter/logging/internal/ConsoleLogRecordExporterProvider.java create mode 100644 exporters/logging/src/main/java/io/opentelemetry/exporter/logging/internal/ConsoleMetricExporterProvider.java create mode 100644 exporters/logging/src/main/java/io/opentelemetry/exporter/logging/internal/ConsoleSpanExporterProvider.java diff --git a/exporters/logging/src/main/java/io/opentelemetry/exporter/logging/internal/ConsoleLogRecordExporterProvider.java b/exporters/logging/src/main/java/io/opentelemetry/exporter/logging/internal/ConsoleLogRecordExporterProvider.java new file mode 100644 index 00000000000..e9911c8fd86 --- /dev/null +++ b/exporters/logging/src/main/java/io/opentelemetry/exporter/logging/internal/ConsoleLogRecordExporterProvider.java @@ -0,0 +1,30 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.exporter.logging.internal; + +import io.opentelemetry.exporter.logging.SystemOutLogRecordExporter; +import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties; +import io.opentelemetry.sdk.autoconfigure.spi.logs.ConfigurableLogRecordExporterProvider; +import io.opentelemetry.sdk.logs.export.LogRecordExporter; + +/** + * {@link LogRecordExporter} SPI implementation for {@link SystemOutLogRecordExporter}. + * + *

    This class is internal and is hence not for public use. Its APIs are unstable and can change + * at any time. + */ +public final class ConsoleLogRecordExporterProvider + implements ConfigurableLogRecordExporterProvider { + @Override + public LogRecordExporter createExporter(ConfigProperties config) { + return SystemOutLogRecordExporter.create(); + } + + @Override + public String getName() { + return "console"; + } +} diff --git a/exporters/logging/src/main/java/io/opentelemetry/exporter/logging/internal/ConsoleMetricExporterProvider.java b/exporters/logging/src/main/java/io/opentelemetry/exporter/logging/internal/ConsoleMetricExporterProvider.java new file mode 100644 index 00000000000..66983914a56 --- /dev/null +++ b/exporters/logging/src/main/java/io/opentelemetry/exporter/logging/internal/ConsoleMetricExporterProvider.java @@ -0,0 +1,29 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.exporter.logging.internal; + +import io.opentelemetry.exporter.logging.LoggingMetricExporter; +import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties; +import io.opentelemetry.sdk.autoconfigure.spi.metrics.ConfigurableMetricExporterProvider; +import io.opentelemetry.sdk.metrics.export.MetricExporter; + +/** + * {@link MetricExporter} SPI implementation for {@link LoggingMetricExporter}. + * + *

    This class is internal and is hence not for public use. Its APIs are unstable and can change + * at any time. + */ +public final class ConsoleMetricExporterProvider implements ConfigurableMetricExporterProvider { + @Override + public MetricExporter createExporter(ConfigProperties config) { + return LoggingMetricExporter.create(); + } + + @Override + public String getName() { + return "console"; + } +} diff --git a/exporters/logging/src/main/java/io/opentelemetry/exporter/logging/internal/ConsoleSpanExporterProvider.java b/exporters/logging/src/main/java/io/opentelemetry/exporter/logging/internal/ConsoleSpanExporterProvider.java new file mode 100644 index 00000000000..220bd2d6ef0 --- /dev/null +++ b/exporters/logging/src/main/java/io/opentelemetry/exporter/logging/internal/ConsoleSpanExporterProvider.java @@ -0,0 +1,29 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.exporter.logging.internal; + +import io.opentelemetry.exporter.logging.LoggingSpanExporter; +import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties; +import io.opentelemetry.sdk.autoconfigure.spi.traces.ConfigurableSpanExporterProvider; +import io.opentelemetry.sdk.trace.export.SpanExporter; + +/** + * {@link SpanExporter} SPI implementation for {@link LoggingSpanExporter}. + * + *

    This class is internal and is hence not for public use. Its APIs are unstable and can change + * at any time. + */ +public final class ConsoleSpanExporterProvider implements ConfigurableSpanExporterProvider { + @Override + public SpanExporter createExporter(ConfigProperties config) { + return LoggingSpanExporter.create(); + } + + @Override + public String getName() { + return "console"; + } +} diff --git a/exporters/logging/src/main/java/io/opentelemetry/exporter/logging/internal/LoggingLogRecordExporterProvider.java b/exporters/logging/src/main/java/io/opentelemetry/exporter/logging/internal/LoggingLogRecordExporterProvider.java index e6fbd6fbc8d..d84c4a9c0e8 100644 --- a/exporters/logging/src/main/java/io/opentelemetry/exporter/logging/internal/LoggingLogRecordExporterProvider.java +++ b/exporters/logging/src/main/java/io/opentelemetry/exporter/logging/internal/LoggingLogRecordExporterProvider.java @@ -15,8 +15,13 @@ * *

    This class is internal and is hence not for public use. Its APIs are unstable and can change * at any time. + * + * @deprecated The name {@code logging} is a deprecated alias for {@code console}, which is provided + * via {@link ConsoleLogRecordExporterProvider}. */ -public class LoggingLogRecordExporterProvider implements ConfigurableLogRecordExporterProvider { +@Deprecated +public final class LoggingLogRecordExporterProvider + implements ConfigurableLogRecordExporterProvider { @Override public LogRecordExporter createExporter(ConfigProperties config) { return SystemOutLogRecordExporter.create(); diff --git a/exporters/logging/src/main/java/io/opentelemetry/exporter/logging/internal/LoggingMetricExporterProvider.java b/exporters/logging/src/main/java/io/opentelemetry/exporter/logging/internal/LoggingMetricExporterProvider.java index 47605ac1154..479e7625202 100644 --- a/exporters/logging/src/main/java/io/opentelemetry/exporter/logging/internal/LoggingMetricExporterProvider.java +++ b/exporters/logging/src/main/java/io/opentelemetry/exporter/logging/internal/LoggingMetricExporterProvider.java @@ -15,8 +15,12 @@ * *

    This class is internal and is hence not for public use. Its APIs are unstable and can change * at any time. + * + * @deprecated The name {@code logging} is a deprecated alias for {@code console}, which is provided + * via {@link ConsoleMetricExporterProvider}. */ -public class LoggingMetricExporterProvider implements ConfigurableMetricExporterProvider { +@Deprecated +public final class LoggingMetricExporterProvider implements ConfigurableMetricExporterProvider { @Override public MetricExporter createExporter(ConfigProperties config) { return LoggingMetricExporter.create(); diff --git a/exporters/logging/src/main/java/io/opentelemetry/exporter/logging/internal/LoggingSpanExporterProvider.java b/exporters/logging/src/main/java/io/opentelemetry/exporter/logging/internal/LoggingSpanExporterProvider.java index 5854a12fe64..24f40ce1867 100644 --- a/exporters/logging/src/main/java/io/opentelemetry/exporter/logging/internal/LoggingSpanExporterProvider.java +++ b/exporters/logging/src/main/java/io/opentelemetry/exporter/logging/internal/LoggingSpanExporterProvider.java @@ -15,8 +15,12 @@ * *

    This class is internal and is hence not for public use. Its APIs are unstable and can change * at any time. + * + * @deprecated The name {@code logging} is a deprecated alias for {@code console}, which is provided + * via {@link ConsoleSpanExporterProvider}. */ -public class LoggingSpanExporterProvider implements ConfigurableSpanExporterProvider { +@Deprecated +public final class LoggingSpanExporterProvider implements ConfigurableSpanExporterProvider { @Override public SpanExporter createExporter(ConfigProperties config) { return LoggingSpanExporter.create(); diff --git a/exporters/logging/src/main/resources/META-INF/services/io.opentelemetry.sdk.autoconfigure.spi.logs.ConfigurableLogRecordExporterProvider b/exporters/logging/src/main/resources/META-INF/services/io.opentelemetry.sdk.autoconfigure.spi.logs.ConfigurableLogRecordExporterProvider index 8d8842825ba..29f8e2db2da 100644 --- a/exporters/logging/src/main/resources/META-INF/services/io.opentelemetry.sdk.autoconfigure.spi.logs.ConfigurableLogRecordExporterProvider +++ b/exporters/logging/src/main/resources/META-INF/services/io.opentelemetry.sdk.autoconfigure.spi.logs.ConfigurableLogRecordExporterProvider @@ -1 +1,2 @@ io.opentelemetry.exporter.logging.internal.LoggingLogRecordExporterProvider +io.opentelemetry.exporter.logging.internal.ConsoleLogRecordExporterProvider diff --git a/exporters/logging/src/main/resources/META-INF/services/io.opentelemetry.sdk.autoconfigure.spi.metrics.ConfigurableMetricExporterProvider b/exporters/logging/src/main/resources/META-INF/services/io.opentelemetry.sdk.autoconfigure.spi.metrics.ConfigurableMetricExporterProvider index 3ad21a55ccd..3bdcd20b33f 100644 --- a/exporters/logging/src/main/resources/META-INF/services/io.opentelemetry.sdk.autoconfigure.spi.metrics.ConfigurableMetricExporterProvider +++ b/exporters/logging/src/main/resources/META-INF/services/io.opentelemetry.sdk.autoconfigure.spi.metrics.ConfigurableMetricExporterProvider @@ -1 +1,2 @@ io.opentelemetry.exporter.logging.internal.LoggingMetricExporterProvider +io.opentelemetry.exporter.logging.internal.ConsoleMetricExporterProvider diff --git a/exporters/logging/src/main/resources/META-INF/services/io.opentelemetry.sdk.autoconfigure.spi.traces.ConfigurableSpanExporterProvider b/exporters/logging/src/main/resources/META-INF/services/io.opentelemetry.sdk.autoconfigure.spi.traces.ConfigurableSpanExporterProvider index 8806e4b9608..682519c7938 100644 --- a/exporters/logging/src/main/resources/META-INF/services/io.opentelemetry.sdk.autoconfigure.spi.traces.ConfigurableSpanExporterProvider +++ b/exporters/logging/src/main/resources/META-INF/services/io.opentelemetry.sdk.autoconfigure.spi.traces.ConfigurableSpanExporterProvider @@ -1 +1,2 @@ io.opentelemetry.exporter.logging.internal.LoggingSpanExporterProvider +io.opentelemetry.exporter.logging.internal.ConsoleSpanExporterProvider diff --git a/sdk-extensions/autoconfigure/README.md b/sdk-extensions/autoconfigure/README.md index fdd3855b82d..8e6e68cbabc 100644 --- a/sdk-extensions/autoconfigure/README.md +++ b/sdk-extensions/autoconfigure/README.md @@ -143,9 +143,14 @@ The logging exporter prints the name of the span along with its attributes to st | System property | Environment variable | Description | |-------------------------------|-------------------------------|----------------------------------------------------------------------| -| otel.traces.exporter=logging | OTEL_TRACES_EXPORTER=logging | Select the logging exporter for tracing | -| otel.metrics.exporter=logging | OTEL_METRICS_EXPORTER=logging | Select the logging exporter for metrics | -| otel.logs.exporter=logging | OTEL_LOGS_EXPORTER=logging | Select the logging exporter for logs | +| otel.traces.exporter=console | OTEL_TRACES_EXPORTER=console | Select the logging exporter for tracing | +| otel.metrics.exporter=console | OTEL_METRICS_EXPORTER=console | Select the logging exporter for metrics | +| otel.logs.exporter=console | OTEL_LOGS_EXPORTER=console | Select the logging exporter for logs | + +The logging exporter is also set when `otel.traces.exporter`, `otel.metrics.exporter`, +or `otel.logs.exporter` is set to `logging`. `logging` is a deprecated alias for `console`, the +preferred value +as [defined in the specification](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/configuration/sdk-environment-variables.md#exporter-selection). #### Logging OTLP JSON exporter diff --git a/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/LogRecordExporterConfiguration.java b/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/LogRecordExporterConfiguration.java index b0eeb2481c0..eacdf9d7c9a 100644 --- a/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/LogRecordExporterConfiguration.java +++ b/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/LogRecordExporterConfiguration.java @@ -27,6 +27,7 @@ final class LogRecordExporterConfiguration { static { EXPORTER_ARTIFACT_ID_BY_NAME = new HashMap<>(); + EXPORTER_ARTIFACT_ID_BY_NAME.put("console", "opentelemetry-exporter-logging"); EXPORTER_ARTIFACT_ID_BY_NAME.put("logging", "opentelemetry-exporter-logging"); EXPORTER_ARTIFACT_ID_BY_NAME.put("logging-otlp", "opentelemetry-exporter-logging-otlp"); EXPORTER_ARTIFACT_ID_BY_NAME.put("otlp", "opentelemetry-exporter-otlp"); diff --git a/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/LoggerProviderConfiguration.java b/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/LoggerProviderConfiguration.java index ff94550ecbb..f762915dc41 100644 --- a/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/LoggerProviderConfiguration.java +++ b/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/LoggerProviderConfiguration.java @@ -21,6 +21,7 @@ import java.io.Closeable; import java.time.Duration; import java.util.ArrayList; +import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -28,6 +29,9 @@ final class LoggerProviderConfiguration { + private static final List simpleProcessorExporterNames = + Arrays.asList("console", "logging"); + static void configureLoggerProvider( SdkLoggerProviderBuilder loggerProviderBuilder, ConfigProperties config, @@ -64,11 +68,13 @@ static List configureLogRecordProcessors( Map exportersByNameCopy = new HashMap<>(exportersByName); List logRecordProcessors = new ArrayList<>(); - LogRecordExporter exporter = exportersByNameCopy.remove("logging"); - if (exporter != null) { - LogRecordProcessor logRecordProcessor = SimpleLogRecordProcessor.create(exporter); - closeables.add(logRecordProcessor); - logRecordProcessors.add(logRecordProcessor); + for (String simpleProcessorExporterName : simpleProcessorExporterNames) { + LogRecordExporter exporter = exportersByNameCopy.remove(simpleProcessorExporterName); + if (exporter != null) { + LogRecordProcessor logRecordProcessor = SimpleLogRecordProcessor.create(exporter); + closeables.add(logRecordProcessor); + logRecordProcessors.add(logRecordProcessor); + } } if (!exportersByNameCopy.isEmpty()) { diff --git a/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/MetricExporterConfiguration.java b/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/MetricExporterConfiguration.java index 3b4a1da1658..c2a63569812 100644 --- a/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/MetricExporterConfiguration.java +++ b/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/MetricExporterConfiguration.java @@ -30,6 +30,7 @@ final class MetricExporterConfiguration { static { EXPORTER_ARTIFACT_ID_BY_NAME = new HashMap<>(); + EXPORTER_ARTIFACT_ID_BY_NAME.put("console", "opentelemetry-exporter-logging"); EXPORTER_ARTIFACT_ID_BY_NAME.put("logging", "opentelemetry-exporter-logging"); EXPORTER_ARTIFACT_ID_BY_NAME.put("logging-otlp", "opentelemetry-exporter-logging-otlp"); EXPORTER_ARTIFACT_ID_BY_NAME.put("otlp", "opentelemetry-exporter-otlp"); diff --git a/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/SpanExporterConfiguration.java b/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/SpanExporterConfiguration.java index c5da0e0a045..581ce575b81 100644 --- a/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/SpanExporterConfiguration.java +++ b/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/SpanExporterConfiguration.java @@ -27,6 +27,7 @@ final class SpanExporterConfiguration { static { EXPORTER_ARTIFACT_ID_BY_NAME = new HashMap<>(); + EXPORTER_ARTIFACT_ID_BY_NAME.put("console", "opentelemetry-exporter-logging"); EXPORTER_ARTIFACT_ID_BY_NAME.put("jaeger", "opentelemetry-exporter-jaeger"); EXPORTER_ARTIFACT_ID_BY_NAME.put("logging", "opentelemetry-exporter-logging"); EXPORTER_ARTIFACT_ID_BY_NAME.put("logging-otlp", "opentelemetry-exporter-logging-otlp"); diff --git a/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/TracerProviderConfiguration.java b/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/TracerProviderConfiguration.java index b2e2a3858c8..ee6d75d4c70 100644 --- a/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/TracerProviderConfiguration.java +++ b/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/TracerProviderConfiguration.java @@ -23,6 +23,7 @@ import java.io.Closeable; import java.time.Duration; import java.util.ArrayList; +import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -32,6 +33,8 @@ final class TracerProviderConfiguration { private static final double DEFAULT_TRACEIDRATIO_SAMPLE_RATIO = 1.0d; private static final String PARENTBASED_ALWAYS_ON = "parentbased_always_on"; + private static final List simpleProcessorExporterNames = + Arrays.asList("console", "logging"); static void configureTracerProvider( SdkTracerProviderBuilder tracerProviderBuilder, @@ -74,11 +77,13 @@ static List configureSpanProcessors( Map exportersByNameCopy = new HashMap<>(exportersByName); List spanProcessors = new ArrayList<>(); - SpanExporter exporter = exportersByNameCopy.remove("logging"); - if (exporter != null) { - SpanProcessor spanProcessor = SimpleSpanProcessor.create(exporter); - closeables.add(spanProcessor); - spanProcessors.add(spanProcessor); + for (String simpleProcessorExporterNames : simpleProcessorExporterNames) { + SpanExporter exporter = exportersByNameCopy.remove(simpleProcessorExporterNames); + if (exporter != null) { + SpanProcessor spanProcessor = SimpleSpanProcessor.create(exporter); + closeables.add(spanProcessor); + spanProcessors.add(spanProcessor); + } } if (!exportersByNameCopy.isEmpty()) { diff --git a/sdk-extensions/autoconfigure/src/testFullConfig/java/io/opentelemetry/sdk/autoconfigure/ConfigurableSpanExporterTest.java b/sdk-extensions/autoconfigure/src/testFullConfig/java/io/opentelemetry/sdk/autoconfigure/ConfigurableSpanExporterTest.java index ef533b82ac3..d2c66386092 100644 --- a/sdk-extensions/autoconfigure/src/testFullConfig/java/io/opentelemetry/sdk/autoconfigure/ConfigurableSpanExporterTest.java +++ b/sdk-extensions/autoconfigure/src/testFullConfig/java/io/opentelemetry/sdk/autoconfigure/ConfigurableSpanExporterTest.java @@ -30,6 +30,7 @@ import java.net.URLClassLoader; import java.util.ArrayList; import java.util.Collections; +import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import org.assertj.core.api.InstanceOfAssertFactories; @@ -137,20 +138,25 @@ void configureExporter_NotFound() { @Test void configureSpanProcessors_simpleSpanProcessor() { - String exporterName = "logging"; List closeables = new ArrayList<>(); + Map exportersByName = new LinkedHashMap<>(); + exportersByName.put("console", LoggingSpanExporter.create()); + exportersByName.put("logging", LoggingSpanExporter.create()); + List spanProcessors = TracerProviderConfiguration.configureSpanProcessors( DefaultConfigProperties.createFromMap( - Collections.singletonMap("otel.traces.exporter", exporterName)), - ImmutableMap.of(exporterName, LoggingSpanExporter.create()), + Collections.singletonMap("otel.traces.exporter", "console,logging")), + exportersByName, MeterProvider.noop(), closeables); cleanup.addCloseables(closeables); - assertThat(spanProcessors).hasExactlyElementsOfTypes(SimpleSpanProcessor.class); - assertThat(closeables).hasExactlyElementsOfTypes(SimpleSpanProcessor.class); + assertThat(spanProcessors) + .hasExactlyElementsOfTypes(SimpleSpanProcessor.class, SimpleSpanProcessor.class); + assertThat(closeables) + .hasExactlyElementsOfTypes(SimpleSpanProcessor.class, SimpleSpanProcessor.class); } @Test diff --git a/sdk-extensions/autoconfigure/src/testFullConfig/java/io/opentelemetry/sdk/autoconfigure/LogRecordExporterConfigurationTest.java b/sdk-extensions/autoconfigure/src/testFullConfig/java/io/opentelemetry/sdk/autoconfigure/LogRecordExporterConfigurationTest.java index 9764d7db8b3..1d670b0e04e 100644 --- a/sdk-extensions/autoconfigure/src/testFullConfig/java/io/opentelemetry/sdk/autoconfigure/LogRecordExporterConfigurationTest.java +++ b/sdk-extensions/autoconfigure/src/testFullConfig/java/io/opentelemetry/sdk/autoconfigure/LogRecordExporterConfigurationTest.java @@ -31,6 +31,8 @@ void configureExporter_KnownSpiExportersOnClasspath() { LogRecordExporterConfiguration.logRecordExporterSpiManager( DefaultConfigProperties.createFromMap(Collections.emptyMap()), spiHelper); + assertThat(LogRecordExporterConfiguration.configureExporter("console", spiExportersManager)) + .isInstanceOf(SystemOutLogRecordExporter.class); assertThat(LogRecordExporterConfiguration.configureExporter("logging", spiExportersManager)) .isInstanceOf(SystemOutLogRecordExporter.class); assertThat( diff --git a/sdk-extensions/autoconfigure/src/testFullConfig/java/io/opentelemetry/sdk/autoconfigure/LoggerProviderConfigurationTest.java b/sdk-extensions/autoconfigure/src/testFullConfig/java/io/opentelemetry/sdk/autoconfigure/LoggerProviderConfigurationTest.java index 6603abf7497..d3856cd93c2 100644 --- a/sdk-extensions/autoconfigure/src/testFullConfig/java/io/opentelemetry/sdk/autoconfigure/LoggerProviderConfigurationTest.java +++ b/sdk-extensions/autoconfigure/src/testFullConfig/java/io/opentelemetry/sdk/autoconfigure/LoggerProviderConfigurationTest.java @@ -7,7 +7,6 @@ import static org.assertj.core.api.Assertions.assertThat; -import com.google.common.collect.ImmutableMap; import io.opentelemetry.api.metrics.MeterProvider; import io.opentelemetry.exporter.logging.SystemOutLogRecordExporter; import io.opentelemetry.exporter.otlp.logs.OtlpGrpcLogRecordExporter; @@ -18,12 +17,14 @@ import io.opentelemetry.sdk.logs.SdkLoggerProvider; import io.opentelemetry.sdk.logs.SdkLoggerProviderBuilder; import io.opentelemetry.sdk.logs.export.BatchLogRecordProcessor; +import io.opentelemetry.sdk.logs.export.LogRecordExporter; import io.opentelemetry.sdk.logs.export.SimpleLogRecordProcessor; import io.opentelemetry.sdk.trace.internal.JcTools; import java.io.Closeable; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; +import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.Queue; @@ -85,26 +86,31 @@ void configureLoggerProvider() { void configureLogRecordProcessors_multipleExportersWithLogging() { List closeables = new ArrayList<>(); + Map exportersByName = new LinkedHashMap<>(); + exportersByName.put("console", SystemOutLogRecordExporter.create()); + exportersByName.put("logging", SystemOutLogRecordExporter.create()); + exportersByName.put("otlp", OtlpGrpcLogRecordExporter.builder().build()); + List logRecordProcessors = LoggerProviderConfiguration.configureLogRecordProcessors( DefaultConfigProperties.createFromMap(Collections.emptyMap()), - ImmutableMap.of( - "logging", - SystemOutLogRecordExporter.create(), - "otlp", - OtlpGrpcLogRecordExporter.builder().build()), + exportersByName, MeterProvider.noop(), closeables); cleanup.addCloseables(closeables); assertThat(logRecordProcessors) - .hasSize(2) - .hasAtLeastOneElementOfType(SimpleLogRecordProcessor.class) - .hasAtLeastOneElementOfType(BatchLogRecordProcessor.class); + .hasSize(3) + .hasExactlyElementsOfTypes( + SimpleLogRecordProcessor.class, + SimpleLogRecordProcessor.class, + BatchLogRecordProcessor.class); assertThat(closeables) - .hasSize(2) - .hasAtLeastOneElementOfType(SimpleLogRecordProcessor.class) - .hasAtLeastOneElementOfType(BatchLogRecordProcessor.class); + .hasSize(3) + .hasExactlyElementsOfTypes( + SimpleLogRecordProcessor.class, + SimpleLogRecordProcessor.class, + BatchLogRecordProcessor.class); } @Test diff --git a/sdk-extensions/autoconfigure/src/testFullConfig/java/io/opentelemetry/sdk/autoconfigure/SpanExporterConfigurationTest.java b/sdk-extensions/autoconfigure/src/testFullConfig/java/io/opentelemetry/sdk/autoconfigure/SpanExporterConfigurationTest.java index 340d322dfc8..64e4a55e91a 100644 --- a/sdk-extensions/autoconfigure/src/testFullConfig/java/io/opentelemetry/sdk/autoconfigure/SpanExporterConfigurationTest.java +++ b/sdk-extensions/autoconfigure/src/testFullConfig/java/io/opentelemetry/sdk/autoconfigure/SpanExporterConfigurationTest.java @@ -33,6 +33,8 @@ void configureExporter_KnownSpiExportersOnClasspath() { SpanExporterConfiguration.spanExporterSpiManager( DefaultConfigProperties.createFromMap(Collections.emptyMap()), spiHelper); + assertThat(SpanExporterConfiguration.configureExporter("console", spiExportersManager)) + .isInstanceOf(LoggingSpanExporter.class); assertThat(SpanExporterConfiguration.configureExporter("logging", spiExportersManager)) .isInstanceOf(LoggingSpanExporter.class); assertThat(SpanExporterConfiguration.configureExporter("logging-otlp", spiExportersManager)) From 7831f2ab2dcaea53fb40d727dc1a722e50ab491d Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 12 Mar 2024 08:03:02 -0700 Subject: [PATCH 290/901] Update errorProneVersion to v2.26.0 (#6286) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- dependencyManagement/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index 28868b7bbb0..1c86e0446f5 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -25,7 +25,7 @@ val DEPENDENCY_BOMS = listOf( ) val autoValueVersion = "1.10.4" -val errorProneVersion = "2.25.0" +val errorProneVersion = "2.26.0" val jmhVersion = "1.37" // Mockito 5.x.x requires Java 11 https://github.com/mockito/mockito/releases/tag/v5.0.0 val mockitoVersion = "4.11.0" From 34b64b1f772f9e6d3874470e86713fc4675abbd1 Mon Sep 17 00:00:00 2001 From: jason plumb <75337021+breedx-splk@users.noreply.github.com> Date: Tue, 12 Mar 2024 12:27:33 -0700 Subject: [PATCH 291/901] Remove domain from event api. (#6253) Co-authored-by: Trask Stalnaker --- .../events/DefaultEventEmitterProvider.java | 5 -- .../api/events/EventEmitter.java | 4 +- .../api/events/EventEmitterBuilder.java | 9 ---- .../DefaultEventEmitterProviderTest.java | 1 - .../api/events/DefaultEventEmitterTest.java | 6 ++- .../OtlpExporterIntegrationTest.java | 5 -- .../sdk/autoconfigure/FullConfigTest.java | 9 +--- .../sdk/logs/internal/SdkEventBuilder.java | 6 +-- .../internal/SdkEventEmitterProvider.java | 28 +++-------- .../logs/internal/SdkEventBuilderTest.java | 8 ++-- .../internal/SdkEventEmitterProviderTest.java | 46 ++----------------- 11 files changed, 23 insertions(+), 104 deletions(-) diff --git a/api/events/src/main/java/io/opentelemetry/api/events/DefaultEventEmitterProvider.java b/api/events/src/main/java/io/opentelemetry/api/events/DefaultEventEmitterProvider.java index 2f5b69826fd..59f75872fa1 100644 --- a/api/events/src/main/java/io/opentelemetry/api/events/DefaultEventEmitterProvider.java +++ b/api/events/src/main/java/io/opentelemetry/api/events/DefaultEventEmitterProvider.java @@ -34,11 +34,6 @@ public EventEmitterBuilder setInstrumentationVersion(String instrumentationVersi return this; } - @Override - public EventEmitterBuilder setEventDomain(String eventDomain) { - return this; - } - @Override public EventEmitter build() { return DefaultEventEmitter.getInstance(); diff --git a/api/events/src/main/java/io/opentelemetry/api/events/EventEmitter.java b/api/events/src/main/java/io/opentelemetry/api/events/EventEmitter.java index a8dc47c83d7..395fa4e53e5 100644 --- a/api/events/src/main/java/io/opentelemetry/api/events/EventEmitter.java +++ b/api/events/src/main/java/io/opentelemetry/api/events/EventEmitter.java @@ -15,8 +15,8 @@ * *

    {@code
      * class MyClass {
    - *   private final EventEmitter eventEmitter = openTelemetryEventEmitterProvider.eventEmitterBuilder("scope-name")
    - *         .setEventDomain("acme.observability")
    + *   private final EventEmitter eventEmitter = openTelemetryEventEmitterProvider
    + *         .eventEmitterBuilder("scope-name")
      *         .build();
      *
      *   void doWork() {
    diff --git a/api/events/src/main/java/io/opentelemetry/api/events/EventEmitterBuilder.java b/api/events/src/main/java/io/opentelemetry/api/events/EventEmitterBuilder.java
    index 0aa67a25b08..0bdb9e2f57e 100644
    --- a/api/events/src/main/java/io/opentelemetry/api/events/EventEmitterBuilder.java
    +++ b/api/events/src/main/java/io/opentelemetry/api/events/EventEmitterBuilder.java
    @@ -14,15 +14,6 @@
      */
     public interface EventEmitterBuilder {
     
    -  /**
    -   * Sets the event domain. Event domain is not part of {@link EventEmitter} identity.
    -   *
    -   * @param eventDomain The event domain, which acts as a namespace for event names. Within a
    -   *     particular event domain, event name defines a particular class or type of event.
    -   * @return this
    -   */
    -  EventEmitterBuilder setEventDomain(String eventDomain);
    -
       /**
        * Set the scope schema URL of the resulting {@link EventEmitter}. Schema URL is part of {@link
        * EventEmitter} identity.
    diff --git a/api/events/src/test/java/io/opentelemetry/api/events/DefaultEventEmitterProviderTest.java b/api/events/src/test/java/io/opentelemetry/api/events/DefaultEventEmitterProviderTest.java
    index 33651e89c6e..04c5cc83e86 100644
    --- a/api/events/src/test/java/io/opentelemetry/api/events/DefaultEventEmitterProviderTest.java
    +++ b/api/events/src/test/java/io/opentelemetry/api/events/DefaultEventEmitterProviderTest.java
    @@ -23,7 +23,6 @@ void noopEventEmitterProvider_doesNotThrow() {
                 () ->
                     provider
                         .eventEmitterBuilder("scope-name")
    -                    .setEventDomain("event-domain")
                         .setInstrumentationVersion("1.0")
                         .setSchemaUrl("http://schema.com")
                         .build())
    diff --git a/api/events/src/test/java/io/opentelemetry/api/events/DefaultEventEmitterTest.java b/api/events/src/test/java/io/opentelemetry/api/events/DefaultEventEmitterTest.java
    index 460cb1583ac..324680d13d6 100644
    --- a/api/events/src/test/java/io/opentelemetry/api/events/DefaultEventEmitterTest.java
    +++ b/api/events/src/test/java/io/opentelemetry/api/events/DefaultEventEmitterTest.java
    @@ -21,7 +21,9 @@ void emit() {
         assertThatCode(
                 () ->
                     DefaultEventEmitter.getInstance()
    -                    .emit("event-name", Attributes.builder().put("key1", "value1").build()))
    +                    .emit(
    +                        "event-domain.event-name",
    +                        Attributes.builder().put("key1", "value1").build()))
             .doesNotThrowAnyException();
       }
     
    @@ -32,7 +34,7 @@ void builder() {
         assertThatCode(
                 () ->
                     emitter
    -                    .builder("myEvent", attributes)
    +                    .builder("com.example.MyEvent", attributes)
                         .setTimestamp(123456L, TimeUnit.NANOSECONDS)
                         .setTimestamp(Instant.now())
                         .emit())
    diff --git a/integration-tests/otlp/src/main/java/io/opentelemetry/integrationtest/OtlpExporterIntegrationTest.java b/integration-tests/otlp/src/main/java/io/opentelemetry/integrationtest/OtlpExporterIntegrationTest.java
    index 271409e8ea3..30ab713b118 100644
    --- a/integration-tests/otlp/src/main/java/io/opentelemetry/integrationtest/OtlpExporterIntegrationTest.java
    +++ b/integration-tests/otlp/src/main/java/io/opentelemetry/integrationtest/OtlpExporterIntegrationTest.java
    @@ -536,7 +536,6 @@ private static void testLogRecordExporter(LogRecordExporter logRecordExporter) {
         EventEmitter eventEmitter =
             SdkEventEmitterProvider.create(loggerProvider)
                 .eventEmitterBuilder(OtlpExporterIntegrationTest.class.getName())
    -            .setEventDomain("event-domain")
                 .build();
     
         SpanContext spanContext =
    @@ -712,10 +711,6 @@ private static void testLogRecordExporter(LogRecordExporter logRecordExporter) {
         assertThat(protoLog2.getBody().getStringValue()).isEmpty();
         assertThat(protoLog2.getAttributesList())
             .containsExactlyInAnyOrder(
    -            KeyValue.newBuilder()
    -                .setKey("event.domain")
    -                .setValue(AnyValue.newBuilder().setStringValue("event-domain").build())
    -                .build(),
                 KeyValue.newBuilder()
                     .setKey("event.name")
                     .setValue(AnyValue.newBuilder().setStringValue("event-name").build())
    diff --git a/sdk-extensions/autoconfigure/src/testFullConfig/java/io/opentelemetry/sdk/autoconfigure/FullConfigTest.java b/sdk-extensions/autoconfigure/src/testFullConfig/java/io/opentelemetry/sdk/autoconfigure/FullConfigTest.java
    index affe5d4fd63..3015339f71e 100644
    --- a/sdk-extensions/autoconfigure/src/testFullConfig/java/io/opentelemetry/sdk/autoconfigure/FullConfigTest.java
    +++ b/sdk-extensions/autoconfigure/src/testFullConfig/java/io/opentelemetry/sdk/autoconfigure/FullConfigTest.java
    @@ -207,10 +207,7 @@ void configures() throws Exception {
         logger.logRecordBuilder().setBody("info log message").setSeverity(Severity.INFO).emit();
     
         EventEmitter eventEmitter =
    -        GlobalEventEmitterProvider.get()
    -            .eventEmitterBuilder("test")
    -            .setEventDomain("test-domain")
    -            .build();
    +        GlobalEventEmitterProvider.get().eventEmitterBuilder("test").build();
         eventEmitter.emit("test-name", Attributes.builder().put("cow", "moo").build());
     
         openTelemetrySdk.getSdkTracerProvider().forceFlush().join(10, TimeUnit.SECONDS);
    @@ -336,10 +333,6 @@ void configures() throws Exception {
                 logRecord ->
                     assertThat(logRecord.getAttributesList())
                         .containsExactlyInAnyOrder(
    -                        KeyValue.newBuilder()
    -                            .setKey("event.domain")
    -                            .setValue(AnyValue.newBuilder().setStringValue("test-domain").build())
    -                            .build(),
                             KeyValue.newBuilder()
                                 .setKey("event.name")
                                 .setValue(AnyValue.newBuilder().setStringValue("test-name").build())
    diff --git a/sdk/logs/src/main/java/io/opentelemetry/sdk/logs/internal/SdkEventBuilder.java b/sdk/logs/src/main/java/io/opentelemetry/sdk/logs/internal/SdkEventBuilder.java
    index a79b09babc3..aefa6832242 100644
    --- a/sdk/logs/src/main/java/io/opentelemetry/sdk/logs/internal/SdkEventBuilder.java
    +++ b/sdk/logs/src/main/java/io/opentelemetry/sdk/logs/internal/SdkEventBuilder.java
    @@ -12,12 +12,10 @@
     
     class SdkEventBuilder implements EventBuilder {
       private final LogRecordBuilder logRecordBuilder;
    -  private final String eventDomain;
       private final String eventName;
     
    -  SdkEventBuilder(LogRecordBuilder logRecordBuilder, String eventDomain, String eventName) {
    +  SdkEventBuilder(LogRecordBuilder logRecordBuilder, String eventName) {
         this.logRecordBuilder = logRecordBuilder;
    -    this.eventDomain = eventDomain;
         this.eventName = eventName;
       }
     
    @@ -35,7 +33,7 @@ public EventBuilder setTimestamp(Instant instant) {
     
       @Override
       public void emit() {
    -    SdkEventEmitterProvider.addEventNameAndDomain(logRecordBuilder, eventDomain, eventName);
    +    SdkEventEmitterProvider.addEventName(logRecordBuilder, eventName);
         logRecordBuilder.emit();
       }
     }
    diff --git a/sdk/logs/src/main/java/io/opentelemetry/sdk/logs/internal/SdkEventEmitterProvider.java b/sdk/logs/src/main/java/io/opentelemetry/sdk/logs/internal/SdkEventEmitterProvider.java
    index 1cc6768667e..885f46f7e94 100644
    --- a/sdk/logs/src/main/java/io/opentelemetry/sdk/logs/internal/SdkEventEmitterProvider.java
    +++ b/sdk/logs/src/main/java/io/opentelemetry/sdk/logs/internal/SdkEventEmitterProvider.java
    @@ -26,11 +26,8 @@
      */
     public final class SdkEventEmitterProvider implements EventEmitterProvider {
     
    -  static final AttributeKey EVENT_DOMAIN = AttributeKey.stringKey("event.domain");
       static final AttributeKey EVENT_NAME = AttributeKey.stringKey("event.name");
     
    -  static final String DEFAULT_EVENT_DOMAIN = "unknown";
    -
       private final LoggerProvider delegateLoggerProvider;
       private final Clock clock;
     
    @@ -55,9 +52,7 @@ public static SdkEventEmitterProvider create(LoggerProvider delegateLoggerProvid
     
       @Override
       public EventEmitter get(String instrumentationScopeName) {
    -    return eventEmitterBuilder(instrumentationScopeName)
    -        .setEventDomain(DEFAULT_EVENT_DOMAIN)
    -        .build();
    +    return eventEmitterBuilder(instrumentationScopeName).build();
       }
     
       @Override
    @@ -70,19 +65,12 @@ private static class SdkEventEmitterBuilder implements EventEmitterBuilder {
     
         private final Clock clock;
         private final LoggerBuilder delegateLoggerBuilder;
    -    private String eventDomain = DEFAULT_EVENT_DOMAIN;
     
         private SdkEventEmitterBuilder(Clock clock, LoggerBuilder delegateLoggerBuilder) {
           this.clock = clock;
           this.delegateLoggerBuilder = delegateLoggerBuilder;
         }
     
    -    @Override
    -    public EventEmitterBuilder setEventDomain(String eventDomain) {
    -      this.eventDomain = eventDomain;
    -      return this;
    -    }
    -
         @Override
         public EventEmitterBuilder setSchemaUrl(String schemaUrl) {
           delegateLoggerBuilder.setSchemaUrl(schemaUrl);
    @@ -97,7 +85,7 @@ public EventEmitterBuilder setInstrumentationVersion(String instrumentationScope
     
         @Override
         public EventEmitter build() {
    -      return new SdkEventEmitter(clock, delegateLoggerBuilder.build(), eventDomain);
    +      return new SdkEventEmitter(clock, delegateLoggerBuilder.build());
         }
       }
     
    @@ -105,12 +93,10 @@ private static class SdkEventEmitter implements EventEmitter {
     
         private final Clock clock;
         private final Logger delegateLogger;
    -    private final String eventDomain;
     
    -    private SdkEventEmitter(Clock clock, Logger delegateLogger, String eventDomain) {
    +    private SdkEventEmitter(Clock clock, Logger delegateLogger) {
           this.clock = clock;
           this.delegateLogger = delegateLogger;
    -      this.eventDomain = eventDomain;
         }
     
         @Override
    @@ -120,7 +106,6 @@ public EventBuilder builder(String eventName, Attributes attributes) {
                   .logRecordBuilder()
                   .setTimestamp(clock.now(), TimeUnit.NANOSECONDS)
                   .setAllAttributes(attributes),
    -          eventDomain,
               eventName);
         }
     
    @@ -131,13 +116,12 @@ public void emit(String eventName, Attributes attributes) {
                   .logRecordBuilder()
                   .setTimestamp(clock.now(), TimeUnit.NANOSECONDS)
                   .setAllAttributes(attributes);
    -      addEventNameAndDomain(logRecordBuilder, eventDomain, eventName);
    +      addEventName(logRecordBuilder, eventName);
           logRecordBuilder.emit();
         }
       }
     
    -  static void addEventNameAndDomain(
    -      LogRecordBuilder logRecordBuilder, String eventDomain, String eventName) {
    -    logRecordBuilder.setAttribute(EVENT_DOMAIN, eventDomain).setAttribute(EVENT_NAME, eventName);
    +  static void addEventName(LogRecordBuilder logRecordBuilder, String eventName) {
    +    logRecordBuilder.setAttribute(EVENT_NAME, eventName);
       }
     }
    diff --git a/sdk/logs/src/test/java/io/opentelemetry/sdk/logs/internal/SdkEventBuilderTest.java b/sdk/logs/src/test/java/io/opentelemetry/sdk/logs/internal/SdkEventBuilderTest.java
    index 2115463a771..e53fd6549a9 100644
    --- a/sdk/logs/src/test/java/io/opentelemetry/sdk/logs/internal/SdkEventBuilderTest.java
    +++ b/sdk/logs/src/test/java/io/opentelemetry/sdk/logs/internal/SdkEventBuilderTest.java
    @@ -8,7 +8,10 @@
     import static io.opentelemetry.api.common.AttributeKey.stringKey;
     import static org.mockito.ArgumentMatchers.any;
     import static org.mockito.ArgumentMatchers.anyLong;
    +import static org.mockito.ArgumentMatchers.anyString;
    +import static org.mockito.ArgumentMatchers.eq;
     import static org.mockito.Mockito.mock;
    +import static org.mockito.Mockito.never;
     import static org.mockito.Mockito.verify;
     import static org.mockito.Mockito.when;
     
    @@ -21,7 +24,6 @@ class SdkEventBuilderTest {
     
       @Test
       void emit() {
    -    String eventDomain = "mydomain";
         String eventName = "banana";
     
         LogRecordBuilder logRecordBuilder = mock(LogRecordBuilder.class);
    @@ -29,11 +31,11 @@ void emit() {
         when(logRecordBuilder.setAttribute(any(), any())).thenReturn(logRecordBuilder);
     
         Instant instant = Instant.now();
    -    new SdkEventBuilder(logRecordBuilder, eventDomain, eventName)
    +    new SdkEventBuilder(logRecordBuilder, eventName)
             .setTimestamp(123456L, TimeUnit.NANOSECONDS)
             .setTimestamp(instant)
             .emit();
    -    verify(logRecordBuilder).setAttribute(stringKey("event.domain"), eventDomain);
    +    verify(logRecordBuilder, never()).setAttribute(eq(stringKey("event.domain")), anyString());
         verify(logRecordBuilder).setAttribute(stringKey("event.name"), eventName);
         verify(logRecordBuilder).setTimestamp(123456L, TimeUnit.NANOSECONDS);
         verify(logRecordBuilder).setTimestamp(instant);
    diff --git a/sdk/logs/src/test/java/io/opentelemetry/sdk/logs/internal/SdkEventEmitterProviderTest.java b/sdk/logs/src/test/java/io/opentelemetry/sdk/logs/internal/SdkEventEmitterProviderTest.java
    index 7f22b1376a8..bf7e58ddc5f 100644
    --- a/sdk/logs/src/test/java/io/opentelemetry/sdk/logs/internal/SdkEventEmitterProviderTest.java
    +++ b/sdk/logs/src/test/java/io/opentelemetry/sdk/logs/internal/SdkEventEmitterProviderTest.java
    @@ -37,12 +37,11 @@ class SdkEventEmitterProviderTest {
               clock);
     
       @Test
    -  void emit_WithDomain() {
    +  void emit() {
         when(clock.now()).thenReturn(10L);
     
         eventEmitterProvider
             .eventEmitterBuilder("test-scope")
    -        .setEventDomain("event-domain")
             .build()
             .emit(
                 "event-name",
    @@ -50,8 +49,6 @@ void emit_WithDomain() {
                     .put("key1", "value1")
                     // should be overridden by the eventName argument passed to emit
                     .put("event.name", "foo")
    -                // should be overridden by the eventDomain
    -                .put("event.domain", "foo")
                     .build());
     
         assertThat(seenLog.get().toLogRecordData())
    @@ -59,40 +56,7 @@ void emit_WithDomain() {
             .hasInstrumentationScope(InstrumentationScopeInfo.create("test-scope"))
             .hasTimestamp(10L)
             .hasAttributes(
    -            Attributes.builder()
    -                .put("key1", "value1")
    -                .put("event.domain", "event-domain")
    -                .put("event.name", "event-name")
    -                .build());
    -  }
    -
    -  @Test
    -  void emit_NoDomain() {
    -    when(clock.now()).thenReturn(10L);
    -
    -    eventEmitterProvider
    -        .eventEmitterBuilder("test-scope")
    -        .build()
    -        .emit(
    -            "event-name",
    -            Attributes.builder()
    -                .put("key1", "value1")
    -                // should be overridden by the eventName argument passed to emit
    -                .put("event.name", "foo")
    -                // should be overridden by the default eventDomain
    -                .put("event.domain", "foo")
    -                .build());
    -
    -    assertThat(seenLog.get().toLogRecordData())
    -        .hasResource(RESOURCE)
    -        .hasInstrumentationScope(InstrumentationScopeInfo.create("test-scope"))
    -        .hasTimestamp(10L)
    -        .hasAttributes(
    -            Attributes.builder()
    -                .put("key1", "value1")
    -                .put("event.domain", "unknown")
    -                .put("event.name", "event-name")
    -                .build());
    +            Attributes.builder().put("key1", "value1").put("event.name", "event-name").build());
       }
     
       @Test
    @@ -111,10 +75,6 @@ private void verifySeen(long timestamp, Attributes attributes) {
             .hasResource(RESOURCE)
             .hasInstrumentationScope(InstrumentationScopeInfo.create("test-scope"))
             .hasTimestamp(timestamp)
    -        .hasAttributes(
    -            attributes.toBuilder()
    -                .put("event.domain", "unknown")
    -                .put("event.name", "testing")
    -                .build());
    +        .hasAttributes(attributes.toBuilder().put("event.name", "testing").build());
       }
     }
    
    From 4a4d9a6a6ca306e718c6036ac6962600cf99cf2c Mon Sep 17 00:00:00 2001
    From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com>
    Date: Tue, 12 Mar 2024 19:52:38 -0700
    Subject: [PATCH 292/901] Update dependency com.fasterxml.jackson:jackson-bom
     to v2.17.0 (#6292)
    
    Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
    ---
     dependencyManagement/build.gradle.kts | 2 +-
     1 file changed, 1 insertion(+), 1 deletion(-)
    
    diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts
    index 1c86e0446f5..7ab0bf89039 100644
    --- a/dependencyManagement/build.gradle.kts
    +++ b/dependencyManagement/build.gradle.kts
    @@ -8,7 +8,7 @@ val dependencyVersions = hashMapOf()
     rootProject.extra["versions"] = dependencyVersions
     
     val DEPENDENCY_BOMS = listOf(
    -  "com.fasterxml.jackson:jackson-bom:2.16.2",
    +  "com.fasterxml.jackson:jackson-bom:2.17.0",
       "com.google.guava:guava-bom:33.0.0-jre",
       "com.google.protobuf:protobuf-bom:3.25.3",
       "com.linecorp.armeria:armeria-bom:1.27.2",
    
    From f83c020d4d2a11f16be8af739790718bb3413cba Mon Sep 17 00:00:00 2001
    From: jack-berg <34418638+jack-berg@users.noreply.github.com>
    Date: Tue, 12 Mar 2024 21:55:11 -0500
    Subject: [PATCH 293/901] Use shared CODECOV_TOKEN (#6291)
    
    ---
     RELEASING.md | 3 ---
     1 file changed, 3 deletions(-)
    
    diff --git a/RELEASING.md b/RELEASING.md
    index cf9c0ebc197..bbea33223bb 100644
    --- a/RELEASING.md
    +++ b/RELEASING.md
    @@ -89,9 +89,6 @@ The following credentials are required for building or publishing (and automatic
       * To obtain `SONATYPE_USER` and `SONATYPE_KEY` for your account, login
         to [oss.sonatype.org](https://oss.sonatype.org/) and navigate to Profile -> User Token -> Access
         User Token.
    -* `CODECOV_TOKEN`: Token used for uploading codecov reports. Each maintainer can obtain their own
    -  credential from codecov as
    -  described [here](https://docs.codecov.com/docs/adding-the-codecov-token#github-actions).
     
     Additionally, credentials are stored with maintainers via
     the [OpenTelemetry 1Password](https://opentelemetry.1password.com/signin) account. The following
    
    From dde0d6936c4e6e3c1fb16482cd4e9092fa3f65dc Mon Sep 17 00:00:00 2001
    From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com>
    Date: Sat, 16 Mar 2024 14:23:46 -0700
    Subject: [PATCH 294/901] Update dependency org.awaitility:awaitility to v4.2.1
     (#6298)
    
    Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
    ---
     dependencyManagement/build.gradle.kts | 2 +-
     1 file changed, 1 insertion(+), 1 deletion(-)
    
    diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts
    index 7ab0bf89039..11390ce760d 100644
    --- a/dependencyManagement/build.gradle.kts
    +++ b/dependencyManagement/build.gradle.kts
    @@ -72,7 +72,7 @@ val DEPENDENCIES = listOf(
       "io.prometheus:prometheus-metrics-exporter-httpserver:1.1.0",
       "junit:junit:4.13.2",
       "nl.jqno.equalsverifier:equalsverifier:3.15.8",
    -  "org.awaitility:awaitility:4.2.0",
    +  "org.awaitility:awaitility:4.2.1",
       "org.bouncycastle:bcpkix-jdk15on:1.70",
       "org.codehaus.mojo:animal-sniffer-annotations:1.23",
       "org.jctools:jctools-core:4.0.3",
    
    From 1f22d1c46eda591006822d83ba5576e655c14d1a Mon Sep 17 00:00:00 2001
    From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com>
    Date: Sat, 16 Mar 2024 14:24:08 -0700
    Subject: [PATCH 295/901] Update dependency com.google.guava:guava to
     v33.1.0-jre (#6296)
    
    Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
    ---
     buildSrc/build.gradle.kts | 2 +-
     1 file changed, 1 insertion(+), 1 deletion(-)
    
    diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts
    index 7e8783cccf6..2bab63d4236 100644
    --- a/buildSrc/build.gradle.kts
    +++ b/buildSrc/build.gradle.kts
    @@ -47,7 +47,7 @@ dependencies {
       // When updating, update above in plugins too
       implementation("com.diffplug.spotless:spotless-plugin-gradle:6.25.0")
       // Needed for japicmp but not automatically brought in for some reason.
    -  implementation("com.google.guava:guava:33.0.0-jre")
    +  implementation("com.google.guava:guava:33.1.0-jre")
       implementation("com.squareup:javapoet:1.13.0")
       implementation("com.squareup.wire:wire-compiler")
       implementation("com.squareup.wire:wire-gradle-plugin")
    
    From 2fc71ea8e34eb9ee6ec64e57dcafa922c248c897 Mon Sep 17 00:00:00 2001
    From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com>
    Date: Sat, 16 Mar 2024 14:24:28 -0700
    Subject: [PATCH 296/901] Update dependency
     com.google.api.grpc:proto-google-common-protos to v2.37.1 (#6299)
    
    Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
    ---
     dependencyManagement/build.gradle.kts | 2 +-
     1 file changed, 1 insertion(+), 1 deletion(-)
    
    diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts
    index 11390ce760d..53e65441128 100644
    --- a/dependencyManagement/build.gradle.kts
    +++ b/dependencyManagement/build.gradle.kts
    @@ -55,7 +55,7 @@ val DEPENDENCIES = listOf(
       "io.prometheus:simpleclient_httpserver:${prometheusClientVersion}",
       "javax.annotation:javax.annotation-api:1.3.2",
       "com.github.stefanbirkner:system-rules:1.19.0",
    -  "com.google.api.grpc:proto-google-common-protos:2.36.0",
    +  "com.google.api.grpc:proto-google-common-protos:2.37.1",
       "com.google.code.findbugs:jsr305:3.0.2",
       "com.google.guava:guava-beta-checker:1.0",
       "com.sun.net.httpserver:http:20070405",
    
    From b0ccf5ec7d8928aa03849b2bad43feb5e608d6f0 Mon Sep 17 00:00:00 2001
    From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com>
    Date: Sat, 16 Mar 2024 14:25:00 -0700
    Subject: [PATCH 297/901] Update dependency com.squareup.okio:okio-bom to
     v3.9.0 (#6293)
    
    Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
    ---
     dependencyManagement/build.gradle.kts | 2 +-
     1 file changed, 1 insertion(+), 1 deletion(-)
    
    diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts
    index 53e65441128..3268767577a 100644
    --- a/dependencyManagement/build.gradle.kts
    +++ b/dependencyManagement/build.gradle.kts
    @@ -13,7 +13,7 @@ val DEPENDENCY_BOMS = listOf(
       "com.google.protobuf:protobuf-bom:3.25.3",
       "com.linecorp.armeria:armeria-bom:1.27.2",
       "com.squareup.okhttp3:okhttp-bom:4.12.0",
    -  "com.squareup.okio:okio-bom:3.8.0", // applies to transitive dependencies of okhttp
    +  "com.squareup.okio:okio-bom:3.9.0", // applies to transitive dependencies of okhttp
       "io.grpc:grpc-bom:1.62.2",
       "io.netty:netty-bom:4.1.107.Final",
       "io.zipkin.brave:brave-bom:6.0.2",
    
    From 970f95f2eceee725d7e7f8ab7a435f2703a590e6 Mon Sep 17 00:00:00 2001
    From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com>
    Date: Sat, 16 Mar 2024 14:25:23 -0700
    Subject: [PATCH 298/901] Update dependency com.google.guava:guava-bom to
     v33.1.0-jre (#6294)
    
    Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
    ---
     dependencyManagement/build.gradle.kts | 2 +-
     1 file changed, 1 insertion(+), 1 deletion(-)
    
    diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts
    index 3268767577a..6a5a19426e1 100644
    --- a/dependencyManagement/build.gradle.kts
    +++ b/dependencyManagement/build.gradle.kts
    @@ -9,7 +9,7 @@ rootProject.extra["versions"] = dependencyVersions
     
     val DEPENDENCY_BOMS = listOf(
       "com.fasterxml.jackson:jackson-bom:2.17.0",
    -  "com.google.guava:guava-bom:33.0.0-jre",
    +  "com.google.guava:guava-bom:33.1.0-jre",
       "com.google.protobuf:protobuf-bom:3.25.3",
       "com.linecorp.armeria:armeria-bom:1.27.2",
       "com.squareup.okhttp3:okhttp-bom:4.12.0",
    
    From b2298ab4c0add0b7b36a5feb42505d4de3d54ba0 Mon Sep 17 00:00:00 2001
    From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com>
    Date: Sat, 16 Mar 2024 14:25:56 -0700
    Subject: [PATCH 299/901] Update dependency org.owasp:dependency-check-gradle
     to v9.0.10 (#6300)
    
    Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
    ---
     buildSrc/build.gradle.kts | 2 +-
     1 file changed, 1 insertion(+), 1 deletion(-)
    
    diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts
    index 2bab63d4236..ee5f847b496 100644
    --- a/buildSrc/build.gradle.kts
    +++ b/buildSrc/build.gradle.kts
    @@ -58,7 +58,7 @@ dependencies {
       implementation("net.ltgt.gradle:gradle-errorprone-plugin:3.1.0")
       implementation("net.ltgt.gradle:gradle-nullaway-plugin:2.0.0")
       implementation("org.jetbrains.kotlin:kotlin-gradle-plugin:1.9.23")
    -  implementation("org.owasp:dependency-check-gradle:9.0.9")
    +  implementation("org.owasp:dependency-check-gradle:9.0.10")
       implementation("ru.vyarus:gradle-animalsniffer-plugin:1.7.1")
     }
     
    
    From 6e3d0873bc1741c361574104ac8fe5d2c8faf3e6 Mon Sep 17 00:00:00 2001
    From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com>
    Date: Tue, 19 Mar 2024 08:25:05 -0700
    Subject: [PATCH 300/901] Update dependency checkstyle to v10.14.2 (#6301)
    
    Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
    ---
     buildSrc/src/main/kotlin/otel.java-conventions.gradle.kts | 2 +-
     1 file changed, 1 insertion(+), 1 deletion(-)
    
    diff --git a/buildSrc/src/main/kotlin/otel.java-conventions.gradle.kts b/buildSrc/src/main/kotlin/otel.java-conventions.gradle.kts
    index 0a2ecb5154d..10fef3da385 100644
    --- a/buildSrc/src/main/kotlin/otel.java-conventions.gradle.kts
    +++ b/buildSrc/src/main/kotlin/otel.java-conventions.gradle.kts
    @@ -35,7 +35,7 @@ java {
     
     checkstyle {
       configDirectory.set(file("$rootDir/buildscripts/"))
    -  toolVersion = "10.14.1"
    +  toolVersion = "10.14.2"
       isIgnoreFailures = false
       configProperties["rootDir"] = rootDir
     }
    
    From 8a73f45a2c4521de29c3c60ee75674b9bbf6c43c Mon Sep 17 00:00:00 2001
    From: jason plumb <75337021+breedx-splk@users.noreply.github.com>
    Date: Wed, 20 Mar 2024 09:03:20 -0700
    Subject: [PATCH 301/901] Fix copypasta artifact (#6311)
    
    ---
     .../exporter/logging/otlp/OtlpJsonLoggingMetricExporter.java    | 2 +-
     1 file changed, 1 insertion(+), 1 deletion(-)
    
    diff --git a/exporters/logging-otlp/src/main/java/io/opentelemetry/exporter/logging/otlp/OtlpJsonLoggingMetricExporter.java b/exporters/logging-otlp/src/main/java/io/opentelemetry/exporter/logging/otlp/OtlpJsonLoggingMetricExporter.java
    index fd0a491bdfb..caacea6e7eb 100644
    --- a/exporters/logging-otlp/src/main/java/io/opentelemetry/exporter/logging/otlp/OtlpJsonLoggingMetricExporter.java
    +++ b/exporters/logging-otlp/src/main/java/io/opentelemetry/exporter/logging/otlp/OtlpJsonLoggingMetricExporter.java
    @@ -22,7 +22,7 @@
     import java.util.logging.Logger;
     
     /**
    - * A {@link MetricExporter} which writes {@linkplain MetricData spans} to a {@link Logger} in OTLP
    + * A {@link MetricExporter} which writes {@linkplain MetricData metrics} to a {@link Logger} in OTLP
      * JSON format. Each log line will include a single {@code ResourceMetrics}.
      */
     public final class OtlpJsonLoggingMetricExporter implements MetricExporter {
    
    From 7926c45a5f8afe11857e632021b29bf6b973f6de Mon Sep 17 00:00:00 2001
    From: jack-berg <34418638+jack-berg@users.noreply.github.com>
    Date: Wed, 20 Mar 2024 11:15:21 -0500
    Subject: [PATCH 302/901] Update jaeger autoconfigure docs to point to OTLP
     (#6307)
    
    ---
     sdk-extensions/autoconfigure/README.md | 8 ++------
     1 file changed, 2 insertions(+), 6 deletions(-)
    
    diff --git a/sdk-extensions/autoconfigure/README.md b/sdk-extensions/autoconfigure/README.md
    index 8e6e68cbabc..6a658a39fe3 100644
    --- a/sdk-extensions/autoconfigure/README.md
    +++ b/sdk-extensions/autoconfigure/README.md
    @@ -253,13 +253,9 @@ The following exporters are only available for the trace signal. See [exporters]
     
     #### Jaeger exporter
     
    -The [Jaeger](https://www.jaegertracing.io/docs/1.21/apis/#protobuf-via-grpc-stable) exporter. This exporter uses gRPC for its communications protocol.
    +The Jaeger exporters (artifacts `opentelemetry-exporter-jaeger` and `opentelemetry-exporter-jaeger-thrift`) were removed in the [1.35.0](https://github.com/open-telemetry/opentelemetry-java/releases/tag/v1.35.0) release (last published in `1.34.0`) and are no longer available in later versions of autoconfigure.
     
    -| System property                   | Environment variable              | Description                                                                                        |
    -|-----------------------------------|-----------------------------------|----------------------------------------------------------------------------------------------------|
    -| otel.traces.exporter=jaeger       | OTEL_TRACES_EXPORTER=jaeger       | Select the Jaeger exporter                                                                         |
    -| otel.exporter.jaeger.endpoint     | OTEL_EXPORTER_JAEGER_ENDPOINT     | The Jaeger gRPC endpoint to connect to. Default is `http://localhost:14250`.                       |
    -| otel.exporter.jaeger.timeout      | OTEL_EXPORTER_JAEGER_TIMEOUT      | The maximum waiting time, in milliseconds, allowed to send each batch. Default is `10000`.         |
    +Jaeger now has [native support for OTLP](https://opentelemetry.io/blog/2022/jaeger-native-otlp/), and users should export to jaeger using [OTLP](https://opentelemetry.io/docs/instrumentation/java/exporters/#otlp-dependencies) instead.
     
     #### Zipkin exporter
     
    
    From 44c69ea6b5477b89cd2b3e735707a92d8e69be86 Mon Sep 17 00:00:00 2001
    From: jack-berg <34418638+jack-berg@users.noreply.github.com>
    Date: Thu, 21 Mar 2024 14:03:07 -0500
    Subject: [PATCH 303/901] Rename opentelemetry-extension-incubator to
     opentelemetry-api-incubator, merge opentelemetry-api-events (#6289)
    
    ---
     CONTRIBUTING.md                                  |  2 +-
     README.md                                        | 15 +++++++--------
     api/events/build.gradle.kts                      | 13 -------------
     api/events/gradle.properties                     |  1 -
     {extensions => api}/incubator/README.md          |  0
     {extensions => api}/incubator/build.gradle.kts   |  2 +-
     {extensions => api}/incubator/gradle.properties  |  0
     .../PassThroughPropagatorBenchmark.java          |  2 +-
     .../incubator}/events/DefaultEventEmitter.java   |  2 +-
     .../events/DefaultEventEmitterProvider.java      |  2 +-
     .../api/incubator}/events/EventBuilder.java      |  2 +-
     .../api/incubator}/events/EventEmitter.java      |  2 +-
     .../incubator}/events/EventEmitterBuilder.java   |  2 +-
     .../incubator}/events/EventEmitterProvider.java  |  2 +-
     .../events/GlobalEventEmitterProvider.java       |  2 +-
     .../api}/incubator/logs/AnyValue.java            |  2 +-
     .../api}/incubator/logs/AnyValueArray.java       |  2 +-
     .../api}/incubator/logs/AnyValueBoolean.java     |  2 +-
     .../api}/incubator/logs/AnyValueBytes.java       |  2 +-
     .../api}/incubator/logs/AnyValueDouble.java      |  2 +-
     .../api}/incubator/logs/AnyValueLong.java        |  2 +-
     .../api}/incubator/logs/AnyValueString.java      |  2 +-
     .../api}/incubator/logs/AnyValueType.java        |  2 +-
     .../incubator/logs/ExtendedLogRecordBuilder.java |  2 +-
     .../api}/incubator/logs/KeyAnyValue.java         |  2 +-
     .../api}/incubator/logs/KeyAnyValueImpl.java     |  2 +-
     .../api}/incubator/logs/KeyAnyValueList.java     |  2 +-
     .../api}/incubator/metrics/DoubleGauge.java      |  2 +-
     .../metrics/ExtendedDoubleCounterBuilder.java    |  2 +-
     .../metrics/ExtendedDoubleGaugeBuilder.java      |  2 +-
     .../metrics/ExtendedDoubleHistogramBuilder.java  |  2 +-
     .../ExtendedDoubleUpDownCounterBuilder.java      |  2 +-
     .../metrics/ExtendedLongCounterBuilder.java      |  2 +-
     .../metrics/ExtendedLongGaugeBuilder.java        |  2 +-
     .../metrics/ExtendedLongHistogramBuilder.java    |  2 +-
     .../ExtendedLongUpDownCounterBuilder.java        |  2 +-
     .../api}/incubator/metrics/LongGauge.java        |  2 +-
     .../propagation/CaseInsensitiveMap.java          |  2 +-
     .../propagation/ExtendedContextPropagators.java  |  2 +-
     .../propagation/PassThroughPropagator.java       |  2 +-
     .../api}/incubator/trace/ExtendedSpan.java       |  2 +-
     .../incubator/trace/ExtendedSpanBuilder.java     |  4 ++--
     .../api}/incubator/trace/ExtendedTracer.java     |  4 ++--
     .../api}/incubator/trace/SpanCallable.java       |  2 +-
     .../api}/incubator/trace/SpanRunnable.java       |  2 +-
     .../events/DefaultEventEmitterProviderTest.java  |  2 +-
     .../events/DefaultEventEmitterTest.java          |  2 +-
     .../events/GlobalEventEmitterProviderTest.java   |  2 +-
     .../api}/incubator/logs/AnyValueTest.java        |  2 +-
     .../propagation/PassThroughPropagatorTest.java   |  2 +-
     .../api}/incubator/trace/ExtendedTracerTest.java |  4 ++--
     exporters/otlp/common/build.gradle.kts           |  2 +-
     .../internal/otlp/AnyValueMarshaler.java         |  4 ++--
     .../internal/otlp/ArrayAnyValueMarshaler.java    |  2 +-
     .../otlp/KeyValueListAnyValueMarshaler.java      |  2 +-
     .../internal/otlp/KeyValueMarshaler.java         |  2 +-
     .../internal/otlp/logs/LogMarshaler.java         |  2 +-
     .../internal/otlp/AnyValueMarshalerTest.java     |  7 +++----
     integration-tests/otlp/build.gradle.kts          |  3 +--
     .../OtlpExporterIntegrationTest.java             |  8 ++++----
     sdk-extensions/autoconfigure/build.gradle.kts    |  4 ++--
     .../AutoConfiguredOpenTelemetrySdkBuilder.java   |  2 +-
     .../AutoConfiguredOpenTelemetrySdkTest.java      |  2 +-
     .../AutoConfiguredOpenTelemetrySdkTest.java      |  2 +-
     .../sdk/autoconfigure/FileConfigurationTest.java |  2 +-
     .../sdk/autoconfigure/FullConfigTest.java        |  4 ++--
     sdk/logs/build.gradle.kts                        |  4 +---
     .../sdk/logs/SdkLogRecordBuilder.java            |  4 ++--
     .../sdk/logs/internal/AnyValueBody.java          |  2 +-
     .../sdk/logs/internal/SdkEventBuilder.java       |  2 +-
     .../logs/internal/SdkEventEmitterProvider.java   |  8 ++++----
     .../opentelemetry/sdk/logs/AnyValueBodyTest.java |  6 +++---
     .../internal/SdkEventEmitterProviderTest.java    |  2 +-
     sdk/metrics/build.gradle.kts                     |  2 +-
     .../sdk/metrics/SdkDoubleCounter.java            |  2 +-
     .../sdk/metrics/SdkDoubleGauge.java              |  4 ++--
     .../sdk/metrics/SdkDoubleHistogram.java          |  2 +-
     .../sdk/metrics/SdkDoubleUpDownCounter.java      |  2 +-
     .../sdk/metrics/SdkLongCounter.java              |  2 +-
     .../opentelemetry/sdk/metrics/SdkLongGauge.java  |  4 ++--
     .../sdk/metrics/SdkLongHistogram.java            |  2 +-
     .../sdk/metrics/SdkLongUpDownCounter.java        |  2 +-
     .../sdk/metrics/AttributesAdviceTest.java        | 16 ++++++++--------
     .../opentelemetry/sdk/metrics/IdentityTest.java  |  2 +-
     .../sdk/metrics/SdkDoubleGaugeTest.java          |  4 ++--
     .../sdk/metrics/SdkLongGaugeTest.java            |  4 ++--
     sdk/trace/build.gradle.kts                       |  2 +-
     .../java/io/opentelemetry/sdk/trace/SdkSpan.java |  2 +-
     .../io/opentelemetry/sdk/trace/SdkSpanTest.java  |  2 +-
     settings.gradle.kts                              |  3 +--
     90 files changed, 120 insertions(+), 140 deletions(-)
     delete mode 100644 api/events/build.gradle.kts
     delete mode 100644 api/events/gradle.properties
     rename {extensions => api}/incubator/README.md (100%)
     rename {extensions => api}/incubator/build.gradle.kts (86%)
     rename {extensions => api}/incubator/gradle.properties (100%)
     rename {extensions => api}/incubator/src/jmh/java/io/opentelemetry/extension/incubator/PassThroughPropagatorBenchmark.java (97%)
     rename api/{events/src/main/java/io/opentelemetry/api => incubator/src/main/java/io/opentelemetry/api/incubator}/events/DefaultEventEmitter.java (95%)
     rename api/{events/src/main/java/io/opentelemetry/api => incubator/src/main/java/io/opentelemetry/api/incubator}/events/DefaultEventEmitterProvider.java (95%)
     rename api/{events/src/main/java/io/opentelemetry/api => incubator/src/main/java/io/opentelemetry/api/incubator}/events/EventBuilder.java (94%)
     rename api/{events/src/main/java/io/opentelemetry/api => incubator/src/main/java/io/opentelemetry/api/incubator}/events/EventEmitter.java (96%)
     rename api/{events/src/main/java/io/opentelemetry/api => incubator/src/main/java/io/opentelemetry/api/incubator}/events/EventEmitterBuilder.java (96%)
     rename api/{events/src/main/java/io/opentelemetry/api => incubator/src/main/java/io/opentelemetry/api/incubator}/events/EventEmitterProvider.java (96%)
     rename api/{events/src/main/java/io/opentelemetry/api => incubator/src/main/java/io/opentelemetry/api/incubator}/events/GlobalEventEmitterProvider.java (97%)
     rename {extensions/incubator/src/main/java/io/opentelemetry/extension => api/incubator/src/main/java/io/opentelemetry/api}/incubator/logs/AnyValue.java (98%)
     rename {extensions/incubator/src/main/java/io/opentelemetry/extension => api/incubator/src/main/java/io/opentelemetry/api}/incubator/logs/AnyValueArray.java (96%)
     rename {extensions/incubator/src/main/java/io/opentelemetry/extension => api/incubator/src/main/java/io/opentelemetry/api}/incubator/logs/AnyValueBoolean.java (95%)
     rename {extensions/incubator/src/main/java/io/opentelemetry/extension => api/incubator/src/main/java/io/opentelemetry/api}/incubator/logs/AnyValueBytes.java (95%)
     rename {extensions/incubator/src/main/java/io/opentelemetry/extension => api/incubator/src/main/java/io/opentelemetry/api}/incubator/logs/AnyValueDouble.java (94%)
     rename {extensions/incubator/src/main/java/io/opentelemetry/extension => api/incubator/src/main/java/io/opentelemetry/api}/incubator/logs/AnyValueLong.java (94%)
     rename {extensions/incubator/src/main/java/io/opentelemetry/extension => api/incubator/src/main/java/io/opentelemetry/api}/incubator/logs/AnyValueString.java (95%)
     rename {extensions/incubator/src/main/java/io/opentelemetry/extension => api/incubator/src/main/java/io/opentelemetry/api}/incubator/logs/AnyValueType.java (89%)
     rename {extensions/incubator/src/main/java/io/opentelemetry/extension => api/incubator/src/main/java/io/opentelemetry/api}/incubator/logs/ExtendedLogRecordBuilder.java (87%)
     rename {extensions/incubator/src/main/java/io/opentelemetry/extension => api/incubator/src/main/java/io/opentelemetry/api}/incubator/logs/KeyAnyValue.java (91%)
     rename {extensions/incubator/src/main/java/io/opentelemetry/extension => api/incubator/src/main/java/io/opentelemetry/api}/incubator/logs/KeyAnyValueImpl.java (87%)
     rename {extensions/incubator/src/main/java/io/opentelemetry/extension => api/incubator/src/main/java/io/opentelemetry/api}/incubator/logs/KeyAnyValueList.java (97%)
     rename {extensions/incubator/src/main/java/io/opentelemetry/extension => api/incubator/src/main/java/io/opentelemetry/api}/incubator/metrics/DoubleGauge.java (92%)
     rename {extensions/incubator/src/main/java/io/opentelemetry/extension => api/incubator/src/main/java/io/opentelemetry/api}/incubator/metrics/ExtendedDoubleCounterBuilder.java (91%)
     rename {extensions/incubator/src/main/java/io/opentelemetry/extension => api/incubator/src/main/java/io/opentelemetry/api}/incubator/metrics/ExtendedDoubleGaugeBuilder.java (95%)
     rename {extensions/incubator/src/main/java/io/opentelemetry/extension => api/incubator/src/main/java/io/opentelemetry/api}/incubator/metrics/ExtendedDoubleHistogramBuilder.java (92%)
     rename {extensions/incubator/src/main/java/io/opentelemetry/extension => api/incubator/src/main/java/io/opentelemetry/api}/incubator/metrics/ExtendedDoubleUpDownCounterBuilder.java (92%)
     rename {extensions/incubator/src/main/java/io/opentelemetry/extension => api/incubator/src/main/java/io/opentelemetry/api}/incubator/metrics/ExtendedLongCounterBuilder.java (91%)
     rename {extensions/incubator/src/main/java/io/opentelemetry/extension => api/incubator/src/main/java/io/opentelemetry/api}/incubator/metrics/ExtendedLongGaugeBuilder.java (95%)
     rename {extensions/incubator/src/main/java/io/opentelemetry/extension => api/incubator/src/main/java/io/opentelemetry/api}/incubator/metrics/ExtendedLongHistogramBuilder.java (91%)
     rename {extensions/incubator/src/main/java/io/opentelemetry/extension => api/incubator/src/main/java/io/opentelemetry/api}/incubator/metrics/ExtendedLongUpDownCounterBuilder.java (92%)
     rename {extensions/incubator/src/main/java/io/opentelemetry/extension => api/incubator/src/main/java/io/opentelemetry/api}/incubator/metrics/LongGauge.java (92%)
     rename {extensions/incubator/src/main/java/io/opentelemetry/extension => api/incubator/src/main/java/io/opentelemetry/api}/incubator/propagation/CaseInsensitiveMap.java (91%)
     rename {extensions/incubator/src/main/java/io/opentelemetry/extension => api/incubator/src/main/java/io/opentelemetry/api}/incubator/propagation/ExtendedContextPropagators.java (97%)
     rename {extensions/incubator/src/main/java/io/opentelemetry/extension => api/incubator/src/main/java/io/opentelemetry/api}/incubator/propagation/PassThroughPropagator.java (98%)
     rename {extensions/incubator/src/main/java/io/opentelemetry/extension => api/incubator/src/main/java/io/opentelemetry/api}/incubator/trace/ExtendedSpan.java (97%)
     rename {extensions/incubator/src/main/java/io/opentelemetry/extension => api/incubator/src/main/java/io/opentelemetry/api}/incubator/trace/ExtendedSpanBuilder.java (98%)
     rename {extensions/incubator/src/main/java/io/opentelemetry/extension => api/incubator/src/main/java/io/opentelemetry/api}/incubator/trace/ExtendedTracer.java (87%)
     rename {extensions/incubator/src/main/java/io/opentelemetry/extension => api/incubator/src/main/java/io/opentelemetry/api}/incubator/trace/SpanCallable.java (86%)
     rename {extensions/incubator/src/main/java/io/opentelemetry/extension => api/incubator/src/main/java/io/opentelemetry/api}/incubator/trace/SpanRunnable.java (86%)
     rename api/{events/src/test/java/io/opentelemetry/api => incubator/src/test/java/io/opentelemetry/api/incubator}/events/DefaultEventEmitterProviderTest.java (96%)
     rename api/{events/src/test/java/io/opentelemetry/api => incubator/src/test/java/io/opentelemetry/api/incubator}/events/DefaultEventEmitterTest.java (96%)
     rename api/{events/src/test/java/io/opentelemetry/api => incubator/src/test/java/io/opentelemetry/api/incubator}/events/GlobalEventEmitterProviderTest.java (97%)
     rename {extensions/incubator/src/test/java/io/opentelemetry/extension => api/incubator/src/test/java/io/opentelemetry/api}/incubator/logs/AnyValueTest.java (99%)
     rename {extensions/incubator/src/test/java/io/opentelemetry/extension => api/incubator/src/test/java/io/opentelemetry/api}/incubator/propagation/PassThroughPropagatorTest.java (98%)
     rename {extensions/incubator/src/test/java/io/opentelemetry/extension => api/incubator/src/test/java/io/opentelemetry/api}/incubator/trace/ExtendedTracerTest.java (98%)
    
    diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
    index 4d1de54157b..491f53be81a 100644
    --- a/CONTRIBUTING.md
    +++ b/CONTRIBUTING.md
    @@ -78,7 +78,7 @@ which implement concepts defined in
     the [opentelemetry-specification](https://github.com/open-telemetry/opentelemetry-specification),
     with a few exceptions / comments:
     
    -* The [API incubator](./extensions/incubator) and [SDK incubator](./extensions/incubator)
    +* The [API incubator](./api/incubator) and [SDK incubator](./sdk-extensions/incubator)
       contain prototypes which have been discussed in the specification
       or [oteps](https://github.com/open-telemetry/oteps) and have a reasonable chance of becoming part
       of the specification, subject to maintainers' discretion.
    diff --git a/README.md b/README.md
    index 38090b6a1d3..dc2dfe5cd2c 100644
    --- a/README.md
    +++ b/README.md
    @@ -48,8 +48,8 @@ This project contains the following top level components:
     * [OpenTelemetry API](api/):
       * [stable apis](api/all) including `Tracer`, `Span`, `SpanContext`, `Meter`, and `Baggage`.
       * [context api](context/) The OpenTelemetry Context implementation.
    -  * [experimental apis](api/events) including `Events`.
    -* [extensions](extensions/) define additional API extensions not part of the core API, including propagators and experimental extension APIs.
    +  * [incubating apis](api/incubator) incubating APIs, including `Events`.
    +* [extensions](extensions/) define additional API extensions not part of the core API, including propagators.
     * [sdk](sdk/) defines the implementation of the OpenTelemetry API.
     * [exporters](exporters/) trace, metric, and log exporters for the SDK.
     * [sdk-extensions](sdk-extensions/) defines additional SDK extensions, which are not part of the core SDK.
    @@ -235,11 +235,11 @@ dependency as follows, replacing `{{artifact-id}}` with the value from the "Arti
     ### API
     
     
    -| Component                         | Description                                                                                                                                                                          | Artifact ID                | Version                                                     | Javadoc                                                                                                                                                         |
    -|-----------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|----------------------------|-------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------|
    -| [API](./api/all)                  | OpenTelemetry API, including metrics, traces, baggage, context                                                                                                                       | `opentelemetry-api`        | 1.36.0           | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-api.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-api)               |
    -| [Events API](./api/events)        | OpenTelemetry Event API for emitting events.                                                                                                                                         | `opentelemetry-api-events` | 1.36.0-alpha | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-api-events.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-api-events) |
    -| [Context API](./context)          | OpenTelemetry context API                                                                                                                                                            | `opentelemetry-context`    | 1.36.0           | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-context.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-context)       |
    +| Component                         | Description                                                                          | Artifact ID                   | Version                                                     | Javadoc                                                                                                                                                         |
    +|-----------------------------------|--------------------------------------------------------------------------------------|-------------------------------|-------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------|
    +| [API](./api/all)                  | OpenTelemetry API, including metrics, traces, baggage, context                       | `opentelemetry-api`           | 1.36.0           | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-api.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-api)               |
    +| [API  Incubator](./api/incubator) | API incubator, including pass through propagator, and extended tracer, and Event API | `opentelemetry-api-incubator` | TODO: add after first publish                               | TODO: add after first publish                                                                                                                                   |
    +| [Context API](./context)          | OpenTelemetry context API                                                            | `opentelemetry-context`       | 1.36.0           | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-context.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-context)       |
     
     ### API Extensions
     
    @@ -247,7 +247,6 @@ dependency as follows, replacing `{{artifact-id}}` with the value from the "Arti
     |---------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|---------------------------------------------|-------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
     | [Kotlin Extension](./extensions/kotlin)                       | Context extension for coroutines                                                                                                                                                        | `opentelemetry-extension-kotlin`            | 1.36.0           | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-extension-kotlin.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-extension-kotlin)                       |
     | [Trace Propagators Extension](./extensions/trace-propagators) | Trace propagators, including B3, Jaeger, OT Trace                                                                                                                                       | `opentelemetry-extension-trace-propagators` | 1.36.0           | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-extension-trace-propagators.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-extension-trace-propagators) |
    -| [Incubator Extension](./extensions/incubator)                 | API incubator, including pass through propagator, and extended tracer                                                                                                                   | `opentelemetry-extension-incubator`         | 1.36.0-alpha | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-extension-incubator.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-extension-incubator)                 |
     
     ### SDK
     
    diff --git a/api/events/build.gradle.kts b/api/events/build.gradle.kts
    deleted file mode 100644
    index 9a0262cded0..00000000000
    --- a/api/events/build.gradle.kts
    +++ /dev/null
    @@ -1,13 +0,0 @@
    -plugins {
    -  id("otel.java-conventions")
    -  id("otel.publish-conventions")
    -
    -  id("otel.animalsniffer-conventions")
    -}
    -
    -description = "OpenTelemetry Events API"
    -otelJava.moduleName.set("io.opentelemetry.api.events")
    -
    -dependencies {
    -  api(project(":api:all"))
    -}
    diff --git a/api/events/gradle.properties b/api/events/gradle.properties
    deleted file mode 100644
    index bbcbb896228..00000000000
    --- a/api/events/gradle.properties
    +++ /dev/null
    @@ -1 +0,0 @@
    -otel.release=alpha
    \ No newline at end of file
    diff --git a/extensions/incubator/README.md b/api/incubator/README.md
    similarity index 100%
    rename from extensions/incubator/README.md
    rename to api/incubator/README.md
    diff --git a/extensions/incubator/build.gradle.kts b/api/incubator/build.gradle.kts
    similarity index 86%
    rename from extensions/incubator/build.gradle.kts
    rename to api/incubator/build.gradle.kts
    index 5812f6462af..b6f726654a3 100644
    --- a/extensions/incubator/build.gradle.kts
    +++ b/api/incubator/build.gradle.kts
    @@ -7,7 +7,7 @@ plugins {
     }
     
     description = "OpenTelemetry API Incubator"
    -otelJava.moduleName.set("io.opentelemetry.extension.incubator")
    +otelJava.moduleName.set("io.opentelemetry.api.incubator")
     
     dependencies {
       api(project(":api:all"))
    diff --git a/extensions/incubator/gradle.properties b/api/incubator/gradle.properties
    similarity index 100%
    rename from extensions/incubator/gradle.properties
    rename to api/incubator/gradle.properties
    diff --git a/extensions/incubator/src/jmh/java/io/opentelemetry/extension/incubator/PassThroughPropagatorBenchmark.java b/api/incubator/src/jmh/java/io/opentelemetry/extension/incubator/PassThroughPropagatorBenchmark.java
    similarity index 97%
    rename from extensions/incubator/src/jmh/java/io/opentelemetry/extension/incubator/PassThroughPropagatorBenchmark.java
    rename to api/incubator/src/jmh/java/io/opentelemetry/extension/incubator/PassThroughPropagatorBenchmark.java
    index 06b68e6d45c..8d340985ae3 100644
    --- a/extensions/incubator/src/jmh/java/io/opentelemetry/extension/incubator/PassThroughPropagatorBenchmark.java
    +++ b/api/incubator/src/jmh/java/io/opentelemetry/extension/incubator/PassThroughPropagatorBenchmark.java
    @@ -5,6 +5,7 @@
     
     package io.opentelemetry.extension.incubator;
     
    +import io.opentelemetry.api.incubator.propagation.PassThroughPropagator;
     import io.opentelemetry.api.trace.Span;
     import io.opentelemetry.api.trace.SpanContext;
     import io.opentelemetry.api.trace.TraceFlags;
    @@ -13,7 +14,6 @@
     import io.opentelemetry.context.Context;
     import io.opentelemetry.context.propagation.TextMapGetter;
     import io.opentelemetry.context.propagation.TextMapPropagator;
    -import io.opentelemetry.extension.incubator.propagation.PassThroughPropagator;
     import java.util.Collections;
     import java.util.HashMap;
     import java.util.Map;
    diff --git a/api/events/src/main/java/io/opentelemetry/api/events/DefaultEventEmitter.java b/api/incubator/src/main/java/io/opentelemetry/api/incubator/events/DefaultEventEmitter.java
    similarity index 95%
    rename from api/events/src/main/java/io/opentelemetry/api/events/DefaultEventEmitter.java
    rename to api/incubator/src/main/java/io/opentelemetry/api/incubator/events/DefaultEventEmitter.java
    index 8d9a81f8e7f..1c914a74d9d 100644
    --- a/api/events/src/main/java/io/opentelemetry/api/events/DefaultEventEmitter.java
    +++ b/api/incubator/src/main/java/io/opentelemetry/api/incubator/events/DefaultEventEmitter.java
    @@ -3,7 +3,7 @@
      * SPDX-License-Identifier: Apache-2.0
      */
     
    -package io.opentelemetry.api.events;
    +package io.opentelemetry.api.incubator.events;
     
     import io.opentelemetry.api.common.Attributes;
     import java.time.Instant;
    diff --git a/api/events/src/main/java/io/opentelemetry/api/events/DefaultEventEmitterProvider.java b/api/incubator/src/main/java/io/opentelemetry/api/incubator/events/DefaultEventEmitterProvider.java
    similarity index 95%
    rename from api/events/src/main/java/io/opentelemetry/api/events/DefaultEventEmitterProvider.java
    rename to api/incubator/src/main/java/io/opentelemetry/api/incubator/events/DefaultEventEmitterProvider.java
    index 59f75872fa1..e69a9a3745f 100644
    --- a/api/events/src/main/java/io/opentelemetry/api/events/DefaultEventEmitterProvider.java
    +++ b/api/incubator/src/main/java/io/opentelemetry/api/incubator/events/DefaultEventEmitterProvider.java
    @@ -3,7 +3,7 @@
      * SPDX-License-Identifier: Apache-2.0
      */
     
    -package io.opentelemetry.api.events;
    +package io.opentelemetry.api.incubator.events;
     
     class DefaultEventEmitterProvider implements EventEmitterProvider {
     
    diff --git a/api/events/src/main/java/io/opentelemetry/api/events/EventBuilder.java b/api/incubator/src/main/java/io/opentelemetry/api/incubator/events/EventBuilder.java
    similarity index 94%
    rename from api/events/src/main/java/io/opentelemetry/api/events/EventBuilder.java
    rename to api/incubator/src/main/java/io/opentelemetry/api/incubator/events/EventBuilder.java
    index a9acabbca6c..d5eb5db85f3 100644
    --- a/api/events/src/main/java/io/opentelemetry/api/events/EventBuilder.java
    +++ b/api/incubator/src/main/java/io/opentelemetry/api/incubator/events/EventBuilder.java
    @@ -3,7 +3,7 @@
      * SPDX-License-Identifier: Apache-2.0
      */
     
    -package io.opentelemetry.api.events;
    +package io.opentelemetry.api.incubator.events;
     
     import java.time.Instant;
     import java.util.concurrent.TimeUnit;
    diff --git a/api/events/src/main/java/io/opentelemetry/api/events/EventEmitter.java b/api/incubator/src/main/java/io/opentelemetry/api/incubator/events/EventEmitter.java
    similarity index 96%
    rename from api/events/src/main/java/io/opentelemetry/api/events/EventEmitter.java
    rename to api/incubator/src/main/java/io/opentelemetry/api/incubator/events/EventEmitter.java
    index 395fa4e53e5..ba588f7ec79 100644
    --- a/api/events/src/main/java/io/opentelemetry/api/events/EventEmitter.java
    +++ b/api/incubator/src/main/java/io/opentelemetry/api/incubator/events/EventEmitter.java
    @@ -3,7 +3,7 @@
      * SPDX-License-Identifier: Apache-2.0
      */
     
    -package io.opentelemetry.api.events;
    +package io.opentelemetry.api.incubator.events;
     
     import io.opentelemetry.api.common.Attributes;
     import javax.annotation.concurrent.ThreadSafe;
    diff --git a/api/events/src/main/java/io/opentelemetry/api/events/EventEmitterBuilder.java b/api/incubator/src/main/java/io/opentelemetry/api/incubator/events/EventEmitterBuilder.java
    similarity index 96%
    rename from api/events/src/main/java/io/opentelemetry/api/events/EventEmitterBuilder.java
    rename to api/incubator/src/main/java/io/opentelemetry/api/incubator/events/EventEmitterBuilder.java
    index 0bdb9e2f57e..5fa04658652 100644
    --- a/api/events/src/main/java/io/opentelemetry/api/events/EventEmitterBuilder.java
    +++ b/api/incubator/src/main/java/io/opentelemetry/api/incubator/events/EventEmitterBuilder.java
    @@ -3,7 +3,7 @@
      * SPDX-License-Identifier: Apache-2.0
      */
     
    -package io.opentelemetry.api.events;
    +package io.opentelemetry.api.incubator.events;
     
     /**
      * Builder class for creating {@link EventEmitter} instances.
    diff --git a/api/events/src/main/java/io/opentelemetry/api/events/EventEmitterProvider.java b/api/incubator/src/main/java/io/opentelemetry/api/incubator/events/EventEmitterProvider.java
    similarity index 96%
    rename from api/events/src/main/java/io/opentelemetry/api/events/EventEmitterProvider.java
    rename to api/incubator/src/main/java/io/opentelemetry/api/incubator/events/EventEmitterProvider.java
    index 521154765fa..d5eb035e3f8 100644
    --- a/api/events/src/main/java/io/opentelemetry/api/events/EventEmitterProvider.java
    +++ b/api/incubator/src/main/java/io/opentelemetry/api/incubator/events/EventEmitterProvider.java
    @@ -3,7 +3,7 @@
      * SPDX-License-Identifier: Apache-2.0
      */
     
    -package io.opentelemetry.api.events;
    +package io.opentelemetry.api.incubator.events;
     
     import javax.annotation.concurrent.ThreadSafe;
     
    diff --git a/api/events/src/main/java/io/opentelemetry/api/events/GlobalEventEmitterProvider.java b/api/incubator/src/main/java/io/opentelemetry/api/incubator/events/GlobalEventEmitterProvider.java
    similarity index 97%
    rename from api/events/src/main/java/io/opentelemetry/api/events/GlobalEventEmitterProvider.java
    rename to api/incubator/src/main/java/io/opentelemetry/api/incubator/events/GlobalEventEmitterProvider.java
    index b6b1685bbfa..bf0e8353d52 100644
    --- a/api/events/src/main/java/io/opentelemetry/api/events/GlobalEventEmitterProvider.java
    +++ b/api/incubator/src/main/java/io/opentelemetry/api/incubator/events/GlobalEventEmitterProvider.java
    @@ -3,7 +3,7 @@
      * SPDX-License-Identifier: Apache-2.0
      */
     
    -package io.opentelemetry.api.events;
    +package io.opentelemetry.api.incubator.events;
     
     import io.opentelemetry.api.GlobalOpenTelemetry;
     import java.util.concurrent.atomic.AtomicReference;
    diff --git a/extensions/incubator/src/main/java/io/opentelemetry/extension/incubator/logs/AnyValue.java b/api/incubator/src/main/java/io/opentelemetry/api/incubator/logs/AnyValue.java
    similarity index 98%
    rename from extensions/incubator/src/main/java/io/opentelemetry/extension/incubator/logs/AnyValue.java
    rename to api/incubator/src/main/java/io/opentelemetry/api/incubator/logs/AnyValue.java
    index 6f250e10da7..1a1519a1044 100644
    --- a/extensions/incubator/src/main/java/io/opentelemetry/extension/incubator/logs/AnyValue.java
    +++ b/api/incubator/src/main/java/io/opentelemetry/api/incubator/logs/AnyValue.java
    @@ -3,7 +3,7 @@
      * SPDX-License-Identifier: Apache-2.0
      */
     
    -package io.opentelemetry.extension.incubator.logs;
    +package io.opentelemetry.api.incubator.logs;
     
     import java.nio.ByteBuffer;
     import java.util.List;
    diff --git a/extensions/incubator/src/main/java/io/opentelemetry/extension/incubator/logs/AnyValueArray.java b/api/incubator/src/main/java/io/opentelemetry/api/incubator/logs/AnyValueArray.java
    similarity index 96%
    rename from extensions/incubator/src/main/java/io/opentelemetry/extension/incubator/logs/AnyValueArray.java
    rename to api/incubator/src/main/java/io/opentelemetry/api/incubator/logs/AnyValueArray.java
    index dd96a60793d..ae448038b18 100644
    --- a/extensions/incubator/src/main/java/io/opentelemetry/extension/incubator/logs/AnyValueArray.java
    +++ b/api/incubator/src/main/java/io/opentelemetry/api/incubator/logs/AnyValueArray.java
    @@ -3,7 +3,7 @@
      * SPDX-License-Identifier: Apache-2.0
      */
     
    -package io.opentelemetry.extension.incubator.logs;
    +package io.opentelemetry.api.incubator.logs;
     
     import static java.util.stream.Collectors.joining;
     
    diff --git a/extensions/incubator/src/main/java/io/opentelemetry/extension/incubator/logs/AnyValueBoolean.java b/api/incubator/src/main/java/io/opentelemetry/api/incubator/logs/AnyValueBoolean.java
    similarity index 95%
    rename from extensions/incubator/src/main/java/io/opentelemetry/extension/incubator/logs/AnyValueBoolean.java
    rename to api/incubator/src/main/java/io/opentelemetry/api/incubator/logs/AnyValueBoolean.java
    index 5fa862b777f..fcaa7525241 100644
    --- a/extensions/incubator/src/main/java/io/opentelemetry/extension/incubator/logs/AnyValueBoolean.java
    +++ b/api/incubator/src/main/java/io/opentelemetry/api/incubator/logs/AnyValueBoolean.java
    @@ -3,7 +3,7 @@
      * SPDX-License-Identifier: Apache-2.0
      */
     
    -package io.opentelemetry.extension.incubator.logs;
    +package io.opentelemetry.api.incubator.logs;
     
     import java.util.Objects;
     
    diff --git a/extensions/incubator/src/main/java/io/opentelemetry/extension/incubator/logs/AnyValueBytes.java b/api/incubator/src/main/java/io/opentelemetry/api/incubator/logs/AnyValueBytes.java
    similarity index 95%
    rename from extensions/incubator/src/main/java/io/opentelemetry/extension/incubator/logs/AnyValueBytes.java
    rename to api/incubator/src/main/java/io/opentelemetry/api/incubator/logs/AnyValueBytes.java
    index 65697978dec..4f572dee172 100644
    --- a/extensions/incubator/src/main/java/io/opentelemetry/extension/incubator/logs/AnyValueBytes.java
    +++ b/api/incubator/src/main/java/io/opentelemetry/api/incubator/logs/AnyValueBytes.java
    @@ -3,7 +3,7 @@
      * SPDX-License-Identifier: Apache-2.0
      */
     
    -package io.opentelemetry.extension.incubator.logs;
    +package io.opentelemetry.api.incubator.logs;
     
     import java.nio.ByteBuffer;
     import java.util.Arrays;
    diff --git a/extensions/incubator/src/main/java/io/opentelemetry/extension/incubator/logs/AnyValueDouble.java b/api/incubator/src/main/java/io/opentelemetry/api/incubator/logs/AnyValueDouble.java
    similarity index 94%
    rename from extensions/incubator/src/main/java/io/opentelemetry/extension/incubator/logs/AnyValueDouble.java
    rename to api/incubator/src/main/java/io/opentelemetry/api/incubator/logs/AnyValueDouble.java
    index 4e2cdccf33b..e1ab55f8528 100644
    --- a/extensions/incubator/src/main/java/io/opentelemetry/extension/incubator/logs/AnyValueDouble.java
    +++ b/api/incubator/src/main/java/io/opentelemetry/api/incubator/logs/AnyValueDouble.java
    @@ -3,7 +3,7 @@
      * SPDX-License-Identifier: Apache-2.0
      */
     
    -package io.opentelemetry.extension.incubator.logs;
    +package io.opentelemetry.api.incubator.logs;
     
     import java.util.Objects;
     
    diff --git a/extensions/incubator/src/main/java/io/opentelemetry/extension/incubator/logs/AnyValueLong.java b/api/incubator/src/main/java/io/opentelemetry/api/incubator/logs/AnyValueLong.java
    similarity index 94%
    rename from extensions/incubator/src/main/java/io/opentelemetry/extension/incubator/logs/AnyValueLong.java
    rename to api/incubator/src/main/java/io/opentelemetry/api/incubator/logs/AnyValueLong.java
    index 558a08376ee..0cc1d3beafa 100644
    --- a/extensions/incubator/src/main/java/io/opentelemetry/extension/incubator/logs/AnyValueLong.java
    +++ b/api/incubator/src/main/java/io/opentelemetry/api/incubator/logs/AnyValueLong.java
    @@ -3,7 +3,7 @@
      * SPDX-License-Identifier: Apache-2.0
      */
     
    -package io.opentelemetry.extension.incubator.logs;
    +package io.opentelemetry.api.incubator.logs;
     
     import java.util.Objects;
     
    diff --git a/extensions/incubator/src/main/java/io/opentelemetry/extension/incubator/logs/AnyValueString.java b/api/incubator/src/main/java/io/opentelemetry/api/incubator/logs/AnyValueString.java
    similarity index 95%
    rename from extensions/incubator/src/main/java/io/opentelemetry/extension/incubator/logs/AnyValueString.java
    rename to api/incubator/src/main/java/io/opentelemetry/api/incubator/logs/AnyValueString.java
    index 6a7b0a1c8e2..d2b8be2e729 100644
    --- a/extensions/incubator/src/main/java/io/opentelemetry/extension/incubator/logs/AnyValueString.java
    +++ b/api/incubator/src/main/java/io/opentelemetry/api/incubator/logs/AnyValueString.java
    @@ -3,7 +3,7 @@
      * SPDX-License-Identifier: Apache-2.0
      */
     
    -package io.opentelemetry.extension.incubator.logs;
    +package io.opentelemetry.api.incubator.logs;
     
     import java.util.Objects;
     
    diff --git a/extensions/incubator/src/main/java/io/opentelemetry/extension/incubator/logs/AnyValueType.java b/api/incubator/src/main/java/io/opentelemetry/api/incubator/logs/AnyValueType.java
    similarity index 89%
    rename from extensions/incubator/src/main/java/io/opentelemetry/extension/incubator/logs/AnyValueType.java
    rename to api/incubator/src/main/java/io/opentelemetry/api/incubator/logs/AnyValueType.java
    index f683cc61ea5..ea41d887094 100644
    --- a/extensions/incubator/src/main/java/io/opentelemetry/extension/incubator/logs/AnyValueType.java
    +++ b/api/incubator/src/main/java/io/opentelemetry/api/incubator/logs/AnyValueType.java
    @@ -3,7 +3,7 @@
      * SPDX-License-Identifier: Apache-2.0
      */
     
    -package io.opentelemetry.extension.incubator.logs;
    +package io.opentelemetry.api.incubator.logs;
     
     /**
      * AnyValue type options, mirroring The README
    + * href="https://github.com/opentelemetry/opentelemetry-java/blob/main/api/incubator">README
      * explains the use cases in more detail.
      */
     public final class ExtendedTracer implements Tracer {
    diff --git a/extensions/incubator/src/main/java/io/opentelemetry/extension/incubator/trace/SpanCallable.java b/api/incubator/src/main/java/io/opentelemetry/api/incubator/trace/SpanCallable.java
    similarity index 86%
    rename from extensions/incubator/src/main/java/io/opentelemetry/extension/incubator/trace/SpanCallable.java
    rename to api/incubator/src/main/java/io/opentelemetry/api/incubator/trace/SpanCallable.java
    index eb87683f04d..881e1bd541d 100644
    --- a/extensions/incubator/src/main/java/io/opentelemetry/extension/incubator/trace/SpanCallable.java
    +++ b/api/incubator/src/main/java/io/opentelemetry/api/incubator/trace/SpanCallable.java
    @@ -3,7 +3,7 @@
      * SPDX-License-Identifier: Apache-2.0
      */
     
    -package io.opentelemetry.extension.incubator.trace;
    +package io.opentelemetry.api.incubator.trace;
     
     /**
      * An interface for creating a lambda that is wrapped in a span, returns a value, and that may
    diff --git a/extensions/incubator/src/main/java/io/opentelemetry/extension/incubator/trace/SpanRunnable.java b/api/incubator/src/main/java/io/opentelemetry/api/incubator/trace/SpanRunnable.java
    similarity index 86%
    rename from extensions/incubator/src/main/java/io/opentelemetry/extension/incubator/trace/SpanRunnable.java
    rename to api/incubator/src/main/java/io/opentelemetry/api/incubator/trace/SpanRunnable.java
    index 508df5a6c31..9f245f340bf 100644
    --- a/extensions/incubator/src/main/java/io/opentelemetry/extension/incubator/trace/SpanRunnable.java
    +++ b/api/incubator/src/main/java/io/opentelemetry/api/incubator/trace/SpanRunnable.java
    @@ -3,7 +3,7 @@
      * SPDX-License-Identifier: Apache-2.0
      */
     
    -package io.opentelemetry.extension.incubator.trace;
    +package io.opentelemetry.api.incubator.trace;
     
     /**
      * An interface for creating a lambda that is wrapped in a span and that may throw.
    diff --git a/api/events/src/test/java/io/opentelemetry/api/events/DefaultEventEmitterProviderTest.java b/api/incubator/src/test/java/io/opentelemetry/api/incubator/events/DefaultEventEmitterProviderTest.java
    similarity index 96%
    rename from api/events/src/test/java/io/opentelemetry/api/events/DefaultEventEmitterProviderTest.java
    rename to api/incubator/src/test/java/io/opentelemetry/api/incubator/events/DefaultEventEmitterProviderTest.java
    index 04c5cc83e86..52e23c5b44d 100644
    --- a/api/events/src/test/java/io/opentelemetry/api/events/DefaultEventEmitterProviderTest.java
    +++ b/api/incubator/src/test/java/io/opentelemetry/api/incubator/events/DefaultEventEmitterProviderTest.java
    @@ -3,7 +3,7 @@
      * SPDX-License-Identifier: Apache-2.0
      */
     
    -package io.opentelemetry.api.events;
    +package io.opentelemetry.api.incubator.events;
     
     import static org.assertj.core.api.Assertions.assertThat;
     import static org.assertj.core.api.Assertions.assertThatCode;
    diff --git a/api/events/src/test/java/io/opentelemetry/api/events/DefaultEventEmitterTest.java b/api/incubator/src/test/java/io/opentelemetry/api/incubator/events/DefaultEventEmitterTest.java
    similarity index 96%
    rename from api/events/src/test/java/io/opentelemetry/api/events/DefaultEventEmitterTest.java
    rename to api/incubator/src/test/java/io/opentelemetry/api/incubator/events/DefaultEventEmitterTest.java
    index 324680d13d6..a8d70533f47 100644
    --- a/api/events/src/test/java/io/opentelemetry/api/events/DefaultEventEmitterTest.java
    +++ b/api/incubator/src/test/java/io/opentelemetry/api/incubator/events/DefaultEventEmitterTest.java
    @@ -3,7 +3,7 @@
      * SPDX-License-Identifier: Apache-2.0
      */
     
    -package io.opentelemetry.api.events;
    +package io.opentelemetry.api.incubator.events;
     
     import static org.assertj.core.api.Assertions.assertThatCode;
     
    diff --git a/api/events/src/test/java/io/opentelemetry/api/events/GlobalEventEmitterProviderTest.java b/api/incubator/src/test/java/io/opentelemetry/api/incubator/events/GlobalEventEmitterProviderTest.java
    similarity index 97%
    rename from api/events/src/test/java/io/opentelemetry/api/events/GlobalEventEmitterProviderTest.java
    rename to api/incubator/src/test/java/io/opentelemetry/api/incubator/events/GlobalEventEmitterProviderTest.java
    index f05763ea2f9..8f48c17bc5b 100644
    --- a/api/events/src/test/java/io/opentelemetry/api/events/GlobalEventEmitterProviderTest.java
    +++ b/api/incubator/src/test/java/io/opentelemetry/api/incubator/events/GlobalEventEmitterProviderTest.java
    @@ -3,7 +3,7 @@
      * SPDX-License-Identifier: Apache-2.0
      */
     
    -package io.opentelemetry.api.events;
    +package io.opentelemetry.api.incubator.events;
     
     import static org.assertj.core.api.Assertions.assertThat;
     import static org.assertj.core.api.Assertions.assertThatThrownBy;
    diff --git a/extensions/incubator/src/test/java/io/opentelemetry/extension/incubator/logs/AnyValueTest.java b/api/incubator/src/test/java/io/opentelemetry/api/incubator/logs/AnyValueTest.java
    similarity index 99%
    rename from extensions/incubator/src/test/java/io/opentelemetry/extension/incubator/logs/AnyValueTest.java
    rename to api/incubator/src/test/java/io/opentelemetry/api/incubator/logs/AnyValueTest.java
    index 900cdd24c93..4f52637f575 100644
    --- a/extensions/incubator/src/test/java/io/opentelemetry/extension/incubator/logs/AnyValueTest.java
    +++ b/api/incubator/src/test/java/io/opentelemetry/api/incubator/logs/AnyValueTest.java
    @@ -3,7 +3,7 @@
      * SPDX-License-Identifier: Apache-2.0
      */
     
    -package io.opentelemetry.extension.incubator.logs;
    +package io.opentelemetry.api.incubator.logs;
     
     import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.assertThat;
     import static org.assertj.core.api.Assertions.assertThatThrownBy;
    diff --git a/extensions/incubator/src/test/java/io/opentelemetry/extension/incubator/propagation/PassThroughPropagatorTest.java b/api/incubator/src/test/java/io/opentelemetry/api/incubator/propagation/PassThroughPropagatorTest.java
    similarity index 98%
    rename from extensions/incubator/src/test/java/io/opentelemetry/extension/incubator/propagation/PassThroughPropagatorTest.java
    rename to api/incubator/src/test/java/io/opentelemetry/api/incubator/propagation/PassThroughPropagatorTest.java
    index de93164c004..008694252b8 100644
    --- a/extensions/incubator/src/test/java/io/opentelemetry/extension/incubator/propagation/PassThroughPropagatorTest.java
    +++ b/api/incubator/src/test/java/io/opentelemetry/api/incubator/propagation/PassThroughPropagatorTest.java
    @@ -3,7 +3,7 @@
      * SPDX-License-Identifier: Apache-2.0
      */
     
    -package io.opentelemetry.extension.incubator.propagation;
    +package io.opentelemetry.api.incubator.propagation;
     
     import static org.assertj.core.api.Assertions.assertThat;
     import static org.assertj.core.api.Assertions.assertThatThrownBy;
    diff --git a/extensions/incubator/src/test/java/io/opentelemetry/extension/incubator/trace/ExtendedTracerTest.java b/api/incubator/src/test/java/io/opentelemetry/api/incubator/trace/ExtendedTracerTest.java
    similarity index 98%
    rename from extensions/incubator/src/test/java/io/opentelemetry/extension/incubator/trace/ExtendedTracerTest.java
    rename to api/incubator/src/test/java/io/opentelemetry/api/incubator/trace/ExtendedTracerTest.java
    index 2268d6e59a0..9417763b842 100644
    --- a/extensions/incubator/src/test/java/io/opentelemetry/extension/incubator/trace/ExtendedTracerTest.java
    +++ b/api/incubator/src/test/java/io/opentelemetry/api/incubator/trace/ExtendedTracerTest.java
    @@ -3,7 +3,7 @@
      * SPDX-License-Identifier: Apache-2.0
      */
     
    -package io.opentelemetry.extension.incubator.trace;
    +package io.opentelemetry.api.incubator.trace;
     
     import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.equalTo;
     import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.satisfies;
    @@ -14,12 +14,12 @@
     
     import com.google.errorprone.annotations.Keep;
     import io.opentelemetry.api.common.Attributes;
    +import io.opentelemetry.api.incubator.propagation.ExtendedContextPropagators;
     import io.opentelemetry.api.trace.Span;
     import io.opentelemetry.api.trace.SpanKind;
     import io.opentelemetry.context.Context;
     import io.opentelemetry.context.Scope;
     import io.opentelemetry.context.propagation.ContextPropagators;
    -import io.opentelemetry.extension.incubator.propagation.ExtendedContextPropagators;
     import io.opentelemetry.sdk.testing.assertj.SpanDataAssert;
     import io.opentelemetry.sdk.testing.junit5.OpenTelemetryExtension;
     import io.opentelemetry.sdk.trace.data.StatusData;
    diff --git a/exporters/otlp/common/build.gradle.kts b/exporters/otlp/common/build.gradle.kts
    index 1baf390fc34..def08665e58 100644
    --- a/exporters/otlp/common/build.gradle.kts
    +++ b/exporters/otlp/common/build.gradle.kts
    @@ -16,7 +16,7 @@ dependencies {
       protoSource("io.opentelemetry.proto:opentelemetry-proto:${versions["io.opentelemetry.proto"]}")
     
       api(project(":exporters:common"))
    -  implementation(project(":extensions:incubator"))
    +  implementation(project(":api:incubator"))
     
       compileOnly(project(":sdk:metrics"))
       compileOnly(project(":sdk:trace"))
    diff --git a/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/AnyValueMarshaler.java b/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/AnyValueMarshaler.java
    index 2bd103a154a..0b39d15df29 100644
    --- a/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/AnyValueMarshaler.java
    +++ b/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/AnyValueMarshaler.java
    @@ -5,9 +5,9 @@
     
     package io.opentelemetry.exporter.internal.otlp;
     
    +import io.opentelemetry.api.incubator.logs.AnyValue;
    +import io.opentelemetry.api.incubator.logs.KeyAnyValue;
     import io.opentelemetry.exporter.internal.marshal.MarshalerWithSize;
    -import io.opentelemetry.extension.incubator.logs.AnyValue;
    -import io.opentelemetry.extension.incubator.logs.KeyAnyValue;
     import java.nio.ByteBuffer;
     import java.util.List;
     
    diff --git a/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/ArrayAnyValueMarshaler.java b/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/ArrayAnyValueMarshaler.java
    index e4184086468..aa1c25e9c14 100644
    --- a/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/ArrayAnyValueMarshaler.java
    +++ b/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/ArrayAnyValueMarshaler.java
    @@ -24,7 +24,7 @@ private ArrayAnyValueMarshaler(ArrayValueMarshaler value) {
       }
     
       static MarshalerWithSize createAnyValue(
    -      List> values) {
    +      List> values) {
         return createInternal(values, AnyValueMarshaler::create);
       }
     
    diff --git a/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/KeyValueListAnyValueMarshaler.java b/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/KeyValueListAnyValueMarshaler.java
    index 823c28226c8..afb884a2d86 100644
    --- a/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/KeyValueListAnyValueMarshaler.java
    +++ b/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/KeyValueListAnyValueMarshaler.java
    @@ -5,11 +5,11 @@
     
     package io.opentelemetry.exporter.internal.otlp;
     
    +import io.opentelemetry.api.incubator.logs.KeyAnyValue;
     import io.opentelemetry.exporter.internal.marshal.Marshaler;
     import io.opentelemetry.exporter.internal.marshal.MarshalerUtil;
     import io.opentelemetry.exporter.internal.marshal.MarshalerWithSize;
     import io.opentelemetry.exporter.internal.marshal.Serializer;
    -import io.opentelemetry.extension.incubator.logs.KeyAnyValue;
     import io.opentelemetry.proto.common.v1.internal.AnyValue;
     import io.opentelemetry.proto.common.v1.internal.KeyValueList;
     import java.io.IOException;
    diff --git a/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/KeyValueMarshaler.java b/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/KeyValueMarshaler.java
    index 1db0dc2edd5..56a3fa06461 100644
    --- a/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/KeyValueMarshaler.java
    +++ b/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/KeyValueMarshaler.java
    @@ -7,12 +7,12 @@
     
     import io.opentelemetry.api.common.AttributeKey;
     import io.opentelemetry.api.common.Attributes;
    +import io.opentelemetry.api.incubator.logs.KeyAnyValue;
     import io.opentelemetry.api.internal.InternalAttributeKeyImpl;
     import io.opentelemetry.exporter.internal.marshal.Marshaler;
     import io.opentelemetry.exporter.internal.marshal.MarshalerUtil;
     import io.opentelemetry.exporter.internal.marshal.MarshalerWithSize;
     import io.opentelemetry.exporter.internal.marshal.Serializer;
    -import io.opentelemetry.extension.incubator.logs.KeyAnyValue;
     import io.opentelemetry.proto.common.v1.internal.KeyValue;
     import java.io.IOException;
     import java.nio.charset.StandardCharsets;
    diff --git a/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/logs/LogMarshaler.java b/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/logs/LogMarshaler.java
    index 911cadf2d84..d73c88bb608 100644
    --- a/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/logs/LogMarshaler.java
    +++ b/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/logs/LogMarshaler.java
    @@ -5,6 +5,7 @@
     
     package io.opentelemetry.exporter.internal.otlp.logs;
     
    +import io.opentelemetry.api.incubator.logs.AnyValue;
     import io.opentelemetry.api.logs.Severity;
     import io.opentelemetry.api.trace.SpanContext;
     import io.opentelemetry.api.trace.SpanId;
    @@ -16,7 +17,6 @@
     import io.opentelemetry.exporter.internal.marshal.Serializer;
     import io.opentelemetry.exporter.internal.otlp.AnyValueMarshaler;
     import io.opentelemetry.exporter.internal.otlp.KeyValueMarshaler;
    -import io.opentelemetry.extension.incubator.logs.AnyValue;
     import io.opentelemetry.proto.logs.v1.internal.LogRecord;
     import io.opentelemetry.proto.logs.v1.internal.SeverityNumber;
     import io.opentelemetry.sdk.logs.data.Body;
    diff --git a/exporters/otlp/common/src/test/java/io/opentelemetry/exporter/internal/otlp/AnyValueMarshalerTest.java b/exporters/otlp/common/src/test/java/io/opentelemetry/exporter/internal/otlp/AnyValueMarshalerTest.java
    index d52d504e9c4..9514249defb 100644
    --- a/exporters/otlp/common/src/test/java/io/opentelemetry/exporter/internal/otlp/AnyValueMarshalerTest.java
    +++ b/exporters/otlp/common/src/test/java/io/opentelemetry/exporter/internal/otlp/AnyValueMarshalerTest.java
    @@ -5,7 +5,7 @@
     
     package io.opentelemetry.exporter.internal.otlp;
     
    -import static io.opentelemetry.extension.incubator.logs.AnyValue.of;
    +import static io.opentelemetry.api.incubator.logs.AnyValue.of;
     import static org.assertj.core.api.Assertions.assertThat;
     import static org.junit.jupiter.params.provider.Arguments.arguments;
     
    @@ -13,9 +13,9 @@
     import com.google.protobuf.InvalidProtocolBufferException;
     import com.google.protobuf.Message;
     import com.google.protobuf.util.JsonFormat;
    +import io.opentelemetry.api.incubator.logs.KeyAnyValue;
     import io.opentelemetry.exporter.internal.marshal.Marshaler;
     import io.opentelemetry.exporter.internal.marshal.MarshalerWithSize;
    -import io.opentelemetry.extension.incubator.logs.KeyAnyValue;
     import io.opentelemetry.proto.common.v1.AnyValue;
     import io.opentelemetry.proto.common.v1.ArrayValue;
     import io.opentelemetry.proto.common.v1.KeyValue;
    @@ -36,8 +36,7 @@ class AnyValueMarshalerTest {
       @ParameterizedTest
       @MethodSource("serializeAnyValueArgs")
       void anyValueString(
    -      io.opentelemetry.extension.incubator.logs.AnyValue anyValue,
    -      AnyValue expectedSerializedValue) {
    +      io.opentelemetry.api.incubator.logs.AnyValue anyValue, AnyValue expectedSerializedValue) {
         MarshalerWithSize marshaler = AnyValueMarshaler.create(anyValue);
         AnyValue serializedValue = parse(AnyValue.getDefaultInstance(), marshaler);
         assertThat(serializedValue).isEqualTo(expectedSerializedValue);
    diff --git a/integration-tests/otlp/build.gradle.kts b/integration-tests/otlp/build.gradle.kts
    index bbd9bc85c4c..5f67edda0e1 100644
    --- a/integration-tests/otlp/build.gradle.kts
    +++ b/integration-tests/otlp/build.gradle.kts
    @@ -9,8 +9,7 @@ dependencies {
       api("org.testcontainers:junit-jupiter")
     
       implementation(project(":exporters:otlp:all"))
    -  implementation(project(":api:events"))
    -  implementation(project(":extensions:incubator"))
    +  implementation(project(":api:incubator"))
     
       compileOnly("com.google.errorprone:error_prone_annotations")
     
    diff --git a/integration-tests/otlp/src/main/java/io/opentelemetry/integrationtest/OtlpExporterIntegrationTest.java b/integration-tests/otlp/src/main/java/io/opentelemetry/integrationtest/OtlpExporterIntegrationTest.java
    index 30ab713b118..544b9a94794 100644
    --- a/integration-tests/otlp/src/main/java/io/opentelemetry/integrationtest/OtlpExporterIntegrationTest.java
    +++ b/integration-tests/otlp/src/main/java/io/opentelemetry/integrationtest/OtlpExporterIntegrationTest.java
    @@ -5,7 +5,7 @@
     
     package io.opentelemetry.integrationtest;
     
    -import static io.opentelemetry.extension.incubator.logs.AnyValue.of;
    +import static io.opentelemetry.api.incubator.logs.AnyValue.of;
     import static java.util.concurrent.CompletableFuture.completedFuture;
     import static org.assertj.core.api.Assertions.assertThat;
     import static org.awaitility.Awaitility.await;
    @@ -21,7 +21,9 @@
     import io.opentelemetry.api.GlobalOpenTelemetry;
     import io.opentelemetry.api.common.AttributeKey;
     import io.opentelemetry.api.common.Attributes;
    -import io.opentelemetry.api.events.EventEmitter;
    +import io.opentelemetry.api.incubator.events.EventEmitter;
    +import io.opentelemetry.api.incubator.logs.ExtendedLogRecordBuilder;
    +import io.opentelemetry.api.incubator.logs.KeyAnyValue;
     import io.opentelemetry.api.logs.Logger;
     import io.opentelemetry.api.logs.Severity;
     import io.opentelemetry.api.metrics.LongCounter;
    @@ -40,8 +42,6 @@
     import io.opentelemetry.exporter.otlp.logs.OtlpGrpcLogRecordExporter;
     import io.opentelemetry.exporter.otlp.metrics.OtlpGrpcMetricExporter;
     import io.opentelemetry.exporter.otlp.trace.OtlpGrpcSpanExporter;
    -import io.opentelemetry.extension.incubator.logs.ExtendedLogRecordBuilder;
    -import io.opentelemetry.extension.incubator.logs.KeyAnyValue;
     import io.opentelemetry.proto.collector.logs.v1.ExportLogsServiceRequest;
     import io.opentelemetry.proto.collector.logs.v1.ExportLogsServiceResponse;
     import io.opentelemetry.proto.collector.metrics.v1.ExportMetricsServiceRequest;
    diff --git a/sdk-extensions/autoconfigure/build.gradle.kts b/sdk-extensions/autoconfigure/build.gradle.kts
    index 04fbde232fc..fb73bdaa6b6 100644
    --- a/sdk-extensions/autoconfigure/build.gradle.kts
    +++ b/sdk-extensions/autoconfigure/build.gradle.kts
    @@ -10,7 +10,7 @@ dependencies {
       api(project(":sdk:all"))
       api(project(":sdk-extensions:autoconfigure-spi"))
     
    -  implementation(project(":api:events"))
    +  implementation(project(":api:incubator"))
     
       annotationProcessor("com.google.auto.value:auto-value")
     
    @@ -47,7 +47,7 @@ testing {
         }
         register("testFullConfig") {
           dependencies {
    -        implementation(project(":api:events"))
    +        implementation(project(":api:incubator"))
             implementation(project(":extensions:trace-propagators"))
             implementation(project(":exporters:logging"))
             implementation(project(":exporters:logging-otlp"))
    diff --git a/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/AutoConfiguredOpenTelemetrySdkBuilder.java b/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/AutoConfiguredOpenTelemetrySdkBuilder.java
    index fe9d75adae3..08bb093939e 100644
    --- a/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/AutoConfiguredOpenTelemetrySdkBuilder.java
    +++ b/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/AutoConfiguredOpenTelemetrySdkBuilder.java
    @@ -8,7 +8,7 @@
     import static java.util.Objects.requireNonNull;
     
     import io.opentelemetry.api.GlobalOpenTelemetry;
    -import io.opentelemetry.api.events.GlobalEventEmitterProvider;
    +import io.opentelemetry.api.incubator.events.GlobalEventEmitterProvider;
     import io.opentelemetry.context.propagation.ContextPropagators;
     import io.opentelemetry.context.propagation.TextMapPropagator;
     import io.opentelemetry.sdk.OpenTelemetrySdk;
    diff --git a/sdk-extensions/autoconfigure/src/test/java/io/opentelemetry/sdk/autoconfigure/AutoConfiguredOpenTelemetrySdkTest.java b/sdk-extensions/autoconfigure/src/test/java/io/opentelemetry/sdk/autoconfigure/AutoConfiguredOpenTelemetrySdkTest.java
    index 5e8ea677c7f..57b8eb011fb 100644
    --- a/sdk-extensions/autoconfigure/src/test/java/io/opentelemetry/sdk/autoconfigure/AutoConfiguredOpenTelemetrySdkTest.java
    +++ b/sdk-extensions/autoconfigure/src/test/java/io/opentelemetry/sdk/autoconfigure/AutoConfiguredOpenTelemetrySdkTest.java
    @@ -26,7 +26,7 @@
     import io.github.netmikey.logunit.api.LogCapturer;
     import io.opentelemetry.api.GlobalOpenTelemetry;
     import io.opentelemetry.api.OpenTelemetry;
    -import io.opentelemetry.api.events.GlobalEventEmitterProvider;
    +import io.opentelemetry.api.incubator.events.GlobalEventEmitterProvider;
     import io.opentelemetry.api.trace.Span;
     import io.opentelemetry.api.trace.SpanId;
     import io.opentelemetry.api.trace.TraceId;
    diff --git a/sdk-extensions/autoconfigure/src/testFullConfig/java/io/opentelemetry/sdk/autoconfigure/AutoConfiguredOpenTelemetrySdkTest.java b/sdk-extensions/autoconfigure/src/testFullConfig/java/io/opentelemetry/sdk/autoconfigure/AutoConfiguredOpenTelemetrySdkTest.java
    index f1f880441e6..2c85ae02507 100644
    --- a/sdk-extensions/autoconfigure/src/testFullConfig/java/io/opentelemetry/sdk/autoconfigure/AutoConfiguredOpenTelemetrySdkTest.java
    +++ b/sdk-extensions/autoconfigure/src/testFullConfig/java/io/opentelemetry/sdk/autoconfigure/AutoConfiguredOpenTelemetrySdkTest.java
    @@ -13,7 +13,7 @@
     import io.github.netmikey.logunit.api.LogCapturer;
     import io.opentelemetry.api.GlobalOpenTelemetry;
     import io.opentelemetry.api.OpenTelemetry;
    -import io.opentelemetry.api.events.GlobalEventEmitterProvider;
    +import io.opentelemetry.api.incubator.events.GlobalEventEmitterProvider;
     import io.opentelemetry.exporter.prometheus.PrometheusHttpServer;
     import io.opentelemetry.sdk.OpenTelemetrySdk;
     import java.lang.reflect.Field;
    diff --git a/sdk-extensions/autoconfigure/src/testFullConfig/java/io/opentelemetry/sdk/autoconfigure/FileConfigurationTest.java b/sdk-extensions/autoconfigure/src/testFullConfig/java/io/opentelemetry/sdk/autoconfigure/FileConfigurationTest.java
    index ea726ca3472..058b6ed91d3 100644
    --- a/sdk-extensions/autoconfigure/src/testFullConfig/java/io/opentelemetry/sdk/autoconfigure/FileConfigurationTest.java
    +++ b/sdk-extensions/autoconfigure/src/testFullConfig/java/io/opentelemetry/sdk/autoconfigure/FileConfigurationTest.java
    @@ -19,7 +19,7 @@
     import io.opentelemetry.api.GlobalOpenTelemetry;
     import io.opentelemetry.api.OpenTelemetry;
     import io.opentelemetry.api.baggage.propagation.W3CBaggagePropagator;
    -import io.opentelemetry.api.events.GlobalEventEmitterProvider;
    +import io.opentelemetry.api.incubator.events.GlobalEventEmitterProvider;
     import io.opentelemetry.api.trace.propagation.W3CTraceContextPropagator;
     import io.opentelemetry.context.propagation.ContextPropagators;
     import io.opentelemetry.context.propagation.TextMapPropagator;
    diff --git a/sdk-extensions/autoconfigure/src/testFullConfig/java/io/opentelemetry/sdk/autoconfigure/FullConfigTest.java b/sdk-extensions/autoconfigure/src/testFullConfig/java/io/opentelemetry/sdk/autoconfigure/FullConfigTest.java
    index 3015339f71e..a5c5fc2fe24 100644
    --- a/sdk-extensions/autoconfigure/src/testFullConfig/java/io/opentelemetry/sdk/autoconfigure/FullConfigTest.java
    +++ b/sdk-extensions/autoconfigure/src/testFullConfig/java/io/opentelemetry/sdk/autoconfigure/FullConfigTest.java
    @@ -18,8 +18,8 @@
     import io.opentelemetry.api.GlobalOpenTelemetry;
     import io.opentelemetry.api.baggage.propagation.W3CBaggagePropagator;
     import io.opentelemetry.api.common.Attributes;
    -import io.opentelemetry.api.events.EventEmitter;
    -import io.opentelemetry.api.events.GlobalEventEmitterProvider;
    +import io.opentelemetry.api.incubator.events.EventEmitter;
    +import io.opentelemetry.api.incubator.events.GlobalEventEmitterProvider;
     import io.opentelemetry.api.logs.Logger;
     import io.opentelemetry.api.logs.Severity;
     import io.opentelemetry.api.metrics.Meter;
    diff --git a/sdk/logs/build.gradle.kts b/sdk/logs/build.gradle.kts
    index 6640c4ed0ee..7c8c020d6a2 100644
    --- a/sdk/logs/build.gradle.kts
    +++ b/sdk/logs/build.gradle.kts
    @@ -12,9 +12,7 @@ otelJava.moduleName.set("io.opentelemetry.sdk.logs")
     dependencies {
       api(project(":api:all"))
       api(project(":sdk:common"))
    -  implementation(project(":extensions:incubator"))
    -
    -  implementation(project(":api:events"))
    +  implementation(project(":api:incubator"))
     
       annotationProcessor("com.google.auto.value:auto-value")
     
    diff --git a/sdk/logs/src/main/java/io/opentelemetry/sdk/logs/SdkLogRecordBuilder.java b/sdk/logs/src/main/java/io/opentelemetry/sdk/logs/SdkLogRecordBuilder.java
    index 70683a0d22b..6ab1cafe648 100644
    --- a/sdk/logs/src/main/java/io/opentelemetry/sdk/logs/SdkLogRecordBuilder.java
    +++ b/sdk/logs/src/main/java/io/opentelemetry/sdk/logs/SdkLogRecordBuilder.java
    @@ -6,12 +6,12 @@
     package io.opentelemetry.sdk.logs;
     
     import io.opentelemetry.api.common.AttributeKey;
    +import io.opentelemetry.api.incubator.logs.AnyValue;
    +import io.opentelemetry.api.incubator.logs.ExtendedLogRecordBuilder;
     import io.opentelemetry.api.logs.LogRecordBuilder;
     import io.opentelemetry.api.logs.Severity;
     import io.opentelemetry.api.trace.Span;
     import io.opentelemetry.context.Context;
    -import io.opentelemetry.extension.incubator.logs.AnyValue;
    -import io.opentelemetry.extension.incubator.logs.ExtendedLogRecordBuilder;
     import io.opentelemetry.sdk.common.InstrumentationScopeInfo;
     import io.opentelemetry.sdk.internal.AttributesMap;
     import io.opentelemetry.sdk.logs.data.Body;
    diff --git a/sdk/logs/src/main/java/io/opentelemetry/sdk/logs/internal/AnyValueBody.java b/sdk/logs/src/main/java/io/opentelemetry/sdk/logs/internal/AnyValueBody.java
    index 7a1a9f2138f..fdf2b936cd1 100644
    --- a/sdk/logs/src/main/java/io/opentelemetry/sdk/logs/internal/AnyValueBody.java
    +++ b/sdk/logs/src/main/java/io/opentelemetry/sdk/logs/internal/AnyValueBody.java
    @@ -5,7 +5,7 @@
     
     package io.opentelemetry.sdk.logs.internal;
     
    -import io.opentelemetry.extension.incubator.logs.AnyValue;
    +import io.opentelemetry.api.incubator.logs.AnyValue;
     import io.opentelemetry.sdk.logs.data.Body;
     import javax.annotation.concurrent.Immutable;
     
    diff --git a/sdk/logs/src/main/java/io/opentelemetry/sdk/logs/internal/SdkEventBuilder.java b/sdk/logs/src/main/java/io/opentelemetry/sdk/logs/internal/SdkEventBuilder.java
    index aefa6832242..d817edad529 100644
    --- a/sdk/logs/src/main/java/io/opentelemetry/sdk/logs/internal/SdkEventBuilder.java
    +++ b/sdk/logs/src/main/java/io/opentelemetry/sdk/logs/internal/SdkEventBuilder.java
    @@ -5,7 +5,7 @@
     
     package io.opentelemetry.sdk.logs.internal;
     
    -import io.opentelemetry.api.events.EventBuilder;
    +import io.opentelemetry.api.incubator.events.EventBuilder;
     import io.opentelemetry.api.logs.LogRecordBuilder;
     import java.time.Instant;
     import java.util.concurrent.TimeUnit;
    diff --git a/sdk/logs/src/main/java/io/opentelemetry/sdk/logs/internal/SdkEventEmitterProvider.java b/sdk/logs/src/main/java/io/opentelemetry/sdk/logs/internal/SdkEventEmitterProvider.java
    index 885f46f7e94..0fdaa6f05ad 100644
    --- a/sdk/logs/src/main/java/io/opentelemetry/sdk/logs/internal/SdkEventEmitterProvider.java
    +++ b/sdk/logs/src/main/java/io/opentelemetry/sdk/logs/internal/SdkEventEmitterProvider.java
    @@ -7,10 +7,10 @@
     
     import io.opentelemetry.api.common.AttributeKey;
     import io.opentelemetry.api.common.Attributes;
    -import io.opentelemetry.api.events.EventBuilder;
    -import io.opentelemetry.api.events.EventEmitter;
    -import io.opentelemetry.api.events.EventEmitterBuilder;
    -import io.opentelemetry.api.events.EventEmitterProvider;
    +import io.opentelemetry.api.incubator.events.EventBuilder;
    +import io.opentelemetry.api.incubator.events.EventEmitter;
    +import io.opentelemetry.api.incubator.events.EventEmitterBuilder;
    +import io.opentelemetry.api.incubator.events.EventEmitterProvider;
     import io.opentelemetry.api.logs.LogRecordBuilder;
     import io.opentelemetry.api.logs.Logger;
     import io.opentelemetry.api.logs.LoggerBuilder;
    diff --git a/sdk/logs/src/test/java/io/opentelemetry/sdk/logs/AnyValueBodyTest.java b/sdk/logs/src/test/java/io/opentelemetry/sdk/logs/AnyValueBodyTest.java
    index 0345ecbd2fa..8ac803c5c7e 100644
    --- a/sdk/logs/src/test/java/io/opentelemetry/sdk/logs/AnyValueBodyTest.java
    +++ b/sdk/logs/src/test/java/io/opentelemetry/sdk/logs/AnyValueBodyTest.java
    @@ -7,10 +7,10 @@
     
     import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.assertThat;
     
    +import io.opentelemetry.api.incubator.logs.AnyValue;
    +import io.opentelemetry.api.incubator.logs.ExtendedLogRecordBuilder;
    +import io.opentelemetry.api.incubator.logs.KeyAnyValue;
     import io.opentelemetry.api.logs.Logger;
    -import io.opentelemetry.extension.incubator.logs.AnyValue;
    -import io.opentelemetry.extension.incubator.logs.ExtendedLogRecordBuilder;
    -import io.opentelemetry.extension.incubator.logs.KeyAnyValue;
     import io.opentelemetry.sdk.logs.export.SimpleLogRecordProcessor;
     import io.opentelemetry.sdk.logs.internal.AnyValueBody;
     import io.opentelemetry.sdk.testing.exporter.InMemoryLogRecordExporter;
    diff --git a/sdk/logs/src/test/java/io/opentelemetry/sdk/logs/internal/SdkEventEmitterProviderTest.java b/sdk/logs/src/test/java/io/opentelemetry/sdk/logs/internal/SdkEventEmitterProviderTest.java
    index bf7e58ddc5f..73db07cce57 100644
    --- a/sdk/logs/src/test/java/io/opentelemetry/sdk/logs/internal/SdkEventEmitterProviderTest.java
    +++ b/sdk/logs/src/test/java/io/opentelemetry/sdk/logs/internal/SdkEventEmitterProviderTest.java
    @@ -11,7 +11,7 @@
     import static org.mockito.Mockito.when;
     
     import io.opentelemetry.api.common.Attributes;
    -import io.opentelemetry.api.events.EventEmitter;
    +import io.opentelemetry.api.incubator.events.EventEmitter;
     import io.opentelemetry.sdk.common.Clock;
     import io.opentelemetry.sdk.common.InstrumentationScopeInfo;
     import io.opentelemetry.sdk.logs.ReadWriteLogRecord;
    diff --git a/sdk/metrics/build.gradle.kts b/sdk/metrics/build.gradle.kts
    index 590a312b043..ef2dd8244a5 100644
    --- a/sdk/metrics/build.gradle.kts
    +++ b/sdk/metrics/build.gradle.kts
    @@ -15,7 +15,7 @@ otelJava.moduleName.set("io.opentelemetry.sdk.metrics")
     dependencies {
       api(project(":api:all"))
       api(project(":sdk:common"))
    -  implementation(project(":extensions:incubator"))
    +  implementation(project(":api:incubator"))
     
       compileOnly("org.codehaus.mojo:animal-sniffer-annotations")
     
    diff --git a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkDoubleCounter.java b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkDoubleCounter.java
    index d92cd29076c..d7aa5f47cad 100644
    --- a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkDoubleCounter.java
    +++ b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkDoubleCounter.java
    @@ -7,12 +7,12 @@
     
     import io.opentelemetry.api.common.AttributeKey;
     import io.opentelemetry.api.common.Attributes;
    +import io.opentelemetry.api.incubator.metrics.ExtendedDoubleCounterBuilder;
     import io.opentelemetry.api.metrics.DoubleCounter;
     import io.opentelemetry.api.metrics.DoubleCounterBuilder;
     import io.opentelemetry.api.metrics.ObservableDoubleCounter;
     import io.opentelemetry.api.metrics.ObservableDoubleMeasurement;
     import io.opentelemetry.context.Context;
    -import io.opentelemetry.extension.incubator.metrics.ExtendedDoubleCounterBuilder;
     import io.opentelemetry.sdk.internal.ThrottlingLogger;
     import io.opentelemetry.sdk.metrics.internal.descriptor.Advice;
     import io.opentelemetry.sdk.metrics.internal.descriptor.InstrumentDescriptor;
    diff --git a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkDoubleGauge.java b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkDoubleGauge.java
    index e9f852510b5..1de8fa341cf 100644
    --- a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkDoubleGauge.java
    +++ b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkDoubleGauge.java
    @@ -7,13 +7,13 @@
     
     import io.opentelemetry.api.common.AttributeKey;
     import io.opentelemetry.api.common.Attributes;
    +import io.opentelemetry.api.incubator.metrics.DoubleGauge;
    +import io.opentelemetry.api.incubator.metrics.ExtendedDoubleGaugeBuilder;
     import io.opentelemetry.api.metrics.DoubleGaugeBuilder;
     import io.opentelemetry.api.metrics.LongGaugeBuilder;
     import io.opentelemetry.api.metrics.ObservableDoubleGauge;
     import io.opentelemetry.api.metrics.ObservableDoubleMeasurement;
     import io.opentelemetry.context.Context;
    -import io.opentelemetry.extension.incubator.metrics.DoubleGauge;
    -import io.opentelemetry.extension.incubator.metrics.ExtendedDoubleGaugeBuilder;
     import io.opentelemetry.sdk.metrics.internal.descriptor.InstrumentDescriptor;
     import io.opentelemetry.sdk.metrics.internal.state.MeterProviderSharedState;
     import io.opentelemetry.sdk.metrics.internal.state.MeterSharedState;
    diff --git a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkDoubleHistogram.java b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkDoubleHistogram.java
    index 9d9c1535f0b..15dd7d2f8c7 100644
    --- a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkDoubleHistogram.java
    +++ b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkDoubleHistogram.java
    @@ -7,11 +7,11 @@
     
     import io.opentelemetry.api.common.AttributeKey;
     import io.opentelemetry.api.common.Attributes;
    +import io.opentelemetry.api.incubator.metrics.ExtendedDoubleHistogramBuilder;
     import io.opentelemetry.api.metrics.DoubleHistogram;
     import io.opentelemetry.api.metrics.DoubleHistogramBuilder;
     import io.opentelemetry.api.metrics.LongHistogramBuilder;
     import io.opentelemetry.context.Context;
    -import io.opentelemetry.extension.incubator.metrics.ExtendedDoubleHistogramBuilder;
     import io.opentelemetry.sdk.internal.ThrottlingLogger;
     import io.opentelemetry.sdk.metrics.internal.aggregator.ExplicitBucketHistogramUtils;
     import io.opentelemetry.sdk.metrics.internal.descriptor.InstrumentDescriptor;
    diff --git a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkDoubleUpDownCounter.java b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkDoubleUpDownCounter.java
    index 6521aeef871..57188aa6a23 100644
    --- a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkDoubleUpDownCounter.java
    +++ b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkDoubleUpDownCounter.java
    @@ -7,12 +7,12 @@
     
     import io.opentelemetry.api.common.AttributeKey;
     import io.opentelemetry.api.common.Attributes;
    +import io.opentelemetry.api.incubator.metrics.ExtendedDoubleUpDownCounterBuilder;
     import io.opentelemetry.api.metrics.DoubleUpDownCounter;
     import io.opentelemetry.api.metrics.DoubleUpDownCounterBuilder;
     import io.opentelemetry.api.metrics.ObservableDoubleMeasurement;
     import io.opentelemetry.api.metrics.ObservableDoubleUpDownCounter;
     import io.opentelemetry.context.Context;
    -import io.opentelemetry.extension.incubator.metrics.ExtendedDoubleUpDownCounterBuilder;
     import io.opentelemetry.sdk.metrics.internal.descriptor.Advice;
     import io.opentelemetry.sdk.metrics.internal.descriptor.InstrumentDescriptor;
     import io.opentelemetry.sdk.metrics.internal.state.MeterProviderSharedState;
    diff --git a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkLongCounter.java b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkLongCounter.java
    index 98f806165af..3847bf716f3 100644
    --- a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkLongCounter.java
    +++ b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkLongCounter.java
    @@ -7,13 +7,13 @@
     
     import io.opentelemetry.api.common.AttributeKey;
     import io.opentelemetry.api.common.Attributes;
    +import io.opentelemetry.api.incubator.metrics.ExtendedLongCounterBuilder;
     import io.opentelemetry.api.metrics.DoubleCounterBuilder;
     import io.opentelemetry.api.metrics.LongCounter;
     import io.opentelemetry.api.metrics.LongCounterBuilder;
     import io.opentelemetry.api.metrics.ObservableLongCounter;
     import io.opentelemetry.api.metrics.ObservableLongMeasurement;
     import io.opentelemetry.context.Context;
    -import io.opentelemetry.extension.incubator.metrics.ExtendedLongCounterBuilder;
     import io.opentelemetry.sdk.internal.ThrottlingLogger;
     import io.opentelemetry.sdk.metrics.internal.descriptor.InstrumentDescriptor;
     import io.opentelemetry.sdk.metrics.internal.state.MeterProviderSharedState;
    diff --git a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkLongGauge.java b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkLongGauge.java
    index 73492eb9849..92d9e84d098 100644
    --- a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkLongGauge.java
    +++ b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkLongGauge.java
    @@ -7,12 +7,12 @@
     
     import io.opentelemetry.api.common.AttributeKey;
     import io.opentelemetry.api.common.Attributes;
    +import io.opentelemetry.api.incubator.metrics.ExtendedLongGaugeBuilder;
    +import io.opentelemetry.api.incubator.metrics.LongGauge;
     import io.opentelemetry.api.metrics.LongGaugeBuilder;
     import io.opentelemetry.api.metrics.ObservableLongGauge;
     import io.opentelemetry.api.metrics.ObservableLongMeasurement;
     import io.opentelemetry.context.Context;
    -import io.opentelemetry.extension.incubator.metrics.ExtendedLongGaugeBuilder;
    -import io.opentelemetry.extension.incubator.metrics.LongGauge;
     import io.opentelemetry.sdk.metrics.internal.descriptor.Advice;
     import io.opentelemetry.sdk.metrics.internal.descriptor.InstrumentDescriptor;
     import io.opentelemetry.sdk.metrics.internal.state.MeterProviderSharedState;
    diff --git a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkLongHistogram.java b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkLongHistogram.java
    index 38a7e52293e..b2975886565 100644
    --- a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkLongHistogram.java
    +++ b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkLongHistogram.java
    @@ -7,10 +7,10 @@
     
     import io.opentelemetry.api.common.AttributeKey;
     import io.opentelemetry.api.common.Attributes;
    +import io.opentelemetry.api.incubator.metrics.ExtendedLongHistogramBuilder;
     import io.opentelemetry.api.metrics.LongHistogram;
     import io.opentelemetry.api.metrics.LongHistogramBuilder;
     import io.opentelemetry.context.Context;
    -import io.opentelemetry.extension.incubator.metrics.ExtendedLongHistogramBuilder;
     import io.opentelemetry.sdk.internal.ThrottlingLogger;
     import io.opentelemetry.sdk.metrics.internal.aggregator.ExplicitBucketHistogramUtils;
     import io.opentelemetry.sdk.metrics.internal.descriptor.Advice;
    diff --git a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkLongUpDownCounter.java b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkLongUpDownCounter.java
    index 9c0aff76c43..4530f3b8405 100644
    --- a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkLongUpDownCounter.java
    +++ b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkLongUpDownCounter.java
    @@ -7,13 +7,13 @@
     
     import io.opentelemetry.api.common.AttributeKey;
     import io.opentelemetry.api.common.Attributes;
    +import io.opentelemetry.api.incubator.metrics.ExtendedLongUpDownCounterBuilder;
     import io.opentelemetry.api.metrics.DoubleUpDownCounterBuilder;
     import io.opentelemetry.api.metrics.LongUpDownCounter;
     import io.opentelemetry.api.metrics.LongUpDownCounterBuilder;
     import io.opentelemetry.api.metrics.ObservableLongMeasurement;
     import io.opentelemetry.api.metrics.ObservableLongUpDownCounter;
     import io.opentelemetry.context.Context;
    -import io.opentelemetry.extension.incubator.metrics.ExtendedLongUpDownCounterBuilder;
     import io.opentelemetry.sdk.metrics.internal.descriptor.InstrumentDescriptor;
     import io.opentelemetry.sdk.metrics.internal.state.MeterProviderSharedState;
     import io.opentelemetry.sdk.metrics.internal.state.MeterSharedState;
    diff --git a/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/AttributesAdviceTest.java b/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/AttributesAdviceTest.java
    index 0e673021556..af6a746da00 100644
    --- a/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/AttributesAdviceTest.java
    +++ b/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/AttributesAdviceTest.java
    @@ -14,6 +14,14 @@
     import com.google.common.util.concurrent.AtomicDouble;
     import io.opentelemetry.api.common.AttributeKey;
     import io.opentelemetry.api.common.Attributes;
    +import io.opentelemetry.api.incubator.metrics.ExtendedDoubleCounterBuilder;
    +import io.opentelemetry.api.incubator.metrics.ExtendedDoubleGaugeBuilder;
    +import io.opentelemetry.api.incubator.metrics.ExtendedDoubleHistogramBuilder;
    +import io.opentelemetry.api.incubator.metrics.ExtendedDoubleUpDownCounterBuilder;
    +import io.opentelemetry.api.incubator.metrics.ExtendedLongCounterBuilder;
    +import io.opentelemetry.api.incubator.metrics.ExtendedLongGaugeBuilder;
    +import io.opentelemetry.api.incubator.metrics.ExtendedLongHistogramBuilder;
    +import io.opentelemetry.api.incubator.metrics.ExtendedLongUpDownCounterBuilder;
     import io.opentelemetry.api.metrics.DoubleCounter;
     import io.opentelemetry.api.metrics.DoubleCounterBuilder;
     import io.opentelemetry.api.metrics.DoubleGaugeBuilder;
    @@ -28,14 +36,6 @@
     import io.opentelemetry.api.metrics.LongHistogramBuilder;
     import io.opentelemetry.api.metrics.LongUpDownCounter;
     import io.opentelemetry.api.metrics.LongUpDownCounterBuilder;
    -import io.opentelemetry.extension.incubator.metrics.ExtendedDoubleCounterBuilder;
    -import io.opentelemetry.extension.incubator.metrics.ExtendedDoubleGaugeBuilder;
    -import io.opentelemetry.extension.incubator.metrics.ExtendedDoubleHistogramBuilder;
    -import io.opentelemetry.extension.incubator.metrics.ExtendedDoubleUpDownCounterBuilder;
    -import io.opentelemetry.extension.incubator.metrics.ExtendedLongCounterBuilder;
    -import io.opentelemetry.extension.incubator.metrics.ExtendedLongGaugeBuilder;
    -import io.opentelemetry.extension.incubator.metrics.ExtendedLongHistogramBuilder;
    -import io.opentelemetry.extension.incubator.metrics.ExtendedLongUpDownCounterBuilder;
     import io.opentelemetry.sdk.testing.assertj.AbstractPointAssert;
     import io.opentelemetry.sdk.testing.assertj.DoublePointAssert;
     import io.opentelemetry.sdk.testing.assertj.HistogramPointAssert;
    diff --git a/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/IdentityTest.java b/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/IdentityTest.java
    index 7332e3d0dba..981d84dcd82 100644
    --- a/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/IdentityTest.java
    +++ b/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/IdentityTest.java
    @@ -8,7 +8,7 @@
     import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.assertThat;
     
     import io.github.netmikey.logunit.api.LogCapturer;
    -import io.opentelemetry.extension.incubator.metrics.ExtendedDoubleHistogramBuilder;
    +import io.opentelemetry.api.incubator.metrics.ExtendedDoubleHistogramBuilder;
     import io.opentelemetry.internal.testing.slf4j.SuppressLogger;
     import io.opentelemetry.sdk.common.InstrumentationScopeInfo;
     import io.opentelemetry.sdk.metrics.internal.state.MetricStorageRegistry;
    diff --git a/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/SdkDoubleGaugeTest.java b/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/SdkDoubleGaugeTest.java
    index cb13c2c9e95..802029d8448 100644
    --- a/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/SdkDoubleGaugeTest.java
    +++ b/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/SdkDoubleGaugeTest.java
    @@ -11,10 +11,10 @@
     import static org.assertj.core.api.Assertions.assertThatThrownBy;
     
     import io.opentelemetry.api.common.Attributes;
    +import io.opentelemetry.api.incubator.metrics.DoubleGauge;
    +import io.opentelemetry.api.incubator.metrics.ExtendedDoubleGaugeBuilder;
     import io.opentelemetry.api.metrics.Meter;
     import io.opentelemetry.api.metrics.ObservableDoubleGauge;
    -import io.opentelemetry.extension.incubator.metrics.DoubleGauge;
    -import io.opentelemetry.extension.incubator.metrics.ExtendedDoubleGaugeBuilder;
     import io.opentelemetry.internal.testing.slf4j.SuppressLogger;
     import io.opentelemetry.sdk.common.InstrumentationScopeInfo;
     import io.opentelemetry.sdk.metrics.internal.state.DefaultSynchronousMetricStorage;
    diff --git a/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/SdkLongGaugeTest.java b/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/SdkLongGaugeTest.java
    index dbe04000bef..e3bd54ab4d5 100644
    --- a/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/SdkLongGaugeTest.java
    +++ b/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/SdkLongGaugeTest.java
    @@ -11,10 +11,10 @@
     import static org.assertj.core.api.Assertions.assertThatThrownBy;
     
     import io.opentelemetry.api.common.Attributes;
    +import io.opentelemetry.api.incubator.metrics.ExtendedLongGaugeBuilder;
    +import io.opentelemetry.api.incubator.metrics.LongGauge;
     import io.opentelemetry.api.metrics.Meter;
     import io.opentelemetry.api.metrics.ObservableLongGauge;
    -import io.opentelemetry.extension.incubator.metrics.ExtendedLongGaugeBuilder;
    -import io.opentelemetry.extension.incubator.metrics.LongGauge;
     import io.opentelemetry.sdk.common.InstrumentationScopeInfo;
     import io.opentelemetry.sdk.resources.Resource;
     import io.opentelemetry.sdk.testing.exporter.InMemoryMetricReader;
    diff --git a/sdk/trace/build.gradle.kts b/sdk/trace/build.gradle.kts
    index 90c41b3b748..34690eaeeca 100644
    --- a/sdk/trace/build.gradle.kts
    +++ b/sdk/trace/build.gradle.kts
    @@ -22,7 +22,7 @@ dependencies {
       api(project(":api:all"))
       api(project(":sdk:common"))
     
    -  implementation(project(":extensions:incubator"))
    +  implementation(project(":api:incubator"))
     
       compileOnly(project(":sdk:trace-shaded-deps"))
     
    diff --git a/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/SdkSpan.java b/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/SdkSpan.java
    index a6b28043d29..71cd2dccd67 100644
    --- a/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/SdkSpan.java
    +++ b/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/SdkSpan.java
    @@ -7,13 +7,13 @@
     
     import io.opentelemetry.api.common.AttributeKey;
     import io.opentelemetry.api.common.Attributes;
    +import io.opentelemetry.api.incubator.trace.ExtendedSpan;
     import io.opentelemetry.api.internal.GuardedBy;
     import io.opentelemetry.api.trace.Span;
     import io.opentelemetry.api.trace.SpanContext;
     import io.opentelemetry.api.trace.SpanKind;
     import io.opentelemetry.api.trace.StatusCode;
     import io.opentelemetry.context.Context;
    -import io.opentelemetry.extension.incubator.trace.ExtendedSpan;
     import io.opentelemetry.sdk.common.Clock;
     import io.opentelemetry.sdk.common.InstrumentationScopeInfo;
     import io.opentelemetry.sdk.internal.AttributeUtil;
    diff --git a/sdk/trace/src/test/java/io/opentelemetry/sdk/trace/SdkSpanTest.java b/sdk/trace/src/test/java/io/opentelemetry/sdk/trace/SdkSpanTest.java
    index df7a6ba1c02..95778058465 100644
    --- a/sdk/trace/src/test/java/io/opentelemetry/sdk/trace/SdkSpanTest.java
    +++ b/sdk/trace/src/test/java/io/opentelemetry/sdk/trace/SdkSpanTest.java
    @@ -25,6 +25,7 @@
     import io.opentelemetry.api.common.AttributeKey;
     import io.opentelemetry.api.common.Attributes;
     import io.opentelemetry.api.common.AttributesBuilder;
    +import io.opentelemetry.api.incubator.trace.ExtendedSpan;
     import io.opentelemetry.api.trace.Span;
     import io.opentelemetry.api.trace.SpanContext;
     import io.opentelemetry.api.trace.SpanId;
    @@ -33,7 +34,6 @@
     import io.opentelemetry.api.trace.TraceFlags;
     import io.opentelemetry.api.trace.TraceState;
     import io.opentelemetry.context.Context;
    -import io.opentelemetry.extension.incubator.trace.ExtendedSpan;
     import io.opentelemetry.sdk.common.InstrumentationScopeInfo;
     import io.opentelemetry.sdk.internal.AttributesMap;
     import io.opentelemetry.sdk.internal.InstrumentationScopeUtil;
    diff --git a/settings.gradle.kts b/settings.gradle.kts
    index 2cdbc1038b1..9bba75b336b 100644
    --- a/settings.gradle.kts
    +++ b/settings.gradle.kts
    @@ -24,12 +24,11 @@ dependencyResolutionManagement {
     rootProject.name = "opentelemetry-java"
     include(":all")
     include(":api:all")
    -include(":api:events")
    +include(":api:incubator")
     include(":bom")
     include(":bom-alpha")
     include(":context")
     include(":dependencyManagement")
    -include(":extensions:incubator")
     include(":extensions:kotlin")
     include(":extensions:trace-propagators")
     include(":exporters:common")
    
    From d8f26b221e35cb529ff48e8fd54c8bd35fd57d9f Mon Sep 17 00:00:00 2001
    From: Bogdan Drutu 
    Date: Thu, 21 Mar 2024 13:32:37 -0700
    Subject: [PATCH 304/901] Check for Java 17 toolchain and fail if not found
     (#6303)
    
    Signed-off-by: Bogdan Drutu 
    Co-authored-by: Jack Berg 
    ---
     buildSrc/build.gradle.kts | 18 +++++++++++++-----
     1 file changed, 13 insertions(+), 5 deletions(-)
    
    diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts
    index ee5f847b496..04d34f71bbc 100644
    --- a/buildSrc/build.gradle.kts
    +++ b/buildSrc/build.gradle.kts
    @@ -5,15 +5,23 @@ plugins {
       id("com.diffplug.spotless") version "6.25.0"
     }
     
    -if (!JavaVersion.current().isCompatibleWith(JavaVersion.VERSION_17)) {
    +if (!hasLauncherForJavaVersion(17)) {
       throw GradleException(
    -    "JDK 17 or higher is required to build. " +
    -      "One option is to download it from https://adoptium.net/. If you believe you already " +
    -      "have it, please check that the JAVA_HOME environment variable is pointing at the " +
    -      "JDK 17 installation.",
    +    "JDK 17 is required to build and gradle was unable to detect it on the system.  " +
    +        "Please install it and see https://docs.gradle.org/current/userguide/toolchains.html#sec:auto_detection " +
    +        "for details on how gradle detects java toolchains."
       )
     }
     
    +fun hasLauncherForJavaVersion(version: Int): Boolean {
    +  return try {
    +    javaToolchains.launcherFor { languageVersion = JavaLanguageVersion.of(version) }.get()
    +    true
    +  } catch (e: Exception) {
    +    false
    +  }
    +}
    +
     spotless {
       kotlinGradle {
         ktlint().editorConfigOverride(mapOf(
    
    From 434609a7bc84564504f32da2b84f0720f281422f Mon Sep 17 00:00:00 2001
    From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com>
    Date: Thu, 21 Mar 2024 15:32:51 -0500
    Subject: [PATCH 305/901] Update errorProneVersion to v2.26.1 (#6288)
    
    Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
    ---
     dependencyManagement/build.gradle.kts | 2 +-
     1 file changed, 1 insertion(+), 1 deletion(-)
    
    diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts
    index 6a5a19426e1..fbbff0fdffc 100644
    --- a/dependencyManagement/build.gradle.kts
    +++ b/dependencyManagement/build.gradle.kts
    @@ -25,7 +25,7 @@ val DEPENDENCY_BOMS = listOf(
     )
     
     val autoValueVersion = "1.10.4"
    -val errorProneVersion = "2.26.0"
    +val errorProneVersion = "2.26.1"
     val jmhVersion = "1.37"
     // Mockito 5.x.x requires Java 11 https://github.com/mockito/mockito/releases/tag/v5.0.0
     val mockitoVersion = "4.11.0"
    
    From b897510bb993899fa00c4d7e537c158459ea3d6e Mon Sep 17 00:00:00 2001
    From: jack-berg <34418638+jack-berg@users.noreply.github.com>
    Date: Fri, 22 Mar 2024 10:38:30 -0500
    Subject: [PATCH 306/901] Add get{Signal}Exporter methods to
     Simple{Signal}Processor, Batch{Signal}Processor (#6078)
    
    ---
     .../apidiffs/current_vs_latest/opentelemetry-sdk-logs.txt | 7 ++++++-
     .../current_vs_latest/opentelemetry-sdk-trace.txt         | 7 ++++++-
     .../sdk/logs/export/BatchLogRecordProcessor.java          | 5 +++++
     .../sdk/logs/export/SimpleLogRecordProcessor.java         | 5 +++++
     .../sdk/logs/export/BatchLogRecordProcessorTest.java      | 8 ++++++++
     .../sdk/logs/export/SimpleLogRecordProcessorTest.java     | 8 ++++++++
     .../sdk/trace/export/BatchSpanProcessor.java              | 5 +++++
     .../sdk/trace/export/SimpleSpanProcessor.java             | 5 +++++
     .../sdk/trace/export/BatchSpanProcessorTest.java          | 6 ++++++
     .../sdk/trace/export/SimpleSpanProcessorTest.java         | 6 ++++++
     10 files changed, 60 insertions(+), 2 deletions(-)
    
    diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-logs.txt b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-logs.txt
    index df26146497b..2039c1c6e68 100644
    --- a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-logs.txt
    +++ b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-logs.txt
    @@ -1,2 +1,7 @@
     Comparing source compatibility of  against 
    -No changes.
    \ No newline at end of file
    +***  MODIFIED CLASS: PUBLIC FINAL io.opentelemetry.sdk.logs.export.BatchLogRecordProcessor  (not serializable)
    +	===  CLASS FILE FORMAT VERSION: 52.0 <- 52.0
    +	+++  NEW METHOD: PUBLIC(+) io.opentelemetry.sdk.logs.export.LogRecordExporter getLogRecordExporter()
    +***  MODIFIED CLASS: PUBLIC FINAL io.opentelemetry.sdk.logs.export.SimpleLogRecordProcessor  (not serializable)
    +	===  CLASS FILE FORMAT VERSION: 52.0 <- 52.0
    +	+++  NEW METHOD: PUBLIC(+) io.opentelemetry.sdk.logs.export.LogRecordExporter getLogRecordExporter()
    diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-trace.txt b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-trace.txt
    index df26146497b..52678bd9ba6 100644
    --- a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-trace.txt
    +++ b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-trace.txt
    @@ -1,2 +1,7 @@
     Comparing source compatibility of  against 
    -No changes.
    \ No newline at end of file
    +***  MODIFIED CLASS: PUBLIC FINAL io.opentelemetry.sdk.trace.export.BatchSpanProcessor  (not serializable)
    +	===  CLASS FILE FORMAT VERSION: 52.0 <- 52.0
    +	+++  NEW METHOD: PUBLIC(+) io.opentelemetry.sdk.trace.export.SpanExporter getSpanExporter()
    +***  MODIFIED CLASS: PUBLIC FINAL io.opentelemetry.sdk.trace.export.SimpleSpanProcessor  (not serializable)
    +	===  CLASS FILE FORMAT VERSION: 52.0 <- 52.0
    +	+++  NEW METHOD: PUBLIC(+) io.opentelemetry.sdk.trace.export.SpanExporter getSpanExporter()
    diff --git a/sdk/logs/src/main/java/io/opentelemetry/sdk/logs/export/BatchLogRecordProcessor.java b/sdk/logs/src/main/java/io/opentelemetry/sdk/logs/export/BatchLogRecordProcessor.java
    index 1c8833fcaf8..8de51235128 100644
    --- a/sdk/logs/src/main/java/io/opentelemetry/sdk/logs/export/BatchLogRecordProcessor.java
    +++ b/sdk/logs/src/main/java/io/opentelemetry/sdk/logs/export/BatchLogRecordProcessor.java
    @@ -105,6 +105,11 @@ public CompletableResultCode forceFlush() {
         return worker.forceFlush();
       }
     
    +  /** Return the processor's configured {@link LogRecordExporter}. */
    +  public LogRecordExporter getLogRecordExporter() {
    +    return worker.logRecordExporter;
    +  }
    +
       // Visible for testing
       List getBatch() {
         return worker.batch;
    diff --git a/sdk/logs/src/main/java/io/opentelemetry/sdk/logs/export/SimpleLogRecordProcessor.java b/sdk/logs/src/main/java/io/opentelemetry/sdk/logs/export/SimpleLogRecordProcessor.java
    index 9b5c4791ef4..c97eaae8c30 100644
    --- a/sdk/logs/src/main/java/io/opentelemetry/sdk/logs/export/SimpleLogRecordProcessor.java
    +++ b/sdk/logs/src/main/java/io/opentelemetry/sdk/logs/export/SimpleLogRecordProcessor.java
    @@ -107,6 +107,11 @@ public CompletableResultCode forceFlush() {
         return CompletableResultCode.ofAll(pendingExports);
       }
     
    +  /** Return the processor's configured {@link LogRecordExporter}. */
    +  public LogRecordExporter getLogRecordExporter() {
    +    return logRecordExporter;
    +  }
    +
       @Override
       public String toString() {
         return "SimpleLogRecordProcessor{" + "logRecordExporter=" + logRecordExporter + '}';
    diff --git a/sdk/logs/src/test/java/io/opentelemetry/sdk/logs/export/BatchLogRecordProcessorTest.java b/sdk/logs/src/test/java/io/opentelemetry/sdk/logs/export/BatchLogRecordProcessorTest.java
    index 9dcf07261bb..4c17a1768f7 100644
    --- a/sdk/logs/src/test/java/io/opentelemetry/sdk/logs/export/BatchLogRecordProcessorTest.java
    +++ b/sdk/logs/src/test/java/io/opentelemetry/sdk/logs/export/BatchLogRecordProcessorTest.java
    @@ -6,6 +6,7 @@
     package io.opentelemetry.sdk.logs.export;
     
     import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.assertThat;
    +import static org.assertj.core.api.Assertions.assertThat;
     import static org.assertj.core.api.Assertions.assertThatThrownBy;
     import static org.assertj.core.api.AssertionsForClassTypes.assertThatCode;
     import static org.awaitility.Awaitility.await;
    @@ -417,6 +418,13 @@ void shutdownPropagatesFailure() {
         assertThat(result.isSuccess()).isFalse();
       }
     
    +  @Test
    +  void getLogRecordExporter() {
    +    assertThat(
    +            BatchLogRecordProcessor.builder(mockLogRecordExporter).build().getLogRecordExporter())
    +        .isSameAs(mockLogRecordExporter);
    +  }
    +
       @Test
       void toString_Valid() {
         when(mockLogRecordExporter.toString()).thenReturn("MockLogRecordExporter");
    diff --git a/sdk/logs/src/test/java/io/opentelemetry/sdk/logs/export/SimpleLogRecordProcessorTest.java b/sdk/logs/src/test/java/io/opentelemetry/sdk/logs/export/SimpleLogRecordProcessorTest.java
    index bace5bdbaf6..e50f6624920 100644
    --- a/sdk/logs/src/test/java/io/opentelemetry/sdk/logs/export/SimpleLogRecordProcessorTest.java
    +++ b/sdk/logs/src/test/java/io/opentelemetry/sdk/logs/export/SimpleLogRecordProcessorTest.java
    @@ -120,6 +120,14 @@ void shutdown() {
         verify(logRecordExporter).shutdown();
       }
     
    +  @Test
    +  void getLogRecordExporter() {
    +    assertThat(
    +            ((SimpleLogRecordProcessor) SimpleLogRecordProcessor.create(logRecordExporter))
    +                .getLogRecordExporter())
    +        .isSameAs(logRecordExporter);
    +  }
    +
       @Test
       void toString_Valid() {
         when(logRecordExporter.toString()).thenReturn("MockLogRecordExporter");
    diff --git a/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/export/BatchSpanProcessor.java b/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/export/BatchSpanProcessor.java
    index da0cf7d080c..ae487600e81 100644
    --- a/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/export/BatchSpanProcessor.java
    +++ b/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/export/BatchSpanProcessor.java
    @@ -122,6 +122,11 @@ public CompletableResultCode forceFlush() {
         return worker.forceFlush();
       }
     
    +  /** Return the processor's configured {@link SpanExporter}. */
    +  public SpanExporter getSpanExporter() {
    +    return worker.spanExporter;
    +  }
    +
       // Visible for testing
       List getBatch() {
         return worker.batch;
    diff --git a/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/export/SimpleSpanProcessor.java b/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/export/SimpleSpanProcessor.java
    index 432d7d056a0..c37afd72411 100644
    --- a/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/export/SimpleSpanProcessor.java
    +++ b/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/export/SimpleSpanProcessor.java
    @@ -135,6 +135,11 @@ public CompletableResultCode forceFlush() {
         return CompletableResultCode.ofAll(pendingExports);
       }
     
    +  /** Return the processor's configured {@link SpanExporter}. */
    +  public SpanExporter getSpanExporter() {
    +    return spanExporter;
    +  }
    +
       @Override
       public String toString() {
         return "SimpleSpanProcessor{"
    diff --git a/sdk/trace/src/test/java/io/opentelemetry/sdk/trace/export/BatchSpanProcessorTest.java b/sdk/trace/src/test/java/io/opentelemetry/sdk/trace/export/BatchSpanProcessorTest.java
    index b774d7fae04..d9f48ecab17 100644
    --- a/sdk/trace/src/test/java/io/opentelemetry/sdk/trace/export/BatchSpanProcessorTest.java
    +++ b/sdk/trace/src/test/java/io/opentelemetry/sdk/trace/export/BatchSpanProcessorTest.java
    @@ -592,6 +592,12 @@ void shutdownPropagatesFailure() {
         assertThat(result.isSuccess()).isFalse();
       }
     
    +  @Test
    +  void getSpanExporter() {
    +    assertThat(BatchSpanProcessor.builder(mockSpanExporter).build().getSpanExporter())
    +        .isSameAs(mockSpanExporter);
    +  }
    +
       @Test
       void stringRepresentation() {
         BatchSpanProcessor processor = BatchSpanProcessor.builder(mockSpanExporter).build();
    diff --git a/sdk/trace/src/test/java/io/opentelemetry/sdk/trace/export/SimpleSpanProcessorTest.java b/sdk/trace/src/test/java/io/opentelemetry/sdk/trace/export/SimpleSpanProcessorTest.java
    index 9bcd195bb11..62b1d59a84f 100644
    --- a/sdk/trace/src/test/java/io/opentelemetry/sdk/trace/export/SimpleSpanProcessorTest.java
    +++ b/sdk/trace/src/test/java/io/opentelemetry/sdk/trace/export/SimpleSpanProcessorTest.java
    @@ -275,4 +275,10 @@ void close() {
         simpleSampledSpansProcessor.close();
         verify(spanExporter).shutdown();
       }
    +
    +  @Test
    +  void getSpanExporter() {
    +    assertThat(((SimpleSpanProcessor) SimpleSpanProcessor.create(spanExporter)).getSpanExporter())
    +        .isSameAs(spanExporter);
    +  }
     }
    
    From 13ea3346a9f1062fd3cc3963602911aca546e1d1 Mon Sep 17 00:00:00 2001
    From: jack-berg <34418638+jack-berg@users.noreply.github.com>
    Date: Tue, 26 Mar 2024 09:31:47 -0500
    Subject: [PATCH 307/901] Rename EventEmitter and related classes to
     EventLogger (#6316)
    
    ---
     .../events/DefaultEventEmitterProvider.java   | 42 -------------
     ...ntEmitter.java => DefaultEventLogger.java} |  8 +--
     .../events/DefaultEventLoggerProvider.java    | 41 +++++++++++++
     .../api/incubator/events/EventEmitter.java    | 52 ----------------
     .../incubator/events/EventEmitterBuilder.java | 41 -------------
     .../api/incubator/events/EventLogger.java     | 58 ++++++++++++++++++
     .../incubator/events/EventLoggerBuilder.java  | 41 +++++++++++++
     ...Provider.java => EventLoggerProvider.java} | 23 ++++---
     .../events/GlobalEventEmitterProvider.java    | 60 -------------------
     .../events/GlobalEventLoggerProvider.java     | 60 +++++++++++++++++++
     ...va => DefaultEventLoggerProviderTest.java} | 12 ++--
     ...rTest.java => DefaultEventLoggerTest.java} | 10 ++--
     .../GlobalEventEmitterProviderTest.java       | 51 ----------------
     .../events/GlobalEventLoggerProviderTest.java | 51 ++++++++++++++++
     .../OtlpExporterIntegrationTest.java          | 14 ++---
     ...AutoConfiguredOpenTelemetrySdkBuilder.java |  8 +--
     .../AutoConfiguredOpenTelemetrySdkTest.java   | 12 ++--
     .../AutoConfiguredOpenTelemetrySdkTest.java   |  4 +-
     .../autoconfigure/FileConfigurationTest.java  | 12 ++--
     .../sdk/autoconfigure/FullConfigTest.java     | 13 ++--
     .../sdk/logs/internal/SdkEventBuilder.java    |  2 +-
     ...vider.java => SdkEventLoggerProvider.java} | 48 +++++++--------
     ...t.java => SdkEventLoggerProviderTest.java} | 16 ++---
     23 files changed, 341 insertions(+), 338 deletions(-)
     delete mode 100644 api/incubator/src/main/java/io/opentelemetry/api/incubator/events/DefaultEventEmitterProvider.java
     rename api/incubator/src/main/java/io/opentelemetry/api/incubator/events/{DefaultEventEmitter.java => DefaultEventLogger.java} (81%)
     create mode 100644 api/incubator/src/main/java/io/opentelemetry/api/incubator/events/DefaultEventLoggerProvider.java
     delete mode 100644 api/incubator/src/main/java/io/opentelemetry/api/incubator/events/EventEmitter.java
     delete mode 100644 api/incubator/src/main/java/io/opentelemetry/api/incubator/events/EventEmitterBuilder.java
     create mode 100644 api/incubator/src/main/java/io/opentelemetry/api/incubator/events/EventLogger.java
     create mode 100644 api/incubator/src/main/java/io/opentelemetry/api/incubator/events/EventLoggerBuilder.java
     rename api/incubator/src/main/java/io/opentelemetry/api/incubator/events/{EventEmitterProvider.java => EventLoggerProvider.java} (52%)
     delete mode 100644 api/incubator/src/main/java/io/opentelemetry/api/incubator/events/GlobalEventEmitterProvider.java
     create mode 100644 api/incubator/src/main/java/io/opentelemetry/api/incubator/events/GlobalEventLoggerProvider.java
     rename api/incubator/src/test/java/io/opentelemetry/api/incubator/events/{DefaultEventEmitterProviderTest.java => DefaultEventLoggerProviderTest.java} (71%)
     rename api/incubator/src/test/java/io/opentelemetry/api/incubator/events/{DefaultEventEmitterTest.java => DefaultEventLoggerTest.java} (79%)
     delete mode 100644 api/incubator/src/test/java/io/opentelemetry/api/incubator/events/GlobalEventEmitterProviderTest.java
     create mode 100644 api/incubator/src/test/java/io/opentelemetry/api/incubator/events/GlobalEventLoggerProviderTest.java
     rename sdk/logs/src/main/java/io/opentelemetry/sdk/logs/internal/{SdkEventEmitterProvider.java => SdkEventLoggerProvider.java} (58%)
     rename sdk/logs/src/test/java/io/opentelemetry/sdk/logs/internal/{SdkEventEmitterProviderTest.java => SdkEventLoggerProviderTest.java} (84%)
    
    diff --git a/api/incubator/src/main/java/io/opentelemetry/api/incubator/events/DefaultEventEmitterProvider.java b/api/incubator/src/main/java/io/opentelemetry/api/incubator/events/DefaultEventEmitterProvider.java
    deleted file mode 100644
    index e69a9a3745f..00000000000
    --- a/api/incubator/src/main/java/io/opentelemetry/api/incubator/events/DefaultEventEmitterProvider.java
    +++ /dev/null
    @@ -1,42 +0,0 @@
    -/*
    - * Copyright The OpenTelemetry Authors
    - * SPDX-License-Identifier: Apache-2.0
    - */
    -
    -package io.opentelemetry.api.incubator.events;
    -
    -class DefaultEventEmitterProvider implements EventEmitterProvider {
    -
    -  private static final EventEmitterProvider INSTANCE = new DefaultEventEmitterProvider();
    -  private static final EventEmitterBuilder NOOP_EVENT_EMITTER_BUILDER =
    -      new NoopEventEmitterBuilder();
    -
    -  private DefaultEventEmitterProvider() {}
    -
    -  static EventEmitterProvider getInstance() {
    -    return INSTANCE;
    -  }
    -
    -  @Override
    -  public EventEmitterBuilder eventEmitterBuilder(String instrumentationScopeName) {
    -    return NOOP_EVENT_EMITTER_BUILDER;
    -  }
    -
    -  private static class NoopEventEmitterBuilder implements EventEmitterBuilder {
    -
    -    @Override
    -    public EventEmitterBuilder setSchemaUrl(String schemaUrl) {
    -      return this;
    -    }
    -
    -    @Override
    -    public EventEmitterBuilder setInstrumentationVersion(String instrumentationVersion) {
    -      return this;
    -    }
    -
    -    @Override
    -    public EventEmitter build() {
    -      return DefaultEventEmitter.getInstance();
    -    }
    -  }
    -}
    diff --git a/api/incubator/src/main/java/io/opentelemetry/api/incubator/events/DefaultEventEmitter.java b/api/incubator/src/main/java/io/opentelemetry/api/incubator/events/DefaultEventLogger.java
    similarity index 81%
    rename from api/incubator/src/main/java/io/opentelemetry/api/incubator/events/DefaultEventEmitter.java
    rename to api/incubator/src/main/java/io/opentelemetry/api/incubator/events/DefaultEventLogger.java
    index 1c914a74d9d..9a9450b009c 100644
    --- a/api/incubator/src/main/java/io/opentelemetry/api/incubator/events/DefaultEventEmitter.java
    +++ b/api/incubator/src/main/java/io/opentelemetry/api/incubator/events/DefaultEventLogger.java
    @@ -9,13 +9,13 @@
     import java.time.Instant;
     import java.util.concurrent.TimeUnit;
     
    -class DefaultEventEmitter implements EventEmitter {
    +class DefaultEventLogger implements EventLogger {
     
    -  private static final EventEmitter INSTANCE = new DefaultEventEmitter();
    +  private static final EventLogger INSTANCE = new DefaultEventLogger();
     
    -  private DefaultEventEmitter() {}
    +  private DefaultEventLogger() {}
     
    -  static EventEmitter getInstance() {
    +  static EventLogger getInstance() {
         return INSTANCE;
       }
     
    diff --git a/api/incubator/src/main/java/io/opentelemetry/api/incubator/events/DefaultEventLoggerProvider.java b/api/incubator/src/main/java/io/opentelemetry/api/incubator/events/DefaultEventLoggerProvider.java
    new file mode 100644
    index 00000000000..d365e2bbd4d
    --- /dev/null
    +++ b/api/incubator/src/main/java/io/opentelemetry/api/incubator/events/DefaultEventLoggerProvider.java
    @@ -0,0 +1,41 @@
    +/*
    + * Copyright The OpenTelemetry Authors
    + * SPDX-License-Identifier: Apache-2.0
    + */
    +
    +package io.opentelemetry.api.incubator.events;
    +
    +class DefaultEventLoggerProvider implements EventLoggerProvider {
    +
    +  private static final EventLoggerProvider INSTANCE = new DefaultEventLoggerProvider();
    +  private static final EventLoggerBuilder NOOP_EVENT_LOGGER_BUILDER = new NoopEventLoggerBuilder();
    +
    +  private DefaultEventLoggerProvider() {}
    +
    +  static EventLoggerProvider getInstance() {
    +    return INSTANCE;
    +  }
    +
    +  @Override
    +  public EventLoggerBuilder eventLoggerBuilder(String instrumentationScopeName) {
    +    return NOOP_EVENT_LOGGER_BUILDER;
    +  }
    +
    +  private static class NoopEventLoggerBuilder implements EventLoggerBuilder {
    +
    +    @Override
    +    public EventLoggerBuilder setSchemaUrl(String schemaUrl) {
    +      return this;
    +    }
    +
    +    @Override
    +    public EventLoggerBuilder setInstrumentationVersion(String instrumentationVersion) {
    +      return this;
    +    }
    +
    +    @Override
    +    public EventLogger build() {
    +      return DefaultEventLogger.getInstance();
    +    }
    +  }
    +}
    diff --git a/api/incubator/src/main/java/io/opentelemetry/api/incubator/events/EventEmitter.java b/api/incubator/src/main/java/io/opentelemetry/api/incubator/events/EventEmitter.java
    deleted file mode 100644
    index ba588f7ec79..00000000000
    --- a/api/incubator/src/main/java/io/opentelemetry/api/incubator/events/EventEmitter.java
    +++ /dev/null
    @@ -1,52 +0,0 @@
    -/*
    - * Copyright The OpenTelemetry Authors
    - * SPDX-License-Identifier: Apache-2.0
    - */
    -
    -package io.opentelemetry.api.incubator.events;
    -
    -import io.opentelemetry.api.common.Attributes;
    -import javax.annotation.concurrent.ThreadSafe;
    -
    -/**
    - * A {@link EventEmitter} is the entry point into an event pipeline.
    - *
    - * 

    Example usage emitting events: - * - *

    {@code
    - * class MyClass {
    - *   private final EventEmitter eventEmitter = openTelemetryEventEmitterProvider
    - *         .eventEmitterBuilder("scope-name")
    - *         .build();
    - *
    - *   void doWork() {
    - *     eventEmitter.emit("my-event", Attributes.builder()
    - *         .put("key1", "value1")
    - *         .put("key2", "value2")
    - *         .build())
    - *     // do work
    - *   }
    - * }
    - * }
    - */ -@ThreadSafe -public interface EventEmitter { - - /** - * Emit an event. - * - * @param eventName the event name, which acts as a classifier for events. Within a particular - * event domain, event name defines a particular class or type of event. - * @param attributes attributes associated with the event - */ - void emit(String eventName, Attributes attributes); - - /** - * Return a {@link EventBuilder} to emit an event. - * - * @param eventName the event name, which acts as a classifier for events. Within a particular - * event domain, event name defines a particular class or type of event. - * @param attributes attributes associated with the event - */ - EventBuilder builder(String eventName, Attributes attributes); -} diff --git a/api/incubator/src/main/java/io/opentelemetry/api/incubator/events/EventEmitterBuilder.java b/api/incubator/src/main/java/io/opentelemetry/api/incubator/events/EventEmitterBuilder.java deleted file mode 100644 index 5fa04658652..00000000000 --- a/api/incubator/src/main/java/io/opentelemetry/api/incubator/events/EventEmitterBuilder.java +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package io.opentelemetry.api.incubator.events; - -/** - * Builder class for creating {@link EventEmitter} instances. - * - *

    {@link EventEmitter}s are identified by their scope name, version, and schema URL. These - * identifying fields, along with attributes, combine to form the instrumentation scope, which is - * attached to all events produced by the {@link EventEmitter}. - */ -public interface EventEmitterBuilder { - - /** - * Set the scope schema URL of the resulting {@link EventEmitter}. Schema URL is part of {@link - * EventEmitter} identity. - * - * @param schemaUrl The schema URL. - * @return this - */ - EventEmitterBuilder setSchemaUrl(String schemaUrl); - - /** - * Sets the instrumentation scope version of the resulting {@link EventEmitter}. Version is part - * of {@link EventEmitter} identity. - * - * @param instrumentationScopeVersion The instrumentation scope version. - * @return this - */ - EventEmitterBuilder setInstrumentationVersion(String instrumentationScopeVersion); - - /** - * Gets or creates a {@link EventEmitter} instance. - * - * @return a {@link EventEmitter} instance configured with the provided options. - */ - EventEmitter build(); -} diff --git a/api/incubator/src/main/java/io/opentelemetry/api/incubator/events/EventLogger.java b/api/incubator/src/main/java/io/opentelemetry/api/incubator/events/EventLogger.java new file mode 100644 index 00000000000..785d8e000ca --- /dev/null +++ b/api/incubator/src/main/java/io/opentelemetry/api/incubator/events/EventLogger.java @@ -0,0 +1,58 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.api.incubator.events; + +import io.opentelemetry.api.common.Attributes; +import javax.annotation.concurrent.ThreadSafe; + +/** + * A {@link EventLogger} is the entry point into an event pipeline. + * + *

    Example usage emitting events: + * + *

    {@code
    + * class MyClass {
    + *   private final EventLogger eventLogger = eventLoggerProvider
    + *         .eventLoggerBuilder("scope-name")
    + *         .build();
    + *
    + *   void doWork() {
    + *     eventLogger.emit("my-namespace.my-event", Attributes.builder()
    + *         .put("key1", "value1")
    + *         .put("key2", "value2")
    + *         .build())
    + *     // do work
    + *   }
    + * }
    + * }
    + */ +@ThreadSafe +public interface EventLogger { + + /** + * Emit an event. + * + * @param eventName the event name, which identifies the class or type of event. Event with the + * same name are structurally similar to one another. Event names are subject to the same + * naming rules as attribute names. Notably, they are namespaced to avoid collisions. See event.name semantic + * conventions for more details. + * @param attributes attributes associated with the event + */ + void emit(String eventName, Attributes attributes); + + /** + * Return a {@link EventBuilder} to emit an event. + * + * @param eventName the event name, which identifies the class or type of event. Event with the + * same name are structurally similar to one another. Event names are subject to the same + * naming rules as attribute names. Notably, they are namespaced to avoid collisions. See event.name semantic + * conventions for more details. + * @param attributes attributes associated with the event + */ + EventBuilder builder(String eventName, Attributes attributes); +} diff --git a/api/incubator/src/main/java/io/opentelemetry/api/incubator/events/EventLoggerBuilder.java b/api/incubator/src/main/java/io/opentelemetry/api/incubator/events/EventLoggerBuilder.java new file mode 100644 index 00000000000..d3105cac6c7 --- /dev/null +++ b/api/incubator/src/main/java/io/opentelemetry/api/incubator/events/EventLoggerBuilder.java @@ -0,0 +1,41 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.api.incubator.events; + +/** + * Builder class for creating {@link EventLogger} instances. + * + *

    {@link EventLogger}s are identified by their scope name, version, and schema URL. These + * identifying fields, along with attributes, combine to form the instrumentation scope, which is + * attached to all events produced by the {@link EventLogger}. + */ +public interface EventLoggerBuilder { + + /** + * Set the scope schema URL of the resulting {@link EventLogger}. Schema URL is part of {@link + * EventLogger} identity. + * + * @param schemaUrl The schema URL. + * @return this + */ + EventLoggerBuilder setSchemaUrl(String schemaUrl); + + /** + * Sets the instrumentation scope version of the resulting {@link EventLogger}. Version is part of + * {@link EventLogger} identity. + * + * @param instrumentationScopeVersion The instrumentation scope version. + * @return this + */ + EventLoggerBuilder setInstrumentationVersion(String instrumentationScopeVersion); + + /** + * Gets or creates a {@link EventLogger} instance. + * + * @return a {@link EventLogger} instance configured with the provided options. + */ + EventLogger build(); +} diff --git a/api/incubator/src/main/java/io/opentelemetry/api/incubator/events/EventEmitterProvider.java b/api/incubator/src/main/java/io/opentelemetry/api/incubator/events/EventLoggerProvider.java similarity index 52% rename from api/incubator/src/main/java/io/opentelemetry/api/incubator/events/EventEmitterProvider.java rename to api/incubator/src/main/java/io/opentelemetry/api/incubator/events/EventLoggerProvider.java index d5eb035e3f8..cfef2a0622d 100644 --- a/api/incubator/src/main/java/io/opentelemetry/api/incubator/events/EventEmitterProvider.java +++ b/api/incubator/src/main/java/io/opentelemetry/api/incubator/events/EventLoggerProvider.java @@ -8,39 +8,38 @@ import javax.annotation.concurrent.ThreadSafe; /** - * A registry for creating scoped {@link EventEmitter}s. The name Provider is for consistency + * A registry for creating scoped {@link EventLogger}s. The name Provider is for consistency * with other languages and it is NOT loaded using reflection. * - * @see EventEmitter + * @see EventLogger */ @ThreadSafe -public interface EventEmitterProvider { +public interface EventLoggerProvider { /** - * Gets or creates a named EventEmitter instance which emits events to the {@code eventDomain}. + * Gets or creates a named {@link EventLogger} instance. * * @param instrumentationScopeName A name uniquely identifying the instrumentation scope, such as * the instrumentation library, package, or fully qualified class name. Must not be null. * @return a Logger instance. */ - default EventEmitter get(String instrumentationScopeName) { - return eventEmitterBuilder(instrumentationScopeName).build(); + default EventLogger get(String instrumentationScopeName) { + return eventLoggerBuilder(instrumentationScopeName).build(); } /** - * Creates a LoggerBuilder for a named EventEmitter instance. + * Creates a LoggerBuilder for a named {@link EventLogger} instance. * * @param instrumentationScopeName A name uniquely identifying the instrumentation scope, such as * the instrumentation library, package, or fully qualified class name. Must not be null. * @return a LoggerBuilder instance. */ - EventEmitterBuilder eventEmitterBuilder(String instrumentationScopeName); + EventLoggerBuilder eventLoggerBuilder(String instrumentationScopeName); /** - * Returns a no-op {@link EventEmitterProvider} which provides Loggers which do not record or - * emit. + * Returns a no-op {@link EventLoggerProvider} which provides Loggers which do not record or emit. */ - static EventEmitterProvider noop() { - return DefaultEventEmitterProvider.getInstance(); + static EventLoggerProvider noop() { + return DefaultEventLoggerProvider.getInstance(); } } diff --git a/api/incubator/src/main/java/io/opentelemetry/api/incubator/events/GlobalEventEmitterProvider.java b/api/incubator/src/main/java/io/opentelemetry/api/incubator/events/GlobalEventEmitterProvider.java deleted file mode 100644 index bf0e8353d52..00000000000 --- a/api/incubator/src/main/java/io/opentelemetry/api/incubator/events/GlobalEventEmitterProvider.java +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package io.opentelemetry.api.incubator.events; - -import io.opentelemetry.api.GlobalOpenTelemetry; -import java.util.concurrent.atomic.AtomicReference; -import javax.annotation.Nullable; - -/** - * This class provides a temporary global accessor for {@link EventEmitterProvider} until the event - * API is marked stable. It will eventually be merged into {@link GlobalOpenTelemetry}. - */ -// We intentionally assign to be used for error reporting. -@SuppressWarnings("StaticAssignmentOfThrowable") -public final class GlobalEventEmitterProvider { - - private static final AtomicReference instance = - new AtomicReference<>(EventEmitterProvider.noop()); - - @SuppressWarnings("NonFinalStaticField") - @Nullable - private static volatile Throwable setInstanceCaller; - - private GlobalEventEmitterProvider() {} - - /** Returns the globally registered {@link EventEmitterProvider}. */ - // instance cannot be set to null - @SuppressWarnings("NullAway") - public static EventEmitterProvider get() { - return instance.get(); - } - - /** - * Sets the global {@link EventEmitterProvider}. Future calls to {@link #get()} will return the - * provided {@link EventEmitterProvider} instance. This should be called once as early as possible - * in your application initialization logic. - */ - public static void set(EventEmitterProvider eventEmitterProvider) { - boolean changed = instance.compareAndSet(EventEmitterProvider.noop(), eventEmitterProvider); - if (!changed && (eventEmitterProvider != EventEmitterProvider.noop())) { - throw new IllegalStateException( - "GlobalEventEmitterProvider.set has already been called. GlobalEventEmitterProvider.set " - + "must be called only once before any calls to GlobalEventEmitterProvider.get. " - + "Previous invocation set to cause of this exception.", - setInstanceCaller); - } - setInstanceCaller = new Throwable(); - } - - /** - * Unsets the global {@link EventEmitterProvider}. This is only meant to be used from tests which - * need to reconfigure {@link EventEmitterProvider}. - */ - public static void resetForTest() { - instance.set(EventEmitterProvider.noop()); - } -} diff --git a/api/incubator/src/main/java/io/opentelemetry/api/incubator/events/GlobalEventLoggerProvider.java b/api/incubator/src/main/java/io/opentelemetry/api/incubator/events/GlobalEventLoggerProvider.java new file mode 100644 index 00000000000..68664f08b56 --- /dev/null +++ b/api/incubator/src/main/java/io/opentelemetry/api/incubator/events/GlobalEventLoggerProvider.java @@ -0,0 +1,60 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.api.incubator.events; + +import io.opentelemetry.api.GlobalOpenTelemetry; +import java.util.concurrent.atomic.AtomicReference; +import javax.annotation.Nullable; + +/** + * This class provides a temporary global accessor for {@link EventLoggerProvider} until the event + * API is marked stable. It will eventually be merged into {@link GlobalOpenTelemetry}. + */ +// We intentionally assign to be used for error reporting. +@SuppressWarnings("StaticAssignmentOfThrowable") +public final class GlobalEventLoggerProvider { + + private static final AtomicReference instance = + new AtomicReference<>(EventLoggerProvider.noop()); + + @SuppressWarnings("NonFinalStaticField") + @Nullable + private static volatile Throwable setInstanceCaller; + + private GlobalEventLoggerProvider() {} + + /** Returns the globally registered {@link EventLoggerProvider}. */ + // instance cannot be set to null + @SuppressWarnings("NullAway") + public static EventLoggerProvider get() { + return instance.get(); + } + + /** + * Sets the global {@link EventLoggerProvider}. Future calls to {@link #get()} will return the + * provided {@link EventLoggerProvider} instance. This should be called once as early as possible + * in your application initialization logic. + */ + public static void set(EventLoggerProvider eventLoggerProvider) { + boolean changed = instance.compareAndSet(EventLoggerProvider.noop(), eventLoggerProvider); + if (!changed && (eventLoggerProvider != EventLoggerProvider.noop())) { + throw new IllegalStateException( + "GlobalEventLoggerProvider.set has already been called. GlobalEventLoggerProvider.set " + + "must be called only once before any calls to GlobalEventLoggerProvider.get. " + + "Previous invocation set to cause of this exception.", + setInstanceCaller); + } + setInstanceCaller = new Throwable(); + } + + /** + * Unsets the global {@link EventLoggerProvider}. This is only meant to be used from tests which + * need to reconfigure {@link EventLoggerProvider}. + */ + public static void resetForTest() { + instance.set(EventLoggerProvider.noop()); + } +} diff --git a/api/incubator/src/test/java/io/opentelemetry/api/incubator/events/DefaultEventEmitterProviderTest.java b/api/incubator/src/test/java/io/opentelemetry/api/incubator/events/DefaultEventLoggerProviderTest.java similarity index 71% rename from api/incubator/src/test/java/io/opentelemetry/api/incubator/events/DefaultEventEmitterProviderTest.java rename to api/incubator/src/test/java/io/opentelemetry/api/incubator/events/DefaultEventLoggerProviderTest.java index 52e23c5b44d..431130045cc 100644 --- a/api/incubator/src/test/java/io/opentelemetry/api/incubator/events/DefaultEventEmitterProviderTest.java +++ b/api/incubator/src/test/java/io/opentelemetry/api/incubator/events/DefaultEventLoggerProviderTest.java @@ -11,18 +11,18 @@ import io.opentelemetry.api.common.Attributes; import org.junit.jupiter.api.Test; -class DefaultEventEmitterProviderTest { +class DefaultEventLoggerProviderTest { @Test - void noopEventEmitterProvider_doesNotThrow() { - EventEmitterProvider provider = EventEmitterProvider.noop(); + void noopEventLoggerProvider_doesNotThrow() { + EventLoggerProvider provider = EventLoggerProvider.noop(); - assertThat(provider).isSameAs(DefaultEventEmitterProvider.getInstance()); + assertThat(provider).isSameAs(DefaultEventLoggerProvider.getInstance()); assertThatCode(() -> provider.get("scope-name")).doesNotThrowAnyException(); assertThatCode( () -> provider - .eventEmitterBuilder("scope-name") + .eventLoggerBuilder("scope-name") .setInstrumentationVersion("1.0") .setSchemaUrl("http://schema.com") .build()) @@ -31,7 +31,7 @@ void noopEventEmitterProvider_doesNotThrow() { assertThatCode( () -> provider - .eventEmitterBuilder("scope-name") + .eventLoggerBuilder("scope-name") .build() .emit("event-name", Attributes.empty())) .doesNotThrowAnyException(); diff --git a/api/incubator/src/test/java/io/opentelemetry/api/incubator/events/DefaultEventEmitterTest.java b/api/incubator/src/test/java/io/opentelemetry/api/incubator/events/DefaultEventLoggerTest.java similarity index 79% rename from api/incubator/src/test/java/io/opentelemetry/api/incubator/events/DefaultEventEmitterTest.java rename to api/incubator/src/test/java/io/opentelemetry/api/incubator/events/DefaultEventLoggerTest.java index a8d70533f47..9d14ef63c48 100644 --- a/api/incubator/src/test/java/io/opentelemetry/api/incubator/events/DefaultEventEmitterTest.java +++ b/api/incubator/src/test/java/io/opentelemetry/api/incubator/events/DefaultEventLoggerTest.java @@ -12,15 +12,15 @@ import java.util.concurrent.TimeUnit; import org.junit.jupiter.api.Test; -class DefaultEventEmitterTest { +class DefaultEventLoggerTest { @Test void emit() { - assertThatCode(() -> DefaultEventEmitter.getInstance().emit("event-name", Attributes.empty())) + assertThatCode(() -> DefaultEventLogger.getInstance().emit("event-name", Attributes.empty())) .doesNotThrowAnyException(); assertThatCode( () -> - DefaultEventEmitter.getInstance() + DefaultEventLogger.getInstance() .emit( "event-domain.event-name", Attributes.builder().put("key1", "value1").build())) @@ -30,10 +30,10 @@ void emit() { @Test void builder() { Attributes attributes = Attributes.builder().put("key1", "value1").build(); - EventEmitter emitter = DefaultEventEmitter.getInstance(); + EventLogger eventLogger = DefaultEventLogger.getInstance(); assertThatCode( () -> - emitter + eventLogger .builder("com.example.MyEvent", attributes) .setTimestamp(123456L, TimeUnit.NANOSECONDS) .setTimestamp(Instant.now()) diff --git a/api/incubator/src/test/java/io/opentelemetry/api/incubator/events/GlobalEventEmitterProviderTest.java b/api/incubator/src/test/java/io/opentelemetry/api/incubator/events/GlobalEventEmitterProviderTest.java deleted file mode 100644 index 8f48c17bc5b..00000000000 --- a/api/incubator/src/test/java/io/opentelemetry/api/incubator/events/GlobalEventEmitterProviderTest.java +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package io.opentelemetry.api.incubator.events; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatThrownBy; - -import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.Test; - -class GlobalEventEmitterProviderTest { - - @BeforeAll - static void beforeClass() { - GlobalEventEmitterProvider.resetForTest(); - } - - @AfterEach - void after() { - GlobalEventEmitterProvider.resetForTest(); - } - - @Test - void setAndGet() { - assertThat(GlobalEventEmitterProvider.get()).isEqualTo(EventEmitterProvider.noop()); - EventEmitterProvider eventEmitterProvider = - instrumentationScopeName -> - EventEmitterProvider.noop().eventEmitterBuilder(instrumentationScopeName); - GlobalEventEmitterProvider.set(eventEmitterProvider); - assertThat(GlobalEventEmitterProvider.get()).isEqualTo(eventEmitterProvider); - } - - @Test - void setThenSet() { - GlobalEventEmitterProvider.set( - instrumentationScopeName -> - EventEmitterProvider.noop().eventEmitterBuilder(instrumentationScopeName)); - assertThatThrownBy( - () -> - GlobalEventEmitterProvider.set( - instrumentationScopeName -> - EventEmitterProvider.noop().eventEmitterBuilder(instrumentationScopeName))) - .isInstanceOf(IllegalStateException.class) - .hasMessageContaining("GlobalEventEmitterProvider.set has already been called") - .hasStackTraceContaining("setThenSet"); - } -} diff --git a/api/incubator/src/test/java/io/opentelemetry/api/incubator/events/GlobalEventLoggerProviderTest.java b/api/incubator/src/test/java/io/opentelemetry/api/incubator/events/GlobalEventLoggerProviderTest.java new file mode 100644 index 00000000000..d3392d59838 --- /dev/null +++ b/api/incubator/src/test/java/io/opentelemetry/api/incubator/events/GlobalEventLoggerProviderTest.java @@ -0,0 +1,51 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.api.incubator.events; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; + +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; + +class GlobalEventLoggerProviderTest { + + @BeforeAll + static void beforeClass() { + GlobalEventLoggerProvider.resetForTest(); + } + + @AfterEach + void after() { + GlobalEventLoggerProvider.resetForTest(); + } + + @Test + void setAndGet() { + assertThat(GlobalEventLoggerProvider.get()).isEqualTo(EventLoggerProvider.noop()); + EventLoggerProvider eventLoggerProvider = + instrumentationScopeName -> + EventLoggerProvider.noop().eventLoggerBuilder(instrumentationScopeName); + GlobalEventLoggerProvider.set(eventLoggerProvider); + assertThat(GlobalEventLoggerProvider.get()).isEqualTo(eventLoggerProvider); + } + + @Test + void setThenSet() { + GlobalEventLoggerProvider.set( + instrumentationScopeName -> + EventLoggerProvider.noop().eventLoggerBuilder(instrumentationScopeName)); + assertThatThrownBy( + () -> + GlobalEventLoggerProvider.set( + instrumentationScopeName -> + EventLoggerProvider.noop().eventLoggerBuilder(instrumentationScopeName))) + .isInstanceOf(IllegalStateException.class) + .hasMessageContaining("GlobalEventLoggerProvider.set has already been called") + .hasStackTraceContaining("setThenSet"); + } +} diff --git a/integration-tests/otlp/src/main/java/io/opentelemetry/integrationtest/OtlpExporterIntegrationTest.java b/integration-tests/otlp/src/main/java/io/opentelemetry/integrationtest/OtlpExporterIntegrationTest.java index 544b9a94794..810b51f5131 100644 --- a/integration-tests/otlp/src/main/java/io/opentelemetry/integrationtest/OtlpExporterIntegrationTest.java +++ b/integration-tests/otlp/src/main/java/io/opentelemetry/integrationtest/OtlpExporterIntegrationTest.java @@ -21,7 +21,7 @@ import io.opentelemetry.api.GlobalOpenTelemetry; import io.opentelemetry.api.common.AttributeKey; import io.opentelemetry.api.common.Attributes; -import io.opentelemetry.api.incubator.events.EventEmitter; +import io.opentelemetry.api.incubator.events.EventLogger; import io.opentelemetry.api.incubator.logs.ExtendedLogRecordBuilder; import io.opentelemetry.api.incubator.logs.KeyAnyValue; import io.opentelemetry.api.logs.Logger; @@ -66,7 +66,7 @@ import io.opentelemetry.sdk.logs.SdkLoggerProvider; import io.opentelemetry.sdk.logs.export.BatchLogRecordProcessor; import io.opentelemetry.sdk.logs.export.LogRecordExporter; -import io.opentelemetry.sdk.logs.internal.SdkEventEmitterProvider; +import io.opentelemetry.sdk.logs.internal.SdkEventLoggerProvider; import io.opentelemetry.sdk.metrics.SdkMeterProvider; import io.opentelemetry.sdk.metrics.SdkMeterProviderBuilder; import io.opentelemetry.sdk.metrics.export.MetricExporter; @@ -533,9 +533,9 @@ private static void testLogRecordExporter(LogRecordExporter logRecordExporter) { .build(); Logger logger = loggerProvider.get(OtlpExporterIntegrationTest.class.getName()); - EventEmitter eventEmitter = - SdkEventEmitterProvider.create(loggerProvider) - .eventEmitterBuilder(OtlpExporterIntegrationTest.class.getName()) + EventLogger eventLogger = + SdkEventLoggerProvider.create(loggerProvider) + .eventLoggerBuilder(OtlpExporterIntegrationTest.class.getName()) .build(); SpanContext spanContext = @@ -568,7 +568,7 @@ private static void testLogRecordExporter(LogRecordExporter logRecordExporter) { .setSeverityText("DEBUG") .setContext(Context.current()) .emit(); - eventEmitter.emit("event-name", Attributes.builder().put("key", "value").build()); + eventLogger.emit("event-name", Attributes.builder().put("key", "value").build()); } // Closing triggers flush of processor @@ -706,7 +706,7 @@ private static void testLogRecordExporter(LogRecordExporter logRecordExporter) { .isEqualTo(spanContext.getTraceFlags()); assertThat(protoLog1.getTimeUnixNano()).isEqualTo(100); - // LogRecord via EventEmitter.emit(String, Attributes) + // LogRecord via EventLogger.emit(String, Attributes) io.opentelemetry.proto.logs.v1.LogRecord protoLog2 = ilLogs.getLogRecords(1); assertThat(protoLog2.getBody().getStringValue()).isEmpty(); assertThat(protoLog2.getAttributesList()) diff --git a/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/AutoConfiguredOpenTelemetrySdkBuilder.java b/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/AutoConfiguredOpenTelemetrySdkBuilder.java index 08bb093939e..3e9a315a737 100644 --- a/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/AutoConfiguredOpenTelemetrySdkBuilder.java +++ b/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/AutoConfiguredOpenTelemetrySdkBuilder.java @@ -8,7 +8,7 @@ import static java.util.Objects.requireNonNull; import io.opentelemetry.api.GlobalOpenTelemetry; -import io.opentelemetry.api.incubator.events.GlobalEventEmitterProvider; +import io.opentelemetry.api.incubator.events.GlobalEventLoggerProvider; import io.opentelemetry.context.propagation.ContextPropagators; import io.opentelemetry.context.propagation.TextMapPropagator; import io.opentelemetry.sdk.OpenTelemetrySdk; @@ -25,7 +25,7 @@ import io.opentelemetry.sdk.logs.SdkLoggerProvider; import io.opentelemetry.sdk.logs.SdkLoggerProviderBuilder; import io.opentelemetry.sdk.logs.export.LogRecordExporter; -import io.opentelemetry.sdk.logs.internal.SdkEventEmitterProvider; +import io.opentelemetry.sdk.logs.internal.SdkEventLoggerProvider; import io.opentelemetry.sdk.metrics.SdkMeterProvider; import io.opentelemetry.sdk.metrics.SdkMeterProviderBuilder; import io.opentelemetry.sdk.metrics.export.MetricExporter; @@ -571,8 +571,8 @@ private void maybeSetAsGlobal(OpenTelemetrySdk openTelemetrySdk) { return; } GlobalOpenTelemetry.set(openTelemetrySdk); - GlobalEventEmitterProvider.set( - SdkEventEmitterProvider.create(openTelemetrySdk.getSdkLoggerProvider())); + GlobalEventLoggerProvider.set( + SdkEventLoggerProvider.create(openTelemetrySdk.getSdkLoggerProvider())); logger.log( Level.FINE, "Global OpenTelemetry set to {0} by autoconfiguration", openTelemetrySdk); } diff --git a/sdk-extensions/autoconfigure/src/test/java/io/opentelemetry/sdk/autoconfigure/AutoConfiguredOpenTelemetrySdkTest.java b/sdk-extensions/autoconfigure/src/test/java/io/opentelemetry/sdk/autoconfigure/AutoConfiguredOpenTelemetrySdkTest.java index 57b8eb011fb..37cafb9bdfa 100644 --- a/sdk-extensions/autoconfigure/src/test/java/io/opentelemetry/sdk/autoconfigure/AutoConfiguredOpenTelemetrySdkTest.java +++ b/sdk-extensions/autoconfigure/src/test/java/io/opentelemetry/sdk/autoconfigure/AutoConfiguredOpenTelemetrySdkTest.java @@ -26,7 +26,7 @@ import io.github.netmikey.logunit.api.LogCapturer; import io.opentelemetry.api.GlobalOpenTelemetry; import io.opentelemetry.api.OpenTelemetry; -import io.opentelemetry.api.incubator.events.GlobalEventEmitterProvider; +import io.opentelemetry.api.incubator.events.GlobalEventLoggerProvider; import io.opentelemetry.api.trace.Span; import io.opentelemetry.api.trace.SpanId; import io.opentelemetry.api.trace.TraceId; @@ -49,7 +49,7 @@ import io.opentelemetry.sdk.logs.LogRecordProcessor; import io.opentelemetry.sdk.logs.SdkLoggerProvider; import io.opentelemetry.sdk.logs.SdkLoggerProviderBuilder; -import io.opentelemetry.sdk.logs.internal.SdkEventEmitterProvider; +import io.opentelemetry.sdk.logs.internal.SdkEventLoggerProvider; import io.opentelemetry.sdk.metrics.SdkMeterProvider; import io.opentelemetry.sdk.metrics.SdkMeterProviderBuilder; import io.opentelemetry.sdk.metrics.export.MetricReader; @@ -156,7 +156,7 @@ public SdkLoggerProviderBuilder apply( @BeforeEach void resetGlobal() { GlobalOpenTelemetry.resetForTest(); - GlobalEventEmitterProvider.resetForTest(); + GlobalEventLoggerProvider.resetForTest(); builder = AutoConfiguredOpenTelemetrySdk.builder() .addPropertiesSupplier(disableExportPropertySupplier()); @@ -456,7 +456,7 @@ void builder_setResultAsGlobalFalse() { OpenTelemetrySdk openTelemetry = builder.build().getOpenTelemetrySdk(); assertThat(GlobalOpenTelemetry.get()).extracting("delegate").isNotSameAs(openTelemetry); - assertThat(GlobalEventEmitterProvider.get()).isNotSameAs(openTelemetry.getSdkLoggerProvider()); + assertThat(GlobalEventLoggerProvider.get()).isNotSameAs(openTelemetry.getSdkLoggerProvider()); } @Test @@ -464,8 +464,8 @@ void builder_setResultAsGlobalTrue() { OpenTelemetrySdk openTelemetry = builder.setResultAsGlobal().build().getOpenTelemetrySdk(); assertThat(GlobalOpenTelemetry.get()).extracting("delegate").isSameAs(openTelemetry); - assertThat(GlobalEventEmitterProvider.get()) - .isInstanceOf(SdkEventEmitterProvider.class) + assertThat(GlobalEventLoggerProvider.get()) + .isInstanceOf(SdkEventLoggerProvider.class) .extracting("delegateLoggerProvider") .isSameAs(openTelemetry.getSdkLoggerProvider()); } diff --git a/sdk-extensions/autoconfigure/src/testFullConfig/java/io/opentelemetry/sdk/autoconfigure/AutoConfiguredOpenTelemetrySdkTest.java b/sdk-extensions/autoconfigure/src/testFullConfig/java/io/opentelemetry/sdk/autoconfigure/AutoConfiguredOpenTelemetrySdkTest.java index 2c85ae02507..4fc7dce0c35 100644 --- a/sdk-extensions/autoconfigure/src/testFullConfig/java/io/opentelemetry/sdk/autoconfigure/AutoConfiguredOpenTelemetrySdkTest.java +++ b/sdk-extensions/autoconfigure/src/testFullConfig/java/io/opentelemetry/sdk/autoconfigure/AutoConfiguredOpenTelemetrySdkTest.java @@ -13,7 +13,7 @@ import io.github.netmikey.logunit.api.LogCapturer; import io.opentelemetry.api.GlobalOpenTelemetry; import io.opentelemetry.api.OpenTelemetry; -import io.opentelemetry.api.incubator.events.GlobalEventEmitterProvider; +import io.opentelemetry.api.incubator.events.GlobalEventLoggerProvider; import io.opentelemetry.exporter.prometheus.PrometheusHttpServer; import io.opentelemetry.sdk.OpenTelemetrySdk; import java.lang.reflect.Field; @@ -32,7 +32,7 @@ class AutoConfiguredOpenTelemetrySdkTest { @BeforeEach void setUp() { GlobalOpenTelemetry.resetForTest(); - GlobalEventEmitterProvider.resetForTest(); + GlobalEventLoggerProvider.resetForTest(); } @SuppressWarnings("ResultOfMethodCallIgnored") diff --git a/sdk-extensions/autoconfigure/src/testFullConfig/java/io/opentelemetry/sdk/autoconfigure/FileConfigurationTest.java b/sdk-extensions/autoconfigure/src/testFullConfig/java/io/opentelemetry/sdk/autoconfigure/FileConfigurationTest.java index 058b6ed91d3..7ce59ad321a 100644 --- a/sdk-extensions/autoconfigure/src/testFullConfig/java/io/opentelemetry/sdk/autoconfigure/FileConfigurationTest.java +++ b/sdk-extensions/autoconfigure/src/testFullConfig/java/io/opentelemetry/sdk/autoconfigure/FileConfigurationTest.java @@ -19,7 +19,7 @@ import io.opentelemetry.api.GlobalOpenTelemetry; import io.opentelemetry.api.OpenTelemetry; import io.opentelemetry.api.baggage.propagation.W3CBaggagePropagator; -import io.opentelemetry.api.incubator.events.GlobalEventEmitterProvider; +import io.opentelemetry.api.incubator.events.GlobalEventLoggerProvider; import io.opentelemetry.api.trace.propagation.W3CTraceContextPropagator; import io.opentelemetry.context.propagation.ContextPropagators; import io.opentelemetry.context.propagation.TextMapPropagator; @@ -29,7 +29,7 @@ import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties; import io.opentelemetry.sdk.autoconfigure.spi.ConfigurationException; import io.opentelemetry.sdk.autoconfigure.spi.internal.DefaultConfigProperties; -import io.opentelemetry.sdk.logs.internal.SdkEventEmitterProvider; +import io.opentelemetry.sdk.logs.internal.SdkEventLoggerProvider; import io.opentelemetry.sdk.resources.Resource; import io.opentelemetry.sdk.trace.SdkTracerProvider; import io.opentelemetry.sdk.trace.export.SimpleSpanProcessor; @@ -71,7 +71,7 @@ void setup() throws IOException { configFilePath = tempDir.resolve("otel-config.yaml"); Files.write(configFilePath, yaml.getBytes(StandardCharsets.UTF_8)); GlobalOpenTelemetry.resetForTest(); - GlobalEventEmitterProvider.resetForTest(); + GlobalEventLoggerProvider.resetForTest(); } @Test @@ -139,7 +139,7 @@ void configFile_setResultAsGlobalFalse() { cleanup.addCloseable(openTelemetrySdk); assertThat(GlobalOpenTelemetry.get()).extracting("delegate").isNotSameAs(openTelemetrySdk); - assertThat(GlobalEventEmitterProvider.get()) + assertThat(GlobalEventLoggerProvider.get()) .isNotSameAs(openTelemetrySdk.getSdkLoggerProvider()); } @@ -155,8 +155,8 @@ void configFile_setResultAsGlobalTrue() { cleanup.addCloseable(openTelemetrySdk); assertThat(GlobalOpenTelemetry.get()).extracting("delegate").isSameAs(openTelemetrySdk); - assertThat(GlobalEventEmitterProvider.get()) - .isInstanceOf(SdkEventEmitterProvider.class) + assertThat(GlobalEventLoggerProvider.get()) + .isInstanceOf(SdkEventLoggerProvider.class) .extracting("delegateLoggerProvider") .isSameAs(openTelemetrySdk.getSdkLoggerProvider()); } diff --git a/sdk-extensions/autoconfigure/src/testFullConfig/java/io/opentelemetry/sdk/autoconfigure/FullConfigTest.java b/sdk-extensions/autoconfigure/src/testFullConfig/java/io/opentelemetry/sdk/autoconfigure/FullConfigTest.java index a5c5fc2fe24..2097af7945c 100644 --- a/sdk-extensions/autoconfigure/src/testFullConfig/java/io/opentelemetry/sdk/autoconfigure/FullConfigTest.java +++ b/sdk-extensions/autoconfigure/src/testFullConfig/java/io/opentelemetry/sdk/autoconfigure/FullConfigTest.java @@ -18,8 +18,8 @@ import io.opentelemetry.api.GlobalOpenTelemetry; import io.opentelemetry.api.baggage.propagation.W3CBaggagePropagator; import io.opentelemetry.api.common.Attributes; -import io.opentelemetry.api.incubator.events.EventEmitter; -import io.opentelemetry.api.incubator.events.GlobalEventEmitterProvider; +import io.opentelemetry.api.incubator.events.EventLogger; +import io.opentelemetry.api.incubator.events.GlobalEventLoggerProvider; import io.opentelemetry.api.logs.Logger; import io.opentelemetry.api.logs.Severity; import io.opentelemetry.api.metrics.Meter; @@ -159,7 +159,7 @@ void setUp() { // Initialize here so we can shutdown when done GlobalOpenTelemetry.resetForTest(); - GlobalEventEmitterProvider.resetForTest(); + GlobalEventLoggerProvider.resetForTest(); openTelemetrySdk = AutoConfiguredOpenTelemetrySdk.initialize().getOpenTelemetrySdk(); } @@ -167,7 +167,7 @@ void setUp() { void afterEach() { openTelemetrySdk.close(); GlobalOpenTelemetry.resetForTest(); - GlobalEventEmitterProvider.resetForTest(); + GlobalEventLoggerProvider.resetForTest(); } @Test @@ -206,9 +206,8 @@ void configures() throws Exception { logger.logRecordBuilder().setBody("debug log message").setSeverity(Severity.DEBUG).emit(); logger.logRecordBuilder().setBody("info log message").setSeverity(Severity.INFO).emit(); - EventEmitter eventEmitter = - GlobalEventEmitterProvider.get().eventEmitterBuilder("test").build(); - eventEmitter.emit("test-name", Attributes.builder().put("cow", "moo").build()); + EventLogger eventLogger = GlobalEventLoggerProvider.get().eventLoggerBuilder("test").build(); + eventLogger.emit("test-name", Attributes.builder().put("cow", "moo").build()); openTelemetrySdk.getSdkTracerProvider().forceFlush().join(10, TimeUnit.SECONDS); openTelemetrySdk.getSdkLoggerProvider().forceFlush().join(10, TimeUnit.SECONDS); diff --git a/sdk/logs/src/main/java/io/opentelemetry/sdk/logs/internal/SdkEventBuilder.java b/sdk/logs/src/main/java/io/opentelemetry/sdk/logs/internal/SdkEventBuilder.java index d817edad529..ce4f5d69623 100644 --- a/sdk/logs/src/main/java/io/opentelemetry/sdk/logs/internal/SdkEventBuilder.java +++ b/sdk/logs/src/main/java/io/opentelemetry/sdk/logs/internal/SdkEventBuilder.java @@ -33,7 +33,7 @@ public EventBuilder setTimestamp(Instant instant) { @Override public void emit() { - SdkEventEmitterProvider.addEventName(logRecordBuilder, eventName); + SdkEventLoggerProvider.addEventName(logRecordBuilder, eventName); logRecordBuilder.emit(); } } diff --git a/sdk/logs/src/main/java/io/opentelemetry/sdk/logs/internal/SdkEventEmitterProvider.java b/sdk/logs/src/main/java/io/opentelemetry/sdk/logs/internal/SdkEventLoggerProvider.java similarity index 58% rename from sdk/logs/src/main/java/io/opentelemetry/sdk/logs/internal/SdkEventEmitterProvider.java rename to sdk/logs/src/main/java/io/opentelemetry/sdk/logs/internal/SdkEventLoggerProvider.java index 0fdaa6f05ad..3eb6bb708ab 100644 --- a/sdk/logs/src/main/java/io/opentelemetry/sdk/logs/internal/SdkEventEmitterProvider.java +++ b/sdk/logs/src/main/java/io/opentelemetry/sdk/logs/internal/SdkEventLoggerProvider.java @@ -8,9 +8,9 @@ import io.opentelemetry.api.common.AttributeKey; import io.opentelemetry.api.common.Attributes; import io.opentelemetry.api.incubator.events.EventBuilder; -import io.opentelemetry.api.incubator.events.EventEmitter; -import io.opentelemetry.api.incubator.events.EventEmitterBuilder; -import io.opentelemetry.api.incubator.events.EventEmitterProvider; +import io.opentelemetry.api.incubator.events.EventLogger; +import io.opentelemetry.api.incubator.events.EventLoggerBuilder; +import io.opentelemetry.api.incubator.events.EventLoggerProvider; import io.opentelemetry.api.logs.LogRecordBuilder; import io.opentelemetry.api.logs.Logger; import io.opentelemetry.api.logs.LoggerBuilder; @@ -19,82 +19,82 @@ import java.util.concurrent.TimeUnit; /** - * SDK implementation for {@link EventEmitterProvider}. + * SDK implementation for {@link EventLoggerProvider}. * *

    Delegates all calls to the configured {@link LoggerProvider}, and its {@link LoggerBuilder}s, * {@link Logger}s. */ -public final class SdkEventEmitterProvider implements EventEmitterProvider { +public final class SdkEventLoggerProvider implements EventLoggerProvider { static final AttributeKey EVENT_NAME = AttributeKey.stringKey("event.name"); private final LoggerProvider delegateLoggerProvider; private final Clock clock; - private SdkEventEmitterProvider(LoggerProvider delegateLoggerProvider, Clock clock) { + private SdkEventLoggerProvider(LoggerProvider delegateLoggerProvider, Clock clock) { this.delegateLoggerProvider = delegateLoggerProvider; this.clock = clock; } /** - * Create a {@link SdkEventEmitterProvider} which delegates to the {@code delegateLoggerProvider}. + * Create a {@link SdkEventLoggerProvider} which delegates to the {@code delegateLoggerProvider}. */ - public static SdkEventEmitterProvider create(LoggerProvider delegateLoggerProvider) { - return new SdkEventEmitterProvider(delegateLoggerProvider, Clock.getDefault()); + public static SdkEventLoggerProvider create(LoggerProvider delegateLoggerProvider) { + return new SdkEventLoggerProvider(delegateLoggerProvider, Clock.getDefault()); } /** - * Create a {@link SdkEventEmitterProvider} which delegates to the {@code delegateLoggerProvider}. + * Create a {@link SdkEventLoggerProvider} which delegates to the {@code delegateLoggerProvider}. */ - public static SdkEventEmitterProvider create(LoggerProvider delegateLoggerProvider, Clock clock) { - return new SdkEventEmitterProvider(delegateLoggerProvider, clock); + public static SdkEventLoggerProvider create(LoggerProvider delegateLoggerProvider, Clock clock) { + return new SdkEventLoggerProvider(delegateLoggerProvider, clock); } @Override - public EventEmitter get(String instrumentationScopeName) { - return eventEmitterBuilder(instrumentationScopeName).build(); + public EventLogger get(String instrumentationScopeName) { + return eventLoggerBuilder(instrumentationScopeName).build(); } @Override - public EventEmitterBuilder eventEmitterBuilder(String instrumentationScopeName) { - return new SdkEventEmitterBuilder( + public EventLoggerBuilder eventLoggerBuilder(String instrumentationScopeName) { + return new SdkEventLoggerBuilder( clock, delegateLoggerProvider.loggerBuilder(instrumentationScopeName)); } - private static class SdkEventEmitterBuilder implements EventEmitterBuilder { + private static class SdkEventLoggerBuilder implements EventLoggerBuilder { private final Clock clock; private final LoggerBuilder delegateLoggerBuilder; - private SdkEventEmitterBuilder(Clock clock, LoggerBuilder delegateLoggerBuilder) { + private SdkEventLoggerBuilder(Clock clock, LoggerBuilder delegateLoggerBuilder) { this.clock = clock; this.delegateLoggerBuilder = delegateLoggerBuilder; } @Override - public EventEmitterBuilder setSchemaUrl(String schemaUrl) { + public EventLoggerBuilder setSchemaUrl(String schemaUrl) { delegateLoggerBuilder.setSchemaUrl(schemaUrl); return this; } @Override - public EventEmitterBuilder setInstrumentationVersion(String instrumentationScopeVersion) { + public EventLoggerBuilder setInstrumentationVersion(String instrumentationScopeVersion) { delegateLoggerBuilder.setInstrumentationVersion(instrumentationScopeVersion); return this; } @Override - public EventEmitter build() { - return new SdkEventEmitter(clock, delegateLoggerBuilder.build()); + public EventLogger build() { + return new SdkEventLogger(clock, delegateLoggerBuilder.build()); } } - private static class SdkEventEmitter implements EventEmitter { + private static class SdkEventLogger implements EventLogger { private final Clock clock; private final Logger delegateLogger; - private SdkEventEmitter(Clock clock, Logger delegateLogger) { + private SdkEventLogger(Clock clock, Logger delegateLogger) { this.clock = clock; this.delegateLogger = delegateLogger; } diff --git a/sdk/logs/src/test/java/io/opentelemetry/sdk/logs/internal/SdkEventEmitterProviderTest.java b/sdk/logs/src/test/java/io/opentelemetry/sdk/logs/internal/SdkEventLoggerProviderTest.java similarity index 84% rename from sdk/logs/src/test/java/io/opentelemetry/sdk/logs/internal/SdkEventEmitterProviderTest.java rename to sdk/logs/src/test/java/io/opentelemetry/sdk/logs/internal/SdkEventLoggerProviderTest.java index 73db07cce57..847d3142e40 100644 --- a/sdk/logs/src/test/java/io/opentelemetry/sdk/logs/internal/SdkEventEmitterProviderTest.java +++ b/sdk/logs/src/test/java/io/opentelemetry/sdk/logs/internal/SdkEventLoggerProviderTest.java @@ -11,7 +11,7 @@ import static org.mockito.Mockito.when; import io.opentelemetry.api.common.Attributes; -import io.opentelemetry.api.incubator.events.EventEmitter; +import io.opentelemetry.api.incubator.events.EventLogger; import io.opentelemetry.sdk.common.Clock; import io.opentelemetry.sdk.common.InstrumentationScopeInfo; import io.opentelemetry.sdk.logs.ReadWriteLogRecord; @@ -21,15 +21,15 @@ import java.util.concurrent.atomic.AtomicReference; import org.junit.jupiter.api.Test; -class SdkEventEmitterProviderTest { +class SdkEventLoggerProviderTest { private static final Resource RESOURCE = Resource.builder().put("resource-key", "resource-value").build(); private final Clock clock = mock(Clock.class); private final AtomicReference seenLog = new AtomicReference<>(); - private final SdkEventEmitterProvider eventEmitterProvider = - SdkEventEmitterProvider.create( + private final SdkEventLoggerProvider eventLoggerProvider = + SdkEventLoggerProvider.create( SdkLoggerProvider.builder() .setResource(RESOURCE) .addLogRecordProcessor((context, logRecord) -> seenLog.set(logRecord)) @@ -40,8 +40,8 @@ class SdkEventEmitterProviderTest { void emit() { when(clock.now()).thenReturn(10L); - eventEmitterProvider - .eventEmitterBuilder("test-scope") + eventLoggerProvider + .eventLoggerBuilder("test-scope") .build() .emit( "event-name", @@ -64,9 +64,9 @@ void builder() { long yesterday = System.nanoTime() - TimeUnit.DAYS.toNanos(1); Attributes attributes = Attributes.of(stringKey("foo"), "bar"); - EventEmitter emitter = eventEmitterProvider.eventEmitterBuilder("test-scope").build(); + EventLogger eventLogger = eventLoggerProvider.eventLoggerBuilder("test-scope").build(); - emitter.builder("testing", attributes).setTimestamp(yesterday, TimeUnit.NANOSECONDS).emit(); + eventLogger.builder("testing", attributes).setTimestamp(yesterday, TimeUnit.NANOSECONDS).emit(); verifySeen(yesterday, attributes); } From 4f99e7cb4ee2e5df7db28466003415c37f533a93 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 28 Mar 2024 09:49:48 -0500 Subject: [PATCH 308/901] Update dependency gradle to v8.7 (#6321) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- gradle/wrapper/gradle-wrapper.jar | Bin 43462 -> 43453 bytes gradle/wrapper/gradle-wrapper.properties | 4 ++-- gradlew.bat | 20 ++++++++++---------- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index d64cd4917707c1f8861d8cb53dd15194d4248596..e6441136f3d4ba8a0da8d277868979cfbc8ad796 100644 GIT binary patch delta 34118 zcmY(qRX`kF)3u#IAjsf0xCD212@LM;?(PINyAue(f;$XO2=4Cg1P$=#e%|lo zKk1`B>Q#GH)wNd-&cJofz}3=WfYndTeo)CyX{fOHsQjGa<{e=jamMNwjdatD={CN3>GNchOE9OGPIqr)3v>RcKWR3Z zF-guIMjE2UF0Wqk1)21791y#}ciBI*bAenY*BMW_)AeSuM5}vz_~`+1i!Lo?XAEq{TlK5-efNFgHr6o zD>^vB&%3ZGEWMS>`?tu!@66|uiDvS5`?bF=gIq3rkK(j<_TybyoaDHg8;Y#`;>tXI z=tXo~e9{U!*hqTe#nZjW4z0mP8A9UUv1}C#R*@yu9G3k;`Me0-BA2&Aw6f`{Ozan2 z8c8Cs#dA-7V)ZwcGKH}jW!Ja&VaUc@mu5a@CObzNot?b{f+~+212lwF;!QKI16FDS zodx>XN$sk9;t;)maB^s6sr^L32EbMV(uvW%or=|0@U6cUkE`_!<=LHLlRGJx@gQI=B(nn z-GEjDE}*8>3U$n(t^(b^C$qSTI;}6q&ypp?-2rGpqg7b}pyT zOARu2x>0HB{&D(d3sp`+}ka+Pca5glh|c=M)Ujn_$ly^X6&u z%Q4Y*LtB_>i6(YR!?{Os-(^J`(70lZ&Hp1I^?t@~SFL1!m0x6j|NM!-JTDk)%Q^R< z@e?23FD&9_W{Bgtr&CG&*Oer3Z(Bu2EbV3T9FeQ|-vo5pwzwQ%g&=zFS7b{n6T2ZQ z*!H(=z<{D9@c`KmHO&DbUIzpg`+r5207}4D=_P$ONIc5lsFgn)UB-oUE#{r+|uHc^hzv_df zV`n8&qry%jXQ33}Bjqcim~BY1?KZ}x453Oh7G@fA(}+m(f$)TY%7n=MeLi{jJ7LMB zt(mE*vFnep?YpkT_&WPV9*f>uSi#n#@STJmV&SLZnlLsWYI@y+Bs=gzcqche=&cBH2WL)dkR!a95*Ri)JH_4c*- zl4pPLl^as5_y&6RDE@@7342DNyF&GLJez#eMJjI}#pZN{Y8io{l*D+|f_Y&RQPia@ zNDL;SBERA|B#cjlNC@VU{2csOvB8$HzU$01Q?y)KEfos>W46VMh>P~oQC8k=26-Ku)@C|n^zDP!hO}Y z_tF}0@*Ds!JMt>?4y|l3?`v#5*oV-=vL7}zehMON^=s1%q+n=^^Z{^mTs7}*->#YL z)x-~SWE{e?YCarwU$=cS>VzmUh?Q&7?#Xrcce+jeZ|%0!l|H_=D_`77hBfd4Zqk&! zq-Dnt_?5*$Wsw8zGd@?woEtfYZ2|9L8b>TO6>oMh%`B7iBb)-aCefM~q|S2Cc0t9T zlu-ZXmM0wd$!gd-dTtik{bqyx32%f;`XUvbUWWJmpHfk8^PQIEsByJm+@+-aj4J#D z4#Br3pO6z1eIC>X^yKk|PeVwX_4B+IYJyJyc3B`4 zPrM#raacGIzVOexcVB;fcsxS=s1e&V;Xe$tw&KQ`YaCkHTKe*Al#velxV{3wxx}`7@isG zp6{+s)CG%HF#JBAQ_jM%zCX5X;J%-*%&jVI?6KpYyzGbq7qf;&hFprh?E5Wyo=bZ) z8YNycvMNGp1836!-?nihm6jI`^C`EeGryoNZO1AFTQhzFJOA%Q{X(sMYlzABt!&f{ zoDENSuoJQIg5Q#@BUsNJX2h>jkdx4<+ipUymWKFr;w+s>$laIIkfP6nU}r+?J9bZg zUIxz>RX$kX=C4m(zh-Eg$BsJ4OL&_J38PbHW&7JmR27%efAkqqdvf)Am)VF$+U3WR z-E#I9H6^)zHLKCs7|Zs<7Bo9VCS3@CDQ;{UTczoEprCKL3ZZW!ffmZFkcWU-V|_M2 zUA9~8tE9<5`59W-UgUmDFp11YlORl3mS3*2#ZHjv{*-1#uMV_oVTy{PY(}AqZv#wF zJVks)%N6LaHF$$<6p8S8Lqn+5&t}DmLKiC~lE{jPZ39oj{wR&fe*LX-z0m}9ZnZ{U z>3-5Bh{KKN^n5i!M79Aw5eY=`6fG#aW1_ZG;fw7JM69qk^*(rmO{|Z6rXy?l=K=#_ zE-zd*P|(sskasO(cZ5L~_{Mz&Y@@@Q)5_8l<6vB$@226O+pDvkFaK8b>%2 zfMtgJ@+cN@w>3)(_uR;s8$sGONbYvoEZ3-)zZk4!`tNzd<0lwt{RAgplo*f@Z)uO` zzd`ljSqKfHJOLxya4_}T`k5Ok1Mpo#MSqf~&ia3uIy{zyuaF}pV6 z)@$ZG5LYh8Gge*LqM_|GiT1*J*uKes=Oku_gMj&;FS`*sfpM+ygN&yOla-^WtIU#$ zuw(_-?DS?6DY7IbON7J)p^IM?N>7x^3)(7wR4PZJu(teex%l>zKAUSNL@~{czc}bR z)I{XzXqZBU3a;7UQ~PvAx8g-3q-9AEd}1JrlfS8NdPc+!=HJ6Bs( zCG!0;e0z-22(Uzw>hkEmC&xj?{0p|kc zM}MMXCF%RLLa#5jG`+}{pDL3M&|%3BlwOi?dq!)KUdv5__zR>u^o|QkYiqr(m3HxF z6J*DyN#Jpooc$ok=b7{UAVM@nwGsr6kozSddwulf5g1{B=0#2)zv!zLXQup^BZ4sv*sEsn)+MA?t zEL)}3*R?4(J~CpeSJPM!oZ~8;8s_=@6o`IA%{aEA9!GELRvOuncE`s7sH91 zmF=+T!Q6%){?lJn3`5}oW31(^Of|$r%`~gT{eimT7R~*Mg@x+tWM3KE>=Q>nkMG$U za7r>Yz2LEaA|PsMafvJ(Y>Xzha?=>#B!sYfVob4k5Orb$INFdL@U0(J8Hj&kgWUlO zPm+R07E+oq^4f4#HvEPANGWLL_!uF{nkHYE&BCH%l1FL_r(Nj@M)*VOD5S42Gk-yT z^23oAMvpA57H(fkDGMx86Z}rtQhR^L!T2iS!788E z+^${W1V}J_NwdwdxpXAW8}#6o1(Uu|vhJvubFvQIH1bDl4J4iDJ+181KuDuHwvM?` z%1@Tnq+7>p{O&p=@QT}4wT;HCb@i)&7int<0#bj8j0sfN3s6|a(l7Bj#7$hxX@~iP z1HF8RFH}irky&eCN4T94VyKqGywEGY{Gt0Xl-`|dOU&{Q;Ao;sL>C6N zXx1y^RZSaL-pG|JN;j9ADjo^XR}gce#seM4QB1?S`L*aB&QlbBIRegMnTkTCks7JU z<0(b+^Q?HN1&$M1l&I@>HMS;!&bb()a}hhJzsmB?I`poqTrSoO>m_JE5U4=?o;OV6 zBZjt;*%1P>%2{UL=;a4(aI>PRk|mr&F^=v6Fr&xMj8fRCXE5Z2qdre&;$_RNid5!S zm^XiLK25G6_j4dWkFqjtU7#s;b8h?BYFxV?OE?c~&ME`n`$ix_`mb^AWr+{M9{^^Rl;~KREplwy2q;&xe zUR0SjHzKVYzuqQ84w$NKVPGVHL_4I)Uw<$uL2-Ml#+5r2X{LLqc*p13{;w#E*Kwb*1D|v?e;(<>vl@VjnFB^^Y;;b3 z=R@(uRj6D}-h6CCOxAdqn~_SG=bN%^9(Ac?zfRkO5x2VM0+@_qk?MDXvf=@q_* z3IM@)er6-OXyE1Z4sU3{8$Y$>8NcnU-nkyWD&2ZaqX1JF_JYL8y}>@V8A5%lX#U3E zet5PJM`z79q9u5v(OE~{by|Jzlw2<0h`hKpOefhw=fgLTY9M8h+?37k@TWpzAb2Fc zQMf^aVf!yXlK?@5d-re}!fuAWu0t57ZKSSacwRGJ$0uC}ZgxCTw>cjRk*xCt%w&hh zoeiIgdz__&u~8s|_TZsGvJ7sjvBW<(C@}Y%#l_ID2&C`0;Eg2Z+pk;IK}4T@W6X5H z`s?ayU-iF+aNr5--T-^~K~p;}D(*GWOAYDV9JEw!w8ZYzS3;W6*_`#aZw&9J ziXhBKU3~zd$kKzCAP-=t&cFDeQR*_e*(excIUxKuD@;-twSlP6>wWQU)$|H3Cy+`= z-#7OW!ZlYzZxkdQpfqVDFU3V2B_-eJS)Fi{fLtRz!K{~7TR~XilNCu=Z;{GIf9KYz zf3h=Jo+1#_s>z$lc~e)l93h&RqW1VHYN;Yjwg#Qi0yzjN^M4cuL>Ew`_-_wRhi*!f zLK6vTpgo^Bz?8AsU%#n}^EGigkG3FXen3M;hm#C38P@Zs4{!QZPAU=m7ZV&xKI_HWNt90Ef zxClm)ZY?S|n**2cNYy-xBlLAVZ=~+!|7y`(fh+M$#4zl&T^gV8ZaG(RBD!`3?9xcK zp2+aD(T%QIgrLx5au&TjG1AazI;`8m{K7^!@m>uGCSR;Ut{&?t%3AsF{>0Cm(Kf)2 z?4?|J+!BUg*P~C{?mwPQ#)gDMmro20YVNsVx5oWQMkzQ? zsQ%Y>%7_wkJqnSMuZjB9lBM(o zWut|B7w48cn}4buUBbdPBW_J@H7g=szrKEpb|aE>!4rLm+sO9K%iI75y~2HkUo^iw zJ3se$8$|W>3}?JU@3h@M^HEFNmvCp|+$-0M?RQ8SMoZ@38%!tz8f8-Ptb@106heiJ z^Bx!`0=Im z1!NUhO=9ICM*+||b3a7w*Y#5*Q}K^ar+oMMtekF0JnO>hzHqZKH0&PZ^^M(j;vwf_ z@^|VMBpcw8;4E-9J{(u7sHSyZpQbS&N{VQ%ZCh{c1UA5;?R} z+52*X_tkDQ(s~#-6`z4|Y}3N#a&dgP4S_^tsV=oZr4A1 zaSoPN1czE(UIBrC_r$0HM?RyBGe#lTBL4~JW#A`P^#0wuK)C-2$B6TvMi@@%K@JAT_IB^T7Zfqc8?{wHcSVG_?{(wUG%zhCm=%qP~EqeqKI$9UivF zv+5IUOs|%@ypo6b+i=xsZ=^G1yeWe)z6IX-EC`F=(|_GCNbHbNp(CZ*lpSu5n`FRA zhnrc4w+Vh?r>her@Ba_jv0Omp#-H7avZb=j_A~B%V0&FNi#!S8cwn0(Gg-Gi_LMI{ zCg=g@m{W@u?GQ|yp^yENd;M=W2s-k7Gw2Z(tsD5fTGF{iZ%Ccgjy6O!AB4x z%&=6jB7^}pyftW2YQpOY1w@%wZy%}-l0qJlOSKZXnN2wo3|hujU+-U~blRF!^;Tan z0w;Srh0|Q~6*tXf!5-rCD)OYE(%S|^WTpa1KHtpHZ{!;KdcM^#g8Z^+LkbiBHt85m z;2xv#83lWB(kplfgqv@ZNDcHizwi4-8+WHA$U-HBNqsZ`hKcUI3zV3d1ngJP-AMRET*A{> zb2A>Fk|L|WYV;Eu4>{a6ESi2r3aZL7x}eRc?cf|~bP)6b7%BnsR{Sa>K^0obn?yiJ zCVvaZ&;d_6WEk${F1SN0{_`(#TuOOH1as&#&xN~+JDzX(D-WU_nLEI}T_VaeLA=bc zl_UZS$nu#C1yH}YV>N2^9^zye{rDrn(rS99>Fh&jtNY7PP15q%g=RGnxACdCov47= zwf^9zfJaL{y`R#~tvVL#*<`=`Qe zj_@Me$6sIK=LMFbBrJps7vdaf_HeX?eC+P^{AgSvbEn?n<}NDWiQGQG4^ZOc|GskK z$Ve2_n8gQ-KZ=s(f`_X!+vM5)4+QmOP()2Fe#IL2toZBf+)8gTVgDSTN1CkP<}!j7 z0SEl>PBg{MnPHkj4wj$mZ?m5x!1ePVEYI(L_sb0OZ*=M%yQb?L{UL(2_*CTVbRxBe z@{)COwTK1}!*CK0Vi4~AB;HF(MmQf|dsoy(eiQ>WTKcEQlnKOri5xYsqi61Y=I4kzAjn5~{IWrz_l))|Ls zvq7xgQs?Xx@`N?f7+3XKLyD~6DRJw*uj*j?yvT3}a;(j_?YOe%hUFcPGWRVBXzpMJ zM43g6DLFqS9tcTLSg=^&N-y0dXL816v&-nqC0iXdg7kV|PY+js`F8dm z2PuHw&k+8*&9SPQ6f!^5q0&AH(i+z3I7a?8O+S5`g)>}fG|BM&ZnmL;rk)|u{1!aZ zEZHpAMmK_v$GbrrWNP|^2^s*!0waLW=-h5PZa-4jWYUt(Hr@EA(m3Mc3^uDxwt-me^55FMA9^>hpp26MhqjLg#^Y7OIJ5%ZLdNx&uDgIIqc zZRZl|n6TyV)0^DDyVtw*jlWkDY&Gw4q;k!UwqSL6&sW$B*5Rc?&)dt29bDB*b6IBY z6SY6Unsf6AOQdEf=P1inu6(6hVZ0~v-<>;LAlcQ2u?wRWj5VczBT$Op#8IhppP-1t zfz5H59Aa~yh7EN;BXJsLyjkjqARS5iIhDVPj<=4AJb}m6M@n{xYj3qsR*Q8;hVxDyC4vLI;;?^eENOb5QARj#nII5l$MtBCI@5u~(ylFi$ zw6-+$$XQ}Ca>FWT>q{k)g{Ml(Yv=6aDfe?m|5|kbGtWS}fKWI+})F6`x@||0oJ^(g|+xi zqlPdy5;`g*i*C=Q(aGeDw!eQg&w>UUj^{o?PrlFI=34qAU2u@BgwrBiaM8zoDTFJ< zh7nWpv>dr?q;4ZA?}V}|7qWz4W?6#S&m>hs4IwvCBe@-C>+oohsQZ^JC*RfDRm!?y zS4$7oxcI|##ga*y5hV>J4a%HHl^t$pjY%caL%-FlRb<$A$E!ws?8hf0@(4HdgQ!@> zds{&g$ocr9W4I84TMa9-(&^_B*&R%^=@?Ntxi|Ejnh;z=!|uVj&3fiTngDPg=0=P2 zB)3#%HetD84ayj??qrxsd9nqrBem(8^_u_UY{1@R_vK-0H9N7lBX5K(^O2=0#TtUUGSz{ z%g>qU8#a$DyZ~EMa|8*@`GOhCW3%DN%xuS91T7~iXRr)SG`%=Lfu%U~Z_`1b=lSi?qpD4$vLh$?HU6t0MydaowUpb zQr{>_${AMesCEffZo`}K0^~x>RY_ZIG{(r39MP>@=aiM@C;K)jUcfQV8#?SDvq>9D zI{XeKM%$$XP5`7p3K0T}x;qn)VMo>2t}Ib(6zui;k}<<~KibAb%p)**e>ln<=qyWU zrRDy|UXFi9y~PdEFIAXejLA{K)6<)Q`?;Q5!KsuEw({!#Rl8*5_F{TP?u|5(Hijv( ztAA^I5+$A*+*e0V0R~fc{ET-RAS3suZ}TRk3r)xqj~g_hxB`qIK5z(5wxYboz%46G zq{izIz^5xW1Vq#%lhXaZL&)FJWp0VZNO%2&ADd?+J%K$fM#T_Eke1{dQsx48dUPUY zLS+DWMJeUSjYL453f@HpRGU6Dv)rw+-c6xB>(=p4U%}_p>z^I@Ow9`nkUG21?cMIh9}hN?R-d)*6%pr6d@mcb*ixr7 z)>Lo<&2F}~>WT1ybm^9UO{6P9;m+fU^06_$o9gBWL9_}EMZFD=rLJ~&e?fhDnJNBI zKM=-WR6g7HY5tHf=V~6~QIQ~rakNvcsamU8m28YE=z8+G7K=h%)l6k zmCpiDInKL6*e#)#Pt;ANmjf`8h-nEt&d}(SBZMI_A{BI#ck-_V7nx)K9_D9K-p@?Zh81#b@{wS?wCcJ%og)8RF*-0z+~)6f#T` zWqF7_CBcnn=S-1QykC*F0YTsKMVG49BuKQBH%WuDkEy%E?*x&tt%0m>>5^HCOq|ux zuvFB)JPR-W|%$24eEC^AtG3Gp4qdK%pjRijF5Sg3X}uaKEE z-L5p5aVR!NTM8T`4|2QA@hXiLXRcJveWZ%YeFfV%mO5q#($TJ`*U>hicS+CMj%Ip# zivoL;dd*araeJK9EA<(tihD50FHWbITBgF9E<33A+eMr2;cgI3Gg6<-2o|_g9|> zv5}i932( zYfTE9?4#nQhP@a|zm#9FST2 z!y+p3B;p>KkUzH!K;GkBW}bWssz)9b>Ulg^)EDca;jDl+q=243BddS$hY^fC6lbpM z(q_bo4V8~eVeA?0LFD6ZtKcmOH^75#q$Eo%a&qvE8Zsqg=$p}u^|>DSWUP5i{6)LAYF4E2DfGZuMJ zMwxxmkxQf}Q$V3&2w|$`9_SQS^2NVbTHh;atB>=A%!}k-f4*i$X8m}Ni^ppZXk5_oYF>Gq(& z0wy{LjJOu}69}~#UFPc;$7ka+=gl(FZCy4xEsk);+he>Nnl>hb5Ud-lj!CNicgd^2 z_Qgr_-&S7*#nLAI7r()P$`x~fy)+y=W~6aNh_humoZr7MWGSWJPLk}$#w_1n%(@? z3FnHf1lbxKJbQ9c&i<$(wd{tUTX6DAKs@cXIOBv~!9i{wD@*|kwfX~sjKASrNFGvN zrFc=!0Bb^OhR2f`%hrp2ibv#KUxl)Np1aixD9{^o=)*U%n%rTHX?FSWL^UGpHpY@7 z74U}KoIRwxI#>)Pn4($A`nw1%-D}`sGRZD8Z#lF$6 zOeA5)+W2qvA%m^|$WluUU-O+KtMqd;Pd58?qZj})MbxYGO<{z9U&t4D{S2G>e+J9K ztFZ?}ya>SVOLp9hpW)}G%kTrg*KXXXsLkGdgHb+R-ZXqdkdQC0_)`?6mqo8(EU#d( zy;u&aVPe6C=YgCRPV!mJ6R6kdY*`e+VGM~`VtC>{k27!9vAZT)x2~AiX5|m1Rq}_= z;A9LX^nd$l-9&2%4s~p5r6ad-siV`HtxKF}l&xGSYJmP=z!?Mlwmwef$EQq~7;#OE z)U5eS6dB~~1pkj#9(}T3j!((8Uf%!W49FfUAozijoxInUE7z`~U3Y^}xc3xp){#9D z<^Tz2xw}@o@fdUZ@hnW#dX6gDOj4R8dV}Dw`u!h@*K)-NrxT8%2`T}EvOImNF_N1S zy?uo6_ZS>Qga4Xme3j#aX+1qdFFE{NT0Wfusa$^;eL5xGE_66!5_N8!Z~jCAH2=${ z*goHjl|z|kbmIE{cl-PloSTtD+2=CDm~ZHRgXJ8~1(g4W=1c3=2eF#3tah7ho`zm4 z05P&?nyqq$nC?iJ-nK_iBo=u5l#|Ka3H7{UZ&O`~t-=triw=SE7ynzMAE{Mv-{7E_ zViZtA(0^wD{iCCcg@c{54Ro@U5p1QZq_XlEGtdBAQ9@nT?(zLO0#)q55G8_Ug~Xnu zR-^1~hp|cy&52iogG@o?-^AD8Jb^;@&Ea5jEicDlze6%>?u$-eE};bQ`T6@(bED0J zKYtdc?%9*<<$2LCBzVx9CA4YV|q-qg*-{yQ;|0=KIgI6~z0DKTtajw2Oms3L zn{C%{P`duw!(F@*P)lFy11|Z&x`E2<=$Ln38>UR~z6~za(3r;45kQK_^QTX%!s zNzoIFFH8|Y>YVrUL5#mgA-Jh>j7)n)5}iVM4%_@^GSwEIBA2g-;43* z*)i7u*xc8jo2z8&=8t7qo|B-rsGw)b8UXnu`RgE4u!(J8yIJi(5m3~aYsADcfZ!GG zzqa7p=sg`V_KjiqI*LA-=T;uiNRB;BZZ)~88 z`C%p8%hIev2rxS12@doqsrjgMg3{A&N8A?%Ui5vSHh7!iC^ltF&HqG~;=16=h0{ygy^@HxixUb1XYcR36SB}}o3nxu z_IpEmGh_CK<+sUh@2zbK9MqO!S5cao=8LSQg0Zv4?ju%ww^mvc0WU$q@!oo#2bv24 z+?c}14L2vlDn%Y0!t*z=$*a!`*|uAVu&NO!z_arim$=btpUPR5XGCG0U3YU`v>yMr z^zmTdcEa!APX zYF>^Q-TP11;{VgtMqC}7>B^2gN-3KYl33gS-p%f!X<_Hr?`rG8{jb9jmuQA9U;BeG zHj6Pk(UB5c6zwX%SNi*Py*)gk^?+729$bAN-EUd*RKN7{CM4`Q65a1qF*-QWACA&m zrT)B(M}yih{2r!Tiv5Y&O&=H_OtaHUz96Npo_k0eN|!*s2mLe!Zkuv>^E8Xa43ZwH zOI058AZznYGrRJ+`*GmZzMi6yliFmGMge6^j?|PN%ARns!Eg$ufpcLc#1Ns!1@1 zvC7N8M$mRgnixwEtX{ypBS^n`k@t2cCh#_6L6WtQb8E~*Vu+Rr)YsKZRX~hzLG*BE zaeU#LPo?RLm(Wzltk79Jd1Y$|6aWz1)wf1K1RtqS;qyQMy@H@B805vQ%wfSJB?m&&=^m4i* zYVH`zTTFbFtNFkAI`Khe4e^CdGZw;O0 zqkQe2|NG_y6D%h(|EZNf&77_!NU%0y={^E=*gKGQ=)LdKPM3zUlM@otH2X07Awv8o zY8Y7a1^&Yy%b%m{mNQ5sWNMTIq96Wtr>a(hL>Qi&F(ckgKkyvM0IH<_}v~Fv-GqDapig=3*ZMOx!%cYY)SKzo7ECyem z9Mj3C)tCYM?C9YIlt1?zTJXNOo&oVxu&uXKJs7i+j8p*Qvu2PAnY}b`KStdpi`trk ztAO}T8eOC%x)mu+4ps8sYZ=vYJp16SVWEEgQyFKSfWQ@O5id6GfL`|2<}hMXLPszS zgK>NWOoR zBRyKeUPevpqKKShD|MZ`R;~#PdNMB3LWjqFKNvH9k+;(`;-pyXM55?qaji#nl~K8m z_MifoM*W*X9CQiXAOH{cZcP0;Bn10E1)T@62Um>et2ci!J2$5-_HPy(AGif+BJpJ^ ziHWynC_%-NlrFY+(f7HyVvbDIM$5ci_i3?22ZkF>Y8RPBhgx-7k3M2>6m5R24C|~I z&RPh9xpMGzhN4bii*ryWaN^d(`0 zTOADlU)g`1p+SVMNLztd)c+;XjXox(VHQwqzu>FROvf0`s&|NEv26}(TAe;@=FpZq zaVs6mp>W0rM3Qg*6x5f_bPJd!6dQGmh?&v0rpBNfS$DW-{4L7#_~-eA@7<2BsZV=X zow){3aATmLZOQrs>uzDkXOD=IiX;Ue*B(^4RF%H zeaZ^*MWn4tBDj(wj114r(`)P96EHq4th-;tWiHhkp2rDlrklX}I@ib-nel0slFoQO zOeTc;Rh7sMIebO`1%u)=GlEj+7HU;c|Nj>2j)J-kpR)s3#+9AiB zd$hAk6;3pu9(GCR#)#>aCGPYq%r&i02$0L9=7AlIGYdlUO5%eH&M!ZWD&6^NBAj0Y9ZDcPg@r@8Y&-}e!aq0S(`}NuQ({;aigCPnq75U9cBH&Y7 ze)W0aD>muAepOKgm7uPg3Dz7G%)nEqTUm_&^^3(>+eEI;$ia`m>m0QHEkTt^=cx^JsBC68#H(3zc~Z$E9I)oSrF$3 zUClHXhMBZ|^1ikm3nL$Z@v|JRhud*IhOvx!6X<(YSX(9LG#yYuZeB{=7-MyPF;?_8 zy2i3iVKG2q!=JHN>~!#Bl{cwa6-yB@b<;8LSj}`f9pw7#x3yTD>C=>1S@H)~(n_K4 z2-yr{2?|1b#lS`qG@+823j;&UE5|2+EdU4nVw5=m>o_gj#K>>(*t=xI7{R)lJhLU{ z4IO6!x@1f$aDVIE@1a0lraN9!(j~_uGlks)!&davUFRNYHflp<|ENwAxsp~4Hun$Q z$w>@YzXp#VX~)ZP8`_b_sTg(Gt7?oXJW%^Pf0UW%YM+OGjKS}X`yO~{7WH6nX8S6Z ztl!5AnM2Lo*_}ZLvo%?iV;D2z>#qdpMx*xY2*GGlRzmHCom`VedAoR=(A1nO)Y>;5 zCK-~a;#g5yDgf7_phlkM@)C8s!xOu)N2UnQhif-v5kL$*t=X}L9EyBRq$V(sI{90> z=ghTPGswRVbTW@dS2H|)QYTY&I$ljbpNPTc_T|FEJkSW7MV!JM4I(ksRqQ8)V5>}v z2Sf^Z9_v;dKSp_orZm09jb8;C(vzFFJgoYuWRc|Tt_&3k({wPKiD|*m!+za$(l*!gNRo{xtmqjy1=kGzFkTH=Nc>EL@1Um0BiN1)wBO$i z6rG={bRcT|%A3s3xh!Bw?=L&_-X+6}L9i~xRj2}-)7fsoq0|;;PS%mcn%_#oV#kAp zGw^23c8_0~ ze}v9(p};6HM0+qF5^^>BBEI3d=2DW&O#|(;wg}?3?uO=w+{*)+^l_-gE zSw8GV=4_%U4*OU^hibDV38{Qb7P#Y8zh@BM9pEM_o2FuFc2LWrW2jRRB<+IE)G=Vx zuu?cp2-`hgqlsn|$nx@I%TC!`>bX^G00_oKboOGGXLgyLKXoo$^@L7v;GWqfUFw3< zekKMWo0LR;TaFY}Tt4!O$3MU@pqcw!0w0 zA}SnJ6Lb597|P5W8$OsEHTku2Kw9y4V=hx*K%iSn!#LW9W#~OiWf^dXEP$^2 zaok=UyGwy3GRp)bm6Gqr>8-4h@3=2`Eto2|JE6Sufh?%U6;ut1v1d@#EfcQP2chCt z+mB{Bk5~()7G>wM3KYf7Xh?LGbwg1uWLotmc_}Z_o;XOUDyfU?{9atAT$={v82^w9 z(MW$gINHt4xB3{bdbhRR%T}L?McK?!zkLK3(e>zKyei(yq%Nsijm~LV|9mll-XHavFcc$teX7v);H>=oN-+E_Q{c|! zp

      JV~-9AH}jxf6IF!PxrB9is{_9s@PYth^`pb%DkwghLdAyDREz(csf9)HcVRq z+2Vn~>{(S&_;bq_qA{v7XbU?yR7;~JrLfo;g$Lkm#ufO1P`QW_`zWW+4+7xzQZnO$ z5&GyJs4-VGb5MEDBc5=zxZh9xEVoY(|2yRv&!T7LAlIs@tw+4n?v1T8M>;hBv}2n) zcqi+>M*U@uY>4N3eDSAH2Rg@dsl!1py>kO39GMP#qOHipL~*cCac2_vH^6x@xmO|E zkWeyvl@P$2Iy*mCgVF+b{&|FY*5Ygi8237i)9YW#Fp& z?TJTQW+7U)xCE*`Nsx^yaiJ0KSW}}jc-ub)8Z8x(|K7G>`&l{Y&~W=q#^4Gf{}aJ%6kLXsmv6cr=Hi*uB`V26;dr4C$WrPnHO>g zg1@A%DvIWPDtXzll39kY6#%j;aN7grYJP9AlJgs3FnC?crv$wC7S4_Z?<_s0j;MmE z75yQGul2=bY%`l__1X3jxju2$Ws%hNv75ywfAqjgFO7wFsFDOW^)q2%VIF~WhwEW0 z45z^+r+}sJ{q+>X-w(}OiD(!*&cy4X&yM`!L0Fe+_RUfs@=J{AH#K~gArqT=#DcGE z!FwY(h&+&811rVCVoOuK)Z<-$EX zp`TzcUQC256@YWZ*GkE@P_et4D@qpM92fWA6c$MV=^qTu7&g)U?O~-fUR&xFqNiY1 zRd=|zUs_rmFZhKI|H}dcKhy%Okl(#y#QuMi81zsY56Y@757xBQqDNkd+XhLQhp2BB zBF^aJ__D676wLu|yYo6jNJNw^B+Ce;DYK!f$!dNs1*?D^97u^jKS++7S z5qE%zG#HY-SMUn^_yru=T6v`)CM%K<>_Z>tPe|js`c<|y7?qol&)C=>uLWkg5 zmzNcSAG_sL)E9or;i+O}tY^70@h7+=bG1;YDlX{<4zF_?{)K5B&?^tKZ6<$SD%@>F zY0cl2H7)%zKeDX%Eo7`ky^mzS)s;842cP{_;dzFuyd~Npb4u!bwkkhf8-^C2e3`q8>MuPhgiv0VxHxvrN9_`rJv&GX0fWz-L-Jg^B zrTsm>)-~j0F1sV=^V?UUi{L2cp%YwpvHwwLaSsCIrGI#({{QfbgDxLKsUC6w@m?y} zg?l=7aMX-RnMxvLn_4oSB|9t;)Qf2%m-GKo_07?N1l^ahJ+Wf8C>h5~=-o1BJzV@5HBTB-ACNpsHnGt6_ku37M z{vIEB^tR=--4SEg{jfF=gEogtGwi&A$mwk7E+SV$$ZuU}#F3Y7t}o{!w4LJh8v4PW%8HfUK@dta#l*z@w*9Xzz(i)r#WXi`r1D#oBPtNM7M?Hkq zhhS1)ea5(6VY45|)tCTr*@yc$^Zc!zQzsNXU?aRN6mh7zVu~i=qTrX^>de+f6HYfDsW@6PBlw0CsDBcOWUmt&st>Z zYNJEsRCP1#g0+Htb=wITvexBY@fOpAmR7?szQNR~nM)?sPWIj)0)jG-EF8U@nnBaQZy z)ImpVYQL>lBejMDjlxA$#G4%y+^_>N;}r@Zoe2|u-9-x@vvD^ZWnV>Gm=pZa7REAf zOnomhCxBaGZgT+4kiE%aS&lH2sI1mSCM<%)Cr*Sli;#!aXcUb&@Z|Hj{VPsJyClqD%>hy`Y7z(GASs8Mqas3!D zSQE83*%uctlD|p%4)v`arra4y>yP5m25V*_+n)Ry1v>z_Fz!TV6t+N?x?#iH$q=m= z8&X{uW%LVRO87dVl=$Y*>dabJVq{o|Kx`7(D2$5DVX&}XGbg|Ua(*5b=;5qzW9;|w>m{hIO(Tu-z(ey8H=EMluJNyK4BJmGpX~ZM2O61 zk*O7js{-MBqwq>Urf0igN+6soGGc!Y?SP6hiXuJzZ1V4WZqE*?h;PG84gvG~dds6~484!kPM zMP87IP?dhdc;%|cS&LxY*Ib6P3%p|9)E3IgRmhhwtUR3eRK6iZ_6fiGW}jnL4(I|t ze`2yLvmuY42lNwO6>I#Son3$R4NOoP*WUm1R4jl#agtSLE}fSu-Z>{+*?pQIn7`s3LAzF#1pSxCAo?clr9 z9PUj#REq28*ZkJnxs$aK%8^5?P<_Q!#Z?%JH0FKVF;&zH3F#J^fz|ahl$Ycs~kFij_XP;U<`FcaDYyXYPM~&jEe1Xj1n;wyRdD;lmnq&FEro=;+Z$=v-&fYM9eK*S_D&oTXFW#b0 zRY}Y7R#bLzTfg9i7{s?=P9~qjA?$-U2p5;0?gPPu`1JY|*?*8IPO!eX>oiX=O#F!A zl`S%e5Y(csR1f)I(iKMf-;5%_rPP7h&}5Fc(8byKUH1*d7?9%QC|4aADj3L8yuo6GOv#%HDgU3bN(UHw1+(99&Om%f!DY(RYSf4&Uny% zH}*&rEXc$W5+eyeEg|I|E-HnkIO0!$1sV7Z&NXxiCZJ@`kH4eEi5}q~!Vv5qQq{MI zi4^`GYoUN-7Q(jy^SKXL4$G4K+FQXR)B}ee=pS0RyK=YC8c2bGnMA~rrOh&jd3_AT zxVaq37w^-;OU3+C`Kko-Z%l_2FC^maa=Ae0Fm@PEtXEg@cX*oka1Lt&h@jES<6?o1Oi1C9>}7+U(Ve zQ$=8RlzcnfCd59CsJ=gG^A!2Bb_PY~K2sSau{)?Ge03G7US&qrgV!3NUi>UHWZ*lo zS;~0--vn{ot+7UWMV{a(X3rZ8Z06Ps3$-sd|CWE(Y#l`swvcDbMjuReGsoA`rmZ`^ z=AaArdbeU0EtwnOuzq@u5P1rlZjH#gNgh6HIhG(>dX%4m{_!&DNTQE)8= zXD-vcpcSi|DSm3aUMnrV;DQY?svz?9*#GT$NXb~Hem=24iy>7xj367(!#RjnrHtrP-Q`T2W*PEvAR-=j ztY2|#<|JvHNVnM-tNdoS_yRSo=yFqukTZmB$|>Vclj)o=YzC9!ph8)ZOH5X=%Aq|9gNgc}^KFVLht!Lyw54v5u&D zW%vT%z`H{Ax>Ry+bD&QjHQke_wEA;oj(&E!s4|OURButQKSc7Ar-PzIiFa8F@ezkaY2J9&PH+VI1!G+{JgsQ7%da*_Gr!exT*OgJld)b-?cd)xI+|v_C`h(Cg`N~oj0`SQPTma z{@vc8L^D-rBXwS#00jT#@=-n1H-C3hvg61r2jx#ok&cr#BV~9JdPaVihyrGq*lb>bm$H6rIoc}ifaSn6mTD9% z$FRJxbNozOo6y}!OUci1VBv-7{TYZ4GkOM@46Y9?8%mSH9?l&lU59)T#Fjg(h%6I} z?ib zZ(xb8Rwr+vv>@$h{WglT2lL`#V=-9tP^c)cjvnz(g|VL^h8^CPVv12dE(o}WQ@0OP z^2-&ssBXP^#Oh`X5@F+~$PCB6kK-T7sFUK|>$lNDSkvAy%{y2qgq-&v zv}^&gm`wiYztWgMS<{^qQKYNV=>CQaOeglAY~EZvr}n~tW=yg)_+fzqF%~+*V_$3h z2hDW`e$qR;QMg?(wKE>%H_6ASS@6bkOi-m- zg6B7AzD;gBS1%OD7|47a%3BykN{w}P!Wn-nQOfpKUpx8Mk{$IO62D!%U9$kr!e%T> zlqQih?3(U&5%r!KZFZPdbwZ0laAJCj!c&pEFVzrH&_&i5m68Y_*J+-Qjlnz}Q{3oAD)`d14H zKUGmbwC|beC9Mtp>SbL~NVrlctU3WBpHz(UeIa~_{u^_4OaHs_LQt>bUwcyD`_Bbh zC=x|1vSjL)JvVHLw|xKynEvq2m)7O-6qdmjht7pZ*z|o%NA17v$9H*(5D5(MXiNo1 z72Tv}QASqr$!mY58s_Q{hHa9MY+QZ`2zX-FT@Kd?`8pczcV^9IeOKDG4WKqiP7N|S z+O977=VQTk8k5dafK`vd(4?_3pBdB?YG9*Z=R@y|$S+d%1sJf-Ka++I&v9hH)h#}} zw-MjQWJ?ME<7PR(G<1#*Z-&M?%=yzhQw$Lki(R+Pq$X~Q!9BO=fP9FyCIS8zE3n04 z8ScD%XmJnIv=pMTgt6VSxBXOZucndRE@7^aU0wefJYueY(Cb%?%0rz)zWEnsNsKhQ z+&o6d^x=R;Pt7fUa_`JVb1HPHYbXg{Jvux|atQ^bV#_|>7QZNC~P^IKUThB6{kvz2pr2*Cyxj zy37Nri8za8J!@Iw9rbt~#^<9zOaM8LOi$kPBcAGqPq-DB^-93Qeup{9@9&=zV6KQN zL)ic5S%n1!F(7b>MQ973$~<0|9MY-G!?wk?j-cQhMQlM2n{&7JoTBGsP;=fC6CBJn zxlpk^%x=B16rfb-W9pYV#9IRHQL9VG4?Uh>pN>2}0-MST2AB2pQjf*rT+TLCX-+&m z9I{ic2ogXoh=HwdI#igr(JC>>NUP|M>SA?-ux<2&>Jyx>Iko!B<3vS}{g*dKqxYW7 z0i`&U#*v)jot+keO#G&wowD!VvD(j`Z9a*-_RALKn0b(KnZ37d#Db7royLhBW~*7o zRa`=1fo9C4dgq;;R)JpP++a9^{xd)8``^fPW9!a%MCDYJc;3yicPs8IiQM>DhUX*; zeIrxE#JRrr|D$@bKgOm4C9D+e!_hQKj3LC`Js)|Aijx=J!rlgnpKeF>b+QlKhI^4* zf%Of^RmkW|xU|p#Lad44Y5LvIUIR>VGH8G zz7ZEIREG%UOy4)C!$muX6StM4@Fsh&Goa}cj10RL(#>oGtr6h~7tZDDQ_J>h)VmYlKK>9ns8w4tdx6LdN5xJQ9t-ABtTf_ zf1dKVv!mhhQFSN=ggf(#$)FtN-okyT&o6Ms+*u72Uf$5?4)78EErTECzweDUbbU)) zc*tt+9J~Pt%!M352Y5b`Mwrjn^Orp+)L_U1ORHJ}OUsB78YPcIRh4p5jzoDB7B*fb z4v`bouQeCAW#z9b1?4(M3dcwNn2F2plwC^RVHl#h&b-8n#5^o+Ll20OlJ^gOYiK2< z;MQuR!t!>`i}CAOa4a+Rh5IL|@kh4EdEL*O=3oGx4asg?XCTcUOQnmHs^6nLu6WcI zSt9q7nl*?2TIikKNb?3JZBo$cW6)b#;ZKzi+(~D-%0Ec+QW=bZZm@w|prGiThO3dy zU#TQ;RYQ+xU~*@Zj;Rf~z~iL8Da`RT!Z)b3ILBhnIl@VX9K0PSj5owH#*FJXX3vZ= zg_Zyn^G&l!WR6wN9GWvt)sM?g2^CA8&F#&t2z3_MiluRqvNbV{Me6yZ&X-_ zd6#Xdh%+6tCmSNTdCBusVkRwJ_A~<^Nd6~MNOvS;YDixM43`|8e_bmc*UWi7TLA})`T_F ztk&Nd=dgFUss#Ol$LXTRzP9l1JOSvAws~^X%(`ct$?2Im?UNpXjBec_-+8YK%rq#P zT9=h8&gCtgx?=Oj$Yr2jI3`VVuZ`lH>*N+*K11CD&>>F)?(`yr~54vHJftY*z?EorK zm`euBK<$(!XO%6-1=m>qqp6F`S@Pe3;pK5URT$8!Dd|;`eOWdmn916Ut5;iXWQoXE z0qtwxlH=m_NONP3EY2eW{Qwr-X1V3;5tV;g7tlL4BRilT#Y&~o_!f;*hWxWmvA;Pg zRb^Y$#PipnVlLXQIzKCuQP9IER0Ai4jZp+STb1Xq0w(nVn<3j(<#!vuc?7eJEZC<- zPhM7ObhgabN2`pm($tu^MaBkRLzx&jdh;>BP|^$TyD1UHt9Qvr{ZcBs^l!JI4~d-Py$P5QOYO&8eQOFe)&G zZm+?jOJioGs7MkkQBCzJSFJV6DiCav#kmdxc@IJ9j5m#&1)dhJt`y8{T!uxpBZ>&z zD^V~%GEaODak5qGj|@cA7HSH{#jHW;Q0KRdTp@PJO#Q1gGI=((a1o%X*{knz&_`ym zkRLikN^fQ%Gy1|~6%h^vx>ToJ(#aJDxoD8qyOD{CPbSvR*bC>Nm+mkw>6mD0mlD0X zGepCcS_x7+6X7dH;%e`aIfPr-NXSqlu&?$Br1R}3lSF2 zWOXDtG;v#EVLSQ!>4323VX-|E#qb+x%IxzUBDI~N23x? zXUHfTTV#_f9T$-2FPG@t)rpc9u9!@h^!4=fL^kg9 zVv%&KY3!?bU*V4X)wNT%Chr;YK()=~lc%$auOB_|oH`H)Xot@1cmk{^qdt&1C55>k zYnIkdoiAYW41zrRBfqR?9r^cpWIEqfS;|R#bIs4$cqA zoq~$yl8h{IXTSdSdH?;`ky6i%+Oc?HvwH+IS`%_a!d#CqQob9OTNIuhUnOQsX;nl_ z;1w99qO9lAb|guQ9?p4*9TmIZ5{su!h?v-jpOuShq!{AuHUYtmZ%brpgHl$BKLK_L z6q5vZodM$)RE^NNO>{ZWPb%Ce111V4wIX}?DHA=uzTu0$1h8zy!SID~m5t)(ov$!6 zB^@fP#vpx3enbrbX=vzol zj^Bg7V$Qa53#3Lptz<6Dz=!f+FvUBVIBtYPN{(%t(EcveSuxi3DI>XQ*$HX~O{KLK5Dh{H2ir87E^!(ye{9H&2U4kFxtKHkw zZPOTIa*29KbXx-U4hj&iH<9Z@0wh8B6+>qQJn{>F0mGnrj|0_{nwN}Vw_C!rm0!dC z>iRlEf}<+z&?Z4o3?C>QrLBhXP!MV0L#CgF{>;ydIBd5A{bd-S+VFn zLqq4a*HD%65IqQ5BxNz~vOGU=JJv|NG{OcW%2PU~MEfy6(bl#^TfT7+az5M-I`i&l z#g!HUfN}j#adA-21x7jbP6F;`99c8Qt|`_@u@fbhZF+Wkmr;IdVHj+F=pDb4MY?fU znDe##Hn){D}<>vVhYL#)+6p9eAT3T$?;-~bZU%l7MpPNh_mPc(h@79 z;LPOXk>e3nmIxl9lno5cI5G@Q!pE&hQ`s{$Ae4JhTebeTsj*|!6%0;g=wH?B1-p{P z`In#EP12q6=xXU)LiD+mLidPrYGHaKbe5%|vzApq9(PI6I5XjlGf<_uyy59iw8W;k zdLZ|8R8RWDc`#)n2?~}@5)vvksY9UaLW`FM=2s|vyg>Remm=QGthdNL87$nR&TKB*LB%*B}|HkG64 zZ|O4=Yq?Zwl>_KgIG@<8i{Zw#P3q_CVT7Dt zoMwoI)BkpQj8u(m!>1dfOwin(50}VNiLA>A2OG&TBXcP=H(3I;!WdPFe?r_e{%>bc6(Zk?6~Ew&;#ZxBJ| zAd1(sAHqlo_*rP;nTk)kAORe3cF&tj>m&LsvB)`-y9#$4XU=Dd^+CzvoAz%9216#f0cS`;kERxrtjbl^7pmO;_y zYBGOL7R1ne7%F9M2~0a7Srciz=MeaMU~ zV%Y#m_KV$XReYHtsraWLrdJItLtRiRo98T3J|x~(a>~)#>JHDJ z|4j!VO^qWQfCm9-$N29SpHUqvz62%#%98;2FNIF*?c9hZ7GAu$q>=0 zX_igPSK8Et(fmD)V=CvbtA-V(wS?z6WV|RX2`g=w=4D)+H|F_N(^ON!jHf72<2nCJ z^$hEygTAq7URR{Vq$)BsmFKTZ+i1i(D@SJuTGBN3W8{JpJ^J zkF=gBTz|P;Xxo1NIypGzJq8GK^#4tl)S%8$PP6E8c|GkkQ)vZ1OiB%mH#@hO1Z%Hp zv%2~Mlar^}7TRN-SscvQ*xVv+i1g8CwybQHCi3k;o$K@bmB%^-U8dILX)7b~#iPu@ z&D&W7YY2M3v`s(lNm2#^dCRFd;UYMUw1Rh2mto8laH1m`n0u;>okp5XmbsShOhQwo z@EYOehg-KNab)Rieib?m&NXls+&31)MB&H-zj_WmJsGjc1sCSOz0!2Cm1vV?y@kkQ z<1k6O$hvTQnGD*esux*aD3lEm$mUi0td0NiOtz3?7}h;Bt*vIC{tDBr@D)9rjhP^< zY*uKu^BiuSO%)&FL>C?Ng!HYZHLy`R>`rgq+lJhdXfo|df zmkzpQf{6o9%^|7Yb5v{Tu& zsP*Y~<#jK$S_}uEisRC;=y{zbq`4Owc@JyvB->nPzb#&vcMKi5n66PVV{Aub>*>q8 z=@u7jYA4Ziw2{fSED#t4QLD7Rt`au^y(Ggp3y(UcwIKtI(OMi@GHxs!bj$v~j(FZK zbdcP^gExtXQqQ8^Q#rHy1&W8q!@^aL>g1v2R45T(KErWB)1rB@rU`#n&-?g2Ti~xXCrexrLgajgzNy=N9|A6K=RZ zc3yk>w5sz1zsg~tO~-Ie?%Aplh#)l3`s632mi#CCl^75%i6IY;dzpuxu+2fliEjQn z&=~U+@fV4>{Fp=kk0oQIvBdqS#yY`Z+>Z|T&K{d;v3}=JqzKx05XU3M&@D5!uPTGydasyeZ5=1~IX-?HlM@AGB9|Mzb{{Dt@bUU8{KUPU@EX zv0fpQNvG~nD2WiOe{Vn=hE^rQD(5m+!$rs%s{w9;yg9oxRhqi0)rwsd245)igLmv* zJb@Xlet$+)oS1Ra#qTB@U|lix{Y4lGW-$5*4xOLY{9v9&RK<|K!fTd0wCKYZ)h&2f zEMcTCd+bj&YVmc#>&|?F!3?br3ChoMPTA{RH@NF(jmGMB2fMyW(<0jUT=8QFYD7-% zS0ydgp%;?W=>{V9>BOf=p$q5U511~Q0-|C!85)W0ov7eb35%XV;3mdUI@f5|x5C)R z$t?xLFZOv}A(ZjjSbF+8&%@RChpRvo>)sy>-IO8A@>i1A+8bZd^5J#(lgNH&A=V4V z*HUa0{zT{u-_FF$978RziwA@@*XkV{<-CE1N=Z!_!7;wq*xt3t((m+^$SZKaPim3K zO|Gq*w5r&7iqiQ!03SY{@*LKDkzhkHe*TzQaYAkz&jNxf^&A_-40(aGs53&}$dlKz zsel3=FvHqdeIf!UYwL&Mg3w_H?utbE_(PL9B|VAyaOo8k4qb>EvNYHrVmj^ocJQTf zL%4vl{qgmJf#@uWL@)WiB>Lm>?ivwB%uO|)i~;#--nFx4Kr6{TruZU0N_t_zqkg`? zwPFK|WiC4sI%o1H%$!1ANyq6_0OSPQJybh^vFriV=`S;kSsYkExZwB{68$dTODWJQ z@N57kBhwN(y~OHW_M}rX2W13cl@*i_tjW`TMfa~Y;I}1hzApXgWqag@(*@(|EMOg- z^qMk(s~dL#ps>>`oWZD=i1XI3(;gs7q#^Uj&L`gVu#4zn$i!BIHMoOZG!YoPO^=Gu z5`X-(KoSsHL77c<7^Y*IM2bI!dzg5j>;I@2-EeB$LgW|;csQTM&Z|R)q>yEjk@Sw% z6FQk*&zHWzcXalUJSoa&pgH24n`wKkg=2^ta$b1`(BBpBT2Ah9yQF&Kh+3jTaSE|=vChGz2_R^{$C;D`Ua(_=|OO11uLm;+3k%kO19EA`U065i;fRBoH z{Hq$cgHKRFPf0#%L?$*KeS@FDD;_TfJ#dwP7zzO5F>xntH(ONK{4)#jYUDQr6N(N< zp+fAS9l9)^c4Ss8628Zq5AzMq4zc(In_yJSXAT57Dtl}@= zvZoD7iq0cx7*#I{{r9m{%~g6@Hdr|*njKBb_5}mobCv=&X^`D9?;x6cHwRcwnlO^h zl;MiKr#LaoB*PELm8+8%btnC)b^E12!^ zMmVA!z>59e7n+^!P{PA?f9M^2FjKVw1%x~<`RY5FcXJE)AE}MTopGFDkyEjGiE|C6 z(ad%<3?v*?p;LJGopSEY18HPu2*}U!Nm|rfewc6(&y(&}B#j85d-5PeQ{}zg>>Rvl zDQ3H4E%q_P&kjuAQ>!0bqgAj){vzHpnn+h(AjQ6GO9v**l0|aCsCyXVE@uh?DU;Em zE*+7EU9tDH````D`|rM6WUlzBf1e{ht8$62#ilA6Dcw)qAzSRwu{czZJAcKv8w(Q6 zx)b$aq*=E=b5(UH-5*u)3iFlD;XQyklZrwHy}+=h6=aKtTriguHP@Inf+H@q32_LL z2tX|+X}4dMYB;*EW9~^5bydv)_!<%q#%Ocyh=1>FwL{rtZ?#2Scp{Q55%Fd-LgLU$ zM2u#|F{%vi%+O2^~uK3)?$6>9cc7_}F zWU72eFrzZ~x3ZIBH;~EMtD%51o*bnW;&QuzwWd$ds=O>Ev807cu%>Ac^ZK&7bCN;Ftk#eeQL4pG0p!W{Ri@tGw>nhIo`rC zi!Z6?70nYrNf92V{Y_i(a4DG=5>RktP=?%GcHEx?aKN$@{w{uj#Cqev$bXefo?yC6KI%Rol z%~$974WCymg;BBhd9Mv}_MeNro_8IB4!evgo*je4h?B-CAkEW-Wr-Q_V9~ef(znU& z{f-OHnj>@lZH(EcUb2TpOkc70@1BPiY0B#++1EPY5|UU?&^Vpw|C`k4ZWiB-3oAQM zgmG%M`2qDw5BMY|tG++34My2fE|^kvMSp(d+~P(Vk*d+RW1833i_bX^RYbg9tDtX` zox?y^YYfs-#fX|y7i(FN7js)66jN!`p9^r7oildEU#6J1(415H3h>W*p(p9@dI|c7 z&c*Aqzksg}o`D@i+o@WIw&jjvL!(`)JglV5zwMn)praO2M05H&CDeps0Wq8(8AkuE zPm|8MB6f0kOzg(gw}k>rzhQyo#<#sVdht~Wdk`y`=%0!jbd1&>Kxed8lS{Xq?Zw>* zU5;dM1tt``JH+A9@>H%-9f=EnW)UkRJe0+e^iqm0C5Z5?iEn#lbp}Xso ztleC}hl&*yPFcoCZ@sgvvjBA_Ew6msFml$cfLQY_(=h03WS_z+Leeh$M3#-?f9YT^Q($z z+pgaEv$rIa*9wST`WHASQio=9IaVS7l<87%;83~X*`{BX#@>>p=k`@FYo ze!K5_h8hOc`m0mK0p}LxsguM}w=9vw6Ku8y@RNrXSRPh&S`t4UQY=e-B8~3YCt1Fc zU$CtRW%hbcy{6K{>v0F*X<`rXVM3a{!muAeG$zBf`a(^l${EA9w3>J{aPwJT?mKVN2ba+v)Mp*~gQ_+Ws6= zy@D?85!U@VY0z9T=E9LMbe$?7_KIg)-R$tD)9NqIt84fb{B;f7C)n+B8)Cvo*F0t! zva6LeeC}AK4gL#d#N_HvvD& z0;mdU3@7%d5>h(xX-NBmJAOChtb(pX-qUtRLF5f$ z`X?Kpu?ENMc88>O&ym_$Jc7LZ> z#73|xJ|aa@l}PawS4Mpt9n)38w#q^P1w2N|rYKdcG;nb!_nHMZA_09L!j)pBK~e+j?tb-_A`wF8 zIyh>&%v=|n?+~h}%i1#^9UqZ?E9W!qJ0d0EHmioSt@%v7FzF`eM$X==#oaPESHBm@ zYzTXVo*y|C0~l_)|NF|F(If~YWJVkQAEMf5IbH{}#>PZpbXZU;+b^P8LWmlmDJ%Zu)4CajvRL!g_Faph`g0hpA2)D0|h zYy0h5+@4T81(s0D=crojdj|dYa{Y=<2zKp@xl&{sHO;#|!uTHtTey25f1U z#=Nyz{rJy#@SPk3_U|aALcg%vEjwIqSO$LZI59^;Mu~Swb53L+>oxWiN7J{;P*(2b@ao*aU~}-_j10 z@fQiaWnb}fRrHhNKrxKmi{aC#34BRP(a#0K>-J8D+v_2!~(V-6J%M@L{s?fU5ChwFfqn)2$siOUKw z?SmIRlbE8ot5P^z0J&G+rQ5}H=JE{FNsg`^jab7g-c}o`s{JS{-#}CRdW@hO`HfEp z1eR0DsN! zt5xmsYt{Uu;ZM`CgW)VYk=!$}N;w+Ct$Wf!*Z-7}@pA62F^1e$Ojz9O5H;TyT&rV( zr#IBM8te~-2t2;kv2xm&z%tt3pyt|s#vg2EOx1XkfsB*RM;D>ab$W-D6#Jdf zJ3{yD;P4=pFNk2GL$g~+5x;f9m*U2!ovWMK^U5`mAgBRhGpu)e`?#4vsE1aofu)iT zDm;aQIK6pNd8MMt@}h|t9c$)FT7PLDvu3e)y`otVe1SU4U=o@d!gn(DB9kC>Ac1wJ z?`{Hq$Q!rGb9h&VL#z+BKsLciCttdLJe9EmZF)J)c1MdVCrxg~EM80_b3k{ur=jVjrVhDK1GTjd3&t#ORvC0Q_&m|n>&TF1C_>k^8&ylR7oz#rG?mE%V| zepj0BlD|o?p8~LK_to`GINhGyW{{jZ{xqaO*SPvH)BYy1eH22DL_Kkn28N!0z3fzj z_+xZ3{ph_Tgkd)D$OjREak$O{F~mODA_D`5VsoobVnpxI zV0F_79%JB!?@jPs=cY73FhGuT!?fpVX1W=Wm zK5}i7(Pfh4o|Z{Ur=Y>bM1BDo2OdXBB(4Y#Z!61A8C6;7`6v-(P{ou1mAETEV?Nt< zMY&?ucJcJ$NyK0Zf@b;U#3ad?#dp`>zmNn=H1&-H`Y+)ai-TfyZJX@O&nRB*7j$ zDQF!q#a7VHL3z#Hc?Ca!MRbgL`daF zW#;L$yiQP|5VvgvRLluk3>-1cS+7MQ1)DC&DpYyS9j;!Rt$HdXK1}tG3G_)ZwXvGH zG;PB^f@CFrbEK4>3gTVj73~Tny+~k_pEHt|^eLw{?6NbG&`Ng9diB9XsMr(ztNC!{FhW8Hi!)TI`(Q|F*b z-z;#*c1T~kN67omP(l7)ZuTlxaC_XI(K8$VPfAzj?R**AMb0*p@$^PsN!LB@RYQ4U zA^xYY9sX4+;7gY%$i%ddfvneGfzbE4ZTJT5Vk3&1`?ULTy28&D#A&{dr5ZlZH&NTz zdfZr%Rw*Ukmgu@$C5$}QLOyb|PMA5syQns?iN@F|VFEvFPK321mTW^uv?GGNH6rnM zR9a2vB`}Y++T3Wumy$6`W)_c0PS*L;;0J^(T7<)`s{}lZVp`e)fM^?{$ zLbNw>N&6aw5Hlf_M)h8=)x0$*)V-w-Pw5Kh+EY{^$?#{v)_Y{9p5K{DjLnJ(ZUcyk*y(6D8wHB8=>Y)fb_Pw0v)Xybk`Sw@hNEaHP$-n`DtYP ziJyiauEXtuMpWyQjg$gdJR?e+=8w+=5GO-OT8pRaVFP1k^vI|I&agGjN-O*bJEK!M z`kt^POhUexh+PA&@And|vk-*MirW?>qB(f%y{ux z*d44UXxQOs+C`e-x4KSWhPg-!gO~kavIL8X3?!Ac2ih-dkK~Ua2qlcs1b-AIWg*8u z0QvL~51vS$LnmJSOnV4JUCUzg&4;bSsR5r_=FD@y|)Y2R_--e zMWJ;~*r=vJssF5_*n?wF0DO_>Mja=g+HvT=Yd^uBU|aw zRixHUQJX0Pgt-nFV+8&|;-n>!jNUj!8Y_YzH*%M!-_uWt6& z|Ec+lAD``i^do;u_?<(RpzsYZVJ8~}|NjUFgXltofbjhf!v&208g^#0h-x?`z8cInq!9kfVwJ|HQ;VK>p_-fn@(3q?e51Keq(=U-7C0#as-q z8Or}Ps07>O2@AAXz_%3bTOh{tKm#uRe}Sqr=w6-Wz$FCdfF3qNabEaj`-OfipxaL- zPh2R*l&%ZbcV?lv4C3+t2DAVSFaRo20^W_n4|0t(_*`?KmmUHG2sNZ*CRZlCFIyZbJqLdBCj)~%if)g|4NJr(8!R!E0iBbm$;`m;1n2@(8*E%B zH!g{hK|WK?1jUfM9zX?hlV#l%!6^p$$P+~rg}OdKg|d^Ed4WTY1$1J@WWHr$Os_(L z;-Zu1FJqhR4LrCUl)C~E7gA!^wtA6YIh10In9rX@LGSjnTPtLp+gPGp6u z3}{?J1!yT~?FwqT;O_-1%37f#4ek&DL){N}MX3RbNfRb-T;U^wXhx#De&QssA$lu~ mWkA_K7-+yz9tH*t6hj_Qg(_m7JaeTomk=)l!_+yTk^le-`GmOu delta 34176 zcmX7vV`H6d(}mmEwr$(CZQE$vU^m*aZQE(=WXEZ2+l}qF_w)XN>&rEBu9;)4>7EB0 zo(HR^Mh47P)@z^^pH!4#b(O8!;$>N+S+v5K5f8RrQ+Qv0_oH#e!pI2>yt4ij>fI9l zW&-hsVAQg%dpn3NRy$kb_vbM2sr`>bZ48b35m{D=OqX;p8A${^Dp|W&J5mXvUl#_I zN!~GCBUzj~C%K?<7+UZ_q|L)EGG#_*2Zzko-&Kck)Qd2%CpS3{P1co1?$|Sj1?E;PO z7alI9$X(MDly9AIEZ-vDLhpAKd1x4U#w$OvBtaA{fW9)iD#|AkMrsSaNz(69;h1iM1#_ z?u?O_aKa>vk=j;AR&*V-p3SY`CI}Uo%eRO(Dr-Te<99WQhi>y&l%UiS%W2m(d#woD zW?alFl75!1NiUzVqgqY98fSQNjhX3uZ&orB08Y*DFD;sjIddWoJF;S_@{Lx#SQk+9 zvSQ-620z0D7cy8-u_7u?PqYt?R0m2k%PWj%V(L|MCO(@3%l&pzEy7ijNv(VXU9byn z@6=4zL|qk*7!@QWd9imT9i%y}1#6+%w=s%WmsHbw@{UVc^?nL*GsnACaLnTbr9A>B zK)H-$tB`>jt9LSwaY+4!F1q(YO!E7@?SX3X-Ug4r($QrmJnM8m#;#LN`kE>?<{vbCZbhKOrMpux zTU=02hy${;n&ikcP8PqufhT9nJU>s;dyl;&~|Cs+o{9pCu{cRF+0{iyuH~6=tIZXVd zR~pJBC3Hf-g%Y|bhTuGyd~3-sm}kaX5=T?p$V?48h4{h2;_u{b}8s~Jar{39PnL7DsXpxcX#3zx@f9K zkkrw9s2*>)&=fLY{=xeIYVICff2Id5cc*~l7ztSsU@xuXYdV1(lLGZ5)?mXyIDf1- zA7j3P{C5s?$Y-kg60&XML*y93zrir8CNq*EMx)Kw)XA(N({9t-XAdX;rjxk`OF%4-0x?ne@LlBQMJe5+$Ir{Oj`@#qe+_-z!g5qQ2SxKQy1ex_x^Huj%u+S@EfEPP-70KeL@7@PBfadCUBt%`huTknOCj{ z;v?wZ2&wsL@-iBa(iFd)7duJTY8z-q5^HR-R9d*ex2m^A-~uCvz9B-1C$2xXL#>ow z!O<5&jhbM&@m=l_aW3F>vjJyy27gY}!9PSU3kITbrbs#Gm0gD?~Tub8ZFFK$X?pdv-%EeopaGB#$rDQHELW!8bVt`%?&>0 zrZUQ0!yP(uzVK?jWJ8^n915hO$v1SLV_&$-2y(iDIg}GDFRo!JzQF#gJoWu^UW0#? z*OC-SPMEY!LYY*OO95!sv{#-t!3Z!CfomqgzFJld>~CTFKGcr^sUai5s-y^vI5K={ z)cmQthQuKS07e8nLfaIYQ5f}PJQqcmokx?%yzFH*`%k}RyXCt1Chfv5KAeMWbq^2MNft;@`hMyhWg50(!jdAn;Jyx4Yt)^^DVCSu?xRu^$*&&=O6#JVShU_N3?D)|$5pyP8A!f)`| z>t0k&S66T*es5(_cs>0F=twYJUrQMqYa2HQvy)d+XW&rai?m;8nW9tL9Ivp9qi2-` zOQM<}D*g`28wJ54H~1U!+)vQh)(cpuf^&8uteU$G{9BUhOL| zBX{5E1**;hlc0ZAi(r@)IK{Y*ro_UL8Ztf8n{Xnwn=s=qH;fxkK+uL zY)0pvf6-iHfX+{F8&6LzG;&d%^5g`_&GEEx0GU=cJM*}RecV-AqHSK@{TMir1jaFf&R{@?|ieOUnmb?lQxCN!GnAqcii9$ z{a!Y{Vfz)xD!m2VfPH=`bk5m6dG{LfgtA4ITT?Sckn<92rt@pG+sk>3UhTQx9ywF3 z=$|RgTN<=6-B4+UbYWxfQUOe8cmEDY3QL$;mOw&X2;q9x9qNz3J97)3^jb zdlzkDYLKm^5?3IV>t3fdWwNpq3qY;hsj=pk9;P!wVmjP|6Dw^ez7_&DH9X33$T=Q{>Nl zv*a*QMM1-2XQ)O=3n@X+RO~S`N13QM81^ZzljPJIFBh%x<~No?@z_&LAl)ap!AflS zb{yFXU(Uw(dw%NR_l7%eN2VVX;^Ln{I1G+yPQr1AY+0MapBnJ3k1>Zdrw^3aUig*! z?xQe8C0LW;EDY(qe_P!Z#Q^jP3u$Z3hQpy^w7?jI;~XTz0ju$DQNc4LUyX}+S5zh> zGkB%~XU+L?3pw&j!i|x6C+RyP+_XYNm9`rtHpqxvoCdV_MXg847oHhYJqO+{t!xxdbsw4Ugn($Cwkm^+36&goy$vkaFs zrH6F29eMPXyoBha7X^b+N*a!>VZ<&Gf3eeE+Bgz7PB-6X7 z_%2M~{sTwC^iQVjH9#fVa3IO6E4b*S%M;#WhHa^L+=DP%arD_`eW5G0<9Tk=Ci?P@ z6tJXhej{ZWF=idj32x7dp{zmQY;;D2*11&-(~wifGXLmD6C-XR=K3c>S^_+x!3OuB z%D&!EOk;V4Sq6eQcE{UEDsPMtED*;qgcJU^UwLwjE-Ww54d73fQ`9Sv%^H>juEKmxN+*aD=0Q+ZFH1_J(*$~9&JyUJ6!>(Nj zi3Z6zWC%Yz0ZjX>thi~rH+lqv<9nkI3?Ghn7@!u3Ef){G(0Pvwnxc&(YeC=Kg2-7z zr>a^@b_QClXs?Obplq@Lq-l5>W);Y^JbCYk^n8G`8PzCH^rnY5Zk-AN6|7Pn=oF(H zxE#8LkI;;}K7I^UK55Z)c=zn7OX_XVgFlEGSO}~H^y|wd7piw*b1$kA!0*X*DQ~O` z*vFvc5Jy7(fFMRq>XA8Tq`E>EF35{?(_;yAdbO8rrmrlb&LceV%;U3haVV}Koh9C| zTZnR0a(*yN^Hp9u*h+eAdn)d}vPCo3k?GCz1w>OOeme(Mbo*A7)*nEmmUt?eN_vA; z=~2}K_}BtDXJM-y5fn^v>QQo+%*FdZQFNz^j&rYhmZHgDA-TH47#Wjn_@iH4?6R{J z%+C8LYIy>{3~A@|y4kN8YZZp72F8F@dOZWp>N0-DyVb4UQd_t^`P)zsCoygL_>>x| z2Hyu7;n(4G&?wCB4YVUIVg0K!CALjRsb}&4aLS|}0t`C}orYqhFe7N~h9XQ_bIW*f zGlDCIE`&wwyFX1U>}g#P0xRRn2q9%FPRfm{-M7;}6cS(V6;kn@6!$y06lO>8AE_!O z{|W{HEAbI0eD$z9tQvWth7y>qpTKQ0$EDsJkQxAaV2+gE28Al8W%t`Pbh zPl#%_S@a^6Y;lH6BfUfZNRKwS#x_keQ`;Rjg@qj zZRwQXZd-rWngbYC}r6X)VCJ-=D54A+81%(L*8?+&r7(wOxDSNn!t(U}!;5|sjq zc5yF5$V!;%C#T+T3*AD+A({T)#p$H_<$nDd#M)KOLbd*KoW~9E19BBd-UwBX1<0h9 z8lNI&7Z_r4bx;`%5&;ky+y7PD9F^;Qk{`J@z!jJKyJ|s@lY^y!r9p^75D)_TJ6S*T zLA7AA*m}Y|5~)-`cyB+lUE9CS_`iB;MM&0fX**f;$n($fQ1_Zo=u>|n~r$HvkOUK(gv_L&@DE0b4#ya{HN)8bNQMl9hCva zi~j0v&plRsp?_zR zA}uI4n;^_Ko5`N-HCw_1BMLd#OAmmIY#ol4M^UjLL-UAat+xA+zxrFqKc@V5Zqan_ z+LoVX-Ub2mT7Dk_ z<+_3?XWBEM84@J_F}FDe-hl@}x@v-s1AR{_YD!_fMgagH6s9uyi6pW3gdhauG>+H? zi<5^{dp*5-9v`|m*ceT&`Hqv77oBQ+Da!=?dDO&9jo;=JkzrQKx^o$RqAgzL{ zjK@n)JW~lzxB>(o(21ibI}i|r3e;17zTjdEl5c`Cn-KAlR7EPp84M@!8~CywES-`mxKJ@Dsf6B18_!XMIq$Q3rTDeIgJ3X zB1)voa#V{iY^ju>*Cdg&UCbx?d3UMArPRHZauE}c@Fdk;z85OcA&Th>ZN%}=VU%3b9={Q(@M4QaeuGE(BbZ{U z?WPDG+sjJSz1OYFpdImKYHUa@ELn%n&PR9&I7B$<-c3e|{tPH*u@hs)Ci>Z@5$M?lP(#d#QIz}~()P7mt`<2PT4oHH}R&#dIx4uq943D8gVbaa2&FygrSk3*whGr~Jn zR4QnS@83UZ_BUGw;?@T zo5jA#potERcBv+dd8V$xTh)COur`TQ^^Yb&cdBcesjHlA3O8SBeKrVj!-D3+_p6%P zP@e{|^-G-C(}g+=bAuAy8)wcS{$XB?I=|r=&=TvbqeyXiuG43RR>R72Ry7d6RS;n^ zO5J-QIc@)sz_l6%Lg5zA8cgNK^GK_b-Z+M{RLYk5=O|6c%!1u6YMm3jJg{TfS*L%2 zA<*7$@wgJ(M*gyTzz8+7{iRP_e~(CCbGB}FN-#`&1ntct@`5gB-u6oUp3#QDxyF8v zOjxr}pS{5RpK1l7+l(bC)0>M;%7L?@6t}S&a zx0gP8^sXi(g2_g8+8-1~hKO;9Nn%_S%9djd*;nCLadHpVx(S0tixw2{Q}vOPCWvZg zjYc6LQ~nIZ*b0m_uN~l{&2df2*ZmBU8dv`#o+^5p>D5l%9@(Y-g%`|$%nQ|SSRm0c zLZV)45DS8d#v(z6gj&6|ay@MP23leodS8-GWIMH8_YCScX#Xr)mbuvXqSHo*)cY9g z#Ea+NvHIA)@`L+)T|f$Etx;-vrE3;Gk^O@IN@1{lpg&XzU5Eh3!w;6l=Q$k|%7nj^ z|HGu}c59-Ilzu^w<93il$cRf@C(4Cr2S!!E&7#)GgUH@py?O;Vl&joXrep=2A|3Vn zH+e$Ctmdy3B^fh%12D$nQk^j|v=>_3JAdKPt2YVusbNW&CL?M*?`K1mK*!&-9Ecp~>V1w{EK(429OT>DJAV21fG z=XP=%m+0vV4LdIi#(~XpaUY$~fQ=xA#5?V%xGRr_|5WWV=uoG_Z&{fae)`2~u{6-p zG>E>8j({w7njU-5Lai|2HhDPntQ(X@yB z9l?NGoKB5N98fWrkdN3g8ox7Vic|gfTF~jIfXkm|9Yuu-p>v3d{5&hC+ZD%mh|_=* zD5v*u(SuLxzX~owH!mJQi%Z=ALvdjyt9U6baVY<88B>{HApAJ~>`buHVGQd%KUu(d z5#{NEKk6Vy08_8*E(?hqZe2L?P2$>!0~26N(rVzB9KbF&JQOIaU{SumX!TsYzR%wB z<5EgJXDJ=1L_SNCNZcBWBNeN+Y`)B%R(wEA?}Wi@mp(jcw9&^1EMSM58?68gwnXF` zzT0_7>)ep%6hid-*DZ42eU)tFcFz7@bo=<~CrLXpNDM}tv*-B(ZF`(9^RiM9W4xC%@ZHv=>w(&~$Wta%)Z;d!{J;e@z zX1Gkw^XrHOfYHR#hAU=G`v43E$Iq}*gwqm@-mPac0HOZ0 zVtfu7>CQYS_F@n6n#CGcC5R%4{+P4m7uVlg3axX}B(_kf((>W?EhIO&rQ{iUO$16X zv{Abj3ZApUrcar7Ck}B1%RvnR%uocMlKsRxV9Qqe^Y_5C$xQW@9QdCcF%W#!zj;!xWc+0#VQ*}u&rJ7)zc+{vpw+nV?{tdd&Xs`NV zKUp|dV98WbWl*_MoyzM0xv8tTNJChwifP!9WM^GD|Mkc75$F;j$K%Y8K@7?uJjq-w zz*|>EH5jH&oTKlIzueAN2926Uo1OryC|CmkyoQZABt#FtHz)QmQvSX35o`f z<^*5XXxexj+Q-a#2h4(?_*|!5Pjph@?Na8Z>K%AAjNr3T!7RN;7c)1SqAJfHY|xAV z1f;p%lSdE8I}E4~tRH(l*rK?OZ>mB4C{3e%E-bUng2ymerg8?M$rXC!D?3O}_mka? zm*Y~JMu+_F7O4T;#nFv)?Ru6 z92r|old*4ZB$*6M40B;V&2w->#>4DEu0;#vHSgXdEzm{+VS48 z7U1tVn#AnQ3z#gP26$!dmS5&JsXsrR>~rWA}%qd{92+j zu+wYAqrJYOA%WC9nZ>BKH&;9vMSW_59z5LtzS4Q@o5vcrWjg+28#&$*8SMYP z!l5=|p@x6YnmNq>23sQ(^du5K)TB&K8t{P`@T4J5cEFL@qwtsCmn~p>>*b=37y!kB zn6x{#KjM{S9O_otGQub*K)iIjtE2NfiV~zD2x{4r)IUD(Y8%r`n;#)ujIrl8Sa+L{ z>ixGoZJ1K@;wTUbRRFgnltN_U*^EOJS zRo4Y+S`cP}e-zNtdl^S5#%oN#HLjmq$W^(Y6=5tM#RBK-M14RO7X(8Gliy3+&9fO; zXn{60%0sWh1_g1Z2r0MuGwSGUE;l4TI*M!$5dm&v9pO7@KlW@j_QboeDd1k9!7S)jIwBza-V#1)(7ht|sjY}a19sO!T z2VEW7nB0!zP=Sx17-6S$r=A)MZikCjlQHE)%_Ka|OY4+jgGOw=I3CM`3ui^=o0p7u z?xujpg#dRVZCg|{%!^DvoR*~;QBH8ia6%4pOh<#t+e_u!8gjuk_Aic=|*H24Yq~Wup1dTRQs0nlZOy+30f16;f7EYh*^*i9hTZ`h`015%{i|4 z?$7qC3&kt#(jI#<76Biz=bl=k=&qyaH>foM#zA7}N`Ji~)-f-t&tR4^do)-5t?Hz_Q+X~S2bZx{t+MEjwy3kGfbv(ij^@;=?H_^FIIu*HP_7mpV)NS{MY-Rr7&rvWo@Wd~{Lt!8|66rq`GdGu% z@<(<7bYcZKCt%_RmTpAjx=TNvdh+ZiLkMN+hT;=tC?%vQQGc7WrCPIYZwYTW`;x|N zrlEz1yf95FiloUU^(onr3A3>+96;;6aL?($@!JwiQ2hO|^i)b4pCJ7-y&a~B#J`#FO!3uBp{5GBvM2U@K85&o0q~6#LtppE&cVY z3Bv{xQ-;i}LN-60B2*1suMd=Fi%Y|7@52axZ|b=Wiwk^5eg{9X4}(q%4D5N5_Gm)` zg~VyFCwfkIKW(@@ZGAlTra6CO$RA_b*yz#){B82N7AYpQ9)sLQfhOAOMUV7$0|d$=_y&jl>va$3u-H z_+H*|UXBPLe%N2Ukwu1*)kt!$Y>(IH3`YbEt; znb1uB*{UgwG{pQnh>h@vyCE!6B~!k}NxEai#iY{$!_w54s5!6jG9%pr=S~3Km^EEA z)sCnnau+ZY)(}IK#(3jGGADw8V7#v~<&y5cF=5_Ypkrs3&7{}%(4KM7) zuSHVqo~g#1kzNwXc39%hL8atpa1Wd#V^uL=W^&E)fvGivt)B!M)?)Y#Ze&zU6O_I?1wj)*M;b*dE zqlcwgX#eVuZj2GKgBu@QB(#LHMd`qk<08i$hG1@g1;zD*#(9PHjVWl*5!;ER{Q#A9 zyQ%fu<$U?dOW=&_#~{nrq{RRyD8upRi}c-m!n)DZw9P>WGs>o1vefI}ujt_`O@l#Z z%xnOt4&e}LlM1-0*dd?|EvrAO-$fX8i{aTP^2wsmSDd!Xc9DxJB=x1}6|yM~QQPbl z0xrJcQNtWHgt*MdGmtj%x6SWYd?uGnrx4{m{6A9bYx`m z$*UAs@9?3s;@Jl19%$!3TxPlCkawEk12FADYJClt0N@O@Pxxhj+Kk(1jK~laR0*KGAc7%C4nI^v2NShTc4#?!p{0@p0T#HSIRndH;#Ts0YECtlSR}~{Uck+keoJq6iH)(Zc~C!fBe2~4(Wd> zR<4I1zMeW$<0xww(@09!l?;oDiq zk8qjS9Lxv$<5m#j(?4VLDgLz;8b$B%XO|9i7^1M;V{aGC#JT)c+L=BgCfO5k>CTlI zOlf~DzcopV29Dajzt*OcYvaUH{UJPaD$;spv%>{y8goE+bDD$~HQbON>W*~JD`;`- zZEcCPSdlCvANe z=?|+e{6AW$f(H;BND>uy1MvQ`pri>SafK5bK!YAE>0URAW9RS8#LWUHBOc&BNQ9T+ zJpg~Eky!u!9WBk)!$Z?!^3M~o_VPERYnk1NmzVYaGH;1h+;st==-;jzF~2LTn+x*k zvywHZg7~=aiJe=OhS@U>1fYGvT1+jsAaiaM;) zay2xsMKhO+FIeK?|K{G4SJOEt*eX?!>K8jpsZWW8c!X|JR#v(1+Ey5NM^TB1n|_40 z@Db2gH}PNT+3YEyqXP8U@)`E|Xat<{K5K;eK7O0yV72m|b!o43!e-!P>iW>7-9HN7 zmmc7)JX0^lPzF#>$#D~nU^3f!~Q zQWly&oZEb1847&czU;dg?=dS>z3lJkADL1innNtE(f?~OxM`%A_PBp?Lj;zDDomf$ z;|P=FTmqX|!sHO6uIfCmh4Fbgw@`DOn#`qAPEsYUiBvUlw zevH{)YWQu>FPXU$%1!h*2rtk_J}qNkkq+StX8Wc*KgG$yH#p-kcD&)%>)Yctb^JDB zJe>=!)5nc~?6hrE_3n^_BE<^;2{}&Z>Dr)bX>H{?kK{@R)`R5lnlO6yU&UmWy=d03 z*(jJIwU3l0HRW1PvReOb|MyZT^700rg8eFp#p<3Et%9msiCxR+jefK%x81+iN0=hG z;<`^RUVU+S)Iv-*5y^MqD@=cp{_cP4`s=z)Ti3!Bf@zCmfpZTwf|>|0t^E8R^s`ad z5~tA?0x7OM{*D;zb6bvPu|F5XpF11`U5;b*$p zNAq7E6c=aUnq>}$JAYsO&=L^`M|DdSSp5O4LA{|tO5^8%Hf1lqqo)sj=!aLNKn9(3 zvKk($N`p`f&u+8e^Z-?uc2GZ_6-HDQs@l%+pWh!|S9+y3!jrr3V%cr{FNe&U6(tYs zLto$0D+2}K_9kuxgFSeQ!EOXjJtZ$Pyl_|$mPQ9#fES=Sw8L% zO7Jij9cscU)@W+$jeGpx&vWP9ZN3fLDTp zaYM$gJD8ccf&g>n?a56X=y zec%nLN`(dVCpSl9&pJLf2BN;cR5F0Nn{(LjGe7RjFe7efp3R_2JmHOY#nWEc2TMhMSj5tBf-L zlxP3sV`!?@!mRnDTac{35I7h@WTfRjRiFw*Q*aD8)n)jdkJC@)jD-&mzAdK6Kqdct8P}~dqixq;n zjnX!pb^;5*Rr?5ycT7>AB9)RED^x+DVDmIbHKjcDv2lHK;apZOc=O@`4nJ;k|iikKk66v4{zN#lmSn$lh z_-Y3FC)iV$rFJH!#mNqWHF-DtSNbI)84+VLDWg$ph_tkKn_6+M1RZ!)EKaRhY={el zG-i@H!fvpH&4~$5Q+zHU(Ub=;Lzcrc3;4Cqqbr$O`c5M#UMtslK$3r+Cuz>xKl+xW?`t2o=q`1djXC=Q6`3C${*>dm~I{ z(aQH&Qd{{X+&+-4{epSL;q%n$)NOQ7kM}ea9bA++*F+t$2$%F!U!U}(&y7Sd0jQMV zkOhuJ$+g7^kb<`jqFiq(y1-~JjP13J&uB=hfjH5yAArMZx?VzW1~>tln~d5pt$uWR~TM!lIg+D)prR zocU0N2}_WTYpU`@Bsi1z{$le`dO{-pHFQr{M}%iEkX@0fv!AGCTcB90@e|slf#unz z*w4Cf>(^XI64l|MmWih1g!kwMJiifdt4C<5BHtaS%Ra>~3IFwjdu;_v*7BL|fPu+c zNp687`{}e@|%)5g4U*i=0zlSWXzz=YcZ*&Bg zr$r(SH0V5a%oHh*t&0y%R8&jDI=6VTWS_kJ!^WN!ET@XfEHYG-T1jJsDd`yEgh!^* z+!P62=v`R2=TBVjt=h}|JIg7N^RevZuyxyS+jsk>=iLA52Ak+7L?2$ZDUaWdi1PgB z_;*Uae_n&7o27ewV*y(wwK~8~tU<#Np6UUIx}zW6fR&dKiPq|$A{BwG_-wVfkm+EP zxHU@m`im3cD#fH63>_X`Il-HjZN_hqOVMG;(#7RmI13D-s_>41l|vDH1BglPsNJ+p zTniY{Hwoief+h%C^|@Syep#722=wmcTR7awIzimAcye?@F~f|n<$%=rM+Jkz9m>PF70$)AK@|h_^(zn?!;={;9Zo7{ zBI7O?6!J2Ixxk;XzS~ScO9{K1U9swGvR_d+SkromF040|Slk%$)M;9O_8h0@WPe4= z%iWM^ust8w$(NhO)7*8uq+9CycO$3m-l}O70sBi<4=j0CeE_&3iRUWJkDM$FIfrkR zHG2|hVh3?Nt$fdI$W?<|Qq@#hjDijk@7eUr1&JHYI>(_Q4^3$+Zz&R)Z`WqhBIvjo zX#EbA8P0Qla-yACvt)%oAVHa#kZi3Y8|(IOp_Z6J-t{)98*OXQ#8^>vTENsV@(M}^ z(>8BXw`{+)BfyZB!&85hT0!$>7$uLgp9hP9M7v=5@H`atsri1^{1VDxDqizj46-2^ z?&eA9udH#BD|QY2B7Zr$l;NJ-$L!u8G{MZoX)~bua5J=0p_JnM`$(D4S!uF}4smWq zVo%kQ~C~X?cWCH zo4s#FqJ)k|D{c_ok+sZ8`m2#-Uk8*o)io`B+WTD0PDA!G`DjtibftJXhPVjLZj~g& z=MM9nF$7}xvILx}BhM;J-Xnz0=^m1N2`Mhn6@ct+-!ijIcgi6FZ*oIPH(tGYJ2EQ0 z{;cjcc>_GkAlWEZ2zZLA_oa-(vYBp7XLPbHCBcGH$K9AK6nx}}ya%QB2=r$A;11*~ z_wfru1SkIQ0&QUqd)%eAY^FL!G;t@7-prQ|drDn#yDf%Uz8&kGtrPxKv?*TqkC(}g zUx10<;3Vhnx{gpWXM8H zKc0kkM~gIAts$E!X-?3DWG&^knj4h(q5(L;V81VWyC@_71oIpXfsb0S(^Js#N_0E} zJ%|XX&EeVPyu}? zz~(%slTw+tcY3ZMG$+diC8zed=CTN}1fB`RXD_v2;{evY z@MCG$l9Az+F()8*SqFyrg3jrN7k^x3?;A?L&>y{ZUi$T8!F7Dv8s}}4r9+Wo0h^m= zAob@CnJ;IR-{|_D;_w)? zcH@~&V^(}Ag}%A90);X2AhDj(-YB>$>GrW1F4C*1S5`u@N{T|;pYX1;E?gtBbPvS* zlv3r#rw2KCmLqX0kGT8&%#A6Sc(S>apOHtfn+UdYiN4qPawcL{Sb$>&I)Ie>Xs~ej z7)a=-92!sv-A{-7sqiG-ysG0k&beq6^nX1L!Fs$JU#fsV*CbsZqBQ|y z{)}zvtEwO%(&mIG|L?qs2Ou1rqTZHV@H+sm8Nth(+#dp0DW4VXG;;tCh`{BpY)THY z_10NNWpJuzCG%Q@#Aj>!v7Eq8eI6_JK3g2CsB2jz)2^bWiM{&U8clnV7<2?Qx5*k_ zl9B$P@LV7Sani>Xum{^yJ6uYxM4UHnw4zbPdM|PeppudXe}+OcX z!nr!xaUA|xYtA~jE|436iL&L={H3e}H`M1;2|pLG)Z~~Ug9X%_#D!DW>w}Es!D{=4 zxRPBf5UWm2{}D>Em;v43miQ~2{>%>O*`wA{7j;yh;*DV=C-bs;3p{AD;>VPcn>E;V zLgtw|Y{|Beo+_ABz`lofH+cdf33LjIf!RdcW~wWgmsE%2yCQGbst4TS_t%6nS8a+m zFEr<|9TQzQC@<(yNN9GR4S$H-SA?xiLIK2O2>*w-?cdzNPsG4D3&%$QOK{w)@Dk}W z|3_Z>U`XBu7j6Vc=es(tz}c7k4al1$cqDW4a~|xgE9zPX(C`IsN(QwNomzsBOHqjd zi{D|jYSv5 zC>6#uB~%#!!*?zXW`!yHWjbjwm!#eo3hm;>nJ!<`ZkJamE6i>>WqkoTpbm(~b%G_v z`t3Z#ERips;EoA_0c?r@WjEP|ulD+hue5r8946Sd0kuBD$A!=dxigTZn)u3>U;Y8l zX9j(R*(;;i&HrB&M|Xnitzf@><3#)aKy=bFCf5Hz@_);{nlL?J!U>%fL$Fk~Ocs3& zB@-Ek%W>h9#$QIYg07&lS_CG3d~LrygXclO!Ws-|PxMsn@n{?77wCaq?uj`dd7lllDCGd?ed&%5k{RqUhiN1u&?uz@Fq zNkv_4xmFcl?vs>;emR1R<$tg;*Ayp@rl=ik z=x2Hk zJqsM%++e|*+#camAiem6f;3-khtIgjYmNL0x|Mz|y{r{6<@_&a7^1XDyE>v*uo!qF zBq^I8PiF#w<-lFvFx9xKoi&0j)4LX~rWsK$%3hr@ebDv^($$T^4m4h#Q-(u*Mbt6F zE%y0Fvozv=WAaTj6EWZ)cX{|9=AZDvPQuq>2fUkU(!j1GmdgeYLX`B0BbGK(331ME zu3yZ3jQ@2)WW5!C#~y}=q5Av=_;+hNi!%gmY;}~~e!S&&^{4eJuNQ2kud%Olf8TRI zW-Dze987Il<^!hCO{AR5tLW{F1WLuZ>nhPjke@CSnN zzoW{m!+PSCb7byUf-1b;`{0GU^zg7b9c!7ueJF`>L;|akVzb&IzoLNNEfxp7b7xMN zKs9QG6v@t7X)yYN9}3d4>*ROMiK-Ig8(Do$3UI&E}z!vcH2t(VIk-cLyC-Y%`)~>Ce23A=dQsc<( ziy;8MmHki+5-(CR8$=lRt{(9B9W59Pz|z0^;`C!q<^PyE$KXt!KibFH*xcB9V%xTD zn;YlZ*tTukwr$(mWMka@|8CW-J8!zCXI{P1-&=wSvZf&%9SZ7m`1&2^nV#D z6T*)`Mz3wGUC69Fg0Xk!hwY}ykk!TE%mr57TLX*U4ygwvM^!#G`HYKLIN>gT;?mo% zAxGgzSnm{}vRG}K)8n(XjG#d+IyAFnozhk|uwiey(p@ zu>j#n4C|Mhtd=0G?Qn5OGh{{^MWR)V*geNY8d)py)@5a85G&_&OSCx4ASW8g&AEXa zC}^ET`eORgG*$$Q1L=9_8MCUO4Mr^1IA{^nsB$>#Bi(vN$l8+p(U^0dvN_{Cu-UUm zQyJc!8>RWp;C3*2dGp49QVW`CRR@no(t+D|@nl138lu@%c1VCy3|v4VoKZ4AwnnjF z__8f$usTzF)TQ$sQ^|#(M}-#0^3Ag%A0%5vA=KK$37I`RY({kF-z$(P50pf3_20YTr%G@w+bxE_V+Tt^YHgrlu$#wjp7igF!=o8e2rqCs|>XM9+M7~TqI&fcx z=pcX6_MQQ{TIR6a0*~xdgFvs<2!yaA1F*4IZgI!)xnzJCwsG&EElg_IpFbrT}nr)UQy}GiK;( zDlG$cksync34R3J^FqJ=={_y9x_pcd%$B*u&vr7^ItxqWFIAkJgaAQiA)pioK1JQ| zYB_6IUKc$UM*~f9{Xzw*tY$pUglV*?BDQuhsca*Fx!sm`9y`V&?lVTH%%1eJ74#D_ z7W+@8@7LAu{aq)sPys{MM~;`k>T%-wPA)E2QH7(Z4XEUrQ5YstG`Uf@w{n_Oc!wem z7=8z;k$N{T74B*zVyJI~4d60M09FYG`33;Wxh=^Ixhs69U_SG_deO~_OUO1s9K-8p z5{HmcXAaKqHrQ@(t?d@;63;Pnj2Kk<;Hx=kr>*Ko`F*l){%GVDj5nkohSU)B&5Vrc zo0u%|b%|VITSB)BXTRPQC=Bv=qplloSI#iKV#~z#t#q*jcS`3s&w-z^m--CYDI7n2 z%{LHFZ*(1u4DvhES|Dc*n%JL8%8?h7boNf|qxl8D)np@5t~VORwQn)TuSI07b-T=_ zo8qh+0yf|-6=x;Ra$w&WeVZhUO%3v6Ni*}i&sby3s_(?l5Er{K9%0_dE<`7^>8mLr zZ|~l#Bi@5}8{iZ$(d9)!`}@2~#sA~?uH|EbrJQcTw|ssG)MSJJIF96-_gf&* zy~I&$m6e0nnLz^M2;G|IeUk?s+afSZ){10*P~9W%RtYeSg{Nv5FG<2QaWpj?d`;}<4( z>V1i|wNTpH`jJtvTD0C3CTws410U9HS_%Ti2HaB~%^h6{+$@5`K9}T=eQL;dMZ?=Y zX^z?B3ZU_!E^OW%Z*-+t&B-(kLmDwikb9+F9bj;NFq-XHRB=+L)Rew{w|7p~7ph{#fRT}}K zWA)F7;kJBCk^aFILnkV^EMs=B~#qh*RG2&@F|x2$?7QTX_T6qL?i$c6J*-cNQC~E6dro zR)CGIoz;~V?=>;(NF4dihkz~Koqu}VNPE9^R{L@e6WkL{fK84H?C*uvKkO(!H-&y( zq|@B~juu*x#J_i3gBrS0*5U*%NDg+Ur9euL*5QaF^?-pxxieMM6k_xAP;S}sfKmIa zj(T6o{4RfARHz25YWzv=QaJ4P!O$LHE(L~6fB89$`6+olZR!#%y?_v+Cf+g)5#!ZM zkabT-y%v|ihYuV}Y%-B%pxL264?K%CXlbd_s<GY5BG*`kYQjao$QHiC_qPk5uE~AO+F=eOtTWJ1vm*cU(D5kvs3kity z$IYG{$L<8|&I>|WwpCWo5K3!On`)9PIx(uWAq>bSQTvSW`NqgprBIuV^V>C~?+d(w$ZXb39Vs`R=BX;4HISfN^qW!{4 z^amy@Nqw6oqqobiNlxzxU*z2>2Q;9$Cr{K;*&l!;Y??vi^)G|tefJG9utf|~4xh=r3UjmRlADyLC*i`r+m;$7?7*bL!oR4=yU<8<-3XVA z%sAb`xe&4RV(2vj+1*ktLs<&m~mGJ@RuJ)1c zLxZyjg~*PfOeAm8R>7e&#FXBsfU_?azU=uxBm=E6z7FSr7J>{XY z1qUT>dh`X(zHRML_H-7He^P_?148AkDqrb>;~1M-k+xHVy>;D7p!z=XBgxMGQX2{* z-xMCOwS33&K^~3%#k`eIjKWvNe1f3y#}U4;J+#-{;=Xne^6+eH@eGJK#i|`~dgV5S zdn%`RHBsC!=9Q=&=wNbV#pDv6rgl?k1wM03*mN`dQBT4K%uRoyoH{e=ZL5E*`~X|T zbKG9aWI}7NGTQtjc3BYDTY3LbkgBNSHG$5xVx8gc@dEuJqT~QPBD=Scf53#kZzZ6W zM^$vkvMx+-0$6R^{{hZ2qLju~e85Em>1nDcRN3-Mm7x;87W#@RSIW9G>TT6Q{4e~b z8DN%n83FvXWdpr|I_8TaMv~MCqq0TA{AXYO-(~l=ug42gpMUvOjG_pWSEdDJ2Bxqz z!em;9=7y3HW*XUtK+M^)fycd8A6Q@B<4biGAR)r%gQf>lWI%WmMbij;un)qhk$bff zQxb{&L;`-1uvaCE7Fm*83^0;!QA5-zeSvKY}WjbwE68)jqnOmj^CTBHaD zvK6}Mc$a39b~Y(AoS|$%ePoHgMjIIux?;*;=Y|3zyfo)^fM=1GBbn7NCuKSxp1J|z zC>n4!X_w*R8es1ofcPrD>%e=E*@^)7gc?+JC@mJAYsXP;10~gZv0!Egi~){3mjVzs z^PrgddFewu>Ax_G&tj-!L=TuRl0FAh#X0gtQE#~}(dSyPO=@7yd zNC6l_?zs_u5&x8O zQ|_JvKf!WHf43F0R%NQwGQi-Dy7~PGZ@KRKMp?kxlaLAV=X{UkKgaTu2!qzPi8aJ z-;n$}unR?%uzCkMHwb56T%IUV)h>qS(XiuRLh3fdlr!Cri|{fZf0x9GVYUOlsKgxLA7vHrkpQddcSsg4JfibzpB zwR!vYiL)7%u8JG7^x@^px(t-c_Xt|9Dm)C@_zGeW_3nMLZBA*9*!fLTV$Uf1a0rDt zJI@Z6pdB9J(a|&T_&AocM2WLNB;fpLnlOFtC9yE6cb39?*1@wy8UgruTtX?@=<6YW zF%82|(F7ANWQ`#HPyPqG6~ggFlhJW#R>%p@fzrpL^K)Kbwj(@#7s97r`)iJ{&-ToR z$7(mQI@~;lwY+8dSKP~0G|#sjL2lS0LQP3Oe=>#NZ|JKKYd6s6qwe#_6Xz_^L4PJ5TM_|#&~zy= zabr|kkr3Osj;bPz`B0s;c&kzzQ2C8|tC9tz;es~zr{hom8bT?t$c|t;M0t2F{xI;G z`0`ADc_nJSdT`#PYCWu4R0Rmbk#PARx(NBfdU>8wxzE(`jA}atMEsaG6zy8^^nCu| z9_tLj90r-&Xc~+p%1vyt>=q_hQsDYB&-hPj(-OGxFpesWm;A(Lh>UWy4SH9&+mB(A z2jkTQ2C&o(Q4wC_>|c()M8_kF?qKhNB+PW6__;U+?ZUoDp2GNr<|*j(CC*#v0{L2E zgVBw6|3c(~V4N*WgJsO(I3o>8)EO5;p7Xg8yU&%rZ3QSRB6Ig6MK7Wn5r+xo2V}fM z0QpfDB9^xJEi}W*Fv6>=p4%@eP`K5k%kCE0YF2Eu5L!DM1ZY7wh`kghC^NwxrL}90dRXjQx=H>8 zOWP@<+C!tcw8EL8aCt9{|4aT+x|70i6m*LP*lhp;kGr5f#OwRy`(60LK@rd=to5yk^%N z6MTSk)7)#!cGDV@pbQ>$N8i2rAD$f{8T{QM+|gaj^sBt%24UJGF4ufrG1_Ag$Rn?c zzICg9`ICT>9N_2vqvVG#_lf9IEd%G5gJ_!j)1X#d^KUJBkE9?|K03AEe zo>5Rql|WuUU=LhLRkd&0rH4#!!>sMg@4Wr=z2|}dpOa`4c;_DqN{3Pj`AgSnc;h%# z{ny1lK%7?@rwZO(ZACq#8mL)|vy8tO0d1^4l;^e?hU+zuH%-8Y^5YqM9}sRzr-XC0 zPzY1l($LC-yyy*1@eoEANoTLQAZ2lVto2r7$|?;PPQX`}rbxPDH-a$8ez@J#v0R5n z7P*qT3aHj02*cK)WzZmoXkw?e3XNu&DkElGZ0Nk~wBti%yLh+l2DYx&U1lD_NW_Yt zGN>yOF?u%ksMW?^+~2&p@NoPzk`T)8qifG_owD>@iwI3@u^Y;Mqaa!2DGUKi{?U3d z|Efe=CBc!_ZDoa~LzZr}%;J|I$dntN24m4|1(#&Tw0R}lP`a`?uT;>szf^0mDJx3u z6IJvpeOpS$OV!Xw21p>Xu~MZ(Nas5Iim-#QSLIYSNhYgx1V!AR>b zf5b7O`ITTvW5z%X8|7>&BeEs8~J1i47l;`7Y#MUMReQ4z!IL1rh8UauKNPG?7rV_;#Y zG*6Vrt^SsTMOpV7mkui}l_S8UNOBcYi+DzcMF>YKrs3*(q5fwVCr;_zO?gpGx*@%O zl`KOwYMSUs4e&}eM#FhB3(RIDJ9ZRn6NN{2Nf+ z2jcz%-u6IPq{n7N3wLH{9c+}4G(NyZa`UmDr5c-SPgj0Sy$VN#Vxxr;kF>-P;5k!w zuAdrP(H+v{Dybn78xM6^*Ym@UGxx?L)m}WY#R>6M2zXnPL_M9#h($ECz^+(4HmKN7 zA>E;`AEqouHJd7pegrq4zkk>kHh`TEb`^(_ea;v{?MW3Sr^FXegkqAQPM-h^)$#Jn z?bKbnXR@k~%*?q`TPL=sD8C+n^I#08(}d$H(@Y;3*{~nv4RLZLw`v=1M0-%j>CtT( zTp#U03GAv{RFAtj4vln4#E4eLOvt zs;=`m&{S@AJbcl1q^39VOtmN^Zm(*x(`(SUgF(=6#&^7oA8T_ojX>V5sJx@*cV|29 z)6_%P6}e}`58Sd;LY2cWv~w}fer&_c1&mlY0`YNNk9q=TRg@Khc5E$N`aYng=!afD z@ewAv^jl$`U5;q4OxFM4ab%X_Jv>V!98w$8ZN*`D-)0S7Y^6xW$pQ%g3_lEmW9Ef^ zGmFsQw`E!ATjDvy@%mdcqrD-uiKB}!)ZRwpZRmyu+x|RUXS+oQ*_jIZKAD~U=3B|t zz>9QQr91qJihg9j9rWHww{v@+SYBzCfc0kI=4Gr{ZLcC~mft^EkJ`CMl?8fZ z3G4ix71=2dQ`5QuTOYA0(}f`@`@U<#K?1TI(XO9c*()q!Hf}JUCaUmg#y?ffT9w1g zc)e=JcF-9J`hK{0##K#A>m^@ZFx!$g09WSBdc8O^IdP&JE@O{i0&G!Ztvt{L4q%x& zGE2s!RVi6ZN9)E*(c33HuMf7#X2*VPVThdmrVz-Fyqxcs&aI4DvP#bfW={h$9>K0HsBTUf z2&!G;( z^oOVIYJv~OM=-i`6=r4Z1*hC8Fcf3rI9?;a_rL*nr@zxwKNlxf(-#Kgn@C~4?BdKk zYvL?QcQeDwwR5_S(`sn&{PL6FYxwb-qSh_rUUo{Yi-GZz5rZotG4R<+!PfsGg`MVtomw z5kzOZJrh(#rMR_87KeP0Q=#^5~r_?y1*kN?3Fq% zvnzHw$r!w|Soxz8Nbx2d&{!#w$^Hua%fx!xUbc2SI-<{h>e2I;$rJL)4)hnT5cx^* zIq#+{3;Leun3Xo=C(XVjt_z)F#PIoAw%SqJ=~DMQeB zNWQ={d|1qtlDS3xFik}#j*8%DG0<^6fW~|NGL#P_weHnJ(cYEdJtI9#1-Pa8M}(r{ zwnPJB_qB?IqZw5h!hRwW2WIEb?&F<52Ruxpr77O2K>=t*3&Z@=5(c^Uy&JSph}{Q^ z0Tl|}gt=&vK;Rb9Tx{{jUvhtmF>;~k$8T7kp;EV`C!~FKW|r$n^d6=thh`)^uYgBd zydgnY9&mm$?B@pKK+_QreOm?wnl5l}-wA$RZCZukfC$slxbqv9uKq0o^QeSID96{Rm^084kZ)*`P zk))V~+<4-_7d6<~)PL%!+%JP`Dn23vUpH47h~xnA=B_a}rLy|7U-f0W+fH`{wnyh2 zD$JYdXuygeP5&OAqpl2)BZ|X){~G;E|7{liYf%AZFmXXyA@32qLA)tuuQz`n^iH1Y z=)pAzxK$jw0Xq?7`M`=kN2WeQFhz)p;QhjbKg#SB zP~_Vqo0SGbc5Q;v4Q7vm6_#iT+p9B>%{s`8H}r|hAL5I8Q|ceJAL*eruzD8~_m>fg26HvLpik&#{3Zd#|1C_>l&-RW2nBBzSO zQ3%G{nI*T}jBjr%3fjG*&G#ruH^ioDM>0 zb0vSM8ML?tPU*y%aoCq;V%x%~!W*HaebuDn9qeT*vk0%X>fq-4zrrQf{Uq5zI1rEy zjQ@V|Cp~$AoBu=VgnVl@Yiro>ZF{uB=5)~i1rZzmDTIzLBy`8Too!#Z4nE$Z{~uB( z_=o=gKuhVpy&`}-c&f%**M&(|;2iy+nZy2Su}GOAH_GT9z`!ogwn$+Bi&1ZhtPF zVS&LO5#Bq}cew$kvE7*t8W^{{7&7WaF{upy0mj*K&xbnXvSP9V$6m6cesHGC!&Us36ld9f*Pn8gbJb3`PPT|ZG zri2?uIu09i>6Y-0-8sREOU?WaGke0+rHPb^sp;*E{Z5P7kFJ@RiLZTO`cN2mRR#Nz zxjJ##Nk+Uy-2N-8K_@576L(kJ>$UhP+)|w!SQHkkz+e62*hpzyfmY4eQLZtZUhEdG zIZluDOoPDlt5#iw+2epC3vEATfok^?SDT`TzBwtgKjY z>ZImbO)i~T=IYAfw$3j2mF1Cj*_yqK(qw(U^r-!gcUKvWQrDG@E{lEyWDWOPtA9v{ z5($&mxw{nZWo_Ov??S#Bo1;+YwVfx%M23|o$24Hdf^&4hQeV=Cffa5MMYOu2NZLSC zQ4UxWvn+8%YVGDg(Y*1iHbUyT^=gP*COcE~QkU|&6_3h z-GOS6-@o9+Vd(D7x#NYt{Bvx2`P&ZuCx#^l0bR89Hr6Vm<||c3Waq(KO0eZ zH(|B;X}{FaZ8_4yyWLdK!G_q9AYZcoOY}Jlf3R;%oR5dwR(rk7NqyF%{r>F4s^>li z`R~-fh>YIAC1?%!O?mxLx!dq*=%IRCj;vXX628aZ;+^M0CDFUY0Rc<1P5e(OVX8n- z*1UOrX{J}b2N)6m5&_xw^WSN=Lp$I$T>f8K6|J_bj%ZsIYKNs1$TFt!RuCWF48;98`7D(XPVnk+~~i=U$} zR#;!ZRo4eVqlDxjDeE^3+8)bzG_o~VRwdxqvD^HNh#@o>1My$0*Y_`wfQ$y}az|Uz zM47oEaYNTH?J^w9EVNnvfmmbV+GHDe)Kf;$^@6?9DrSHnk@*{PuJ>ra|9KO!qQ-Fp zNNcZB4ZdAI>jEh@3Mt(E1Fy!^gH-Zx6&lr8%=duIgI^~gC{Q;4yoe;#F7B`w9daIe z{(I;y)=)anc;C;)#P`8H6~iAG_q-4rPJb(6rn4pjclGi6$_L79sFAj#CTv;t@94S6 zz`Id7?k!#3JItckcwOf?sj=Xr6oKvAyt1=jiWN@XBFoW6dw_+c9O9x2i4or?*~8f& zm<>yzc6Aw_E-gsGAa`6`cjK~k^TJt(^`E1^_h)5(8)1kzAsBxjd4+!hJ&&T!qklDN z`?j#za=(^wRCvEI75uE^K#IBe5!5g2XW}|lUqAmdmIQb7xJtP}G9^(=!V`ZS_7#RZ zjXq#Cekw>fE*YS-?Qea|7~H?)bbLK;G&(~%!B@H`o#LYAuu6;-c~jFfjY7GKZ|9~{ zE!`!d@@rhY_@5fDbuQ8gRI~R_vs4%fR5$?yot4hDPJ28k_Wzmc^0yzwMr#*(OXq@g zRUgQmJA?E>3GO=5N8iWIfBP{&QM%!Oa*iwTlbd0Fbm*QCX>oRb*2XfG-=Bz1Qz0$v zn#X!2C!LqE601LEMq;X7`P*5nurdKZAmmsI-zZ|rTH;AFxNDyZ_#hN2m4W(|YB64E z470#yh$;8QzsdA;6vbNvc95HLvZvyT4{C>F(fwy&izvNDuvfO1Z;`Ss#4a_c6pm*{0t|_i9z{@84^lffQa5zG4<{(+p5-S z^>lG-^GJR#V>;5f3~y%n=`U_jBp~WgB0cp;Lx5VZYPYCH&(evw#}AYRlGJ>vcoeVr z3%#-QUBgeH!GB>XLw;rT&oMI9ynP;leDwh4O2uM!oIWo&Qxk{^9#nX&^3GJ z(U~5{S9aw@yHH^yuQGso=~*JOC9Zdi6(TFP+IddkfK5Eu9q;+F9?PPNAe-O;;P_Aa zPJ{Dqa1gQb%dZ|0I{#B0(z|r(qq!A4CxlW92-LwXFjYfOzAT1DDK`9rm4AB~l&oVv zi6_{)M9L1%JP}i52y@`!T9RB~!CRel53wl?amNHqcuElq%hn)|#BPvW5_m51RVb|? zXQ&B*eAD}}QamG>o{?i~usG5X6IDa3+Xkb8w%7;C8|Cln70biA+ZH}fxkH^Wei$vZPnuqIT!Mmy26;mLfU z3Bbv4M^vvMlz-I+46=g>0^wWkmA!hlYj*I!%it^x9Kx(d{L|+L{rW?Y#hLHWJfd5X z>B=Swk8=;mRtIz}Hr3NE_garb5W*!7fnNM{+m2_>!cHZZlNEeof~7M#FBEQ+f&gJ3 z^zv*t?XV)jQi%0-Ra|ISiW-fx)DsK-> zI}Fv%uee$#-1PKJwr=lU89eh=M{>Nk7IlJ)U33U)lLW+OOU%A|9-Lf;`@c*+vX{W2 z{{?0QoP!#?8=5%yL=fP%iF+?n$0#iHz`P;1{Ra6iwr=V7v^8;NoLJ5)QxIyIx>ur?lMwV=mBo0BA?28kMow8SX=Ax5L%S~x4+EQi#Ig`(ht%)D(F#Pa!)SiHy&PvUp32=VtAsR|6|NZR@jkad zX^aEgojf9(-)rNOZ=NVA&a;6Cljkb=H-bY9m^_I)`pBHB16QW)sU27zF13ypefeATJc1Wzy39GrKF{UntHsIU59AdXp?j{eh2R)IbU&omd zk6(qzvE@hve1yM6dgkbz>5HDR&MD~yi$yymQ}?b;RfL$N-#l7(u?T^Wlu+Q;fo|jd zBe^jzGMHY(2=5l?bEIh+zgE$1TEQ&!p3fH;AW`P?W5Hkj3eJnT>dqg! zf~}A*SZU5HHDCbdywQ^l_PqssHRlrySYN=`hAv2sVrtcF!`kyEu%XeeRUTJU7vB%h zY0*)N$mLo6d=tJfe}IPIeiH~>AKwCpkn&WEfYgl?3anq5#-F$6$v-(G_j0*S9mdsn zg@ek_ut4(?+JP_9-n`YqoD(gAz+Ttm1#t za96D}oQR(o=e8wwes19_(p4g(A1vSGwPAp~Hh3hh!fc>u{1E^+^}AzwilFVf6^vbL zc&NnRs`u)N-P|Cu4()yTiuE{j_V&=K?iP!IUBf~ei2}~_KBvUAlXa;R#Wl`gOBtJ$Y5(L))@`riLB)v*r>9*8VfmQt<72?+fdwP{BA@?_qo>mN7yzICUCaeG(+>Rb~8wg~6U(P)NlDLuhQgjbC}=)HuZgC}0Z-qLX4lJ7^)8~!!*qP0=~`Y_(A z{@15*ZevZSI^s|OnpCeCwLXf#tgbq8y~R*GB5anmZ;_N!+-3>!wu@NBFCNJ$#y?{? zMI!?s*=_xA;V&aX)ROxzVW8*de+&P#2zucA|8mksdgCXBsZ*TM=%{L1Tk5LB_*^@&S?O=ot{h)1xRVSn27&Tk8>rF|6ruzYb;Nq) z;qvlmrP^SL$mhe4Ai)xpl6Wx&y;z8o!7-+6$qj;ZLXvfR71I@w(R|6lyuP6v-lP&r z@KK-TEmGQfMmk1c0^fd7!^si}T%b5a2%>T-Drh|^Cf z$}qxIv@zxbmJ#qjK6Q_aGDe{ciVT20V1lW52Xs!}x(4_j)sUXYdm4 zwYC9FOa;X*c*LxL;xE5ov?|?^7gWXyALy_D2GvDo-8%0-Y%9TkkO_Tcr2qIUg3(OC z%3wt?hyn*+e^z%(~2#!2dvMFa$mzgwk1I1X;naFMjXSbnmZ!zd%7u)=cgi z*0&@Scrl&BDfU(9Pks8#;!~v~r7~DN{G6WE&_;7i{{a*?oiCao(l%2ruxX0fAt69e2vLgL%Mf_)!*(Tz zNKW>sW@YB2vBfP>C&L|-pq)Uq^PsG_THu;8iEcqafO?0k$IQp1KyWyOoTxwmKvlc^ zO9$%Tt8;%qQxwy5;CsJ)V}a7I6}SvQ%0_H53Kcqx=m83fIzpLSGgfVe^SPdc*xPdciI5dg}#{Etv$e<)gGD=qm0v=!aN@*?$s zLhzD%4w{vf-g6FHQjG9XyC+4=bewb?Mz%!u8%oP{G9{UJFTLTcCi3R(=Nm&t&Sl(? zr>pj?=ECdDVa}-g%`LF^1EY@>7d}%VhYpKFSDPH)D(zB+gPe1m7E}W>TiW=8L0&(D&YG=0<&7G4Bu{;-#Ud;-1%Ta9V}U6fyK1YX z`Rq|i-X(loPZ)M$H%m@j7bGx>uj~y=0)!t#dc|c}+hT%~Sq>fefez0Ul|jOJHta~u zx7*mV6~Jpt(FkY(pQN91>aFk7VS%Sa^oLaq$*)W?fy`xuFJgH<2s=!Rz}_(qdmdF~ zlr2f=)q_vpi8X;Jq>5^$GweJ{iS`Khw2f)fsvKpgh;U~13a+9 zfaw}UuGiBy;q10pI^Avb#X3D=k_r(T{N;-xA)OM}2Py5L##<96NU*Sr7GQqhfrPej z?;B$Bt_sTxuSAPXfTSC{zr?@$$0iHxC@z*5F52j*PG87hh`0w3At8jPf*rjNE~_Gj z2)fjeUFJ(#l9uWuw&5#@13|AQ1;pdA?EL4YKq0JDR5T8I?aWGxI=J9}vdyH;gQ@iE z>+UnC2iwT0f80-VuE^bY!N@(}9?bOXyy%rTqSNDN4rO4Zt#(kZwcGgTp&3((F+nsd ze~B)%K6oP4WX_w1>|QImC;9q zy}4p+s%^Too2(gE>yo%+yY#F{)phtmNqsJPVQQ0lGR|H9q>aA&AtU4M+EZ%`xvQLb zbigBOc`dL}&j3er?EOI`!W)N#>+uwp_!h^5FspaEylq!e(FPY-6T3~WeNmZ<$?Y6y z-!bM1kD7ZF8xl+Pi6fiv1?)q%`aNxn#pK%)ct||L&Xnf8Gu&3g;Of{B8Pt=u`e+Mn zA(DmU#3cF#Nr7W;X0V4ksFHMcNDAf4G&D8VjLeZ^|5-f$>_|71>P3xuu)?4NJed*w z6GR_RB5HQLzT(h+`Y?-3esxeue{-Q%b+!&o>IJ!#=}#_&q+hwJga>fkt(*(WdoN5vSta z#$mMN6}YzYRpaBZ)j)EL91-oL1(|d(>%UclsTUOyXyWM&(hNqLwqtn`!E>HJM{ zh>M~xa1@*U^cwx-k5QjePr5=B6u*jpJ)C0{C?f7Yga+I^4$TleyX$x&jm9z@c!?cC z<2kY7)p^+W{AXd@l1C09_yB*TG|yzb96BYk z8Wpj81vB>zcR+qM4m~A44w1n7$fxB$-?MV}S?Fh}c_|2FXg`cZ?750i;Cdl-_nGK# zta)h)6!*AsQ-z8caSh)%5JY>_yCeJs~FpAzdY8 zF@SU_hN#~ip5I;UACFzx1v0yf{j97l&)e-=`d#1Kp6A(Kj&HC!%vK!wEdK3HFJ?|6 za;WwUczZ+&<$g!Td^48@lJtfW@doXL#jY6)dK_RDCQAZ}l&OdD+?Yl5-bqpsHZR^( zF{u_cR(x>u(c4i5f(^8!h6CV0#ZxRFhLlunWiGDLO6yoRb(wV<(P^8=fOU7Hp{AHE z;Yg%kg@6&tL3Z*IrbkDeQ$%rbalVP39D@LVrC2xSavnTp%PorXPf1DVzHyqjDsDnS zL=mv0a2s60bHKGQM)ue>npH0SCp;XtZFUzm?R-x7D*(PxMmuJ4J*K2eY&ebe0yQHe zVG&*qe{pot{PM^xQv`H_rn2FcYOrEN+I#uX^1`Id%J$;Hi2cNCU!0Hlc0TjxLzkss zHxmC;hQBu5U4J0XflWM;{uH`_47Sg)QyZ{8D&T0;bdc3{^^<=q7P?C_2E-}PQn>*= z2T5q^J|Q_2+x%Qt`i3m6=6V$)BxIx{2KAFkMb#q`iMCD|L>+}_dYVA$wBr1Zr}YOF z^MMGO@PHGGh>g|^yF`PvvtDwN@kxt?ClLcG<+murHMz1Asj!$l=b)4{d}SqOJ}>Y< zSeAyP@ZEcpx`ayIdp>{--UVLYC_cZZURh_!4u2(*#x@Tk(QJa}4BqqZ$6%LhF-HB~ zAcc?$I6KP}IxANcAteEBX$Ys?T=JB|Fnd3*UAO0mYAXCgWf~?7Z_G7G5`H4;S^QKK zG*2l75vI@DHQC*es>6&|r^#RHKRQ5rwv_l4`!(!I3%)Z$P1fnZ8N@27zyg}54ElO%SjQ_4uujX)4ta@Gz2)_>4b~vX|rhRIH-eqdD zL)xaEpW3K|a>daQRRR*_$W>rWOsW-IE4VQl3L$3}=-PFU)s@XG&9+DFivH-;2&w~$ES_nJZJH!?1mO!CnP)Jb{mW9=f`bDpo^PI6i4|YurK)Q1 z^Ys1oHRdr!$X4RuyR%kgp!a*Lz*_AAoJ$EVAdsNCoPA^VZE1pGO@D3UStACE+%vs6 z$io@E>DmB|3VV~GbOt2oc+K;t zdn3gaFvYz;vRN-+2+Qk{8|O}e86nVck)fZn3sg$j#dLVham{yGkc$I#!HF7mRS%f* z!+NdzG49K(qaO^SBlp@K@D?|^rAq;8{*@kRc4sYSNQmoy7@_RS_ksWl2T_38h2A)# ziU2WXWD03(NqS&Mu*?0-iK8X_Z3w`}c7MPv0qZ7iM|L3xdTnR{y!7{#82$}uJCiGT zqa=8<9L05hu6 z1N+2n7OzT{NEf?gS@eq7@buCDFe9mAxY%THo^b@BHckKK>jg6{@)>n z43cPs%$Qi0iwyZ+{C491>FRu5+6baJ{&XXXC@Sp+b!QE|{7_d?lm5K=B z)myKEcxjFm74+drF|JCYcxdY%ASig#YoRBRUV7An7f-%rqj%PHECbxh#5476cEq@NQL?dI6gUqvS@w zq!WmD(aR0{NxItAZCKDCVw=Zu{9WGDu^i?2g zLerPiOU*HSaXg^3CdOX^F6c9MiHINP339N%)a96`^Z-c#&EogcxMSYo0Cb4{-}q1( zRrJine`P|6WRkm8u4Ja1QRYq$AR>b7tugd#EsT-VmXN-t!TYjZy}i!uKi6$u>EJ?w zvdHZg+hp+5ree?>fdJAX)5#Wtm#2M-{~2jfX2{G`)?D6UD1MevdeeU;;HCi}AtJr( SGW6ptSs!X7{rG*o_g?|vpSEZK diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 4baf5a11d45..381baa9cef1 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,7 +1,7 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionSha256Sum=9631d53cf3e74bfa726893aee1f8994fee4e060c401335946dba2156f440f24c -distributionUrl=https\://services.gradle.org/distributions/gradle-8.6-bin.zip +distributionSha256Sum=544c35d6bd849ae8a5ed0bcea39ba677dc40f49df7d1835561582da2009b961d +distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip networkTimeout=10000 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME diff --git a/gradlew.bat b/gradlew.bat index 93e3f59f135..25da30dbdee 100644 --- a/gradlew.bat +++ b/gradlew.bat @@ -43,11 +43,11 @@ set JAVA_EXE=java.exe %JAVA_EXE% -version >NUL 2>&1 if %ERRORLEVEL% equ 0 goto execute -echo. -echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. +echo. 1>&2 +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2 +echo. 1>&2 +echo Please set the JAVA_HOME variable in your environment to match the 1>&2 +echo location of your Java installation. 1>&2 goto fail @@ -57,11 +57,11 @@ set JAVA_EXE=%JAVA_HOME%/bin/java.exe if exist "%JAVA_EXE%" goto execute -echo. -echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. +echo. 1>&2 +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2 +echo. 1>&2 +echo Please set the JAVA_HOME variable in your environment to match the 1>&2 +echo location of your Java installation. 1>&2 goto fail From 53fd6f063dba61eb3bbff8ae120d572eb8d5b561 Mon Sep 17 00:00:00 2001 From: Robert Lu Date: Fri, 29 Mar 2024 05:36:35 +0800 Subject: [PATCH 309/901] migrate gradle/gradle-build-action to gradle/actions/setup-gradle (#6326) --- .github/workflows/benchmark-tags.yml | 2 +- .github/workflows/benchmark.yml | 2 +- .github/workflows/build.yml | 4 ++-- .github/workflows/codeql-daily.yml | 2 +- .github/workflows/owasp-dependency-check-daily.yml | 2 +- .github/workflows/release.yml | 2 +- 6 files changed, 7 insertions(+), 7 deletions(-) diff --git a/.github/workflows/benchmark-tags.yml b/.github/workflows/benchmark-tags.yml index f1b91acf252..81335228f2b 100644 --- a/.github/workflows/benchmark-tags.yml +++ b/.github/workflows/benchmark-tags.yml @@ -50,7 +50,7 @@ jobs: distribution: temurin java-version: 17 - - uses: gradle/gradle-build-action@v3 + - uses: gradle/actions/setup-gradle@v3 with: arguments: | jmhJar diff --git a/.github/workflows/benchmark.yml b/.github/workflows/benchmark.yml index e5f6ff19dbd..82bb73e5d17 100644 --- a/.github/workflows/benchmark.yml +++ b/.github/workflows/benchmark.yml @@ -20,7 +20,7 @@ jobs: distribution: temurin java-version: 17 - - uses: gradle/gradle-build-action@v3 + - uses: gradle/actions/setup-gradle@v3 with: arguments: | jmhJar diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index a4e5b19ec97..694d63a578d 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -50,7 +50,7 @@ jobs: distribution: temurin java-version: 17 - - uses: gradle/gradle-build-action@v3 + - uses: gradle/actions/setup-gradle@v3 with: arguments: | build @@ -123,7 +123,7 @@ jobs: distribution: temurin java-version: 17 - - uses: gradle/gradle-build-action@v3 + - uses: gradle/actions/setup-gradle@v3 # skipping release branches because the versions in those branches are not snapshots # (also this skips pull requests) if: ${{ github.ref_name == 'main' && github.repository == 'open-telemetry/opentelemetry-java' }} diff --git a/.github/workflows/codeql-daily.yml b/.github/workflows/codeql-daily.yml index 065704888f7..903ed11f4b5 100644 --- a/.github/workflows/codeql-daily.yml +++ b/.github/workflows/codeql-daily.yml @@ -27,7 +27,7 @@ jobs: # see https://github.com/github/codeql-action/issues/1555#issuecomment-1452228433 tools: latest - - uses: gradle/gradle-build-action@v3 + - uses: gradle/actions/setup-gradle@v3 with: # skipping build cache is needed so that all modules will be analyzed arguments: assemble --no-build-cache diff --git a/.github/workflows/owasp-dependency-check-daily.yml b/.github/workflows/owasp-dependency-check-daily.yml index 9adaf80948d..b67270f55aa 100644 --- a/.github/workflows/owasp-dependency-check-daily.yml +++ b/.github/workflows/owasp-dependency-check-daily.yml @@ -19,7 +19,7 @@ jobs: distribution: temurin java-version: 17 - - uses: gradle/gradle-build-action@v3 + - uses: gradle/actions/setup-gradle@v3 with: arguments: "dependencyCheckAnalyze" diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 815bc4d5afc..11b02a7df9c 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -22,7 +22,7 @@ jobs: java-version: 17 - name: Build and publish artifacts - uses: gradle/gradle-build-action@v3 + uses: gradle/actions/setup-gradle@v3 with: arguments: assemble publishToSonatype closeAndReleaseSonatypeStagingRepository env: From f95b9f50c16967a74da4581aa774bc813e305167 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 29 Mar 2024 10:50:22 -0500 Subject: [PATCH 310/901] Update dependency com.linecorp.armeria:armeria-bom to v1.27.3 (#6325) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- dependencyManagement/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index fbbff0fdffc..362de9dd48f 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -11,7 +11,7 @@ val DEPENDENCY_BOMS = listOf( "com.fasterxml.jackson:jackson-bom:2.17.0", "com.google.guava:guava-bom:33.1.0-jre", "com.google.protobuf:protobuf-bom:3.25.3", - "com.linecorp.armeria:armeria-bom:1.27.2", + "com.linecorp.armeria:armeria-bom:1.27.3", "com.squareup.okhttp3:okhttp-bom:4.12.0", "com.squareup.okio:okio-bom:3.9.0", // applies to transitive dependencies of okhttp "io.grpc:grpc-bom:1.62.2", From 52bbd917f5b1cacea6a438310c6734db35282f28 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 29 Mar 2024 10:50:38 -0500 Subject: [PATCH 311/901] Update dependency nl.jqno.equalsverifier:equalsverifier to v3.16 (#6320) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- dependencyManagement/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index 362de9dd48f..43907372a3b 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -71,7 +71,7 @@ val DEPENDENCIES = listOf( "io.opentracing:opentracing-noop:0.33.0", "io.prometheus:prometheus-metrics-exporter-httpserver:1.1.0", "junit:junit:4.13.2", - "nl.jqno.equalsverifier:equalsverifier:3.15.8", + "nl.jqno.equalsverifier:equalsverifier:3.16", "org.awaitility:awaitility:4.2.1", "org.bouncycastle:bcpkix-jdk15on:1.70", "org.codehaus.mojo:animal-sniffer-annotations:1.23", From e688c256ac1966910a22725cf5865dcc7f84f026 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 29 Mar 2024 10:50:59 -0500 Subject: [PATCH 312/901] Update dependency io.prometheus:prometheus-metrics-exporter-httpserver to v1.2.0 (#6322) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Co-authored-by: Jack Berg --- .../kotlin/otel.java-conventions.gradle.kts | 5 +- dependencyManagement/build.gradle.kts | 2 +- .../PrometheusMetricReaderTest.java | 63 ++++++++++++++++--- 3 files changed, 56 insertions(+), 14 deletions(-) diff --git a/buildSrc/src/main/kotlin/otel.java-conventions.gradle.kts b/buildSrc/src/main/kotlin/otel.java-conventions.gradle.kts index 10fef3da385..f9f7e245011 100644 --- a/buildSrc/src/main/kotlin/otel.java-conventions.gradle.kts +++ b/buildSrc/src/main/kotlin/otel.java-conventions.gradle.kts @@ -79,10 +79,7 @@ tasks { // https://groups.google.com/forum/#!topic/bazel-discuss/_R3A9TJSoPM "-Xlint:-processing", // We suppress the "options" warning because it prevents compilation on modern JDKs - "-Xlint:-options", - - // Fail build on any warning - "-Werror", + "-Xlint:-options" ), ) } diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index 43907372a3b..b5cd10ffce0 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -69,7 +69,7 @@ val DEPENDENCIES = listOf( "io.opentelemetry.contrib:opentelemetry-aws-xray-propagator:1.29.0-alpha", "io.opentracing:opentracing-api:0.33.0", "io.opentracing:opentracing-noop:0.33.0", - "io.prometheus:prometheus-metrics-exporter-httpserver:1.1.0", + "io.prometheus:prometheus-metrics-exporter-httpserver:1.2.0", "junit:junit:4.13.2", "nl.jqno.equalsverifier:equalsverifier:3.16", "org.awaitility:awaitility:4.2.1", diff --git a/exporters/prometheus/src/test/java/io/opentelemetry/exporter/prometheus/PrometheusMetricReaderTest.java b/exporters/prometheus/src/test/java/io/opentelemetry/exporter/prometheus/PrometheusMetricReaderTest.java index 1e978a60d43..1a4f9d42889 100644 --- a/exporters/prometheus/src/test/java/io/opentelemetry/exporter/prometheus/PrometheusMetricReaderTest.java +++ b/exporters/prometheus/src/test/java/io/opentelemetry/exporter/prometheus/PrometheusMetricReaderTest.java @@ -5,7 +5,6 @@ package io.opentelemetry.exporter.prometheus; -import static java.util.stream.Collectors.joining; import static org.assertj.core.api.Assertions.assertThat; import io.opentelemetry.api.common.Attributes; @@ -37,9 +36,12 @@ import java.nio.charset.StandardCharsets; import java.time.Duration; import java.time.Instant; -import java.util.Arrays; +import java.util.HashMap; +import java.util.Map; import java.util.Random; import java.util.concurrent.TimeUnit; +import java.util.regex.MatchResult; +import java.util.regex.Matcher; import java.util.regex.Pattern; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Disabled; @@ -433,7 +435,11 @@ private void assertHistogramComplete( + "request_size_bytes_bucket{animal=\"bear\",otel_scope_name=\"test\",le=\"7500.0\"} 2\n" + "request_size_bytes_bucket{animal=\"bear\",otel_scope_name=\"test\",le=\"10000.0\"} 2\n" + "request_size_bytes_bucket{animal=\"bear\",otel_scope_name=\"test\",le=\"+Inf\"} 2\n" - + "request_size_bytes_count{animal=\"bear\",otel_scope_name=\"test\"} 2\n" + + "request_size_bytes_count{animal=\"bear\",otel_scope_name=\"test\"} 2 # {span_id=\"" + + "" + + "\",trace_id=\"" + + "" + + "\"} \n" + "request_size_bytes_sum{animal=\"bear\",otel_scope_name=\"test\"} 573.0\n" + "request_size_bytes_created{animal=\"bear\",otel_scope_name=\"test\"} " + createdTimestamp @@ -458,7 +464,11 @@ private void assertHistogramComplete( + "request_size_bytes_bucket{animal=\"mouse\",otel_scope_name=\"test\",le=\"7500.0\"} 1\n" + "request_size_bytes_bucket{animal=\"mouse\",otel_scope_name=\"test\",le=\"10000.0\"} 1\n" + "request_size_bytes_bucket{animal=\"mouse\",otel_scope_name=\"test\",le=\"+Inf\"} 1\n" - + "request_size_bytes_count{animal=\"mouse\",otel_scope_name=\"test\"} 1\n" + + "request_size_bytes_count{animal=\"mouse\",otel_scope_name=\"test\"} 1 # {span_id=\"" + + span3.getSpanContext().getSpanId() + + "\",trace_id=\"" + + span3.getSpanContext().getTraceId() + + "\"} 204.0 \n" + "request_size_bytes_sum{animal=\"mouse\",otel_scope_name=\"test\"} 204.0\n" + "request_size_bytes_created{animal=\"mouse\",otel_scope_name=\"test\"} " + createdTimestamp @@ -1086,16 +1096,51 @@ void addResourceAttributesWorks() throws IOException { * {@code expected} equals {@code actual} but {@code } matches arbitrary timestamps. */ private static void assertMatches(String expected, String actual) { - String[] parts = expected.split(Pattern.quote("")); - String timestampRegex = "[0-9]+(\\.[0-9]+)?"; - - String regex = Arrays.stream(parts).map(Pattern::quote).collect(joining(timestampRegex)); - + String regex = toPattern(expected); assertThat(actual) .as("Expected: " + expected + "\nActual: " + actual) .matches(Pattern.compile(regex)); } + /** + * Replace non-deterministic portions of {@code expected} with regex patterns. Other portions are + * quoted such that must match exactly. The following sequences are replaced: + * + *
        + *
      • {@code } + *
      • {@code } + *
      • {@code } + *
      • {@code } + *
      + */ + private static String toPattern(String expected) { + Map replacePatterns = new HashMap<>(); + replacePatterns.put("timestamp", "[0-9]+(\\.[0-9]+)?"); + replacePatterns.put("spanId", "[a-z0-9]*"); + replacePatterns.put("traceId", "[a-z0-9]*"); + replacePatterns.put("measurement", "[0-9\\.]*"); + + Matcher matcher = Pattern.compile("\\<([a-zA-Z]*)\\>").matcher(expected); + if (!matcher.find()) { + return Pattern.quote(expected); + } + int offset = 0; + StringBuilder regexBuilder = new StringBuilder(); + do { + MatchResult matchResult = matcher.toMatchResult(); + String key = matchResult.group(1); + String pattern = replacePatterns.getOrDefault(key, key); + regexBuilder + .append(Pattern.quote(expected.substring(offset, matchResult.start()))) + .append(pattern); + offset = matchResult.end(); + } while (matcher.find()); + if (offset != expected.length()) { + regexBuilder.append(Pattern.quote(expected.substring(offset))); + } + return regexBuilder.toString(); + } + private static String toOpenMetrics(MetricSnapshots snapshots) throws IOException { ByteArrayOutputStream out = new ByteArrayOutputStream(); OpenMetricsTextFormatWriter writer = new OpenMetricsTextFormatWriter(true, true); From 101c0a80f2e6c605d1d8844fe2ad5b3d08a33970 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 29 Mar 2024 10:51:10 -0500 Subject: [PATCH 313/901] Update gradle/wrapper-validation-action action to v2.1.2 (#6319) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/gradle-wrapper-validation.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/gradle-wrapper-validation.yml b/.github/workflows/gradle-wrapper-validation.yml index d4aee174fab..9d33b0441d6 100644 --- a/.github/workflows/gradle-wrapper-validation.yml +++ b/.github/workflows/gradle-wrapper-validation.yml @@ -13,4 +13,4 @@ jobs: steps: - uses: actions/checkout@v4 - - uses: gradle/wrapper-validation-action@v2.1.1 + - uses: gradle/wrapper-validation-action@v2.1.2 From 80971c1ff7d9dacd4ca5009e69637697c0dcecfd Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 29 Mar 2024 10:51:24 -0500 Subject: [PATCH 314/901] Update dependency io.netty:netty-bom to v4.1.108.Final (#6315) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- dependencyManagement/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index b5cd10ffce0..44bc2cb3569 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -15,7 +15,7 @@ val DEPENDENCY_BOMS = listOf( "com.squareup.okhttp3:okhttp-bom:4.12.0", "com.squareup.okio:okio-bom:3.9.0", // applies to transitive dependencies of okhttp "io.grpc:grpc-bom:1.62.2", - "io.netty:netty-bom:4.1.107.Final", + "io.netty:netty-bom:4.1.108.Final", "io.zipkin.brave:brave-bom:6.0.2", "io.zipkin.reporter2:zipkin-reporter-bom:3.3.0", "org.assertj:assertj-bom:3.25.3", From 570d5827306f8de3804e39a529369453a3496235 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 29 Mar 2024 15:51:38 -0500 Subject: [PATCH 315/901] Update dependency com.uber.nullaway:nullaway to v0.10.25 (#6330) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- dependencyManagement/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index 44bc2cb3569..c7942fff49c 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -60,7 +60,7 @@ val DEPENDENCIES = listOf( "com.google.guava:guava-beta-checker:1.0", "com.sun.net.httpserver:http:20070405", "com.tngtech.archunit:archunit-junit5:1.2.1", - "com.uber.nullaway:nullaway:0.10.24", + "com.uber.nullaway:nullaway:0.10.25", "edu.berkeley.cs.jqf:jqf-fuzz:1.7", // jqf-fuzz version 1.8+ requires Java 11+ "eu.rekawek.toxiproxy:toxiproxy-java:2.1.7", "io.github.netmikey.logunit:logunit-jul:2.0.0", From 622d977f8726bd2eb50b8bb66b171b1cf8883e25 Mon Sep 17 00:00:00 2001 From: jack-berg <34418638+jack-berg@users.noreply.github.com> Date: Fri, 29 Mar 2024 16:48:12 -0500 Subject: [PATCH 316/901] Refactor Event API to reflect spec changes (#6318) --- .../incubator/events/DefaultEventLogger.java | 28 ++++- .../api/incubator/events/EventBuilder.java | 83 +++++++++++++- .../api/incubator/events/EventLogger.java | 20 +--- .../api/incubator/logs/AnyValue.java | 5 + .../api/incubator/logs/AnyValueArray.java | 4 + .../DefaultEventLoggerProviderTest.java | 4 +- .../events/DefaultEventLoggerTest.java | 22 ++-- .../OtlpExporterIntegrationTest.java | 15 +-- .../sdk/autoconfigure/FullConfigTest.java | 32 +++--- .../sdk/logs/internal/SdkEventBuilder.java | 52 ++++++++- .../logs/internal/SdkEventLoggerProvider.java | 30 ++---- .../logs/internal/SdkEventBuilderTest.java | 21 +++- .../internal/SdkEventLoggerProviderTest.java | 101 +++++++++++++----- 13 files changed, 299 insertions(+), 118 deletions(-) diff --git a/api/incubator/src/main/java/io/opentelemetry/api/incubator/events/DefaultEventLogger.java b/api/incubator/src/main/java/io/opentelemetry/api/incubator/events/DefaultEventLogger.java index 9a9450b009c..8017965bf00 100644 --- a/api/incubator/src/main/java/io/opentelemetry/api/incubator/events/DefaultEventLogger.java +++ b/api/incubator/src/main/java/io/opentelemetry/api/incubator/events/DefaultEventLogger.java @@ -6,6 +6,9 @@ package io.opentelemetry.api.incubator.events; import io.opentelemetry.api.common.Attributes; +import io.opentelemetry.api.incubator.logs.AnyValue; +import io.opentelemetry.api.logs.Severity; +import io.opentelemetry.context.Context; import java.time.Instant; import java.util.concurrent.TimeUnit; @@ -20,10 +23,7 @@ static EventLogger getInstance() { } @Override - public void emit(String eventName, Attributes attributes) {} - - @Override - public EventBuilder builder(String eventName, Attributes attributes) { + public EventBuilder builder(String eventName) { return NoOpEventBuilder.INSTANCE; } @@ -31,6 +31,11 @@ private static class NoOpEventBuilder implements EventBuilder { public static final EventBuilder INSTANCE = new NoOpEventBuilder(); + @Override + public EventBuilder put(String key, AnyValue value) { + return this; + } + @Override public EventBuilder setTimestamp(long timestamp, TimeUnit unit) { return this; @@ -41,6 +46,21 @@ public EventBuilder setTimestamp(Instant instant) { return this; } + @Override + public EventBuilder setContext(Context context) { + return this; + } + + @Override + public EventBuilder setSeverity(Severity severity) { + return this; + } + + @Override + public EventBuilder setAttributes(Attributes attributes) { + return this; + } + @Override public void emit() {} } diff --git a/api/incubator/src/main/java/io/opentelemetry/api/incubator/events/EventBuilder.java b/api/incubator/src/main/java/io/opentelemetry/api/incubator/events/EventBuilder.java index d5eb5db85f3..27cd6f8c367 100644 --- a/api/incubator/src/main/java/io/opentelemetry/api/incubator/events/EventBuilder.java +++ b/api/incubator/src/main/java/io/opentelemetry/api/incubator/events/EventBuilder.java @@ -5,14 +5,79 @@ package io.opentelemetry.api.incubator.events; +import io.opentelemetry.api.common.Attributes; +import io.opentelemetry.api.incubator.logs.AnyValue; +import io.opentelemetry.api.logs.Severity; +import io.opentelemetry.context.Context; import java.time.Instant; +import java.util.ArrayList; +import java.util.List; import java.util.concurrent.TimeUnit; /** The EventBuilder is used to {@link #emit()} events. */ public interface EventBuilder { + /** Put the given {@code key} and {@code value} in the payload. */ + default EventBuilder put(String key, String value) { + return put(key, AnyValue.of(value)); + } + + /** Put the given {@code key} and {@code value} in the payload. */ + default EventBuilder put(String key, long value) { + return put(key, AnyValue.of(value)); + } + + /** Put the given {@code key} and {@code value} in the payload. */ + default EventBuilder put(String key, double value) { + return put(key, AnyValue.of(value)); + } + + /** Put the given {@code key} and {@code value} in the payload. */ + default EventBuilder put(String key, boolean value) { + return put(key, AnyValue.of(value)); + } + + /** Put the given {@code key} and {@code value} in the payload. */ + default EventBuilder put(String key, String... value) { + List> values = new ArrayList<>(value.length); + for (String val : value) { + values.add(AnyValue.of(val)); + } + return put(key, AnyValue.of(values)); + } + + /** Put the given {@code key} and {@code value} in the payload. */ + default EventBuilder put(String key, long... value) { + List> values = new ArrayList<>(value.length); + for (long val : value) { + values.add(AnyValue.of(val)); + } + return put(key, AnyValue.of(values)); + } + + /** Put the given {@code key} and {@code value} in the payload. */ + default EventBuilder put(String key, double... value) { + List> values = new ArrayList<>(value.length); + for (double val : value) { + values.add(AnyValue.of(val)); + } + return put(key, AnyValue.of(values)); + } + + /** Put the given {@code key} and {@code value} in the payload. */ + default EventBuilder put(String key, boolean... value) { + List> values = new ArrayList<>(value.length); + for (boolean val : value) { + values.add(AnyValue.of(val)); + } + return put(key, AnyValue.of(values)); + } + + /** Put the given {@code key} and {@code value} in the payload. */ + EventBuilder put(String key, AnyValue value); + /** - * Set the epoch {@code timestamp} for the event, using the timestamp and unit. + * Set the epoch {@code timestamp}, using the timestamp and unit. * *

      The {@code timestamp} is the time at which the event occurred. If unset, it will be set to * the current time when {@link #emit()} is called. @@ -20,13 +85,27 @@ public interface EventBuilder { EventBuilder setTimestamp(long timestamp, TimeUnit unit); /** - * Set the epoch {@code timestamp} for the event, using the instant. + * Set the epoch {@code timestamp}, using the instant. * *

      The {@code timestamp} is the time at which the event occurred. If unset, it will be set to * the current time when {@link #emit()} is called. */ EventBuilder setTimestamp(Instant instant); + /** Set the context. */ + EventBuilder setContext(Context context); + + /** Set the severity. */ + EventBuilder setSeverity(Severity severity); + + /** + * Set the attributes. + * + *

      Event {@link io.opentelemetry.api.common.Attributes} provide additional details about the + * Event which are not part of the well-defined {@link AnyValue} {@code payload}. + */ + EventBuilder setAttributes(Attributes attributes); + /** Emit an event. */ void emit(); } diff --git a/api/incubator/src/main/java/io/opentelemetry/api/incubator/events/EventLogger.java b/api/incubator/src/main/java/io/opentelemetry/api/incubator/events/EventLogger.java index 785d8e000ca..3d273a30c7a 100644 --- a/api/incubator/src/main/java/io/opentelemetry/api/incubator/events/EventLogger.java +++ b/api/incubator/src/main/java/io/opentelemetry/api/incubator/events/EventLogger.java @@ -5,7 +5,6 @@ package io.opentelemetry.api.incubator.events; -import io.opentelemetry.api.common.Attributes; import javax.annotation.concurrent.ThreadSafe; /** @@ -20,10 +19,10 @@ * .build(); * * void doWork() { - * eventLogger.emit("my-namespace.my-event", Attributes.builder() + * eventLogger.builder("my-namespace.my-event") * .put("key1", "value1") * .put("key2", "value2") - * .build()) + * .emit(); * // do work * } * } @@ -32,18 +31,6 @@ @ThreadSafe public interface EventLogger { - /** - * Emit an event. - * - * @param eventName the event name, which identifies the class or type of event. Event with the - * same name are structurally similar to one another. Event names are subject to the same - * naming rules as attribute names. Notably, they are namespaced to avoid collisions. See event.name semantic - * conventions for more details. - * @param attributes attributes associated with the event - */ - void emit(String eventName, Attributes attributes); - /** * Return a {@link EventBuilder} to emit an event. * @@ -52,7 +39,6 @@ public interface EventLogger { * naming rules as attribute names. Notably, they are namespaced to avoid collisions. See event.name semantic * conventions for more details. - * @param attributes attributes associated with the event */ - EventBuilder builder(String eventName, Attributes attributes); + EventBuilder builder(String eventName); } diff --git a/api/incubator/src/main/java/io/opentelemetry/api/incubator/logs/AnyValue.java b/api/incubator/src/main/java/io/opentelemetry/api/incubator/logs/AnyValue.java index 1a1519a1044..602e9e289b7 100644 --- a/api/incubator/src/main/java/io/opentelemetry/api/incubator/logs/AnyValue.java +++ b/api/incubator/src/main/java/io/opentelemetry/api/incubator/logs/AnyValue.java @@ -62,6 +62,11 @@ static AnyValue>> of(AnyValue... value) { return AnyValueArray.create(value); } + /** Returns an {@link AnyValue} for the list of {@link AnyValue} values. */ + static AnyValue>> of(List> value) { + return AnyValueArray.create(value); + } + /** * Returns an {@link AnyValue} for the array of {@link KeyAnyValue} values. {@link * KeyAnyValue#getKey()} values should not repeat - duplicates may be dropped. diff --git a/api/incubator/src/main/java/io/opentelemetry/api/incubator/logs/AnyValueArray.java b/api/incubator/src/main/java/io/opentelemetry/api/incubator/logs/AnyValueArray.java index ae448038b18..2332c253392 100644 --- a/api/incubator/src/main/java/io/opentelemetry/api/incubator/logs/AnyValueArray.java +++ b/api/incubator/src/main/java/io/opentelemetry/api/incubator/logs/AnyValueArray.java @@ -28,6 +28,10 @@ static AnyValue>> create(AnyValue... value) { return new AnyValueArray(Collections.unmodifiableList(list)); } + static AnyValue>> create(List> value) { + return new AnyValueArray(Collections.unmodifiableList(value)); + } + @Override public AnyValueType getType() { return AnyValueType.ARRAY; diff --git a/api/incubator/src/test/java/io/opentelemetry/api/incubator/events/DefaultEventLoggerProviderTest.java b/api/incubator/src/test/java/io/opentelemetry/api/incubator/events/DefaultEventLoggerProviderTest.java index 431130045cc..196c0bc307a 100644 --- a/api/incubator/src/test/java/io/opentelemetry/api/incubator/events/DefaultEventLoggerProviderTest.java +++ b/api/incubator/src/test/java/io/opentelemetry/api/incubator/events/DefaultEventLoggerProviderTest.java @@ -8,7 +8,6 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatCode; -import io.opentelemetry.api.common.Attributes; import org.junit.jupiter.api.Test; class DefaultEventLoggerProviderTest { @@ -33,7 +32,8 @@ void noopEventLoggerProvider_doesNotThrow() { provider .eventLoggerBuilder("scope-name") .build() - .emit("event-name", Attributes.empty())) + .builder("namespace.event-name") + .emit()) .doesNotThrowAnyException(); } } diff --git a/api/incubator/src/test/java/io/opentelemetry/api/incubator/events/DefaultEventLoggerTest.java b/api/incubator/src/test/java/io/opentelemetry/api/incubator/events/DefaultEventLoggerTest.java index 9d14ef63c48..e1f1f2e7ce7 100644 --- a/api/incubator/src/test/java/io/opentelemetry/api/incubator/events/DefaultEventLoggerTest.java +++ b/api/incubator/src/test/java/io/opentelemetry/api/incubator/events/DefaultEventLoggerTest.java @@ -8,35 +8,27 @@ import static org.assertj.core.api.Assertions.assertThatCode; import io.opentelemetry.api.common.Attributes; +import io.opentelemetry.api.logs.Severity; +import io.opentelemetry.context.Context; import java.time.Instant; import java.util.concurrent.TimeUnit; import org.junit.jupiter.api.Test; class DefaultEventLoggerTest { - @Test - void emit() { - assertThatCode(() -> DefaultEventLogger.getInstance().emit("event-name", Attributes.empty())) - .doesNotThrowAnyException(); - assertThatCode( - () -> - DefaultEventLogger.getInstance() - .emit( - "event-domain.event-name", - Attributes.builder().put("key1", "value1").build())) - .doesNotThrowAnyException(); - } - @Test void builder() { - Attributes attributes = Attributes.builder().put("key1", "value1").build(); EventLogger eventLogger = DefaultEventLogger.getInstance(); assertThatCode( () -> eventLogger - .builder("com.example.MyEvent", attributes) + .builder("namespace.myEvent") + .put("key", "value") .setTimestamp(123456L, TimeUnit.NANOSECONDS) .setTimestamp(Instant.now()) + .setContext(Context.current()) + .setSeverity(Severity.DEBUG) + .setAttributes(Attributes.empty()) .emit()) .doesNotThrowAnyException(); } diff --git a/integration-tests/otlp/src/main/java/io/opentelemetry/integrationtest/OtlpExporterIntegrationTest.java b/integration-tests/otlp/src/main/java/io/opentelemetry/integrationtest/OtlpExporterIntegrationTest.java index 810b51f5131..141159c3d8d 100644 --- a/integration-tests/otlp/src/main/java/io/opentelemetry/integrationtest/OtlpExporterIntegrationTest.java +++ b/integration-tests/otlp/src/main/java/io/opentelemetry/integrationtest/OtlpExporterIntegrationTest.java @@ -568,7 +568,7 @@ private static void testLogRecordExporter(LogRecordExporter logRecordExporter) { .setSeverityText("DEBUG") .setContext(Context.current()) .emit(); - eventLogger.emit("event-name", Attributes.builder().put("key", "value").build()); + eventLogger.builder("namespace.event-name").put("key", "value").emit(); } // Closing triggers flush of processor @@ -708,17 +708,18 @@ private static void testLogRecordExporter(LogRecordExporter logRecordExporter) { // LogRecord via EventLogger.emit(String, Attributes) io.opentelemetry.proto.logs.v1.LogRecord protoLog2 = ilLogs.getLogRecords(1); - assertThat(protoLog2.getBody().getStringValue()).isEmpty(); - assertThat(protoLog2.getAttributesList()) + assertThat(protoLog2.getBody().getKvlistValue().getValuesList()) .containsExactlyInAnyOrder( - KeyValue.newBuilder() - .setKey("event.name") - .setValue(AnyValue.newBuilder().setStringValue("event-name").build()) - .build(), KeyValue.newBuilder() .setKey("key") .setValue(AnyValue.newBuilder().setStringValue("value").build()) .build()); + assertThat(protoLog2.getAttributesList()) + .containsExactlyInAnyOrder( + KeyValue.newBuilder() + .setKey("event.name") + .setValue(AnyValue.newBuilder().setStringValue("namespace.event-name").build()) + .build()); assertThat(protoLog2.getSeverityText()).isEmpty(); assertThat(TraceId.fromBytes(protoLog2.getTraceId().toByteArray())) .isEqualTo(spanContext.getTraceId()); diff --git a/sdk-extensions/autoconfigure/src/testFullConfig/java/io/opentelemetry/sdk/autoconfigure/FullConfigTest.java b/sdk-extensions/autoconfigure/src/testFullConfig/java/io/opentelemetry/sdk/autoconfigure/FullConfigTest.java index 2097af7945c..e4ac7963ea8 100644 --- a/sdk-extensions/autoconfigure/src/testFullConfig/java/io/opentelemetry/sdk/autoconfigure/FullConfigTest.java +++ b/sdk-extensions/autoconfigure/src/testFullConfig/java/io/opentelemetry/sdk/autoconfigure/FullConfigTest.java @@ -38,6 +38,7 @@ import io.opentelemetry.proto.collector.trace.v1.TraceServiceGrpc; import io.opentelemetry.proto.common.v1.AnyValue; import io.opentelemetry.proto.common.v1.KeyValue; +import io.opentelemetry.proto.logs.v1.SeverityNumber; import io.opentelemetry.proto.metrics.v1.Metric; import io.opentelemetry.sdk.OpenTelemetrySdk; import java.util.ArrayList; @@ -207,7 +208,8 @@ void configures() throws Exception { logger.logRecordBuilder().setBody("info log message").setSeverity(Severity.INFO).emit(); EventLogger eventLogger = GlobalEventLoggerProvider.get().eventLoggerBuilder("test").build(); - eventLogger.emit("test-name", Attributes.builder().put("cow", "moo").build()); + eventLogger.builder("namespace.test-name").put("cow", "moo").emit(); + ; openTelemetrySdk.getSdkTracerProvider().forceFlush().join(10, TimeUnit.SECONDS); openTelemetrySdk.getSdkLoggerProvider().forceFlush().join(10, TimeUnit.SECONDS); @@ -329,17 +331,23 @@ void configures() throws Exception { assertThat(logRecord.getSeverityNumberValue()) .isEqualTo(Severity.INFO.getSeverityNumber()); }, - logRecord -> - assertThat(logRecord.getAttributesList()) - .containsExactlyInAnyOrder( - KeyValue.newBuilder() - .setKey("event.name") - .setValue(AnyValue.newBuilder().setStringValue("test-name").build()) - .build(), - KeyValue.newBuilder() - .setKey("cow") - .setValue(AnyValue.newBuilder().setStringValue("moo").build()) - .build())); + logRecord -> { + assertThat(logRecord.getBody().getKvlistValue().getValuesList()) + .containsExactlyInAnyOrder( + KeyValue.newBuilder() + .setKey("cow") + .setValue(AnyValue.newBuilder().setStringValue("moo").build()) + .build()); + assertThat(logRecord.getSeverityNumber()) + .isEqualTo(SeverityNumber.SEVERITY_NUMBER_INFO); + assertThat(logRecord.getAttributesList()) + .containsExactlyInAnyOrder( + KeyValue.newBuilder() + .setKey("event.name") + .setValue( + AnyValue.newBuilder().setStringValue("namespace.test-name").build()) + .build()); + }); } private static List getFirstDataPointLabels(Metric metric) { diff --git a/sdk/logs/src/main/java/io/opentelemetry/sdk/logs/internal/SdkEventBuilder.java b/sdk/logs/src/main/java/io/opentelemetry/sdk/logs/internal/SdkEventBuilder.java index ce4f5d69623..5daa5ae56f4 100644 --- a/sdk/logs/src/main/java/io/opentelemetry/sdk/logs/internal/SdkEventBuilder.java +++ b/sdk/logs/src/main/java/io/opentelemetry/sdk/logs/internal/SdkEventBuilder.java @@ -5,35 +5,83 @@ package io.opentelemetry.sdk.logs.internal; +import io.opentelemetry.api.common.AttributeKey; +import io.opentelemetry.api.common.Attributes; import io.opentelemetry.api.incubator.events.EventBuilder; +import io.opentelemetry.api.incubator.logs.AnyValue; +import io.opentelemetry.api.incubator.logs.ExtendedLogRecordBuilder; import io.opentelemetry.api.logs.LogRecordBuilder; +import io.opentelemetry.api.logs.Severity; +import io.opentelemetry.context.Context; +import io.opentelemetry.sdk.common.Clock; import java.time.Instant; +import java.util.HashMap; +import java.util.Map; import java.util.concurrent.TimeUnit; class SdkEventBuilder implements EventBuilder { + + private static final AttributeKey EVENT_NAME = AttributeKey.stringKey("event.name"); + + private final Map> payload = new HashMap<>(); + private final Clock clock; private final LogRecordBuilder logRecordBuilder; private final String eventName; + private boolean hasTimestamp = false; - SdkEventBuilder(LogRecordBuilder logRecordBuilder, String eventName) { + SdkEventBuilder(Clock clock, LogRecordBuilder logRecordBuilder, String eventName) { + this.clock = clock; this.logRecordBuilder = logRecordBuilder; this.eventName = eventName; } + @Override + public EventBuilder put(String key, AnyValue value) { + payload.put(key, value); + return this; + } + @Override public EventBuilder setTimestamp(long timestamp, TimeUnit unit) { this.logRecordBuilder.setTimestamp(timestamp, unit); + this.hasTimestamp = true; return this; } @Override public EventBuilder setTimestamp(Instant instant) { this.logRecordBuilder.setTimestamp(instant); + this.hasTimestamp = true; + return this; + } + + @Override + public EventBuilder setContext(Context context) { + logRecordBuilder.setContext(context); + return this; + } + + @Override + public EventBuilder setSeverity(Severity severity) { + logRecordBuilder.setSeverity(severity); + return this; + } + + @Override + public EventBuilder setAttributes(Attributes attributes) { + logRecordBuilder.setAllAttributes(attributes); return this; } @Override public void emit() { - SdkEventLoggerProvider.addEventName(logRecordBuilder, eventName); + if (!payload.isEmpty()) { + ((ExtendedLogRecordBuilder) logRecordBuilder).setBody(AnyValue.of(payload)); + } + if (!hasTimestamp) { + logRecordBuilder.setTimestamp(clock.now(), TimeUnit.NANOSECONDS); + } + logRecordBuilder.setAttribute(EVENT_NAME, eventName); logRecordBuilder.emit(); } } diff --git a/sdk/logs/src/main/java/io/opentelemetry/sdk/logs/internal/SdkEventLoggerProvider.java b/sdk/logs/src/main/java/io/opentelemetry/sdk/logs/internal/SdkEventLoggerProvider.java index 3eb6bb708ab..391547201df 100644 --- a/sdk/logs/src/main/java/io/opentelemetry/sdk/logs/internal/SdkEventLoggerProvider.java +++ b/sdk/logs/src/main/java/io/opentelemetry/sdk/logs/internal/SdkEventLoggerProvider.java @@ -5,18 +5,16 @@ package io.opentelemetry.sdk.logs.internal; -import io.opentelemetry.api.common.AttributeKey; -import io.opentelemetry.api.common.Attributes; import io.opentelemetry.api.incubator.events.EventBuilder; import io.opentelemetry.api.incubator.events.EventLogger; import io.opentelemetry.api.incubator.events.EventLoggerBuilder; import io.opentelemetry.api.incubator.events.EventLoggerProvider; -import io.opentelemetry.api.logs.LogRecordBuilder; import io.opentelemetry.api.logs.Logger; import io.opentelemetry.api.logs.LoggerBuilder; import io.opentelemetry.api.logs.LoggerProvider; +import io.opentelemetry.api.logs.Severity; +import io.opentelemetry.context.Context; import io.opentelemetry.sdk.common.Clock; -import java.util.concurrent.TimeUnit; /** * SDK implementation for {@link EventLoggerProvider}. @@ -26,7 +24,7 @@ */ public final class SdkEventLoggerProvider implements EventLoggerProvider { - static final AttributeKey EVENT_NAME = AttributeKey.stringKey("event.name"); + private static final Severity DEFAULT_SEVERITY = Severity.INFO; private final LoggerProvider delegateLoggerProvider; private final Clock clock; @@ -100,28 +98,14 @@ private SdkEventLogger(Clock clock, Logger delegateLogger) { } @Override - public EventBuilder builder(String eventName, Attributes attributes) { + public EventBuilder builder(String eventName) { return new SdkEventBuilder( + clock, delegateLogger .logRecordBuilder() - .setTimestamp(clock.now(), TimeUnit.NANOSECONDS) - .setAllAttributes(attributes), + .setSeverity(DEFAULT_SEVERITY) + .setContext(Context.current()), eventName); } - - @Override - public void emit(String eventName, Attributes attributes) { - LogRecordBuilder logRecordBuilder = - delegateLogger - .logRecordBuilder() - .setTimestamp(clock.now(), TimeUnit.NANOSECONDS) - .setAllAttributes(attributes); - addEventName(logRecordBuilder, eventName); - logRecordBuilder.emit(); - } - } - - static void addEventName(LogRecordBuilder logRecordBuilder, String eventName) { - logRecordBuilder.setAttribute(EVENT_NAME, eventName); } } diff --git a/sdk/logs/src/test/java/io/opentelemetry/sdk/logs/internal/SdkEventBuilderTest.java b/sdk/logs/src/test/java/io/opentelemetry/sdk/logs/internal/SdkEventBuilderTest.java index e53fd6549a9..bf45863d985 100644 --- a/sdk/logs/src/test/java/io/opentelemetry/sdk/logs/internal/SdkEventBuilderTest.java +++ b/sdk/logs/src/test/java/io/opentelemetry/sdk/logs/internal/SdkEventBuilderTest.java @@ -8,14 +8,15 @@ import static io.opentelemetry.api.common.AttributeKey.stringKey; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyLong; -import static org.mockito.ArgumentMatchers.anyString; -import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.never; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; +import io.opentelemetry.api.common.Attributes; import io.opentelemetry.api.logs.LogRecordBuilder; +import io.opentelemetry.api.logs.Severity; +import io.opentelemetry.context.Context; +import io.opentelemetry.sdk.common.Clock; import java.time.Instant; import java.util.concurrent.TimeUnit; import org.junit.jupiter.api.Test; @@ -29,16 +30,26 @@ void emit() { LogRecordBuilder logRecordBuilder = mock(LogRecordBuilder.class); when(logRecordBuilder.setTimestamp(anyLong(), any())).thenReturn(logRecordBuilder); when(logRecordBuilder.setAttribute(any(), any())).thenReturn(logRecordBuilder); + when(logRecordBuilder.setContext(any())).thenReturn(logRecordBuilder); + when(logRecordBuilder.setSeverity(any())).thenReturn(logRecordBuilder); + when(logRecordBuilder.setAllAttributes(any())).thenReturn(logRecordBuilder); Instant instant = Instant.now(); - new SdkEventBuilder(logRecordBuilder, eventName) + Context context = Context.root(); + Attributes attributes = Attributes.builder().put("extra-attribute", "value").build(); + new SdkEventBuilder(Clock.getDefault(), logRecordBuilder, eventName) .setTimestamp(123456L, TimeUnit.NANOSECONDS) .setTimestamp(instant) + .setContext(context) + .setSeverity(Severity.DEBUG) + .setAttributes(attributes) .emit(); - verify(logRecordBuilder, never()).setAttribute(eq(stringKey("event.domain")), anyString()); verify(logRecordBuilder).setAttribute(stringKey("event.name"), eventName); verify(logRecordBuilder).setTimestamp(123456L, TimeUnit.NANOSECONDS); verify(logRecordBuilder).setTimestamp(instant); + verify(logRecordBuilder).setContext(context); + verify(logRecordBuilder).setSeverity(Severity.DEBUG); + verify(logRecordBuilder).setAllAttributes(attributes); verify(logRecordBuilder).emit(); } } diff --git a/sdk/logs/src/test/java/io/opentelemetry/sdk/logs/internal/SdkEventLoggerProviderTest.java b/sdk/logs/src/test/java/io/opentelemetry/sdk/logs/internal/SdkEventLoggerProviderTest.java index 847d3142e40..5c30a6b305d 100644 --- a/sdk/logs/src/test/java/io/opentelemetry/sdk/logs/internal/SdkEventLoggerProviderTest.java +++ b/sdk/logs/src/test/java/io/opentelemetry/sdk/logs/internal/SdkEventLoggerProviderTest.java @@ -5,18 +5,24 @@ package io.opentelemetry.sdk.logs.internal; -import static io.opentelemetry.api.common.AttributeKey.stringKey; import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.assertThat; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; +import com.google.common.collect.ImmutableMap; import io.opentelemetry.api.common.Attributes; import io.opentelemetry.api.incubator.events.EventLogger; +import io.opentelemetry.api.incubator.logs.AnyValue; +import io.opentelemetry.api.logs.Severity; import io.opentelemetry.sdk.common.Clock; import io.opentelemetry.sdk.common.InstrumentationScopeInfo; import io.opentelemetry.sdk.logs.ReadWriteLogRecord; import io.opentelemetry.sdk.logs.SdkLoggerProvider; import io.opentelemetry.sdk.resources.Resource; +import java.util.Arrays; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicReference; import org.junit.jupiter.api.Test; @@ -28,7 +34,7 @@ class SdkEventLoggerProviderTest { private final Clock clock = mock(Clock.class); private final AtomicReference seenLog = new AtomicReference<>(); - private final SdkEventLoggerProvider eventLoggerProvider = + private final SdkEventLoggerProvider eventEmitterProvider = SdkEventLoggerProvider.create( SdkLoggerProvider.builder() .setResource(RESOURCE) @@ -37,44 +43,81 @@ class SdkEventLoggerProviderTest { clock); @Test - void emit() { + void builder() { when(clock.now()).thenReturn(10L); - eventLoggerProvider - .eventLoggerBuilder("test-scope") - .build() - .emit( - "event-name", - Attributes.builder() - .put("key1", "value1") - // should be overridden by the eventName argument passed to emit - .put("event.name", "foo") - .build()); + long yesterday = System.nanoTime() - TimeUnit.DAYS.toNanos(1); + EventLogger eventLogger = eventEmitterProvider.eventLoggerBuilder("test-scope").build(); + + eventLogger + .builder("namespace.event-name") + .put("key1", "value1") + .setTimestamp(yesterday, TimeUnit.NANOSECONDS) + .setSeverity(Severity.DEBUG) + .setAttributes(Attributes.builder().put("extra-attribute", "value").build()) + .emit(); assertThat(seenLog.get().toLogRecordData()) .hasResource(RESOURCE) .hasInstrumentationScope(InstrumentationScopeInfo.create("test-scope")) - .hasTimestamp(10L) + .hasTimestamp(yesterday) + .hasSeverity(Severity.DEBUG) .hasAttributes( - Attributes.builder().put("key1", "value1").put("event.name", "event-name").build()); + Attributes.builder() + .put("event.name", "namespace.event-name") + .put("extra-attribute", "value") + .build()); + assertThat(seenLog.get().toLogRecordData().getObservedTimestampEpochNanos()).isPositive(); + AnyValue expectedPayload = + AnyValue.of(Collections.singletonMap("key1", AnyValue.of("value1"))); + assertThat(((AnyValueBody) seenLog.get().toLogRecordData().getBody()).asAnyValue()) + .isEqualTo(expectedPayload); } @Test - void builder() { - long yesterday = System.nanoTime() - TimeUnit.DAYS.toNanos(1); - Attributes attributes = Attributes.of(stringKey("foo"), "bar"); + void eventBuilder_FullPayload() { + EventLogger eventLogger = eventEmitterProvider.get("test-scoe"); - EventLogger eventLogger = eventLoggerProvider.eventLoggerBuilder("test-scope").build(); - - eventLogger.builder("testing", attributes).setTimestamp(yesterday, TimeUnit.NANOSECONDS).emit(); - verifySeen(yesterday, attributes); - } + eventLogger + .builder("namespace.my-event-name") + // Helper methods to set primitive types + .put("stringKey", "value") + .put("longKey", 1L) + .put("doubleKey", 1.0) + .put("boolKey", true) + // Helper methods to set primitive array types + .put("stringArrKey", "value1", "value2") + .put("longArrKey", 1L, 2L) + .put("doubleArrKey", 1.0, 2.0) + .put("boolArrKey", true, false) + // Set AnyValue types to encode complex data + .put( + "anyValueKey", + AnyValue.of( + ImmutableMap.of( + "childKey1", AnyValue.of("value"), + "childKey2", AnyValue.of("value")))) + .emit(); - private void verifySeen(long timestamp, Attributes attributes) { - assertThat(seenLog.get().toLogRecordData()) - .hasResource(RESOURCE) - .hasInstrumentationScope(InstrumentationScopeInfo.create("test-scope")) - .hasTimestamp(timestamp) - .hasAttributes(attributes.toBuilder().put("event.name", "testing").build()); + Map> expectedPayload = new HashMap<>(); + expectedPayload.put("stringKey", AnyValue.of("value")); + expectedPayload.put("longKey", AnyValue.of(1L)); + expectedPayload.put("doubleKey", AnyValue.of(1.0)); + expectedPayload.put("boolKey", AnyValue.of(true)); + expectedPayload.put( + "stringArrKey", AnyValue.of(Arrays.asList(AnyValue.of("value1"), AnyValue.of("value2")))); + expectedPayload.put("longArrKey", AnyValue.of(Arrays.asList(AnyValue.of(1L), AnyValue.of(2L)))); + expectedPayload.put( + "doubleArrKey", AnyValue.of(Arrays.asList(AnyValue.of(1.0), AnyValue.of(2.0)))); + expectedPayload.put( + "boolArrKey", AnyValue.of(Arrays.asList(AnyValue.of(true), AnyValue.of(false)))); + expectedPayload.put( + "anyValueKey", + AnyValue.of( + ImmutableMap.of( + "childKey1", AnyValue.of("value"), + "childKey2", AnyValue.of("value")))); + assertThat(((AnyValueBody) seenLog.get().toLogRecordData().getBody()).asAnyValue()) + .isEqualTo(AnyValue.of(expectedPayload)); } } From 98eded9f862e1c404d761fd680cfb0c51acade34 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 29 Mar 2024 16:48:29 -0500 Subject: [PATCH 317/901] Update dependency com.squareup.wire:wire-bom to v4.9.8 (#6302) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- buildSrc/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts index 04d34f71bbc..1bbea4ba0c0 100644 --- a/buildSrc/build.gradle.kts +++ b/buildSrc/build.gradle.kts @@ -50,7 +50,7 @@ repositories { } dependencies { - implementation(enforcedPlatform("com.squareup.wire:wire-bom:4.9.7")) + implementation(enforcedPlatform("com.squareup.wire:wire-bom:4.9.8")) implementation("com.google.auto.value:auto-value-annotations:1.10.4") // When updating, update above in plugins too implementation("com.diffplug.spotless:spotless-plugin-gradle:6.25.0") From ec464079ee611c2fe8830c338b7dcac57161c803 Mon Sep 17 00:00:00 2001 From: Gregor Zeitlinger Date: Tue, 2 Apr 2024 18:47:00 +0200 Subject: [PATCH 318/901] service.instance.id implementation (#6226) Co-authored-by: Jack Berg --- .../internal/EnvironmentResourceProvider.java | 5 +- .../ServiceInstanceIdResourceProvider.java | 47 ++++++++++++ ...try.sdk.autoconfigure.spi.ResourceProvider | 1 + ...ServiceInstanceIdResourceProviderTest.java | 71 +++++++++++++++++++ 4 files changed, 122 insertions(+), 2 deletions(-) create mode 100644 sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/resources/ServiceInstanceIdResourceProvider.java create mode 100644 sdk-extensions/incubator/src/main/resources/META-INF/services/io.opentelemetry.sdk.autoconfigure.spi.ResourceProvider create mode 100644 sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/resources/ServiceInstanceIdResourceProviderTest.java diff --git a/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/internal/EnvironmentResourceProvider.java b/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/internal/EnvironmentResourceProvider.java index 5e1dfcf356c..98af5c0d7e5 100644 --- a/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/internal/EnvironmentResourceProvider.java +++ b/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/internal/EnvironmentResourceProvider.java @@ -22,7 +22,8 @@ public Resource createResource(ConfigProperties config) { @Override public int order() { - // Environment resource takes precedent over all other ResourceProviders - return Integer.MAX_VALUE; + // Environment resource takes precedent over all other ResourceProviders except + // ServiceInstanceIdResourceProvider. + return Integer.MAX_VALUE - 1; } } diff --git a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/resources/ServiceInstanceIdResourceProvider.java b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/resources/ServiceInstanceIdResourceProvider.java new file mode 100644 index 00000000000..97e84f3c686 --- /dev/null +++ b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/resources/ServiceInstanceIdResourceProvider.java @@ -0,0 +1,47 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.sdk.extension.incubator.resources; + +import io.opentelemetry.api.common.AttributeKey; +import io.opentelemetry.api.common.Attributes; +import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties; +import io.opentelemetry.sdk.autoconfigure.spi.ResourceProvider; +import io.opentelemetry.sdk.autoconfigure.spi.internal.ConditionalResourceProvider; +import io.opentelemetry.sdk.resources.Resource; +import java.util.UUID; + +/** + * does not implement {@link ResourceProvider}, because it depends on all attributes discovered by + * the other providers. + */ +public final class ServiceInstanceIdResourceProvider implements ConditionalResourceProvider { + + public static final AttributeKey SERVICE_INSTANCE_ID = + AttributeKey.stringKey("service.instance.id"); + + // multiple calls to this resource provider should return the same value + private static final Resource RANDOM = + Resource.create(Attributes.of(SERVICE_INSTANCE_ID, UUID.randomUUID().toString())); + + static final int ORDER = Integer.MAX_VALUE; + + @Override + public Resource createResource(ConfigProperties config) { + return RANDOM; + } + + @Override + public boolean shouldApply(ConfigProperties config, Resource existing) { + return existing.getAttribute(SERVICE_INSTANCE_ID) == null; + } + + @Override + public int order() { + // Run after environment resource provider - only set the service instance ID if it + // hasn't been set by any other provider or the user. + return ORDER; + } +} diff --git a/sdk-extensions/incubator/src/main/resources/META-INF/services/io.opentelemetry.sdk.autoconfigure.spi.ResourceProvider b/sdk-extensions/incubator/src/main/resources/META-INF/services/io.opentelemetry.sdk.autoconfigure.spi.ResourceProvider new file mode 100644 index 00000000000..189af738dcf --- /dev/null +++ b/sdk-extensions/incubator/src/main/resources/META-INF/services/io.opentelemetry.sdk.autoconfigure.spi.ResourceProvider @@ -0,0 +1 @@ +io.opentelemetry.sdk.extension.incubator.resources.ServiceInstanceIdResourceProvider diff --git a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/resources/ServiceInstanceIdResourceProviderTest.java b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/resources/ServiceInstanceIdResourceProviderTest.java new file mode 100644 index 00000000000..59acb29e2dd --- /dev/null +++ b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/resources/ServiceInstanceIdResourceProviderTest.java @@ -0,0 +1,71 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.sdk.extension.incubator.resources; + +import static org.assertj.core.api.Assertions.assertThat; + +import com.google.common.collect.ImmutableMap; +import io.opentelemetry.api.common.Attributes; +import io.opentelemetry.api.common.AttributesBuilder; +import io.opentelemetry.sdk.autoconfigure.spi.internal.DefaultConfigProperties; +import io.opentelemetry.sdk.resources.Resource; +import java.util.Collections; +import java.util.Map; +import java.util.stream.Stream; +import org.junit.jupiter.api.DynamicTest; +import org.junit.jupiter.api.TestFactory; + +class ServiceInstanceIdResourceProviderTest { + + private static class TestCase { + private final String name; + final String expectedValue; + final Map attributes; + + TestCase(String name, String expectedValue, Map attributes) { + this.name = name; + this.expectedValue = expectedValue; + this.attributes = attributes; + } + } + + @TestFactory + Stream createResource() { + return Stream.of( + new TestCase( + "user provided service.instance.id", + null, + ImmutableMap.of("service.instance.id", "custom")), + new TestCase("random value", "random", Collections.emptyMap())) + .map( + testCase -> + DynamicTest.dynamicTest( + testCase.name, + () -> { + ServiceInstanceIdResourceProvider provider = + new ServiceInstanceIdResourceProvider(); + DefaultConfigProperties config = + DefaultConfigProperties.createFromMap(Collections.emptyMap()); + AttributesBuilder builder = Attributes.builder(); + testCase.attributes.forEach(builder::put); + Resource existing = Resource.create(builder.build()); + Resource resource = + provider.shouldApply(config, existing) + ? provider.createResource(config) + : Resource.empty(); + + String actual = + resource + .getAttributes() + .get(ServiceInstanceIdResourceProvider.SERVICE_INSTANCE_ID); + if ("random".equals(testCase.expectedValue)) { + assertThat(actual).isNotNull(); + } else { + assertThat(actual).isEqualTo(testCase.expectedValue); + } + })); + } +} From 40d18f614a58020918a961ffdca401ca73ef4602 Mon Sep 17 00:00:00 2001 From: Pranav Sharma Date: Tue, 2 Apr 2024 12:53:42 -0400 Subject: [PATCH 319/901] Add GCP resource detector to ResourceProvider list (#6336) --- sdk-extensions/autoconfigure/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/sdk-extensions/autoconfigure/README.md b/sdk-extensions/autoconfigure/README.md index 6a658a39fe3..92def7c0b3c 100644 --- a/sdk-extensions/autoconfigure/README.md +++ b/sdk-extensions/autoconfigure/README.md @@ -197,6 +197,7 @@ your own ResourceProvider, or optionally use an artifact that includes built-in * [io.opentelemetry.contrib:opentelemetry-aws-resources](https://github.com/open-telemetry/opentelemetry-java-contrib/tree/main/aws-resources) includes providers for [common AWS resources](https://github.com/open-telemetry/opentelemetry-java-contrib/tree/main/aws-resources/src/main/java/io/opentelemetry/contrib/aws/resource) +* [io.opentelemetry.contrib:opentelemetry-gcp-resources](https://github.com/open-telemetry/opentelemetry-java-contrib/tree/main/gcp-resources) includes providers for [common GCP resources](https://github.com/open-telemetry/opentelemetry-java-contrib/tree/main/gcp-resources/src/main/java/io/opentelemetry/contrib/gcp/resource) #### Disabling Automatic ResourceProviders From bc5eb9ea24b32f7ce906fcf46e3e321e6f8455e2 Mon Sep 17 00:00:00 2001 From: Asaf Mesika Date: Wed, 3 Apr 2024 17:24:04 +0300 Subject: [PATCH 320/901] Add toBuilder() at PrometheusHttpServer (#6333) Co-authored-by: jack-berg <34418638+jack-berg@users.noreply.github.com> --- .../prometheus/PrometheusHttpServer.java | 10 ++++++ .../PrometheusHttpServerBuilder.java | 12 +++++++ .../prometheus/PrometheusHttpServerTest.java | 32 +++++++++++++++++++ 3 files changed, 54 insertions(+) diff --git a/exporters/prometheus/src/main/java/io/opentelemetry/exporter/prometheus/PrometheusHttpServer.java b/exporters/prometheus/src/main/java/io/opentelemetry/exporter/prometheus/PrometheusHttpServer.java index 9024fe4f97b..388fe1a4f6b 100644 --- a/exporters/prometheus/src/main/java/io/opentelemetry/exporter/prometheus/PrometheusHttpServer.java +++ b/exporters/prometheus/src/main/java/io/opentelemetry/exporter/prometheus/PrometheusHttpServer.java @@ -36,6 +36,7 @@ public final class PrometheusHttpServer implements MetricReader { private final PrometheusMetricReader prometheusMetricReader; private final PrometheusRegistry prometheusRegistry; private final String host; + private final PrometheusHttpServerBuilder builder; /** * Returns a new {@link PrometheusHttpServer} which can be registered to an {@link @@ -52,12 +53,14 @@ public static PrometheusHttpServerBuilder builder() { } PrometheusHttpServer( + PrometheusHttpServerBuilder builder, String host, int port, @Nullable ExecutorService executor, PrometheusRegistry prometheusRegistry, boolean otelScopeEnabled, @Nullable Predicate allowedResourceAttributesFilter) { + this.builder = builder; this.prometheusMetricReader = new PrometheusMetricReader(otelScopeEnabled, allowedResourceAttributesFilter); this.host = host; @@ -121,6 +124,13 @@ public String toString() { return "PrometheusHttpServer{address=" + getAddress() + "}"; } + /** + * Returns a new {@link PrometheusHttpServerBuilder} with the same configuration as this instance. + */ + public PrometheusHttpServerBuilder toBuilder() { + return new PrometheusHttpServerBuilder(builder); + } + // Visible for testing. InetSocketAddress getAddress() { return new InetSocketAddress(host, httpServer.getPort()); diff --git a/exporters/prometheus/src/main/java/io/opentelemetry/exporter/prometheus/PrometheusHttpServerBuilder.java b/exporters/prometheus/src/main/java/io/opentelemetry/exporter/prometheus/PrometheusHttpServerBuilder.java index 9c4594411f5..1d53679b52b 100644 --- a/exporters/prometheus/src/main/java/io/opentelemetry/exporter/prometheus/PrometheusHttpServerBuilder.java +++ b/exporters/prometheus/src/main/java/io/opentelemetry/exporter/prometheus/PrometheusHttpServerBuilder.java @@ -49,6 +49,7 @@ public PrometheusHttpServerBuilder setExecutor(ExecutorService executor) { } /** Sets the {@link PrometheusRegistry} to be used for {@link PrometheusHttpServer}. */ + @SuppressWarnings("UnusedReturnValue") public PrometheusHttpServerBuilder setPrometheusRegistry(PrometheusRegistry prometheusRegistry) { requireNonNull(prometheusRegistry, "prometheusRegistry"); this.prometheusRegistry = prometheusRegistry; @@ -56,6 +57,7 @@ public PrometheusHttpServerBuilder setPrometheusRegistry(PrometheusRegistry prom } /** Set if the {@code otel_scope_*} attributes are generated. Default is {@code true}. */ + @SuppressWarnings("UnusedReturnValue") public PrometheusHttpServerBuilder setOtelScopeEnabled(boolean otelScopeEnabled) { this.otelScopeEnabled = otelScopeEnabled; return this; @@ -83,6 +85,7 @@ public PrometheusHttpServerBuilder setAllowedResourceAttributesFilter( */ public PrometheusHttpServer build() { return new PrometheusHttpServer( + new PrometheusHttpServerBuilder(this), // copy to prevent modification host, port, executor, @@ -92,4 +95,13 @@ public PrometheusHttpServer build() { } PrometheusHttpServerBuilder() {} + + PrometheusHttpServerBuilder(PrometheusHttpServerBuilder builder) { + this.host = builder.host; + this.port = builder.port; + this.prometheusRegistry = builder.prometheusRegistry; + this.otelScopeEnabled = builder.otelScopeEnabled; + this.allowedResourceAttributesFilter = builder.allowedResourceAttributesFilter; + this.executor = builder.executor; + } } diff --git a/exporters/prometheus/src/test/java/io/opentelemetry/exporter/prometheus/PrometheusHttpServerTest.java b/exporters/prometheus/src/test/java/io/opentelemetry/exporter/prometheus/PrometheusHttpServerTest.java index 93842d78a26..3fc114c1ed3 100644 --- a/exporters/prometheus/src/test/java/io/opentelemetry/exporter/prometheus/PrometheusHttpServerTest.java +++ b/exporters/prometheus/src/test/java/io/opentelemetry/exporter/prometheus/PrometheusHttpServerTest.java @@ -34,6 +34,7 @@ import io.opentelemetry.sdk.metrics.internal.data.ImmutableSumData; import io.opentelemetry.sdk.resources.Resource; import io.prometheus.metrics.exporter.httpserver.HTTPServer; +import io.prometheus.metrics.model.registry.PrometheusRegistry; import java.io.ByteArrayInputStream; import java.io.IOException; import java.net.ServerSocket; @@ -41,11 +42,13 @@ import java.util.Collection; import java.util.Collections; import java.util.List; +import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.ScheduledThreadPoolExecutor; import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.atomic.AtomicReference; +import java.util.function.Predicate; import java.util.zip.GZIPInputStream; import org.assertj.core.api.InstanceOfAssertFactories; import org.junit.jupiter.api.AfterAll; @@ -387,4 +390,33 @@ private static List generateTestData() { ImmutableDoublePointData.create( 123, 456, Attributes.of(stringKey("kp"), "vp"), 3.5))))); } + + @Test + void toBuilder() { + PrometheusHttpServerBuilder builder = PrometheusHttpServer.builder(); + builder.setHost("localhost"); + builder.setPort(1234); + builder.setOtelScopeEnabled(false); + + Predicate resourceAttributesFilter = s -> false; + builder.setAllowedResourceAttributesFilter(resourceAttributesFilter); + + ExecutorService executor = Executors.newSingleThreadExecutor(); + builder.setExecutor(executor); + + PrometheusRegistry prometheusRegistry = new PrometheusRegistry(); + builder.setPrometheusRegistry(prometheusRegistry); + + PrometheusHttpServer httpServer = builder.build(); + PrometheusHttpServerBuilder fromOriginalBuilder = httpServer.toBuilder(); + httpServer.close(); + assertThat(fromOriginalBuilder) + .isInstanceOf(PrometheusHttpServerBuilder.class) + .hasFieldOrPropertyWithValue("host", "localhost") + .hasFieldOrPropertyWithValue("port", 1234) + .hasFieldOrPropertyWithValue("otelScopeEnabled", false) + .hasFieldOrPropertyWithValue("allowedResourceAttributesFilter", resourceAttributesFilter) + .hasFieldOrPropertyWithValue("executor", executor) + .hasFieldOrPropertyWithValue("prometheusRegistry", prometheusRegistry); + } } From 1dde2550b01fd5fa4582c8ac5ab74c34a445ff5f Mon Sep 17 00:00:00 2001 From: jack-berg <34418638+jack-berg@users.noreply.github.com> Date: Wed, 3 Apr 2024 10:23:17 -0500 Subject: [PATCH 321/901] Use synchronized instead of reentrant lock in explicit bucket histogram (#6309) --- CONTRIBUTING.md | 8 ++++++++ .../DoubleExplicitBucketHistogramAggregator.java | 15 ++++----------- 2 files changed, 12 insertions(+), 11 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 491f53be81a..3b8c7b62f36 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -138,6 +138,14 @@ uses [google-java-format](https://github.com/google/google-java-format) library: * Adding `toString()` overrides on classes is encouraged, but we only use `toString()` to provide debugging assistance. The implementations of all `toString()` methods should be considered to be unstable unless explicitly documented otherwise. +* Avoid synchronizing using a class's intrinsic lock. Instead, synchronize on a dedicated lock object. E.g: + ```java + private final Object lock = new Object(); + + public void doSomething() { + synchronized (lock) { ... } + } + ``` If you notice any practice being applied in the project consistently that isn't listed here, please consider a pull request to add it. diff --git a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/aggregator/DoubleExplicitBucketHistogramAggregator.java b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/aggregator/DoubleExplicitBucketHistogramAggregator.java index 40850a8bd97..82d71f25313 100644 --- a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/aggregator/DoubleExplicitBucketHistogramAggregator.java +++ b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/aggregator/DoubleExplicitBucketHistogramAggregator.java @@ -26,7 +26,6 @@ import java.util.Collection; import java.util.Collections; import java.util.List; -import java.util.concurrent.locks.ReentrantLock; import java.util.function.Supplier; import javax.annotation.Nullable; @@ -95,6 +94,8 @@ static final class Handle extends AggregatorHandle exemplars, boolean reset) { - lock.lock(); - try { + synchronized (lock) { HistogramPointData pointData; if (reusablePoint == null) { pointData = @@ -180,8 +178,6 @@ protected HistogramPointData doAggregateThenMaybeReset( Arrays.fill(this.counts, 0); } return pointData; - } finally { - lock.unlock(); } } @@ -189,15 +185,12 @@ protected HistogramPointData doAggregateThenMaybeReset( protected void doRecordDouble(double value) { int bucketIndex = ExplicitBucketHistogramUtils.findBucketIndex(this.boundaries, value); - lock.lock(); - try { + synchronized (lock) { this.sum += value; this.min = Math.min(this.min, value); this.max = Math.max(this.max, value); this.count++; this.counts[bucketIndex]++; - } finally { - lock.unlock(); } } From 6c11235f6f30eb5313fe66d58026a985ed834f12 Mon Sep 17 00:00:00 2001 From: jack-berg <34418638+jack-berg@users.noreply.github.com> Date: Thu, 4 Apr 2024 09:42:37 -0500 Subject: [PATCH 322/901] Restore build fail on warning (#6347) --- buildSrc/src/main/kotlin/otel.java-conventions.gradle.kts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/buildSrc/src/main/kotlin/otel.java-conventions.gradle.kts b/buildSrc/src/main/kotlin/otel.java-conventions.gradle.kts index f9f7e245011..10fef3da385 100644 --- a/buildSrc/src/main/kotlin/otel.java-conventions.gradle.kts +++ b/buildSrc/src/main/kotlin/otel.java-conventions.gradle.kts @@ -79,7 +79,10 @@ tasks { // https://groups.google.com/forum/#!topic/bazel-discuss/_R3A9TJSoPM "-Xlint:-processing", // We suppress the "options" warning because it prevents compilation on modern JDKs - "-Xlint:-options" + "-Xlint:-options", + + // Fail build on any warning + "-Werror", ), ) } From fc5469dc493eb61b7b34c2e7c39f81423d5aba69 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 4 Apr 2024 08:12:58 -0700 Subject: [PATCH 323/901] Update dependency nl.jqno.equalsverifier:equalsverifier to v3.16.1 (#6346) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- dependencyManagement/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index c7942fff49c..debeb447fb3 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -71,7 +71,7 @@ val DEPENDENCIES = listOf( "io.opentracing:opentracing-noop:0.33.0", "io.prometheus:prometheus-metrics-exporter-httpserver:1.2.0", "junit:junit:4.13.2", - "nl.jqno.equalsverifier:equalsverifier:3.16", + "nl.jqno.equalsverifier:equalsverifier:3.16.1", "org.awaitility:awaitility:4.2.1", "org.bouncycastle:bcpkix-jdk15on:1.70", "org.codehaus.mojo:animal-sniffer-annotations:1.23", From b416aceeed4ddd16a88394f2fcefd6478bb728ed Mon Sep 17 00:00:00 2001 From: jack-berg <34418638+jack-berg@users.noreply.github.com> Date: Thu, 4 Apr 2024 12:09:00 -0500 Subject: [PATCH 324/901] Move mateusz to emeritus (#6345) Co-authored-by: John Watson --- README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index dc2dfe5cd2c..aa2737f78ba 100644 --- a/README.md +++ b/README.md @@ -304,7 +304,6 @@ Approvers ([@open-telemetry/java-approvers](https://github.com/orgs/open-telemet - [Jason Plumb](https://github.com/breedx-splk), Splunk - [Josh Suereth](https://github.com/jsuereth), Google -- [Mateusz Rzeszutek](https://github.com/mateuszrzeszutek), Splunk - [Trask Stalnaker](https://github.com/trask), Microsoft *Find more about the approver role in [community repository](https://github.com/open-telemetry/community/blob/master/community-membership.md#approver).* @@ -314,10 +313,11 @@ Maintainers ([@open-telemetry/java-maintainers](https://github.com/orgs/open-tel - [Jack Berg](https://github.com/jack-berg), New Relic - [John Watson](https://github.com/jkwatson), Verta.ai -Maintainers Emeritus: +Emeritus: -- [Bogdan Drutu](https://github.com/BogdanDrutu), Splunk -- [Carlos Alberto](https://github.com/carlosalberto), LightStep +- Maintainer [Bogdan Drutu](https://github.com/BogdanDrutu) +- Maintainer [Carlos Alberto](https://github.com/carlosalberto) +- Approver [Mateusz Rzeszutek](https://github.com/mateuszrzeszutek) *Find more about the maintainer role in [community repository](https://github.com/open-telemetry/community/blob/master/community-membership.md#maintainer).* From d7370f3367dfbf378cbe594f316b7e282162caec Mon Sep 17 00:00:00 2001 From: jack-berg <34418638+jack-berg@users.noreply.github.com> Date: Thu, 4 Apr 2024 12:09:17 -0500 Subject: [PATCH 325/901] Promote Span addLink to stable API (#6317) --- .../java/io/opentelemetry/api/trace/Span.java | 41 ++++++++++++++ .../api/trace/DefaultTracerTest.java | 12 ++++ .../api/incubator/trace/ExtendedSpan.java | 56 ------------------- .../current_vs_latest/opentelemetry-api.txt | 5 +- .../opencensusshim/DelegatingSpanTest.java | 6 +- sdk/trace/build.gradle.kts | 2 - .../io/opentelemetry/sdk/trace/SdkSpan.java | 3 +- .../opentelemetry/sdk/trace/SdkSpanTest.java | 20 ++----- 8 files changed, 67 insertions(+), 78 deletions(-) delete mode 100644 api/incubator/src/main/java/io/opentelemetry/api/incubator/trace/ExtendedSpan.java diff --git a/api/all/src/main/java/io/opentelemetry/api/trace/Span.java b/api/all/src/main/java/io/opentelemetry/api/trace/Span.java index a54e7666c9c..6f8f790a112 100644 --- a/api/all/src/main/java/io/opentelemetry/api/trace/Span.java +++ b/api/all/src/main/java/io/opentelemetry/api/trace/Span.java @@ -359,6 +359,47 @@ default Span recordException(Throwable exception) { */ Span updateName(String name); + /** + * Adds a link to this {@code Span}. + * + *

      Links are used to link {@link Span}s in different traces. Used (for example) in batching + * operations, where a single batch handler processes multiple requests from different traces or + * the same trace. + * + *

      Implementations may ignore calls with an {@linkplain SpanContext#isValid() invalid span + * context}. + * + *

      Callers should prefer to add links before starting the span via {@link + * SpanBuilder#addLink(SpanContext)} if possible. + * + * @param spanContext the context of the linked {@code Span}. + * @return this. + */ + default Span addLink(SpanContext spanContext) { + return addLink(spanContext, Attributes.empty()); + } + + /** + * Adds a link to this {@code Span}. + * + *

      Links are used to link {@link Span}s in different traces. Used (for example) in batching + * operations, where a single batch handler processes multiple requests from different traces or + * the same trace. + * + *

      Implementations may ignore calls with an {@linkplain SpanContext#isValid() invalid span + * context}. + * + *

      Callers should prefer to add links before starting the span via {@link + * SpanBuilder#addLink(SpanContext, Attributes)} if possible. + * + * @param spanContext the context of the linked {@code Span}. + * @param attributes the attributes of the {@code Link}. + * @return this. + */ + default Span addLink(SpanContext spanContext, Attributes attributes) { + return this; + } + /** * Marks the end of {@code Span} execution. * diff --git a/api/all/src/test/java/io/opentelemetry/api/trace/DefaultTracerTest.java b/api/all/src/test/java/io/opentelemetry/api/trace/DefaultTracerTest.java index e1379592062..dc364e96457 100644 --- a/api/all/src/test/java/io/opentelemetry/api/trace/DefaultTracerTest.java +++ b/api/all/src/test/java/io/opentelemetry/api/trace/DefaultTracerTest.java @@ -6,7 +6,9 @@ package io.opentelemetry.api.trace; import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatCode; +import io.opentelemetry.api.common.Attributes; import io.opentelemetry.context.Context; import org.junit.jupiter.api.Test; @@ -78,4 +80,14 @@ void testSpanContextPropagation_fromContextThenNoParent() { Span span = defaultTracer.spanBuilder(SPAN_NAME).setParent(context).setNoParent().startSpan(); assertThat(span.getSpanContext()).isEqualTo(SpanContext.getInvalid()); } + + @Test + void addLink() { + Span span = Span.fromContext(Context.root()); + assertThatCode(() -> span.addLink(null)).doesNotThrowAnyException(); + assertThatCode(() -> span.addLink(SpanContext.getInvalid())).doesNotThrowAnyException(); + assertThatCode(() -> span.addLink(null, null)).doesNotThrowAnyException(); + assertThatCode(() -> span.addLink(SpanContext.getInvalid(), Attributes.empty())) + .doesNotThrowAnyException(); + } } diff --git a/api/incubator/src/main/java/io/opentelemetry/api/incubator/trace/ExtendedSpan.java b/api/incubator/src/main/java/io/opentelemetry/api/incubator/trace/ExtendedSpan.java deleted file mode 100644 index 93bfc25ecc1..00000000000 --- a/api/incubator/src/main/java/io/opentelemetry/api/incubator/trace/ExtendedSpan.java +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package io.opentelemetry.api.incubator.trace; - -import io.opentelemetry.api.common.Attributes; -import io.opentelemetry.api.trace.Span; -import io.opentelemetry.api.trace.SpanBuilder; -import io.opentelemetry.api.trace.SpanContext; - -/** Extended {@link Span} with experimental APIs. */ -public interface ExtendedSpan extends Span { - - /** - * Adds a link to this {@code Span}. - * - *

      Links are used to link {@link Span}s in different traces. Used (for example) in batching - * operations, where a single batch handler processes multiple requests from different traces or - * the same trace. - * - *

      Implementations may ignore calls with an {@linkplain SpanContext#isValid() invalid span - * context}. - * - *

      Callers should prefer to add links before starting the span via {@link - * SpanBuilder#addLink(SpanContext)} if possible. - * - * @param spanContext the context of the linked {@code Span}. - * @return this. - */ - default Span addLink(SpanContext spanContext) { - return addLink(spanContext, Attributes.empty()); - } - - /** - * Adds a link to this {@code Span}. - * - *

      Links are used to link {@link Span}s in different traces. Used (for example) in batching - * operations, where a single batch handler processes multiple requests from different traces or - * the same trace. - * - *

      Implementations may ignore calls with an {@linkplain SpanContext#isValid() invalid span - * context}. - * - *

      Callers should prefer to add links before starting the span via {@link - * SpanBuilder#addLink(SpanContext, Attributes)} if possible. - * - * @param spanContext the context of the linked {@code Span}. - * @param attributes the attributes of the {@code Link}. - * @return this. - */ - default Span addLink(SpanContext spanContext, Attributes attributes) { - return this; - } -} diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-api.txt b/docs/apidiffs/current_vs_latest/opentelemetry-api.txt index df26146497b..815a9fed06c 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-api.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-api.txt @@ -1,2 +1,5 @@ Comparing source compatibility of against -No changes. \ No newline at end of file +*** MODIFIED INTERFACE: PUBLIC ABSTRACT io.opentelemetry.api.trace.Span (not serializable) + === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 + +++ NEW METHOD: PUBLIC(+) io.opentelemetry.api.trace.Span addLink(io.opentelemetry.api.trace.SpanContext) + +++ NEW METHOD: PUBLIC(+) io.opentelemetry.api.trace.Span addLink(io.opentelemetry.api.trace.SpanContext, io.opentelemetry.api.common.Attributes) diff --git a/opencensus-shim/src/test/java/io/opentelemetry/opencensusshim/DelegatingSpanTest.java b/opencensus-shim/src/test/java/io/opentelemetry/opencensusshim/DelegatingSpanTest.java index a8f69082ee9..2843ed89061 100644 --- a/opencensus-shim/src/test/java/io/opentelemetry/opencensusshim/DelegatingSpanTest.java +++ b/opencensus-shim/src/test/java/io/opentelemetry/opencensusshim/DelegatingSpanTest.java @@ -11,6 +11,7 @@ import io.opentelemetry.api.common.AttributeKey; import io.opentelemetry.api.common.Attributes; import io.opentelemetry.api.trace.Span; +import io.opentelemetry.api.trace.SpanContext; import io.opentelemetry.api.trace.StatusCode; import io.opentelemetry.context.Context; import java.lang.reflect.InvocationTargetException; @@ -120,7 +121,10 @@ static Stream delegateMethodsProvider() { // `true` Arguments.of("isRecording", new Class[] {}, times(0)), // called twice: once in constructor, then once during delegation - Arguments.of("getSpanContext", new Class[] {}, times(2))); + Arguments.of("getSpanContext", new Class[] {}, times(2)), + // addLink is never called + Arguments.of("addLink", new Class[] {SpanContext.class}, times(0)), + Arguments.of("addLink", new Class[] {SpanContext.class, Attributes.class}, times(0))); } // gets default values for all cases, as mockito can't mock wrappers or primitives, including diff --git a/sdk/trace/build.gradle.kts b/sdk/trace/build.gradle.kts index 34690eaeeca..ae87071507a 100644 --- a/sdk/trace/build.gradle.kts +++ b/sdk/trace/build.gradle.kts @@ -22,8 +22,6 @@ dependencies { api(project(":api:all")) api(project(":sdk:common")) - implementation(project(":api:incubator")) - compileOnly(project(":sdk:trace-shaded-deps")) annotationProcessor("com.google.auto.value:auto-value") diff --git a/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/SdkSpan.java b/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/SdkSpan.java index 71cd2dccd67..dfa8e9689a0 100644 --- a/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/SdkSpan.java +++ b/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/SdkSpan.java @@ -7,7 +7,6 @@ import io.opentelemetry.api.common.AttributeKey; import io.opentelemetry.api.common.Attributes; -import io.opentelemetry.api.incubator.trace.ExtendedSpan; import io.opentelemetry.api.internal.GuardedBy; import io.opentelemetry.api.trace.Span; import io.opentelemetry.api.trace.SpanContext; @@ -36,7 +35,7 @@ /** Implementation for the {@link Span} class that records trace events. */ @ThreadSafe -final class SdkSpan implements ReadWriteSpan, ExtendedSpan { +final class SdkSpan implements ReadWriteSpan { private static final Logger logger = Logger.getLogger(SdkSpan.class.getName()); diff --git a/sdk/trace/src/test/java/io/opentelemetry/sdk/trace/SdkSpanTest.java b/sdk/trace/src/test/java/io/opentelemetry/sdk/trace/SdkSpanTest.java index 95778058465..42302f54b82 100644 --- a/sdk/trace/src/test/java/io/opentelemetry/sdk/trace/SdkSpanTest.java +++ b/sdk/trace/src/test/java/io/opentelemetry/sdk/trace/SdkSpanTest.java @@ -15,7 +15,6 @@ import static io.opentelemetry.api.common.AttributeKey.stringKey; import static java.util.stream.Collectors.joining; import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatCode; import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.never; @@ -25,7 +24,6 @@ import io.opentelemetry.api.common.AttributeKey; import io.opentelemetry.api.common.Attributes; import io.opentelemetry.api.common.AttributesBuilder; -import io.opentelemetry.api.incubator.trace.ExtendedSpan; import io.opentelemetry.api.trace.Span; import io.opentelemetry.api.trace.SpanContext; import io.opentelemetry.api.trace.SpanId; @@ -821,10 +819,10 @@ void addLink() { null, null); try { - ExtendedSpan span1 = createTestSpan(SpanKind.INTERNAL); - ExtendedSpan span2 = createTestSpan(SpanKind.INTERNAL); - ExtendedSpan span3 = createTestSpan(SpanKind.INTERNAL); - ExtendedSpan span4 = createTestSpan(SpanKind.INTERNAL); + Span span1 = createTestSpan(SpanKind.INTERNAL); + Span span2 = createTestSpan(SpanKind.INTERNAL); + Span span3 = createTestSpan(SpanKind.INTERNAL); + Span span4 = createTestSpan(SpanKind.INTERNAL); span.addLink(span1.getSpanContext()); @@ -887,16 +885,6 @@ void addLink() { } } - @Test - void addLink_InvalidArgs() { - ExtendedSpan span = createTestSpan(SpanKind.INTERNAL); - assertThatCode(() -> span.addLink(null)).doesNotThrowAnyException(); - assertThatCode(() -> span.addLink(SpanContext.getInvalid())).doesNotThrowAnyException(); - assertThatCode(() -> span.addLink(null, null)).doesNotThrowAnyException(); - assertThatCode(() -> span.addLink(SpanContext.getInvalid(), Attributes.empty())) - .doesNotThrowAnyException(); - } - @Test void droppingAttributes() { int maxNumberOfAttributes = 8; From c8ca99c54e530242cf023338687731417e9c9335 Mon Sep 17 00:00:00 2001 From: jack-berg <34418638+jack-berg@users.noreply.github.com> Date: Thu, 4 Apr 2024 12:40:21 -0500 Subject: [PATCH 326/901] Use getPrometheusName for Otel2PrometheusConverter map keys (#6308) --- .../prometheus/Otel2PrometheusConverter.java | 2 +- .../Otel2PrometheusConverterTest.java | 29 +++++++++++++++++++ 2 files changed, 30 insertions(+), 1 deletion(-) diff --git a/exporters/prometheus/src/main/java/io/opentelemetry/exporter/prometheus/Otel2PrometheusConverter.java b/exporters/prometheus/src/main/java/io/opentelemetry/exporter/prometheus/Otel2PrometheusConverter.java index 3b601328ac7..72dbaa446f5 100644 --- a/exporters/prometheus/src/main/java/io/opentelemetry/exporter/prometheus/Otel2PrometheusConverter.java +++ b/exporters/prometheus/src/main/java/io/opentelemetry/exporter/prometheus/Otel2PrometheusConverter.java @@ -550,7 +550,7 @@ private static MetricMetadata convertMetadata(MetricData metricData) { private static void putOrMerge( Map snapshotsByName, MetricSnapshot snapshot) { - String name = snapshot.getMetadata().getName(); + String name = snapshot.getMetadata().getPrometheusName(); if (snapshotsByName.containsKey(name)) { MetricSnapshot merged = merge(snapshotsByName.get(name), snapshot); if (merged != null) { diff --git a/exporters/prometheus/src/test/java/io/opentelemetry/exporter/prometheus/Otel2PrometheusConverterTest.java b/exporters/prometheus/src/test/java/io/opentelemetry/exporter/prometheus/Otel2PrometheusConverterTest.java index 33729f7ac8d..26466c1e393 100644 --- a/exporters/prometheus/src/test/java/io/opentelemetry/exporter/prometheus/Otel2PrometheusConverterTest.java +++ b/exporters/prometheus/src/test/java/io/opentelemetry/exporter/prometheus/Otel2PrometheusConverterTest.java @@ -7,6 +7,7 @@ import static io.opentelemetry.api.common.AttributeKey.stringKey; import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatCode; import io.opentelemetry.api.common.Attributes; import io.opentelemetry.sdk.common.InstrumentationScopeInfo; @@ -108,6 +109,34 @@ void resourceAttributesAddition( assertThat(metricLabels).isEqualTo(expectedMetricLabels); } + @Test + void prometheusNameCollisionTest_Issue6277() { + // NOTE: Metrics with the same resolved prometheus name should merge. However, + // Otel2PrometheusConverter is not responsible for merging individual series, so the merge will + // fail if the two different metrics contain overlapping series. Users should deal with this by + // adding a view that renames one of the two metrics such that the conflict does not occur. + MetricData dotName = + createSampleMetricData( + "my.metric", + "units", + MetricDataType.LONG_SUM, + Attributes.builder().put("key", "a").build(), + Resource.create(Attributes.empty())); + MetricData underscoreName = + createSampleMetricData( + "my_metric", + "units", + MetricDataType.LONG_SUM, + Attributes.builder().put("key", "b").build(), + Resource.create(Attributes.empty())); + + List metricData = new ArrayList<>(); + metricData.add(dotName); + metricData.add(underscoreName); + + assertThatCode(() -> converter.convert(metricData)).doesNotThrowAnyException(); + } + private static Stream resourceAttributesAdditionArgs() { List arguments = new ArrayList<>(); From 68cd649517f6b72906139ccf858591b93a084fcb Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 4 Apr 2024 14:49:21 -0500 Subject: [PATCH 327/901] Update plugin com.gradle.enterprise to v3.17 (#6339) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- settings.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/settings.gradle.kts b/settings.gradle.kts index 9bba75b336b..e6fbf76cc34 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -1,7 +1,7 @@ pluginManagement { plugins { id("com.github.johnrengelman.shadow") version "8.1.1" - id("com.gradle.enterprise") version "3.16.2" + id("com.gradle.enterprise") version "3.17" id("de.undercouch.download") version "5.6.0" id("org.jsonschema2pojo") version "1.2.1" id("io.github.gradle-nexus.publish-plugin") version "1.3.0" From 7f3e3e3e646e78dcab280ef318582a0f207187f1 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 4 Apr 2024 14:49:35 -0500 Subject: [PATCH 328/901] Update dependency jacoco to v0.8.12 (#6338) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- buildSrc/src/main/kotlin/otel.jacoco-conventions.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/buildSrc/src/main/kotlin/otel.jacoco-conventions.gradle.kts b/buildSrc/src/main/kotlin/otel.jacoco-conventions.gradle.kts index fa6360129fd..c99788df5fe 100644 --- a/buildSrc/src/main/kotlin/otel.jacoco-conventions.gradle.kts +++ b/buildSrc/src/main/kotlin/otel.jacoco-conventions.gradle.kts @@ -5,7 +5,7 @@ plugins { } jacoco { - toolVersion = "0.8.11" + toolVersion = "0.8.12" } // https://docs.gradle.org/current/samples/sample_jvm_multi_project_with_code_coverage.html From f5490fbdb8b36e306eee990f228311dc8ab3c966 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 4 Apr 2024 14:51:28 -0500 Subject: [PATCH 329/901] Update dependency com.squareup.wire:wire-bom to v4.9.9 (#6337) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- buildSrc/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts index 1bbea4ba0c0..e3a37e58131 100644 --- a/buildSrc/build.gradle.kts +++ b/buildSrc/build.gradle.kts @@ -50,7 +50,7 @@ repositories { } dependencies { - implementation(enforcedPlatform("com.squareup.wire:wire-bom:4.9.8")) + implementation(enforcedPlatform("com.squareup.wire:wire-bom:4.9.9")) implementation("com.google.auto.value:auto-value-annotations:1.10.4") // When updating, update above in plugins too implementation("com.diffplug.spotless:spotless-plugin-gradle:6.25.0") From 7471fb8032c69c4509a61f5d1c4a8428485c37cf Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 4 Apr 2024 14:51:44 -0500 Subject: [PATCH 330/901] Update dependency checkstyle to v10.15.0 (#6335) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- buildSrc/src/main/kotlin/otel.java-conventions.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/buildSrc/src/main/kotlin/otel.java-conventions.gradle.kts b/buildSrc/src/main/kotlin/otel.java-conventions.gradle.kts index 10fef3da385..c069c5473b8 100644 --- a/buildSrc/src/main/kotlin/otel.java-conventions.gradle.kts +++ b/buildSrc/src/main/kotlin/otel.java-conventions.gradle.kts @@ -35,7 +35,7 @@ java { checkstyle { configDirectory.set(file("$rootDir/buildscripts/")) - toolVersion = "10.14.2" + toolVersion = "10.15.0" isIgnoreFailures = false configProperties["rootDir"] = rootDir } From d1fef93e1c9914a939c23e746cf03abc1d2b29c7 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 4 Apr 2024 14:52:09 -0500 Subject: [PATCH 331/901] Update dependency org.owasp:dependency-check-gradle to v9.1.0 (#6332) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- buildSrc/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts index e3a37e58131..7f83154c04d 100644 --- a/buildSrc/build.gradle.kts +++ b/buildSrc/build.gradle.kts @@ -66,7 +66,7 @@ dependencies { implementation("net.ltgt.gradle:gradle-errorprone-plugin:3.1.0") implementation("net.ltgt.gradle:gradle-nullaway-plugin:2.0.0") implementation("org.jetbrains.kotlin:kotlin-gradle-plugin:1.9.23") - implementation("org.owasp:dependency-check-gradle:9.0.10") + implementation("org.owasp:dependency-check-gradle:9.1.0") implementation("ru.vyarus:gradle-animalsniffer-plugin:1.7.1") } From ff0480c354732ed1739b95f03aef3230e573c038 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 4 Apr 2024 16:04:16 -0500 Subject: [PATCH 332/901] Update dependency io.grpc:grpc-bom to v1.63.0 (#6349) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- dependencyManagement/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index debeb447fb3..1f929f213bb 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -14,7 +14,7 @@ val DEPENDENCY_BOMS = listOf( "com.linecorp.armeria:armeria-bom:1.27.3", "com.squareup.okhttp3:okhttp-bom:4.12.0", "com.squareup.okio:okio-bom:3.9.0", // applies to transitive dependencies of okhttp - "io.grpc:grpc-bom:1.62.2", + "io.grpc:grpc-bom:1.63.0", "io.netty:netty-bom:4.1.108.Final", "io.zipkin.brave:brave-bom:6.0.2", "io.zipkin.reporter2:zipkin-reporter-bom:3.3.0", From 4d8f4f31111cfac2ad8e0e467f604318ae88e3ab Mon Sep 17 00:00:00 2001 From: jack-berg <34418638+jack-berg@users.noreply.github.com> Date: Fri, 5 Apr 2024 09:46:51 -0500 Subject: [PATCH 333/901] Metric exporter REUSABLE_DATA memory mode configuration options (#6304) --- .../opentelemetry-exporter-otlp.txt | 7 ++- exporters/common/build.gradle.kts | 1 + .../internal/ExporterBuilderUtil.java | 21 +++++++ .../http/metrics/OtlpHttpMetricExporter.java | 13 +++- .../OtlpHttpMetricExporterBuilder.java | 22 ++++++- .../otlp/internal/OtlpConfigUtil.java | 43 +++++++++++++ .../internal/OtlpMetricExporterProvider.java | 9 +++ .../otlp/metrics/OtlpGrpcMetricExporter.java | 13 +++- .../OtlpGrpcMetricExporterBuilder.java | 23 ++++++- .../otlp/metrics/OtlpGrpcMetricUtil.java | 19 ++++++ .../OtlpMetricExporterProviderTest.java | 7 +++ exporters/prometheus/build.gradle.kts | 1 + .../prometheus/PrometheusHttpServer.java | 13 +++- .../PrometheusHttpServerBuilder.java | 35 +++++++---- .../PrometheusMetricReaderProvider.java | 3 + .../PrometheusMetricReaderProviderTest.java | 4 ++ .../OtlpExporterIntegrationTest.java | 61 ++++++++++++++++--- sdk-extensions/autoconfigure/README.md | 17 ++++-- 18 files changed, 274 insertions(+), 38 deletions(-) create mode 100644 exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/metrics/OtlpGrpcMetricUtil.java diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-otlp.txt b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-otlp.txt index df26146497b..d8fcd994b8d 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-otlp.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-otlp.txt @@ -1,2 +1,7 @@ Comparing source compatibility of against -No changes. \ No newline at end of file +*** MODIFIED CLASS: PUBLIC FINAL io.opentelemetry.exporter.otlp.http.metrics.OtlpHttpMetricExporter (not serializable) + === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 + +++ NEW METHOD: PUBLIC(+) io.opentelemetry.sdk.common.export.MemoryMode getMemoryMode() +*** MODIFIED CLASS: PUBLIC FINAL io.opentelemetry.exporter.otlp.metrics.OtlpGrpcMetricExporter (not serializable) + === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 + +++ NEW METHOD: PUBLIC(+) io.opentelemetry.sdk.common.export.MemoryMode getMemoryMode() diff --git a/exporters/common/build.gradle.kts b/exporters/common/build.gradle.kts index d6cb5ebe86f..b8868565287 100644 --- a/exporters/common/build.gradle.kts +++ b/exporters/common/build.gradle.kts @@ -11,6 +11,7 @@ otelJava.moduleName.set("io.opentelemetry.exporter.internal") val versions: Map by project dependencies { api(project(":api:all")) + api(project(":sdk-extensions:autoconfigure-spi")) compileOnly(project(":sdk:common")) diff --git a/exporters/common/src/main/java/io/opentelemetry/exporter/internal/ExporterBuilderUtil.java b/exporters/common/src/main/java/io/opentelemetry/exporter/internal/ExporterBuilderUtil.java index d45bdb09283..b19aad8e131 100644 --- a/exporters/common/src/main/java/io/opentelemetry/exporter/internal/ExporterBuilderUtil.java +++ b/exporters/common/src/main/java/io/opentelemetry/exporter/internal/ExporterBuilderUtil.java @@ -5,8 +5,13 @@ package io.opentelemetry.exporter.internal; +import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties; +import io.opentelemetry.sdk.autoconfigure.spi.ConfigurationException; +import io.opentelemetry.sdk.common.export.MemoryMode; import java.net.URI; import java.net.URISyntaxException; +import java.util.Locale; +import java.util.function.Consumer; /** * Utilities for exporter builders. @@ -33,5 +38,21 @@ public static URI validateEndpoint(String endpoint) { return uri; } + /** Invoke the {@code memoryModeConsumer} with the configured {@link MemoryMode}. */ + public static void configureExporterMemoryMode( + ConfigProperties config, Consumer memoryModeConsumer) { + String memoryModeStr = config.getString("otel.java.experimental.exporter.memory_mode"); + if (memoryModeStr == null) { + return; + } + MemoryMode memoryMode; + try { + memoryMode = MemoryMode.valueOf(memoryModeStr.toUpperCase(Locale.ROOT)); + } catch (IllegalArgumentException e) { + throw new ConfigurationException("Unrecognized memory mode: " + memoryModeStr, e); + } + memoryModeConsumer.accept(memoryMode); + } + private ExporterBuilderUtil() {} } diff --git a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/metrics/OtlpHttpMetricExporter.java b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/metrics/OtlpHttpMetricExporter.java index 922baaaec5b..d9b0dd7d2c9 100644 --- a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/metrics/OtlpHttpMetricExporter.java +++ b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/metrics/OtlpHttpMetricExporter.java @@ -9,6 +9,7 @@ import io.opentelemetry.exporter.internal.http.HttpExporterBuilder; import io.opentelemetry.exporter.internal.otlp.metrics.MetricsRequestMarshaler; import io.opentelemetry.sdk.common.CompletableResultCode; +import io.opentelemetry.sdk.common.export.MemoryMode; import io.opentelemetry.sdk.metrics.Aggregation; import io.opentelemetry.sdk.metrics.InstrumentType; import io.opentelemetry.sdk.metrics.data.AggregationTemporality; @@ -31,16 +32,19 @@ public final class OtlpHttpMetricExporter implements MetricExporter { private final HttpExporter delegate; private final AggregationTemporalitySelector aggregationTemporalitySelector; private final DefaultAggregationSelector defaultAggregationSelector; + private final MemoryMode memoryMode; OtlpHttpMetricExporter( HttpExporterBuilder builder, HttpExporter delegate, AggregationTemporalitySelector aggregationTemporalitySelector, - DefaultAggregationSelector defaultAggregationSelector) { + DefaultAggregationSelector defaultAggregationSelector, + MemoryMode memoryMode) { this.builder = builder; this.delegate = delegate; this.aggregationTemporalitySelector = aggregationTemporalitySelector; this.defaultAggregationSelector = defaultAggregationSelector; + this.memoryMode = memoryMode; } /** @@ -72,7 +76,7 @@ public static OtlpHttpMetricExporterBuilder builder() { * @since 1.29.0 */ public OtlpHttpMetricExporterBuilder toBuilder() { - return new OtlpHttpMetricExporterBuilder(builder.copy()); + return new OtlpHttpMetricExporterBuilder(builder.copy(), memoryMode); } @Override @@ -85,6 +89,11 @@ public Aggregation getDefaultAggregation(InstrumentType instrumentType) { return defaultAggregationSelector.getDefaultAggregation(instrumentType); } + @Override + public MemoryMode getMemoryMode() { + return memoryMode; + } + /** * Submits all the given metrics in a single batch to the OpenTelemetry collector. * diff --git a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/metrics/OtlpHttpMetricExporterBuilder.java b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/metrics/OtlpHttpMetricExporterBuilder.java index 8fa21d1aa50..8390d5e03b3 100644 --- a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/metrics/OtlpHttpMetricExporterBuilder.java +++ b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/metrics/OtlpHttpMetricExporterBuilder.java @@ -15,6 +15,7 @@ import io.opentelemetry.exporter.internal.http.HttpExporterBuilder; import io.opentelemetry.exporter.internal.otlp.metrics.MetricsRequestMarshaler; import io.opentelemetry.exporter.otlp.internal.OtlpUserAgent; +import io.opentelemetry.sdk.common.export.MemoryMode; import io.opentelemetry.sdk.common.export.ProxyOptions; import io.opentelemetry.sdk.common.export.RetryPolicy; import io.opentelemetry.sdk.metrics.InstrumentType; @@ -39,6 +40,7 @@ public final class OtlpHttpMetricExporterBuilder { private static final AggregationTemporalitySelector DEFAULT_AGGREGATION_TEMPORALITY_SELECTOR = AggregationTemporalitySelector.alwaysCumulative(); + private static final MemoryMode DEFAULT_MEMORY_MODE = MemoryMode.IMMUTABLE_DATA; private final HttpExporterBuilder delegate; private AggregationTemporalitySelector aggregationTemporalitySelector = @@ -46,15 +48,18 @@ public final class OtlpHttpMetricExporterBuilder { private DefaultAggregationSelector defaultAggregationSelector = DefaultAggregationSelector.getDefault(); + private MemoryMode memoryMode; - OtlpHttpMetricExporterBuilder(HttpExporterBuilder delegate) { + OtlpHttpMetricExporterBuilder( + HttpExporterBuilder delegate, MemoryMode memoryMode) { this.delegate = delegate; + this.memoryMode = memoryMode; delegate.setMeterProvider(MeterProvider::noop); OtlpUserAgent.addUserAgentHeader(delegate::addConstantHeaders); } OtlpHttpMetricExporterBuilder() { - this(new HttpExporterBuilder<>("otlp", "metric", DEFAULT_ENDPOINT)); + this(new HttpExporterBuilder<>("otlp", "metric", DEFAULT_ENDPOINT), DEFAULT_MEMORY_MODE); } /** @@ -227,6 +232,13 @@ public OtlpHttpMetricExporterBuilder setProxyOptions(ProxyOptions proxyOptions) return this; } + /** Set the {@link MemoryMode}. */ + OtlpHttpMetricExporterBuilder setMemoryMode(MemoryMode memoryMode) { + requireNonNull(memoryMode, "memoryMode"); + this.memoryMode = memoryMode; + return this; + } + OtlpHttpMetricExporterBuilder exportAsJson() { delegate.exportAsJson(); return this; @@ -239,6 +251,10 @@ OtlpHttpMetricExporterBuilder exportAsJson() { */ public OtlpHttpMetricExporter build() { return new OtlpHttpMetricExporter( - delegate, delegate.build(), aggregationTemporalitySelector, defaultAggregationSelector); + delegate, + delegate.build(), + aggregationTemporalitySelector, + defaultAggregationSelector, + memoryMode); } } diff --git a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/OtlpConfigUtil.java b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/OtlpConfigUtil.java index da02c32dee5..5bd08742b09 100644 --- a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/OtlpConfigUtil.java +++ b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/OtlpConfigUtil.java @@ -7,8 +7,11 @@ import static io.opentelemetry.sdk.metrics.Aggregation.explicitBucketHistogram; +import io.opentelemetry.exporter.otlp.http.metrics.OtlpHttpMetricExporterBuilder; +import io.opentelemetry.exporter.otlp.metrics.OtlpGrpcMetricExporterBuilder; import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties; import io.opentelemetry.sdk.autoconfigure.spi.ConfigurationException; +import io.opentelemetry.sdk.common.export.MemoryMode; import io.opentelemetry.sdk.common.export.RetryPolicy; import io.opentelemetry.sdk.metrics.Aggregation; import io.opentelemetry.sdk.metrics.InstrumentType; @@ -19,6 +22,8 @@ import java.io.File; import java.io.IOException; import java.io.RandomAccessFile; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; import java.net.MalformedURLException; import java.net.URL; import java.net.URLDecoder; @@ -206,6 +211,44 @@ public static void configureOtlpHistogramDefaultAggregation( } } + /** + * Calls {@code #setMemoryMode} on the {@code Otlp{Protocol}MetricExporterBuilder} with the {@code + * memoryMode}. + */ + public static void setMemoryModeOnOtlpMetricExporterBuilder( + Object builder, MemoryMode memoryMode) { + try { + if (builder instanceof OtlpGrpcMetricExporterBuilder) { + // Calling getDeclaredMethod causes all private methods to be read, which causes a + // ClassNotFoundException when running with the OkHttHttpProvider as the private + // setManagedChanel(io.grpc.ManagedChannel) is reached and io.grpc.ManagedChannel is not on + // the classpath. io.opentelemetry.exporter.otlp.metrics.OtlpGrpcMetricUtil provides a layer + // of indirection which avoids scanning the OtlpGrpcMetricExporterBuilder private methods. + Class otlpGrpcMetricUtil = + Class.forName("io.opentelemetry.exporter.otlp.metrics.OtlpGrpcMetricUtil"); + Method method = + otlpGrpcMetricUtil.getDeclaredMethod( + "setMemoryMode", OtlpGrpcMetricExporterBuilder.class, MemoryMode.class); + method.setAccessible(true); + method.invoke(null, builder, memoryMode); + } else if (builder instanceof OtlpHttpMetricExporterBuilder) { + Method method = + OtlpHttpMetricExporterBuilder.class.getDeclaredMethod( + "setMemoryMode", MemoryMode.class); + method.setAccessible(true); + method.invoke(builder, memoryMode); + } else { + throw new IllegalArgumentException( + "Can only set memory mode on OtlpHttpMetricExporterBuilder and OtlpGrpcMetricExporterBuilder."); + } + } catch (NoSuchMethodException + | InvocationTargetException + | IllegalAccessException + | ClassNotFoundException e) { + throw new IllegalStateException("Error calling setMemoryMode.", e); + } + } + private static URL createUrl(URL context, String spec) { try { return new URL(context, spec); diff --git a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/OtlpMetricExporterProvider.java b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/OtlpMetricExporterProvider.java index 3d424b498f0..cfea314f028 100644 --- a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/OtlpMetricExporterProvider.java +++ b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/OtlpMetricExporterProvider.java @@ -9,6 +9,7 @@ import static io.opentelemetry.exporter.otlp.internal.OtlpConfigUtil.PROTOCOL_GRPC; import static io.opentelemetry.exporter.otlp.internal.OtlpConfigUtil.PROTOCOL_HTTP_PROTOBUF; +import io.opentelemetry.exporter.internal.ExporterBuilderUtil; import io.opentelemetry.exporter.otlp.http.metrics.OtlpHttpMetricExporter; import io.opentelemetry.exporter.otlp.http.metrics.OtlpHttpMetricExporterBuilder; import io.opentelemetry.exporter.otlp.metrics.OtlpGrpcMetricExporter; @@ -48,6 +49,10 @@ public MetricExporter createExporter(ConfigProperties config) { config, builder::setAggregationTemporalitySelector); OtlpConfigUtil.configureOtlpHistogramDefaultAggregation( config, builder::setDefaultAggregationSelector); + ExporterBuilderUtil.configureExporterMemoryMode( + config, + memoryMode -> + OtlpConfigUtil.setMemoryModeOnOtlpMetricExporterBuilder(builder, memoryMode)); return builder.build(); } else if (protocol.equals(PROTOCOL_GRPC)) { @@ -67,6 +72,10 @@ public MetricExporter createExporter(ConfigProperties config) { config, builder::setAggregationTemporalitySelector); OtlpConfigUtil.configureOtlpHistogramDefaultAggregation( config, builder::setDefaultAggregationSelector); + ExporterBuilderUtil.configureExporterMemoryMode( + config, + memoryMode -> + OtlpConfigUtil.setMemoryModeOnOtlpMetricExporterBuilder(builder, memoryMode)); return builder.build(); } diff --git a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/metrics/OtlpGrpcMetricExporter.java b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/metrics/OtlpGrpcMetricExporter.java index e006675f28c..f6e5f635ee9 100644 --- a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/metrics/OtlpGrpcMetricExporter.java +++ b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/metrics/OtlpGrpcMetricExporter.java @@ -9,6 +9,7 @@ import io.opentelemetry.exporter.internal.grpc.GrpcExporterBuilder; import io.opentelemetry.exporter.internal.otlp.metrics.MetricsRequestMarshaler; import io.opentelemetry.sdk.common.CompletableResultCode; +import io.opentelemetry.sdk.common.export.MemoryMode; import io.opentelemetry.sdk.metrics.Aggregation; import io.opentelemetry.sdk.metrics.InstrumentType; import io.opentelemetry.sdk.metrics.data.AggregationTemporality; @@ -31,6 +32,7 @@ public final class OtlpGrpcMetricExporter implements MetricExporter { private final GrpcExporter delegate; private final AggregationTemporalitySelector aggregationTemporalitySelector; private final DefaultAggregationSelector defaultAggregationSelector; + private final MemoryMode memoryMode; /** * Returns a new {@link OtlpGrpcMetricExporter} using the default values. @@ -57,11 +59,13 @@ public static OtlpGrpcMetricExporterBuilder builder() { GrpcExporterBuilder builder, GrpcExporter delegate, AggregationTemporalitySelector aggregationTemporalitySelector, - DefaultAggregationSelector defaultAggregationSelector) { + DefaultAggregationSelector defaultAggregationSelector, + MemoryMode memoryMode) { this.builder = builder; this.delegate = delegate; this.aggregationTemporalitySelector = aggregationTemporalitySelector; this.defaultAggregationSelector = defaultAggregationSelector; + this.memoryMode = memoryMode; } /** @@ -72,7 +76,7 @@ public static OtlpGrpcMetricExporterBuilder builder() { * @since 1.29.0 */ public OtlpGrpcMetricExporterBuilder toBuilder() { - return new OtlpGrpcMetricExporterBuilder(builder.copy()); + return new OtlpGrpcMetricExporterBuilder(builder.copy(), memoryMode); } @Override @@ -85,6 +89,11 @@ public Aggregation getDefaultAggregation(InstrumentType instrumentType) { return defaultAggregationSelector.getDefaultAggregation(instrumentType); } + @Override + public MemoryMode getMemoryMode() { + return memoryMode; + } + /** * Submits all the given metrics in a single batch to the OpenTelemetry collector. * diff --git a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/metrics/OtlpGrpcMetricExporterBuilder.java b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/metrics/OtlpGrpcMetricExporterBuilder.java index 2fc86bab6bd..782907cd27c 100644 --- a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/metrics/OtlpGrpcMetricExporterBuilder.java +++ b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/metrics/OtlpGrpcMetricExporterBuilder.java @@ -16,6 +16,7 @@ import io.opentelemetry.exporter.internal.grpc.GrpcExporterBuilder; import io.opentelemetry.exporter.internal.otlp.metrics.MetricsRequestMarshaler; import io.opentelemetry.exporter.otlp.internal.OtlpUserAgent; +import io.opentelemetry.sdk.common.export.MemoryMode; import io.opentelemetry.sdk.common.export.RetryPolicy; import io.opentelemetry.sdk.metrics.InstrumentType; import io.opentelemetry.sdk.metrics.export.AggregationTemporalitySelector; @@ -46,6 +47,7 @@ public final class OtlpGrpcMetricExporterBuilder { private static final long DEFAULT_TIMEOUT_SECS = 10; private static final AggregationTemporalitySelector DEFAULT_AGGREGATION_TEMPORALITY_SELECTOR = AggregationTemporalitySelector.alwaysCumulative(); + private static final MemoryMode DEFAULT_MEMORY_MODE = MemoryMode.IMMUTABLE_DATA; // Visible for testing final GrpcExporterBuilder delegate; @@ -55,9 +57,12 @@ public final class OtlpGrpcMetricExporterBuilder { private DefaultAggregationSelector defaultAggregationSelector = DefaultAggregationSelector.getDefault(); + private MemoryMode memoryMode; - OtlpGrpcMetricExporterBuilder(GrpcExporterBuilder delegate) { + OtlpGrpcMetricExporterBuilder( + GrpcExporterBuilder delegate, MemoryMode memoryMode) { this.delegate = delegate; + this.memoryMode = memoryMode; delegate.setMeterProvider(MeterProvider::noop); OtlpUserAgent.addUserAgentHeader(delegate::addConstantHeader); } @@ -70,7 +75,8 @@ public final class OtlpGrpcMetricExporterBuilder { DEFAULT_TIMEOUT_SECS, DEFAULT_ENDPOINT, () -> MarshalerMetricsServiceGrpc::newFutureStub, - GRPC_ENDPOINT_PATH)); + GRPC_ENDPOINT_PATH), + DEFAULT_MEMORY_MODE); } /** @@ -259,6 +265,13 @@ public OtlpGrpcMetricExporterBuilder setRetryPolicy(RetryPolicy retryPolicy) { return this; } + /** Set the {@link MemoryMode}. */ + OtlpGrpcMetricExporterBuilder setMemoryMode(MemoryMode memoryMode) { + requireNonNull(memoryMode, "memoryMode"); + this.memoryMode = memoryMode; + return this; + } + /** * Constructs a new instance of the exporter based on the builder's values. * @@ -266,6 +279,10 @@ public OtlpGrpcMetricExporterBuilder setRetryPolicy(RetryPolicy retryPolicy) { */ public OtlpGrpcMetricExporter build() { return new OtlpGrpcMetricExporter( - delegate, delegate.build(), aggregationTemporalitySelector, defaultAggregationSelector); + delegate, + delegate.build(), + aggregationTemporalitySelector, + defaultAggregationSelector, + memoryMode); } } diff --git a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/metrics/OtlpGrpcMetricUtil.java b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/metrics/OtlpGrpcMetricUtil.java new file mode 100644 index 00000000000..f99243cb0ba --- /dev/null +++ b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/metrics/OtlpGrpcMetricUtil.java @@ -0,0 +1,19 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.exporter.otlp.metrics; + +import io.opentelemetry.exporter.otlp.internal.OtlpConfigUtil; +import io.opentelemetry.sdk.common.export.MemoryMode; + +final class OtlpGrpcMetricUtil { + + private OtlpGrpcMetricUtil() {} + + /** See {@link OtlpConfigUtil#setMemoryModeOnOtlpMetricExporterBuilder(Object, MemoryMode)}. */ + static void setMemoryMode(OtlpGrpcMetricExporterBuilder builder, MemoryMode memoryMode) { + builder.setMemoryMode(memoryMode); + } +} diff --git a/exporters/otlp/all/src/test/java/io/opentelemetry/exporter/otlp/internal/OtlpMetricExporterProviderTest.java b/exporters/otlp/all/src/test/java/io/opentelemetry/exporter/otlp/internal/OtlpMetricExporterProviderTest.java index f1ff7a71f02..36e6b88cfa8 100644 --- a/exporters/otlp/all/src/test/java/io/opentelemetry/exporter/otlp/internal/OtlpMetricExporterProviderTest.java +++ b/exporters/otlp/all/src/test/java/io/opentelemetry/exporter/otlp/internal/OtlpMetricExporterProviderTest.java @@ -20,6 +20,7 @@ import io.opentelemetry.exporter.otlp.metrics.OtlpGrpcMetricExporterBuilder; import io.opentelemetry.sdk.autoconfigure.spi.ConfigurationException; import io.opentelemetry.sdk.autoconfigure.spi.internal.DefaultConfigProperties; +import io.opentelemetry.sdk.common.export.MemoryMode; import io.opentelemetry.sdk.metrics.export.MetricExporter; import java.io.IOException; import java.nio.file.Files; @@ -127,6 +128,7 @@ void createExporter_GrpcDefaults() { verify(grpcBuilder, never()).setTrustedCertificates(any()); verify(grpcBuilder, never()).setClientTls(any(), any()); assertThat(grpcBuilder).extracting("delegate").extracting("retryPolicy").isNull(); + assertThat(exporter.getMemoryMode()).isEqualTo(MemoryMode.IMMUTABLE_DATA); } Mockito.verifyNoInteractions(httpBuilder); } @@ -176,6 +178,7 @@ void createExporter_GrpcWithSignalConfiguration() throws CertificateEncodingExce config.put("otel.exporter.otlp.metrics.compression", "gzip"); config.put("otel.exporter.otlp.timeout", "1s"); config.put("otel.exporter.otlp.metrics.timeout", "15s"); + config.put("otel.java.experimental.exporter.memory_mode", "reusable_data"); try (MetricExporter exporter = provider.createExporter(DefaultConfigProperties.createFromMap(config))) { @@ -188,6 +191,7 @@ void createExporter_GrpcWithSignalConfiguration() throws CertificateEncodingExce verify(grpcBuilder).setTrustedCertificates(serverTls.certificate().getEncoded()); verify(grpcBuilder) .setClientTls(clientTls.privateKey().getEncoded(), clientTls.certificate().getEncoded()); + assertThat(exporter.getMemoryMode()).isEqualTo(MemoryMode.REUSABLE_DATA); } Mockito.verifyNoInteractions(httpBuilder); } @@ -208,6 +212,7 @@ void createExporter_HttpDefaults() { verify(httpBuilder, never()).setTrustedCertificates(any()); verify(httpBuilder, never()).setClientTls(any(), any()); assertThat(httpBuilder).extracting("delegate").extracting("retryPolicy").isNull(); + assertThat(exporter.getMemoryMode()).isEqualTo(MemoryMode.IMMUTABLE_DATA); } Mockito.verifyNoInteractions(grpcBuilder); } @@ -260,6 +265,7 @@ void createExporter_HttpWithSignalConfiguration() throws CertificateEncodingExce config.put("otel.exporter.otlp.metrics.compression", "gzip"); config.put("otel.exporter.otlp.timeout", "1s"); config.put("otel.exporter.otlp.metrics.timeout", "15s"); + config.put("otel.java.experimental.exporter.memory_mode", "reusable_data"); try (MetricExporter exporter = provider.createExporter(DefaultConfigProperties.createFromMap(config))) { @@ -272,6 +278,7 @@ void createExporter_HttpWithSignalConfiguration() throws CertificateEncodingExce verify(httpBuilder).setTrustedCertificates(serverTls.certificate().getEncoded()); verify(httpBuilder) .setClientTls(clientTls.privateKey().getEncoded(), clientTls.certificate().getEncoded()); + assertThat(exporter.getMemoryMode()).isEqualTo(MemoryMode.REUSABLE_DATA); } Mockito.verifyNoInteractions(grpcBuilder); } diff --git a/exporters/prometheus/build.gradle.kts b/exporters/prometheus/build.gradle.kts index 31044c70b23..a1da9e7e243 100644 --- a/exporters/prometheus/build.gradle.kts +++ b/exporters/prometheus/build.gradle.kts @@ -11,6 +11,7 @@ otelJava.moduleName.set("io.opentelemetry.exporter.prometheus") dependencies { api(project(":sdk:metrics")) + implementation(project(":exporters:common")) implementation(project(":sdk-extensions:autoconfigure-spi")) implementation("io.prometheus:prometheus-metrics-exporter-httpserver") diff --git a/exporters/prometheus/src/main/java/io/opentelemetry/exporter/prometheus/PrometheusHttpServer.java b/exporters/prometheus/src/main/java/io/opentelemetry/exporter/prometheus/PrometheusHttpServer.java index 388fe1a4f6b..e4a15612856 100644 --- a/exporters/prometheus/src/main/java/io/opentelemetry/exporter/prometheus/PrometheusHttpServer.java +++ b/exporters/prometheus/src/main/java/io/opentelemetry/exporter/prometheus/PrometheusHttpServer.java @@ -11,6 +11,7 @@ package io.opentelemetry.exporter.prometheus; import io.opentelemetry.sdk.common.CompletableResultCode; +import io.opentelemetry.sdk.common.export.MemoryMode; import io.opentelemetry.sdk.metrics.InstrumentType; import io.opentelemetry.sdk.metrics.data.AggregationTemporality; import io.opentelemetry.sdk.metrics.export.CollectionRegistration; @@ -32,11 +33,12 @@ */ public final class PrometheusHttpServer implements MetricReader { + private final PrometheusHttpServerBuilder builder; private final HTTPServer httpServer; private final PrometheusMetricReader prometheusMetricReader; private final PrometheusRegistry prometheusRegistry; private final String host; - private final PrometheusHttpServerBuilder builder; + private final MemoryMode memoryMode; /** * Returns a new {@link PrometheusHttpServer} which can be registered to an {@link @@ -59,11 +61,13 @@ public static PrometheusHttpServerBuilder builder() { @Nullable ExecutorService executor, PrometheusRegistry prometheusRegistry, boolean otelScopeEnabled, - @Nullable Predicate allowedResourceAttributesFilter) { + @Nullable Predicate allowedResourceAttributesFilter, + MemoryMode memoryMode) { this.builder = builder; this.prometheusMetricReader = new PrometheusMetricReader(otelScopeEnabled, allowedResourceAttributesFilter); this.host = host; + this.memoryMode = memoryMode; this.prometheusRegistry = prometheusRegistry; prometheusRegistry.register(prometheusMetricReader); try { @@ -85,6 +89,11 @@ public AggregationTemporality getAggregationTemporality(InstrumentType instrumen return prometheusMetricReader.getAggregationTemporality(instrumentType); } + @Override + public MemoryMode getMemoryMode() { + return memoryMode; + } + @Override public void register(CollectionRegistration registration) { prometheusMetricReader.register(registration); diff --git a/exporters/prometheus/src/main/java/io/opentelemetry/exporter/prometheus/PrometheusHttpServerBuilder.java b/exporters/prometheus/src/main/java/io/opentelemetry/exporter/prometheus/PrometheusHttpServerBuilder.java index 1d53679b52b..3c20eea3a2f 100644 --- a/exporters/prometheus/src/main/java/io/opentelemetry/exporter/prometheus/PrometheusHttpServerBuilder.java +++ b/exporters/prometheus/src/main/java/io/opentelemetry/exporter/prometheus/PrometheusHttpServerBuilder.java @@ -8,6 +8,7 @@ import static io.opentelemetry.api.internal.Utils.checkArgument; import static java.util.Objects.requireNonNull; +import io.opentelemetry.sdk.common.export.MemoryMode; import io.prometheus.metrics.model.registry.PrometheusRegistry; import java.util.concurrent.ExecutorService; import java.util.function.Predicate; @@ -18,6 +19,7 @@ public final class PrometheusHttpServerBuilder { static final int DEFAULT_PORT = 9464; private static final String DEFAULT_HOST = "0.0.0.0"; + private static final MemoryMode DEFAULT_MEMORY_MODE = MemoryMode.IMMUTABLE_DATA; private String host = DEFAULT_HOST; private int port = DEFAULT_PORT; @@ -25,6 +27,18 @@ public final class PrometheusHttpServerBuilder { private boolean otelScopeEnabled = true; @Nullable private Predicate allowedResourceAttributesFilter; @Nullable private ExecutorService executor; + private MemoryMode memoryMode = DEFAULT_MEMORY_MODE; + + PrometheusHttpServerBuilder() {} + + PrometheusHttpServerBuilder(PrometheusHttpServerBuilder builder) { + this.host = builder.host; + this.port = builder.port; + this.prometheusRegistry = builder.prometheusRegistry; + this.otelScopeEnabled = builder.otelScopeEnabled; + this.allowedResourceAttributesFilter = builder.allowedResourceAttributesFilter; + this.executor = builder.executor; + } /** Sets the host to bind to. If unset, defaults to {@value #DEFAULT_HOST}. */ public PrometheusHttpServerBuilder setHost(String host) { @@ -79,6 +93,13 @@ public PrometheusHttpServerBuilder setAllowedResourceAttributesFilter( return this; } + /** Set the {@link MemoryMode}. */ + public PrometheusHttpServerBuilder setMemoryMode(MemoryMode memoryMode) { + requireNonNull(memoryMode, "memoryMode"); + this.memoryMode = memoryMode; + return this; + } + /** * Returns a new {@link PrometheusHttpServer} with the configuration of this builder which can be * registered with a {@link io.opentelemetry.sdk.metrics.SdkMeterProvider}. @@ -91,17 +112,7 @@ public PrometheusHttpServer build() { executor, prometheusRegistry, otelScopeEnabled, - allowedResourceAttributesFilter); - } - - PrometheusHttpServerBuilder() {} - - PrometheusHttpServerBuilder(PrometheusHttpServerBuilder builder) { - this.host = builder.host; - this.port = builder.port; - this.prometheusRegistry = builder.prometheusRegistry; - this.otelScopeEnabled = builder.otelScopeEnabled; - this.allowedResourceAttributesFilter = builder.allowedResourceAttributesFilter; - this.executor = builder.executor; + allowedResourceAttributesFilter, + memoryMode); } } diff --git a/exporters/prometheus/src/main/java/io/opentelemetry/exporter/prometheus/internal/PrometheusMetricReaderProvider.java b/exporters/prometheus/src/main/java/io/opentelemetry/exporter/prometheus/internal/PrometheusMetricReaderProvider.java index d7393dabf8b..39d6c755e17 100644 --- a/exporters/prometheus/src/main/java/io/opentelemetry/exporter/prometheus/internal/PrometheusMetricReaderProvider.java +++ b/exporters/prometheus/src/main/java/io/opentelemetry/exporter/prometheus/internal/PrometheusMetricReaderProvider.java @@ -5,6 +5,7 @@ package io.opentelemetry.exporter.prometheus.internal; +import io.opentelemetry.exporter.internal.ExporterBuilderUtil; import io.opentelemetry.exporter.prometheus.PrometheusHttpServer; import io.opentelemetry.exporter.prometheus.PrometheusHttpServerBuilder; import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties; @@ -32,6 +33,8 @@ public MetricReader createMetricReader(ConfigProperties config) { prometheusBuilder.setHost(host); } + ExporterBuilderUtil.configureExporterMemoryMode(config, prometheusBuilder::setMemoryMode); + return prometheusBuilder.build(); } diff --git a/exporters/prometheus/src/test/java/io/opentelemetry/exporter/prometheus/internal/PrometheusMetricReaderProviderTest.java b/exporters/prometheus/src/test/java/io/opentelemetry/exporter/prometheus/internal/PrometheusMetricReaderProviderTest.java index 58504e2e7e9..5f450ab751f 100644 --- a/exporters/prometheus/src/test/java/io/opentelemetry/exporter/prometheus/internal/PrometheusMetricReaderProviderTest.java +++ b/exporters/prometheus/src/test/java/io/opentelemetry/exporter/prometheus/internal/PrometheusMetricReaderProviderTest.java @@ -14,6 +14,7 @@ import io.opentelemetry.exporter.prometheus.PrometheusHttpServer; import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties; import io.opentelemetry.sdk.autoconfigure.spi.internal.DefaultConfigProperties; +import io.opentelemetry.sdk.common.export.MemoryMode; import io.opentelemetry.sdk.metrics.export.MetricReader; import io.prometheus.metrics.exporter.httpserver.HTTPServer; import java.io.IOException; @@ -57,6 +58,7 @@ void createMetricReader_Default() throws IOException { assertThat(server.getAddress().getHostName()).isEqualTo("0:0:0:0:0:0:0:0"); assertThat(server.getAddress().getPort()).isEqualTo(9464); }); + assertThat(metricReader.getMemoryMode()).isEqualTo(MemoryMode.IMMUTABLE_DATA); } } @@ -73,6 +75,7 @@ void createMetricReader_WithConfiguration() throws IOException { Map config = new HashMap<>(); config.put("otel.exporter.prometheus.host", "localhost"); config.put("otel.exporter.prometheus.port", String.valueOf(port)); + config.put("otel.java.experimental.exporter.memory_mode", "reusable_data"); when(configProperties.getInt(any())).thenReturn(null); when(configProperties.getString(any())).thenReturn(null); @@ -87,6 +90,7 @@ void createMetricReader_WithConfiguration() throws IOException { assertThat(server.getAddress().getHostName()).isEqualTo("localhost"); assertThat(server.getAddress().getPort()).isEqualTo(port); }); + assertThat(metricReader.getMemoryMode()).isEqualTo(MemoryMode.REUSABLE_DATA); } } } diff --git a/integration-tests/otlp/src/main/java/io/opentelemetry/integrationtest/OtlpExporterIntegrationTest.java b/integration-tests/otlp/src/main/java/io/opentelemetry/integrationtest/OtlpExporterIntegrationTest.java index 141159c3d8d..1339734f5b8 100644 --- a/integration-tests/otlp/src/main/java/io/opentelemetry/integrationtest/OtlpExporterIntegrationTest.java +++ b/integration-tests/otlp/src/main/java/io/opentelemetry/integrationtest/OtlpExporterIntegrationTest.java @@ -38,9 +38,12 @@ import io.opentelemetry.context.Scope; import io.opentelemetry.exporter.otlp.http.logs.OtlpHttpLogRecordExporter; import io.opentelemetry.exporter.otlp.http.metrics.OtlpHttpMetricExporter; +import io.opentelemetry.exporter.otlp.http.metrics.OtlpHttpMetricExporterBuilder; import io.opentelemetry.exporter.otlp.http.trace.OtlpHttpSpanExporter; +import io.opentelemetry.exporter.otlp.internal.OtlpConfigUtil; import io.opentelemetry.exporter.otlp.logs.OtlpGrpcLogRecordExporter; import io.opentelemetry.exporter.otlp.metrics.OtlpGrpcMetricExporter; +import io.opentelemetry.exporter.otlp.metrics.OtlpGrpcMetricExporterBuilder; import io.opentelemetry.exporter.otlp.trace.OtlpGrpcSpanExporter; import io.opentelemetry.proto.collector.logs.v1.ExportLogsServiceRequest; import io.opentelemetry.proto.collector.logs.v1.ExportLogsServiceResponse; @@ -63,6 +66,7 @@ import io.opentelemetry.proto.trace.v1.ResourceSpans; import io.opentelemetry.proto.trace.v1.ScopeSpans; import io.opentelemetry.proto.trace.v1.Span.Link; +import io.opentelemetry.sdk.common.export.MemoryMode; import io.opentelemetry.sdk.logs.SdkLoggerProvider; import io.opentelemetry.sdk.logs.export.BatchLogRecordProcessor; import io.opentelemetry.sdk.logs.export.LogRecordExporter; @@ -93,6 +97,7 @@ import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.RegisterExtension; import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.EnumSource; import org.junit.jupiter.params.provider.ValueSource; import org.slf4j.LoggerFactory; import org.testcontainers.containers.BindMode; @@ -195,7 +200,7 @@ void afterEach() {} @ParameterizedTest @ValueSource(strings = {"gzip", "none"}) void testOtlpGrpcTraceExport(String compression) { - SpanExporter otlpGrpcTraceExporter = + SpanExporter exporter = OtlpGrpcSpanExporter.builder() .setEndpoint( "http://" @@ -205,7 +210,7 @@ void testOtlpGrpcTraceExport(String compression) { .setCompression(compression) .build(); - testTraceExport(otlpGrpcTraceExporter); + testTraceExport(exporter); } @Test @@ -227,7 +232,7 @@ void testOtlpGrpcTraceExport_mtls() throws Exception { @ParameterizedTest @ValueSource(strings = {"gzip", "none"}) void testOtlpHttpTraceExport(String compression) { - SpanExporter otlpGrpcTraceExporter = + SpanExporter exporter = OtlpHttpSpanExporter.builder() .setEndpoint( "http://" @@ -238,7 +243,7 @@ void testOtlpHttpTraceExport(String compression) { .setCompression(compression) .build(); - testTraceExport(otlpGrpcTraceExporter); + testTraceExport(exporter); } @Test @@ -328,7 +333,7 @@ private static void testTraceExport(SpanExporter spanExporter) { @ParameterizedTest @ValueSource(strings = {"gzip", "none"}) void testOtlpGrpcMetricExport(String compression) { - MetricExporter otlpGrpcMetricExporter = + MetricExporter exporter = OtlpGrpcMetricExporter.builder() .setEndpoint( "http://" @@ -338,7 +343,26 @@ void testOtlpGrpcMetricExport(String compression) { .setCompression(compression) .build(); - testMetricExport(otlpGrpcMetricExporter); + testMetricExport(exporter); + } + + @ParameterizedTest + @EnumSource(MemoryMode.class) + void testOtlpGrpcMetricExport_memoryMode(MemoryMode memoryMode) { + OtlpGrpcMetricExporterBuilder builder = OtlpGrpcMetricExporter.builder(); + OtlpConfigUtil.setMemoryModeOnOtlpMetricExporterBuilder(builder, memoryMode); + + MetricExporter exporter = + builder + .setEndpoint( + "http://" + + collector.getHost() + + ":" + + collector.getMappedPort(COLLECTOR_OTLP_GRPC_PORT)) + .build(); + assertThat(exporter.getMemoryMode()).isEqualTo(memoryMode); + + testMetricExport(exporter); } @Test @@ -360,7 +384,8 @@ void testOtlpGrpcMetricExport_mtls() throws Exception { @ParameterizedTest @ValueSource(strings = {"gzip", "none"}) void testOtlpHttpMetricExport(String compression) { - MetricExporter otlpGrpcMetricExporter = + + MetricExporter exporter = OtlpHttpMetricExporter.builder() .setEndpoint( "http://" @@ -371,7 +396,27 @@ void testOtlpHttpMetricExport(String compression) { .setCompression(compression) .build(); - testMetricExport(otlpGrpcMetricExporter); + testMetricExport(exporter); + } + + @ParameterizedTest + @EnumSource(MemoryMode.class) + void testOtlpHttpMetricExport_memoryMode(MemoryMode memoryMode) { + OtlpHttpMetricExporterBuilder builder = OtlpHttpMetricExporter.builder(); + OtlpConfigUtil.setMemoryModeOnOtlpMetricExporterBuilder(builder, memoryMode); + + MetricExporter exporter = + builder + .setEndpoint( + "http://" + + collector.getHost() + + ":" + + collector.getMappedPort(COLLECTOR_OTLP_HTTP_PORT) + + "/v1/metrics") + .build(); + assertThat(exporter.getMemoryMode()).isEqualTo(memoryMode); + + testMetricExport(exporter); } @Test diff --git a/sdk-extensions/autoconfigure/README.md b/sdk-extensions/autoconfigure/README.md index 92def7c0b3c..a064dd79be2 100644 --- a/sdk-extensions/autoconfigure/README.md +++ b/sdk-extensions/autoconfigure/README.md @@ -72,11 +72,18 @@ The OpenTelemetry SDK can be disabled entirely. If disabled, `AutoConfiguredOpen The following configuration properties are common to all exporters: -| System property | Environment variable | Purpose | -|-----------------------|-----------------------|----------------------------------------------------------------------------------------------------------------------------| -| otel.traces.exporter | OTEL_TRACES_EXPORTER | List of exporters to be used for tracing, separated by commas. Default is `otlp`. `none` means no autoconfigured exporter. | -| otel.metrics.exporter | OTEL_METRICS_EXPORTER | List of exporters to be used for metrics, separated by commas. Default is `otlp`. `none` means no autoconfigured exporter. | -| otel.logs.exporter | OTEL_LOGS_EXPORTER | List of exporters to be used for logging, separated by commas. Default is `otlp`. `none` means no autoconfigured exporter. | +| System property | Environment variable | Purpose | +|---------------------------------------------|---------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| otel.traces.exporter | OTEL_TRACES_EXPORTER | List of exporters to be used for tracing, separated by commas. Default is `otlp`. `none` means no autoconfigured exporter. | +| otel.metrics.exporter | OTEL_METRICS_EXPORTER | List of exporters to be used for metrics, separated by commas. Default is `otlp`. `none` means no autoconfigured exporter. | +| otel.logs.exporter | OTEL_LOGS_EXPORTER | List of exporters to be used for logging, separated by commas. Default is `otlp`. `none` means no autoconfigured exporter. | +| otel.java.experimental.exporter.memory_mode | OTEL_JAVA_EXPERIMENTAL_EXPORTER_MEMORY_MODE | If `reusable_data`, enable reusable memory mode (on exporters which support it) to reduce allocations. Default is `immutable_data`. This option is experimental and subject to change or removal.**[1]** | + +**[1]**: NOTE: The exporters which adhere +to `otel.java.experimental.exporter.memory_mode=reusable_data` +are `OtlpGrpcMetricExporter`, `OtlpHttpMetricExporter`, and `PrometheusHttpServer`. Support for +additional exporters may be added in the future. + #### OTLP exporter (span, metric, and log exporters) From 5ab678f7af9103d60c9364322865542dfddb9c5c Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 5 Apr 2024 09:50:41 -0500 Subject: [PATCH 334/901] Update dependency io.prometheus:prometheus-metrics-exporter-httpserver to v1.2.1 (#6351) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- dependencyManagement/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index 1f929f213bb..acc690a6673 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -69,7 +69,7 @@ val DEPENDENCIES = listOf( "io.opentelemetry.contrib:opentelemetry-aws-xray-propagator:1.29.0-alpha", "io.opentracing:opentracing-api:0.33.0", "io.opentracing:opentracing-noop:0.33.0", - "io.prometheus:prometheus-metrics-exporter-httpserver:1.2.0", + "io.prometheus:prometheus-metrics-exporter-httpserver:1.2.1", "junit:junit:4.13.2", "nl.jqno.equalsverifier:equalsverifier:3.16.1", "org.awaitility:awaitility:4.2.1", From 95b83564bc8aeb4db50622a0a76ec17e380107e8 Mon Sep 17 00:00:00 2001 From: jack-berg <34418638+jack-berg@users.noreply.github.com> Date: Fri, 5 Apr 2024 12:30:22 -0500 Subject: [PATCH 335/901] Prepare 1.37.0 (#6353) --- CHANGELOG.md | 64 +++++++++++++++++++ .../java/io/opentelemetry/api/trace/Span.java | 2 + .../logs/export/BatchLogRecordProcessor.java | 6 +- .../logs/export/SimpleLogRecordProcessor.java | 6 +- .../sdk/trace/export/BatchSpanProcessor.java | 6 +- .../sdk/trace/export/SimpleSpanProcessor.java | 6 +- 6 files changed, 86 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 24b19d0adc6..6e7b84aa2e8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,70 @@ ## Unreleased +**NOTICE:** This release contains a significant restructuring of the experimental event API and the API incubator artifact. Please read the notes in the `API -> Incubator` section carefully. + +### API + +* Promote `Span#addLink` to stable API + ([#6317](https://github.com/open-telemetry/opentelemetry-java/pull/6317)) + +#### Incubator + +* BREAKING: Rename `opentelemetry-extension-incubator` to `opentelemetry-api-incubator`, + merge `opentelemetry-api-events` into `opentelemetry-api-incubator`. + ([#6289](https://github.com/open-telemetry/opentelemetry-java/pull/6289)) +* BREAKING: Remove domain from event api. `EventEmitterProvider#setEventDomain` has been removed. + The `event.name` field should now be namespaced to avoid collisions. + See [Semantic Conventions for Event Attributes](https://opentelemetry.io/docs/specs/semconv/general/events/) + for more details. + ([#6253](https://github.com/open-telemetry/opentelemetry-java/pull/6253)) +* BREAKING: Rename `EventEmitter` and related classes to `EventLogger`. + ([#6316](https://github.com/open-telemetry/opentelemetry-java/pull/6316)) +* BREAKING: Refactor Event API to reflect spec changes. Restructure API to put fields in + the `AnyValue` log record body. Add setters for timestamp, context, and severity. Set default + severity to `INFO=9`. + ([#6318](https://github.com/open-telemetry/opentelemetry-java/pull/6318)) + +### SDK + +* Add `get{Signal}Exporter` methods to `Simple{Signal}Processor`, `Batch{Signal}Processor`. + ([#6078](https://github.com/open-telemetry/opentelemetry-java/pull/6078)) + +#### Metrics + +* Use synchronized instead of reentrant lock in explicit bucket histogram + ([#6309](https://github.com/open-telemetry/opentelemetry-java/pull/6309)) + +#### Exporters + +* Fix typo in OTLP javadoc + ([#6311](https://github.com/open-telemetry/opentelemetry-java/pull/6311)) +* Add `PrometheusHttpServer#toBuilder()` + ([#6333](https://github.com/open-telemetry/opentelemetry-java/pull/6333)) +* Bugfix: Use `getPrometheusName` for Otel2PrometheusConverter map keys to avoid metric name + conflicts + ([#6308](https://github.com/open-telemetry/opentelemetry-java/pull/6308)) + +#### Extensions + +* Add Metric exporter REUSABLE_DATA memory mode configuration options, including autoconfigure + support via env var `OTEL_JAVA_EXPERIMENTAL_EXPORTER_MEMORY_MODE=REUSABLE_DATA`. + ([#6304](https://github.com/open-telemetry/opentelemetry-java/pull/6304)) +* Add autoconfigure console alias for logging exporter + ([#6027](https://github.com/open-telemetry/opentelemetry-java/pull/6027)) +* Update jaeger autoconfigure docs to point to OTLP + ([#6307](https://github.com/open-telemetry/opentelemetry-java/pull/6307)) +* Add `ServiceInstanceIdResourceProvider` implementation for generating `service.instance.id` UUID + if not already provided by user. Included in `opentelemetry-sdk-extension-incubator`. + ([#6226](https://github.com/open-telemetry/opentelemetry-java/pull/6226)) +* Add GCP resource detector to list of resource providers in autoconfigure docs + ([#6336](https://github.com/open-telemetry/opentelemetry-java/pull/6336)) + +### Tooling + +* Check for Java 17 toolchain and fail if not found + ([#6303](https://github.com/open-telemetry/opentelemetry-java/pull/6303)) + ## Version 1.36.0 (2024-03-08) ### SDK diff --git a/api/all/src/main/java/io/opentelemetry/api/trace/Span.java b/api/all/src/main/java/io/opentelemetry/api/trace/Span.java index 6f8f790a112..8d502859908 100644 --- a/api/all/src/main/java/io/opentelemetry/api/trace/Span.java +++ b/api/all/src/main/java/io/opentelemetry/api/trace/Span.java @@ -374,6 +374,7 @@ default Span recordException(Throwable exception) { * * @param spanContext the context of the linked {@code Span}. * @return this. + * @since 1.37.0 */ default Span addLink(SpanContext spanContext) { return addLink(spanContext, Attributes.empty()); @@ -395,6 +396,7 @@ default Span addLink(SpanContext spanContext) { * @param spanContext the context of the linked {@code Span}. * @param attributes the attributes of the {@code Link}. * @return this. + * @since 1.37.0 */ default Span addLink(SpanContext spanContext, Attributes attributes) { return this; diff --git a/sdk/logs/src/main/java/io/opentelemetry/sdk/logs/export/BatchLogRecordProcessor.java b/sdk/logs/src/main/java/io/opentelemetry/sdk/logs/export/BatchLogRecordProcessor.java index 8de51235128..601bfdfa208 100644 --- a/sdk/logs/src/main/java/io/opentelemetry/sdk/logs/export/BatchLogRecordProcessor.java +++ b/sdk/logs/src/main/java/io/opentelemetry/sdk/logs/export/BatchLogRecordProcessor.java @@ -105,7 +105,11 @@ public CompletableResultCode forceFlush() { return worker.forceFlush(); } - /** Return the processor's configured {@link LogRecordExporter}. */ + /** + * Return the processor's configured {@link LogRecordExporter}. + * + * @since 1.37.0 + */ public LogRecordExporter getLogRecordExporter() { return worker.logRecordExporter; } diff --git a/sdk/logs/src/main/java/io/opentelemetry/sdk/logs/export/SimpleLogRecordProcessor.java b/sdk/logs/src/main/java/io/opentelemetry/sdk/logs/export/SimpleLogRecordProcessor.java index c97eaae8c30..5302212345e 100644 --- a/sdk/logs/src/main/java/io/opentelemetry/sdk/logs/export/SimpleLogRecordProcessor.java +++ b/sdk/logs/src/main/java/io/opentelemetry/sdk/logs/export/SimpleLogRecordProcessor.java @@ -107,7 +107,11 @@ public CompletableResultCode forceFlush() { return CompletableResultCode.ofAll(pendingExports); } - /** Return the processor's configured {@link LogRecordExporter}. */ + /** + * Return the processor's configured {@link LogRecordExporter}. + * + * @since 1.37.0 + */ public LogRecordExporter getLogRecordExporter() { return logRecordExporter; } diff --git a/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/export/BatchSpanProcessor.java b/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/export/BatchSpanProcessor.java index ae487600e81..f6093c5ae8f 100644 --- a/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/export/BatchSpanProcessor.java +++ b/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/export/BatchSpanProcessor.java @@ -122,7 +122,11 @@ public CompletableResultCode forceFlush() { return worker.forceFlush(); } - /** Return the processor's configured {@link SpanExporter}. */ + /** + * Return the processor's configured {@link SpanExporter}. + * + * @since 1.37.0 + */ public SpanExporter getSpanExporter() { return worker.spanExporter; } diff --git a/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/export/SimpleSpanProcessor.java b/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/export/SimpleSpanProcessor.java index c37afd72411..68b197a4b5b 100644 --- a/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/export/SimpleSpanProcessor.java +++ b/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/export/SimpleSpanProcessor.java @@ -135,7 +135,11 @@ public CompletableResultCode forceFlush() { return CompletableResultCode.ofAll(pendingExports); } - /** Return the processor's configured {@link SpanExporter}. */ + /** + * Return the processor's configured {@link SpanExporter}. + * + * @since 1.37.0 + */ public SpanExporter getSpanExporter() { return spanExporter; } From 1f80fe857d0bba6c3951a7d1dd64f05cf2fa6ff3 Mon Sep 17 00:00:00 2001 From: OpenTelemetry Bot <107717825+opentelemetrybot@users.noreply.github.com> Date: Fri, 5 Apr 2024 20:02:57 +0200 Subject: [PATCH 336/901] Update version to 1.38.0 (#6354) --- CHANGELOG.md | 2 ++ version.gradle.kts | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6e7b84aa2e8..7e7f629103b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,8 @@ ## Unreleased +## Version 1.37.0 (2024-04-05) + **NOTICE:** This release contains a significant restructuring of the experimental event API and the API incubator artifact. Please read the notes in the `API -> Incubator` section carefully. ### API diff --git a/version.gradle.kts b/version.gradle.kts index 6a6a6fa9384..bcb45a91233 100644 --- a/version.gradle.kts +++ b/version.gradle.kts @@ -1,7 +1,7 @@ val snapshot = true allprojects { - var ver = "1.37.0" + var ver = "1.38.0" val release = findProperty("otel.release") if (release != null) { ver += "-" + release From 572606ad502158424e6384583d92e5d275f1de0a Mon Sep 17 00:00:00 2001 From: jack-berg <34418638+jack-berg@users.noreply.github.com> Date: Mon, 8 Apr 2024 09:18:55 -0500 Subject: [PATCH 337/901] Add additional API incubator docs (#6356) --- api/incubator/README.md | 45 +++++- api/incubator/build.gradle.kts | 5 +- .../incubator/events/EventApiUsageTest.java | 82 +++++++++++ .../logs/ExtendedLogsBridgeApiUsageTest.java | 74 ++++++++++ .../metrics/ExtendedMetricsApiUsageTest.java | 136 ++++++++++++++++++ .../ExtendedContextPropagatorsUsageTest.java | 76 ++++++++++ dependencyManagement/build.gradle.kts | 3 +- 7 files changed, 415 insertions(+), 6 deletions(-) create mode 100644 api/incubator/src/test/java/io/opentelemetry/api/incubator/events/EventApiUsageTest.java create mode 100644 api/incubator/src/test/java/io/opentelemetry/api/incubator/logs/ExtendedLogsBridgeApiUsageTest.java create mode 100644 api/incubator/src/test/java/io/opentelemetry/api/incubator/metrics/ExtendedMetricsApiUsageTest.java create mode 100644 api/incubator/src/test/java/io/opentelemetry/api/incubator/propagation/ExtendedContextPropagatorsUsageTest.java diff --git a/api/incubator/README.md b/api/incubator/README.md index 64264d01681..68769849e5c 100644 --- a/api/incubator/README.md +++ b/api/incubator/README.md @@ -1,11 +1,48 @@ -# ExtendedTracer +# API Incubator -Utility methods to make it easier to use the OpenTelemetry tracer. +Experimental APIs, including Event API, extended Log Bridge APIs, extended Metrics APIs, extended ContextPropagator APIs, and extended Trace APIs. + +## Event API + +Features: + +* Event API for producing log records according to [Event Semantic Conventions](https://opentelemetry.io/docs/specs/semconv/general/events/). + +See [EventApiUsageTest](./src/test/java/io/opentelemetry/api/incubator/events/EventApiUsageTest.java). + +## Extended Log Bridge API + +Features: + +* Set AnyValue log record body with arbitrarily complex data + +See [ExtendedLogsBridgeApiUsageTest](./src/test/java/io/opentelemetry/api/incubator/logs/ExtendedLogsBridgeApiUsageTest.java). + +## Extended Metrics APIs -## Usage Examples +Features: + +* Synchronous gauge instrument +* Attributes advice + +See [ExtendedMetricsApiUsageTest](./src/test/java/io/opentelemetry/api/incubator/metrics/ExtendedMetricsApiUsageTest.java). + +## Extended ContextPropagator APIs + +Features: + +* Simplified injection / extraction of context + +See [ExtendedContextPropagatorsUsageTest](./src/test/java/io/opentelemetry/api/incubator/propagation/ExtendedContextPropagatorsUsageTest.java). + +## ExtendedTracer + +Utility methods to make it easier to use the OpenTelemetry tracer. Here are some examples how the utility methods can help reduce boilerplate code. +TODO: translate examples to test to ensure no java compilation issues. + ### Tracing a function Before: @@ -145,7 +182,7 @@ String transactionId = extendedTracer.spanBuilder("checkout_cart") .startAndCall(() -> processCheckout(cartId)); ``` -## Exception handling +### Exception handling `ExtendedTracer` re-throws exceptions without modification. This means you can catch exceptions around `ExtendedTracer` calls and handle them as you would without `ExtendedTracer`. diff --git a/api/incubator/build.gradle.kts b/api/incubator/build.gradle.kts index b6f726654a3..05d2b80382c 100644 --- a/api/incubator/build.gradle.kts +++ b/api/incubator/build.gradle.kts @@ -14,6 +14,9 @@ dependencies { annotationProcessor("com.google.auto.value:auto-value") - testImplementation("io.opentelemetry.semconv:opentelemetry-semconv:1.21.0-alpha") testImplementation(project(":sdk:testing")) + + testImplementation("io.opentelemetry.semconv:opentelemetry-semconv") + + testImplementation("com.google.guava:guava") } diff --git a/api/incubator/src/test/java/io/opentelemetry/api/incubator/events/EventApiUsageTest.java b/api/incubator/src/test/java/io/opentelemetry/api/incubator/events/EventApiUsageTest.java new file mode 100644 index 00000000000..4b074ae5b13 --- /dev/null +++ b/api/incubator/src/test/java/io/opentelemetry/api/incubator/events/EventApiUsageTest.java @@ -0,0 +1,82 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.api.incubator.events; + +import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.assertThat; + +import com.google.common.collect.ImmutableMap; +import io.opentelemetry.api.common.Attributes; +import io.opentelemetry.api.incubator.logs.AnyValue; +import io.opentelemetry.sdk.logs.SdkLoggerProvider; +import io.opentelemetry.sdk.logs.export.SimpleLogRecordProcessor; +import io.opentelemetry.sdk.logs.internal.AnyValueBody; +import io.opentelemetry.sdk.logs.internal.SdkEventLoggerProvider; +import io.opentelemetry.sdk.resources.Resource; +import io.opentelemetry.sdk.testing.exporter.InMemoryLogRecordExporter; +import java.util.concurrent.TimeUnit; +import org.junit.jupiter.api.Test; + +/** Demonstrating usage of Event API. */ +class EventApiUsageTest { + + @Test + void eventApiUsage() { + // Setup SdkEventLoggerProvider, which delegates to SdkLoggerProvider + InMemoryLogRecordExporter exporter = InMemoryLogRecordExporter.create(); + SdkLoggerProvider loggerProvider = + SdkLoggerProvider.builder() + // Default resource used for demonstration purposes + .setResource(Resource.getDefault()) + // Simple processor w/ in-memory exporter used for demonstration purposes + .addLogRecordProcessor(SimpleLogRecordProcessor.create(exporter)) + .build(); + EventLoggerProvider eventLoggerProvider = SdkEventLoggerProvider.create(loggerProvider); + + // Get an EventLogger for a scope + EventLogger eventLogger = eventLoggerProvider.get("org.foo.my-scope"); + + // Emit an event + eventLogger + .builder("org.foo.my-event") + // Add fields to the payload. The API has helpers for adding field values which are + // primitives or arrays of primitives, but you can also add a field with type AnyValue, + // allowing for arbitrarily complex payloads. + .put("key1", "value1") + .put( + "key2", + AnyValue.of( + ImmutableMap.of( + "childKey1", AnyValue.of("value2"), "childKey2", AnyValue.of("value3")))) + // Optionally set other fields, including timestamp, severity, context, and attributes + // (attributes provide additional details about the event which are not part of the well + // defined payload) + .emit(); + + // Events manifest as log records with an event.name attribute, and with the payload fields in + // the AnyValue log record body + loggerProvider.forceFlush().join(10, TimeUnit.SECONDS); + assertThat(exporter.getFinishedLogRecordItems()) + .satisfiesExactly( + logData -> { + assertThat(logData) + .hasAttributes( + Attributes.builder().put("event.name", "org.foo.my-event").build()); + assertThat(((AnyValueBody) logData.getBody()).asAnyValue()) + .isEqualTo( + AnyValue.of( + ImmutableMap.of( + "key1", + AnyValue.of("value1"), + "key2", + AnyValue.of( + ImmutableMap.of( + "childKey1", + AnyValue.of("value2"), + "childKey2", + AnyValue.of("value3")))))); + }); + } +} diff --git a/api/incubator/src/test/java/io/opentelemetry/api/incubator/logs/ExtendedLogsBridgeApiUsageTest.java b/api/incubator/src/test/java/io/opentelemetry/api/incubator/logs/ExtendedLogsBridgeApiUsageTest.java new file mode 100644 index 00000000000..7a1f82e64d0 --- /dev/null +++ b/api/incubator/src/test/java/io/opentelemetry/api/incubator/logs/ExtendedLogsBridgeApiUsageTest.java @@ -0,0 +1,74 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.api.incubator.logs; + +import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.assertThat; + +import com.google.common.collect.ImmutableMap; +import io.opentelemetry.api.logs.Logger; +import io.opentelemetry.sdk.logs.SdkLoggerProvider; +import io.opentelemetry.sdk.logs.export.SimpleLogRecordProcessor; +import io.opentelemetry.sdk.logs.internal.AnyValueBody; +import io.opentelemetry.sdk.resources.Resource; +import io.opentelemetry.sdk.testing.exporter.InMemoryLogRecordExporter; +import java.util.concurrent.TimeUnit; +import org.junit.jupiter.api.Test; + +/** Demonstrating usage of extended Logs Bridge API. */ +class ExtendedLogsBridgeApiUsageTest { + + @Test + void extendedLogRecordBuilderUsage() { + // Setup SdkLoggerProvider + InMemoryLogRecordExporter exporter = InMemoryLogRecordExporter.create(); + SdkLoggerProvider loggerProvider = + SdkLoggerProvider.builder() + // Default resource used for demonstration purposes + .setResource(Resource.getDefault()) + // Simple processor w/ in-memory exporter used for demonstration purposes + .addLogRecordProcessor(SimpleLogRecordProcessor.create(exporter)) + .build(); + + // Get a Logger for a scope + Logger logger = loggerProvider.get("org.foo.my-scope"); + + // Cast to ExtendedLogRecordBuilder, and emit a log + ((ExtendedLogRecordBuilder) logger.logRecordBuilder()) + // ...can set AnyValue log record body, allowing for arbitrarily complex data + .setBody( + AnyValue.of( + ImmutableMap.of( + "key1", + AnyValue.of("value1"), + "key2", + AnyValue.of( + ImmutableMap.of( + "childKey1", + AnyValue.of("value2"), + "childKey2", + AnyValue.of("value3")))))) + .emit(); + + // SDK can access AnyValue body by casting to AnyValueBody + loggerProvider.forceFlush().join(10, TimeUnit.SECONDS); + assertThat(exporter.getFinishedLogRecordItems()) + .satisfiesExactly( + logData -> + assertThat(((AnyValueBody) logData.getBody()).asAnyValue()) + .isEqualTo( + AnyValue.of( + ImmutableMap.of( + "key1", + AnyValue.of("value1"), + "key2", + AnyValue.of( + ImmutableMap.of( + "childKey1", + AnyValue.of("value2"), + "childKey2", + AnyValue.of("value3"))))))); + } +} diff --git a/api/incubator/src/test/java/io/opentelemetry/api/incubator/metrics/ExtendedMetricsApiUsageTest.java b/api/incubator/src/test/java/io/opentelemetry/api/incubator/metrics/ExtendedMetricsApiUsageTest.java new file mode 100644 index 00000000000..ea219c1cc70 --- /dev/null +++ b/api/incubator/src/test/java/io/opentelemetry/api/incubator/metrics/ExtendedMetricsApiUsageTest.java @@ -0,0 +1,136 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.api.incubator.metrics; + +import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.assertThat; + +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableSet; +import io.opentelemetry.api.common.AttributeKey; +import io.opentelemetry.api.common.Attributes; +import io.opentelemetry.api.metrics.LongCounter; +import io.opentelemetry.api.metrics.Meter; +import io.opentelemetry.sdk.metrics.InstrumentSelector; +import io.opentelemetry.sdk.metrics.SdkMeterProvider; +import io.opentelemetry.sdk.metrics.View; +import io.opentelemetry.sdk.resources.Resource; +import io.opentelemetry.sdk.testing.exporter.InMemoryMetricReader; +import org.junit.jupiter.api.Test; + +/** Demonstrating usage of extended Metrics API. */ +class ExtendedMetricsApiUsageTest { + + @Test + void synchronousGaugeUsage() { + // Setup SdkMeterProvider + InMemoryMetricReader reader = InMemoryMetricReader.create(); + SdkMeterProvider meterProvider = + SdkMeterProvider.builder() + // Default resource used for demonstration purposes + .setResource(Resource.getDefault()) + // In-memory reader used for demonstration purposes + .registerMetricReader(reader) + .build(); + + // Get a Meter for a scope + Meter meter = meterProvider.get("org.foo.my-scope"); + + // Cast GaugeBuilder to ExtendedDoubleGaugeBuilder + DoubleGauge gauge = ((ExtendedDoubleGaugeBuilder) meter.gaugeBuilder("my-gauge")).build(); + + // Call set synchronously to set the value + gauge.set(1.0, Attributes.builder().put("key", "value1").build()); + gauge.set(2.0, Attributes.builder().put("key", "value2").build()); + + assertThat(reader.collectAllMetrics()) + .satisfiesExactly( + metricData -> + assertThat(metricData) + .hasName("my-gauge") + .hasDoubleGaugeSatisfying( + gaugeAssert -> + gaugeAssert.hasPointsSatisfying( + point -> + point + .hasValue(1.0) + .hasAttributes( + Attributes.builder().put("key", "value1").build()), + point -> + point + .hasValue(2.0) + .hasAttributes( + Attributes.builder().put("key", "value2").build())))); + } + + @Test + void attributesAdvice() { + // Setup SdkMeterProvider + InMemoryMetricReader reader = InMemoryMetricReader.create(); + SdkMeterProvider meterProvider = + SdkMeterProvider.builder() + // Default resource used for demonstration purposes + .setResource(Resource.getDefault()) + // In-memory reader used for demonstration purposes + .registerMetricReader(reader) + // Register a view which indicates that for counter1, attributes key1, key2 should be + // retained + .registerView( + InstrumentSelector.builder().setName("counter1").build(), + View.builder().setAttributeFilter(ImmutableSet.of("key1", "key2")).build()) + .build(); + + // Get a Meter for a scope + Meter meter = meterProvider.get("org.foo.my-scope"); + + // To apply attribute advice, cast the instrument builder to appropriate + // Extended{Instrument}Builder, and call setAttributeAdvice + // Here we create counter1 and counter2, both configured to only retain attribute key1. counter1 + // has a view configured which overrides this and retains key1, key2. + LongCounter counter1 = + ((ExtendedLongCounterBuilder) meter.counterBuilder("counter1")) + .setAttributesAdvice(ImmutableList.of(AttributeKey.stringKey("key1"))) + .build(); + LongCounter counter2 = + ((ExtendedLongCounterBuilder) meter.counterBuilder("counter2")) + .setAttributesAdvice(ImmutableList.of(AttributeKey.stringKey("key1"))) + .build(); + + // Record data with attribute key1, key2 + counter1.add(1, Attributes.builder().put("key1", "value1").put("key2", "value2").build()); + counter2.add(1, Attributes.builder().put("key1", "value1").put("key2", "value2").build()); + + // Verify that counter1 has both key1, key2 since view overrides the attribute advice + // Verify that counter2 only has key1, since attribute advice causes key2 to be dropped by + // default + assertThat(reader.collectAllMetrics()) + .satisfiesExactlyInAnyOrder( + metricData -> + assertThat(metricData) + .hasName("counter1") + .hasLongSumSatisfying( + sumAssert -> + sumAssert.hasPointsSatisfying( + point -> + point + .hasValue(1L) + .hasAttributes( + Attributes.builder() + .put("key1", "value1") + .put("key2", "value2") + .build()))), + metricData -> + assertThat(metricData) + .hasName("counter2") + .hasLongSumSatisfying( + sumAssert -> + sumAssert.hasPointsSatisfying( + point -> + point + .hasValue(1L) + .hasAttributes( + Attributes.builder().put("key1", "value1").build())))); + } +} diff --git a/api/incubator/src/test/java/io/opentelemetry/api/incubator/propagation/ExtendedContextPropagatorsUsageTest.java b/api/incubator/src/test/java/io/opentelemetry/api/incubator/propagation/ExtendedContextPropagatorsUsageTest.java new file mode 100644 index 00000000000..d3bacb21483 --- /dev/null +++ b/api/incubator/src/test/java/io/opentelemetry/api/incubator/propagation/ExtendedContextPropagatorsUsageTest.java @@ -0,0 +1,76 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.api.incubator.propagation; + +import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.assertThat; + +import com.google.common.collect.ImmutableMap; +import io.opentelemetry.api.trace.Span; +import io.opentelemetry.api.trace.SpanContext; +import io.opentelemetry.api.trace.TraceFlags; +import io.opentelemetry.api.trace.TraceState; +import io.opentelemetry.api.trace.Tracer; +import io.opentelemetry.api.trace.propagation.W3CTraceContextPropagator; +import io.opentelemetry.context.Context; +import io.opentelemetry.context.Scope; +import io.opentelemetry.context.propagation.ContextPropagators; +import io.opentelemetry.context.propagation.TextMapPropagator; +import io.opentelemetry.sdk.trace.SdkTracerProvider; +import io.opentelemetry.sdk.trace.samplers.Sampler; +import java.util.Map; +import org.junit.jupiter.api.Test; + +/** Demonstrating usage of extended ContextPropagators API. */ +class ExtendedContextPropagatorsUsageTest { + + @Test + void getTextMapPropagationContextUsage() { + // Setup Propagators + ContextPropagators propagators = + ContextPropagators.create( + TextMapPropagator.composite(W3CTraceContextPropagator.getInstance())); + + // Setup SdkTracerProvider + SdkTracerProvider tracerProvider = + SdkTracerProvider.builder().setSampler(Sampler.alwaysOn()).build(); + + // Get a Tracer for a scope + Tracer tracer = tracerProvider.get("org.foo.my-scope"); + + try (Scope scope = tracer.spanBuilder("span name").startSpan().makeCurrent()) { + // Simplify context injection by getting a text map of the key/value pairs to inject + Map textMap = + ExtendedContextPropagators.getTextMapPropagationContext(propagators); + // Assert textmap contains the "traceparent" field as injected by W3CTraceContextPropagator + assertThat(textMap) + .hasEntrySatisfying("traceparent", value -> assertThat(value).isNotEmpty()); + } + } + + @Test + void extractTextMapPropagationContextUsage() { + // Setup Propagators + ContextPropagators propagators = + ContextPropagators.create( + TextMapPropagator.composite(W3CTraceContextPropagator.getInstance())); + + // Setup map with context key/value pairs + Map contextCarrier = + ImmutableMap.of("traceparent", "00-713bde54561be5ded62545d0e7369d4a-3c3a5ddefce9c1e1-01"); + + // Extract context from the carrier map + Context context = + ExtendedContextPropagators.extractTextMapPropagationContext(contextCarrier, propagators); + // Assert SpanContext is properly extracted from the W3cTraceContextPropagator + assertThat(Span.fromContext(context).getSpanContext()) + .isEqualTo( + SpanContext.createFromRemoteParent( + "713bde54561be5ded62545d0e7369d4a", + "3c3a5ddefce9c1e1", + TraceFlags.getSampled(), + TraceState.getDefault())); + } +} diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index acc690a6673..5ad03624ce5 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -65,8 +65,9 @@ val DEPENDENCIES = listOf( "eu.rekawek.toxiproxy:toxiproxy-java:2.1.7", "io.github.netmikey.logunit:logunit-jul:2.0.0", "io.jaegertracing:jaeger-client:1.8.1", - "io.opentelemetry.proto:opentelemetry-proto:1.1.0-alpha", "io.opentelemetry.contrib:opentelemetry-aws-xray-propagator:1.29.0-alpha", + "io.opentelemetry.semconv:opentelemetry-semconv:1.21.0-alpha", + "io.opentelemetry.proto:opentelemetry-proto:1.1.0-alpha", "io.opentracing:opentracing-api:0.33.0", "io.opentracing:opentracing-noop:0.33.0", "io.prometheus:prometheus-metrics-exporter-httpserver:1.2.1", From bbcb2511d48d33bfb33b7c602bd71c232e8e484f Mon Sep 17 00:00:00 2001 From: Trask Stalnaker Date: Mon, 8 Apr 2024 07:23:29 -0700 Subject: [PATCH 338/901] Tell renovate to update opentelemetry-proto and opentelemetry-semconv alpha artifacts (#6358) --- .github/renovate.json5 | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/.github/renovate.json5 b/.github/renovate.json5 index a22fdfb2e4e..fb24ef3474d 100644 --- a/.github/renovate.json5 +++ b/.github/renovate.json5 @@ -4,6 +4,18 @@ "config:base" ], "packageRules": [ + { + "matchPackageNames": [ + "io.opentelemetry.proto:opentelemetry-proto", + "io.opentelemetry.semconv:opentelemetry-semconv" + ], + // Renovate's default behavior is only to update from unstable -> unstable if it's for the + // major.minor.patch, under the assumption that you would want to update to the stable version + // of that release instead of the unstable version for a future release + // (TODO remove once the artifacts above release stable versions) + "ignoreUnstable": false, + "allowedVersions": "!/\\-SNAPSHOT$/" + }, { // junit-pioneer 2+ requires Java 11+ "matchPackageNames": ["org.junit-pioneer:junit-pioneer"], From ab18dd6e556697291c55c5d9e4d36bf2597558e1 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 8 Apr 2024 13:42:18 -0500 Subject: [PATCH 339/901] Update dependency io.opentelemetry.semconv:opentelemetry-semconv to v1.24.0-alpha (#6362) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Co-authored-by: Jack Berg --- .github/renovate.json5 | 2 +- api/incubator/build.gradle.kts | 2 +- .../api/incubator/trace/ExtendedTracerTest.java | 13 ++++++++----- dependencyManagement/build.gradle.kts | 2 +- 4 files changed, 11 insertions(+), 8 deletions(-) diff --git a/.github/renovate.json5 b/.github/renovate.json5 index fb24ef3474d..d5a05ac2ea2 100644 --- a/.github/renovate.json5 +++ b/.github/renovate.json5 @@ -7,7 +7,7 @@ { "matchPackageNames": [ "io.opentelemetry.proto:opentelemetry-proto", - "io.opentelemetry.semconv:opentelemetry-semconv" + "io.opentelemetry.semconv:opentelemetry-semconv-incubating" ], // Renovate's default behavior is only to update from unstable -> unstable if it's for the // major.minor.patch, under the assumption that you would want to update to the stable version diff --git a/api/incubator/build.gradle.kts b/api/incubator/build.gradle.kts index 05d2b80382c..3dfa0e79a3c 100644 --- a/api/incubator/build.gradle.kts +++ b/api/incubator/build.gradle.kts @@ -16,7 +16,7 @@ dependencies { testImplementation(project(":sdk:testing")) - testImplementation("io.opentelemetry.semconv:opentelemetry-semconv") + testImplementation("io.opentelemetry.semconv:opentelemetry-semconv-incubating") testImplementation("com.google.guava:guava") } diff --git a/api/incubator/src/test/java/io/opentelemetry/api/incubator/trace/ExtendedTracerTest.java b/api/incubator/src/test/java/io/opentelemetry/api/incubator/trace/ExtendedTracerTest.java index 9417763b842..93124fe25cc 100644 --- a/api/incubator/src/test/java/io/opentelemetry/api/incubator/trace/ExtendedTracerTest.java +++ b/api/incubator/src/test/java/io/opentelemetry/api/incubator/trace/ExtendedTracerTest.java @@ -23,7 +23,8 @@ import io.opentelemetry.sdk.testing.assertj.SpanDataAssert; import io.opentelemetry.sdk.testing.junit5.OpenTelemetryExtension; import io.opentelemetry.sdk.trace.data.StatusData; -import io.opentelemetry.semconv.SemanticAttributes; +import io.opentelemetry.semconv.ClientAttributes; +import io.opentelemetry.semconv.incubating.ExceptionIncubatingAttributes; import java.time.Instant; import java.util.Collections; import java.util.Map; @@ -84,14 +85,16 @@ void wrapInSpan() { .hasName("exception") .hasAttributesSatisfyingExactly( equalTo( - SemanticAttributes.EXCEPTION_TYPE, + ExceptionIncubatingAttributes.EXCEPTION_TYPE, "java.lang.IllegalStateException"), satisfies( - SemanticAttributes.EXCEPTION_STACKTRACE, + ExceptionIncubatingAttributes.EXCEPTION_STACKTRACE, string -> string.contains( "java.lang.IllegalStateException: ex")), - equalTo(SemanticAttributes.EXCEPTION_MESSAGE, "ex")))), + equalTo( + ExceptionIncubatingAttributes.EXCEPTION_MESSAGE, + "ex")))), trace -> trace.hasSpansSatisfyingExactly(a -> a.hasName("another test"))); } @@ -123,7 +126,7 @@ void propagation() { .setAttribute("key2", 0) .setAttribute("key3", 0.0) .setAttribute("key4", false) - .setAttribute(SemanticAttributes.CLIENT_PORT, 1234L) + .setAttribute(ClientAttributes.CLIENT_PORT, 1234L) .addLink(invalid.getSpanContext()) .addLink(invalid.getSpanContext(), Attributes.empty()) .setAllAttributes(Attributes.empty()) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index 5ad03624ce5..8437028c12b 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -66,7 +66,7 @@ val DEPENDENCIES = listOf( "io.github.netmikey.logunit:logunit-jul:2.0.0", "io.jaegertracing:jaeger-client:1.8.1", "io.opentelemetry.contrib:opentelemetry-aws-xray-propagator:1.29.0-alpha", - "io.opentelemetry.semconv:opentelemetry-semconv:1.21.0-alpha", + "io.opentelemetry.semconv:opentelemetry-semconv-incubating:1.24.0-alpha", "io.opentelemetry.proto:opentelemetry-proto:1.1.0-alpha", "io.opentracing:opentracing-api:0.33.0", "io.opentracing:opentracing-noop:0.33.0", From 001f34f1703a43cdd473d2a94d15c125f6d2d622 Mon Sep 17 00:00:00 2001 From: jack-berg <34418638+jack-berg@users.noreply.github.com> Date: Mon, 8 Apr 2024 17:37:01 -0500 Subject: [PATCH 340/901] Post release 1.37.0 (#6364) --- README.md | 74 +++++++++---------- .../1.37.0_vs_1.36.0/opentelemetry-api.txt | 5 ++ .../opentelemetry-context.txt | 2 + .../opentelemetry-exporter-common.txt | 2 + .../opentelemetry-exporter-logging-otlp.txt | 2 + .../opentelemetry-exporter-logging.txt | 2 + .../opentelemetry-exporter-otlp-common.txt | 2 + .../opentelemetry-exporter-otlp.txt | 7 ++ ...y-exporter-sender-grpc-managed-channel.txt | 2 + .../opentelemetry-exporter-sender-okhttp.txt | 2 + .../opentelemetry-exporter-zipkin.txt | 2 + .../opentelemetry-extension-kotlin.txt | 2 + ...ntelemetry-extension-trace-propagators.txt | 2 + .../opentelemetry-opentracing-shim.txt | 2 + .../opentelemetry-sdk-common.txt | 2 + ...emetry-sdk-extension-autoconfigure-spi.txt | 2 + ...ntelemetry-sdk-extension-autoconfigure.txt | 2 + ...ry-sdk-extension-jaeger-remote-sampler.txt | 2 + .../opentelemetry-sdk-logs.txt | 7 ++ .../opentelemetry-sdk-metrics.txt | 2 + .../opentelemetry-sdk-testing.txt | 2 + .../opentelemetry-sdk-trace.txt | 7 ++ .../1.37.0_vs_1.36.0/opentelemetry-sdk.txt | 2 + .../current_vs_latest/opentelemetry-api.txt | 5 +- .../opentelemetry-exporter-otlp.txt | 7 +- .../opentelemetry-sdk-logs.txt | 7 +- .../opentelemetry-sdk-trace.txt | 7 +- 27 files changed, 103 insertions(+), 59 deletions(-) create mode 100644 docs/apidiffs/1.37.0_vs_1.36.0/opentelemetry-api.txt create mode 100644 docs/apidiffs/1.37.0_vs_1.36.0/opentelemetry-context.txt create mode 100644 docs/apidiffs/1.37.0_vs_1.36.0/opentelemetry-exporter-common.txt create mode 100644 docs/apidiffs/1.37.0_vs_1.36.0/opentelemetry-exporter-logging-otlp.txt create mode 100644 docs/apidiffs/1.37.0_vs_1.36.0/opentelemetry-exporter-logging.txt create mode 100644 docs/apidiffs/1.37.0_vs_1.36.0/opentelemetry-exporter-otlp-common.txt create mode 100644 docs/apidiffs/1.37.0_vs_1.36.0/opentelemetry-exporter-otlp.txt create mode 100644 docs/apidiffs/1.37.0_vs_1.36.0/opentelemetry-exporter-sender-grpc-managed-channel.txt create mode 100644 docs/apidiffs/1.37.0_vs_1.36.0/opentelemetry-exporter-sender-okhttp.txt create mode 100644 docs/apidiffs/1.37.0_vs_1.36.0/opentelemetry-exporter-zipkin.txt create mode 100644 docs/apidiffs/1.37.0_vs_1.36.0/opentelemetry-extension-kotlin.txt create mode 100644 docs/apidiffs/1.37.0_vs_1.36.0/opentelemetry-extension-trace-propagators.txt create mode 100644 docs/apidiffs/1.37.0_vs_1.36.0/opentelemetry-opentracing-shim.txt create mode 100644 docs/apidiffs/1.37.0_vs_1.36.0/opentelemetry-sdk-common.txt create mode 100644 docs/apidiffs/1.37.0_vs_1.36.0/opentelemetry-sdk-extension-autoconfigure-spi.txt create mode 100644 docs/apidiffs/1.37.0_vs_1.36.0/opentelemetry-sdk-extension-autoconfigure.txt create mode 100644 docs/apidiffs/1.37.0_vs_1.36.0/opentelemetry-sdk-extension-jaeger-remote-sampler.txt create mode 100644 docs/apidiffs/1.37.0_vs_1.36.0/opentelemetry-sdk-logs.txt create mode 100644 docs/apidiffs/1.37.0_vs_1.36.0/opentelemetry-sdk-metrics.txt create mode 100644 docs/apidiffs/1.37.0_vs_1.36.0/opentelemetry-sdk-testing.txt create mode 100644 docs/apidiffs/1.37.0_vs_1.36.0/opentelemetry-sdk-trace.txt create mode 100644 docs/apidiffs/1.37.0_vs_1.36.0/opentelemetry-sdk.txt diff --git a/README.md b/README.md index aa2737f78ba..dbf41811f26 100644 --- a/README.md +++ b/README.md @@ -104,7 +104,7 @@ dependency versions in sync. io.opentelemetry opentelemetry-bom - 1.36.0 + 1.37.0 pom import @@ -123,7 +123,7 @@ dependency versions in sync. ```groovy dependencies { - implementation platform("io.opentelemetry:opentelemetry-bom:1.36.0") + implementation platform("io.opentelemetry:opentelemetry-bom:1.37.0") implementation('io.opentelemetry:opentelemetry-api') } ``` @@ -132,8 +132,8 @@ Note that if you want to use any artifacts that have not fully stabilized yet (s ```groovy dependencies { - implementation platform("io.opentelemetry:opentelemetry-bom:1.36.0") - implementation platform('io.opentelemetry:opentelemetry-bom-alpha:1.36.0-alpha') + implementation platform("io.opentelemetry:opentelemetry-bom:1.37.0") + implementation platform('io.opentelemetry:opentelemetry-bom-alpha:1.37.0-alpha') implementation('io.opentelemetry:opentelemetry-api') implementation('io.opentelemetry:opentelemetry-exporter-prometheus') @@ -161,7 +161,7 @@ We strongly recommend using our published BOM to keep all dependency versions in io.opentelemetry opentelemetry-bom - 1.37.0-SNAPSHOT + 1.38.0-SNAPSHOT pom import @@ -184,7 +184,7 @@ repositories { } dependencies { - implementation platform("io.opentelemetry:opentelemetry-bom:1.37.0-SNAPSHOT") + implementation platform("io.opentelemetry:opentelemetry-bom:1.38.0-SNAPSHOT") implementation('io.opentelemetry:opentelemetry-api') } ``` @@ -229,66 +229,66 @@ dependency as follows, replacing `{{artifact-id}}` with the value from the "Arti | Component | Description | Artifact ID | Version | Javadoc | |----------------------------------------------|----------------------------------------|---------------------------|-------------------------------------------------------------|---------| -| [Bill of Materials (BOM)](./bom) | Bill of materials for stable artifacts | `opentelemetry-bom` | 1.36.0 | N/A | -| [Alpha Bill of Materials (BOM)](./bom-alpha) | Bill of materials for alpha artifacts | `opentelemetry-bom-alpha` | 1.36.0-alpha | N/A | +| [Bill of Materials (BOM)](./bom) | Bill of materials for stable artifacts | `opentelemetry-bom` | 1.37.0 | N/A | +| [Alpha Bill of Materials (BOM)](./bom-alpha) | Bill of materials for alpha artifacts | `opentelemetry-bom-alpha` | 1.37.0-alpha | N/A | ### API -| Component | Description | Artifact ID | Version | Javadoc | -|-----------------------------------|--------------------------------------------------------------------------------------|-------------------------------|-------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------| -| [API](./api/all) | OpenTelemetry API, including metrics, traces, baggage, context | `opentelemetry-api` | 1.36.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-api.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-api) | -| [API Incubator](./api/incubator) | API incubator, including pass through propagator, and extended tracer, and Event API | `opentelemetry-api-incubator` | TODO: add after first publish | TODO: add after first publish | -| [Context API](./context) | OpenTelemetry context API | `opentelemetry-context` | 1.36.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-context.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-context) | +| Component | Description | Artifact ID | Version | Javadoc | +|-----------------------------------|--------------------------------------------------------------------------------------|-------------------------------|---------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| [API](./api/all) | OpenTelemetry API, including metrics, traces, baggage, context | `opentelemetry-api` | 1.37.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-api.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-api) | +| [API Incubator](./api/incubator) | API incubator, including pass through propagator, and extended tracer, and Event API | `opentelemetry-api-incubator` | 1.37.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-api-incubator.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-api-incubator) | +| [Context API](./context) | OpenTelemetry context API | `opentelemetry-context` | 1.37.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-context.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-context) | ### API Extensions | Component | Description | Artifact ID | Version | Javadoc | |---------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|---------------------------------------------|-------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| [Kotlin Extension](./extensions/kotlin) | Context extension for coroutines | `opentelemetry-extension-kotlin` | 1.36.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-extension-kotlin.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-extension-kotlin) | -| [Trace Propagators Extension](./extensions/trace-propagators) | Trace propagators, including B3, Jaeger, OT Trace | `opentelemetry-extension-trace-propagators` | 1.36.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-extension-trace-propagators.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-extension-trace-propagators) | +| [Kotlin Extension](./extensions/kotlin) | Context extension for coroutines | `opentelemetry-extension-kotlin` | 1.37.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-extension-kotlin.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-extension-kotlin) | +| [Trace Propagators Extension](./extensions/trace-propagators) | Trace propagators, including B3, Jaeger, OT Trace | `opentelemetry-extension-trace-propagators` | 1.37.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-extension-trace-propagators.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-extension-trace-propagators) | ### SDK | Component | Description | Artifact ID | Version | Javadoc | |------------------------------|--------------------------------------------------------|-----------------------------|---------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| [SDK](./sdk/all) | OpenTelemetry SDK, including metrics, traces, and logs | `opentelemetry-sdk` | 1.36.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk) | -| [Metrics SDK](./sdk/metrics) | OpenTelemetry metrics SDK | `opentelemetry-sdk-metrics` | 1.36.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-metrics.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-metrics) | -| [Trace SDK](./sdk/trace) | OpenTelemetry trace SDK | `opentelemetry-sdk-trace` | 1.36.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-trace.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-trace) | -| [Log SDK](./sdk/logs) | OpenTelemetry log SDK | `opentelemetry-sdk-logs` | 1.36.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-logs.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-logs) | -| [SDK Common](./sdk/common) | Shared SDK components | `opentelemetry-sdk-common` | 1.36.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-common.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-common) | -| [SDK Testing](./sdk/testing) | Components for testing OpenTelemetry instrumentation | `opentelemetry-sdk-testing` | 1.36.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-testing.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-testing) | +| [SDK](./sdk/all) | OpenTelemetry SDK, including metrics, traces, and logs | `opentelemetry-sdk` | 1.37.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk) | +| [Metrics SDK](./sdk/metrics) | OpenTelemetry metrics SDK | `opentelemetry-sdk-metrics` | 1.37.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-metrics.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-metrics) | +| [Trace SDK](./sdk/trace) | OpenTelemetry trace SDK | `opentelemetry-sdk-trace` | 1.37.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-trace.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-trace) | +| [Log SDK](./sdk/logs) | OpenTelemetry log SDK | `opentelemetry-sdk-logs` | 1.37.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-logs.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-logs) | +| [SDK Common](./sdk/common) | Shared SDK components | `opentelemetry-sdk-common` | 1.37.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-common.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-common) | +| [SDK Testing](./sdk/testing) | Components for testing OpenTelemetry instrumentation | `opentelemetry-sdk-testing` | 1.37.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-testing.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-testing) | ### SDK Exporters | Component | Description | Artifact ID | Version | Javadoc | |-----------------------------------------------------------------------|------------------------------------------------------------------------------|------------------------------------------------------|-------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| [OTLP Exporters](./exporters/otlp/all) | OTLP gRPC & HTTP exporters, including traces, metrics, and logs | `opentelemetry-exporter-otlp` | 1.36.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-otlp.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-otlp) | -| [OTLP Logging Exporters](./exporters/logging-otlp) | Logging exporters in OTLP JSON encoding, including traces, metrics, and logs | `opentelemetry-exporter-logging-otlp` | 1.36.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-logging-otlp.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-logging-otlp) | -| [OTLP Common](./exporters/otlp/common) | Shared OTLP components (internal) | `opentelemetry-exporter-otlp-common` | 1.36.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-otlp-common.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-otlp-common) | -| [Logging Exporter](./exporters/logging) | Logging exporters, including metrics, traces, and logs | `opentelemetry-exporter-logging` | 1.36.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-logging.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-logging) | -| [Zipkin Exporter](./exporters/zipkin) | Zipkin trace exporter | `opentelemetry-exporter-zipkin` | 1.36.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-zipkin.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-zipkin) | -| [Prometheus Exporter](./exporters/prometheus) | Prometheus metric exporter | `opentelemetry-exporter-prometheus` | 1.36.0-alpha | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-prometheus.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-prometheus) | -| [Exporter Common](./exporters/common) | Shared exporter components (internal) | `opentelemetry-exporter-common` | 1.36.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-common.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-common) | -| [OkHttp Sender](./exporters/sender/okhttp) | OkHttp implementation of HttpSender (internal) | `opentelemetry-exporter-sender-okhttp` | 1.36.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-sender-okhttp.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-sender-okhttp) | -| [JDK Sender](./exporters/sender/okhttp) | Java 11+ native HttpClient implementation of HttpSender (internal) | `opentelemetry-exporter-sender-jdk` | 1.36.0-alpha | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-sender-jdk.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-sender-jdk) | | -| [gRPC ManagedChannel Sender](./exporters/sender/grpc-managed-channel) | gRPC ManagedChannel implementation of GrpcSender (internal) | `opentelemetry-exporter-sender-grpc-managed-channel` | 1.36.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-sender-grpc-managed-channel.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-sender-grpc-managed-channel) | | +| [OTLP Exporters](./exporters/otlp/all) | OTLP gRPC & HTTP exporters, including traces, metrics, and logs | `opentelemetry-exporter-otlp` | 1.37.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-otlp.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-otlp) | +| [OTLP Logging Exporters](./exporters/logging-otlp) | Logging exporters in OTLP JSON encoding, including traces, metrics, and logs | `opentelemetry-exporter-logging-otlp` | 1.37.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-logging-otlp.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-logging-otlp) | +| [OTLP Common](./exporters/otlp/common) | Shared OTLP components (internal) | `opentelemetry-exporter-otlp-common` | 1.37.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-otlp-common.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-otlp-common) | +| [Logging Exporter](./exporters/logging) | Logging exporters, including metrics, traces, and logs | `opentelemetry-exporter-logging` | 1.37.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-logging.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-logging) | +| [Zipkin Exporter](./exporters/zipkin) | Zipkin trace exporter | `opentelemetry-exporter-zipkin` | 1.37.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-zipkin.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-zipkin) | +| [Prometheus Exporter](./exporters/prometheus) | Prometheus metric exporter | `opentelemetry-exporter-prometheus` | 1.37.0-alpha | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-prometheus.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-prometheus) | +| [Exporter Common](./exporters/common) | Shared exporter components (internal) | `opentelemetry-exporter-common` | 1.37.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-common.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-common) | +| [OkHttp Sender](./exporters/sender/okhttp) | OkHttp implementation of HttpSender (internal) | `opentelemetry-exporter-sender-okhttp` | 1.37.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-sender-okhttp.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-sender-okhttp) | +| [JDK Sender](./exporters/sender/okhttp) | Java 11+ native HttpClient implementation of HttpSender (internal) | `opentelemetry-exporter-sender-jdk` | 1.37.0-alpha | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-sender-jdk.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-sender-jdk) | | +| [gRPC ManagedChannel Sender](./exporters/sender/grpc-managed-channel) | gRPC ManagedChannel implementation of GrpcSender (internal) | `opentelemetry-exporter-sender-grpc-managed-channel` | 1.37.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-sender-grpc-managed-channel.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-sender-grpc-managed-channel) | | ### SDK Extensions | Component | Description | Artifact ID | Version | Javadoc | |-------------------------------------------------------------------------------|------------------------------------------------------------------------------------|-----------------------------------------------------|-------------------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| [SDK Autoconfigure](./sdk-extensions/autoconfigure) | Autoconfigure OpenTelemetry SDK from env vars, system properties, and SPI | `opentelemetry-sdk-extension-autoconfigure` | 1.36.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-extension-autoconfigure.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-extension-autoconfigure) | -| [SDK Autoconfigure SPI](./sdk-extensions/autoconfigure-spi) | Service Provider Interface (SPI) definitions for autoconfigure | `opentelemetry-sdk-extension-autoconfigure-spi` | 1.36.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-extension-autoconfigure-spi.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-extension-autoconfigure-spi) | -| [SDK Jaeger Remote Sampler Extension](./sdk-extensions/jaeger-remote-sampler) | Sampler which obtains sampling configuration from remote Jaeger server | `opentelemetry-sdk-extension-jaeger-remote-sampler` | 1.36.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-extension-jaeger-remote-sampler.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-extension-jaeger-remote-sampler) | -| [SDK Incubator](./sdk-extensions/incubator) | SDK incubator, including YAML based view configuration, LeakDetectingSpanProcessor | `opentelemetry-sdk-extension-incubator` | 1.36.0-alpha | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-extension-incubator.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-extension-incubator) | +| [SDK Autoconfigure](./sdk-extensions/autoconfigure) | Autoconfigure OpenTelemetry SDK from env vars, system properties, and SPI | `opentelemetry-sdk-extension-autoconfigure` | 1.37.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-extension-autoconfigure.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-extension-autoconfigure) | +| [SDK Autoconfigure SPI](./sdk-extensions/autoconfigure-spi) | Service Provider Interface (SPI) definitions for autoconfigure | `opentelemetry-sdk-extension-autoconfigure-spi` | 1.37.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-extension-autoconfigure-spi.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-extension-autoconfigure-spi) | +| [SDK Jaeger Remote Sampler Extension](./sdk-extensions/jaeger-remote-sampler) | Sampler which obtains sampling configuration from remote Jaeger server | `opentelemetry-sdk-extension-jaeger-remote-sampler` | 1.37.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-extension-jaeger-remote-sampler.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-extension-jaeger-remote-sampler) | +| [SDK Incubator](./sdk-extensions/incubator) | SDK incubator, including YAML based view configuration, LeakDetectingSpanProcessor | `opentelemetry-sdk-extension-incubator` | 1.37.0-alpha | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-extension-incubator.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-extension-incubator) | ### Shims | Component | Description | Artifact ID | Version | Javadoc | |----------------------------------------|--------------------------------------------------------------|----------------------------------|-------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| [OpenCensus Shim](./opencensus-shim) | Bridge opencensus metrics into the OpenTelemetry metrics SDK | `opentelemetry-opencensus-shim` | 1.36.0-alpha | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-opencensus-shim.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-opencensus-shim) | -| [OpenTracing Shim](./opentracing-shim) | Bridge opentracing spans into the OpenTelemetry trace API | `opentelemetry-opentracing-shim` | 1.36.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-opentracing-shim.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-opentracing-shim) | +| [OpenCensus Shim](./opencensus-shim) | Bridge opencensus metrics into the OpenTelemetry metrics SDK | `opentelemetry-opencensus-shim` | 1.37.0-alpha | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-opencensus-shim.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-opencensus-shim) | +| [OpenTracing Shim](./opentracing-shim) | Bridge opentracing spans into the OpenTelemetry trace API | `opentelemetry-opentracing-shim` | 1.37.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-opentracing-shim.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-opentracing-shim) | ## Contributing diff --git a/docs/apidiffs/1.37.0_vs_1.36.0/opentelemetry-api.txt b/docs/apidiffs/1.37.0_vs_1.36.0/opentelemetry-api.txt new file mode 100644 index 00000000000..815a9fed06c --- /dev/null +++ b/docs/apidiffs/1.37.0_vs_1.36.0/opentelemetry-api.txt @@ -0,0 +1,5 @@ +Comparing source compatibility of against +*** MODIFIED INTERFACE: PUBLIC ABSTRACT io.opentelemetry.api.trace.Span (not serializable) + === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 + +++ NEW METHOD: PUBLIC(+) io.opentelemetry.api.trace.Span addLink(io.opentelemetry.api.trace.SpanContext) + +++ NEW METHOD: PUBLIC(+) io.opentelemetry.api.trace.Span addLink(io.opentelemetry.api.trace.SpanContext, io.opentelemetry.api.common.Attributes) diff --git a/docs/apidiffs/1.37.0_vs_1.36.0/opentelemetry-context.txt b/docs/apidiffs/1.37.0_vs_1.36.0/opentelemetry-context.txt new file mode 100644 index 00000000000..df26146497b --- /dev/null +++ b/docs/apidiffs/1.37.0_vs_1.36.0/opentelemetry-context.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of against +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.37.0_vs_1.36.0/opentelemetry-exporter-common.txt b/docs/apidiffs/1.37.0_vs_1.36.0/opentelemetry-exporter-common.txt new file mode 100644 index 00000000000..df26146497b --- /dev/null +++ b/docs/apidiffs/1.37.0_vs_1.36.0/opentelemetry-exporter-common.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of against +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.37.0_vs_1.36.0/opentelemetry-exporter-logging-otlp.txt b/docs/apidiffs/1.37.0_vs_1.36.0/opentelemetry-exporter-logging-otlp.txt new file mode 100644 index 00000000000..df26146497b --- /dev/null +++ b/docs/apidiffs/1.37.0_vs_1.36.0/opentelemetry-exporter-logging-otlp.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of against +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.37.0_vs_1.36.0/opentelemetry-exporter-logging.txt b/docs/apidiffs/1.37.0_vs_1.36.0/opentelemetry-exporter-logging.txt new file mode 100644 index 00000000000..df26146497b --- /dev/null +++ b/docs/apidiffs/1.37.0_vs_1.36.0/opentelemetry-exporter-logging.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of against +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.37.0_vs_1.36.0/opentelemetry-exporter-otlp-common.txt b/docs/apidiffs/1.37.0_vs_1.36.0/opentelemetry-exporter-otlp-common.txt new file mode 100644 index 00000000000..df26146497b --- /dev/null +++ b/docs/apidiffs/1.37.0_vs_1.36.0/opentelemetry-exporter-otlp-common.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of against +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.37.0_vs_1.36.0/opentelemetry-exporter-otlp.txt b/docs/apidiffs/1.37.0_vs_1.36.0/opentelemetry-exporter-otlp.txt new file mode 100644 index 00000000000..d8fcd994b8d --- /dev/null +++ b/docs/apidiffs/1.37.0_vs_1.36.0/opentelemetry-exporter-otlp.txt @@ -0,0 +1,7 @@ +Comparing source compatibility of against +*** MODIFIED CLASS: PUBLIC FINAL io.opentelemetry.exporter.otlp.http.metrics.OtlpHttpMetricExporter (not serializable) + === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 + +++ NEW METHOD: PUBLIC(+) io.opentelemetry.sdk.common.export.MemoryMode getMemoryMode() +*** MODIFIED CLASS: PUBLIC FINAL io.opentelemetry.exporter.otlp.metrics.OtlpGrpcMetricExporter (not serializable) + === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 + +++ NEW METHOD: PUBLIC(+) io.opentelemetry.sdk.common.export.MemoryMode getMemoryMode() diff --git a/docs/apidiffs/1.37.0_vs_1.36.0/opentelemetry-exporter-sender-grpc-managed-channel.txt b/docs/apidiffs/1.37.0_vs_1.36.0/opentelemetry-exporter-sender-grpc-managed-channel.txt new file mode 100644 index 00000000000..df26146497b --- /dev/null +++ b/docs/apidiffs/1.37.0_vs_1.36.0/opentelemetry-exporter-sender-grpc-managed-channel.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of against +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.37.0_vs_1.36.0/opentelemetry-exporter-sender-okhttp.txt b/docs/apidiffs/1.37.0_vs_1.36.0/opentelemetry-exporter-sender-okhttp.txt new file mode 100644 index 00000000000..df26146497b --- /dev/null +++ b/docs/apidiffs/1.37.0_vs_1.36.0/opentelemetry-exporter-sender-okhttp.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of against +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.37.0_vs_1.36.0/opentelemetry-exporter-zipkin.txt b/docs/apidiffs/1.37.0_vs_1.36.0/opentelemetry-exporter-zipkin.txt new file mode 100644 index 00000000000..df26146497b --- /dev/null +++ b/docs/apidiffs/1.37.0_vs_1.36.0/opentelemetry-exporter-zipkin.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of against +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.37.0_vs_1.36.0/opentelemetry-extension-kotlin.txt b/docs/apidiffs/1.37.0_vs_1.36.0/opentelemetry-extension-kotlin.txt new file mode 100644 index 00000000000..df26146497b --- /dev/null +++ b/docs/apidiffs/1.37.0_vs_1.36.0/opentelemetry-extension-kotlin.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of against +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.37.0_vs_1.36.0/opentelemetry-extension-trace-propagators.txt b/docs/apidiffs/1.37.0_vs_1.36.0/opentelemetry-extension-trace-propagators.txt new file mode 100644 index 00000000000..df26146497b --- /dev/null +++ b/docs/apidiffs/1.37.0_vs_1.36.0/opentelemetry-extension-trace-propagators.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of against +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.37.0_vs_1.36.0/opentelemetry-opentracing-shim.txt b/docs/apidiffs/1.37.0_vs_1.36.0/opentelemetry-opentracing-shim.txt new file mode 100644 index 00000000000..df26146497b --- /dev/null +++ b/docs/apidiffs/1.37.0_vs_1.36.0/opentelemetry-opentracing-shim.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of against +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.37.0_vs_1.36.0/opentelemetry-sdk-common.txt b/docs/apidiffs/1.37.0_vs_1.36.0/opentelemetry-sdk-common.txt new file mode 100644 index 00000000000..df26146497b --- /dev/null +++ b/docs/apidiffs/1.37.0_vs_1.36.0/opentelemetry-sdk-common.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of against +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.37.0_vs_1.36.0/opentelemetry-sdk-extension-autoconfigure-spi.txt b/docs/apidiffs/1.37.0_vs_1.36.0/opentelemetry-sdk-extension-autoconfigure-spi.txt new file mode 100644 index 00000000000..df26146497b --- /dev/null +++ b/docs/apidiffs/1.37.0_vs_1.36.0/opentelemetry-sdk-extension-autoconfigure-spi.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of against +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.37.0_vs_1.36.0/opentelemetry-sdk-extension-autoconfigure.txt b/docs/apidiffs/1.37.0_vs_1.36.0/opentelemetry-sdk-extension-autoconfigure.txt new file mode 100644 index 00000000000..df26146497b --- /dev/null +++ b/docs/apidiffs/1.37.0_vs_1.36.0/opentelemetry-sdk-extension-autoconfigure.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of against +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.37.0_vs_1.36.0/opentelemetry-sdk-extension-jaeger-remote-sampler.txt b/docs/apidiffs/1.37.0_vs_1.36.0/opentelemetry-sdk-extension-jaeger-remote-sampler.txt new file mode 100644 index 00000000000..df26146497b --- /dev/null +++ b/docs/apidiffs/1.37.0_vs_1.36.0/opentelemetry-sdk-extension-jaeger-remote-sampler.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of against +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.37.0_vs_1.36.0/opentelemetry-sdk-logs.txt b/docs/apidiffs/1.37.0_vs_1.36.0/opentelemetry-sdk-logs.txt new file mode 100644 index 00000000000..2039c1c6e68 --- /dev/null +++ b/docs/apidiffs/1.37.0_vs_1.36.0/opentelemetry-sdk-logs.txt @@ -0,0 +1,7 @@ +Comparing source compatibility of against +*** MODIFIED CLASS: PUBLIC FINAL io.opentelemetry.sdk.logs.export.BatchLogRecordProcessor (not serializable) + === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 + +++ NEW METHOD: PUBLIC(+) io.opentelemetry.sdk.logs.export.LogRecordExporter getLogRecordExporter() +*** MODIFIED CLASS: PUBLIC FINAL io.opentelemetry.sdk.logs.export.SimpleLogRecordProcessor (not serializable) + === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 + +++ NEW METHOD: PUBLIC(+) io.opentelemetry.sdk.logs.export.LogRecordExporter getLogRecordExporter() diff --git a/docs/apidiffs/1.37.0_vs_1.36.0/opentelemetry-sdk-metrics.txt b/docs/apidiffs/1.37.0_vs_1.36.0/opentelemetry-sdk-metrics.txt new file mode 100644 index 00000000000..df26146497b --- /dev/null +++ b/docs/apidiffs/1.37.0_vs_1.36.0/opentelemetry-sdk-metrics.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of against +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.37.0_vs_1.36.0/opentelemetry-sdk-testing.txt b/docs/apidiffs/1.37.0_vs_1.36.0/opentelemetry-sdk-testing.txt new file mode 100644 index 00000000000..df26146497b --- /dev/null +++ b/docs/apidiffs/1.37.0_vs_1.36.0/opentelemetry-sdk-testing.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of against +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.37.0_vs_1.36.0/opentelemetry-sdk-trace.txt b/docs/apidiffs/1.37.0_vs_1.36.0/opentelemetry-sdk-trace.txt new file mode 100644 index 00000000000..52678bd9ba6 --- /dev/null +++ b/docs/apidiffs/1.37.0_vs_1.36.0/opentelemetry-sdk-trace.txt @@ -0,0 +1,7 @@ +Comparing source compatibility of against +*** MODIFIED CLASS: PUBLIC FINAL io.opentelemetry.sdk.trace.export.BatchSpanProcessor (not serializable) + === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 + +++ NEW METHOD: PUBLIC(+) io.opentelemetry.sdk.trace.export.SpanExporter getSpanExporter() +*** MODIFIED CLASS: PUBLIC FINAL io.opentelemetry.sdk.trace.export.SimpleSpanProcessor (not serializable) + === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 + +++ NEW METHOD: PUBLIC(+) io.opentelemetry.sdk.trace.export.SpanExporter getSpanExporter() diff --git a/docs/apidiffs/1.37.0_vs_1.36.0/opentelemetry-sdk.txt b/docs/apidiffs/1.37.0_vs_1.36.0/opentelemetry-sdk.txt new file mode 100644 index 00000000000..df26146497b --- /dev/null +++ b/docs/apidiffs/1.37.0_vs_1.36.0/opentelemetry-sdk.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of against +No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-api.txt b/docs/apidiffs/current_vs_latest/opentelemetry-api.txt index 815a9fed06c..df26146497b 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-api.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-api.txt @@ -1,5 +1,2 @@ Comparing source compatibility of against -*** MODIFIED INTERFACE: PUBLIC ABSTRACT io.opentelemetry.api.trace.Span (not serializable) - === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 - +++ NEW METHOD: PUBLIC(+) io.opentelemetry.api.trace.Span addLink(io.opentelemetry.api.trace.SpanContext) - +++ NEW METHOD: PUBLIC(+) io.opentelemetry.api.trace.Span addLink(io.opentelemetry.api.trace.SpanContext, io.opentelemetry.api.common.Attributes) +No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-otlp.txt b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-otlp.txt index d8fcd994b8d..df26146497b 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-otlp.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-otlp.txt @@ -1,7 +1,2 @@ Comparing source compatibility of against -*** MODIFIED CLASS: PUBLIC FINAL io.opentelemetry.exporter.otlp.http.metrics.OtlpHttpMetricExporter (not serializable) - === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 - +++ NEW METHOD: PUBLIC(+) io.opentelemetry.sdk.common.export.MemoryMode getMemoryMode() -*** MODIFIED CLASS: PUBLIC FINAL io.opentelemetry.exporter.otlp.metrics.OtlpGrpcMetricExporter (not serializable) - === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 - +++ NEW METHOD: PUBLIC(+) io.opentelemetry.sdk.common.export.MemoryMode getMemoryMode() +No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-logs.txt b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-logs.txt index 2039c1c6e68..df26146497b 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-logs.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-logs.txt @@ -1,7 +1,2 @@ Comparing source compatibility of against -*** MODIFIED CLASS: PUBLIC FINAL io.opentelemetry.sdk.logs.export.BatchLogRecordProcessor (not serializable) - === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 - +++ NEW METHOD: PUBLIC(+) io.opentelemetry.sdk.logs.export.LogRecordExporter getLogRecordExporter() -*** MODIFIED CLASS: PUBLIC FINAL io.opentelemetry.sdk.logs.export.SimpleLogRecordProcessor (not serializable) - === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 - +++ NEW METHOD: PUBLIC(+) io.opentelemetry.sdk.logs.export.LogRecordExporter getLogRecordExporter() +No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-trace.txt b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-trace.txt index 52678bd9ba6..df26146497b 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-trace.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-trace.txt @@ -1,7 +1,2 @@ Comparing source compatibility of against -*** MODIFIED CLASS: PUBLIC FINAL io.opentelemetry.sdk.trace.export.BatchSpanProcessor (not serializable) - === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 - +++ NEW METHOD: PUBLIC(+) io.opentelemetry.sdk.trace.export.SpanExporter getSpanExporter() -*** MODIFIED CLASS: PUBLIC FINAL io.opentelemetry.sdk.trace.export.SimpleSpanProcessor (not serializable) - === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 - +++ NEW METHOD: PUBLIC(+) io.opentelemetry.sdk.trace.export.SpanExporter getSpanExporter() +No changes. \ No newline at end of file From 92d659a17f82377b2a20b761a44b41de63e8ea10 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 9 Apr 2024 09:51:27 -0500 Subject: [PATCH 341/901] Update plugin io.github.gradle-nexus.publish-plugin to v2 (#6359) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- settings.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/settings.gradle.kts b/settings.gradle.kts index e6fbf76cc34..57236ebc854 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -4,7 +4,7 @@ pluginManagement { id("com.gradle.enterprise") version "3.17" id("de.undercouch.download") version "5.6.0" id("org.jsonschema2pojo") version "1.2.1" - id("io.github.gradle-nexus.publish-plugin") version "1.3.0" + id("io.github.gradle-nexus.publish-plugin") version "2.0.0" id("org.graalvm.buildtools.native") version "0.10.1" } } From 66cf1b6b28f9b4f4d1ab62fba5a74b3f221332d3 Mon Sep 17 00:00:00 2001 From: jack-berg <34418638+jack-berg@users.noreply.github.com> Date: Tue, 9 Apr 2024 15:14:32 -0500 Subject: [PATCH 342/901] Run build on java 21 (#6370) --- .github/workflows/build.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 694d63a578d..e4fe1b2afba 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -26,11 +26,11 @@ jobs: - 8 - 11 - 17 - - 20 + - 21 # Collect coverage on latest LTS include: - os: ubuntu-20.04 - test-java-version: 17 + test-java-version: 21 coverage: true jmh-based-tests: true steps: From 7acc4e28f55ec94d887ab7b19c4575e8e68139ef Mon Sep 17 00:00:00 2001 From: jack-berg <34418638+jack-berg@users.noreply.github.com> Date: Wed, 10 Apr 2024 17:18:23 -0500 Subject: [PATCH 343/901] Mark opentelemetry-exporter-sender-jdk stable (#6357) --- README.md | 24 +++++++++---------- .../opentelemetry-exporter-sender-jdk.txt | 2 ++ exporters/sender/jdk/gradle.properties | 1 - 3 files changed, 14 insertions(+), 13 deletions(-) create mode 100644 docs/apidiffs/current_vs_latest/opentelemetry-exporter-sender-jdk.txt delete mode 100644 exporters/sender/jdk/gradle.properties diff --git a/README.md b/README.md index dbf41811f26..e81854004ac 100644 --- a/README.md +++ b/README.md @@ -261,18 +261,18 @@ dependency as follows, replacing `{{artifact-id}}` with the value from the "Arti ### SDK Exporters -| Component | Description | Artifact ID | Version | Javadoc | -|-----------------------------------------------------------------------|------------------------------------------------------------------------------|------------------------------------------------------|-------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| [OTLP Exporters](./exporters/otlp/all) | OTLP gRPC & HTTP exporters, including traces, metrics, and logs | `opentelemetry-exporter-otlp` | 1.37.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-otlp.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-otlp) | -| [OTLP Logging Exporters](./exporters/logging-otlp) | Logging exporters in OTLP JSON encoding, including traces, metrics, and logs | `opentelemetry-exporter-logging-otlp` | 1.37.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-logging-otlp.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-logging-otlp) | -| [OTLP Common](./exporters/otlp/common) | Shared OTLP components (internal) | `opentelemetry-exporter-otlp-common` | 1.37.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-otlp-common.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-otlp-common) | -| [Logging Exporter](./exporters/logging) | Logging exporters, including metrics, traces, and logs | `opentelemetry-exporter-logging` | 1.37.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-logging.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-logging) | -| [Zipkin Exporter](./exporters/zipkin) | Zipkin trace exporter | `opentelemetry-exporter-zipkin` | 1.37.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-zipkin.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-zipkin) | -| [Prometheus Exporter](./exporters/prometheus) | Prometheus metric exporter | `opentelemetry-exporter-prometheus` | 1.37.0-alpha | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-prometheus.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-prometheus) | -| [Exporter Common](./exporters/common) | Shared exporter components (internal) | `opentelemetry-exporter-common` | 1.37.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-common.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-common) | -| [OkHttp Sender](./exporters/sender/okhttp) | OkHttp implementation of HttpSender (internal) | `opentelemetry-exporter-sender-okhttp` | 1.37.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-sender-okhttp.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-sender-okhttp) | -| [JDK Sender](./exporters/sender/okhttp) | Java 11+ native HttpClient implementation of HttpSender (internal) | `opentelemetry-exporter-sender-jdk` | 1.37.0-alpha | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-sender-jdk.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-sender-jdk) | | -| [gRPC ManagedChannel Sender](./exporters/sender/grpc-managed-channel) | gRPC ManagedChannel implementation of GrpcSender (internal) | `opentelemetry-exporter-sender-grpc-managed-channel` | 1.37.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-sender-grpc-managed-channel.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-sender-grpc-managed-channel) | | +| Component | Description | Artifact ID | Version | Javadoc | +|-----------------------------------------------------------------------|------------------------------------------------------------------------------|-------------------------------------------------------------------------|-------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| [OTLP Exporters](./exporters/otlp/all) | OTLP gRPC & HTTP exporters, including traces, metrics, and logs | `opentelemetry-exporter-otlp` | 1.37.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-otlp.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-otlp) | +| [OTLP Logging Exporters](./exporters/logging-otlp) | Logging exporters in OTLP JSON encoding, including traces, metrics, and logs | `opentelemetry-exporter-logging-otlp` | 1.37.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-logging-otlp.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-logging-otlp) | +| [OTLP Common](./exporters/otlp/common) | Shared OTLP components (internal) | `opentelemetry-exporter-otlp-common` | 1.37.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-otlp-common.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-otlp-common) | +| [Logging Exporter](./exporters/logging) | Logging exporters, including metrics, traces, and logs | `opentelemetry-exporter-logging` | 1.37.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-logging.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-logging) | +| [Zipkin Exporter](./exporters/zipkin) | Zipkin trace exporter | `opentelemetry-exporter-zipkin` | 1.37.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-zipkin.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-zipkin) | +| [Prometheus Exporter](./exporters/prometheus) | Prometheus metric exporter | `opentelemetry-exporter-prometheus` | 1.37.0-alpha | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-prometheus.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-prometheus) | +| [Exporter Common](./exporters/common) | Shared exporter components (internal) | `opentelemetry-exporter-common` | 1.37.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-common.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-common) | +| [OkHttp Sender](./exporters/sender/okhttp) | OkHttp implementation of HttpSender (internal) | `opentelemetry-exporter-sender-okhttp` | 1.37.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-sender-okhttp.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-sender-okhttp) | +| [JDK Sender](./exporters/sender/okhttp) | Java 11+ native HttpClient implementation of HttpSender (internal) | `opentelemetry-exporter-sender-jdk` TODO: remove `-alpha` after release | 1.37.0-alpha | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-sender-jdk.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-sender-jdk) | | +| [gRPC ManagedChannel Sender](./exporters/sender/grpc-managed-channel) | gRPC ManagedChannel implementation of GrpcSender (internal) | `opentelemetry-exporter-sender-grpc-managed-channel` | 1.37.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-sender-grpc-managed-channel.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-sender-grpc-managed-channel) | | ### SDK Extensions diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-sender-jdk.txt b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-sender-jdk.txt new file mode 100644 index 00000000000..df26146497b --- /dev/null +++ b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-sender-jdk.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of against +No changes. \ No newline at end of file diff --git a/exporters/sender/jdk/gradle.properties b/exporters/sender/jdk/gradle.properties deleted file mode 100644 index 4476ae57e31..00000000000 --- a/exporters/sender/jdk/gradle.properties +++ /dev/null @@ -1 +0,0 @@ -otel.release=alpha From 1c64445cf6f4cfbc8d07cc17463673aa718b7804 Mon Sep 17 00:00:00 2001 From: jack-berg <34418638+jack-berg@users.noreply.github.com> Date: Thu, 11 Apr 2024 09:31:46 -0500 Subject: [PATCH 344/901] Move away from deprecated gradle enterprise APIs (#6363) --- .github/repository-settings.md | 2 +- settings.gradle.kts | 29 ++++++++++++++--------------- 2 files changed, 15 insertions(+), 16 deletions(-) diff --git a/.github/repository-settings.md b/.github/repository-settings.md index e066f5fc18b..7e777d110b6 100644 --- a/.github/repository-settings.md +++ b/.github/repository-settings.md @@ -66,7 +66,7 @@ Same settings as above for `main`, except: * `GPG_PASSWORD` - stored in OpenTelemetry-Java 1Password * `GPG_PRIVATE_KEY` - stored in OpenTelemetry-Java 1Password -* `GRADLE_ENTERPRISE_ACCESS_KEY` - owned by [@jack-berg](https://github.com/jack-berg) +* `DEVELOCITY_ACCESS_KEY` - owned by [@jack-berg](https://github.com/jack-berg) * Generated at https://ge.opentelemetry.io > My settings > Access keys * format of env var is `ge.opentelemetry.io=`, see [docs](https://docs.gradle.com/enterprise/gradle-plugin/#via_environment_variable) diff --git a/settings.gradle.kts b/settings.gradle.kts index 57236ebc854..e8368cb4e4d 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -1,7 +1,7 @@ pluginManagement { plugins { id("com.github.johnrengelman.shadow") version "8.1.1" - id("com.gradle.enterprise") version "3.17" + id("com.gradle.develocity") version "3.17" id("de.undercouch.download") version "5.6.0" id("org.jsonschema2pojo") version "1.2.1" id("io.github.gradle-nexus.publish-plugin") version "2.0.0" @@ -10,7 +10,7 @@ pluginManagement { } plugins { - id("com.gradle.enterprise") + id("com.gradle.develocity") } dependencyResolutionManagement { @@ -71,30 +71,29 @@ val geAccessKey = System.getenv("GRADLE_ENTERPRISE_ACCESS_KEY") ?: "" val useScansGradleCom = isCI && geAccessKey.isEmpty() if (useScansGradleCom) { - gradleEnterprise { + develocity { buildScan { - termsOfServiceUrl = "https://gradle.com/terms-of-service" - termsOfServiceAgree = "yes" - isUploadInBackground = !isCI - publishAlways() + termsOfUseUrl.set("https://gradle.com/terms-of-service") + termsOfUseAgree.set("yes") + uploadInBackground.set(!isCI) + publishing.onlyIf { true } capture { - isTaskInputFiles = true + fileFingerprints.set(true) } } } } else { - gradleEnterprise { + develocity { server = gradleEnterpriseServer buildScan { - isUploadInBackground = !isCI - - this as com.gradle.enterprise.gradleplugin.internal.extension.BuildScanExtensionWithHiddenFeatures - publishIfAuthenticated() - publishAlways() + uploadInBackground.set(!isCI) + publishing.onlyIf { + it.isAuthenticated + } capture { - isTaskInputFiles = true + fileFingerprints.set(true) } gradle.startParameter.projectProperties["testJavaVersion"]?.let { tag(it) } From 6c7770bb25a6de623e6e8a27784e840cb65607e6 Mon Sep 17 00:00:00 2001 From: jason plumb <75337021+breedx-splk@users.noreply.github.com> Date: Thu, 11 Apr 2024 07:32:13 -0700 Subject: [PATCH 345/901] Add forward slash to InstrumentName log message (#6343) --- .../src/main/java/io/opentelemetry/api/metrics/Meter.java | 8 ++++---- .../main/java/io/opentelemetry/sdk/metrics/SdkMeter.java | 2 +- .../java/io/opentelemetry/sdk/metrics/SdkMeterTest.java | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/api/all/src/main/java/io/opentelemetry/api/metrics/Meter.java b/api/all/src/main/java/io/opentelemetry/api/metrics/Meter.java index a640334d4d5..d8566457d4c 100644 --- a/api/all/src/main/java/io/opentelemetry/api/metrics/Meter.java +++ b/api/all/src/main/java/io/opentelemetry/api/metrics/Meter.java @@ -65,7 +65,7 @@ public interface Meter { * callbacks). * * @param name the name of the Counter. Instrument names must consist of 255 or fewer characters - * including alphanumeric, _, ., -, and start with a letter. + * including alphanumeric, _, ., -, /, and start with a letter. * @return a builder for configuring a Counter instrument. Defaults to recording long values, but * may be changed. * @see Date: Thu, 11 Apr 2024 11:54:41 -0500 Subject: [PATCH 346/901] Update dependency com.tngtech.archunit:archunit-junit5 to v1.3.0 (#6380) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- dependencyManagement/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index 8437028c12b..7ccee88cf3e 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -59,7 +59,7 @@ val DEPENDENCIES = listOf( "com.google.code.findbugs:jsr305:3.0.2", "com.google.guava:guava-beta-checker:1.0", "com.sun.net.httpserver:http:20070405", - "com.tngtech.archunit:archunit-junit5:1.2.1", + "com.tngtech.archunit:archunit-junit5:1.3.0", "com.uber.nullaway:nullaway:0.10.25", "edu.berkeley.cs.jqf:jqf-fuzz:1.7", // jqf-fuzz version 1.8+ requires Java 11+ "eu.rekawek.toxiproxy:toxiproxy-java:2.1.7", From 63b91c6bd95e9166fa8978f974ab2470d7fa07e0 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 11 Apr 2024 11:54:59 -0500 Subject: [PATCH 347/901] Update dependency io.zipkin.brave:brave-bom to v6.0.3 (#6376) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- dependencyManagement/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index 7ccee88cf3e..20b725f6b31 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -16,7 +16,7 @@ val DEPENDENCY_BOMS = listOf( "com.squareup.okio:okio-bom:3.9.0", // applies to transitive dependencies of okhttp "io.grpc:grpc-bom:1.63.0", "io.netty:netty-bom:4.1.108.Final", - "io.zipkin.brave:brave-bom:6.0.2", + "io.zipkin.brave:brave-bom:6.0.3", "io.zipkin.reporter2:zipkin-reporter-bom:3.3.0", "org.assertj:assertj-bom:3.25.3", "org.junit:junit-bom:5.10.2", From 8242a4eb3e07bc7ee7246e0bcb01aaac336566a3 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 11 Apr 2024 11:55:48 -0500 Subject: [PATCH 348/901] Update plugin com.gradle.develocity to v3.17.1 (#6379) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- settings.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/settings.gradle.kts b/settings.gradle.kts index e8368cb4e4d..e0f917e278d 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -1,7 +1,7 @@ pluginManagement { plugins { id("com.github.johnrengelman.shadow") version "8.1.1" - id("com.gradle.develocity") version "3.17" + id("com.gradle.develocity") version "3.17.1" id("de.undercouch.download") version "5.6.0" id("org.jsonschema2pojo") version "1.2.1" id("io.github.gradle-nexus.publish-plugin") version "2.0.0" From 9e12dd60c457ddbe0f5a178fc9790f7a22c1e926 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 11 Apr 2024 13:01:53 -0500 Subject: [PATCH 349/901] Update dependency io.opentelemetry.semconv:opentelemetry-semconv-incubating to v1.25.0-alpha (#6366) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Co-authored-by: Jack Berg --- .../api/incubator/trace/ExtendedTracerTest.java | 10 ++++------ dependencyManagement/build.gradle.kts | 2 +- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/api/incubator/src/test/java/io/opentelemetry/api/incubator/trace/ExtendedTracerTest.java b/api/incubator/src/test/java/io/opentelemetry/api/incubator/trace/ExtendedTracerTest.java index 93124fe25cc..20ad50ca0be 100644 --- a/api/incubator/src/test/java/io/opentelemetry/api/incubator/trace/ExtendedTracerTest.java +++ b/api/incubator/src/test/java/io/opentelemetry/api/incubator/trace/ExtendedTracerTest.java @@ -24,7 +24,7 @@ import io.opentelemetry.sdk.testing.junit5.OpenTelemetryExtension; import io.opentelemetry.sdk.trace.data.StatusData; import io.opentelemetry.semconv.ClientAttributes; -import io.opentelemetry.semconv.incubating.ExceptionIncubatingAttributes; +import io.opentelemetry.semconv.ExceptionAttributes; import java.time.Instant; import java.util.Collections; import java.util.Map; @@ -85,16 +85,14 @@ void wrapInSpan() { .hasName("exception") .hasAttributesSatisfyingExactly( equalTo( - ExceptionIncubatingAttributes.EXCEPTION_TYPE, + ExceptionAttributes.EXCEPTION_TYPE, "java.lang.IllegalStateException"), satisfies( - ExceptionIncubatingAttributes.EXCEPTION_STACKTRACE, + ExceptionAttributes.EXCEPTION_STACKTRACE, string -> string.contains( "java.lang.IllegalStateException: ex")), - equalTo( - ExceptionIncubatingAttributes.EXCEPTION_MESSAGE, - "ex")))), + equalTo(ExceptionAttributes.EXCEPTION_MESSAGE, "ex")))), trace -> trace.hasSpansSatisfyingExactly(a -> a.hasName("another test"))); } diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index 20b725f6b31..492fd554699 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -66,7 +66,7 @@ val DEPENDENCIES = listOf( "io.github.netmikey.logunit:logunit-jul:2.0.0", "io.jaegertracing:jaeger-client:1.8.1", "io.opentelemetry.contrib:opentelemetry-aws-xray-propagator:1.29.0-alpha", - "io.opentelemetry.semconv:opentelemetry-semconv-incubating:1.24.0-alpha", + "io.opentelemetry.semconv:opentelemetry-semconv-incubating:1.25.0-alpha", "io.opentelemetry.proto:opentelemetry-proto:1.1.0-alpha", "io.opentracing:opentracing-api:0.33.0", "io.opentracing:opentracing-noop:0.33.0", From a85e888d82de5a6bbe0280918ef71e573b3b88a1 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 11 Apr 2024 14:53:10 -0500 Subject: [PATCH 350/901] Update dependency io.opentelemetry.proto:opentelemetry-proto to v1.2.0-alpha (#6365) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- dependencyManagement/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index 492fd554699..65f031c99da 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -67,7 +67,7 @@ val DEPENDENCIES = listOf( "io.jaegertracing:jaeger-client:1.8.1", "io.opentelemetry.contrib:opentelemetry-aws-xray-propagator:1.29.0-alpha", "io.opentelemetry.semconv:opentelemetry-semconv-incubating:1.25.0-alpha", - "io.opentelemetry.proto:opentelemetry-proto:1.1.0-alpha", + "io.opentelemetry.proto:opentelemetry-proto:1.2.0-alpha", "io.opentracing:opentracing-api:0.33.0", "io.opentracing:opentracing-noop:0.33.0", "io.prometheus:prometheus-metrics-exporter-httpserver:1.2.1", From 876408e7a7d35b3e5140971c153ab58e38a965ea Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 13 Apr 2024 11:09:13 -0700 Subject: [PATCH 351/901] Update gradle/wrapper-validation-action action to v2.1.3 (#6373) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/gradle-wrapper-validation.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/gradle-wrapper-validation.yml b/.github/workflows/gradle-wrapper-validation.yml index 9d33b0441d6..e424e408d29 100644 --- a/.github/workflows/gradle-wrapper-validation.yml +++ b/.github/workflows/gradle-wrapper-validation.yml @@ -13,4 +13,4 @@ jobs: steps: - uses: actions/checkout@v4 - - uses: gradle/wrapper-validation-action@v2.1.2 + - uses: gradle/wrapper-validation-action@v2.1.3 From 6c6b678c76e82ec6e13409a1815702427d560ab7 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 13 Apr 2024 11:09:33 -0700 Subject: [PATCH 352/901] Update slf4j monorepo to v2.0.13 (#6385) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- dependencyManagement/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index 65f031c99da..7f08c8db7a1 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -29,7 +29,7 @@ val errorProneVersion = "2.26.1" val jmhVersion = "1.37" // Mockito 5.x.x requires Java 11 https://github.com/mockito/mockito/releases/tag/v5.0.0 val mockitoVersion = "4.11.0" -val slf4jVersion = "2.0.12" +val slf4jVersion = "2.0.13" val opencensusVersion = "0.31.1" val prometheusClientVersion = "0.16.0" From 8937a1009a59059fdbafcc58e4bcdd642b172200 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 13 Apr 2024 11:09:52 -0700 Subject: [PATCH 353/901] Update dependency com.linecorp.armeria:armeria-bom to v1.28.0 (#6384) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- dependencyManagement/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index 7f08c8db7a1..31f95aa4576 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -11,7 +11,7 @@ val DEPENDENCY_BOMS = listOf( "com.fasterxml.jackson:jackson-bom:2.17.0", "com.google.guava:guava-bom:33.1.0-jre", "com.google.protobuf:protobuf-bom:3.25.3", - "com.linecorp.armeria:armeria-bom:1.27.3", + "com.linecorp.armeria:armeria-bom:1.28.0", "com.squareup.okhttp3:okhttp-bom:4.12.0", "com.squareup.okio:okio-bom:3.9.0", // applies to transitive dependencies of okhttp "io.grpc:grpc-bom:1.63.0", From 7b4bb8fb0a663b5b24cfb8fbb3b05e7e580dd48e Mon Sep 17 00:00:00 2001 From: jack-berg <34418638+jack-berg@users.noreply.github.com> Date: Wed, 17 Apr 2024 13:24:52 -0500 Subject: [PATCH 354/901] Add ReadableSpan#getAttributes (#6382) --- .../opentelemetry-sdk-trace.txt | 4 ++- .../opentelemetry/sdk/trace/ReadableSpan.java | 17 ++++++++++++ .../io/opentelemetry/sdk/trace/SdkSpan.java | 7 +++++ .../opentelemetry/sdk/trace/SdkSpanTest.java | 26 +++++++++++++++++++ 4 files changed, 53 insertions(+), 1 deletion(-) diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-trace.txt b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-trace.txt index df26146497b..722ee3a950f 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-trace.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-trace.txt @@ -1,2 +1,4 @@ Comparing source compatibility of against -No changes. \ No newline at end of file +*** MODIFIED INTERFACE: PUBLIC ABSTRACT io.opentelemetry.sdk.trace.ReadableSpan (not serializable) + === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 + +++ NEW METHOD: PUBLIC(+) io.opentelemetry.api.common.Attributes getAttributes() diff --git a/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/ReadableSpan.java b/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/ReadableSpan.java index f367aa67b28..f59b87599c1 100644 --- a/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/ReadableSpan.java +++ b/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/ReadableSpan.java @@ -6,6 +6,7 @@ package io.opentelemetry.sdk.trace; import io.opentelemetry.api.common.AttributeKey; +import io.opentelemetry.api.common.Attributes; import io.opentelemetry.api.trace.Span; import io.opentelemetry.api.trace.SpanContext; import io.opentelemetry.api.trace.SpanKind; @@ -111,4 +112,20 @@ default InstrumentationScopeInfo getInstrumentationScopeInfo() { */ @Nullable T getAttribute(AttributeKey key); + + /** + * Returns the Span attributes. + * + *

      Attributes can be changed during the lifetime of the Span by using {@link + * Span#setAttribute}} so this value cannot be cached. + * + *

      Note: the implementation of this method performs locking and returns an immutable copy to + * ensure thread-safe behavior. If you only need a single attribute it is better to call {@link + * #getAttribute(AttributeKey)}. + * + * @return the Span attributes, or {@link Attributes#empty()} if the span has no attributes. + */ + default Attributes getAttributes() { + return Attributes.empty(); + } } diff --git a/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/SdkSpan.java b/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/SdkSpan.java index dfa8e9689a0..e70359aa46d 100644 --- a/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/SdkSpan.java +++ b/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/SdkSpan.java @@ -232,6 +232,13 @@ public T getAttribute(AttributeKey key) { } } + @Override + public Attributes getAttributes() { + synchronized (lock) { + return attributes == null ? Attributes.empty() : attributes.immutableCopy(); + } + } + @Override public boolean hasEnded() { synchronized (lock) { diff --git a/sdk/trace/src/test/java/io/opentelemetry/sdk/trace/SdkSpanTest.java b/sdk/trace/src/test/java/io/opentelemetry/sdk/trace/SdkSpanTest.java index 42302f54b82..13defbdca82 100644 --- a/sdk/trace/src/test/java/io/opentelemetry/sdk/trace/SdkSpanTest.java +++ b/sdk/trace/src/test/java/io/opentelemetry/sdk/trace/SdkSpanTest.java @@ -339,6 +339,32 @@ void getAttribute() { } } + @Test + void getAttributes() { + SdkSpan span = createTestSpanWithAttributes(attributes); + try { + assertThat(span.getAttributes()) + .isEqualTo( + Attributes.builder() + .put("MyBooleanAttributeKey", false) + .put("MyStringAttributeKey", "MyStringAttributeValue") + .put("MyLongAttributeKey", 123L) + .build()); + } finally { + span.end(); + } + } + + @Test + void getAttributes_Empty() { + SdkSpan span = createTestSpan(SpanKind.INTERNAL); + try { + assertThat(span.getAttributes()).isEqualTo(Attributes.empty()); + } finally { + span.end(); + } + } + @Test @SuppressWarnings("deprecation") // Testing deprecated code void getInstrumentationLibraryInfo() { From ecc8ffe09f41a8544b371d3ec0f2f86c4ea0b7b7 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 18 Apr 2024 09:31:34 -0500 Subject: [PATCH 355/901] Update dependency io.netty:netty-bom to v4.1.109.Final (#6391) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- dependencyManagement/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index 31f95aa4576..f3e3d07b7fb 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -15,7 +15,7 @@ val DEPENDENCY_BOMS = listOf( "com.squareup.okhttp3:okhttp-bom:4.12.0", "com.squareup.okio:okio-bom:3.9.0", // applies to transitive dependencies of okhttp "io.grpc:grpc-bom:1.63.0", - "io.netty:netty-bom:4.1.108.Final", + "io.netty:netty-bom:4.1.109.Final", "io.zipkin.brave:brave-bom:6.0.3", "io.zipkin.reporter2:zipkin-reporter-bom:3.3.0", "org.assertj:assertj-bom:3.25.3", From 3b1092b3d53fccbe00dad120d6c987eb75cec51a Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 18 Apr 2024 09:31:42 -0500 Subject: [PATCH 356/901] Update dependency com.linecorp.armeria:armeria-bom to v1.28.2 (#6390) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- dependencyManagement/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index f3e3d07b7fb..09c64bd68d9 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -11,7 +11,7 @@ val DEPENDENCY_BOMS = listOf( "com.fasterxml.jackson:jackson-bom:2.17.0", "com.google.guava:guava-bom:33.1.0-jre", "com.google.protobuf:protobuf-bom:3.25.3", - "com.linecorp.armeria:armeria-bom:1.28.0", + "com.linecorp.armeria:armeria-bom:1.28.2", "com.squareup.okhttp3:okhttp-bom:4.12.0", "com.squareup.okio:okio-bom:3.9.0", // applies to transitive dependencies of okhttp "io.grpc:grpc-bom:1.63.0", From ba9356192ad133ae2a20b447ddc61dc9de3022f1 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 18 Apr 2024 09:32:22 -0500 Subject: [PATCH 357/901] Update plugin com.gradle.develocity to v3.17.2 (#6393) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- settings.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/settings.gradle.kts b/settings.gradle.kts index e0f917e278d..4c0a2099101 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -1,7 +1,7 @@ pluginManagement { plugins { id("com.github.johnrengelman.shadow") version "8.1.1" - id("com.gradle.develocity") version "3.17.1" + id("com.gradle.develocity") version "3.17.2" id("de.undercouch.download") version "5.6.0" id("org.jsonschema2pojo") version "1.2.1" id("io.github.gradle-nexus.publish-plugin") version "2.0.0" From 9d955e6c0a20cfc1e9c12d82e74cfd3554bf5e8a Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 18 Apr 2024 09:32:33 -0500 Subject: [PATCH 358/901] Update dependency io.zipkin.reporter2:zipkin-reporter-bom to v3.4.0 (#6386) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- dependencyManagement/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index 09c64bd68d9..53ddd94dffc 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -17,7 +17,7 @@ val DEPENDENCY_BOMS = listOf( "io.grpc:grpc-bom:1.63.0", "io.netty:netty-bom:4.1.109.Final", "io.zipkin.brave:brave-bom:6.0.3", - "io.zipkin.reporter2:zipkin-reporter-bom:3.3.0", + "io.zipkin.reporter2:zipkin-reporter-bom:3.4.0", "org.assertj:assertj-bom:3.25.3", "org.junit:junit-bom:5.10.2", "org.testcontainers:testcontainers-bom:1.19.7", From 7128a8a5abc7817b154636aadc8f1447c9e658e8 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 18 Apr 2024 09:33:23 -0500 Subject: [PATCH 359/901] Update gradle/wrapper-validation-action action to v3 (#6387) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Co-authored-by: jason plumb <75337021+breedx-splk@users.noreply.github.com> --- .github/workflows/gradle-wrapper-validation.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/gradle-wrapper-validation.yml b/.github/workflows/gradle-wrapper-validation.yml index e424e408d29..b09272f06b8 100644 --- a/.github/workflows/gradle-wrapper-validation.yml +++ b/.github/workflows/gradle-wrapper-validation.yml @@ -13,4 +13,4 @@ jobs: steps: - uses: actions/checkout@v4 - - uses: gradle/wrapper-validation-action@v2.1.3 + - uses: gradle/actions/wrapper-validation@v3.3.0 From feef40813f89a0bb1751e890cd6cf266352615c6 Mon Sep 17 00:00:00 2001 From: jack-berg <34418638+jack-berg@users.noreply.github.com> Date: Thu, 18 Apr 2024 13:36:29 -0500 Subject: [PATCH 360/901] Rename otel.config.file to otel.experimental.config.file (#6396) --- sdk-extensions/autoconfigure/README.md | 6 +++--- .../AutoConfiguredOpenTelemetrySdkBuilder.java | 7 ++++++- .../sdk/autoconfigure/FileConfigurationTest.java | 2 +- .../sdk/autoconfigure/FileConfigurationTest.java | 10 +++++----- sdk-extensions/incubator/README.md | 2 +- 5 files changed, 16 insertions(+), 11 deletions(-) diff --git a/sdk-extensions/autoconfigure/README.md b/sdk-extensions/autoconfigure/README.md index a064dd79be2..2b0fc01960c 100644 --- a/sdk-extensions/autoconfigure/README.md +++ b/sdk-extensions/autoconfigure/README.md @@ -383,9 +383,9 @@ and [file configuration](https://github.com/open-telemetry/opentelemetry-specifi To use, include `io.opentelemetry:opentelemetry-sdk-extension:incubator:` and specify the path to the config file as described in the table below. -| System property | Environment variable | Purpose | -|------------------|----------------------|------------------------------------------------------------| -| otel.config.file | OTEL_CONFIG_FILE | The path to the SDK configuration file. Defaults to unset. | +| System property | Environment variable | Purpose | +|-------------------------------|-------------------------------|------------------------------------------------------------| +| otel.experimental.config.file | OTEL_EXPERIMENTAL_CONFIG_FILE | The path to the SDK configuration file. Defaults to unset. | NOTE: When a config file is specified, other environment variables described in this document along with SPI [customizations](#customizing-the-opentelemetry-sdk) are ignored. The contents of the file diff --git a/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/AutoConfiguredOpenTelemetrySdkBuilder.java b/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/AutoConfiguredOpenTelemetrySdkBuilder.java index 3e9a315a737..923f1535257 100644 --- a/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/AutoConfiguredOpenTelemetrySdkBuilder.java +++ b/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/AutoConfiguredOpenTelemetrySdkBuilder.java @@ -527,7 +527,12 @@ public AutoConfiguredOpenTelemetrySdk build() { @Nullable private static AutoConfiguredOpenTelemetrySdk maybeConfigureFromFile(ConfigProperties config) { - String configurationFile = config.getString("otel.config.file"); + String otelConfigFile = config.getString("otel.config.file"); + if (otelConfigFile != null && !otelConfigFile.isEmpty()) { + logger.warning( + "otel.config.file was set, but has been replaced with otel.experimental.config.file"); + } + String configurationFile = config.getString("otel.experimental.config.file"); if (configurationFile == null || configurationFile.isEmpty()) { return null; } diff --git a/sdk-extensions/autoconfigure/src/test/java/io/opentelemetry/sdk/autoconfigure/FileConfigurationTest.java b/sdk-extensions/autoconfigure/src/test/java/io/opentelemetry/sdk/autoconfigure/FileConfigurationTest.java index 418dd263625..332c70352ee 100644 --- a/sdk-extensions/autoconfigure/src/test/java/io/opentelemetry/sdk/autoconfigure/FileConfigurationTest.java +++ b/sdk-extensions/autoconfigure/src/test/java/io/opentelemetry/sdk/autoconfigure/FileConfigurationTest.java @@ -44,7 +44,7 @@ void configFile(@TempDir Path tempDir) throws IOException { Files.write(path, yaml.getBytes(StandardCharsets.UTF_8)); ConfigProperties config = DefaultConfigProperties.createFromMap( - Collections.singletonMap("otel.config.file", path.toString())); + Collections.singletonMap("otel.experimental.config.file", path.toString())); assertThatThrownBy(() -> AutoConfiguredOpenTelemetrySdk.builder().setConfig(config).build()) .isInstanceOf(ConfigurationException.class) diff --git a/sdk-extensions/autoconfigure/src/testFullConfig/java/io/opentelemetry/sdk/autoconfigure/FileConfigurationTest.java b/sdk-extensions/autoconfigure/src/testFullConfig/java/io/opentelemetry/sdk/autoconfigure/FileConfigurationTest.java index 7ce59ad321a..a40884d032b 100644 --- a/sdk-extensions/autoconfigure/src/testFullConfig/java/io/opentelemetry/sdk/autoconfigure/FileConfigurationTest.java +++ b/sdk-extensions/autoconfigure/src/testFullConfig/java/io/opentelemetry/sdk/autoconfigure/FileConfigurationTest.java @@ -78,7 +78,7 @@ void setup() throws IOException { void configFile_Valid() { ConfigProperties config = DefaultConfigProperties.createFromMap( - Collections.singletonMap("otel.config.file", configFilePath.toString())); + Collections.singletonMap("otel.experimental.config.file", configFilePath.toString())); OpenTelemetrySdk expectedSdk = OpenTelemetrySdk.builder() .setTracerProvider( @@ -116,7 +116,7 @@ void configFile_Valid() { void configFile_NoShutdownHook() { ConfigProperties config = DefaultConfigProperties.createFromMap( - Collections.singletonMap("otel.config.file", configFilePath.toString())); + Collections.singletonMap("otel.experimental.config.file", configFilePath.toString())); AutoConfiguredOpenTelemetrySdkBuilder builder = spy(AutoConfiguredOpenTelemetrySdk.builder()); AutoConfiguredOpenTelemetrySdk autoConfiguredOpenTelemetrySdk = @@ -131,7 +131,7 @@ void configFile_setResultAsGlobalFalse() { GlobalOpenTelemetry.set(OpenTelemetry.noop()); ConfigProperties config = DefaultConfigProperties.createFromMap( - Collections.singletonMap("otel.config.file", configFilePath.toString())); + Collections.singletonMap("otel.experimental.config.file", configFilePath.toString())); AutoConfiguredOpenTelemetrySdk autoConfiguredOpenTelemetrySdk = AutoConfiguredOpenTelemetrySdk.builder().setConfig(config).build(); @@ -147,7 +147,7 @@ void configFile_setResultAsGlobalFalse() { void configFile_setResultAsGlobalTrue() { ConfigProperties config = DefaultConfigProperties.createFromMap( - Collections.singletonMap("otel.config.file", configFilePath.toString())); + Collections.singletonMap("otel.experimental.config.file", configFilePath.toString())); AutoConfiguredOpenTelemetrySdk autoConfiguredOpenTelemetrySdk = AutoConfiguredOpenTelemetrySdk.builder().setConfig(config).setResultAsGlobal().build(); @@ -177,7 +177,7 @@ void configFile_Error(@TempDir Path tempDir) throws IOException { Files.write(path, yaml.getBytes(StandardCharsets.UTF_8)); ConfigProperties config = DefaultConfigProperties.createFromMap( - Collections.singletonMap("otel.config.file", path.toString())); + Collections.singletonMap("otel.experimental.config.file", path.toString())); assertThatThrownBy(() -> AutoConfiguredOpenTelemetrySdk.builder().setConfig(config).build()) .isInstanceOf(ConfigurationException.class) diff --git a/sdk-extensions/incubator/README.md b/sdk-extensions/incubator/README.md index 8301d01f3f5..cfc76184c31 100644 --- a/sdk-extensions/incubator/README.md +++ b/sdk-extensions/incubator/README.md @@ -20,7 +20,7 @@ try (FileInputStream yamlConfigFileInputStream = new FileInputStream("/path/to/c Notes: * Environment variable substitution is supported as [defined in the spec](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/configuration/file-configuration.md#environment-variable-substitution) * Currently, there is no support for the SPIs defined in [opentelemetry-sdk-extension-autoconfigure-spi](../autoconfigure-spi). Only built in samplers, processors, exporters, etc can be configured. -* You can use file configuration with [autoconfigure](https://github.com/open-telemetry/opentelemetry-java/tree/main/sdk-extensions/autoconfigure#file-configuration) to specify a configuration file via environment variable, e.g. `OTEL_CONFIG_FILE=/path/to/config.yaml`. +* You can use file configuration with [autoconfigure](https://github.com/open-telemetry/opentelemetry-java/tree/main/sdk-extensions/autoconfigure#file-configuration) to specify a configuration file via environment variable, e.g. `OTEL_EXPERIMENTAL_CONFIG_FILE=/path/to/config.yaml`. ## View File Configuration From 1623a80d4c092fa377d0406b547dc539deb63235 Mon Sep 17 00:00:00 2001 From: jack-berg <34418638+jack-berg@users.noreply.github.com> Date: Thu, 18 Apr 2024 13:36:39 -0500 Subject: [PATCH 361/901] Add put(AttributeKey, T) overload to EventBuilder (#6331) --- .../api/incubator/events/EventBuilder.java | 45 ++++++++++++++++++- .../events/DefaultEventLoggerTest.java | 37 ++++++++++++++- .../internal/SdkEventLoggerProviderTest.java | 23 ++++++++++ 3 files changed, 103 insertions(+), 2 deletions(-) diff --git a/api/incubator/src/main/java/io/opentelemetry/api/incubator/events/EventBuilder.java b/api/incubator/src/main/java/io/opentelemetry/api/incubator/events/EventBuilder.java index 27cd6f8c367..9aca02b3077 100644 --- a/api/incubator/src/main/java/io/opentelemetry/api/incubator/events/EventBuilder.java +++ b/api/incubator/src/main/java/io/opentelemetry/api/incubator/events/EventBuilder.java @@ -5,6 +5,9 @@ package io.opentelemetry.api.incubator.events; +import static java.util.stream.Collectors.toList; + +import io.opentelemetry.api.common.AttributeKey; import io.opentelemetry.api.common.Attributes; import io.opentelemetry.api.incubator.logs.AnyValue; import io.opentelemetry.api.logs.Severity; @@ -73,6 +76,44 @@ default EventBuilder put(String key, boolean... value) { return put(key, AnyValue.of(values)); } + /** + * Put the given key and value in the payload. + * + *

      NOTE: The key value pair is NOT added to the event attributes. Setting event attributes is + * less common than adding entries to the event payload. Use {@link #setAttributes(Attributes)} if + * intending the data to be set in attributes instead of the payload. + */ + @SuppressWarnings("unchecked") + default EventBuilder put(AttributeKey key, T value) { + switch (key.getType()) { + case STRING: + return put(key.getKey(), (String) value); + case BOOLEAN: + return put(key.getKey(), (boolean) value); + case LONG: + return put(key.getKey(), (long) value); + case DOUBLE: + return put(key.getKey(), (double) value); + case STRING_ARRAY: + return put( + key.getKey(), + AnyValue.of(((List) value).stream().map(AnyValue::of).collect(toList()))); + case BOOLEAN_ARRAY: + return put( + key.getKey(), + AnyValue.of(((List) value).stream().map(AnyValue::of).collect(toList()))); + case LONG_ARRAY: + return put( + key.getKey(), + AnyValue.of(((List) value).stream().map(AnyValue::of).collect(toList()))); + case DOUBLE_ARRAY: + return put( + key.getKey(), + AnyValue.of(((List) value).stream().map(AnyValue::of).collect(toList()))); + } + return this; + } + /** Put the given {@code key} and {@code value} in the payload. */ EventBuilder put(String key, AnyValue value); @@ -102,7 +143,9 @@ default EventBuilder put(String key, boolean... value) { * Set the attributes. * *

      Event {@link io.opentelemetry.api.common.Attributes} provide additional details about the - * Event which are not part of the well-defined {@link AnyValue} {@code payload}. + * Event which are not part of the well-defined {@link AnyValue} payload. Setting event attributes + * is less common than adding entries to the event payload. Most users will want to call one of + * the {@code #put(String, ?)} methods instead. */ EventBuilder setAttributes(Attributes attributes); diff --git a/api/incubator/src/test/java/io/opentelemetry/api/incubator/events/DefaultEventLoggerTest.java b/api/incubator/src/test/java/io/opentelemetry/api/incubator/events/DefaultEventLoggerTest.java index e1f1f2e7ce7..054e09d2c35 100644 --- a/api/incubator/src/test/java/io/opentelemetry/api/incubator/events/DefaultEventLoggerTest.java +++ b/api/incubator/src/test/java/io/opentelemetry/api/incubator/events/DefaultEventLoggerTest.java @@ -7,23 +7,58 @@ import static org.assertj.core.api.Assertions.assertThatCode; +import io.opentelemetry.api.common.AttributeKey; import io.opentelemetry.api.common.Attributes; +import io.opentelemetry.api.incubator.logs.AnyValue; import io.opentelemetry.api.logs.Severity; import io.opentelemetry.context.Context; import java.time.Instant; +import java.util.Arrays; +import java.util.HashMap; import java.util.concurrent.TimeUnit; import org.junit.jupiter.api.Test; class DefaultEventLoggerTest { @Test + @SuppressWarnings("DoubleBraceInitialization") void builder() { EventLogger eventLogger = DefaultEventLogger.getInstance(); assertThatCode( () -> eventLogger .builder("namespace.myEvent") - .put("key", "value") + // Helper methods to set primitive types + .put("stringKey", "value") + .put("longKey", 1L) + .put("doubleKey", 1.0) + .put("boolKey", true) + // Helper methods to set primitive array types + .put("stringArrKey", "value1", "value2") + .put("longArrKey", 1L, 2L) + .put("doubleArrKey", 1.0, 2.0) + .put("boolArrKey", true, false) + // Set AnyValue types to encode complex data + .put( + "anyValueKey", + AnyValue.of( + new HashMap>() { + { + put("key", AnyValue.of("value")); + } + })) + // Helper methods to set AttributeKey types + .put(AttributeKey.stringKey("attrStringKey"), "value") + .put(AttributeKey.longKey("attrLongKey"), 1L) + .put(AttributeKey.doubleKey("attrDoubleKey"), 1.0) + .put(AttributeKey.booleanKey("attrBoolKey"), true) + .put( + AttributeKey.stringArrayKey("attrStringArrKey"), + Arrays.asList("value1", "value2")) + .put(AttributeKey.longArrayKey("attrLongArrKey"), Arrays.asList(1L, 2L)) + .put(AttributeKey.doubleArrayKey("attrDoubleArrKey"), Arrays.asList(1.0, 2.0)) + .put(AttributeKey.booleanArrayKey("attrBoolArrKey"), Arrays.asList(true, false)) + // Other setters .setTimestamp(123456L, TimeUnit.NANOSECONDS) .setTimestamp(Instant.now()) .setContext(Context.current()) diff --git a/sdk/logs/src/test/java/io/opentelemetry/sdk/logs/internal/SdkEventLoggerProviderTest.java b/sdk/logs/src/test/java/io/opentelemetry/sdk/logs/internal/SdkEventLoggerProviderTest.java index 5c30a6b305d..71f48757207 100644 --- a/sdk/logs/src/test/java/io/opentelemetry/sdk/logs/internal/SdkEventLoggerProviderTest.java +++ b/sdk/logs/src/test/java/io/opentelemetry/sdk/logs/internal/SdkEventLoggerProviderTest.java @@ -10,6 +10,7 @@ import static org.mockito.Mockito.when; import com.google.common.collect.ImmutableMap; +import io.opentelemetry.api.common.AttributeKey; import io.opentelemetry.api.common.Attributes; import io.opentelemetry.api.incubator.events.EventLogger; import io.opentelemetry.api.incubator.logs.AnyValue; @@ -97,6 +98,15 @@ void eventBuilder_FullPayload() { ImmutableMap.of( "childKey1", AnyValue.of("value"), "childKey2", AnyValue.of("value")))) + // Helper methods to set AttributeKey types + .put(AttributeKey.stringKey("attrStringKey"), "value") + .put(AttributeKey.longKey("attrLongKey"), 1L) + .put(AttributeKey.doubleKey("attrDoubleKey"), 1.0) + .put(AttributeKey.booleanKey("attrBoolKey"), true) + .put(AttributeKey.stringArrayKey("attrStringArrKey"), Arrays.asList("value1", "value2")) + .put(AttributeKey.longArrayKey("attrLongArrKey"), Arrays.asList(1L, 2L)) + .put(AttributeKey.doubleArrayKey("attrDoubleArrKey"), Arrays.asList(1.0, 2.0)) + .put(AttributeKey.booleanArrayKey("attrBoolArrKey"), Arrays.asList(true, false)) .emit(); Map> expectedPayload = new HashMap<>(); @@ -117,6 +127,19 @@ void eventBuilder_FullPayload() { ImmutableMap.of( "childKey1", AnyValue.of("value"), "childKey2", AnyValue.of("value")))); + expectedPayload.put("attrStringKey", AnyValue.of("value")); + expectedPayload.put("attrLongKey", AnyValue.of(1L)); + expectedPayload.put("attrDoubleKey", AnyValue.of(1.0)); + expectedPayload.put("attrBoolKey", AnyValue.of(true)); + expectedPayload.put( + "attrStringArrKey", + AnyValue.of(Arrays.asList(AnyValue.of("value1"), AnyValue.of("value2")))); + expectedPayload.put( + "attrLongArrKey", AnyValue.of(Arrays.asList(AnyValue.of(1L), AnyValue.of(2L)))); + expectedPayload.put( + "attrDoubleArrKey", AnyValue.of(Arrays.asList(AnyValue.of(1.0), AnyValue.of(2.0)))); + expectedPayload.put( + "attrBoolArrKey", AnyValue.of(Arrays.asList(AnyValue.of(true), AnyValue.of(false)))); assertThat(((AnyValueBody) seenLog.get().toLogRecordData().getBody()).asAnyValue()) .isEqualTo(AnyValue.of(expectedPayload)); } From c33febbea6250d771d2081637764c25ddd071875 Mon Sep 17 00:00:00 2001 From: jack-berg <34418638+jack-berg@users.noreply.github.com> Date: Thu, 18 Apr 2024 16:36:40 -0500 Subject: [PATCH 362/901] Scope config (#6375) --- .../sdk/ScopeConfiguratorTest.java | 237 ++++++++++++++++++ .../opentelemetry/sdk/internal/GlobUtil.java | 82 ++++++ .../sdk/internal/ScopeConfigurator.java | 33 +++ .../internal/ScopeConfiguratorBuilder.java | 114 +++++++++ .../sdk/internal/GlobUtilTest.java | 46 ++++ .../io/opentelemetry/sdk/logs/SdkLogger.java | 15 +- .../sdk/logs/SdkLoggerProvider.java | 19 +- .../sdk/logs/SdkLoggerProviderBuilder.java | 44 +++- .../sdk/logs/internal/LoggerConfig.java | 63 +++++ .../logs/internal/SdkLoggerProviderUtil.java | 58 +++++ .../sdk/logs/LoggerConfigTest.java | 127 ++++++++++ .../opentelemetry/sdk/logs/SdkLoggerTest.java | 3 +- .../opentelemetry/sdk/metrics/SdkMeter.java | 39 +-- .../sdk/metrics/SdkMeterProvider.java | 19 +- .../sdk/metrics/SdkMeterProviderBuilder.java | 48 +++- .../sdk/metrics/internal/MeterConfig.java | 62 +++++ .../internal/SdkMeterProviderUtil.java | 42 +++- .../state/MeterProviderSharedState.java | 5 +- .../metrics/internal/view/ViewRegistry.java | 69 +---- .../sdk/metrics/MeterConfigTest.java | 148 +++++++++++ .../internal/view/ViewRegistryTest.java | 23 -- .../io/opentelemetry/sdk/trace/SdkTracer.java | 12 +- .../sdk/trace/SdkTracerProvider.java | 20 +- .../sdk/trace/SdkTracerProviderBuilder.java | 49 +++- .../sdk/trace/TracerSharedState.java | 1 + .../trace/internal/SdkTracerProviderUtil.java | 58 +++++ .../sdk/trace/internal/TracerConfig.java | 63 +++++ .../sdk/trace/TracerConfigTest.java | 156 ++++++++++++ 28 files changed, 1533 insertions(+), 122 deletions(-) create mode 100644 sdk/all/src/test/java/io/opentelemetry/sdk/ScopeConfiguratorTest.java create mode 100644 sdk/common/src/main/java/io/opentelemetry/sdk/internal/GlobUtil.java create mode 100644 sdk/common/src/main/java/io/opentelemetry/sdk/internal/ScopeConfigurator.java create mode 100644 sdk/common/src/main/java/io/opentelemetry/sdk/internal/ScopeConfiguratorBuilder.java create mode 100644 sdk/common/src/test/java/io/opentelemetry/sdk/internal/GlobUtilTest.java create mode 100644 sdk/logs/src/main/java/io/opentelemetry/sdk/logs/internal/LoggerConfig.java create mode 100644 sdk/logs/src/main/java/io/opentelemetry/sdk/logs/internal/SdkLoggerProviderUtil.java create mode 100644 sdk/logs/src/test/java/io/opentelemetry/sdk/logs/LoggerConfigTest.java create mode 100644 sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/MeterConfig.java create mode 100644 sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/MeterConfigTest.java create mode 100644 sdk/trace/src/main/java/io/opentelemetry/sdk/trace/internal/SdkTracerProviderUtil.java create mode 100644 sdk/trace/src/main/java/io/opentelemetry/sdk/trace/internal/TracerConfig.java create mode 100644 sdk/trace/src/test/java/io/opentelemetry/sdk/trace/TracerConfigTest.java diff --git a/sdk/all/src/test/java/io/opentelemetry/sdk/ScopeConfiguratorTest.java b/sdk/all/src/test/java/io/opentelemetry/sdk/ScopeConfiguratorTest.java new file mode 100644 index 00000000000..0055df8ce7f --- /dev/null +++ b/sdk/all/src/test/java/io/opentelemetry/sdk/ScopeConfiguratorTest.java @@ -0,0 +1,237 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.sdk; + +import static io.opentelemetry.sdk.internal.ScopeConfiguratorBuilder.nameEquals; +import static org.assertj.core.api.Assertions.assertThat; + +import io.opentelemetry.api.OpenTelemetry; +import io.opentelemetry.api.logs.Logger; +import io.opentelemetry.api.metrics.Meter; +import io.opentelemetry.api.trace.Span; +import io.opentelemetry.api.trace.Tracer; +import io.opentelemetry.context.Scope; +import io.opentelemetry.sdk.common.InstrumentationScopeInfo; +import io.opentelemetry.sdk.logs.SdkLoggerProvider; +import io.opentelemetry.sdk.logs.SdkLoggerProviderBuilder; +import io.opentelemetry.sdk.logs.data.LogRecordData; +import io.opentelemetry.sdk.logs.export.SimpleLogRecordProcessor; +import io.opentelemetry.sdk.logs.internal.LoggerConfig; +import io.opentelemetry.sdk.logs.internal.SdkLoggerProviderUtil; +import io.opentelemetry.sdk.metrics.SdkMeterProvider; +import io.opentelemetry.sdk.metrics.SdkMeterProviderBuilder; +import io.opentelemetry.sdk.metrics.data.MetricData; +import io.opentelemetry.sdk.metrics.internal.MeterConfig; +import io.opentelemetry.sdk.metrics.internal.SdkMeterProviderUtil; +import io.opentelemetry.sdk.testing.exporter.InMemoryLogRecordExporter; +import io.opentelemetry.sdk.testing.exporter.InMemoryMetricReader; +import io.opentelemetry.sdk.testing.exporter.InMemorySpanExporter; +import io.opentelemetry.sdk.trace.SdkTracerProvider; +import io.opentelemetry.sdk.trace.SdkTracerProviderBuilder; +import io.opentelemetry.sdk.trace.data.SpanData; +import io.opentelemetry.sdk.trace.export.SimpleSpanProcessor; +import io.opentelemetry.sdk.trace.internal.SdkTracerProviderUtil; +import io.opentelemetry.sdk.trace.internal.TracerConfig; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; +import org.junit.jupiter.api.Test; + +class ScopeConfiguratorTest { + + private final InMemoryLogRecordExporter logRecordExporter = InMemoryLogRecordExporter.create(); + private final InMemoryMetricReader metricReader = InMemoryMetricReader.create(); + private final InMemorySpanExporter spanExporter = InMemorySpanExporter.create(); + + private static final InstrumentationScopeInfo scopeA = InstrumentationScopeInfo.create("scopeA"); + private static final InstrumentationScopeInfo scopeB = InstrumentationScopeInfo.create("scopeB"); + private static final InstrumentationScopeInfo scopeC = InstrumentationScopeInfo.create("scopeC"); + + /** Disable "scopeB". All other scopes are enabled by default. */ + @Test + void disableScopeB() { + // Configuration ergonomics will improve after APIs stabilize + SdkTracerProviderBuilder tracerProviderBuilder = SdkTracerProvider.builder(); + SdkTracerProviderUtil.addTracerConfiguratorCondition( + tracerProviderBuilder, nameEquals(scopeB.getName()), TracerConfig.disabled()); + SdkMeterProviderBuilder meterProviderBuilder = SdkMeterProvider.builder(); + SdkMeterProviderUtil.addMeterConfiguratorCondition( + meterProviderBuilder, nameEquals(scopeB.getName()), MeterConfig.disabled()); + SdkLoggerProviderBuilder loggerProviderBuilder = SdkLoggerProvider.builder(); + SdkLoggerProviderUtil.addLoggerConfiguratorCondition( + loggerProviderBuilder, nameEquals(scopeB.getName()), LoggerConfig.disabled()); + + OpenTelemetrySdk sdk = + OpenTelemetrySdk.builder() + .setTracerProvider( + tracerProviderBuilder + .addSpanProcessor(SimpleSpanProcessor.create(spanExporter)) + .build()) + .setMeterProvider(meterProviderBuilder.registerMetricReader(metricReader).build()) + .setLoggerProvider( + loggerProviderBuilder + .addLogRecordProcessor(SimpleLogRecordProcessor.create(logRecordExporter)) + .build()) + .build(); + + simulateInstrumentation(sdk); + + // Collect all the telemetry. Ensure we don't see any from scopeB, and that the telemetry from + // scopeA and scopeC is valid. + assertThat(spanExporter.getFinishedSpanItems()) + .satisfies( + spans -> { + Map> spansByScope = + spans.stream() + .collect(Collectors.groupingBy(SpanData::getInstrumentationScopeInfo)); + assertThat(spansByScope.get(scopeA)).hasSize(1); + assertThat(spansByScope.get(scopeB)).isNull(); + assertThat(spansByScope.get(scopeC)).hasSize(1); + }); + assertThat(metricReader.collectAllMetrics()) + .satisfies( + metrics -> { + Map> metricsByScope = + metrics.stream() + .collect(Collectors.groupingBy(MetricData::getInstrumentationScopeInfo)); + assertThat(metricsByScope.get(scopeA)).hasSize(1); + assertThat(metricsByScope.get(scopeB)).isNull(); + assertThat(metricsByScope.get(scopeC)).hasSize(1); + }); + assertThat(logRecordExporter.getFinishedLogRecordItems()) + .satisfies( + logs -> { + Map> logsByScope = + logs.stream() + .collect(Collectors.groupingBy(LogRecordData::getInstrumentationScopeInfo)); + assertThat(logsByScope.get(scopeA)).hasSize(1); + assertThat(logsByScope.get(scopeB)).isNull(); + assertThat(logsByScope.get(scopeC)).hasSize(1); + }); + } + + /** Disable all scopes by default and enable a single scope. */ + @Test + void disableAllScopesExceptB() { + // Configuration ergonomics will improve after APIs stabilize + SdkTracerProviderBuilder tracerProviderBuilder = SdkTracerProvider.builder(); + SdkTracerProviderUtil.setTracerConfigurator( + tracerProviderBuilder, + TracerConfig.configuratorBuilder() + .setDefault(TracerConfig.disabled()) + .addCondition(nameEquals(scopeB.getName()), TracerConfig.enabled()) + .build()); + SdkMeterProviderBuilder meterProviderBuilder = SdkMeterProvider.builder(); + SdkMeterProviderUtil.setMeterConfigurator( + meterProviderBuilder, + MeterConfig.configuratorBuilder() + .setDefault(MeterConfig.disabled()) + .addCondition(nameEquals(scopeB.getName()), MeterConfig.enabled()) + .build()); + SdkLoggerProviderBuilder loggerProviderBuilder = SdkLoggerProvider.builder(); + SdkLoggerProviderUtil.setLoggerConfigurator( + loggerProviderBuilder, + LoggerConfig.configuratorBuilder() + .setDefault(LoggerConfig.disabled()) + .addCondition(nameEquals(scopeB.getName()), LoggerConfig.enabled()) + .build()); + + OpenTelemetrySdk sdk = + OpenTelemetrySdk.builder() + .setTracerProvider( + tracerProviderBuilder + .addSpanProcessor(SimpleSpanProcessor.create(spanExporter)) + .build()) + .setMeterProvider(meterProviderBuilder.registerMetricReader(metricReader).build()) + .setLoggerProvider( + loggerProviderBuilder + .addLogRecordProcessor(SimpleLogRecordProcessor.create(logRecordExporter)) + .build()) + .build(); + + simulateInstrumentation(sdk); + + // Collect all the telemetry. Ensure we only see telemetry from scopeB, since other scopes have + // been disabled by default. + assertThat(spanExporter.getFinishedSpanItems()) + .satisfies( + spans -> { + Map> spansByScope = + spans.stream() + .collect(Collectors.groupingBy(SpanData::getInstrumentationScopeInfo)); + assertThat(spansByScope.get(scopeA)).isNull(); + assertThat(spansByScope.get(scopeB)).hasSize(1); + assertThat(spansByScope.get(scopeC)).isNull(); + }); + assertThat(metricReader.collectAllMetrics()) + .satisfies( + metrics -> { + Map> metricsByScope = + metrics.stream() + .collect(Collectors.groupingBy(MetricData::getInstrumentationScopeInfo)); + assertThat(metricsByScope.get(scopeA)).isNull(); + assertThat(metricsByScope.get(scopeB)).hasSize(1); + assertThat(metricsByScope.get(scopeC)).isNull(); + }); + assertThat(logRecordExporter.getFinishedLogRecordItems()) + .satisfies( + logs -> { + Map> logsByScope = + logs.stream() + .collect(Collectors.groupingBy(LogRecordData::getInstrumentationScopeInfo)); + assertThat(logsByScope.get(scopeA)).isNull(); + assertThat(logsByScope.get(scopeB)).hasSize(1); + assertThat(logsByScope.get(scopeC)).isNull(); + }); + } + + /** + * Emit spans, metrics and logs in a hierarchy of 3 scopes: scopeA -> scopeB -> scopeC. Exercise + * the scope config which is common across all signals. + */ + private static void simulateInstrumentation(OpenTelemetry openTelemetry) { + // Start scopeA + Tracer scopeATracer = openTelemetry.getTracer(scopeA.getName()); + Meter scopeAMeter = openTelemetry.getMeter(scopeA.getName()); + Logger scopeALogger = openTelemetry.getLogsBridge().get(scopeA.getName()); + Span spanA = scopeATracer.spanBuilder("spanA").startSpan(); + try (Scope spanAScope = spanA.makeCurrent()) { + scopeALogger.logRecordBuilder().setBody("scopeA log message").emit(); + + // Start scopeB + Tracer scopeBTracer = openTelemetry.getTracer(scopeB.getName()); + Meter scopeBMeter = openTelemetry.getMeter(scopeB.getName()); + Logger scopeBLogger = openTelemetry.getLogsBridge().get(scopeB.getName()); + Span spanB = scopeBTracer.spanBuilder("spanB").startSpan(); + try (Scope spanBScope = spanB.makeCurrent()) { + scopeBLogger.logRecordBuilder().setBody("scopeB log message").emit(); + + // Start scopeC + Tracer scopeCTracer = openTelemetry.getTracer(scopeC.getName()); + Meter scopeCMeter = openTelemetry.getMeter(scopeC.getName()); + Logger scopeCLogger = openTelemetry.getLogsBridge().get(scopeC.getName()); + Span spanC = scopeCTracer.spanBuilder("spanC").startSpan(); + try (Scope spanCScope = spanB.makeCurrent()) { + scopeCLogger.logRecordBuilder().setBody("scopeC log message").emit(); + } finally { + spanC.end(); + scopeCMeter.counterBuilder("scopeCCounter").build().add(1); + } + // End scopeC + + } finally { + spanB.end(); + scopeBMeter.counterBuilder("scopeBCounter").build().add(1); + } + // End scopeB + + } finally { + spanA.end(); + scopeAMeter.counterBuilder("scopeACounter").build().add(1); + } + // End scopeA + } +} diff --git a/sdk/common/src/main/java/io/opentelemetry/sdk/internal/GlobUtil.java b/sdk/common/src/main/java/io/opentelemetry/sdk/internal/GlobUtil.java new file mode 100644 index 00000000000..9c914055d7d --- /dev/null +++ b/sdk/common/src/main/java/io/opentelemetry/sdk/internal/GlobUtil.java @@ -0,0 +1,82 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.sdk.internal; + +import java.util.function.Predicate; +import java.util.regex.Pattern; + +/** + * Utilities for glob pattern matching. + * + *

      This class is internal and is hence not for public use. Its APIs are unstable and can change + * at any time. + */ +public final class GlobUtil { + + private GlobUtil() {} + + /** + * Return a predicate that returns {@code true} if a string matches the {@code globPattern}. + * + *

      {@code globPattern} may contain the wildcard characters {@code *} and {@code ?} with the + * following matching criteria: + * + *

      + */ + public static Predicate toGlobPatternPredicate(String globPattern) { + // Match all + if (globPattern.equals("*")) { + return unused -> true; + } + + // If globPattern contains '*' or '?', convert it to a regex and return corresponding predicate + for (int i = 0; i < globPattern.length(); i++) { + char c = globPattern.charAt(i); + if (c == '*' || c == '?') { + Pattern pattern = toRegexPattern(globPattern); + return string -> pattern.matcher(string).matches(); + } + } + + // Exact match, ignoring case + return globPattern::equalsIgnoreCase; + } + + /** + * Transform the {@code globPattern} to a regex by converting {@code *} to {@code .*}, {@code ?} + * to {@code .}, and escaping other regex special characters. + */ + private static Pattern toRegexPattern(String globPattern) { + int tokenStart = -1; + StringBuilder patternBuilder = new StringBuilder(); + for (int i = 0; i < globPattern.length(); i++) { + char c = globPattern.charAt(i); + if (c == '*' || c == '?') { + if (tokenStart != -1) { + patternBuilder.append(Pattern.quote(globPattern.substring(tokenStart, i))); + tokenStart = -1; + } + if (c == '*') { + patternBuilder.append(".*"); + } else { + // c == '?' + patternBuilder.append("."); + } + } else { + if (tokenStart == -1) { + tokenStart = i; + } + } + } + if (tokenStart != -1) { + patternBuilder.append(Pattern.quote(globPattern.substring(tokenStart))); + } + return Pattern.compile(patternBuilder.toString()); + } +} diff --git a/sdk/common/src/main/java/io/opentelemetry/sdk/internal/ScopeConfigurator.java b/sdk/common/src/main/java/io/opentelemetry/sdk/internal/ScopeConfigurator.java new file mode 100644 index 00000000000..cb1fdaeed43 --- /dev/null +++ b/sdk/common/src/main/java/io/opentelemetry/sdk/internal/ScopeConfigurator.java @@ -0,0 +1,33 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.sdk.internal; + +import io.opentelemetry.sdk.common.InstrumentationScopeInfo; +import java.util.function.Function; + +/** + * A {@link ScopeConfigurator} computes configuration for a given {@link InstrumentationScopeInfo}. + * + *

      This class is internal and is hence not for public use. Its APIs are unstable and can change + * at any time. + */ +@FunctionalInterface +public interface ScopeConfigurator extends Function { + + /** Create a new builder. */ + static ScopeConfiguratorBuilder builder() { + return new ScopeConfiguratorBuilder<>(unused -> null); + } + + /** + * Convert this {@link ScopeConfigurator} to a builder. Additional added matchers only apply when + * {@link #apply(Object)} returns {@code null}. If this configurator contains {@link + * ScopeConfiguratorBuilder#setDefault(Object)}, additional matchers are never applied. + */ + default ScopeConfiguratorBuilder toBuilder() { + return new ScopeConfiguratorBuilder<>(this); + } +} diff --git a/sdk/common/src/main/java/io/opentelemetry/sdk/internal/ScopeConfiguratorBuilder.java b/sdk/common/src/main/java/io/opentelemetry/sdk/internal/ScopeConfiguratorBuilder.java new file mode 100644 index 00000000000..4c32e2f8d9a --- /dev/null +++ b/sdk/common/src/main/java/io/opentelemetry/sdk/internal/ScopeConfiguratorBuilder.java @@ -0,0 +1,114 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.sdk.internal; + +import io.opentelemetry.sdk.common.InstrumentationScopeInfo; +import java.util.ArrayList; +import java.util.List; +import java.util.function.Predicate; +import javax.annotation.Nullable; + +/** + * Builder for {@link ScopeConfigurator}. + * + *

      This class is internal and is hence not for public use. Its APIs are unstable and can change + * at any time. + * + * @param The scope configuration object, e.g. {@code TracerConfig}, {@code LoggerConfig}, + * {@code MeterConfig}. + */ +public final class ScopeConfiguratorBuilder { + + private final ScopeConfigurator baseScopeConfigurator; + @Nullable private T defaultScopeConfig; + private final List> conditions = new ArrayList<>(); + + ScopeConfiguratorBuilder(ScopeConfigurator baseScopeConfigurator) { + this.baseScopeConfigurator = baseScopeConfigurator; + } + + /** + * Set the default scope config, which is returned by {@link ScopeConfigurator#apply(Object)} if a + * {@link InstrumentationScopeInfo} does not match any {@link #addCondition(Predicate, Object) + * conditions}. If a default is not set, an SDK defined default is used. + */ + public ScopeConfiguratorBuilder setDefault(T defaultScopeConfig) { + this.defaultScopeConfig = defaultScopeConfig; + return this; + } + + /** + * Add a condition. Conditions are evaluated in order. The {@code scopeConfig} for the first match + * is returned by {@link ScopeConfigurator#apply(Object)}. + * + * @param scopePredicate predicate that {@link InstrumentationScopeInfo}s are evaluated against + * @param scopeConfig the scope config to use when this condition is the first matching {@code + * scopePredicate} + * @see #nameMatchesGlob(String) + * @see #nameEquals(String) + */ + public ScopeConfiguratorBuilder addCondition( + Predicate scopePredicate, T scopeConfig) { + conditions.add(new Condition<>(scopePredicate, scopeConfig)); + return this; + } + + /** + * Helper function for pattern matching {@link InstrumentationScopeInfo#getName()} against the + * {@code globPattern}. + * + *

      {@code globPattern} may contain the wildcard characters {@code *} and {@code ?} with the + * following matching criteria: + * + *

        + *
      • {@code *} matches 0 or more instances of any character + *
      • {@code ?} matches exactly one instance of any character + *
      + * + * @see #addCondition(Predicate, Object) + */ + public static Predicate nameMatchesGlob(String globPattern) { + Predicate globPredicate = GlobUtil.toGlobPatternPredicate(globPattern); + return scopeInfo -> globPredicate.test(scopeInfo.getName()); + } + + /** + * Helper function for exact matching {@link InstrumentationScopeInfo#getName()} against the + * {@code scopeName}. + * + * @see #addCondition(Predicate, Object) + */ + public static Predicate nameEquals(String scopeName) { + return scopeInfo -> scopeInfo.getName().equals(scopeName); + } + + /** Build a {@link ScopeConfigurator} with the configuration of this builder. */ + public ScopeConfigurator build() { + // TODO: return an instance with toString implementation which self describes rules + return scopeInfo -> { + T scopeConfig = baseScopeConfigurator.apply(scopeInfo); + if (scopeConfig != null) { + return scopeConfig; + } + for (Condition condition : conditions) { + if (condition.scopeMatcher.test(scopeInfo)) { + return condition.scopeConfig; + } + } + return defaultScopeConfig; + }; + } + + private static final class Condition { + private final Predicate scopeMatcher; + private final T scopeConfig; + + private Condition(Predicate scopeMatcher, T scopeConfig) { + this.scopeMatcher = scopeMatcher; + this.scopeConfig = scopeConfig; + } + } +} diff --git a/sdk/common/src/test/java/io/opentelemetry/sdk/internal/GlobUtilTest.java b/sdk/common/src/test/java/io/opentelemetry/sdk/internal/GlobUtilTest.java new file mode 100644 index 00000000000..a26928f34bc --- /dev/null +++ b/sdk/common/src/test/java/io/opentelemetry/sdk/internal/GlobUtilTest.java @@ -0,0 +1,46 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.sdk.internal; + +import static io.opentelemetry.sdk.internal.GlobUtil.toGlobPatternPredicate; +import static org.assertj.core.api.Assertions.assertThat; + +import org.junit.jupiter.api.Test; + +class GlobUtilTest { + + @Test + void matchesName() { + assertThat(toGlobPatternPredicate("foo").test("foo")).isTrue(); + assertThat(toGlobPatternPredicate("foo").test("Foo")).isTrue(); + assertThat(toGlobPatternPredicate("foo").test("bar")).isFalse(); + assertThat(toGlobPatternPredicate("fo?").test("foo")).isTrue(); + assertThat(toGlobPatternPredicate("fo??").test("fooo")).isTrue(); + assertThat(toGlobPatternPredicate("fo?").test("fob")).isTrue(); + assertThat(toGlobPatternPredicate("fo?").test("fooo")).isFalse(); + assertThat(toGlobPatternPredicate("*").test("foo")).isTrue(); + assertThat(toGlobPatternPredicate("*").test("bar")).isTrue(); + assertThat(toGlobPatternPredicate("*").test("baz")).isTrue(); + assertThat(toGlobPatternPredicate("*").test("foo.bar.baz")).isTrue(); + assertThat(toGlobPatternPredicate("*").test(null)).isTrue(); + assertThat(toGlobPatternPredicate("*").test("")).isTrue(); + assertThat(toGlobPatternPredicate("fo*").test("fo")).isTrue(); + assertThat(toGlobPatternPredicate("fo*").test("foo")).isTrue(); + assertThat(toGlobPatternPredicate("fo*").test("fooo")).isTrue(); + assertThat(toGlobPatternPredicate("fo*").test("foo.bar.baz")).isTrue(); + assertThat(toGlobPatternPredicate("*bar").test("sandbar")).isTrue(); + assertThat(toGlobPatternPredicate("fo*b*").test("foobar")).isTrue(); + assertThat(toGlobPatternPredicate("fo*b*").test("foob")).isTrue(); + assertThat(toGlobPatternPredicate("fo*b*").test("foo bar")).isTrue(); + assertThat(toGlobPatternPredicate("fo? b??").test("foo bar")).isTrue(); + assertThat(toGlobPatternPredicate("fo? b??").test("fooo bar")).isFalse(); + assertThat(toGlobPatternPredicate("fo* ba?").test("foo is not bar")).isTrue(); + assertThat(toGlobPatternPredicate("fo? b*").test("fox beetles for lunch")).isTrue(); + assertThat(toGlobPatternPredicate("f()[]$^.{}|").test("f()[]$^.{}|")).isTrue(); + assertThat(toGlobPatternPredicate("f()[]$^.{}|?").test("f()[]$^.{}|o")).isTrue(); + assertThat(toGlobPatternPredicate("f()[]$^.{}|*").test("f()[]$^.{}|ooo")).isTrue(); + } +} diff --git a/sdk/logs/src/main/java/io/opentelemetry/sdk/logs/SdkLogger.java b/sdk/logs/src/main/java/io/opentelemetry/sdk/logs/SdkLogger.java index efcb7882ade..74bad693bfa 100644 --- a/sdk/logs/src/main/java/io/opentelemetry/sdk/logs/SdkLogger.java +++ b/sdk/logs/src/main/java/io/opentelemetry/sdk/logs/SdkLogger.java @@ -7,23 +7,34 @@ import io.opentelemetry.api.logs.LogRecordBuilder; import io.opentelemetry.api.logs.Logger; +import io.opentelemetry.api.logs.LoggerProvider; import io.opentelemetry.sdk.common.InstrumentationScopeInfo; +import io.opentelemetry.sdk.logs.internal.LoggerConfig; /** SDK implementation of {@link Logger}. */ final class SdkLogger implements Logger { + private static final Logger NOOP_LOGGER = LoggerProvider.noop().get("noop"); + private final LoggerSharedState loggerSharedState; private final InstrumentationScopeInfo instrumentationScopeInfo; + private final LoggerConfig loggerConfig; SdkLogger( - LoggerSharedState loggerSharedState, InstrumentationScopeInfo instrumentationScopeInfo) { + LoggerSharedState loggerSharedState, + InstrumentationScopeInfo instrumentationScopeInfo, + LoggerConfig loggerConfig) { this.loggerSharedState = loggerSharedState; this.instrumentationScopeInfo = instrumentationScopeInfo; + this.loggerConfig = loggerConfig; } @Override public LogRecordBuilder logRecordBuilder() { - return new SdkLogRecordBuilder(loggerSharedState, instrumentationScopeInfo); + if (loggerConfig.isEnabled()) { + return new SdkLogRecordBuilder(loggerSharedState, instrumentationScopeInfo); + } + return NOOP_LOGGER.logRecordBuilder(); } // VisibleForTesting diff --git a/sdk/logs/src/main/java/io/opentelemetry/sdk/logs/SdkLoggerProvider.java b/sdk/logs/src/main/java/io/opentelemetry/sdk/logs/SdkLoggerProvider.java index 9b9b2e1a97d..2d7b87e6b47 100644 --- a/sdk/logs/src/main/java/io/opentelemetry/sdk/logs/SdkLoggerProvider.java +++ b/sdk/logs/src/main/java/io/opentelemetry/sdk/logs/SdkLoggerProvider.java @@ -11,7 +11,10 @@ import io.opentelemetry.api.logs.LoggerProvider; import io.opentelemetry.sdk.common.Clock; import io.opentelemetry.sdk.common.CompletableResultCode; +import io.opentelemetry.sdk.common.InstrumentationScopeInfo; import io.opentelemetry.sdk.internal.ComponentRegistry; +import io.opentelemetry.sdk.internal.ScopeConfigurator; +import io.opentelemetry.sdk.logs.internal.LoggerConfig; import io.opentelemetry.sdk.resources.Resource; import java.io.Closeable; import java.util.List; @@ -33,6 +36,7 @@ public final class SdkLoggerProvider implements LoggerProvider, Closeable { private final LoggerSharedState sharedState; private final ComponentRegistry loggerComponentRegistry; + private final ScopeConfigurator loggerConfigurator; private final boolean isNoopLogRecordProcessor; /** @@ -48,16 +52,27 @@ public static SdkLoggerProviderBuilder builder() { Resource resource, Supplier logLimitsSupplier, List processors, - Clock clock) { + Clock clock, + ScopeConfigurator loggerConfigurator) { LogRecordProcessor logRecordProcessor = LogRecordProcessor.composite(processors); this.sharedState = new LoggerSharedState(resource, logLimitsSupplier, logRecordProcessor, clock); this.loggerComponentRegistry = new ComponentRegistry<>( - instrumentationScopeInfo -> new SdkLogger(sharedState, instrumentationScopeInfo)); + instrumentationScopeInfo -> + new SdkLogger( + sharedState, + instrumentationScopeInfo, + getLoggerConfig(instrumentationScopeInfo))); + this.loggerConfigurator = loggerConfigurator; this.isNoopLogRecordProcessor = logRecordProcessor instanceof NoopLogRecordProcessor; } + private LoggerConfig getLoggerConfig(InstrumentationScopeInfo instrumentationScopeInfo) { + LoggerConfig loggerConfig = loggerConfigurator.apply(instrumentationScopeInfo); + return loggerConfig == null ? LoggerConfig.defaultConfig() : loggerConfig; + } + @Override public Logger get(String instrumentationScopeName) { return loggerComponentRegistry.get( diff --git a/sdk/logs/src/main/java/io/opentelemetry/sdk/logs/SdkLoggerProviderBuilder.java b/sdk/logs/src/main/java/io/opentelemetry/sdk/logs/SdkLoggerProviderBuilder.java index 8d7004eeabd..87fec0c8d84 100644 --- a/sdk/logs/src/main/java/io/opentelemetry/sdk/logs/SdkLoggerProviderBuilder.java +++ b/sdk/logs/src/main/java/io/opentelemetry/sdk/logs/SdkLoggerProviderBuilder.java @@ -11,11 +11,16 @@ import io.opentelemetry.api.logs.Logger; import io.opentelemetry.context.Context; import io.opentelemetry.sdk.common.Clock; +import io.opentelemetry.sdk.common.InstrumentationScopeInfo; +import io.opentelemetry.sdk.internal.ScopeConfigurator; +import io.opentelemetry.sdk.internal.ScopeConfiguratorBuilder; import io.opentelemetry.sdk.logs.data.LogRecordData; +import io.opentelemetry.sdk.logs.internal.LoggerConfig; import io.opentelemetry.sdk.resources.Resource; import java.util.ArrayList; import java.util.List; import java.util.Objects; +import java.util.function.Predicate; import java.util.function.Supplier; /** @@ -29,6 +34,8 @@ public final class SdkLoggerProviderBuilder { private Resource resource = Resource.getDefault(); private Supplier logLimitsSupplier = LogLimits::getDefault; private Clock clock = Clock.getDefault(); + private ScopeConfiguratorBuilder loggerConfiguratorBuilder = + LoggerConfig.configuratorBuilder(); SdkLoggerProviderBuilder() {} @@ -100,12 +107,47 @@ public SdkLoggerProviderBuilder setClock(Clock clock) { return this; } + /** + * Set the logger configurator, which computes {@link LoggerConfig} for each {@link + * InstrumentationScopeInfo}. + * + *

      Overrides any matchers added via {@link #addLoggerConfiguratorCondition(Predicate, + * LoggerConfig)}. + * + * @see LoggerConfig#configuratorBuilder() + */ + SdkLoggerProviderBuilder setLoggerConfigurator( + ScopeConfigurator loggerConfigurator) { + this.loggerConfiguratorBuilder = loggerConfigurator.toBuilder(); + return this; + } + + /** + * Adds a condition to the logger configurator, which computes {@link LoggerConfig} for each + * {@link InstrumentationScopeInfo}. + * + *

      Applies after any previously added conditions. + * + *

      If {@link #setLoggerConfigurator(ScopeConfigurator)} was previously called, this condition + * will only be applied if the {@link ScopeConfigurator#apply(Object)} returns null for the + * matched {@link InstrumentationScopeInfo}(s). + * + * @see ScopeConfiguratorBuilder#nameEquals(String) + * @see ScopeConfiguratorBuilder#nameMatchesGlob(String) + */ + SdkLoggerProviderBuilder addLoggerConfiguratorCondition( + Predicate scopeMatcher, LoggerConfig loggerConfig) { + this.loggerConfiguratorBuilder.addCondition(scopeMatcher, loggerConfig); + return this; + } + /** * Create a {@link SdkLoggerProvider} instance. * * @return an instance configured with the provided options */ public SdkLoggerProvider build() { - return new SdkLoggerProvider(resource, logLimitsSupplier, logRecordProcessors, clock); + return new SdkLoggerProvider( + resource, logLimitsSupplier, logRecordProcessors, clock, loggerConfiguratorBuilder.build()); } } diff --git a/sdk/logs/src/main/java/io/opentelemetry/sdk/logs/internal/LoggerConfig.java b/sdk/logs/src/main/java/io/opentelemetry/sdk/logs/internal/LoggerConfig.java new file mode 100644 index 00000000000..39825686c86 --- /dev/null +++ b/sdk/logs/src/main/java/io/opentelemetry/sdk/logs/internal/LoggerConfig.java @@ -0,0 +1,63 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.sdk.logs.internal; + +import com.google.auto.value.AutoValue; +import io.opentelemetry.api.logs.Logger; +import io.opentelemetry.sdk.common.InstrumentationScopeInfo; +import io.opentelemetry.sdk.internal.ScopeConfigurator; +import io.opentelemetry.sdk.internal.ScopeConfiguratorBuilder; +import io.opentelemetry.sdk.logs.SdkLoggerProviderBuilder; +import java.util.function.Predicate; +import javax.annotation.concurrent.Immutable; + +/** + * A collection of configuration options which define the behavior of a {@link Logger}. + * + * @see SdkLoggerProviderUtil#setLoggerConfigurator(SdkLoggerProviderBuilder, ScopeConfigurator) + * @see SdkLoggerProviderUtil#addLoggerConfiguratorCondition(SdkLoggerProviderBuilder, Predicate, + * LoggerConfig) + */ +@AutoValue +@Immutable +public abstract class LoggerConfig { + + private static final LoggerConfig DEFAULT_CONFIG = + new AutoValue_LoggerConfig(/* enabled= */ true); + private static final LoggerConfig DISABLED_CONFIG = + new AutoValue_LoggerConfig(/* enabled= */ false); + + /** Returns a disabled {@link LoggerConfig}. */ + public static LoggerConfig disabled() { + return DISABLED_CONFIG; + } + + /** Returns an enabled {@link LoggerConfig}. */ + public static LoggerConfig enabled() { + return DEFAULT_CONFIG; + } + + /** + * Returns the default {@link LoggerConfig}, which is used when no configurator is set or when the + * logger configurator returns {@code null} for a {@link InstrumentationScopeInfo}. + */ + public static LoggerConfig defaultConfig() { + return DEFAULT_CONFIG; + } + + /** + * Create a {@link ScopeConfiguratorBuilder} for configuring {@link + * SdkLoggerProviderUtil#setLoggerConfigurator(SdkLoggerProviderBuilder, ScopeConfigurator)}. + */ + public static ScopeConfiguratorBuilder configuratorBuilder() { + return ScopeConfigurator.builder(); + } + + LoggerConfig() {} + + /** Returns {@code true} if this logger is enabled. Defaults to {@code true}. */ + public abstract boolean isEnabled(); +} diff --git a/sdk/logs/src/main/java/io/opentelemetry/sdk/logs/internal/SdkLoggerProviderUtil.java b/sdk/logs/src/main/java/io/opentelemetry/sdk/logs/internal/SdkLoggerProviderUtil.java new file mode 100644 index 00000000000..eb4fbb4ec29 --- /dev/null +++ b/sdk/logs/src/main/java/io/opentelemetry/sdk/logs/internal/SdkLoggerProviderUtil.java @@ -0,0 +1,58 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.sdk.logs.internal; + +import io.opentelemetry.sdk.common.InstrumentationScopeInfo; +import io.opentelemetry.sdk.internal.ScopeConfigurator; +import io.opentelemetry.sdk.logs.SdkLoggerProviderBuilder; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.function.Predicate; + +/** + * A collection of methods that allow use of experimental features prior to availability in public + * APIs. + * + *

      This class is internal and is hence not for public use. Its APIs are unstable and can change + * at any time. + */ +public final class SdkLoggerProviderUtil { + + private SdkLoggerProviderUtil() {} + + /** Reflectively set the {@link ScopeConfigurator} to the {@link SdkLoggerProviderBuilder}. */ + public static void setLoggerConfigurator( + SdkLoggerProviderBuilder sdkLoggerProviderBuilder, + ScopeConfigurator loggerConfigurator) { + try { + Method method = + SdkLoggerProviderBuilder.class.getDeclaredMethod( + "setLoggerConfigurator", ScopeConfigurator.class); + method.setAccessible(true); + method.invoke(sdkLoggerProviderBuilder, loggerConfigurator); + } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) { + throw new IllegalStateException( + "Error calling setLoggerConfigurator on SdkLoggerProviderBuilder", e); + } + } + + /** Reflectively add a logger configurator condition to the {@link SdkLoggerProviderBuilder}. */ + public static void addLoggerConfiguratorCondition( + SdkLoggerProviderBuilder sdkLoggerProviderBuilder, + Predicate scopeMatcher, + LoggerConfig loggerConfig) { + try { + Method method = + SdkLoggerProviderBuilder.class.getDeclaredMethod( + "addLoggerConfiguratorCondition", Predicate.class, LoggerConfig.class); + method.setAccessible(true); + method.invoke(sdkLoggerProviderBuilder, scopeMatcher, loggerConfig); + } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) { + throw new IllegalStateException( + "Error calling addLoggerConfiguratorCondition on SdkLoggerProviderBuilder", e); + } + } +} diff --git a/sdk/logs/src/test/java/io/opentelemetry/sdk/logs/LoggerConfigTest.java b/sdk/logs/src/test/java/io/opentelemetry/sdk/logs/LoggerConfigTest.java new file mode 100644 index 00000000000..371098267eb --- /dev/null +++ b/sdk/logs/src/test/java/io/opentelemetry/sdk/logs/LoggerConfigTest.java @@ -0,0 +1,127 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.sdk.logs; + +import static io.opentelemetry.sdk.internal.ScopeConfiguratorBuilder.nameEquals; +import static io.opentelemetry.sdk.internal.ScopeConfiguratorBuilder.nameMatchesGlob; +import static io.opentelemetry.sdk.logs.internal.LoggerConfig.defaultConfig; +import static io.opentelemetry.sdk.logs.internal.LoggerConfig.enabled; +import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.assertThat; + +import io.opentelemetry.api.logs.Logger; +import io.opentelemetry.sdk.common.InstrumentationScopeInfo; +import io.opentelemetry.sdk.internal.ScopeConfigurator; +import io.opentelemetry.sdk.logs.data.LogRecordData; +import io.opentelemetry.sdk.logs.export.SimpleLogRecordProcessor; +import io.opentelemetry.sdk.logs.internal.LoggerConfig; +import io.opentelemetry.sdk.testing.exporter.InMemoryLogRecordExporter; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; +import java.util.stream.Stream; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; + +class LoggerConfigTest { + + @Test + void disableScopes() { + InMemoryLogRecordExporter exporter = InMemoryLogRecordExporter.create(); + SdkLoggerProvider loggerProvider = + SdkLoggerProvider.builder() + // Disable loggerB. Since loggers are enabled by default, loggerA and loggerC are + // enabled. + .addLoggerConfiguratorCondition(nameEquals("loggerB"), LoggerConfig.disabled()) + .addLogRecordProcessor(SimpleLogRecordProcessor.create(exporter)) + .build(); + + Logger loggerA = loggerProvider.get("loggerA"); + Logger loggerB = loggerProvider.get("loggerB"); + Logger loggerC = loggerProvider.get("loggerC"); + + loggerA.logRecordBuilder().setBody("messageA").emit(); + loggerB.logRecordBuilder().setBody("messageB").emit(); + loggerC.logRecordBuilder().setBody("messageC").emit(); + + // Only logs from loggerA and loggerC should be seen + assertThat(exporter.getFinishedLogRecordItems()) + .satisfies( + metrics -> { + Map> logsByScope = + metrics.stream() + .collect(Collectors.groupingBy(LogRecordData::getInstrumentationScopeInfo)); + assertThat(logsByScope.get(InstrumentationScopeInfo.create("loggerA"))).hasSize(1); + assertThat(logsByScope.get(InstrumentationScopeInfo.create("loggerB"))).isNull(); + assertThat(logsByScope.get(InstrumentationScopeInfo.create("loggerC"))).hasSize(1); + }); + } + + @ParameterizedTest + @MethodSource("loggerConfiguratorArgs") + void loggerConfigurator( + ScopeConfigurator loggerConfigurator, + InstrumentationScopeInfo scope, + LoggerConfig expectedLoggerConfig) { + LoggerConfig loggerConfig = loggerConfigurator.apply(scope); + loggerConfig = loggerConfig == null ? defaultConfig() : loggerConfig; + assertThat(loggerConfig).isEqualTo(expectedLoggerConfig); + } + + private static final InstrumentationScopeInfo scopeCat = InstrumentationScopeInfo.create("cat"); + private static final InstrumentationScopeInfo scopeDog = InstrumentationScopeInfo.create("dog"); + private static final InstrumentationScopeInfo scopeDuck = InstrumentationScopeInfo.create("duck"); + + private static Stream loggerConfiguratorArgs() { + ScopeConfigurator defaultConfigurator = + LoggerConfig.configuratorBuilder().build(); + ScopeConfigurator disableCat = + LoggerConfig.configuratorBuilder() + .addCondition(nameEquals("cat"), LoggerConfig.disabled()) + // Second matching rule for cat should be ignored + .addCondition(nameEquals("cat"), enabled()) + .build(); + ScopeConfigurator disableStartsWithD = + LoggerConfig.configuratorBuilder() + .addCondition(nameMatchesGlob("d*"), LoggerConfig.disabled()) + .build(); + ScopeConfigurator enableCat = + LoggerConfig.configuratorBuilder() + .setDefault(LoggerConfig.disabled()) + .addCondition(nameEquals("cat"), enabled()) + // Second matching rule for cat should be ignored + .addCondition(nameEquals("cat"), LoggerConfig.disabled()) + .build(); + ScopeConfigurator enableStartsWithD = + LoggerConfig.configuratorBuilder() + .setDefault(LoggerConfig.disabled()) + .addCondition(nameMatchesGlob("d*"), LoggerConfig.enabled()) + .build(); + + return Stream.of( + // default + Arguments.of(defaultConfigurator, scopeCat, defaultConfig()), + Arguments.of(defaultConfigurator, scopeDog, defaultConfig()), + Arguments.of(defaultConfigurator, scopeDuck, defaultConfig()), + // default enabled, disable cat + Arguments.of(disableCat, scopeCat, LoggerConfig.disabled()), + Arguments.of(disableCat, scopeDog, enabled()), + Arguments.of(disableCat, scopeDuck, enabled()), + // default enabled, disable pattern + Arguments.of(disableStartsWithD, scopeCat, enabled()), + Arguments.of(disableStartsWithD, scopeDog, LoggerConfig.disabled()), + Arguments.of(disableStartsWithD, scopeDuck, LoggerConfig.disabled()), + // default disabled, enable cat + Arguments.of(enableCat, scopeCat, enabled()), + Arguments.of(enableCat, scopeDog, LoggerConfig.disabled()), + Arguments.of(enableCat, scopeDuck, LoggerConfig.disabled()), + // default disabled, enable pattern + Arguments.of(enableStartsWithD, scopeCat, LoggerConfig.disabled()), + Arguments.of(enableStartsWithD, scopeDog, enabled()), + Arguments.of(enableStartsWithD, scopeDuck, enabled())); + } +} diff --git a/sdk/logs/src/test/java/io/opentelemetry/sdk/logs/SdkLoggerTest.java b/sdk/logs/src/test/java/io/opentelemetry/sdk/logs/SdkLoggerTest.java index f8246dfc0a9..2ea1ee19291 100644 --- a/sdk/logs/src/test/java/io/opentelemetry/sdk/logs/SdkLoggerTest.java +++ b/sdk/logs/src/test/java/io/opentelemetry/sdk/logs/SdkLoggerTest.java @@ -24,6 +24,7 @@ import io.opentelemetry.sdk.common.Clock; import io.opentelemetry.sdk.common.CompletableResultCode; import io.opentelemetry.sdk.common.InstrumentationScopeInfo; +import io.opentelemetry.sdk.logs.internal.LoggerConfig; import io.opentelemetry.sdk.resources.Resource; import java.util.Arrays; import java.util.concurrent.TimeUnit; @@ -44,7 +45,7 @@ void logRecordBuilder() { when(state.getLogRecordProcessor()).thenReturn(logRecordProcessor); when(state.getClock()).thenReturn(clock); - SdkLogger logger = new SdkLogger(state, info); + SdkLogger logger = new SdkLogger(state, info, LoggerConfig.defaultConfig()); LogRecordBuilder logRecordBuilder = logger.logRecordBuilder(); logRecordBuilder.setBody("foo"); diff --git a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkMeter.java b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkMeter.java index bd356b1e8b9..bb76fe6701a 100644 --- a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkMeter.java +++ b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkMeter.java @@ -15,6 +15,7 @@ import io.opentelemetry.api.metrics.ObservableMeasurement; import io.opentelemetry.sdk.common.InstrumentationScopeInfo; import io.opentelemetry.sdk.metrics.data.MetricData; +import io.opentelemetry.sdk.metrics.internal.MeterConfig; import io.opentelemetry.sdk.metrics.internal.export.RegisteredReader; import io.opentelemetry.sdk.metrics.internal.state.CallbackRegistration; import io.opentelemetry.sdk.metrics.internal.state.MeterProviderSharedState; @@ -55,14 +56,17 @@ final class SdkMeter implements Meter { private final InstrumentationScopeInfo instrumentationScopeInfo; private final MeterProviderSharedState meterProviderSharedState; private final MeterSharedState meterSharedState; + private final MeterConfig meterConfig; SdkMeter( MeterProviderSharedState meterProviderSharedState, InstrumentationScopeInfo instrumentationScopeInfo, - List registeredReaders) { + List registeredReaders, + MeterConfig meterConfig) { this.instrumentationScopeInfo = instrumentationScopeInfo; this.meterProviderSharedState = meterProviderSharedState; this.meterSharedState = MeterSharedState.create(instrumentationScopeInfo, registeredReaders); + this.meterConfig = meterConfig; } // Visible for testing @@ -82,34 +86,32 @@ void resetForTest() { @Override public LongCounterBuilder counterBuilder(String name) { - return !checkValidInstrumentName(name) - ? NOOP_METER.counterBuilder(NOOP_INSTRUMENT_NAME) - : new SdkLongCounter.SdkLongCounterBuilder( - meterProviderSharedState, meterSharedState, name); + return meterConfig.isEnabled() && checkValidInstrumentName(name) + ? new SdkLongCounter.SdkLongCounterBuilder(meterProviderSharedState, meterSharedState, name) + : NOOP_METER.counterBuilder(NOOP_INSTRUMENT_NAME); } @Override public LongUpDownCounterBuilder upDownCounterBuilder(String name) { - return !checkValidInstrumentName(name) - ? NOOP_METER.upDownCounterBuilder(NOOP_INSTRUMENT_NAME) - : new SdkLongUpDownCounter.SdkLongUpDownCounterBuilder( - meterProviderSharedState, meterSharedState, name); + return meterConfig.isEnabled() && checkValidInstrumentName(name) + ? new SdkLongUpDownCounter.SdkLongUpDownCounterBuilder( + meterProviderSharedState, meterSharedState, name) + : NOOP_METER.upDownCounterBuilder(NOOP_INSTRUMENT_NAME); } @Override public DoubleHistogramBuilder histogramBuilder(String name) { - return !checkValidInstrumentName(name) - ? NOOP_METER.histogramBuilder(NOOP_INSTRUMENT_NAME) - : new SdkDoubleHistogram.SdkDoubleHistogramBuilder( - meterProviderSharedState, meterSharedState, name); + return meterConfig.isEnabled() && checkValidInstrumentName(name) + ? new SdkDoubleHistogram.SdkDoubleHistogramBuilder( + meterProviderSharedState, meterSharedState, name) + : NOOP_METER.histogramBuilder(NOOP_INSTRUMENT_NAME); } @Override public DoubleGaugeBuilder gaugeBuilder(String name) { - return !checkValidInstrumentName(name) - ? NOOP_METER.gaugeBuilder(NOOP_INSTRUMENT_NAME) - : new SdkDoubleGauge.SdkDoubleGaugeBuilder( - meterProviderSharedState, meterSharedState, name); + return meterConfig.isEnabled() && checkValidInstrumentName(name) + ? new SdkDoubleGauge.SdkDoubleGaugeBuilder(meterProviderSharedState, meterSharedState, name) + : NOOP_METER.gaugeBuilder(NOOP_INSTRUMENT_NAME); } @Override @@ -117,6 +119,9 @@ public BatchCallback batchCallback( Runnable callback, ObservableMeasurement observableMeasurement, ObservableMeasurement... additionalMeasurements) { + if (!meterConfig.isEnabled()) { + return NOOP_METER.batchCallback(callback, observableMeasurement, additionalMeasurements); + } Set measurements = new HashSet<>(); measurements.add(observableMeasurement); Collections.addAll(measurements, additionalMeasurements); diff --git a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkMeterProvider.java b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkMeterProvider.java index 63b241bc5b1..6990ea30cac 100644 --- a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkMeterProvider.java +++ b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkMeterProvider.java @@ -11,11 +11,14 @@ import io.opentelemetry.api.metrics.MeterProvider; import io.opentelemetry.sdk.common.Clock; import io.opentelemetry.sdk.common.CompletableResultCode; +import io.opentelemetry.sdk.common.InstrumentationScopeInfo; import io.opentelemetry.sdk.internal.ComponentRegistry; +import io.opentelemetry.sdk.internal.ScopeConfigurator; import io.opentelemetry.sdk.metrics.data.MetricData; import io.opentelemetry.sdk.metrics.export.CollectionRegistration; import io.opentelemetry.sdk.metrics.export.MetricProducer; import io.opentelemetry.sdk.metrics.export.MetricReader; +import io.opentelemetry.sdk.metrics.internal.MeterConfig; import io.opentelemetry.sdk.metrics.internal.SdkMeterProviderUtil; import io.opentelemetry.sdk.metrics.internal.exemplar.ExemplarFilter; import io.opentelemetry.sdk.metrics.internal.export.CardinalityLimitSelector; @@ -49,6 +52,7 @@ public final class SdkMeterProvider implements MeterProvider, Closeable { private final List metricProducers; private final MeterProviderSharedState sharedState; private final ComponentRegistry registry; + private final ScopeConfigurator meterConfigurator; private final AtomicBoolean isClosed = new AtomicBoolean(false); /** Returns a new {@link SdkMeterProviderBuilder} for {@link SdkMeterProvider}. */ @@ -62,7 +66,8 @@ public static SdkMeterProviderBuilder builder() { List metricProducers, Clock clock, Resource resource, - ExemplarFilter exemplarFilter) { + ExemplarFilter exemplarFilter, + ScopeConfigurator meterConfigurator) { long startEpochNanos = clock.now(); this.registeredViews = registeredViews; this.registeredReaders = @@ -79,7 +84,12 @@ public static SdkMeterProviderBuilder builder() { this.registry = new ComponentRegistry<>( instrumentationLibraryInfo -> - new SdkMeter(sharedState, instrumentationLibraryInfo, registeredReaders)); + new SdkMeter( + sharedState, + instrumentationLibraryInfo, + registeredReaders, + getMeterConfig(instrumentationLibraryInfo))); + this.meterConfigurator = meterConfigurator; for (RegisteredReader registeredReader : registeredReaders) { List readerMetricProducers = new ArrayList<>(metricProducers); readerMetricProducers.add(new LeasedMetricProducer(registry, sharedState, registeredReader)); @@ -90,6 +100,11 @@ public static SdkMeterProviderBuilder builder() { } } + private MeterConfig getMeterConfig(InstrumentationScopeInfo instrumentationScopeInfo) { + MeterConfig meterConfig = meterConfigurator.apply(instrumentationScopeInfo); + return meterConfig == null ? MeterConfig.defaultConfig() : meterConfig; + } + @Override public MeterBuilder meterBuilder(String instrumentationScopeName) { if (registeredReaders.isEmpty()) { diff --git a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkMeterProviderBuilder.java b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkMeterProviderBuilder.java index 3e444f10f93..9317c26e6c9 100644 --- a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkMeterProviderBuilder.java +++ b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkMeterProviderBuilder.java @@ -6,8 +6,12 @@ package io.opentelemetry.sdk.metrics; import io.opentelemetry.sdk.common.Clock; +import io.opentelemetry.sdk.common.InstrumentationScopeInfo; +import io.opentelemetry.sdk.internal.ScopeConfigurator; +import io.opentelemetry.sdk.internal.ScopeConfiguratorBuilder; import io.opentelemetry.sdk.metrics.export.MetricProducer; import io.opentelemetry.sdk.metrics.export.MetricReader; +import io.opentelemetry.sdk.metrics.internal.MeterConfig; import io.opentelemetry.sdk.metrics.internal.SdkMeterProviderUtil; import io.opentelemetry.sdk.metrics.internal.debug.SourceInfo; import io.opentelemetry.sdk.metrics.internal.exemplar.ExemplarFilter; @@ -18,6 +22,7 @@ import java.util.IdentityHashMap; import java.util.List; import java.util.Objects; +import java.util.function.Predicate; /** * Builder class for the {@link SdkMeterProvider}. @@ -40,6 +45,8 @@ public final class SdkMeterProviderBuilder { private final List metricProducers = new ArrayList<>(); private final List registeredViews = new ArrayList<>(); private ExemplarFilter exemplarFilter = DEFAULT_EXEMPLAR_FILTER; + private ScopeConfiguratorBuilder meterConfiguratorBuilder = + MeterConfig.configuratorBuilder(); SdkMeterProviderBuilder() {} @@ -150,9 +157,48 @@ public SdkMeterProviderBuilder registerMetricProducer(MetricProducer metricProdu return this; } + /** + * Set the meter configurator, which computes {@link MeterConfig} for each {@link + * InstrumentationScopeInfo}. + * + *

      Overrides any matchers added via {@link #addMeterConfiguratorCondition(Predicate, + * MeterConfig)}. + * + * @see MeterConfig#configuratorBuilder() + */ + SdkMeterProviderBuilder setMeterConfigurator(ScopeConfigurator meterConfigurator) { + this.meterConfiguratorBuilder = meterConfigurator.toBuilder(); + return this; + } + + /** + * Adds a condition to the meter configurator, which computes {@link MeterConfig} for each {@link + * InstrumentationScopeInfo}. + * + *

      Applies after any previously added conditions. + * + *

      If {@link #setMeterConfigurator(ScopeConfigurator)} was previously called, this condition + * will only be applied if the {@link ScopeConfigurator#apply(Object)} returns null for the + * matched {@link InstrumentationScopeInfo}(s). + * + * @see ScopeConfiguratorBuilder#nameEquals(String) + * @see ScopeConfiguratorBuilder#nameMatchesGlob(String) + */ + SdkMeterProviderBuilder addMeterConfiguratorCondition( + Predicate scopeMatcher, MeterConfig meterConfig) { + this.meterConfiguratorBuilder.addCondition(scopeMatcher, meterConfig); + return this; + } + /** Returns an {@link SdkMeterProvider} built with the configuration of this builder. */ public SdkMeterProvider build() { return new SdkMeterProvider( - registeredViews, metricReaders, metricProducers, clock, resource, exemplarFilter); + registeredViews, + metricReaders, + metricProducers, + clock, + resource, + exemplarFilter, + meterConfiguratorBuilder.build()); } } diff --git a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/MeterConfig.java b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/MeterConfig.java new file mode 100644 index 00000000000..12d2c1df1b1 --- /dev/null +++ b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/MeterConfig.java @@ -0,0 +1,62 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.sdk.metrics.internal; + +import com.google.auto.value.AutoValue; +import io.opentelemetry.api.metrics.Meter; +import io.opentelemetry.sdk.common.InstrumentationScopeInfo; +import io.opentelemetry.sdk.internal.ScopeConfigurator; +import io.opentelemetry.sdk.internal.ScopeConfiguratorBuilder; +import io.opentelemetry.sdk.metrics.SdkMeterProviderBuilder; +import java.util.function.Predicate; +import javax.annotation.concurrent.Immutable; + +/** + * A collection of configuration options which define the behavior of a {@link Meter}. + * + * @see SdkMeterProviderUtil#setMeterConfigurator(SdkMeterProviderBuilder, ScopeConfigurator) + * @see SdkMeterProviderUtil#addMeterConfiguratorCondition(SdkMeterProviderBuilder, Predicate, + * MeterConfig) + */ +@AutoValue +@Immutable +public abstract class MeterConfig { + + private static final MeterConfig DEFAULT_CONFIG = new AutoValue_MeterConfig(/* enabled= */ true); + private static final MeterConfig DISABLED_CONFIG = + new AutoValue_MeterConfig(/* enabled= */ false); + + /** Returns a disabled {@link MeterConfig}. */ + public static MeterConfig disabled() { + return DISABLED_CONFIG; + } + + /** Returns an enabled {@link MeterConfig}. */ + public static MeterConfig enabled() { + return DEFAULT_CONFIG; + } + + /** + * Returns the default {@link MeterConfig}, which is used when no configurator is set or when the + * meter configurator returns {@code null} for a {@link InstrumentationScopeInfo}. + */ + public static MeterConfig defaultConfig() { + return DEFAULT_CONFIG; + } + + /** + * Create a {@link ScopeConfiguratorBuilder} for configuring {@link + * SdkMeterProviderUtil#setMeterConfigurator(SdkMeterProviderBuilder, ScopeConfigurator)}. + */ + public static ScopeConfiguratorBuilder configuratorBuilder() { + return ScopeConfigurator.builder(); + } + + MeterConfig() {} + + /** Returns {@code true} if this meter is enabled. Defaults to {@code true}. */ + public abstract boolean isEnabled(); +} diff --git a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/SdkMeterProviderUtil.java b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/SdkMeterProviderUtil.java index ecaf5e388ca..e27856881e1 100644 --- a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/SdkMeterProviderUtil.java +++ b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/SdkMeterProviderUtil.java @@ -5,6 +5,8 @@ package io.opentelemetry.sdk.metrics.internal; +import io.opentelemetry.sdk.common.InstrumentationScopeInfo; +import io.opentelemetry.sdk.internal.ScopeConfigurator; import io.opentelemetry.sdk.metrics.SdkMeterProvider; import io.opentelemetry.sdk.metrics.SdkMeterProviderBuilder; import io.opentelemetry.sdk.metrics.ViewBuilder; @@ -18,8 +20,11 @@ import java.util.function.Predicate; /** - * This class is internal and is hence not for public use. Its APIs are unstable and can change at - * any time. + * A collection of methods that allow use of experimental features prior to availability in public + * APIs. + * + *

      This class is internal and is hence not for public use. Its APIs are unstable and can change + * at any time. */ public final class SdkMeterProviderUtil { @@ -66,6 +71,39 @@ public static void registerMetricReaderWithCardinalitySelector( } } + /** Reflectively set the {@link ScopeConfigurator} to the {@link SdkMeterProviderBuilder}. */ + public static void setMeterConfigurator( + SdkMeterProviderBuilder sdkMeterProviderBuilder, + ScopeConfigurator meterConfigurator) { + try { + Method method = + SdkMeterProviderBuilder.class.getDeclaredMethod( + "setMeterConfigurator", ScopeConfigurator.class); + method.setAccessible(true); + method.invoke(sdkMeterProviderBuilder, meterConfigurator); + } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) { + throw new IllegalStateException( + "Error calling setMeterConfigurator on SdkMeterProviderBuilder", e); + } + } + + /** Reflectively add a tracer configurator condition to the {@link SdkMeterProviderBuilder}. */ + public static void addMeterConfiguratorCondition( + SdkMeterProviderBuilder sdkMeterProviderBuilder, + Predicate scopeMatcher, + MeterConfig meterConfig) { + try { + Method method = + SdkMeterProviderBuilder.class.getDeclaredMethod( + "addMeterConfiguratorCondition", Predicate.class, MeterConfig.class); + method.setAccessible(true); + method.invoke(sdkMeterProviderBuilder, scopeMatcher, meterConfig); + } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) { + throw new IllegalStateException( + "Error calling addMeterConfiguratorCondition on SdkMeterProviderBuilder", e); + } + } + /** * Reflectively add an {@link AttributesProcessor} to the {@link ViewBuilder} which appends * key-values from baggage to all measurements. diff --git a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/state/MeterProviderSharedState.java b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/state/MeterProviderSharedState.java index 9b185b36a84..8f3647c6d46 100644 --- a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/state/MeterProviderSharedState.java +++ b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/state/MeterProviderSharedState.java @@ -21,9 +21,12 @@ @AutoValue @Immutable public abstract class MeterProviderSharedState { + public static MeterProviderSharedState create( Clock clock, Resource resource, ExemplarFilter exemplarFilter, long startEpochNanos) { - return new AutoValue_MeterProviderSharedState(clock, resource, startEpochNanos, exemplarFilter); + MeterProviderSharedState sharedState = + new AutoValue_MeterProviderSharedState(clock, resource, startEpochNanos, exemplarFilter); + return sharedState; } MeterProviderSharedState() {} diff --git a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/view/ViewRegistry.java b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/view/ViewRegistry.java index 9e5bba37233..4df9f1a35ec 100644 --- a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/view/ViewRegistry.java +++ b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/view/ViewRegistry.java @@ -9,6 +9,7 @@ import static java.util.Objects.requireNonNull; import io.opentelemetry.sdk.common.InstrumentationScopeInfo; +import io.opentelemetry.sdk.internal.GlobUtil; import io.opentelemetry.sdk.metrics.Aggregation; import io.opentelemetry.sdk.metrics.InstrumentSelector; import io.opentelemetry.sdk.metrics.InstrumentType; @@ -27,10 +28,8 @@ import java.util.HashMap; import java.util.List; import java.util.Map; -import java.util.function.Predicate; import java.util.logging.Level; import java.util.logging.Logger; -import java.util.regex.Pattern; import javax.annotation.concurrent.Immutable; /** @@ -170,7 +169,8 @@ private static boolean matchesSelector( return false; } if (selector.getInstrumentName() != null - && !toGlobPatternPredicate(selector.getInstrumentName()).test(descriptor.getName())) { + && !GlobUtil.toGlobPatternPredicate(selector.getInstrumentName()) + .test(descriptor.getName())) { return false; } return matchesMeter(selector, meterScope); @@ -190,69 +190,6 @@ private static boolean matchesMeter( || selector.getMeterSchemaUrl().equals(meterScope.getSchemaUrl()); } - /** - * Return a predicate that returns {@code true} if a string matches the {@code globPattern}. - * - *

      {@code globPattern} may contain the wildcard characters {@code *} and {@code ?} with the - * following matching criteria: - * - *

        - *
      • {@code *} matches 0 or more instances of any character - *
      • {@code ?} matches exactly one instance of any character - *
      - */ - // Visible for testing - static Predicate toGlobPatternPredicate(String globPattern) { - // Match all - if (globPattern.equals("*")) { - return unused -> true; - } - - // If globPattern contains '*' or '?', convert it to a regex and return corresponding predicate - for (int i = 0; i < globPattern.length(); i++) { - char c = globPattern.charAt(i); - if (c == '*' || c == '?') { - Pattern pattern = toRegexPattern(globPattern); - return string -> pattern.matcher(string).matches(); - } - } - - // Exact match, ignoring case - return globPattern::equalsIgnoreCase; - } - - /** - * Transform the {@code globPattern} to a regex by converting {@code *} to {@code .*}, {@code ?} - * to {@code .}, and escaping other regex special characters. - */ - private static Pattern toRegexPattern(String globPattern) { - int tokenStart = -1; - StringBuilder patternBuilder = new StringBuilder(); - for (int i = 0; i < globPattern.length(); i++) { - char c = globPattern.charAt(i); - if (c == '*' || c == '?') { - if (tokenStart != -1) { - patternBuilder.append(Pattern.quote(globPattern.substring(tokenStart, i))); - tokenStart = -1; - } - if (c == '*') { - patternBuilder.append(".*"); - } else { - // c == '?' - patternBuilder.append("."); - } - } else { - if (tokenStart == -1) { - tokenStart = i; - } - } - } - if (tokenStart != -1) { - patternBuilder.append(Pattern.quote(globPattern.substring(tokenStart))); - } - return Pattern.compile(patternBuilder.toString()); - } - private static RegisteredView applyAdviceToDefaultView( RegisteredView instrumentDefaultView, Advice advice) { return RegisteredView.create( diff --git a/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/MeterConfigTest.java b/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/MeterConfigTest.java new file mode 100644 index 00000000000..3b78f2abd0d --- /dev/null +++ b/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/MeterConfigTest.java @@ -0,0 +1,148 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.sdk.metrics; + +import static io.opentelemetry.sdk.internal.ScopeConfiguratorBuilder.nameEquals; +import static io.opentelemetry.sdk.internal.ScopeConfiguratorBuilder.nameMatchesGlob; +import static io.opentelemetry.sdk.metrics.internal.MeterConfig.defaultConfig; +import static io.opentelemetry.sdk.metrics.internal.MeterConfig.disabled; +import static io.opentelemetry.sdk.metrics.internal.MeterConfig.enabled; +import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.assertThat; + +import io.opentelemetry.api.metrics.Meter; +import io.opentelemetry.sdk.common.InstrumentationScopeInfo; +import io.opentelemetry.sdk.internal.ScopeConfigurator; +import io.opentelemetry.sdk.metrics.data.MetricData; +import io.opentelemetry.sdk.metrics.internal.MeterConfig; +import io.opentelemetry.sdk.testing.exporter.InMemoryMetricReader; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; +import java.util.stream.Stream; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; + +class MeterConfigTest { + + @Test + void disableScopes() { + InMemoryMetricReader reader = InMemoryMetricReader.create(); + SdkMeterProvider meterProvider = + SdkMeterProvider.builder() + // Disable meterB. Since meters are enabled by default, meterA and meterC are enabled. + .addMeterConfiguratorCondition(nameEquals("meterB"), disabled()) + .registerMetricReader(reader) + .build(); + + Meter meterA = meterProvider.get("meterA"); + Meter meterB = meterProvider.get("meterB"); + Meter meterC = meterProvider.get("meterC"); + + meterA.counterBuilder("counterA").build().add(1); + meterA.counterBuilder("asyncCounterA").buildWithCallback(observable -> observable.record(1)); + meterA.upDownCounterBuilder("upDownCounterA").build().add(1); + meterA + .upDownCounterBuilder("asyncUpDownCounterA") + .buildWithCallback(observable -> observable.record(1)); + meterA.histogramBuilder("histogramA").build().record(1.0); + meterA.gaugeBuilder("gaugeA").buildWithCallback(observable -> observable.record(1.0)); + + meterB.counterBuilder("counterB").build().add(1); + meterB.counterBuilder("asyncCounterB").buildWithCallback(observable -> observable.record(1)); + meterB.upDownCounterBuilder("upDownCounterB").build().add(1); + meterB + .upDownCounterBuilder("asyncUpDownCounterB") + .buildWithCallback(observable -> observable.record(1)); + meterB.histogramBuilder("histogramB").build().record(1.0); + meterB.gaugeBuilder("gaugeB").buildWithCallback(observable -> observable.record(1.0)); + + meterC.counterBuilder("counterC").build().add(1); + meterC.counterBuilder("asyncCounterC").buildWithCallback(observable -> observable.record(1)); + meterC.upDownCounterBuilder("upDownCounterC").build().add(1); + meterC + .upDownCounterBuilder("asyncUpDownCounterC") + .buildWithCallback(observable -> observable.record(1)); + meterC.histogramBuilder("histogramC").build().record(1.0); + meterC.gaugeBuilder("gaugeC").buildWithCallback(observable -> observable.record(1.0)); + + // Only metrics from meterA and meterC should be seen + assertThat(reader.collectAllMetrics()) + .satisfies( + metrics -> { + Map> metricsByScope = + metrics.stream() + .collect(Collectors.groupingBy(MetricData::getInstrumentationScopeInfo)); + assertThat(metricsByScope.get(InstrumentationScopeInfo.create("meterA"))).hasSize(6); + assertThat(metricsByScope.get(InstrumentationScopeInfo.create("meterB"))).isNull(); + assertThat(metricsByScope.get(InstrumentationScopeInfo.create("meterC"))).hasSize(6); + }); + } + + @ParameterizedTest + @MethodSource("meterConfiguratorArgs") + void meterConfigurator( + ScopeConfigurator meterConfigurator, + InstrumentationScopeInfo scope, + MeterConfig expectedMeterConfig) { + MeterConfig meterConfig = meterConfigurator.apply(scope); + meterConfig = meterConfig == null ? defaultConfig() : meterConfig; + assertThat(meterConfig).isEqualTo(expectedMeterConfig); + } + + private static final InstrumentationScopeInfo scopeCat = InstrumentationScopeInfo.create("cat"); + private static final InstrumentationScopeInfo scopeDog = InstrumentationScopeInfo.create("dog"); + private static final InstrumentationScopeInfo scopeDuck = InstrumentationScopeInfo.create("duck"); + + private static Stream meterConfiguratorArgs() { + ScopeConfigurator defaultConfigurator = MeterConfig.configuratorBuilder().build(); + ScopeConfigurator disableCat = + MeterConfig.configuratorBuilder() + .addCondition(nameEquals("cat"), MeterConfig.disabled()) + // Second matching rule for cat should be ignored + .addCondition(nameEquals("cat"), enabled()) + .build(); + ScopeConfigurator disableStartsWithD = + MeterConfig.configuratorBuilder() + .addCondition(nameMatchesGlob("d*"), MeterConfig.disabled()) + .build(); + ScopeConfigurator enableCat = + MeterConfig.configuratorBuilder() + .setDefault(MeterConfig.disabled()) + .addCondition(nameEquals("cat"), enabled()) + // Second matching rule for cat should be ignored + .addCondition(nameEquals("cat"), MeterConfig.disabled()) + .build(); + ScopeConfigurator enableStartsWithD = + MeterConfig.configuratorBuilder() + .setDefault(MeterConfig.disabled()) + .addCondition(nameMatchesGlob("d*"), MeterConfig.enabled()) + .build(); + + return Stream.of( + // default + Arguments.of(defaultConfigurator, scopeCat, defaultConfig()), + Arguments.of(defaultConfigurator, scopeDog, defaultConfig()), + Arguments.of(defaultConfigurator, scopeDuck, defaultConfig()), + // default enabled, disable cat + Arguments.of(disableCat, scopeCat, MeterConfig.disabled()), + Arguments.of(disableCat, scopeDog, enabled()), + Arguments.of(disableCat, scopeDuck, enabled()), + // default enabled, disable pattern + Arguments.of(disableStartsWithD, scopeCat, enabled()), + Arguments.of(disableStartsWithD, scopeDog, MeterConfig.disabled()), + Arguments.of(disableStartsWithD, scopeDuck, MeterConfig.disabled()), + // default disabled, enable cat + Arguments.of(enableCat, scopeCat, enabled()), + Arguments.of(enableCat, scopeDog, MeterConfig.disabled()), + Arguments.of(enableCat, scopeDuck, MeterConfig.disabled()), + // default disabled, enable pattern + Arguments.of(enableStartsWithD, scopeCat, MeterConfig.disabled()), + Arguments.of(enableStartsWithD, scopeDog, enabled()), + Arguments.of(enableStartsWithD, scopeDuck, enabled())); + } +} diff --git a/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/internal/view/ViewRegistryTest.java b/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/internal/view/ViewRegistryTest.java index abba1c32133..d2f5925873c 100644 --- a/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/internal/view/ViewRegistryTest.java +++ b/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/internal/view/ViewRegistryTest.java @@ -7,7 +7,6 @@ import static io.opentelemetry.api.common.AttributeKey.stringKey; import static io.opentelemetry.sdk.metrics.internal.view.ViewRegistry.DEFAULT_REGISTERED_VIEW; -import static io.opentelemetry.sdk.metrics.internal.view.ViewRegistry.toGlobPatternPredicate; import static org.assertj.core.api.Assertions.assertThat; import io.github.netmikey.logunit.api.LogCapturer; @@ -544,26 +543,4 @@ void findViews_ApplyAdvice() { INSTRUMENTATION_SCOPE_INFO)) .isEqualTo(Collections.singletonList(DEFAULT_REGISTERED_VIEW)); } - - @Test - void matchesName() { - assertThat(toGlobPatternPredicate("foo").test("foo")).isTrue(); - assertThat(toGlobPatternPredicate("foo").test("Foo")).isTrue(); - assertThat(toGlobPatternPredicate("foo").test("bar")).isFalse(); - assertThat(toGlobPatternPredicate("fo?").test("foo")).isTrue(); - assertThat(toGlobPatternPredicate("fo??").test("fooo")).isTrue(); - assertThat(toGlobPatternPredicate("fo?").test("fob")).isTrue(); - assertThat(toGlobPatternPredicate("fo?").test("fooo")).isFalse(); - assertThat(toGlobPatternPredicate("*").test("foo")).isTrue(); - assertThat(toGlobPatternPredicate("*").test("bar")).isTrue(); - assertThat(toGlobPatternPredicate("*").test("baz")).isTrue(); - assertThat(toGlobPatternPredicate("*").test("foo.bar.baz")).isTrue(); - assertThat(toGlobPatternPredicate("fo*").test("fo")).isTrue(); - assertThat(toGlobPatternPredicate("fo*").test("foo")).isTrue(); - assertThat(toGlobPatternPredicate("fo*").test("fooo")).isTrue(); - assertThat(toGlobPatternPredicate("fo*").test("foo.bar.baz")).isTrue(); - assertThat(toGlobPatternPredicate("f()[]$^.{}|").test("f()[]$^.{}|")).isTrue(); - assertThat(toGlobPatternPredicate("f()[]$^.{}|?").test("f()[]$^.{}|o")).isTrue(); - assertThat(toGlobPatternPredicate("f()[]$^.{}|*").test("f()[]$^.{}|ooo")).isTrue(); - } } diff --git a/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/SdkTracer.java b/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/SdkTracer.java index 81282097cd1..a0b2704fc72 100644 --- a/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/SdkTracer.java +++ b/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/SdkTracer.java @@ -9,21 +9,31 @@ import io.opentelemetry.api.trace.Tracer; import io.opentelemetry.api.trace.TracerProvider; import io.opentelemetry.sdk.common.InstrumentationScopeInfo; +import io.opentelemetry.sdk.trace.internal.TracerConfig; /** {@link SdkTracer} is SDK implementation of {@link Tracer}. */ final class SdkTracer implements Tracer { static final String FALLBACK_SPAN_NAME = ""; + private static final Tracer NOOP_TRACER = TracerProvider.noop().get("noop"); private final TracerSharedState sharedState; private final InstrumentationScopeInfo instrumentationScopeInfo; + private final TracerConfig tracerConfig; - SdkTracer(TracerSharedState sharedState, InstrumentationScopeInfo instrumentationScopeInfo) { + SdkTracer( + TracerSharedState sharedState, + InstrumentationScopeInfo instrumentationScopeInfo, + TracerConfig tracerConfig) { this.sharedState = sharedState; this.instrumentationScopeInfo = instrumentationScopeInfo; + this.tracerConfig = tracerConfig; } @Override public SpanBuilder spanBuilder(String spanName) { + if (!tracerConfig.isEnabled()) { + return NOOP_TRACER.spanBuilder(spanName); + } if (spanName == null || spanName.trim().isEmpty()) { spanName = FALLBACK_SPAN_NAME; } diff --git a/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/SdkTracerProvider.java b/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/SdkTracerProvider.java index 2e07af579a9..036e812c5ab 100644 --- a/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/SdkTracerProvider.java +++ b/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/SdkTracerProvider.java @@ -10,8 +10,11 @@ import io.opentelemetry.api.trace.TracerProvider; import io.opentelemetry.sdk.common.Clock; import io.opentelemetry.sdk.common.CompletableResultCode; +import io.opentelemetry.sdk.common.InstrumentationScopeInfo; import io.opentelemetry.sdk.internal.ComponentRegistry; +import io.opentelemetry.sdk.internal.ScopeConfigurator; import io.opentelemetry.sdk.resources.Resource; +import io.opentelemetry.sdk.trace.internal.TracerConfig; import io.opentelemetry.sdk.trace.samplers.Sampler; import java.io.Closeable; import java.util.List; @@ -27,6 +30,7 @@ public final class SdkTracerProvider implements TracerProvider, Closeable { static final String DEFAULT_TRACER_NAME = ""; private final TracerSharedState sharedState; private final ComponentRegistry tracerSdkComponentRegistry; + private final ScopeConfigurator tracerConfigurator; /** * Returns a new {@link SdkTracerProviderBuilder} for {@link SdkTracerProvider}. @@ -37,19 +41,31 @@ public static SdkTracerProviderBuilder builder() { return new SdkTracerProviderBuilder(); } + @SuppressWarnings("NonApiType") SdkTracerProvider( Clock clock, IdGenerator idsGenerator, Resource resource, Supplier spanLimitsSupplier, Sampler sampler, - List spanProcessors) { + List spanProcessors, + ScopeConfigurator tracerConfigurator) { this.sharedState = new TracerSharedState( clock, idsGenerator, resource, spanLimitsSupplier, sampler, spanProcessors); this.tracerSdkComponentRegistry = new ComponentRegistry<>( - instrumentationScopeInfo -> new SdkTracer(sharedState, instrumentationScopeInfo)); + instrumentationScopeInfo -> + new SdkTracer( + sharedState, + instrumentationScopeInfo, + getTracerConfig(instrumentationScopeInfo))); + this.tracerConfigurator = tracerConfigurator; + } + + private TracerConfig getTracerConfig(InstrumentationScopeInfo instrumentationScopeInfo) { + TracerConfig tracerConfig = tracerConfigurator.apply(instrumentationScopeInfo); + return tracerConfig == null ? TracerConfig.defaultConfig() : tracerConfig; } @Override diff --git a/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/SdkTracerProviderBuilder.java b/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/SdkTracerProviderBuilder.java index 20dd76536d5..f84c7f79855 100644 --- a/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/SdkTracerProviderBuilder.java +++ b/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/SdkTracerProviderBuilder.java @@ -8,11 +8,16 @@ import static java.util.Objects.requireNonNull; import io.opentelemetry.sdk.common.Clock; +import io.opentelemetry.sdk.common.InstrumentationScopeInfo; +import io.opentelemetry.sdk.internal.ScopeConfigurator; +import io.opentelemetry.sdk.internal.ScopeConfiguratorBuilder; import io.opentelemetry.sdk.resources.Resource; +import io.opentelemetry.sdk.trace.internal.TracerConfig; import io.opentelemetry.sdk.trace.samplers.Sampler; import java.util.ArrayList; import java.util.List; import java.util.Objects; +import java.util.function.Predicate; import java.util.function.Supplier; /** Builder of {@link SdkTracerProvider}. */ @@ -26,6 +31,8 @@ public final class SdkTracerProviderBuilder { private Resource resource = Resource.getDefault(); private Supplier spanLimitsSupplier = SpanLimits::getDefault; private Sampler sampler = DEFAULT_SAMPLER; + private ScopeConfiguratorBuilder tracerConfiguratorBuilder = + TracerConfig.configuratorBuilder(); /** * Assign a {@link Clock}. {@link Clock} will be used each time a {@link @@ -147,6 +154,40 @@ public SdkTracerProviderBuilder addSpanProcessor(SpanProcessor spanProcessor) { return this; } + /** + * Set the tracer configurator, which computes {@link TracerConfig} for each {@link + * InstrumentationScopeInfo}. + * + *

      Overrides any matchers added via {@link #addTracerConfiguratorCondition(Predicate, + * TracerConfig)}. + * + * @see TracerConfig#configuratorBuilder() + */ + SdkTracerProviderBuilder setTracerConfigurator( + ScopeConfigurator tracerConfigurator) { + this.tracerConfiguratorBuilder = tracerConfigurator.toBuilder(); + return this; + } + + /** + * Adds a condition to the tracer configurator, which computes {@link TracerConfig} for each + * {@link InstrumentationScopeInfo}. + * + *

      Applies after any previously added conditions. + * + *

      If {@link #setTracerConfigurator(ScopeConfigurator)} was previously called, this condition + * will only be applied if the {@link ScopeConfigurator#apply(Object)} returns null for the + * matched {@link InstrumentationScopeInfo}(s). + * + * @see ScopeConfiguratorBuilder#nameEquals(String) + * @see ScopeConfiguratorBuilder#nameMatchesGlob(String) + */ + SdkTracerProviderBuilder addTracerConfiguratorCondition( + Predicate scopeMatcher, TracerConfig tracerConfig) { + this.tracerConfiguratorBuilder.addCondition(scopeMatcher, tracerConfig); + return this; + } + /** * Create a new {@link SdkTracerProvider} instance with the configuration. * @@ -154,7 +195,13 @@ public SdkTracerProviderBuilder addSpanProcessor(SpanProcessor spanProcessor) { */ public SdkTracerProvider build() { return new SdkTracerProvider( - clock, idsGenerator, resource, spanLimitsSupplier, sampler, spanProcessors); + clock, + idsGenerator, + resource, + spanLimitsSupplier, + sampler, + spanProcessors, + tracerConfiguratorBuilder.build()); } SdkTracerProviderBuilder() {} diff --git a/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/TracerSharedState.java b/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/TracerSharedState.java index 99cd1ea26c0..3d07a2853f8 100644 --- a/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/TracerSharedState.java +++ b/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/TracerSharedState.java @@ -15,6 +15,7 @@ // Represents the shared state/config between all Tracers created by the same TracerProvider. final class TracerSharedState { + private final Object lock = new Object(); private final Clock clock; private final IdGenerator idGenerator; diff --git a/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/internal/SdkTracerProviderUtil.java b/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/internal/SdkTracerProviderUtil.java new file mode 100644 index 00000000000..7d00f230dea --- /dev/null +++ b/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/internal/SdkTracerProviderUtil.java @@ -0,0 +1,58 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.sdk.trace.internal; + +import io.opentelemetry.sdk.common.InstrumentationScopeInfo; +import io.opentelemetry.sdk.internal.ScopeConfigurator; +import io.opentelemetry.sdk.trace.SdkTracerProviderBuilder; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.function.Predicate; + +/** + * A collection of methods that allow use of experimental features prior to availability in public + * APIs. + * + *

      This class is internal and is hence not for public use. Its APIs are unstable and can change + * at any time. + */ +public final class SdkTracerProviderUtil { + + private SdkTracerProviderUtil() {} + + /** Reflectively set the {@link ScopeConfigurator} to the {@link SdkTracerProviderBuilder}. */ + public static void setTracerConfigurator( + SdkTracerProviderBuilder sdkTracerProviderBuilder, + ScopeConfigurator tracerConfigurator) { + try { + Method method = + SdkTracerProviderBuilder.class.getDeclaredMethod( + "setTracerConfigurator", ScopeConfigurator.class); + method.setAccessible(true); + method.invoke(sdkTracerProviderBuilder, tracerConfigurator); + } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) { + throw new IllegalStateException( + "Error calling setTracerConfigurator on SdkTracerProviderBuilder", e); + } + } + + /** Reflectively add a tracer configurator condition to the {@link SdkTracerProviderBuilder}. */ + public static void addTracerConfiguratorCondition( + SdkTracerProviderBuilder sdkTracerProviderBuilder, + Predicate scopeMatcher, + TracerConfig tracerConfig) { + try { + Method method = + SdkTracerProviderBuilder.class.getDeclaredMethod( + "addTracerConfiguratorCondition", Predicate.class, TracerConfig.class); + method.setAccessible(true); + method.invoke(sdkTracerProviderBuilder, scopeMatcher, tracerConfig); + } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) { + throw new IllegalStateException( + "Error calling addTracerConfiguratorCondition on SdkTracerProviderBuilder", e); + } + } +} diff --git a/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/internal/TracerConfig.java b/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/internal/TracerConfig.java new file mode 100644 index 00000000000..d019055b36a --- /dev/null +++ b/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/internal/TracerConfig.java @@ -0,0 +1,63 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.sdk.trace.internal; + +import com.google.auto.value.AutoValue; +import io.opentelemetry.api.trace.Tracer; +import io.opentelemetry.sdk.common.InstrumentationScopeInfo; +import io.opentelemetry.sdk.internal.ScopeConfigurator; +import io.opentelemetry.sdk.internal.ScopeConfiguratorBuilder; +import io.opentelemetry.sdk.trace.SdkTracerProviderBuilder; +import java.util.function.Predicate; +import javax.annotation.concurrent.Immutable; + +/** + * A collection of configuration options which define the behavior of a {@link Tracer}. + * + * @see SdkTracerProviderUtil#setTracerConfigurator(SdkTracerProviderBuilder, ScopeConfigurator) + * @see SdkTracerProviderUtil#addTracerConfiguratorCondition(SdkTracerProviderBuilder, Predicate, + * TracerConfig) + */ +@AutoValue +@Immutable +public abstract class TracerConfig { + + private static final TracerConfig DEFAULT_CONFIG = + new AutoValue_TracerConfig(/* enabled= */ true); + private static final TracerConfig DISABLED_CONFIG = + new AutoValue_TracerConfig(/* enabled= */ false); + + /** Returns a disabled {@link TracerConfig}. */ + public static TracerConfig disabled() { + return DISABLED_CONFIG; + } + + /** Returns an enabled {@link TracerConfig}. */ + public static TracerConfig enabled() { + return DEFAULT_CONFIG; + } + + /** + * Returns the default {@link TracerConfig}, which is used when no configurator is set or when the + * tracer configurator returns {@code null} for a {@link InstrumentationScopeInfo}. + */ + public static TracerConfig defaultConfig() { + return DEFAULT_CONFIG; + } + + /** + * Create a {@link ScopeConfiguratorBuilder} for configuring {@link + * SdkTracerProviderUtil#setTracerConfigurator(SdkTracerProviderBuilder, ScopeConfigurator)}. + */ + public static ScopeConfiguratorBuilder configuratorBuilder() { + return ScopeConfigurator.builder(); + } + + TracerConfig() {} + + /** Returns {@code true} if this tracer is enabled. Defaults to {@code true}. */ + public abstract boolean isEnabled(); +} diff --git a/sdk/trace/src/test/java/io/opentelemetry/sdk/trace/TracerConfigTest.java b/sdk/trace/src/test/java/io/opentelemetry/sdk/trace/TracerConfigTest.java new file mode 100644 index 00000000000..4df99b4c999 --- /dev/null +++ b/sdk/trace/src/test/java/io/opentelemetry/sdk/trace/TracerConfigTest.java @@ -0,0 +1,156 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.sdk.trace; + +import static io.opentelemetry.sdk.internal.ScopeConfiguratorBuilder.nameEquals; +import static io.opentelemetry.sdk.internal.ScopeConfiguratorBuilder.nameMatchesGlob; +import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.assertThat; +import static io.opentelemetry.sdk.trace.internal.TracerConfig.defaultConfig; +import static io.opentelemetry.sdk.trace.internal.TracerConfig.disabled; +import static io.opentelemetry.sdk.trace.internal.TracerConfig.enabled; + +import io.opentelemetry.api.common.Attributes; +import io.opentelemetry.api.trace.Span; +import io.opentelemetry.api.trace.SpanId; +import io.opentelemetry.api.trace.Tracer; +import io.opentelemetry.context.Scope; +import io.opentelemetry.sdk.common.InstrumentationScopeInfo; +import io.opentelemetry.sdk.internal.ScopeConfigurator; +import io.opentelemetry.sdk.testing.exporter.InMemorySpanExporter; +import io.opentelemetry.sdk.trace.export.SimpleSpanProcessor; +import io.opentelemetry.sdk.trace.internal.TracerConfig; +import java.util.stream.Stream; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; + +class TracerConfigTest { + + @Test + void disableScopes() throws InterruptedException { + InMemorySpanExporter exporter = InMemorySpanExporter.create(); + SdkTracerProvider tracerProvider = + SdkTracerProvider.builder() + // Disable tracerB. Since tracers are enabled by default, tracerA and tracerC are + // enabled. + .addTracerConfiguratorCondition(nameEquals("tracerB"), disabled()) + .addSpanProcessor(SimpleSpanProcessor.create(exporter)) + .build(); + + Tracer tracerA = tracerProvider.get("tracerA"); + Tracer tracerB = tracerProvider.get("tracerB"); + Tracer tracerC = tracerProvider.get("tracerC"); + + Span parent; + Span child; + Span grandchild; + + parent = tracerA.spanBuilder("parent").startSpan(); + try (Scope parentScope = parent.makeCurrent()) { + parent.setAttribute("a", "1"); + child = tracerB.spanBuilder("child").startSpan(); + // tracerB is disabled and should behave the same as noop tracer + assertThat(child.getSpanContext()).isEqualTo(parent.getSpanContext()); + assertThat(child.isRecording()).isFalse(); + try (Scope childScope = child.makeCurrent()) { + child.setAttribute("b", "1"); + grandchild = tracerC.spanBuilder("grandchild").startSpan(); + try (Scope grandchildScope = grandchild.makeCurrent()) { + grandchild.setAttribute("c", "1"); + Thread.sleep(100); + } finally { + grandchild.end(); + } + } finally { + child.end(); + } + } finally { + parent.end(); + } + + // Only contain tracerA:parent and tracerC:child should be seen + // tracerC:grandchild should list tracerA:parent as its parent + assertThat(exporter.getFinishedSpanItems()) + .satisfiesExactlyInAnyOrder( + spanData -> + assertThat(spanData) + .hasInstrumentationScopeInfo(InstrumentationScopeInfo.create("tracerA")) + .hasName("parent") + .hasSpanId(parent.getSpanContext().getSpanId()) + .hasParentSpanId(SpanId.getInvalid()) + .hasAttributes(Attributes.builder().put("a", "1").build()), + spanData -> + assertThat(spanData) + .hasInstrumentationScopeInfo(InstrumentationScopeInfo.create("tracerC")) + .hasName("grandchild") + .hasSpanId(grandchild.getSpanContext().getSpanId()) + .hasParentSpanId(parent.getSpanContext().getSpanId()) + .hasAttributes(Attributes.builder().put("c", "1").build())); + } + + @ParameterizedTest + @MethodSource("tracerConfiguratorArgs") + void tracerConfigurator( + ScopeConfigurator tracerConfigurator, + InstrumentationScopeInfo scope, + TracerConfig expectedTracerConfig) { + TracerConfig tracerConfig = tracerConfigurator.apply(scope); + tracerConfig = tracerConfig == null ? defaultConfig() : tracerConfig; + assertThat(tracerConfig).isEqualTo(expectedTracerConfig); + } + + private static final InstrumentationScopeInfo scopeCat = InstrumentationScopeInfo.create("cat"); + private static final InstrumentationScopeInfo scopeDog = InstrumentationScopeInfo.create("dog"); + private static final InstrumentationScopeInfo scopeDuck = InstrumentationScopeInfo.create("duck"); + + private static Stream tracerConfiguratorArgs() { + ScopeConfigurator defaultConfigurator = + TracerConfig.configuratorBuilder().build(); + ScopeConfigurator disableCat = + TracerConfig.configuratorBuilder() + .addCondition(nameEquals("cat"), disabled()) + // Second matching rule for cat should be ignored + .addCondition(nameEquals("cat"), enabled()) + .build(); + ScopeConfigurator disableStartsWithD = + TracerConfig.configuratorBuilder().addCondition(nameMatchesGlob("d*"), disabled()).build(); + ScopeConfigurator enableCat = + TracerConfig.configuratorBuilder() + .setDefault(disabled()) + .addCondition(nameEquals("cat"), enabled()) + // Second matching rule for cat should be ignored + .addCondition(nameEquals("cat"), disabled()) + .build(); + ScopeConfigurator enableStartsWithD = + TracerConfig.configuratorBuilder() + .setDefault(disabled()) + .addCondition(nameMatchesGlob("d*"), TracerConfig.enabled()) + .build(); + + return Stream.of( + // default + Arguments.of(defaultConfigurator, scopeCat, defaultConfig()), + Arguments.of(defaultConfigurator, scopeDog, defaultConfig()), + Arguments.of(defaultConfigurator, scopeDuck, defaultConfig()), + // default enabled, disable cat + Arguments.of(disableCat, scopeCat, disabled()), + Arguments.of(disableCat, scopeDog, enabled()), + Arguments.of(disableCat, scopeDuck, enabled()), + // default enabled, disable pattern + Arguments.of(disableStartsWithD, scopeCat, enabled()), + Arguments.of(disableStartsWithD, scopeDog, disabled()), + Arguments.of(disableStartsWithD, scopeDuck, disabled()), + // default disabled, enable cat + Arguments.of(enableCat, scopeCat, enabled()), + Arguments.of(enableCat, scopeDog, disabled()), + Arguments.of(enableCat, scopeDuck, disabled()), + // default disabled, enable pattern + Arguments.of(enableStartsWithD, scopeCat, disabled()), + Arguments.of(enableStartsWithD, scopeDog, enabled()), + Arguments.of(enableStartsWithD, scopeDuck, enabled())); + } +} From b499bdc4ecbc8972fd0f49451e0e757f8a47606d Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 18 Apr 2024 17:04:12 -0500 Subject: [PATCH 363/901] Update gradle/actions action to v3.3.1 (#6398) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/gradle-wrapper-validation.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/gradle-wrapper-validation.yml b/.github/workflows/gradle-wrapper-validation.yml index b09272f06b8..70505e8a550 100644 --- a/.github/workflows/gradle-wrapper-validation.yml +++ b/.github/workflows/gradle-wrapper-validation.yml @@ -13,4 +13,4 @@ jobs: steps: - uses: actions/checkout@v4 - - uses: gradle/actions/wrapper-validation@v3.3.0 + - uses: gradle/actions/wrapper-validation@v3.3.1 From e22c562fa70d6ab6b4c53fe0570c897d750b6dbf Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 19 Apr 2024 20:53:20 -0700 Subject: [PATCH 364/901] Update dependency gradle.plugin.io.morethan.jmhreport:gradle-jmh-report to v0.9.6 (#6404) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- buildSrc/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts index 7f83154c04d..6815e635564 100644 --- a/buildSrc/build.gradle.kts +++ b/buildSrc/build.gradle.kts @@ -60,7 +60,7 @@ dependencies { implementation("com.squareup.wire:wire-compiler") implementation("com.squareup.wire:wire-gradle-plugin") implementation("gradle.plugin.com.google.protobuf:protobuf-gradle-plugin:0.8.18") - implementation("gradle.plugin.io.morethan.jmhreport:gradle-jmh-report:0.9.0") + implementation("gradle.plugin.io.morethan.jmhreport:gradle-jmh-report:0.9.6") implementation("me.champeau.gradle:japicmp-gradle-plugin:0.4.2") implementation("me.champeau.jmh:jmh-gradle-plugin:0.7.2") implementation("net.ltgt.gradle:gradle-errorprone-plugin:3.1.0") From 1960606bce091f5331949de8dcdcc43474365a30 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 20 Apr 2024 10:44:02 -0700 Subject: [PATCH 365/901] Update dependency com.google.api.grpc:proto-google-common-protos to v2.38.0 (#6399) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- dependencyManagement/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index 53ddd94dffc..c2f616ed617 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -55,7 +55,7 @@ val DEPENDENCIES = listOf( "io.prometheus:simpleclient_httpserver:${prometheusClientVersion}", "javax.annotation:javax.annotation-api:1.3.2", "com.github.stefanbirkner:system-rules:1.19.0", - "com.google.api.grpc:proto-google-common-protos:2.37.1", + "com.google.api.grpc:proto-google-common-protos:2.38.0", "com.google.code.findbugs:jsr305:3.0.2", "com.google.guava:guava-beta-checker:1.0", "com.sun.net.httpserver:http:20070405", From a5fc312d268489e808845e29917cae0b3c845afc Mon Sep 17 00:00:00 2001 From: jack-berg <34418638+jack-berg@users.noreply.github.com> Date: Mon, 22 Apr 2024 09:46:06 -0500 Subject: [PATCH 366/901] Add missing fields to OTLP metric exporters (#6402) --- .../opentelemetry-sdk-metrics.txt | 7 ++++- .../http/metrics/OtlpHttpMetricExporter.java | 12 +++++++- .../otlp/metrics/OtlpGrpcMetricExporter.java | 12 +++++++- ...tlpHttpMetricExporterOkHttpSenderTest.java | 29 +++++++++++++++++++ .../metrics/OtlpGrpcMetricExporterTest.java | 28 ++++++++++++++++++ .../OtlpHttpMetricExporterJdkSenderTest.java | 29 +++++++++++++++++++ .../AbstractGrpcTelemetryExporterTest.java | 4 +-- .../AbstractHttpTelemetryExporterTest.java | 2 ++ .../fileconfig/MetricExporterFactoryTest.java | 8 +++++ .../AggregationTemporalitySelector.java | 13 +++++++++ .../export/DefaultAggregationSelector.java | 17 +++++++++++ .../AggregationTemporalitySelectorTest.java | 28 ++++++++++++++++++ .../DefaultAggregationSelectorTest.java | 27 +++++++++++++++++ 13 files changed, 211 insertions(+), 5 deletions(-) diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-metrics.txt b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-metrics.txt index df26146497b..37f807adf9b 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-metrics.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-metrics.txt @@ -1,2 +1,7 @@ Comparing source compatibility of against -No changes. \ No newline at end of file +*** MODIFIED INTERFACE: PUBLIC ABSTRACT io.opentelemetry.sdk.metrics.export.AggregationTemporalitySelector (not serializable) + === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 + +++ NEW METHOD: PUBLIC(+) STATIC(+) java.lang.String asString(io.opentelemetry.sdk.metrics.export.AggregationTemporalitySelector) +*** MODIFIED INTERFACE: PUBLIC ABSTRACT io.opentelemetry.sdk.metrics.export.DefaultAggregationSelector (not serializable) + === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 + +++ NEW METHOD: PUBLIC(+) STATIC(+) java.lang.String asString(io.opentelemetry.sdk.metrics.export.DefaultAggregationSelector) diff --git a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/metrics/OtlpHttpMetricExporter.java b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/metrics/OtlpHttpMetricExporter.java index d9b0dd7d2c9..e361bb5d2da 100644 --- a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/metrics/OtlpHttpMetricExporter.java +++ b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/metrics/OtlpHttpMetricExporter.java @@ -18,6 +18,7 @@ import io.opentelemetry.sdk.metrics.export.DefaultAggregationSelector; import io.opentelemetry.sdk.metrics.export.MetricExporter; import java.util.Collection; +import java.util.StringJoiner; import javax.annotation.concurrent.ThreadSafe; /** @@ -124,6 +125,15 @@ public CompletableResultCode shutdown() { @Override public String toString() { - return "OtlpHttpMetricExporter{" + builder.toString(false) + "}"; + StringJoiner joiner = new StringJoiner(", ", "OtlpHttpMetricExporter{", "}"); + joiner.add(builder.toString(false)); + joiner.add( + "aggregationTemporalitySelector=" + + AggregationTemporalitySelector.asString(aggregationTemporalitySelector)); + joiner.add( + "defaultAggregationSelector=" + + DefaultAggregationSelector.asString(defaultAggregationSelector)); + joiner.add("memoryMode=" + memoryMode); + return joiner.toString(); } } diff --git a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/metrics/OtlpGrpcMetricExporter.java b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/metrics/OtlpGrpcMetricExporter.java index f6e5f635ee9..eeeba0773b7 100644 --- a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/metrics/OtlpGrpcMetricExporter.java +++ b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/metrics/OtlpGrpcMetricExporter.java @@ -18,6 +18,7 @@ import io.opentelemetry.sdk.metrics.export.DefaultAggregationSelector; import io.opentelemetry.sdk.metrics.export.MetricExporter; import java.util.Collection; +import java.util.StringJoiner; import javax.annotation.concurrent.ThreadSafe; /** @@ -128,6 +129,15 @@ public CompletableResultCode shutdown() { @Override public String toString() { - return "OtlpGrpcMetricExporter{" + builder.toString(false) + "}"; + StringJoiner joiner = new StringJoiner(", ", "OtlpGrpcMetricExporter{", "}"); + joiner.add(builder.toString(false)); + joiner.add( + "aggregationTemporalitySelector=" + + AggregationTemporalitySelector.asString(aggregationTemporalitySelector)); + joiner.add( + "defaultAggregationSelector=" + + DefaultAggregationSelector.asString(defaultAggregationSelector)); + joiner.add("memoryMode=" + memoryMode); + return joiner.toString(); } } diff --git a/exporters/otlp/all/src/testDefaultSender/java/io/opentelemetry/exporter/otlp/http/metrics/OtlpHttpMetricExporterOkHttpSenderTest.java b/exporters/otlp/all/src/testDefaultSender/java/io/opentelemetry/exporter/otlp/http/metrics/OtlpHttpMetricExporterOkHttpSenderTest.java index 052e4c9c8b2..a6686aa9d5d 100644 --- a/exporters/otlp/all/src/testDefaultSender/java/io/opentelemetry/exporter/otlp/http/metrics/OtlpHttpMetricExporterOkHttpSenderTest.java +++ b/exporters/otlp/all/src/testDefaultSender/java/io/opentelemetry/exporter/otlp/http/metrics/OtlpHttpMetricExporterOkHttpSenderTest.java @@ -23,7 +23,9 @@ import io.opentelemetry.sdk.metrics.data.MetricData; import io.opentelemetry.sdk.metrics.export.AggregationTemporalitySelector; import io.opentelemetry.sdk.metrics.export.DefaultAggregationSelector; +import io.opentelemetry.sdk.metrics.export.MetricExporter; import java.util.List; +import java.util.concurrent.TimeUnit; import org.junit.jupiter.api.Test; class OtlpHttpMetricExporterOkHttpSenderTest @@ -77,6 +79,33 @@ void invalidMetricConfig() { .hasMessage("defaultAggregationSelector"); } + /** Test configuration specific to metric exporter. */ + @Test + void stringRepresentation() { + try (MetricExporter metricExporter = OtlpHttpMetricExporter.builder().build()) { + assertThat(metricExporter.toString()) + .matches( + "OtlpHttpMetricExporter\\{" + + "exporterName=otlp, " + + "type=metric, " + + "endpoint=http://localhost:4318/v1/metrics, " + + "timeoutNanos=" + + TimeUnit.SECONDS.toNanos(10) + + ", " + + "proxyOptions=null, " + + "compressorEncoding=null, " + + "connectTimeoutNanos=" + + TimeUnit.SECONDS.toNanos(10) + + ", " + + "exportAsJson=false, " + + "headers=Headers\\{User-Agent=OBFUSCATED\\}, " + + "aggregationTemporalitySelector=AggregationTemporalitySelector\\{.*\\}, " + + "defaultAggregationSelector=DefaultAggregationSelector\\{.*\\}, " + + "memoryMode=IMMUTABLE_DATA" + + "\\}"); + } + } + @Override protected TelemetryExporterBuilder exporterBuilder() { return new HttpMetricExporterBuilderWrapper(OtlpHttpMetricExporter.builder()); diff --git a/exporters/otlp/all/src/testDefaultSender/java/io/opentelemetry/exporter/otlp/metrics/OtlpGrpcMetricExporterTest.java b/exporters/otlp/all/src/testDefaultSender/java/io/opentelemetry/exporter/otlp/metrics/OtlpGrpcMetricExporterTest.java index 65cbf9320ce..7a9e52a741c 100644 --- a/exporters/otlp/all/src/testDefaultSender/java/io/opentelemetry/exporter/otlp/metrics/OtlpGrpcMetricExporterTest.java +++ b/exporters/otlp/all/src/testDefaultSender/java/io/opentelemetry/exporter/otlp/metrics/OtlpGrpcMetricExporterTest.java @@ -23,8 +23,10 @@ import io.opentelemetry.sdk.metrics.data.MetricData; import io.opentelemetry.sdk.metrics.export.AggregationTemporalitySelector; import io.opentelemetry.sdk.metrics.export.DefaultAggregationSelector; +import io.opentelemetry.sdk.metrics.export.MetricExporter; import java.io.Closeable; import java.util.List; +import java.util.concurrent.TimeUnit; import org.junit.jupiter.api.Test; class OtlpGrpcMetricExporterTest @@ -78,6 +80,32 @@ void invalidMetricConfig() { .hasMessage("defaultAggregationSelector"); } + /** Test configuration specific to metric exporter. */ + @Test + void stringRepresentation() { + try (MetricExporter metricExporter = OtlpGrpcMetricExporter.builder().build()) { + assertThat(metricExporter.toString()) + .matches( + "OtlpGrpcMetricExporter\\{" + + "exporterName=otlp, " + + "type=metric, " + + "endpoint=http://localhost:4317, " + + "endpointPath=.*, " + + "timeoutNanos=" + + TimeUnit.SECONDS.toNanos(10) + + ", " + + "connectTimeoutNanos=" + + TimeUnit.SECONDS.toNanos(10) + + ", " + + "compressorEncoding=null, " + + "headers=Headers\\{User-Agent=OBFUSCATED\\}, " + + "aggregationTemporalitySelector=AggregationTemporalitySelector\\{.*\\}, " + + "defaultAggregationSelector=DefaultAggregationSelector\\{.*\\}, " + + "memoryMode=IMMUTABLE_DATA" + + "\\}"); + } + } + @Test void usingOkHttp() throws Exception { try (Closeable exporter = OtlpGrpcMetricExporter.builder().build()) { diff --git a/exporters/otlp/all/src/testJdkHttpSender/java/io/opentelemetry/exporter/otlp/http/metrics/OtlpHttpMetricExporterJdkSenderTest.java b/exporters/otlp/all/src/testJdkHttpSender/java/io/opentelemetry/exporter/otlp/http/metrics/OtlpHttpMetricExporterJdkSenderTest.java index 5418acea369..cf08d4dc05f 100644 --- a/exporters/otlp/all/src/testJdkHttpSender/java/io/opentelemetry/exporter/otlp/http/metrics/OtlpHttpMetricExporterJdkSenderTest.java +++ b/exporters/otlp/all/src/testJdkHttpSender/java/io/opentelemetry/exporter/otlp/http/metrics/OtlpHttpMetricExporterJdkSenderTest.java @@ -24,7 +24,9 @@ import io.opentelemetry.sdk.metrics.data.MetricData; import io.opentelemetry.sdk.metrics.export.AggregationTemporalitySelector; import io.opentelemetry.sdk.metrics.export.DefaultAggregationSelector; +import io.opentelemetry.sdk.metrics.export.MetricExporter; import java.util.List; +import java.util.concurrent.TimeUnit; import org.junit.jupiter.api.Test; class OtlpHttpMetricExporterJdkSenderTest @@ -78,6 +80,33 @@ void invalidMetricConfig() { .hasMessage("defaultAggregationSelector"); } + /** Test configuration specific to metric exporter. */ + @Test + void stringRepresentation() { + try (MetricExporter metricExporter = OtlpHttpMetricExporter.builder().build()) { + assertThat(metricExporter.toString()) + .matches( + "OtlpHttpMetricExporter\\{" + + "exporterName=otlp, " + + "type=metric, " + + "endpoint=http://localhost:4318/v1/metrics, " + + "timeoutNanos=" + + TimeUnit.SECONDS.toNanos(10) + + ", " + + "proxyOptions=null, " + + "compressorEncoding=null, " + + "connectTimeoutNanos=" + + TimeUnit.SECONDS.toNanos(10) + + ", " + + "exportAsJson=false, " + + "headers=Headers\\{User-Agent=OBFUSCATED\\}, " + + "aggregationTemporalitySelector=AggregationTemporalitySelector\\{.*\\}, " + + "defaultAggregationSelector=DefaultAggregationSelector\\{.*\\}, " + + "memoryMode=IMMUTABLE_DATA" + + "\\}"); + } + } + @Override protected boolean hasAuthenticatorSupport() { return false; diff --git a/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/AbstractGrpcTelemetryExporterTest.java b/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/AbstractGrpcTelemetryExporterTest.java index c9106353a6e..7a8384e15e8 100644 --- a/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/AbstractGrpcTelemetryExporterTest.java +++ b/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/AbstractGrpcTelemetryExporterTest.java @@ -872,7 +872,7 @@ void stringRepresentation() throws IOException, CertificateEncodingException { + ", " + "compressorEncoding=null, " + "headers=Headers\\{User-Agent=OBFUSCATED\\}" - + ".*" // Maybe additional grpcChannel field + + ".*" // Maybe additional grpcChannel field, signal specific fields + "\\}"); } finally { telemetryExporter.shutdown(); @@ -914,7 +914,7 @@ void stringRepresentation() throws IOException, CertificateEncodingException { + "compressorEncoding=gzip, " + "headers=Headers\\{.*foo=OBFUSCATED.*\\}, " + "retryPolicy=RetryPolicy\\{maxAttempts=2, initialBackoff=PT0\\.05S, maxBackoff=PT3S, backoffMultiplier=1\\.3\\}" - + ".*" // Maybe additional grpcChannel field + + ".*" // Maybe additional grpcChannel field, signal specific fields + "\\}"); } finally { telemetryExporter.shutdown(); diff --git a/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/AbstractHttpTelemetryExporterTest.java b/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/AbstractHttpTelemetryExporterTest.java index 27d9e5f2f2a..da31843490c 100644 --- a/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/AbstractHttpTelemetryExporterTest.java +++ b/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/AbstractHttpTelemetryExporterTest.java @@ -858,6 +858,7 @@ void stringRepresentation() throws IOException, CertificateEncodingException { + ", " + "exportAsJson=false, " + "headers=Headers\\{User-Agent=OBFUSCATED\\}" + + ".*" // Maybe additional signal specific fields + "\\}"); } finally { telemetryExporter.shutdown(); @@ -900,6 +901,7 @@ void stringRepresentation() throws IOException, CertificateEncodingException { + "exportAsJson=false, " + "headers=Headers\\{.*foo=OBFUSCATED.*\\}, " + "retryPolicy=RetryPolicy\\{maxAttempts=2, initialBackoff=PT0\\.05S, maxBackoff=PT3S, backoffMultiplier=1\\.3\\}" + + ".*" // Maybe additional signal specific fields + "\\}"); } finally { telemetryExporter.shutdown(); diff --git a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/MetricExporterFactoryTest.java b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/MetricExporterFactoryTest.java index 4b9b7520441..6470239bfdf 100644 --- a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/MetricExporterFactoryTest.java +++ b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/MetricExporterFactoryTest.java @@ -28,6 +28,10 @@ import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.OtlpMetric; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.OtlpMetric.DefaultHistogramAggregation; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.Prometheus; +import io.opentelemetry.sdk.metrics.Aggregation; +import io.opentelemetry.sdk.metrics.InstrumentType; +import io.opentelemetry.sdk.metrics.export.AggregationTemporalitySelector; +import io.opentelemetry.sdk.metrics.export.DefaultAggregationSelector; import io.opentelemetry.sdk.metrics.export.MetricExporter; import java.io.Closeable; import java.io.IOException; @@ -118,6 +122,10 @@ void create_OtlpConfigured(@TempDir Path tempDir) .addHeader("key2", "value2") .setTimeout(Duration.ofSeconds(15)) .setCompression("gzip") + .setAggregationTemporalitySelector(AggregationTemporalitySelector.deltaPreferred()) + .setDefaultAggregationSelector( + DefaultAggregationSelector.getDefault() + .with(InstrumentType.HISTOGRAM, Aggregation.base2ExponentialBucketHistogram())) .build(); cleanup.addCloseable(expectedExporter); diff --git a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/export/AggregationTemporalitySelector.java b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/export/AggregationTemporalitySelector.java index ac13acd964e..0d0e4a85625 100644 --- a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/export/AggregationTemporalitySelector.java +++ b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/export/AggregationTemporalitySelector.java @@ -7,6 +7,7 @@ import io.opentelemetry.sdk.metrics.InstrumentType; import io.opentelemetry.sdk.metrics.data.AggregationTemporality; +import java.util.StringJoiner; /** * A functional interface that selects {@link AggregationTemporality} based on {@link @@ -76,4 +77,16 @@ static AggregationTemporalitySelector lowMemory() { /** Return the aggregation temporality for the {@link InstrumentType}. */ AggregationTemporality getAggregationTemporality(InstrumentType instrumentType); + + /** + * Returns a string representation of this selector, for using in {@link Object#toString()} + * implementations. + */ + static String asString(AggregationTemporalitySelector selector) { + StringJoiner joiner = new StringJoiner(", ", "AggregationTemporalitySelector{", "}"); + for (InstrumentType type : InstrumentType.values()) { + joiner.add(type.name() + "=" + selector.getAggregationTemporality(type).name()); + } + return joiner.toString(); + } } diff --git a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/export/DefaultAggregationSelector.java b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/export/DefaultAggregationSelector.java index f3cae755ad4..86a33440fc0 100644 --- a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/export/DefaultAggregationSelector.java +++ b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/export/DefaultAggregationSelector.java @@ -9,6 +9,8 @@ import io.opentelemetry.sdk.metrics.Aggregation; import io.opentelemetry.sdk.metrics.InstrumentType; +import io.opentelemetry.sdk.metrics.internal.aggregator.AggregationUtil; +import java.util.StringJoiner; /** * A functional interface that selects default {@link Aggregation} based on {@link InstrumentType}. @@ -58,4 +60,19 @@ default DefaultAggregationSelector with(InstrumentType instrumentType, Aggregati *

      The default aggregation is used when an instrument does not match any views. */ Aggregation getDefaultAggregation(InstrumentType instrumentType); + + /** + * Returns a string representation of this selector, for using in {@link Object#toString()} + * implementations. + */ + static String asString(DefaultAggregationSelector selector) { + StringJoiner joiner = new StringJoiner(", ", "DefaultAggregationSelector{", "}"); + for (InstrumentType type : InstrumentType.values()) { + joiner.add( + type.name() + + "=" + + AggregationUtil.aggregationName(selector.getDefaultAggregation(type))); + } + return joiner.toString(); + } } diff --git a/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/export/AggregationTemporalitySelectorTest.java b/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/export/AggregationTemporalitySelectorTest.java index cb3affac280..30bb02d5db3 100644 --- a/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/export/AggregationTemporalitySelectorTest.java +++ b/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/export/AggregationTemporalitySelectorTest.java @@ -63,4 +63,32 @@ void lowMemory() { assertThat(selector.getAggregationTemporality(InstrumentType.OBSERVABLE_UP_DOWN_COUNTER)) .isEqualTo(AggregationTemporality.CUMULATIVE); } + + @Test + void stringRepresentation() { + assertThat( + AggregationTemporalitySelector.asString( + AggregationTemporalitySelector.alwaysCumulative())) + .isEqualTo( + "AggregationTemporalitySelector{" + + "COUNTER=CUMULATIVE, " + + "UP_DOWN_COUNTER=CUMULATIVE, " + + "HISTOGRAM=CUMULATIVE, " + + "OBSERVABLE_COUNTER=CUMULATIVE, " + + "OBSERVABLE_UP_DOWN_COUNTER=CUMULATIVE, " + + "OBSERVABLE_GAUGE=CUMULATIVE" + + "}"); + assertThat( + AggregationTemporalitySelector.asString( + AggregationTemporalitySelector.deltaPreferred())) + .isEqualTo( + "AggregationTemporalitySelector{" + + "COUNTER=DELTA, " + + "UP_DOWN_COUNTER=CUMULATIVE, " + + "HISTOGRAM=DELTA, " + + "OBSERVABLE_COUNTER=DELTA, " + + "OBSERVABLE_UP_DOWN_COUNTER=CUMULATIVE, " + + "OBSERVABLE_GAUGE=DELTA" + + "}"); + } } diff --git a/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/export/DefaultAggregationSelectorTest.java b/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/export/DefaultAggregationSelectorTest.java index 03d3a2c3689..53bd0fbc0b0 100644 --- a/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/export/DefaultAggregationSelectorTest.java +++ b/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/export/DefaultAggregationSelectorTest.java @@ -61,4 +61,31 @@ void with() { assertThat(selector2.getDefaultAggregation(InstrumentType.OBSERVABLE_GAUGE)) .isEqualTo(Aggregation.defaultAggregation()); } + + @Test + void stringRepresentation() { + assertThat(DefaultAggregationSelector.asString(DefaultAggregationSelector.getDefault())) + .isEqualTo( + "DefaultAggregationSelector{" + + "COUNTER=default, " + + "UP_DOWN_COUNTER=default, " + + "HISTOGRAM=default, " + + "OBSERVABLE_COUNTER=default, " + + "OBSERVABLE_UP_DOWN_COUNTER=default, " + + "OBSERVABLE_GAUGE=default" + + "}"); + assertThat( + DefaultAggregationSelector.asString( + DefaultAggregationSelector.getDefault() + .with(InstrumentType.HISTOGRAM, Aggregation.base2ExponentialBucketHistogram()))) + .isEqualTo( + "DefaultAggregationSelector{" + + "COUNTER=default, " + + "UP_DOWN_COUNTER=default, " + + "HISTOGRAM=base2_exponential_bucket_histogram, " + + "OBSERVABLE_COUNTER=default, " + + "OBSERVABLE_UP_DOWN_COUNTER=default, " + + "OBSERVABLE_GAUGE=default" + + "}"); + } } From 8f791f2c6169571e468a376ee9883729edae8005 Mon Sep 17 00:00:00 2001 From: jack-berg <34418638+jack-berg@users.noreply.github.com> Date: Mon, 22 Apr 2024 09:47:15 -0500 Subject: [PATCH 367/901] PrometheusHttpServer prevent concurrent reads when reusable memory mode (#6371) --- .../prometheus/PrometheusHttpServer.java | 7 ++ .../PrometheusHttpServerBuilder.java | 9 ++- .../prometheus/PrometheusHttpServerTest.java | 65 +++++++++++++++++++ 3 files changed, 80 insertions(+), 1 deletion(-) diff --git a/exporters/prometheus/src/main/java/io/opentelemetry/exporter/prometheus/PrometheusHttpServer.java b/exporters/prometheus/src/main/java/io/opentelemetry/exporter/prometheus/PrometheusHttpServer.java index e4a15612856..f815ea0ac54 100644 --- a/exporters/prometheus/src/main/java/io/opentelemetry/exporter/prometheus/PrometheusHttpServer.java +++ b/exporters/prometheus/src/main/java/io/opentelemetry/exporter/prometheus/PrometheusHttpServer.java @@ -23,6 +23,7 @@ import java.io.UncheckedIOException; import java.net.InetSocketAddress; import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; import java.util.concurrent.TimeUnit; import java.util.function.Predicate; import javax.annotation.Nullable; @@ -70,6 +71,12 @@ public static PrometheusHttpServerBuilder builder() { this.memoryMode = memoryMode; this.prometheusRegistry = prometheusRegistry; prometheusRegistry.register(prometheusMetricReader); + // When memory mode is REUSABLE_DATA, concurrent reads lead to data corruption. To prevent this, + // we configure prometheus with a single thread executor such that requests are handled + // sequentially. + if (memoryMode == MemoryMode.REUSABLE_DATA) { + executor = Executors.newSingleThreadExecutor(); + } try { this.httpServer = HTTPServer.builder() diff --git a/exporters/prometheus/src/main/java/io/opentelemetry/exporter/prometheus/PrometheusHttpServerBuilder.java b/exporters/prometheus/src/main/java/io/opentelemetry/exporter/prometheus/PrometheusHttpServerBuilder.java index 3c20eea3a2f..2be7dee6215 100644 --- a/exporters/prometheus/src/main/java/io/opentelemetry/exporter/prometheus/PrometheusHttpServerBuilder.java +++ b/exporters/prometheus/src/main/java/io/opentelemetry/exporter/prometheus/PrometheusHttpServerBuilder.java @@ -11,6 +11,7 @@ import io.opentelemetry.sdk.common.export.MemoryMode; import io.prometheus.metrics.model.registry.PrometheusRegistry; import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; import java.util.function.Predicate; import javax.annotation.Nullable; @@ -93,7 +94,13 @@ public PrometheusHttpServerBuilder setAllowedResourceAttributesFilter( return this; } - /** Set the {@link MemoryMode}. */ + /** + * Set the {@link MemoryMode}. + * + *

      If set to {@link MemoryMode#REUSABLE_DATA}, requests are served sequentially which is + * accomplished by overriding {@link #setExecutor(ExecutorService)} to {@link + * Executors#newSingleThreadExecutor()}. + */ public PrometheusHttpServerBuilder setMemoryMode(MemoryMode memoryMode) { requireNonNull(memoryMode, "memoryMode"); this.memoryMode = memoryMode; diff --git a/exporters/prometheus/src/test/java/io/opentelemetry/exporter/prometheus/PrometheusHttpServerTest.java b/exporters/prometheus/src/test/java/io/opentelemetry/exporter/prometheus/PrometheusHttpServerTest.java index 3fc114c1ed3..449cc4c5c4c 100644 --- a/exporters/prometheus/src/test/java/io/opentelemetry/exporter/prometheus/PrometheusHttpServerTest.java +++ b/exporters/prometheus/src/test/java/io/opentelemetry/exporter/prometheus/PrometheusHttpServerTest.java @@ -24,6 +24,7 @@ import io.opentelemetry.api.common.Attributes; import io.opentelemetry.internal.testing.slf4j.SuppressLogger; import io.opentelemetry.sdk.common.InstrumentationScopeInfo; +import io.opentelemetry.sdk.common.export.MemoryMode; import io.opentelemetry.sdk.metrics.data.AggregationTemporality; import io.opentelemetry.sdk.metrics.data.MetricData; import io.opentelemetry.sdk.metrics.export.CollectionRegistration; @@ -39,6 +40,7 @@ import java.io.IOException; import java.net.ServerSocket; import java.nio.charset.StandardCharsets; +import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.List; @@ -47,6 +49,7 @@ import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.ScheduledThreadPoolExecutor; import java.util.concurrent.ThreadPoolExecutor; +import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicReference; import java.util.function.Predicate; import java.util.zip.GZIPInputStream; @@ -129,6 +132,68 @@ void fetchPrometheus() { + "target_info{kr=\"vr\"} 1\n"); } + @Test + void fetch_ReusableMemoryMode() throws InterruptedException { + try (PrometheusHttpServer prometheusServer = + PrometheusHttpServer.builder() + .setHost("localhost") + .setPort(0) + .setMemoryMode(MemoryMode.REUSABLE_DATA) + .build()) { + AtomicBoolean collectInProgress = new AtomicBoolean(); + AtomicBoolean concurrentRead = new AtomicBoolean(); + prometheusServer.register( + new CollectionRegistration() { + @Override + public Collection collectAllMetrics() { + if (!collectInProgress.compareAndSet(false, true)) { + concurrentRead.set(true); + } + Collection response = metricData.get(); + try { + Thread.sleep(1); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } + if (!collectInProgress.compareAndSet(true, false)) { + concurrentRead.set(true); + } + return response; + } + }); + + WebClient client = + WebClient.builder("http://localhost:" + prometheusServer.getAddress().getPort()) + .decorator(RetryingClient.newDecorator(RetryRule.failsafe())) + .build(); + + // Spin up 4 threads calling /metrics simultaneously. If concurrent read happens, + // collectAllMetrics will set concurrentRead to true and the test will fail. + List threads = new ArrayList<>(); + for (int i = 0; i < 4; i++) { + Thread thread = + new Thread( + () -> { + for (int j = 0; j < 10; j++) { + AggregatedHttpResponse response = client.get("/metrics").aggregate().join(); + assertThat(response.status()).isEqualTo(HttpStatus.OK); + } + }); + thread.setDaemon(true); + thread.start(); + threads.add(thread); + } + + // Wait for threads to complete + for (Thread thread : threads) { + thread.join(); + } + + // Confirm no concurrent reads took place + assertThat(concurrentRead.get()).isFalse(); + } + } + @Test void fetchOpenMetrics() { AggregatedHttpResponse response = From da4cd931f827bda109fa5a2f988472465cdc2a4c Mon Sep 17 00:00:00 2001 From: Alexander Wert Date: Tue, 23 Apr 2024 16:27:09 +0200 Subject: [PATCH 368/901] Add is_remote_parent span flags to OTLP exported Spans and SpanLinks (#6388) Signed-off-by: Alexander Wert --- .../internal/otlp/traces/SpanFlags.java | 95 ++++++++++++++ .../otlp/traces/SpanLinkMarshaler.java | 22 +++- .../internal/otlp/traces/SpanMarshaler.java | 21 ++- .../internal/otlp/traces/SpanFlagsTest.java | 121 ++++++++++++++++++ .../traces/TraceRequestMarshalerTest.java | 73 ++++++++++- 5 files changed, 315 insertions(+), 17 deletions(-) create mode 100644 exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/traces/SpanFlags.java create mode 100644 exporters/otlp/common/src/test/java/io/opentelemetry/exporter/internal/otlp/traces/SpanFlagsTest.java diff --git a/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/traces/SpanFlags.java b/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/traces/SpanFlags.java new file mode 100644 index 00000000000..06c57b90541 --- /dev/null +++ b/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/traces/SpanFlags.java @@ -0,0 +1,95 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.exporter.internal.otlp.traces; + +import io.opentelemetry.api.trace.TraceFlags; + +/** + * Represents the 32 bit span flags as + * specified in the proto definition. + */ +public final class SpanFlags { + // As defined at: + // https://github.com/open-telemetry/opentelemetry-proto/blob/342e1d4c3a1fe43312823ffb53bd38327f263059/opentelemetry/proto/trace/v1/trace.proto#L351-L352 + static final int CONTEXT_HAS_IS_REMOTE_BIT = 0x00000100; + static final int CONTEXT_IS_REMOTE_BIT = 0x00000200; + static final int CONTEXT_IS_REMOTE_MASK = CONTEXT_HAS_IS_REMOTE_BIT | CONTEXT_IS_REMOTE_BIT; + + private SpanFlags() {} + + /** + * Returns the int (fixed32) representation of the {@link TraceFlags} enriched with the flags + * indicating a remote parent. + * + * @param isParentRemote indicates whether the parent context is remote + * @return the int (fixed32) representation of the {@link TraceFlags} enriched with the flags + * indicating a remote parent. + */ + public static int withParentIsRemoteFlags(TraceFlags traceFlags, boolean isParentRemote) { + byte byteRep = traceFlags.asByte(); + if (isParentRemote) { + return (byteRep & 0xff) | CONTEXT_IS_REMOTE_MASK; + } + return (byteRep & 0xff) | CONTEXT_HAS_IS_REMOTE_BIT; + } + + /** + * Returns the int (fixed32) representation of the 4 bytes flags with the + * has_parent_context_is_remote flag bit on. + * + * @return the int (fixed32) representation of the 4 bytes flags with the * + * has_parent_context_is_remote flag bit on. + */ + public static int getHasParentIsRemoteMask() { + return CONTEXT_HAS_IS_REMOTE_BIT; + } + + /** + * Checks whether the given flags contain information about parent context being remote or not. + * + * @param flags The int representation of the 32 bit span flags field defined in proto. + * @return True, if the given flags contain information about the span's parent context being + * remote, otherwise, false. + */ + public static boolean isKnownWhetherParentIsRemote(int flags) { + return (flags & CONTEXT_HAS_IS_REMOTE_BIT) != 0; + } + + /** + * Returns the int (fixed32) representation of the 4 bytes flags with the + * has_parent_context_is_remote and parent_context_is_remote flag bits on. + * + * @return the int (fixed32) representation of the 4 bytes flags with the + * has_parent_context_is_remote and parent_context_is_remote flag bits on. + */ + public static int getParentIsRemoteMask() { + return CONTEXT_IS_REMOTE_MASK; + } + + /** + * Checks whether in the given flags the parent is marked as remote. + * + * @param flags The int representation of the 32 bit span flags field defined in proto. + * @return True, if the given flags contain information about the span's parent context and the + * parent is marked as remote, otherwise false. + */ + public static boolean isParentRemote(int flags) { + return (flags & CONTEXT_IS_REMOTE_MASK) == CONTEXT_IS_REMOTE_MASK; + } + + /** + * Returns the W3C {@link TraceFlags} (least significant 8 bits) portion from the given 32 bit + * span flags fields. + * + * @param flags The int representation of the 32 bit span flags field defined in proto. + * @return the W3C {@link TraceFlags} (least significant 8 bits) portion from the given 32 bit + * span flags fields. + */ + public static TraceFlags getTraceFlags(int flags) { + return TraceFlags.fromByte((byte) (flags & 0xff)); + } +} diff --git a/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/traces/SpanLinkMarshaler.java b/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/traces/SpanLinkMarshaler.java index 6adcac370e1..01310713009 100644 --- a/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/traces/SpanLinkMarshaler.java +++ b/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/traces/SpanLinkMarshaler.java @@ -28,6 +28,7 @@ final class SpanLinkMarshaler extends MarshalerWithSize { private final KeyValueMarshaler[] attributeMarshalers; private final int droppedAttributesCount; private final TraceFlags traceFlags; + private final boolean isLinkContextRemote; static SpanLinkMarshaler[] createRepeated(List links) { if (links.isEmpty()) { @@ -50,13 +51,15 @@ static SpanLinkMarshaler create(LinkData link) { traceState.isEmpty() ? EMPTY_BYTES : encodeTraceState(traceState).getBytes(StandardCharsets.UTF_8); + return new SpanLinkMarshaler( link.getSpanContext().getTraceId(), link.getSpanContext().getSpanId(), link.getSpanContext().getTraceFlags(), traceStateUtf8, KeyValueMarshaler.createForAttributes(link.getAttributes()), - link.getTotalAttributeCount() - link.getAttributes().size()); + link.getTotalAttributeCount() - link.getAttributes().size(), + link.getSpanContext().isRemote()); } private SpanLinkMarshaler( @@ -65,7 +68,8 @@ private SpanLinkMarshaler( TraceFlags traceFlags, byte[] traceStateUtf8, KeyValueMarshaler[] attributeMarshalers, - int droppedAttributesCount) { + int droppedAttributesCount, + boolean isLinkContextRemote) { super( calculateSize( traceId, @@ -73,13 +77,15 @@ private SpanLinkMarshaler( traceFlags, traceStateUtf8, attributeMarshalers, - droppedAttributesCount)); + droppedAttributesCount, + isLinkContextRemote)); this.traceId = traceId; this.spanId = spanId; this.traceFlags = traceFlags; this.traceStateUtf8 = traceStateUtf8; this.attributeMarshalers = attributeMarshalers; this.droppedAttributesCount = droppedAttributesCount; + this.isLinkContextRemote = isLinkContextRemote; } @Override @@ -89,7 +95,8 @@ public void writeTo(Serializer output) throws IOException { output.serializeString(Span.Link.TRACE_STATE, traceStateUtf8); output.serializeRepeatedMessage(Span.Link.ATTRIBUTES, attributeMarshalers); output.serializeUInt32(Span.Link.DROPPED_ATTRIBUTES_COUNT, droppedAttributesCount); - output.serializeByteAsFixed32(Span.Link.FLAGS, traceFlags.asByte()); + output.serializeFixed32( + Span.Link.FLAGS, SpanFlags.withParentIsRemoteFlags(traceFlags, isLinkContextRemote)); } private static int calculateSize( @@ -98,14 +105,17 @@ private static int calculateSize( TraceFlags flags, byte[] traceStateUtf8, KeyValueMarshaler[] attributeMarshalers, - int droppedAttributesCount) { + int droppedAttributesCount, + boolean isLinkContextRemote) { int size = 0; size += MarshalerUtil.sizeTraceId(Span.Link.TRACE_ID, traceId); size += MarshalerUtil.sizeSpanId(Span.Link.SPAN_ID, spanId); size += MarshalerUtil.sizeBytes(Span.Link.TRACE_STATE, traceStateUtf8); size += MarshalerUtil.sizeRepeatedMessage(Span.Link.ATTRIBUTES, attributeMarshalers); size += MarshalerUtil.sizeUInt32(Span.Link.DROPPED_ATTRIBUTES_COUNT, droppedAttributesCount); - size += MarshalerUtil.sizeByteAsFixed32(Span.Link.FLAGS, flags.asByte()); + size += + MarshalerUtil.sizeFixed32( + Span.Link.FLAGS, SpanFlags.withParentIsRemoteFlags(flags, isLinkContextRemote)); return size; } } diff --git a/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/traces/SpanMarshaler.java b/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/traces/SpanMarshaler.java index e2e83c0f129..15e310c1ac7 100644 --- a/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/traces/SpanMarshaler.java +++ b/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/traces/SpanMarshaler.java @@ -39,6 +39,7 @@ final class SpanMarshaler extends MarshalerWithSize { private final int droppedLinksCount; private final SpanStatusMarshaler spanStatusMarshaler; private final TraceFlags flags; + private final boolean isParentContextRemote; // Because SpanMarshaler is always part of a repeated field, it cannot return "null". static SpanMarshaler create(SpanData spanData) { @@ -75,7 +76,8 @@ static SpanMarshaler create(SpanData spanData) { spanLinkMarshalers, spanData.getTotalRecordedLinks() - spanData.getLinks().size(), SpanStatusMarshaler.create(spanData.getStatus()), - spanData.getSpanContext().getTraceFlags()); + spanData.getSpanContext().getTraceFlags(), + spanData.getParentSpanContext().isRemote()); } private SpanMarshaler( @@ -94,7 +96,8 @@ private SpanMarshaler( SpanLinkMarshaler[] spanLinkMarshalers, int droppedLinksCount, SpanStatusMarshaler spanStatusMarshaler, - TraceFlags flags) { + TraceFlags flags, + boolean isParentContextRemote) { super( calculateSize( traceId, @@ -112,7 +115,8 @@ private SpanMarshaler( spanLinkMarshalers, droppedLinksCount, spanStatusMarshaler, - flags)); + flags, + isParentContextRemote)); this.traceId = traceId; this.spanId = spanId; this.traceStateUtf8 = traceStateUtf8; @@ -129,6 +133,7 @@ private SpanMarshaler( this.droppedLinksCount = droppedLinksCount; this.spanStatusMarshaler = spanStatusMarshaler; this.flags = flags; + this.isParentContextRemote = isParentContextRemote; } @Override @@ -154,7 +159,8 @@ public void writeTo(Serializer output) throws IOException { output.serializeUInt32(Span.DROPPED_LINKS_COUNT, droppedLinksCount); output.serializeMessage(Span.STATUS, spanStatusMarshaler); - output.serializeByteAsFixed32(Span.FLAGS, flags.asByte()); + output.serializeFixed32( + Span.FLAGS, SpanFlags.withParentIsRemoteFlags(flags, isParentContextRemote)); } private static int calculateSize( @@ -173,7 +179,8 @@ private static int calculateSize( SpanLinkMarshaler[] spanLinkMarshalers, int droppedLinksCount, SpanStatusMarshaler spanStatusMarshaler, - TraceFlags flags) { + TraceFlags flags, + boolean isParentContextRemote) { int size = 0; size += MarshalerUtil.sizeTraceId(Span.TRACE_ID, traceId); size += MarshalerUtil.sizeSpanId(Span.SPAN_ID, spanId); @@ -196,7 +203,9 @@ private static int calculateSize( size += MarshalerUtil.sizeUInt32(Span.DROPPED_LINKS_COUNT, droppedLinksCount); size += MarshalerUtil.sizeMessage(Span.STATUS, spanStatusMarshaler); - size += MarshalerUtil.sizeByteAsFixed32(Span.FLAGS, flags.asByte()); + size += + MarshalerUtil.sizeFixed32( + Span.FLAGS, SpanFlags.withParentIsRemoteFlags(flags, isParentContextRemote)); return size; } diff --git a/exporters/otlp/common/src/test/java/io/opentelemetry/exporter/internal/otlp/traces/SpanFlagsTest.java b/exporters/otlp/common/src/test/java/io/opentelemetry/exporter/internal/otlp/traces/SpanFlagsTest.java new file mode 100644 index 00000000000..481ffc2d23c --- /dev/null +++ b/exporters/otlp/common/src/test/java/io/opentelemetry/exporter/internal/otlp/traces/SpanFlagsTest.java @@ -0,0 +1,121 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.exporter.internal.otlp.traces; + +import static org.assertj.core.api.Assertions.assertThat; + +import io.opentelemetry.api.trace.TraceFlags; +import org.junit.jupiter.api.Test; + +/** Unit tests for {@link SpanFlags}. */ +public class SpanFlagsTest { + + @Test + void withParentIsRemoteFlags() { + assertThat(SpanFlags.withParentIsRemoteFlags(TraceFlags.fromByte((byte) 0xff), false)) + .isEqualTo(0x1ff); + assertThat(SpanFlags.withParentIsRemoteFlags(TraceFlags.fromByte((byte) 0x01), false)) + .isEqualTo(0x101); + assertThat(SpanFlags.withParentIsRemoteFlags(TraceFlags.fromByte((byte) 0x05), false)) + .isEqualTo(0x105); + assertThat(SpanFlags.withParentIsRemoteFlags(TraceFlags.fromByte((byte) 0x00), false)) + .isEqualTo(0x100); + + assertThat(SpanFlags.withParentIsRemoteFlags(TraceFlags.fromByte((byte) 0xff), true)) + .isEqualTo(0x3ff); + assertThat(SpanFlags.withParentIsRemoteFlags(TraceFlags.fromByte((byte) 0x01), true)) + .isEqualTo(0x301); + assertThat(SpanFlags.withParentIsRemoteFlags(TraceFlags.fromByte((byte) 0x05), true)) + .isEqualTo(0x305); + assertThat(SpanFlags.withParentIsRemoteFlags(TraceFlags.fromByte((byte) 0x00), true)) + .isEqualTo(0x300); + } + + @Test + void getTraceFlags() { + assertThat(SpanFlags.getTraceFlags(0x1ff)).isEqualTo(TraceFlags.fromByte((byte) 0xff)); + assertThat(SpanFlags.getTraceFlags(0xffffffff)).isEqualTo(TraceFlags.fromByte((byte) 0xff)); + assertThat(SpanFlags.getTraceFlags(0x000000ff)).isEqualTo(TraceFlags.fromByte((byte) 0xff)); + + assertThat(SpanFlags.getTraceFlags(0x100)).isEqualTo(TraceFlags.fromByte((byte) 0x00)); + assertThat(SpanFlags.getTraceFlags(0xffffff00)).isEqualTo(TraceFlags.fromByte((byte) 0x00)); + assertThat(SpanFlags.getTraceFlags(0x00000000)).isEqualTo(TraceFlags.fromByte((byte) 0x00)); + + assertThat(SpanFlags.getTraceFlags(0x101)).isEqualTo(TraceFlags.fromByte((byte) 0x01)); + assertThat(SpanFlags.getTraceFlags(0xffffff01)).isEqualTo(TraceFlags.fromByte((byte) 0x01)); + assertThat(SpanFlags.getTraceFlags(0x00000001)).isEqualTo(TraceFlags.fromByte((byte) 0x01)); + } + + @Test + void isKnownWhetherParentIsRemote() { + assertThat(SpanFlags.isKnownWhetherParentIsRemote(SpanFlags.CONTEXT_HAS_IS_REMOTE_BIT)) + .isTrue(); + assertThat( + SpanFlags.isKnownWhetherParentIsRemote( + 0x00000001 | SpanFlags.CONTEXT_HAS_IS_REMOTE_BIT)) + .isTrue(); + assertThat( + SpanFlags.isKnownWhetherParentIsRemote( + 0x10000000 | SpanFlags.CONTEXT_HAS_IS_REMOTE_BIT)) + .isTrue(); + assertThat( + SpanFlags.isKnownWhetherParentIsRemote( + 0x00000200 | SpanFlags.CONTEXT_HAS_IS_REMOTE_BIT)) + .isTrue(); + assertThat(SpanFlags.isKnownWhetherParentIsRemote(SpanFlags.CONTEXT_IS_REMOTE_MASK)).isTrue(); + assertThat(SpanFlags.isKnownWhetherParentIsRemote(0xffffffff)).isTrue(); + + assertThat(SpanFlags.isKnownWhetherParentIsRemote(~SpanFlags.CONTEXT_HAS_IS_REMOTE_BIT)) + .isFalse(); + assertThat( + SpanFlags.isKnownWhetherParentIsRemote( + 0x00000001 & ~SpanFlags.CONTEXT_HAS_IS_REMOTE_BIT)) + .isFalse(); + assertThat( + SpanFlags.isKnownWhetherParentIsRemote( + 0x10000000 & ~SpanFlags.CONTEXT_HAS_IS_REMOTE_BIT)) + .isFalse(); + assertThat( + SpanFlags.isKnownWhetherParentIsRemote( + 0x00000200 & ~SpanFlags.CONTEXT_HAS_IS_REMOTE_BIT)) + .isFalse(); + assertThat(SpanFlags.isKnownWhetherParentIsRemote(0x00000000)).isFalse(); + } + + @Test + void isParentRemote() { + assertThat( + SpanFlags.isParentRemote( + SpanFlags.CONTEXT_HAS_IS_REMOTE_BIT | SpanFlags.CONTEXT_IS_REMOTE_BIT)) + .isTrue(); + assertThat( + SpanFlags.isParentRemote( + 0x00000001 | SpanFlags.CONTEXT_HAS_IS_REMOTE_BIT | SpanFlags.CONTEXT_IS_REMOTE_BIT)) + .isTrue(); + assertThat( + SpanFlags.isParentRemote( + 0x10000000 | SpanFlags.CONTEXT_HAS_IS_REMOTE_BIT | SpanFlags.CONTEXT_IS_REMOTE_BIT)) + .isTrue(); + assertThat( + SpanFlags.isParentRemote( + 0x00000200 | SpanFlags.CONTEXT_HAS_IS_REMOTE_BIT | SpanFlags.CONTEXT_IS_REMOTE_BIT)) + .isTrue(); + assertThat(SpanFlags.isParentRemote(SpanFlags.CONTEXT_IS_REMOTE_MASK)).isTrue(); + assertThat(SpanFlags.isParentRemote(0xffffffff)).isTrue(); + + assertThat(SpanFlags.isParentRemote(SpanFlags.CONTEXT_HAS_IS_REMOTE_BIT)).isFalse(); + assertThat(SpanFlags.isParentRemote(~SpanFlags.CONTEXT_HAS_IS_REMOTE_BIT)).isFalse(); + assertThat(SpanFlags.isParentRemote(SpanFlags.CONTEXT_IS_REMOTE_BIT)).isFalse(); + assertThat(SpanFlags.isParentRemote(~SpanFlags.CONTEXT_IS_REMOTE_BIT)).isFalse(); + assertThat( + SpanFlags.isParentRemote( + ~SpanFlags.CONTEXT_HAS_IS_REMOTE_BIT & ~SpanFlags.CONTEXT_IS_REMOTE_BIT)) + .isFalse(); + assertThat(SpanFlags.isParentRemote(0x00000200 & ~SpanFlags.CONTEXT_HAS_IS_REMOTE_BIT)) + .isFalse(); + assertThat(SpanFlags.isParentRemote(0x00000000)).isFalse(); + } +} diff --git a/exporters/otlp/common/src/test/java/io/opentelemetry/exporter/internal/otlp/traces/TraceRequestMarshalerTest.java b/exporters/otlp/common/src/test/java/io/opentelemetry/exporter/internal/otlp/traces/TraceRequestMarshalerTest.java index 6bc17a22109..8ace6d3231a 100644 --- a/exporters/otlp/common/src/test/java/io/opentelemetry/exporter/internal/otlp/traces/TraceRequestMarshalerTest.java +++ b/exporters/otlp/common/src/test/java/io/opentelemetry/exporter/internal/otlp/traces/TraceRequestMarshalerTest.java @@ -56,7 +56,9 @@ class TraceRequestMarshalerTest { new byte[] {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4}; private static final String TRACE_ID = TraceId.fromBytes(TRACE_ID_BYTES); private static final byte[] SPAN_ID_BYTES = new byte[] {0, 0, 0, 0, 4, 3, 2, 1}; + private static final byte[] PARENT_SPAN_ID_BYTES = new byte[] {0, 0, 0, 0, 5, 6, 7, 8}; private static final String SPAN_ID = SpanId.fromBytes(SPAN_ID_BYTES); + private static final String PARENT_SPAN_ID = SpanId.fromBytes(PARENT_SPAN_ID_BYTES); private static final String TRACE_STATE_VALUE = "baz=qux,foo=bar"; private static final SpanContext SPAN_CONTEXT = SpanContext.create( @@ -65,6 +67,10 @@ class TraceRequestMarshalerTest { TraceFlags.getSampled(), TraceState.builder().put("foo", "bar").put("baz", "qux").build()); + private static final SpanContext PARENT_SPAN_CONTEXT = + SpanContext.createFromRemoteParent( + TRACE_ID, PARENT_SPAN_ID, TraceFlags.getSampled(), TraceState.builder().build()); + @Test void toProtoResourceSpans() { ResourceSpansMarshaler[] resourceSpansMarshalers = @@ -147,8 +153,10 @@ void toProtoSpan() { assertThat(protoSpan.getTraceId().toByteArray()).isEqualTo(TRACE_ID_BYTES); assertThat(protoSpan.getSpanId().toByteArray()).isEqualTo(SPAN_ID_BYTES); - assertThat(protoSpan.getFlags()) - .isEqualTo(((int) SPAN_CONTEXT.getTraceFlags().asByte()) & 0x00ff); + assertThat(protoSpan.getFlags() & 0xff) + .isEqualTo((SPAN_CONTEXT.getTraceFlags().asByte() & 0xff)); + assertThat(SpanFlags.isKnownWhetherParentIsRemote(protoSpan.getFlags())).isTrue(); + assertThat(SpanFlags.isParentRemote(protoSpan.getFlags())).isFalse(); assertThat(protoSpan.getTraceState()).isEqualTo(TRACE_STATE_VALUE); assertThat(protoSpan.getParentSpanId().toByteArray()).isEqualTo(new byte[] {}); assertThat(protoSpan.getName()).isEqualTo("GET /api/endpoint"); @@ -227,7 +235,9 @@ void toProtoSpan() { Span.Link.newBuilder() .setTraceId(ByteString.copyFrom(TRACE_ID_BYTES)) .setSpanId(ByteString.copyFrom(SPAN_ID_BYTES)) - .setFlags(SPAN_CONTEXT.getTraceFlags().asByte()) + .setFlags( + (SPAN_CONTEXT.getTraceFlags().asByte() & 0xff) + | SpanFlags.getHasParentIsRemoteMask()) .setTraceState(encodeTraceState(SPAN_CONTEXT.getTraceState())) .build()); assertThat(protoSpan.getDroppedLinksCount()).isEqualTo(1); // 2 - 1 @@ -235,6 +245,39 @@ void toProtoSpan() { .isEqualTo(Status.newBuilder().setCode(STATUS_CODE_OK).build()); } + @Test + void toProtoSpan_withRemoteParent() { + Span protoSpan = + parse( + Span.getDefaultInstance(), + SpanMarshaler.create( + TestSpanData.builder() + .setHasEnded(true) + .setSpanContext(SPAN_CONTEXT) + .setParentSpanContext(PARENT_SPAN_CONTEXT) + .setName("GET /api/endpoint") + .setKind(SpanKind.SERVER) + .setStartEpochNanos(12345) + .setEndEpochNanos(12349) + .setStatus(StatusData.ok()) + .build())); + + assertThat(protoSpan.getTraceId().toByteArray()).isEqualTo(TRACE_ID_BYTES); + assertThat(protoSpan.getSpanId().toByteArray()).isEqualTo(SPAN_ID_BYTES); + assertThat(protoSpan.getFlags() & 0xff) + .isEqualTo((SPAN_CONTEXT.getTraceFlags().asByte() & 0xff)); + assertThat(SpanFlags.isKnownWhetherParentIsRemote(protoSpan.getFlags())).isTrue(); + assertThat(SpanFlags.isParentRemote(protoSpan.getFlags())).isTrue(); + assertThat(protoSpan.getTraceState()).isEqualTo(TRACE_STATE_VALUE); + assertThat(protoSpan.getParentSpanId().toByteArray()).isEqualTo(PARENT_SPAN_ID_BYTES); + assertThat(protoSpan.getName()).isEqualTo("GET /api/endpoint"); + assertThat(protoSpan.getKind()).isEqualTo(SPAN_KIND_SERVER); + assertThat(protoSpan.getStartTimeUnixNano()).isEqualTo(12345); + assertThat(protoSpan.getEndTimeUnixNano()).isEqualTo(12349); + assertThat(protoSpan.getStatus()) + .isEqualTo(Status.newBuilder().setCode(STATUS_CODE_OK).build()); + } + @Test void toProtoSpanKind() { assertThat(SpanMarshaler.toProtoSpanKind(SpanKind.INTERNAL)) @@ -318,11 +361,29 @@ void toProtoSpanLink_WithoutAttributes() { Span.Link.newBuilder() .setTraceId(ByteString.copyFrom(TRACE_ID_BYTES)) .setSpanId(ByteString.copyFrom(SPAN_ID_BYTES)) - .setFlags(SPAN_CONTEXT.getTraceFlags().asByte()) + .setFlags( + (SPAN_CONTEXT.getTraceFlags().asByte() & 0xff) + | SpanFlags.getHasParentIsRemoteMask()) .setTraceState(TRACE_STATE_VALUE) .build()); } + @Test + void toProtoSpanLink_WithRemoteContext() { + assertThat( + parse( + Span.Link.getDefaultInstance(), + SpanLinkMarshaler.create(LinkData.create(PARENT_SPAN_CONTEXT)))) + .isEqualTo( + Span.Link.newBuilder() + .setTraceId(ByteString.copyFrom(TRACE_ID_BYTES)) + .setSpanId(ByteString.copyFrom(PARENT_SPAN_ID_BYTES)) + .setFlags( + (SPAN_CONTEXT.getTraceFlags().asByte() & 0xff) + | SpanFlags.getParentIsRemoteMask()) + .build()); + } + @Test void toProtoSpanLink_WithAttributes() { assertThat( @@ -335,7 +396,9 @@ void toProtoSpanLink_WithAttributes() { Span.Link.newBuilder() .setTraceId(ByteString.copyFrom(TRACE_ID_BYTES)) .setSpanId(ByteString.copyFrom(SPAN_ID_BYTES)) - .setFlags(SPAN_CONTEXT.getTraceFlags().asByte()) + .setFlags( + (SPAN_CONTEXT.getTraceFlags().asByte() & 0xff) + | SpanFlags.getHasParentIsRemoteMask()) .setTraceState(TRACE_STATE_VALUE) .addAttributes( KeyValue.newBuilder() From 0e0f4177608c454ef15790441016209504b3f424 Mon Sep 17 00:00:00 2001 From: Lauri Tulmin Date: Fri, 26 Apr 2024 19:21:35 +0300 Subject: [PATCH 369/901] Fix running tests with java 8 on macos (#6411) Co-authored-by: jack-berg <34418638+jack-berg@users.noreply.github.com> --- .github/workflows/build.yml | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index e4fe1b2afba..fa2a758d8b5 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -21,6 +21,7 @@ jobs: matrix: os: - macos-latest + - macos-13 - ubuntu-latest test-java-version: - 8 @@ -33,6 +34,16 @@ jobs: test-java-version: 21 coverage: true jmh-based-tests: true + # macos-latest drops support for java 8 temurin. Run java 8 on macos-13. Run java 11, 17, 21 on macos-latest. + exclude: + - os: macos-latest + test-java-version: 8 + - os: macos-13 + test-java-version: 11 + - os: macos-13 + test-java-version: 17 + - os: macos-13 + test-java-version: 21 steps: - uses: actions/checkout@v4 From 51ff6bcf335a488ff04b49514f9360f59f27677a Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 26 Apr 2024 12:53:10 -0700 Subject: [PATCH 370/901] Update dependency com.linecorp.armeria:armeria-bom to v1.28.3 (#6408) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- dependencyManagement/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index c2f616ed617..d784bbb97d7 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -11,7 +11,7 @@ val DEPENDENCY_BOMS = listOf( "com.fasterxml.jackson:jackson-bom:2.17.0", "com.google.guava:guava-bom:33.1.0-jre", "com.google.protobuf:protobuf-bom:3.25.3", - "com.linecorp.armeria:armeria-bom:1.28.2", + "com.linecorp.armeria:armeria-bom:1.28.3", "com.squareup.okhttp3:okhttp-bom:4.12.0", "com.squareup.okio:okio-bom:3.9.0", // applies to transitive dependencies of okhttp "io.grpc:grpc-bom:1.63.0", From 7e34b795936bc911fb98324be49249499e6f5e23 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 29 Apr 2024 08:02:57 -0700 Subject: [PATCH 371/901] Update dependency checkstyle to v10.16.0 (#6413) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- buildSrc/src/main/kotlin/otel.java-conventions.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/buildSrc/src/main/kotlin/otel.java-conventions.gradle.kts b/buildSrc/src/main/kotlin/otel.java-conventions.gradle.kts index c069c5473b8..a1445ef80a3 100644 --- a/buildSrc/src/main/kotlin/otel.java-conventions.gradle.kts +++ b/buildSrc/src/main/kotlin/otel.java-conventions.gradle.kts @@ -35,7 +35,7 @@ java { checkstyle { configDirectory.set(file("$rootDir/buildscripts/")) - toolVersion = "10.15.0" + toolVersion = "10.16.0" isIgnoreFailures = false configProperties["rootDir"] = rootDir } From 5781da112140ae2c07622eec20757374113bcef0 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 29 Apr 2024 08:03:24 -0700 Subject: [PATCH 372/901] Update dependency com.linecorp.armeria:armeria-bom to v1.28.4 (#6414) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- dependencyManagement/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index d784bbb97d7..02fdaa123b5 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -11,7 +11,7 @@ val DEPENDENCY_BOMS = listOf( "com.fasterxml.jackson:jackson-bom:2.17.0", "com.google.guava:guava-bom:33.1.0-jre", "com.google.protobuf:protobuf-bom:3.25.3", - "com.linecorp.armeria:armeria-bom:1.28.3", + "com.linecorp.armeria:armeria-bom:1.28.4", "com.squareup.okhttp3:okhttp-bom:4.12.0", "com.squareup.okio:okio-bom:3.9.0", // applies to transitive dependencies of okhttp "io.grpc:grpc-bom:1.63.0", From 9845ac94bdfb5f30585dfa35aacb10ee7c6f0290 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 29 Apr 2024 18:02:02 -0500 Subject: [PATCH 373/901] Update gradle/actions action to v3.3.2 (#6407) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/gradle-wrapper-validation.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/gradle-wrapper-validation.yml b/.github/workflows/gradle-wrapper-validation.yml index 70505e8a550..7ae0a27e360 100644 --- a/.github/workflows/gradle-wrapper-validation.yml +++ b/.github/workflows/gradle-wrapper-validation.yml @@ -13,4 +13,4 @@ jobs: steps: - uses: actions/checkout@v4 - - uses: gradle/actions/wrapper-validation@v3.3.1 + - uses: gradle/actions/wrapper-validation@v3.3.2 From 35bc345f7e7d33552aa8d6a18f5d2fe69f3cef82 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Serkan=20=C3=96ZAL?= Date: Tue, 30 Apr 2024 23:09:02 +0300 Subject: [PATCH 374/901] Ignore TLS components (SSLContext, TrustManager, KeyManager) if plain HTTP protocol is used for exporting (#6329) --- .../exporter/internal/grpc/GrpcExporterBuilder.java | 5 +++-- .../exporter/internal/http/HttpExporterBuilder.java | 5 +++-- .../sender/okhttp/internal/OkHttpGrpcSender.java | 13 +++++++++---- .../sender/okhttp/internal/OkHttpHttpSender.java | 9 ++++++++- .../jaeger/sampler/JaegerRemoteSamplerBuilder.java | 12 ++++++++---- 5 files changed, 31 insertions(+), 13 deletions(-) diff --git a/exporters/common/src/main/java/io/opentelemetry/exporter/internal/grpc/GrpcExporterBuilder.java b/exporters/common/src/main/java/io/opentelemetry/exporter/internal/grpc/GrpcExporterBuilder.java index ad0b8c86aaf..52dd51fe552 100644 --- a/exporters/common/src/main/java/io/opentelemetry/exporter/internal/grpc/GrpcExporterBuilder.java +++ b/exporters/common/src/main/java/io/opentelemetry/exporter/internal/grpc/GrpcExporterBuilder.java @@ -195,6 +195,7 @@ public GrpcExporter build() { return result; }; + boolean isPlainHttp = "http".equals(endpoint.getScheme()); GrpcSenderProvider grpcSenderProvider = resolveGrpcSenderProvider(); GrpcSender grpcSender = grpcSenderProvider.createSender( @@ -207,8 +208,8 @@ public GrpcExporter build() { grpcChannel, grpcStubFactory, retryPolicy, - tlsConfigHelper.getSslContext(), - tlsConfigHelper.getTrustManager()); + isPlainHttp ? null : tlsConfigHelper.getSslContext(), + isPlainHttp ? null : tlsConfigHelper.getTrustManager()); LOGGER.log(Level.FINE, "Using GrpcSender: " + grpcSender.getClass().getName()); return new GrpcExporter<>(exporterName, type, grpcSender, meterProviderSupplier); diff --git a/exporters/common/src/main/java/io/opentelemetry/exporter/internal/http/HttpExporterBuilder.java b/exporters/common/src/main/java/io/opentelemetry/exporter/internal/http/HttpExporterBuilder.java index c9087185ecb..8f1d441b154 100644 --- a/exporters/common/src/main/java/io/opentelemetry/exporter/internal/http/HttpExporterBuilder.java +++ b/exporters/common/src/main/java/io/opentelemetry/exporter/internal/http/HttpExporterBuilder.java @@ -185,6 +185,7 @@ public HttpExporter build() { return result; }; + boolean isPlainHttp = endpoint.startsWith("http://"); HttpSenderProvider httpSenderProvider = resolveHttpSenderProvider(); HttpSender httpSender = httpSenderProvider.createSender( @@ -198,8 +199,8 @@ public HttpExporter build() { proxyOptions, authenticator, retryPolicy, - tlsConfigHelper.getSslContext(), - tlsConfigHelper.getTrustManager()); + isPlainHttp ? null : tlsConfigHelper.getSslContext(), + isPlainHttp ? null : tlsConfigHelper.getTrustManager()); LOGGER.log(Level.FINE, "Using HttpSender: " + httpSender.getClass().getName()); return new HttpExporter<>(exporterName, type, httpSender, meterProviderSupplier, exportAsJson); diff --git a/exporters/sender/okhttp/src/main/java/io/opentelemetry/exporter/sender/okhttp/internal/OkHttpGrpcSender.java b/exporters/sender/okhttp/src/main/java/io/opentelemetry/exporter/sender/okhttp/internal/OkHttpGrpcSender.java index 3c5cb153e12..d9ceecb77b7 100644 --- a/exporters/sender/okhttp/src/main/java/io/opentelemetry/exporter/sender/okhttp/internal/OkHttpGrpcSender.java +++ b/exporters/sender/okhttp/src/main/java/io/opentelemetry/exporter/sender/okhttp/internal/OkHttpGrpcSender.java @@ -47,6 +47,7 @@ import javax.net.ssl.X509TrustManager; import okhttp3.Call; import okhttp3.Callback; +import okhttp3.ConnectionSpec; import okhttp3.HttpUrl; import okhttp3.OkHttpClient; import okhttp3.Protocol; @@ -89,14 +90,18 @@ public OkHttpGrpcSender( clientBuilder.addInterceptor( new RetryInterceptor(retryPolicy, OkHttpGrpcSender::isRetryable)); } - if (sslContext != null && trustManager != null) { - clientBuilder.sslSocketFactory(sslContext.getSocketFactory(), trustManager); - } - if (endpoint.startsWith("http://")) { + + boolean isPlainHttp = endpoint.startsWith("http://"); + if (isPlainHttp) { + clientBuilder.connectionSpecs(Collections.singletonList(ConnectionSpec.CLEARTEXT)); clientBuilder.protocols(Collections.singletonList(Protocol.H2_PRIOR_KNOWLEDGE)); } else { clientBuilder.protocols(Arrays.asList(Protocol.HTTP_2, Protocol.HTTP_1_1)); + if (sslContext != null && trustManager != null) { + clientBuilder.sslSocketFactory(sslContext.getSocketFactory(), trustManager); + } } + this.client = clientBuilder.build(); this.headersSupplier = headersSupplier; this.url = HttpUrl.get(endpoint); diff --git a/exporters/sender/okhttp/src/main/java/io/opentelemetry/exporter/sender/okhttp/internal/OkHttpHttpSender.java b/exporters/sender/okhttp/src/main/java/io/opentelemetry/exporter/sender/okhttp/internal/OkHttpHttpSender.java index 5d0c839046b..8b85396ce08 100644 --- a/exporters/sender/okhttp/src/main/java/io/opentelemetry/exporter/sender/okhttp/internal/OkHttpHttpSender.java +++ b/exporters/sender/okhttp/src/main/java/io/opentelemetry/exporter/sender/okhttp/internal/OkHttpHttpSender.java @@ -16,6 +16,7 @@ import io.opentelemetry.sdk.common.export.RetryPolicy; import java.io.IOException; import java.time.Duration; +import java.util.Collections; import java.util.List; import java.util.Map; import java.util.function.Consumer; @@ -25,6 +26,7 @@ import javax.net.ssl.X509TrustManager; import okhttp3.Call; import okhttp3.Callback; +import okhttp3.ConnectionSpec; import okhttp3.HttpUrl; import okhttp3.MediaType; import okhttp3.OkHttpClient; @@ -88,9 +90,14 @@ public OkHttpHttpSender( if (retryPolicy != null) { builder.addInterceptor(new RetryInterceptor(retryPolicy, OkHttpHttpSender::isRetryable)); } - if (sslContext != null && trustManager != null) { + + boolean isPlainHttp = endpoint.startsWith("http://"); + if (isPlainHttp) { + builder.connectionSpecs(Collections.singletonList(ConnectionSpec.CLEARTEXT)); + } else if (sslContext != null && trustManager != null) { builder.sslSocketFactory(sslContext.getSocketFactory(), trustManager); } + this.client = builder.build(); this.url = HttpUrl.get(endpoint); this.compressor = compressor; diff --git a/sdk-extensions/jaeger-remote-sampler/src/main/java/io/opentelemetry/sdk/extension/trace/jaeger/sampler/JaegerRemoteSamplerBuilder.java b/sdk-extensions/jaeger-remote-sampler/src/main/java/io/opentelemetry/sdk/extension/trace/jaeger/sampler/JaegerRemoteSamplerBuilder.java index 4cb4f6f4970..24dfac82acc 100644 --- a/sdk-extensions/jaeger-remote-sampler/src/main/java/io/opentelemetry/sdk/extension/trace/jaeger/sampler/JaegerRemoteSamplerBuilder.java +++ b/sdk-extensions/jaeger-remote-sampler/src/main/java/io/opentelemetry/sdk/extension/trace/jaeger/sampler/JaegerRemoteSamplerBuilder.java @@ -21,6 +21,7 @@ import javax.annotation.Nullable; import javax.net.ssl.SSLContext; import javax.net.ssl.X509TrustManager; +import okhttp3.ConnectionSpec; import okhttp3.Headers; import okhttp3.OkHttpClient; import okhttp3.Protocol; @@ -165,14 +166,17 @@ public JaegerRemoteSampler build() { clientBuilder.callTimeout(Duration.ofNanos(TimeUnit.SECONDS.toNanos(DEFAULT_TIMEOUT_SECS))); - SSLContext sslContext = tlsConfigHelper.getSslContext(); - X509TrustManager trustManager = tlsConfigHelper.getTrustManager(); + String endpoint = this.endpoint.resolve(GRPC_ENDPOINT_PATH).toString(); + boolean isPlainHttp = endpoint.startsWith("http://"); + + SSLContext sslContext = isPlainHttp ? null : tlsConfigHelper.getSslContext(); + X509TrustManager trustManager = isPlainHttp ? null : tlsConfigHelper.getTrustManager(); if (sslContext != null && trustManager != null) { clientBuilder.sslSocketFactory(sslContext.getSocketFactory(), trustManager); } - String endpoint = this.endpoint.resolve(GRPC_ENDPOINT_PATH).toString(); - if (endpoint.startsWith("http://")) { + if (isPlainHttp) { + clientBuilder.connectionSpecs(Collections.singletonList(ConnectionSpec.CLEARTEXT)); clientBuilder.protocols(Collections.singletonList(Protocol.H2_PRIOR_KNOWLEDGE)); } else { clientBuilder.protocols(Arrays.asList(Protocol.HTTP_2, Protocol.HTTP_1_1)); From e1f707e8dc8ec60961c67a747b99dac80b135bac Mon Sep 17 00:00:00 2001 From: jack-berg <34418638+jack-berg@users.noreply.github.com> Date: Wed, 1 May 2024 10:00:36 -0500 Subject: [PATCH 375/901] Fix opencensus shim spanBuilderWithRemoteParent behavior (#6415) --- .../OpenTelemetrySpanBuilderImpl.java | 6 +++- .../opencensusshim/SpanConverter.java | 19 ++++++++---- .../opencensusshim/InteroperabilityTest.java | 30 ++++++++++++++----- 3 files changed, 41 insertions(+), 14 deletions(-) diff --git a/opencensus-shim/src/main/java/io/opentelemetry/opencensusshim/OpenTelemetrySpanBuilderImpl.java b/opencensus-shim/src/main/java/io/opentelemetry/opencensusshim/OpenTelemetrySpanBuilderImpl.java index ede66642e06..023180bb870 100644 --- a/opencensus-shim/src/main/java/io/opentelemetry/opencensusshim/OpenTelemetrySpanBuilderImpl.java +++ b/opencensus-shim/src/main/java/io/opentelemetry/opencensusshim/OpenTelemetrySpanBuilderImpl.java @@ -164,7 +164,11 @@ public Span startSpan() { otelSpanBuilder.setParent(Context.current().with((OpenTelemetrySpanImpl) ocParent)); } if (ocRemoteParentSpanContext != null) { - otelSpanBuilder.addLink(SpanConverter.mapSpanContext(ocRemoteParentSpanContext)); + io.opentelemetry.api.trace.SpanContext spanContext = + SpanConverter.mapSpanContext(ocRemoteParentSpanContext, /* isRemoteParent= */ true); + otelSpanBuilder.setParent( + Context.current().with(io.opentelemetry.api.trace.Span.wrap(spanContext))); + otelSpanBuilder.addLink(spanContext); } if (otelKind != null) { otelSpanBuilder.setSpanKind(otelKind); diff --git a/opencensus-shim/src/main/java/io/opentelemetry/opencensusshim/SpanConverter.java b/opencensus-shim/src/main/java/io/opentelemetry/opencensusshim/SpanConverter.java index fc559d2d063..cf031586e60 100644 --- a/opencensus-shim/src/main/java/io/opentelemetry/opencensusshim/SpanConverter.java +++ b/opencensus-shim/src/main/java/io/opentelemetry/opencensusshim/SpanConverter.java @@ -57,13 +57,22 @@ static SpanContext mapSpanContext(io.opentelemetry.api.trace.SpanContext otelSpa } static io.opentelemetry.api.trace.SpanContext mapSpanContext(SpanContext ocSpanContext) { - return io.opentelemetry.api.trace.SpanContext.create( - ocSpanContext.getTraceId().toLowerBase16(), - ocSpanContext.getSpanId().toLowerBase16(), + return mapSpanContext(ocSpanContext, /* isRemoteParent= */ false); + } + + static io.opentelemetry.api.trace.SpanContext mapSpanContext( + SpanContext ocSpanContext, boolean isRemoteParent) { + String traceId = ocSpanContext.getTraceId().toLowerBase16(); + String spanId = ocSpanContext.getSpanId().toLowerBase16(); + TraceFlags traceFlags = ocSpanContext.getTraceOptions().isSampled() ? TraceFlags.getSampled() - : TraceFlags.getDefault(), - mapTracestate(ocSpanContext.getTracestate())); + : TraceFlags.getDefault(); + TraceState traceState = mapTracestate(ocSpanContext.getTracestate()); + return isRemoteParent + ? io.opentelemetry.api.trace.SpanContext.createFromRemoteParent( + traceId, spanId, traceFlags, traceState) + : io.opentelemetry.api.trace.SpanContext.create(traceId, spanId, traceFlags, traceState); } private static TraceState mapTracestate(Tracestate tracestate) { diff --git a/opencensus-shim/src/test/java/io/opentelemetry/opencensusshim/InteroperabilityTest.java b/opencensus-shim/src/test/java/io/opentelemetry/opencensusshim/InteroperabilityTest.java index 33c21b00c30..4d2fefc7242 100644 --- a/opencensus-shim/src/test/java/io/opentelemetry/opencensusshim/InteroperabilityTest.java +++ b/opencensus-shim/src/test/java/io/opentelemetry/opencensusshim/InteroperabilityTest.java @@ -44,6 +44,7 @@ import io.opentelemetry.sdk.trace.data.StatusData; import io.opentelemetry.sdk.trace.export.SimpleSpanProcessor; import io.opentelemetry.sdk.trace.export.SpanExporter; +import io.opentelemetry.sdk.trace.samplers.Sampler; import java.util.Collection; import java.util.concurrent.TimeUnit; import org.junit.jupiter.api.BeforeEach; @@ -71,7 +72,11 @@ class InteroperabilityTest { SpanProcessor spanProcessor = SimpleSpanProcessor.create(spanExporter); openTelemetry = OpenTelemetrySdk.builder() - .setTracerProvider(SdkTracerProvider.builder().addSpanProcessor(spanProcessor).build()) + .setTracerProvider( + SdkTracerProvider.builder() + .setSampler(Sampler.alwaysOn()) + .addSpanProcessor(spanProcessor) + .build()) .buildAndRegisterGlobal(); } @@ -84,7 +89,7 @@ void resetMocks() { } @Test - void testParentChildRelationshipsAreExportedCorrectly() { + void parentChildRelationshipsAreExportedCorrectly() { Tracer tracer = openTelemetry.getTracer("io.opentelemetry.test.scoped.span.1"); Span span = tracer.spanBuilder("OpenTelemetrySpan").startSpan(); try (Scope scope = Context.current().with(span).makeCurrent()) { @@ -128,7 +133,7 @@ void testParentChildRelationshipsAreExportedCorrectly() { } @Test - void testRemoteParent() { + void remoteParent() { io.opencensus.trace.Tracer tracer = Tracing.getTracer(); io.opencensus.trace.Span remoteParentSpan = tracer.spanBuilder("remote parent span").startSpan(); @@ -148,6 +153,15 @@ void testRemoteParent() { assertThat(export1.size()).isEqualTo(1); SpanData spanData1 = export1.iterator().next(); + + // Remote parent should be set to parent span context + assertThat(spanData1.getParentSpanContext().isRemote()).isTrue(); + assertThat(spanData1.getParentSpanContext().getTraceId()) + .isEqualTo(remoteParentSpan.getContext().getTraceId().toLowerBase16()); + assertThat(spanData1.getParentSpanContext().getSpanId()) + .isEqualTo(remoteParentSpan.getContext().getSpanId().toLowerBase16()); + + // Remote parent should be added as link assertThat(spanData1.getName()).isEqualTo("OpenCensusSpan"); assertThat(spanData1.getLinks().get(0).getSpanContext().getSpanId()) .isEqualTo(remoteParentSpan.getContext().getSpanId().toLowerBase16()); @@ -155,7 +169,7 @@ void testRemoteParent() { @Test @SuppressLogger(OpenTelemetrySpanImpl.class) - void testParentChildRelationshipsAreExportedCorrectlyForOpenCensusOnly() { + void parentChildRelationshipsAreExportedCorrectlyForOpenCensusOnly() { io.opencensus.trace.Tracer tracer = Tracing.getTracer(); io.opencensus.trace.Span parentLinkSpan = tracer.spanBuilder("parent link span").startSpan(); try (io.opencensus.common.Scope scope = @@ -261,7 +275,7 @@ void testParentChildRelationshipsAreExportedCorrectlyForOpenCensusOnly() { } @Test - void testOpenTelemetryMethodsOnOpenCensusSpans() { + void openTelemetryMethodsOnOpenCensusSpans() { io.opencensus.trace.Tracer tracer = Tracing.getTracer(); try (io.opencensus.common.Scope scope = tracer @@ -308,7 +322,7 @@ void testOpenTelemetryMethodsOnOpenCensusSpans() { } @Test - public void testNoSampleDoesNotExport() { + public void noSampleDoesNotExport() { io.opencensus.trace.Tracer tracer = Tracing.getTracer(); try (io.opencensus.common.Scope scope = tracer.spanBuilder("OpenCensusSpan").setSampler(Samplers.neverSample()).startScopedSpan()) { @@ -324,14 +338,14 @@ public void testNoSampleDoesNotExport() { } @Test - public void testOpenCensusSamplerIsAlwaysOn() { + public void openCensusSamplerIsAlwaysOn() { // OpenTelemetryTraceComponentImpl provides this behavior assertThat(Tracing.getTraceConfig().getActiveTraceParams().getSampler()) .isEqualTo(Samplers.alwaysSample()); } @Test - public void testByDefaultDoesExport() { + public void byDefaultDoesExport() { io.opencensus.trace.Tracer tracer = Tracing.getTracer(); try (io.opencensus.common.Scope scope = tracer.spanBuilder("OpenCensusSpan").setRecordEvents(false).startScopedSpan()) { From 2e59f5477f255058ff03b8f177d8eec8aadbf92c Mon Sep 17 00:00:00 2001 From: Lauri Tulmin Date: Wed, 1 May 2024 18:03:37 +0300 Subject: [PATCH 376/901] Low allocation OTLP trace marshaler (#6410) --- .../api/internal/OtelEncodingUtils.java | 9 +- .../internal/marshal/JsonSerializer.java | 46 ++ .../internal/marshal/MarshalerContext.java | 226 +++++++++ .../internal/marshal/ProtoSerializer.java | 70 +++ .../exporter/internal/marshal/Serializer.java | 265 ++++++++++- .../internal/marshal/StatelessMarshaler.java | 28 ++ .../internal/marshal/StatelessMarshaler2.java | 28 ++ .../marshal/StatelessMarshalerUtil.java | 436 ++++++++++++++++++ .../marshal/StatelessMarshalerUtilTest.java | 68 +++ .../otlp/RequestMarshalBenchmarks.java | 66 ++- .../internal/otlp/StringMarshalBenchmark.java | 121 +++++ .../internal/otlp/StringMarshalState.java | 37 ++ .../internal/otlp/TestOutputStream.java | 15 +- .../otlp/ArrayAnyValueStatelessMarshaler.java | 88 ++++ .../otlp/BoolAnyValueStatelessMarshaler.java | 29 ++ .../DoubleAnyValueStatelessMarshaler.java | 29 ++ .../otlp/IntAnyValueStatelessMarshaler.java | 28 ++ .../otlp/KeyValueStatelessMarshaler.java | 142 ++++++ .../StringAnyValueStatelessMarshaler.java | 34 ++ ...mentationScopeSpansStatelessMarshaler.java | 63 +++ .../LowAllocationTraceRequestMarshaler.java | 107 +++++ .../ResourceSpansStatelessMarshaler.java | 80 ++++ .../traces/SpanEventStatelessMarshaler.java | 49 ++ .../otlp/traces/SpanLinkMarshaler.java | 16 +- .../traces/SpanLinkStatelessMarshaler.java | 65 +++ .../internal/otlp/traces/SpanMarshaler.java | 20 +- .../otlp/traces/SpanStatelessMarshaler.java | 117 +++++ .../otlp/traces/SpanStatusMarshaler.java | 17 +- .../traces/SpanStatusStatelessMarshaler.java | 45 ++ ...owAllocationTraceRequestMarshalerTest.java | 159 +++++++ .../traces/TraceRequestMarshalerTest.java | 134 +++++- 31 files changed, 2575 insertions(+), 62 deletions(-) create mode 100644 exporters/common/src/main/java/io/opentelemetry/exporter/internal/marshal/MarshalerContext.java create mode 100644 exporters/common/src/main/java/io/opentelemetry/exporter/internal/marshal/StatelessMarshaler.java create mode 100644 exporters/common/src/main/java/io/opentelemetry/exporter/internal/marshal/StatelessMarshaler2.java create mode 100644 exporters/common/src/main/java/io/opentelemetry/exporter/internal/marshal/StatelessMarshalerUtil.java create mode 100644 exporters/common/src/test/java/io/opentelemetry/exporter/internal/marshal/StatelessMarshalerUtilTest.java create mode 100644 exporters/otlp/common/src/jmh/java/io/opentelemetry/exporter/internal/otlp/StringMarshalBenchmark.java create mode 100644 exporters/otlp/common/src/jmh/java/io/opentelemetry/exporter/internal/otlp/StringMarshalState.java create mode 100644 exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/ArrayAnyValueStatelessMarshaler.java create mode 100644 exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/BoolAnyValueStatelessMarshaler.java create mode 100644 exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/DoubleAnyValueStatelessMarshaler.java create mode 100644 exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/IntAnyValueStatelessMarshaler.java create mode 100644 exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/KeyValueStatelessMarshaler.java create mode 100644 exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/StringAnyValueStatelessMarshaler.java create mode 100644 exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/traces/InstrumentationScopeSpansStatelessMarshaler.java create mode 100644 exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/traces/LowAllocationTraceRequestMarshaler.java create mode 100644 exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/traces/ResourceSpansStatelessMarshaler.java create mode 100644 exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/traces/SpanEventStatelessMarshaler.java create mode 100644 exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/traces/SpanLinkStatelessMarshaler.java create mode 100644 exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/traces/SpanStatelessMarshaler.java create mode 100644 exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/traces/SpanStatusStatelessMarshaler.java create mode 100644 exporters/otlp/common/src/test/java/io/opentelemetry/exporter/internal/otlp/traces/LowAllocationTraceRequestMarshalerTest.java diff --git a/api/all/src/main/java/io/opentelemetry/api/internal/OtelEncodingUtils.java b/api/all/src/main/java/io/opentelemetry/api/internal/OtelEncodingUtils.java index ba8e99fe1c3..bb6a5484488 100644 --- a/api/all/src/main/java/io/opentelemetry/api/internal/OtelEncodingUtils.java +++ b/api/all/src/main/java/io/opentelemetry/api/internal/OtelEncodingUtils.java @@ -89,10 +89,15 @@ public static void longToBase16String(long value, char[] dest, int destOffset) { /** Returns the {@code byte[]} decoded from the given hex {@link CharSequence}. */ public static byte[] bytesFromBase16(CharSequence value, int length) { byte[] result = new byte[length / 2]; + bytesFromBase16(value, length, result); + return result; + } + + /** Fills {@code bytes} with bytes decoded from the given hex {@link CharSequence}. */ + public static void bytesFromBase16(CharSequence value, int length, byte[] bytes) { for (int i = 0; i < length; i += 2) { - result[i / 2] = byteFromBase16(value.charAt(i), value.charAt(i + 1)); + bytes[i / 2] = byteFromBase16(value.charAt(i), value.charAt(i + 1)); } - return result; } /** Fills {@code dest} with the hex encoding of {@code bytes}. */ diff --git a/exporters/common/src/main/java/io/opentelemetry/exporter/internal/marshal/JsonSerializer.java b/exporters/common/src/main/java/io/opentelemetry/exporter/internal/marshal/JsonSerializer.java index f4745e68cba..37d18598762 100644 --- a/exporters/common/src/main/java/io/opentelemetry/exporter/internal/marshal/JsonSerializer.java +++ b/exporters/common/src/main/java/io/opentelemetry/exporter/internal/marshal/JsonSerializer.java @@ -108,6 +108,14 @@ public void writeString(ProtoFieldInfo field, byte[] utf8Bytes) throws IOExcepti generator.writeString(new String(utf8Bytes, StandardCharsets.UTF_8)); } + @Override + public void writeString( + ProtoFieldInfo field, String string, int utf8Length, MarshalerContext context) + throws IOException { + generator.writeFieldName(field.getJsonName()); + generator.writeString(string); + } + @Override public void writeBytes(ProtoFieldInfo field, byte[] value) throws IOException { generator.writeBinaryField(field.getJsonName(), value); @@ -165,6 +173,44 @@ public void serializeRepeatedMessage( generator.writeEndArray(); } + @Override + public void serializeRepeatedMessageWithContext( + ProtoFieldInfo field, + List messages, + StatelessMarshaler marshaler, + MarshalerContext context) + throws IOException { + generator.writeArrayFieldStart(field.getJsonName()); + for (int i = 0; i < messages.size(); i++) { + T message = messages.get(i); + generator.writeStartObject(); + marshaler.writeTo(this, message, context); + generator.writeEndObject(); + } + generator.writeEndArray(); + } + + @Override + protected void writeStartRepeated(ProtoFieldInfo field) throws IOException { + generator.writeArrayFieldStart(field.getJsonName()); + } + + @Override + protected void writeEndRepeated() throws IOException { + generator.writeEndArray(); + } + + @Override + protected void writeStartRepeatedElement(ProtoFieldInfo field, int protoMessageSize) + throws IOException { + generator.writeStartObject(); + } + + @Override + protected void writeEndRepeatedElement() throws IOException { + generator.writeEndObject(); + } + // Not a field. void writeMessageValue(Marshaler message) throws IOException { generator.writeStartObject(); diff --git a/exporters/common/src/main/java/io/opentelemetry/exporter/internal/marshal/MarshalerContext.java b/exporters/common/src/main/java/io/opentelemetry/exporter/internal/marshal/MarshalerContext.java new file mode 100644 index 00000000000..fab949aeb71 --- /dev/null +++ b/exporters/common/src/main/java/io/opentelemetry/exporter/internal/marshal/MarshalerContext.java @@ -0,0 +1,226 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.exporter.internal.marshal; + +import io.opentelemetry.api.trace.SpanId; +import io.opentelemetry.api.trace.TraceId; +import java.util.ArrayList; +import java.util.IdentityHashMap; +import java.util.List; +import java.util.Map; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.function.Consumer; +import java.util.function.Supplier; +import javax.annotation.Nullable; + +/** + * Class for keeping marshaling state. The state consists of integers, that we call sizes, and + * objects, that we call data. Both integers and objects can be read from the state in the order + * they were added (first in, first out). Additionally, this class provides various pools and caches + * for objects that can be reused between marshalling attempts. + */ +public final class MarshalerContext { + private final boolean marshalStringNoAllocation; + + private int[] sizes = new int[16]; + private int sizeReadIndex; + private int sizeWriteIndex; + private Object[] data = new Object[16]; + private int dataReadIndex; + private int dataWriteIndex; + + @SuppressWarnings("BooleanParameter") + public MarshalerContext() { + this(true); + } + + public MarshalerContext(boolean marshalStringNoAllocation) { + this.marshalStringNoAllocation = marshalStringNoAllocation; + } + + public boolean marshalStringNoAllocation() { + return marshalStringNoAllocation; + } + + public void addSize(int size) { + growSizeIfNeeded(); + sizes[sizeWriteIndex++] = size; + } + + public int addSize() { + growSizeIfNeeded(); + return sizeWriteIndex++; + } + + private void growSizeIfNeeded() { + if (sizeWriteIndex == sizes.length) { + int[] newSizes = new int[sizes.length * 2]; + System.arraycopy(sizes, 0, newSizes, 0, sizes.length); + sizes = newSizes; + } + } + + public void setSize(int index, int size) { + sizes[index] = size; + } + + public int getSize() { + return sizes[sizeReadIndex++]; + } + + public void addData(@Nullable Object o) { + growDataIfNeeded(); + data[dataWriteIndex++] = o; + } + + private void growDataIfNeeded() { + if (dataWriteIndex == data.length) { + Object[] newData = new Object[data.length * 2]; + System.arraycopy(data, 0, newData, 0, data.length); + data = newData; + } + } + + public T getData(Class type) { + return type.cast(data[dataReadIndex++]); + } + + private final IdPool traceIdPool = new IdPool(TraceId.getLength() / 2); + + /** Returns a buffer that can be used to hold a trace id. */ + public byte[] getTraceIdBuffer() { + return traceIdPool.get(); + } + + private final IdPool spanIdPool = new IdPool(SpanId.getLength() / 2); + + /** Returns a buffer that can be used to hold a span id. */ + public byte[] getSpanIdBuffer() { + return spanIdPool.get(); + } + + private static class IdPool { + private final List pool = new ArrayList<>(); + int index; + final int idSize; + + IdPool(int idSize) { + this.idSize = idSize; + } + + byte[] get() { + if (index < pool.size()) { + return pool.get(index++); + } + byte[] result = new byte[idSize]; + pool.add(result); + index++; + + return result; + } + + void reset() { + index = 0; + } + } + + private final Pool> mapPool = new Pool<>(IdentityHashMap::new, Map::clear); + + /** Returns a pooled identity map. */ + @SuppressWarnings("unchecked") + public Map getIdentityMap() { + return (Map) mapPool.get(); + } + + private final Pool> listPool = new Pool<>(ArrayList::new, List::clear); + + /** Returns a pooled list. */ + @SuppressWarnings("unchecked") + public List getList() { + return (List) listPool.get(); + } + + private static class Pool { + private final List pool = new ArrayList<>(); + private int index; + private final Supplier factory; + private final Consumer clean; + + Pool(Supplier factory, Consumer clean) { + this.factory = factory; + this.clean = clean; + } + + T get() { + if (index < pool.size()) { + return pool.get(index++); + } + T result = factory.get(); + pool.add(result); + index++; + + return result; + } + + void reset() { + for (int i = 0; i < index; i++) { + clean.accept(pool.get(i)); + } + index = 0; + } + } + + /** Reset context so that serialization could be re-run. */ + public void resetReadIndex() { + sizeReadIndex = 0; + dataReadIndex = 0; + } + + /** Reset context so that it could be reused. */ + public void reset() { + sizeReadIndex = 0; + sizeWriteIndex = 0; + for (int i = 0; i < dataWriteIndex; i++) { + data[i] = null; + } + dataReadIndex = 0; + dataWriteIndex = 0; + + traceIdPool.reset(); + spanIdPool.reset(); + + mapPool.reset(); + listPool.reset(); + } + + private static final AtomicInteger KEY_INDEX = new AtomicInteger(); + + public static class Key { + final int index = KEY_INDEX.getAndIncrement(); + } + + public static Key key() { + return new Key(); + } + + private Object[] instances = new Object[16]; + + @SuppressWarnings("unchecked") + public T getInstance(Key key, Supplier supplier) { + if (key.index >= instances.length) { + Object[] newData = new Object[instances.length * 2]; + System.arraycopy(instances, 0, newData, 0, instances.length); + instances = newData; + } + + T result = (T) instances[key.index]; + if (result == null) { + result = supplier.get(); + instances[key.index] = result; + } + return result; + } +} diff --git a/exporters/common/src/main/java/io/opentelemetry/exporter/internal/marshal/ProtoSerializer.java b/exporters/common/src/main/java/io/opentelemetry/exporter/internal/marshal/ProtoSerializer.java index 16015fe6bbf..3149de80f6b 100644 --- a/exporters/common/src/main/java/io/opentelemetry/exporter/internal/marshal/ProtoSerializer.java +++ b/exporters/common/src/main/java/io/opentelemetry/exporter/internal/marshal/ProtoSerializer.java @@ -40,6 +40,18 @@ protected void writeTraceId(ProtoFieldInfo field, String traceId) throws IOExcep writeBytes(field, traceIdBytes); } + @Override + protected void writeTraceId(ProtoFieldInfo field, String traceId, MarshalerContext context) + throws IOException { + byte[] traceIdBytes = idCache.get(traceId); + if (traceIdBytes == null) { + traceIdBytes = context.getTraceIdBuffer(); + OtelEncodingUtils.bytesFromBase16(traceId, TraceId.getLength(), traceIdBytes); + idCache.put(traceId, traceIdBytes); + } + writeBytes(field, traceIdBytes); + } + @Override protected void writeSpanId(ProtoFieldInfo field, String spanId) throws IOException { byte[] spanIdBytes = @@ -48,6 +60,18 @@ protected void writeSpanId(ProtoFieldInfo field, String spanId) throws IOExcepti writeBytes(field, spanIdBytes); } + @Override + protected void writeSpanId(ProtoFieldInfo field, String spanId, MarshalerContext context) + throws IOException { + byte[] spanIdBytes = idCache.get(spanId); + if (spanIdBytes == null) { + spanIdBytes = context.getSpanIdBuffer(); + OtelEncodingUtils.bytesFromBase16(spanId, SpanId.getLength(), spanIdBytes); + idCache.put(spanId, spanIdBytes); + } + writeBytes(field, spanIdBytes); + } + @Override public void writeBool(ProtoFieldInfo field, boolean value) throws IOException { output.writeUInt32NoTag(field.getTag()); @@ -122,6 +146,16 @@ public void writeString(ProtoFieldInfo field, byte[] utf8Bytes) throws IOExcepti writeBytes(field, utf8Bytes); } + @Override + public void writeString( + ProtoFieldInfo field, String string, int utf8Length, MarshalerContext context) + throws IOException { + output.writeUInt32NoTag(field.getTag()); + output.writeUInt32NoTag(utf8Length); + + StatelessMarshalerUtil.writeUtf8(output, string, utf8Length, context); + } + @Override public void writeBytes(ProtoFieldInfo field, byte[] value) throws IOException { output.writeUInt32NoTag(field.getTag()); @@ -179,6 +213,42 @@ public void serializeRepeatedMessage( } } + @Override + public void serializeRepeatedMessageWithContext( + ProtoFieldInfo field, + List messages, + StatelessMarshaler marshaler, + MarshalerContext context) + throws IOException { + for (int i = 0; i < messages.size(); i++) { + T message = messages.get(i); + writeStartMessage(field, context.getSize()); + marshaler.writeTo(this, message, context); + writeEndMessage(); + } + } + + @Override + protected void writeStartRepeated(ProtoFieldInfo field) { + // Do nothing + } + + @Override + protected void writeEndRepeated() { + // Do nothing + } + + @Override + protected void writeStartRepeatedElement(ProtoFieldInfo field, int protoMessageSize) + throws IOException { + writeStartMessage(field, protoMessageSize); + } + + @Override + protected void writeEndRepeatedElement() { + writeEndMessage(); + } + @Override public void writeSerializedMessage(byte[] protoSerialized, String jsonSerialized) throws IOException { diff --git a/exporters/common/src/main/java/io/opentelemetry/exporter/internal/marshal/Serializer.java b/exporters/common/src/main/java/io/opentelemetry/exporter/internal/marshal/Serializer.java index ba182316add..45a855ee131 100644 --- a/exporters/common/src/main/java/io/opentelemetry/exporter/internal/marshal/Serializer.java +++ b/exporters/common/src/main/java/io/opentelemetry/exporter/internal/marshal/Serializer.java @@ -5,9 +5,15 @@ package io.opentelemetry.exporter.internal.marshal; +import io.opentelemetry.api.common.AttributeKey; +import io.opentelemetry.api.common.Attributes; import io.opentelemetry.sdk.internal.DynamicPrimitiveLongList; import java.io.IOException; +import java.util.Collection; import java.util.List; +import java.util.Map; +import java.util.function.BiConsumer; +import java.util.function.Consumer; import javax.annotation.Nullable; /** @@ -23,6 +29,7 @@ * at any time. */ public abstract class Serializer implements AutoCloseable { + private static final MarshalerContext.Key ATTRIBUTES_WRITER_KEY = MarshalerContext.key(); Serializer() {} @@ -34,8 +41,21 @@ public void serializeTraceId(ProtoFieldInfo field, @Nullable String traceId) thr writeTraceId(field, traceId); } + public void serializeTraceId( + ProtoFieldInfo field, @Nullable String traceId, MarshalerContext context) throws IOException { + if (traceId == null) { + return; + } + writeTraceId(field, traceId, context); + } + protected abstract void writeTraceId(ProtoFieldInfo field, String traceId) throws IOException; + protected void writeTraceId(ProtoFieldInfo field, String traceId, MarshalerContext context) + throws IOException { + writeTraceId(field, traceId); + } + /** Serializes a span ID field. */ public void serializeSpanId(ProtoFieldInfo field, @Nullable String spanId) throws IOException { if (spanId == null) { @@ -44,8 +64,21 @@ public void serializeSpanId(ProtoFieldInfo field, @Nullable String spanId) throw writeSpanId(field, spanId); } + public void serializeSpanId( + ProtoFieldInfo field, @Nullable String spanId, MarshalerContext context) throws IOException { + if (spanId == null) { + return; + } + writeSpanId(field, spanId, context); + } + protected abstract void writeSpanId(ProtoFieldInfo field, String spanId) throws IOException; + protected void writeSpanId(ProtoFieldInfo field, String spanId, MarshalerContext context) + throws IOException { + writeSpanId(field, spanId); + } + /** Serializes a protobuf {@code bool} field. */ public void serializeBool(ProtoFieldInfo field, boolean value) throws IOException { if (!value) { @@ -175,9 +208,32 @@ public void serializeString(ProtoFieldInfo field, byte[] utf8Bytes) throws IOExc writeString(field, utf8Bytes); } + /** + * Serializes a protobuf {@code string} field. {@code string} is the value to be serialized and + * {@code utf8Length} is the length of the string after it is encoded in UTF8. This method reads + * elements from context, use together with {@link + * StatelessMarshalerUtil#sizeStringWithContext(ProtoFieldInfo, String, MarshalerContext)}. + */ + public void serializeStringWithContext( + ProtoFieldInfo field, @Nullable String string, MarshalerContext context) throws IOException { + if (string == null || string.isEmpty()) { + return; + } + if (context.marshalStringNoAllocation()) { + writeString(field, string, context.getSize(), context); + } else { + byte[] valueUtf8 = context.getData(byte[].class); + writeString(field, valueUtf8); + } + } + /** Writes a protobuf {@code string} field, even if it matches the default value. */ public abstract void writeString(ProtoFieldInfo field, byte[] utf8Bytes) throws IOException; + public abstract void writeString( + ProtoFieldInfo field, String string, int utf8Length, MarshalerContext context) + throws IOException; + /** Serializes a protobuf {@code bytes} field. */ public void serializeBytes(ProtoFieldInfo field, byte[] value) throws IOException { if (value.length == 0) { @@ -200,6 +256,36 @@ public void serializeMessage(ProtoFieldInfo field, Marshaler message) throws IOE writeEndMessage(); } + /** + * Serializes a protobuf embedded {@code message}. This method adds elements to context, use + * together with {@link StatelessMarshalerUtil#sizeMessageWithContext(ProtoFieldInfo, Object, + * StatelessMarshaler, MarshalerContext)}. + */ + public void serializeMessageWithContext( + ProtoFieldInfo field, T message, StatelessMarshaler marshaler, MarshalerContext context) + throws IOException { + writeStartMessage(field, context.getSize()); + marshaler.writeTo(this, message, context); + writeEndMessage(); + } + + /** + * Serializes a protobuf embedded {@code message}. This method adds elements to context, use + * together with {@link StatelessMarshalerUtil#sizeMessageWithContext(ProtoFieldInfo, Object, + * Object, StatelessMarshaler2, MarshalerContext)}. + */ + public void serializeMessageWithContext( + ProtoFieldInfo field, + K key, + V value, + StatelessMarshaler2 marshaler, + MarshalerContext context) + throws IOException { + writeStartMessage(field, context.getSize()); + marshaler.writeTo(this, key, value, context); + writeEndMessage(); + } + @SuppressWarnings("SameParameterValue") protected abstract void writeStartRepeatedPrimitive( ProtoFieldInfo field, int protoSizePerElement, int numElements) throws IOException; @@ -217,7 +303,8 @@ public void serializeRepeatedFixed64(ProtoFieldInfo field, List values) th return; } writeStartRepeatedPrimitive(field, WireFormat.FIXED64_SIZE, values.size()); - for (long value : values) { + for (int i = 0; i < values.size(); i++) { + Long value = values.get(i); writeFixed64Value(value); } writeEndRepeatedPrimitive(); @@ -286,7 +373,8 @@ public void serializeRepeatedDouble(ProtoFieldInfo field, List values) return; } writeStartRepeatedPrimitive(field, WireFormat.FIXED64_SIZE, values.size()); - for (double value : values) { + for (int i = 0; i < values.size(); i++) { + Double value = values.get(i); writeDoubleValue(value); } writeEndRepeatedPrimitive(); @@ -301,6 +389,179 @@ public abstract void serializeRepeatedMessage(ProtoFieldInfo field, Marshaler[] public abstract void serializeRepeatedMessage( ProtoFieldInfo field, List repeatedMessage) throws IOException; + /** + * Serializes {@code repeated message} field. This method reads elements from context, use + * together with {@link StatelessMarshalerUtil#sizeRepeatedMessageWithContext(ProtoFieldInfo, + * List, StatelessMarshaler, MarshalerContext)}. + */ + public abstract void serializeRepeatedMessageWithContext( + ProtoFieldInfo field, + List messages, + StatelessMarshaler marshaler, + MarshalerContext context) + throws IOException; + + /** + * Serializes {@code repeated message} field. This method reads elements from context, use + * together with {@link StatelessMarshalerUtil#sizeRepeatedMessageWithContext(ProtoFieldInfo, + * Collection, StatelessMarshaler, MarshalerContext, MarshalerContext.Key)}. + */ + @SuppressWarnings("unchecked") + public void serializeRepeatedMessageWithContext( + ProtoFieldInfo field, + Collection messages, + StatelessMarshaler marshaler, + MarshalerContext context, + MarshalerContext.Key key) + throws IOException { + if (messages instanceof List) { + serializeRepeatedMessageWithContext(field, (List) messages, marshaler, context); + return; + } + + writeStartRepeated(field); + + if (!messages.isEmpty()) { + RepeatedElementWriter writer = context.getInstance(key, RepeatedElementWriter::new); + writer.initialize(field, this, marshaler, context); + messages.forEach(writer); + } + + writeEndRepeated(); + } + + /** + * Serializes {@code repeated message} field. This method reads elements from context, use + * together with {@link StatelessMarshalerUtil#sizeRepeatedMessageWithContext(ProtoFieldInfo, Map, + * StatelessMarshaler2, MarshalerContext, MarshalerContext.Key)}. + */ + public void serializeRepeatedMessageWithContext( + ProtoFieldInfo field, + Map messages, + StatelessMarshaler2 marshaler, + MarshalerContext context, + MarshalerContext.Key key) + throws IOException { + writeStartRepeated(field); + + if (!messages.isEmpty()) { + RepeatedElementPairWriter writer = + context.getInstance(key, RepeatedElementPairWriter::new); + writer.initialize(field, this, marshaler, context); + messages.forEach(writer); + } + + writeEndRepeated(); + } + + /** + * Serializes {@code repeated message} field. This method reads elements from context, use + * together with {@link StatelessMarshalerUtil#sizeRepeatedMessageWithContext(ProtoFieldInfo, + * Attributes, StatelessMarshaler2, MarshalerContext)}. + */ + public void serializeRepeatedMessageWithContext( + ProtoFieldInfo field, + Attributes attributes, + StatelessMarshaler2, Object> marshaler, + MarshalerContext context) + throws IOException { + writeStartRepeated(field); + + if (!attributes.isEmpty()) { + RepeatedElementPairWriter, Object> writer = + context.getInstance(ATTRIBUTES_WRITER_KEY, RepeatedElementPairWriter::new); + writer.initialize(field, this, marshaler, context); + attributes.forEach(writer); + } + + writeEndRepeated(); + } + + private static class RepeatedElementWriter implements Consumer { + @SuppressWarnings("NullAway") + private ProtoFieldInfo field; + + @SuppressWarnings("NullAway") + private Serializer output; + + @SuppressWarnings("NullAway") + private StatelessMarshaler marshaler; + + @SuppressWarnings("NullAway") + private MarshalerContext context; + + void initialize( + ProtoFieldInfo field, + Serializer output, + StatelessMarshaler marshaler, + MarshalerContext context) { + this.field = field; + this.output = output; + this.marshaler = marshaler; + this.context = context; + } + + @Override + public void accept(T element) { + try { + output.writeStartRepeatedElement(field, context.getSize()); + marshaler.writeTo(output, element, context); + output.writeEndRepeatedElement(); + } catch (IOException e) { + throw new IllegalStateException(e); + } + } + } + + private static class RepeatedElementPairWriter implements BiConsumer { + @SuppressWarnings("NullAway") + private ProtoFieldInfo field; + + @SuppressWarnings("NullAway") + private Serializer output; + + @SuppressWarnings("NullAway") + private StatelessMarshaler2 marshaler; + + @SuppressWarnings("NullAway") + private MarshalerContext context; + + void initialize( + ProtoFieldInfo field, + Serializer output, + StatelessMarshaler2 marshaler, + MarshalerContext context) { + this.field = field; + this.output = output; + this.marshaler = marshaler; + this.context = context; + } + + @Override + public void accept(K key, V value) { + try { + output.writeStartRepeatedElement(field, context.getSize()); + marshaler.writeTo(output, key, value, context); + output.writeEndRepeatedElement(); + } catch (IOException e) { + throw new IllegalStateException(e); + } + } + } + + /** Writes start of repeated messages. */ + protected abstract void writeStartRepeated(ProtoFieldInfo field) throws IOException; + + /** Writes end of repeated messages. */ + protected abstract void writeEndRepeated() throws IOException; + + /** Writes start of a repeated message element. */ + protected abstract void writeStartRepeatedElement(ProtoFieldInfo field, int protoMessageSize) + throws IOException; + + /** Writes end of a repeated message element. */ + protected abstract void writeEndRepeatedElement() throws IOException; + /** Writes the value for a message field that has been pre-serialized. */ public abstract void writeSerializedMessage(byte[] protoSerialized, String jsonSerialized) throws IOException; diff --git a/exporters/common/src/main/java/io/opentelemetry/exporter/internal/marshal/StatelessMarshaler.java b/exporters/common/src/main/java/io/opentelemetry/exporter/internal/marshal/StatelessMarshaler.java new file mode 100644 index 00000000000..dac3b7bbb94 --- /dev/null +++ b/exporters/common/src/main/java/io/opentelemetry/exporter/internal/marshal/StatelessMarshaler.java @@ -0,0 +1,28 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.exporter.internal.marshal; + +import java.io.IOException; + +/** + * Marshaler from an SDK structure to protobuf wire format. It is intended that the instances of + * this interface don't keep marshaling state and can be singletons. Any state needed for marshaling + * should be stored in {@link MarshalerContext}. Marshaler should be used so that first {@link + * #getBinarySerializedSize} is called and after that {@link #writeTo} is called. Calling {@link + * #getBinarySerializedSize} may add values to {@link MarshalerContext} that are later used in + * {@link #writeTo}. + * + *

      This class is internal and is hence not for public use. Its APIs are unstable and can change + * at any time. + */ +public interface StatelessMarshaler { + + /** Returns the number of bytes marshaling given value will write in proto binary format. */ + int getBinarySerializedSize(T value, MarshalerContext context); + + /** Marshal given value using the provided {@link Serializer}. */ + void writeTo(Serializer output, T value, MarshalerContext context) throws IOException; +} diff --git a/exporters/common/src/main/java/io/opentelemetry/exporter/internal/marshal/StatelessMarshaler2.java b/exporters/common/src/main/java/io/opentelemetry/exporter/internal/marshal/StatelessMarshaler2.java new file mode 100644 index 00000000000..c2fc8769046 --- /dev/null +++ b/exporters/common/src/main/java/io/opentelemetry/exporter/internal/marshal/StatelessMarshaler2.java @@ -0,0 +1,28 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.exporter.internal.marshal; + +import java.io.IOException; + +/** + * Marshaler from an SDK structure to protobuf wire format. It is intended that the instances of + * this interface don't keep marshaling state and can be singletons. Any state needed for marshaling + * should be stored in {@link MarshalerContext}. Marshaler should be used so that first {@link + * #getBinarySerializedSize} is called and after that {@link #writeTo} is called. Calling {@link + * #getBinarySerializedSize} may add values to {@link MarshalerContext} that are later used in + * {@link #writeTo}. + * + *

      This class is internal and is hence not for public use. Its APIs are unstable and can change + * at any time. + */ +public interface StatelessMarshaler2 { + + /** Returns the number of bytes this Marshaler will write. */ + int getBinarySerializedSize(K key, V value, MarshalerContext context); + + /** Marshal given key and value using the provided {@link Serializer}. */ + void writeTo(Serializer output, K key, V value, MarshalerContext context) throws IOException; +} diff --git a/exporters/common/src/main/java/io/opentelemetry/exporter/internal/marshal/StatelessMarshalerUtil.java b/exporters/common/src/main/java/io/opentelemetry/exporter/internal/marshal/StatelessMarshalerUtil.java new file mode 100644 index 00000000000..87c8b3d96bb --- /dev/null +++ b/exporters/common/src/main/java/io/opentelemetry/exporter/internal/marshal/StatelessMarshalerUtil.java @@ -0,0 +1,436 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.exporter.internal.marshal; + +import io.opentelemetry.api.common.AttributeKey; +import io.opentelemetry.api.common.Attributes; +import io.opentelemetry.sdk.common.InstrumentationScopeInfo; +import io.opentelemetry.sdk.resources.Resource; +import java.io.IOException; +import java.util.Collection; +import java.util.List; +import java.util.Map; +import java.util.function.BiConsumer; +import java.util.function.Consumer; +import java.util.function.Function; +import javax.annotation.Nullable; + +/** + * Marshaler utilities. + * + *

      This class is internal and is hence not for public use. Its APIs are unstable and can change + * at any time. + */ +public final class StatelessMarshalerUtil { + private static final MarshalerContext.Key GROUPER_KEY = MarshalerContext.key(); + private static final MarshalerContext.Key ATTRIBUTES_SIZE_CALCULATOR_KEY = MarshalerContext.key(); + + /** Groups SDK items by resource and instrumentation scope. */ + public static Map>> groupByResourceAndScope( + Collection dataList, + Function getResource, + Function getInstrumentationScope, + MarshalerContext context) { + Map>> result = context.getIdentityMap(); + + Grouper grouper = context.getInstance(GROUPER_KEY, Grouper::new); + grouper.initialize(result, getResource, getInstrumentationScope, context); + dataList.forEach(grouper); + + return result; + } + + private static class Grouper implements Consumer { + @SuppressWarnings("NullAway") + private Map>> result; + + @SuppressWarnings("NullAway") + private Function getResource; + + @SuppressWarnings("NullAway") + private Function getInstrumentationScope; + + @SuppressWarnings("NullAway") + private MarshalerContext context; + + void initialize( + Map>> result, + Function getResource, + Function getInstrumentationScope, + MarshalerContext context) { + this.result = result; + this.getResource = getResource; + this.getInstrumentationScope = getInstrumentationScope; + this.context = context; + } + + @Override + public void accept(T data) { + Resource resource = getResource.apply(data); + Map> scopeInfoListMap = result.get(resource); + if (scopeInfoListMap == null) { + scopeInfoListMap = context.getIdentityMap(); + result.put(resource, scopeInfoListMap); + } + InstrumentationScopeInfo instrumentationScopeInfo = getInstrumentationScope.apply(data); + List elementList = scopeInfoListMap.get(instrumentationScopeInfo); + if (elementList == null) { + elementList = context.getList(); + scopeInfoListMap.put(instrumentationScopeInfo, elementList); + } + elementList.add(data); + } + } + + /** + * Returns the size of a string field. This method adds elements to context, use together with + * {@link Serializer#serializeStringWithContext(ProtoFieldInfo, String, MarshalerContext)}. + */ + public static int sizeStringWithContext( + ProtoFieldInfo field, @Nullable String value, MarshalerContext context) { + if (value == null || value.isEmpty()) { + return sizeBytes(field, 0); + } + if (context.marshalStringNoAllocation()) { + int utf8Size = getUtf8Size(value, context); + context.addSize(utf8Size); + return sizeBytes(field, utf8Size); + } else { + byte[] valueUtf8 = MarshalerUtil.toBytes(value); + context.addData(valueUtf8); + return sizeBytes(field, valueUtf8.length); + } + } + + /** Returns the size of a bytes field. */ + private static int sizeBytes(ProtoFieldInfo field, int length) { + if (length == 0) { + return 0; + } + return field.getTagSize() + CodedOutputStream.computeLengthDelimitedFieldSize(length); + } + + /** + * Returns the size of a repeated message field. This method adds elements to context, use + * together with {@link Serializer#serializeRepeatedMessageWithContext(ProtoFieldInfo, List, + * StatelessMarshaler, MarshalerContext)}. + */ + public static int sizeRepeatedMessageWithContext( + ProtoFieldInfo field, + List messages, + StatelessMarshaler marshaler, + MarshalerContext context) { + if (messages.isEmpty()) { + return 0; + } + + int size = 0; + int fieldTagSize = field.getTagSize(); + for (int i = 0; i < messages.size(); i++) { + T message = messages.get(i); + int sizeIndex = context.addSize(); + int fieldSize = marshaler.getBinarySerializedSize(message, context); + context.setSize(sizeIndex, fieldSize); + size += fieldTagSize + CodedOutputStream.computeUInt32SizeNoTag(fieldSize) + fieldSize; + } + return size; + } + + /** + * Returns the size of a repeated message field. This method adds elements to context, use + * together with {@link Serializer#serializeRepeatedMessageWithContext(ProtoFieldInfo, Collection, + * StatelessMarshaler, MarshalerContext, MarshalerContext.Key)}. + */ + @SuppressWarnings("unchecked") + public static int sizeRepeatedMessageWithContext( + ProtoFieldInfo field, + Collection messages, + StatelessMarshaler marshaler, + MarshalerContext context, + MarshalerContext.Key key) { + if (messages instanceof List) { + return sizeRepeatedMessageWithContext(field, (List) messages, marshaler, context); + } + + if (messages.isEmpty()) { + return 0; + } + + RepeatedElementSizeCalculator sizeCalculator = + context.getInstance(key, RepeatedElementSizeCalculator::new); + sizeCalculator.initialize(field, marshaler, context); + messages.forEach(sizeCalculator); + + return sizeCalculator.size; + } + + /** + * Returns the size of a repeated message field. This method adds elements to context, use + * together with {@link Serializer#serializeRepeatedMessageWithContext(ProtoFieldInfo, Map, + * StatelessMarshaler2, MarshalerContext, MarshalerContext.Key)}. + */ + public static int sizeRepeatedMessageWithContext( + ProtoFieldInfo field, + Map messages, + StatelessMarshaler2 marshaler, + MarshalerContext context, + MarshalerContext.Key key) { + if (messages.isEmpty()) { + return 0; + } + + RepeatedElementPairSizeCalculator sizeCalculator = + context.getInstance(key, RepeatedElementPairSizeCalculator::new); + sizeCalculator.initialize(field, marshaler, context); + messages.forEach(sizeCalculator); + + return sizeCalculator.size; + } + + /** + * Returns the size of a repeated message field. This method adds elements to context, use + * together with {@link Serializer#serializeRepeatedMessageWithContext(ProtoFieldInfo, Attributes, + * StatelessMarshaler2, MarshalerContext)}. + */ + public static int sizeRepeatedMessageWithContext( + ProtoFieldInfo field, + Attributes attributes, + StatelessMarshaler2, Object> marshaler, + MarshalerContext context) { + if (attributes.isEmpty()) { + return 0; + } + + RepeatedElementPairSizeCalculator, Object> sizeCalculator = + context.getInstance(ATTRIBUTES_SIZE_CALCULATOR_KEY, RepeatedElementPairSizeCalculator::new); + sizeCalculator.initialize(field, marshaler, context); + attributes.forEach(sizeCalculator); + + return sizeCalculator.size; + } + + private static class RepeatedElementSizeCalculator implements Consumer { + private int size; + private int fieldTagSize; + + @SuppressWarnings("NullAway") + private StatelessMarshaler marshaler; + + @SuppressWarnings("NullAway") + private MarshalerContext context; + + void initialize( + ProtoFieldInfo field, StatelessMarshaler marshaler, MarshalerContext context) { + this.size = 0; + this.fieldTagSize = field.getTagSize(); + this.marshaler = marshaler; + this.context = context; + } + + @Override + public void accept(T element) { + int sizeIndex = context.addSize(); + int fieldSize = marshaler.getBinarySerializedSize(element, context); + context.setSize(sizeIndex, fieldSize); + size += fieldTagSize + CodedOutputStream.computeUInt32SizeNoTag(fieldSize) + fieldSize; + } + } + + private static class RepeatedElementPairSizeCalculator implements BiConsumer { + private int size; + private int fieldTagSize; + + @SuppressWarnings("NullAway") + private StatelessMarshaler2 marshaler; + + @SuppressWarnings("NullAway") + private MarshalerContext context; + + void initialize( + ProtoFieldInfo field, StatelessMarshaler2 marshaler, MarshalerContext context) { + this.size = 0; + this.fieldTagSize = field.getTagSize(); + this.marshaler = marshaler; + this.context = context; + } + + @Override + public void accept(K key, V value) { + int sizeIndex = context.addSize(); + int fieldSize = marshaler.getBinarySerializedSize(key, value, context); + context.setSize(sizeIndex, fieldSize); + size += fieldTagSize + CodedOutputStream.computeUInt32SizeNoTag(fieldSize) + fieldSize; + } + } + + /** + * Returns the size of a message field. This method adds elements to context, use together with + * {@link Serializer#serializeMessageWithContext(ProtoFieldInfo, Object, StatelessMarshaler, + * MarshalerContext)}. + */ + public static int sizeMessageWithContext( + ProtoFieldInfo field, T element, StatelessMarshaler marshaler, MarshalerContext context) { + int sizeIndex = context.addSize(); + int fieldSize = marshaler.getBinarySerializedSize(element, context); + int size = field.getTagSize() + CodedOutputStream.computeUInt32SizeNoTag(fieldSize) + fieldSize; + context.setSize(sizeIndex, fieldSize); + return size; + } + + /** + * Returns the size of a message field. This method adds elements to context, use together with + * {@link Serializer#serializeMessageWithContext(ProtoFieldInfo, Object, Object, + * StatelessMarshaler2, MarshalerContext)}. + */ + public static int sizeMessageWithContext( + ProtoFieldInfo field, + K key, + V value, + StatelessMarshaler2 marshaler, + MarshalerContext context) { + int sizeIndex = context.addSize(); + int fieldSize = marshaler.getBinarySerializedSize(key, value, context); + int size = field.getTagSize() + CodedOutputStream.computeUInt32SizeNoTag(fieldSize) + fieldSize; + context.setSize(sizeIndex, fieldSize); + return size; + } + + /** Returns the size of utf8 encoded string in bytes. */ + @SuppressWarnings("UnusedVariable") + private static int getUtf8Size(String string, MarshalerContext context) { + return getUtf8Size(string); + } + + // Visible for testing + static int getUtf8Size(String string) { + return encodedUtf8Length(string); + } + + // adapted from + // https://github.com/protocolbuffers/protobuf/blob/b618f6750aed641a23d5f26fbbaf654668846d24/java/core/src/main/java/com/google/protobuf/Utf8.java#L217 + private static int encodedUtf8Length(String string) { + // Warning to maintainers: this implementation is highly optimized. + int utf16Length = string.length(); + int utf8Length = utf16Length; + int i = 0; + + // This loop optimizes for pure ASCII. + while (i < utf16Length && string.charAt(i) < 0x80) { + i++; + } + + // This loop optimizes for chars less than 0x800. + for (; i < utf16Length; i++) { + char c = string.charAt(i); + if (c < 0x800) { + utf8Length += ((0x7f - c) >>> 31); // branch free! + } else { + utf8Length += encodedUtf8LengthGeneral(string, i); + break; + } + } + + if (utf8Length < utf16Length) { + // Necessary and sufficient condition for overflow because of maximum 3x expansion + throw new IllegalArgumentException( + "UTF-8 length does not fit in int: " + (utf8Length + (1L << 32))); + } + + return utf8Length; + } + + // adapted from + // https://github.com/protocolbuffers/protobuf/blob/b618f6750aed641a23d5f26fbbaf654668846d24/java/core/src/main/java/com/google/protobuf/Utf8.java#L247 + private static int encodedUtf8LengthGeneral(String string, int start) { + int utf16Length = string.length(); + int utf8Length = 0; + for (int i = start; i < utf16Length; i++) { + char c = string.charAt(i); + if (c < 0x800) { + utf8Length += (0x7f - c) >>> 31; // branch free! + } else { + utf8Length += 2; + if (Character.isSurrogate(c)) { + // Check that we have a well-formed surrogate pair. + if (Character.codePointAt(string, i) != c) { + i++; + } else { + // invalid sequence + // At this point we have accumulated 3 byes of length (2 in this method and 1 in caller) + // for current character, reduce the length to 1 bytes as we are going to encode the + // invalid character as ? + utf8Length -= 2; + } + } + } + } + + return utf8Length; + } + + /** Write utf8 encoded string to output stream. */ + @SuppressWarnings("UnusedVariable") // context argument is added for future use + static void writeUtf8( + CodedOutputStream output, String string, int utf8Length, MarshalerContext context) + throws IOException { + writeUtf8(output, string, utf8Length); + } + + // Visible for testing + @SuppressWarnings("UnusedVariable") // utf8Length argument is added for future use + static void writeUtf8(CodedOutputStream output, String string, int utf8Length) + throws IOException { + encodeUtf8(output, string); + } + + // encode utf8 the same way as length is computed in encodedUtf8Length + // adapted from + // https://github.com/protocolbuffers/protobuf/blob/b618f6750aed641a23d5f26fbbaf654668846d24/java/core/src/main/java/com/google/protobuf/Utf8.java#L1016 + private static void encodeUtf8(CodedOutputStream output, String in) throws IOException { + int utf16Length = in.length(); + int i = 0; + // Designed to take advantage of + // https://wiki.openjdk.java.net/display/HotSpotInternals/RangeCheckElimination + for (char c; i < utf16Length && (c = in.charAt(i)) < 0x80; i++) { + output.write((byte) c); + } + if (i == utf16Length) { + return; + } + + for (char c; i < utf16Length; i++) { + c = in.charAt(i); + if (c < 0x80) { + // 1 byte, 7 bits + output.write((byte) c); + } else if (c < 0x800) { // 11 bits, two UTF-8 bytes + output.write((byte) ((0xF << 6) | (c >>> 6))); + output.write((byte) (0x80 | (0x3F & c))); + } else if (!Character.isSurrogate(c)) { + // Maximum single-char code point is 0xFFFF, 16 bits, three UTF-8 bytes + output.write((byte) ((0xF << 5) | (c >>> 12))); + output.write((byte) (0x80 | (0x3F & (c >>> 6)))); + output.write((byte) (0x80 | (0x3F & c))); + } else { + // Minimum code point represented by a surrogate pair is 0x10000, 17 bits, + // four UTF-8 bytes + int codePoint = Character.codePointAt(in, i); + if (codePoint != c) { + output.write((byte) ((0xF << 4) | (codePoint >>> 18))); + output.write((byte) (0x80 | (0x3F & (codePoint >>> 12)))); + output.write((byte) (0x80 | (0x3F & (codePoint >>> 6)))); + output.write((byte) (0x80 | (0x3F & codePoint))); + i++; + } else { + // invalid sequence + output.write((byte) '?'); + } + } + } + } + + private StatelessMarshalerUtil() {} +} diff --git a/exporters/common/src/test/java/io/opentelemetry/exporter/internal/marshal/StatelessMarshalerUtilTest.java b/exporters/common/src/test/java/io/opentelemetry/exporter/internal/marshal/StatelessMarshalerUtilTest.java new file mode 100644 index 00000000000..6857589822e --- /dev/null +++ b/exporters/common/src/test/java/io/opentelemetry/exporter/internal/marshal/StatelessMarshalerUtilTest.java @@ -0,0 +1,68 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.exporter.internal.marshal; + +import static io.opentelemetry.exporter.internal.marshal.StatelessMarshalerUtil.getUtf8Size; +import static io.opentelemetry.exporter.internal.marshal.StatelessMarshalerUtil.writeUtf8; +import static org.assertj.core.api.Assertions.assertThat; + +import java.io.ByteArrayOutputStream; +import java.nio.charset.StandardCharsets; +import java.util.Random; +import org.junit.jupiter.api.RepeatedTest; +import org.junit.jupiter.api.Test; + +class StatelessMarshalerUtilTest { + + @Test + @SuppressWarnings("AvoidEscapedUnicodeCharacters") + void encodeUtf8() { + assertThat(getUtf8Size("")).isEqualTo(0); + assertThat(testUtf8("", 0)).isEqualTo(""); + + assertThat(getUtf8Size("a")).isEqualTo(1); + assertThat(testUtf8("a", 1)).isEqualTo("a"); + + assertThat(getUtf8Size("©")).isEqualTo(2); + assertThat(testUtf8("©", 2)).isEqualTo("©"); + + assertThat(getUtf8Size("∆")).isEqualTo(3); + assertThat(testUtf8("∆", 3)).isEqualTo("∆"); + + assertThat(getUtf8Size("😀")).isEqualTo(4); + assertThat(testUtf8("😀", 4)).isEqualTo("😀"); + + // test that invalid characters are replaced with ? + assertThat(getUtf8Size("\uD83D😀\uDE00")).isEqualTo(6); + assertThat(testUtf8("\uD83D😀\uDE00", 6)).isEqualTo("?😀?"); + + // the same invalid sequence as encoded by the jdk + byte[] bytes = "\uD83D😀\uDE00".getBytes(StandardCharsets.UTF_8); + assertThat(bytes.length).isEqualTo(6); + assertThat(new String(bytes, StandardCharsets.UTF_8)).isEqualTo("?😀?"); + } + + @RepeatedTest(1000) + void testUtf8SizeLatin1() { + Random random = new Random(); + byte[] bytes = new byte[15001]; + random.nextBytes(bytes); + String string = new String(bytes, StandardCharsets.ISO_8859_1); + int utf8Size = string.getBytes(StandardCharsets.UTF_8).length; + assertThat(getUtf8Size(string)).isEqualTo(utf8Size); + } + + private static String testUtf8(String string, int utf8Length) { + try (ByteArrayOutputStream outputStream = new ByteArrayOutputStream()) { + CodedOutputStream codedOutputStream = CodedOutputStream.newInstance(outputStream); + writeUtf8(codedOutputStream, string, utf8Length); + codedOutputStream.flush(); + return new String(outputStream.toByteArray(), StandardCharsets.UTF_8); + } catch (Exception exception) { + throw new IllegalArgumentException(exception); + } + } +} diff --git a/exporters/otlp/common/src/jmh/java/io/opentelemetry/exporter/internal/otlp/RequestMarshalBenchmarks.java b/exporters/otlp/common/src/jmh/java/io/opentelemetry/exporter/internal/otlp/RequestMarshalBenchmarks.java index 87cce61bfc2..fbdfa290011 100644 --- a/exporters/otlp/common/src/jmh/java/io/opentelemetry/exporter/internal/otlp/RequestMarshalBenchmarks.java +++ b/exporters/otlp/common/src/jmh/java/io/opentelemetry/exporter/internal/otlp/RequestMarshalBenchmarks.java @@ -5,6 +5,7 @@ package io.opentelemetry.exporter.internal.otlp; +import io.opentelemetry.exporter.internal.otlp.traces.LowAllocationTraceRequestMarshaler; import io.opentelemetry.exporter.internal.otlp.traces.TraceRequestMarshaler; import java.io.IOException; import java.util.concurrent.TimeUnit; @@ -24,29 +25,72 @@ @Fork(1) public class RequestMarshalBenchmarks { + private static final LowAllocationTraceRequestMarshaler MARSHALER = + new LowAllocationTraceRequestMarshaler(); + private static final TestOutputStream OUTPUT = new TestOutputStream(); + @Benchmark @Threads(1) - public TestOutputStream createCustomMarshal(RequestMarshalState state) { + public int createStatefulMarshaler(RequestMarshalState state) { TraceRequestMarshaler requestMarshaler = TraceRequestMarshaler.create(state.spanDataList); - return new TestOutputStream(requestMarshaler.getBinarySerializedSize()); + return requestMarshaler.getBinarySerializedSize(); } @Benchmark @Threads(1) - public TestOutputStream marshalCustom(RequestMarshalState state) throws IOException { + public int marshalStatefulBinary(RequestMarshalState state) throws IOException { TraceRequestMarshaler requestMarshaler = TraceRequestMarshaler.create(state.spanDataList); - TestOutputStream customOutput = - new TestOutputStream(requestMarshaler.getBinarySerializedSize()); - requestMarshaler.writeBinaryTo(customOutput); - return customOutput; + OUTPUT.reset(requestMarshaler.getBinarySerializedSize()); + requestMarshaler.writeBinaryTo(OUTPUT); + return OUTPUT.getCount(); } @Benchmark @Threads(1) - public TestOutputStream marshalJson(RequestMarshalState state) throws IOException { + public int marshalStatefulJson(RequestMarshalState state) throws IOException { TraceRequestMarshaler requestMarshaler = TraceRequestMarshaler.create(state.spanDataList); - TestOutputStream customOutput = new TestOutputStream(); - requestMarshaler.writeJsonTo(customOutput); - return customOutput; + OUTPUT.reset(); + requestMarshaler.writeJsonTo(OUTPUT); + return OUTPUT.getCount(); + } + + @Benchmark + @Threads(1) + public int createStatelessMarshaler(RequestMarshalState state) { + LowAllocationTraceRequestMarshaler requestMarshaler = MARSHALER; + requestMarshaler.initialize(state.spanDataList); + try { + return requestMarshaler.getBinarySerializedSize(); + } finally { + requestMarshaler.reset(); + } + } + + @Benchmark + @Threads(1) + public int marshalStatelessBinary(RequestMarshalState state) throws IOException { + LowAllocationTraceRequestMarshaler requestMarshaler = MARSHALER; + requestMarshaler.initialize(state.spanDataList); + try { + OUTPUT.reset(); + requestMarshaler.writeBinaryTo(OUTPUT); + return OUTPUT.getCount(); + } finally { + requestMarshaler.reset(); + } + } + + @Benchmark + @Threads(1) + public int marshalStatelessJson(RequestMarshalState state) throws IOException { + LowAllocationTraceRequestMarshaler requestMarshaler = MARSHALER; + requestMarshaler.initialize(state.spanDataList); + try { + OUTPUT.reset(); + requestMarshaler.writeJsonTo(OUTPUT); + return OUTPUT.getCount(); + } finally { + requestMarshaler.reset(); + } } } diff --git a/exporters/otlp/common/src/jmh/java/io/opentelemetry/exporter/internal/otlp/StringMarshalBenchmark.java b/exporters/otlp/common/src/jmh/java/io/opentelemetry/exporter/internal/otlp/StringMarshalBenchmark.java new file mode 100644 index 00000000000..f375a200185 --- /dev/null +++ b/exporters/otlp/common/src/jmh/java/io/opentelemetry/exporter/internal/otlp/StringMarshalBenchmark.java @@ -0,0 +1,121 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.exporter.internal.otlp; + +import io.opentelemetry.exporter.internal.marshal.Marshaler; +import io.opentelemetry.exporter.internal.marshal.MarshalerContext; +import io.opentelemetry.exporter.internal.marshal.Serializer; +import java.io.IOException; +import java.util.concurrent.TimeUnit; +import org.openjdk.jmh.annotations.Benchmark; +import org.openjdk.jmh.annotations.BenchmarkMode; +import org.openjdk.jmh.annotations.Fork; +import org.openjdk.jmh.annotations.Measurement; +import org.openjdk.jmh.annotations.Mode; +import org.openjdk.jmh.annotations.OutputTimeUnit; +import org.openjdk.jmh.annotations.Threads; +import org.openjdk.jmh.annotations.Warmup; + +@BenchmarkMode({Mode.AverageTime}) +@OutputTimeUnit(TimeUnit.MICROSECONDS) +@Warmup(iterations = 5, time = 1) +@Measurement(iterations = 10, time = 1) +@Fork(1) +public class StringMarshalBenchmark { + private static final TestMarshaler MARSHALER = new TestMarshaler(); + private static final TestOutputStream OUTPUT = new TestOutputStream(); + + @Benchmark + @Threads(1) + public int marshalAsciiString(StringMarshalState state) throws IOException { + OUTPUT.reset(); + Marshaler marshaler = StringAnyValueMarshaler.create(state.asciiString); + marshaler.writeBinaryTo(OUTPUT); + return OUTPUT.getCount(); + } + + @Benchmark + @Threads(1) + public int marshalLatin1String(StringMarshalState state) throws IOException { + OUTPUT.reset(); + Marshaler marshaler = StringAnyValueMarshaler.create(state.latin1String); + marshaler.writeBinaryTo(OUTPUT); + return OUTPUT.getCount(); + } + + @Benchmark + @Threads(1) + public int marshalUnicodeString(StringMarshalState state) throws IOException { + OUTPUT.reset(); + Marshaler marshaler = StringAnyValueMarshaler.create(state.unicodeString); + marshaler.writeBinaryTo(OUTPUT); + return OUTPUT.getCount(); + } + + @Benchmark + @Threads(1) + public int marshalAsciiStringLowAllocation(StringMarshalState state) throws IOException { + OUTPUT.reset(); + try { + MARSHALER.initialize(state.asciiString); + MARSHALER.writeBinaryTo(OUTPUT); + return OUTPUT.getCount(); + } finally { + MARSHALER.reset(); + } + } + + @Benchmark + @Threads(1) + public int marshalLatin1StringLowAllocation(StringMarshalState state) throws IOException { + OUTPUT.reset(); + try { + MARSHALER.initialize(state.latin1String); + MARSHALER.writeBinaryTo(OUTPUT); + return OUTPUT.getCount(); + } finally { + MARSHALER.reset(); + } + } + + @Benchmark + @Threads(1) + public int marshalUnicodeStringLowAllocation(StringMarshalState state) throws IOException { + OUTPUT.reset(); + try { + MARSHALER.initialize(state.unicodeString); + MARSHALER.writeBinaryTo(OUTPUT); + return OUTPUT.getCount(); + } finally { + MARSHALER.reset(); + } + } + + private static class TestMarshaler extends Marshaler { + private final MarshalerContext context = new MarshalerContext(); + private int size; + private String value; + + public void initialize(String string) { + value = string; + size = StringAnyValueStatelessMarshaler.INSTANCE.getBinarySerializedSize(string, context); + } + + public void reset() { + context.reset(); + } + + @Override + public int getBinarySerializedSize() { + return size; + } + + @Override + public void writeTo(Serializer output) throws IOException { + StringAnyValueStatelessMarshaler.INSTANCE.writeTo(output, value, context); + } + } +} diff --git a/exporters/otlp/common/src/jmh/java/io/opentelemetry/exporter/internal/otlp/StringMarshalState.java b/exporters/otlp/common/src/jmh/java/io/opentelemetry/exporter/internal/otlp/StringMarshalState.java new file mode 100644 index 00000000000..684b6c65080 --- /dev/null +++ b/exporters/otlp/common/src/jmh/java/io/opentelemetry/exporter/internal/otlp/StringMarshalState.java @@ -0,0 +1,37 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.exporter.internal.otlp; + +import org.openjdk.jmh.annotations.Param; +import org.openjdk.jmh.annotations.Scope; +import org.openjdk.jmh.annotations.Setup; +import org.openjdk.jmh.annotations.State; + +@State(Scope.Benchmark) +public class StringMarshalState { + + @Param({"16", "512"}) + int stringSize; + + String asciiString; + String latin1String; + String unicodeString; + + @Setup + public void setup() { + asciiString = makeString('a', stringSize); + latin1String = makeString('ä', stringSize); + unicodeString = makeString('∆', stringSize); + } + + private static String makeString(char c, int size) { + StringBuilder sb = new StringBuilder(); + for (int i = 0; i < size; i++) { + sb.append(c); + } + return sb.toString(); + } +} diff --git a/exporters/otlp/common/src/jmh/java/io/opentelemetry/exporter/internal/otlp/TestOutputStream.java b/exporters/otlp/common/src/jmh/java/io/opentelemetry/exporter/internal/otlp/TestOutputStream.java index 160853e89fe..cfaba56ec3e 100644 --- a/exporters/otlp/common/src/jmh/java/io/opentelemetry/exporter/internal/otlp/TestOutputStream.java +++ b/exporters/otlp/common/src/jmh/java/io/opentelemetry/exporter/internal/otlp/TestOutputStream.java @@ -8,7 +8,7 @@ import java.io.OutputStream; class TestOutputStream extends OutputStream { - private final int size; + private int size; private int count; TestOutputStream() { @@ -26,4 +26,17 @@ public void write(int b) { throw new IllegalStateException("max size exceeded"); } } + + void reset(int size) { + this.size = size; + this.count = 0; + } + + void reset() { + reset(-1); + } + + int getCount() { + return count; + } } diff --git a/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/ArrayAnyValueStatelessMarshaler.java b/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/ArrayAnyValueStatelessMarshaler.java new file mode 100644 index 00000000000..87e2bd3eb7a --- /dev/null +++ b/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/ArrayAnyValueStatelessMarshaler.java @@ -0,0 +1,88 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.exporter.internal.otlp; + +import io.opentelemetry.api.common.AttributeType; +import io.opentelemetry.exporter.internal.marshal.MarshalerContext; +import io.opentelemetry.exporter.internal.marshal.Serializer; +import io.opentelemetry.exporter.internal.marshal.StatelessMarshaler2; +import io.opentelemetry.exporter.internal.marshal.StatelessMarshalerUtil; +import io.opentelemetry.proto.common.v1.internal.ArrayValue; +import java.io.IOException; +import java.util.List; + +/** See {@link ArrayAnyValueMarshaler}. */ +// TODO: add support for List> +final class ArrayAnyValueStatelessMarshaler + implements StatelessMarshaler2> { + static final ArrayAnyValueStatelessMarshaler INSTANCE = + new ArrayAnyValueStatelessMarshaler<>(); + + @SuppressWarnings("unchecked") + @Override + public void writeTo(Serializer output, AttributeType type, List list, MarshalerContext context) + throws IOException { + switch (type) { + case STRING_ARRAY: + output.serializeRepeatedMessageWithContext( + ArrayValue.VALUES, + (List) list, + StringAnyValueStatelessMarshaler.INSTANCE, + context); + return; + case LONG_ARRAY: + output.serializeRepeatedMessageWithContext( + ArrayValue.VALUES, (List) list, IntAnyValueStatelessMarshaler.INSTANCE, context); + return; + case BOOLEAN_ARRAY: + output.serializeRepeatedMessageWithContext( + ArrayValue.VALUES, + (List) list, + BoolAnyValueStatelessMarshaler.INSTANCE, + context); + return; + case DOUBLE_ARRAY: + output.serializeRepeatedMessageWithContext( + ArrayValue.VALUES, + (List) list, + DoubleAnyValueStatelessMarshaler.INSTANCE, + context); + return; + default: + throw new IllegalArgumentException("Unsupported attribute type."); + } + } + + @SuppressWarnings("unchecked") + @Override + public int getBinarySerializedSize(AttributeType type, List list, MarshalerContext context) { + switch (type) { + case STRING_ARRAY: + return StatelessMarshalerUtil.sizeRepeatedMessageWithContext( + ArrayValue.VALUES, + (List) list, + StringAnyValueStatelessMarshaler.INSTANCE, + context); + case LONG_ARRAY: + return StatelessMarshalerUtil.sizeRepeatedMessageWithContext( + ArrayValue.VALUES, (List) list, IntAnyValueStatelessMarshaler.INSTANCE, context); + case BOOLEAN_ARRAY: + return StatelessMarshalerUtil.sizeRepeatedMessageWithContext( + ArrayValue.VALUES, + (List) list, + BoolAnyValueStatelessMarshaler.INSTANCE, + context); + case DOUBLE_ARRAY: + return StatelessMarshalerUtil.sizeRepeatedMessageWithContext( + ArrayValue.VALUES, + (List) list, + DoubleAnyValueStatelessMarshaler.INSTANCE, + context); + default: + throw new IllegalArgumentException("Unsupported attribute type."); + } + } +} diff --git a/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/BoolAnyValueStatelessMarshaler.java b/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/BoolAnyValueStatelessMarshaler.java new file mode 100644 index 00000000000..da05b557c8f --- /dev/null +++ b/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/BoolAnyValueStatelessMarshaler.java @@ -0,0 +1,29 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.exporter.internal.otlp; + +import io.opentelemetry.exporter.internal.marshal.CodedOutputStream; +import io.opentelemetry.exporter.internal.marshal.MarshalerContext; +import io.opentelemetry.exporter.internal.marshal.Serializer; +import io.opentelemetry.exporter.internal.marshal.StatelessMarshaler; +import io.opentelemetry.proto.common.v1.internal.AnyValue; +import java.io.IOException; + +/** See {@link BoolAnyValueMarshaler}. */ +final class BoolAnyValueStatelessMarshaler implements StatelessMarshaler { + static final BoolAnyValueStatelessMarshaler INSTANCE = new BoolAnyValueStatelessMarshaler(); + + @Override + public void writeTo(Serializer output, Boolean value, MarshalerContext context) + throws IOException { + output.writeBool(AnyValue.BOOL_VALUE, value); + } + + @Override + public int getBinarySerializedSize(Boolean value, MarshalerContext context) { + return AnyValue.BOOL_VALUE.getTagSize() + CodedOutputStream.computeBoolSizeNoTag(value); + } +} diff --git a/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/DoubleAnyValueStatelessMarshaler.java b/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/DoubleAnyValueStatelessMarshaler.java new file mode 100644 index 00000000000..879116d3f0f --- /dev/null +++ b/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/DoubleAnyValueStatelessMarshaler.java @@ -0,0 +1,29 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.exporter.internal.otlp; + +import io.opentelemetry.exporter.internal.marshal.CodedOutputStream; +import io.opentelemetry.exporter.internal.marshal.MarshalerContext; +import io.opentelemetry.exporter.internal.marshal.Serializer; +import io.opentelemetry.exporter.internal.marshal.StatelessMarshaler; +import io.opentelemetry.proto.common.v1.internal.AnyValue; +import java.io.IOException; + +/** See {@link DoubleAnyValueMarshaler}. */ +final class DoubleAnyValueStatelessMarshaler implements StatelessMarshaler { + static final DoubleAnyValueStatelessMarshaler INSTANCE = new DoubleAnyValueStatelessMarshaler(); + + @Override + public void writeTo(Serializer output, Double value, MarshalerContext context) + throws IOException { + output.writeDouble(AnyValue.DOUBLE_VALUE, value); + } + + @Override + public int getBinarySerializedSize(Double value, MarshalerContext context) { + return AnyValue.DOUBLE_VALUE.getTagSize() + CodedOutputStream.computeDoubleSizeNoTag(value); + } +} diff --git a/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/IntAnyValueStatelessMarshaler.java b/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/IntAnyValueStatelessMarshaler.java new file mode 100644 index 00000000000..c1b97dd02a4 --- /dev/null +++ b/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/IntAnyValueStatelessMarshaler.java @@ -0,0 +1,28 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.exporter.internal.otlp; + +import io.opentelemetry.exporter.internal.marshal.CodedOutputStream; +import io.opentelemetry.exporter.internal.marshal.MarshalerContext; +import io.opentelemetry.exporter.internal.marshal.Serializer; +import io.opentelemetry.exporter.internal.marshal.StatelessMarshaler; +import io.opentelemetry.proto.common.v1.internal.AnyValue; +import java.io.IOException; + +/** See {@link IntAnyValueMarshaler}. */ +final class IntAnyValueStatelessMarshaler implements StatelessMarshaler { + static final IntAnyValueStatelessMarshaler INSTANCE = new IntAnyValueStatelessMarshaler(); + + @Override + public void writeTo(Serializer output, Long value, MarshalerContext context) throws IOException { + output.writeInt64(AnyValue.INT_VALUE, value); + } + + @Override + public int getBinarySerializedSize(Long value, MarshalerContext context) { + return AnyValue.INT_VALUE.getTagSize() + CodedOutputStream.computeInt64SizeNoTag(value); + } +} diff --git a/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/KeyValueStatelessMarshaler.java b/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/KeyValueStatelessMarshaler.java new file mode 100644 index 00000000000..5714912d2d0 --- /dev/null +++ b/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/KeyValueStatelessMarshaler.java @@ -0,0 +1,142 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.exporter.internal.otlp; + +import io.opentelemetry.api.common.AttributeKey; +import io.opentelemetry.api.common.AttributeType; +import io.opentelemetry.api.internal.InternalAttributeKeyImpl; +import io.opentelemetry.exporter.internal.marshal.MarshalerContext; +import io.opentelemetry.exporter.internal.marshal.MarshalerUtil; +import io.opentelemetry.exporter.internal.marshal.Serializer; +import io.opentelemetry.exporter.internal.marshal.StatelessMarshaler2; +import io.opentelemetry.exporter.internal.marshal.StatelessMarshalerUtil; +import io.opentelemetry.proto.common.v1.internal.AnyValue; +import io.opentelemetry.proto.common.v1.internal.KeyValue; +import java.io.IOException; +import java.util.List; + +/** + * A Marshaler of key value pairs. See {@link KeyValueMarshaler}. + * + *

      This class is internal and is hence not for public use. Its APIs are unstable and can change + * at any time. + */ +public final class KeyValueStatelessMarshaler + implements StatelessMarshaler2, Object> { + public static final KeyValueStatelessMarshaler INSTANCE = new KeyValueStatelessMarshaler(); + private static final byte[] EMPTY_BYTES = new byte[0]; + + @Override + public void writeTo( + Serializer output, AttributeKey attributeKey, Object value, MarshalerContext context) + throws IOException { + if (attributeKey.getKey().isEmpty()) { + output.serializeString(KeyValue.KEY, EMPTY_BYTES); + } else if (attributeKey instanceof InternalAttributeKeyImpl) { + byte[] keyUtf8 = ((InternalAttributeKeyImpl) attributeKey).getKeyUtf8(); + output.serializeString(KeyValue.KEY, keyUtf8); + } else { + output.serializeStringWithContext(KeyValue.KEY, attributeKey.getKey(), context); + } + output.serializeMessageWithContext( + KeyValue.VALUE, attributeKey, value, ValueStatelessMarshaler.INSTANCE, context); + } + + @Override + public int getBinarySerializedSize( + AttributeKey attributeKey, Object value, MarshalerContext context) { + int size = 0; + if (!attributeKey.getKey().isEmpty()) { + if (attributeKey instanceof InternalAttributeKeyImpl) { + byte[] keyUtf8 = ((InternalAttributeKeyImpl) attributeKey).getKeyUtf8(); + size += MarshalerUtil.sizeBytes(KeyValue.KEY, keyUtf8); + } else { + return StatelessMarshalerUtil.sizeStringWithContext( + KeyValue.KEY, attributeKey.getKey(), context); + } + } + size += + StatelessMarshalerUtil.sizeMessageWithContext( + KeyValue.VALUE, attributeKey, value, ValueStatelessMarshaler.INSTANCE, context); + + return size; + } + + private static class ValueStatelessMarshaler + implements StatelessMarshaler2, Object> { + static final ValueStatelessMarshaler INSTANCE = new ValueStatelessMarshaler(); + + @SuppressWarnings("unchecked") + @Override + public int getBinarySerializedSize( + AttributeKey attributeKey, Object value, MarshalerContext context) { + AttributeType attributeType = attributeKey.getType(); + switch (attributeType) { + case STRING: + return StringAnyValueStatelessMarshaler.INSTANCE.getBinarySerializedSize( + (String) value, context); + case LONG: + return IntAnyValueStatelessMarshaler.INSTANCE.getBinarySerializedSize( + (Long) value, context); + case BOOLEAN: + return BoolAnyValueStatelessMarshaler.INSTANCE.getBinarySerializedSize( + (Boolean) value, context); + case DOUBLE: + return DoubleAnyValueStatelessMarshaler.INSTANCE.getBinarySerializedSize( + (Double) value, context); + case STRING_ARRAY: + case LONG_ARRAY: + case BOOLEAN_ARRAY: + case DOUBLE_ARRAY: + return StatelessMarshalerUtil.sizeMessageWithContext( + AnyValue.ARRAY_VALUE, + attributeType, + (List) value, + ArrayAnyValueStatelessMarshaler.INSTANCE, + context); + } + // Error prone ensures the switch statement is complete, otherwise only can happen with + // unaligned versions which are not supported. + throw new IllegalArgumentException("Unsupported attribute type."); + } + + @SuppressWarnings("unchecked") + @Override + public void writeTo( + Serializer output, AttributeKey attributeKey, Object value, MarshalerContext context) + throws IOException { + AttributeType attributeType = attributeKey.getType(); + switch (attributeType) { + case STRING: + StringAnyValueStatelessMarshaler.INSTANCE.writeTo(output, (String) value, context); + return; + case LONG: + IntAnyValueStatelessMarshaler.INSTANCE.writeTo(output, (Long) value, context); + return; + case BOOLEAN: + BoolAnyValueStatelessMarshaler.INSTANCE.writeTo(output, (Boolean) value, context); + return; + case DOUBLE: + DoubleAnyValueStatelessMarshaler.INSTANCE.writeTo(output, (Double) value, context); + return; + case STRING_ARRAY: + case LONG_ARRAY: + case BOOLEAN_ARRAY: + case DOUBLE_ARRAY: + output.serializeMessageWithContext( + AnyValue.ARRAY_VALUE, + attributeType, + (List) value, + ArrayAnyValueStatelessMarshaler.INSTANCE, + context); + return; + } + // Error prone ensures the switch statement is complete, otherwise only can happen with + // unaligned versions which are not supported. + throw new IllegalArgumentException("Unsupported attribute type."); + } + } +} diff --git a/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/StringAnyValueStatelessMarshaler.java b/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/StringAnyValueStatelessMarshaler.java new file mode 100644 index 00000000000..59924ae4dbc --- /dev/null +++ b/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/StringAnyValueStatelessMarshaler.java @@ -0,0 +1,34 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.exporter.internal.otlp; + +import io.opentelemetry.exporter.internal.marshal.MarshalerContext; +import io.opentelemetry.exporter.internal.marshal.Serializer; +import io.opentelemetry.exporter.internal.marshal.StatelessMarshaler; +import io.opentelemetry.exporter.internal.marshal.StatelessMarshalerUtil; +import io.opentelemetry.proto.common.v1.internal.AnyValue; +import java.io.IOException; + +/** + * A Marshaler of string-valued {@link AnyValue}. See {@link StringAnyValueMarshaler}. + * + *

      This class is internal and is hence not for public use. Its APIs are unstable and can change + * at any time. + */ +final class StringAnyValueStatelessMarshaler implements StatelessMarshaler { + static final StringAnyValueStatelessMarshaler INSTANCE = new StringAnyValueStatelessMarshaler(); + + @Override + public void writeTo(Serializer output, String value, MarshalerContext context) + throws IOException { + output.serializeStringWithContext(AnyValue.STRING_VALUE, value, context); + } + + @Override + public int getBinarySerializedSize(String value, MarshalerContext context) { + return StatelessMarshalerUtil.sizeStringWithContext(AnyValue.STRING_VALUE, value, context); + } +} diff --git a/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/traces/InstrumentationScopeSpansStatelessMarshaler.java b/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/traces/InstrumentationScopeSpansStatelessMarshaler.java new file mode 100644 index 00000000000..7bfdcb75adb --- /dev/null +++ b/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/traces/InstrumentationScopeSpansStatelessMarshaler.java @@ -0,0 +1,63 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.exporter.internal.otlp.traces; + +import io.opentelemetry.exporter.internal.marshal.MarshalerContext; +import io.opentelemetry.exporter.internal.marshal.MarshalerUtil; +import io.opentelemetry.exporter.internal.marshal.Serializer; +import io.opentelemetry.exporter.internal.marshal.StatelessMarshaler2; +import io.opentelemetry.exporter.internal.marshal.StatelessMarshalerUtil; +import io.opentelemetry.exporter.internal.otlp.InstrumentationScopeMarshaler; +import io.opentelemetry.proto.trace.v1.internal.ScopeSpans; +import io.opentelemetry.sdk.common.InstrumentationScopeInfo; +import io.opentelemetry.sdk.trace.data.SpanData; +import java.io.IOException; +import java.util.List; + +/** See {@link InstrumentationScopeSpansMarshaler}. */ +final class InstrumentationScopeSpansStatelessMarshaler + implements StatelessMarshaler2> { + static final InstrumentationScopeSpansStatelessMarshaler INSTANCE = + new InstrumentationScopeSpansStatelessMarshaler(); + + @Override + public void writeTo( + Serializer output, + InstrumentationScopeInfo instrumentationScope, + List spans, + MarshalerContext context) + throws IOException { + InstrumentationScopeMarshaler instrumentationScopeMarshaler = + context.getData(InstrumentationScopeMarshaler.class); + + output.serializeMessage(ScopeSpans.SCOPE, instrumentationScopeMarshaler); + output.serializeRepeatedMessageWithContext( + ScopeSpans.SPANS, spans, SpanStatelessMarshaler.INSTANCE, context); + output.serializeStringWithContext( + ScopeSpans.SCHEMA_URL, instrumentationScope.getSchemaUrl(), context); + } + + @Override + public int getBinarySerializedSize( + InstrumentationScopeInfo instrumentationScope, + List spans, + MarshalerContext context) { + InstrumentationScopeMarshaler instrumentationScopeMarshaler = + InstrumentationScopeMarshaler.create(instrumentationScope); + context.addData(instrumentationScopeMarshaler); + + int size = 0; + size += MarshalerUtil.sizeMessage(ScopeSpans.SCOPE, instrumentationScopeMarshaler); + size += + StatelessMarshalerUtil.sizeRepeatedMessageWithContext( + ScopeSpans.SPANS, spans, SpanStatelessMarshaler.INSTANCE, context); + size += + StatelessMarshalerUtil.sizeStringWithContext( + ScopeSpans.SCHEMA_URL, instrumentationScope.getSchemaUrl(), context); + + return size; + } +} diff --git a/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/traces/LowAllocationTraceRequestMarshaler.java b/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/traces/LowAllocationTraceRequestMarshaler.java new file mode 100644 index 00000000000..5da173f3c3a --- /dev/null +++ b/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/traces/LowAllocationTraceRequestMarshaler.java @@ -0,0 +1,107 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.exporter.internal.otlp.traces; + +import io.opentelemetry.exporter.internal.marshal.Marshaler; +import io.opentelemetry.exporter.internal.marshal.MarshalerContext; +import io.opentelemetry.exporter.internal.marshal.Serializer; +import io.opentelemetry.exporter.internal.marshal.StatelessMarshalerUtil; +import io.opentelemetry.proto.collector.trace.v1.internal.ExportTraceServiceRequest; +import io.opentelemetry.sdk.common.InstrumentationScopeInfo; +import io.opentelemetry.sdk.resources.Resource; +import io.opentelemetry.sdk.trace.data.SpanData; +import java.io.IOException; +import java.util.Collection; +import java.util.Collections; +import java.util.List; +import java.util.Map; + +/** + * {@link Marshaler} to convert SDK {@link SpanData} to OTLP ExportTraceServiceRequest. See {@link + * TraceRequestMarshaler}. + * + *

      Example usage: + * + *

      {@code
      + * void marshal(LowAllocationTraceRequestMarshaler requestMarshaler, OutputStream output,
      + *     List spanList) throws IOException {
      + *   requestMarshaler.initialize(spanList);
      + *   try {
      + *     requestMarshaler.writeBinaryTo(output);
      + *   } finally {
      + *     requestMarshaler.reset();
      + *   }
      + * }
      + * }
      + * + *

      This class is internal and is hence not for public use. Its APIs are unstable and can change + * at any time. + */ +public final class LowAllocationTraceRequestMarshaler extends Marshaler { + private static final MarshalerContext.Key RESOURCE_SPAN_SIZE_CALCULATOR_KEY = + MarshalerContext.key(); + private static final MarshalerContext.Key RESOURCE_SPAN_WRITER_KEY = MarshalerContext.key(); + + private final MarshalerContext context = new MarshalerContext(); + + @SuppressWarnings("NullAway") + private Map>> resourceAndScopeMap; + + private int size; + + public void initialize(Collection spanDataList) { + resourceAndScopeMap = groupByResourceAndScope(context, spanDataList); + size = calculateSize(context, resourceAndScopeMap); + } + + public void reset() { + context.reset(); + } + + @Override + public int getBinarySerializedSize() { + return size; + } + + @Override + public void writeTo(Serializer output) throws IOException { + // serializing can be retried, reset the indexes, so we could call writeTo multiple times + context.resetReadIndex(); + output.serializeRepeatedMessageWithContext( + ExportTraceServiceRequest.RESOURCE_SPANS, + resourceAndScopeMap, + ResourceSpansStatelessMarshaler.INSTANCE, + context, + RESOURCE_SPAN_WRITER_KEY); + } + + private static int calculateSize( + MarshalerContext context, + Map>> resourceAndScopeMap) { + return StatelessMarshalerUtil.sizeRepeatedMessageWithContext( + ExportTraceServiceRequest.RESOURCE_SPANS, + resourceAndScopeMap, + ResourceSpansStatelessMarshaler.INSTANCE, + context, + RESOURCE_SPAN_SIZE_CALCULATOR_KEY); + } + + private static Map>> + groupByResourceAndScope(MarshalerContext context, Collection spanDataList) { + + if (spanDataList.isEmpty()) { + return Collections.emptyMap(); + } + + return StatelessMarshalerUtil.groupByResourceAndScope( + spanDataList, + // TODO(anuraaga): Replace with an internal SdkData type of interface that exposes these + // two. + SpanData::getResource, + SpanData::getInstrumentationScopeInfo, + context); + } +} diff --git a/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/traces/ResourceSpansStatelessMarshaler.java b/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/traces/ResourceSpansStatelessMarshaler.java new file mode 100644 index 00000000000..de2aa078f0e --- /dev/null +++ b/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/traces/ResourceSpansStatelessMarshaler.java @@ -0,0 +1,80 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.exporter.internal.otlp.traces; + +import io.opentelemetry.exporter.internal.marshal.MarshalerContext; +import io.opentelemetry.exporter.internal.marshal.MarshalerUtil; +import io.opentelemetry.exporter.internal.marshal.Serializer; +import io.opentelemetry.exporter.internal.marshal.StatelessMarshaler2; +import io.opentelemetry.exporter.internal.marshal.StatelessMarshalerUtil; +import io.opentelemetry.exporter.internal.otlp.ResourceMarshaler; +import io.opentelemetry.proto.trace.v1.internal.ResourceSpans; +import io.opentelemetry.sdk.common.InstrumentationScopeInfo; +import io.opentelemetry.sdk.resources.Resource; +import io.opentelemetry.sdk.trace.data.SpanData; +import java.io.IOException; +import java.util.List; +import java.util.Map; + +/** + * A Marshaler of ResourceSpans. See {@link ResourceSpansMarshaler}. + * + *

      This class is internal and is hence not for public use. Its APIs are unstable and can change + * at any time. + */ +public final class ResourceSpansStatelessMarshaler + implements StatelessMarshaler2>> { + static final ResourceSpansStatelessMarshaler INSTANCE = new ResourceSpansStatelessMarshaler(); + private static final MarshalerContext.Key SCOPE_SPAN_WRITER_KEY = MarshalerContext.key(); + private static final MarshalerContext.Key SCOPE_SPAN_SIZE_CALCULATOR_KEY = MarshalerContext.key(); + + @Override + public void writeTo( + Serializer output, + Resource resource, + Map> scopeMap, + MarshalerContext context) + throws IOException { + ResourceMarshaler resourceMarshaler = context.getData(ResourceMarshaler.class); + output.serializeMessage(ResourceSpans.RESOURCE, resourceMarshaler); + + output.serializeRepeatedMessageWithContext( + ResourceSpans.SCOPE_SPANS, + scopeMap, + InstrumentationScopeSpansStatelessMarshaler.INSTANCE, + context, + SCOPE_SPAN_WRITER_KEY); + + output.serializeStringWithContext(ResourceSpans.SCHEMA_URL, resource.getSchemaUrl(), context); + } + + @Override + public int getBinarySerializedSize( + Resource resource, + Map> scopeMap, + MarshalerContext context) { + + int size = 0; + + ResourceMarshaler resourceMarshaler = ResourceMarshaler.create(resource); + context.addData(resourceMarshaler); + size += MarshalerUtil.sizeMessage(ResourceSpans.RESOURCE, resourceMarshaler); + + size += + StatelessMarshalerUtil.sizeRepeatedMessageWithContext( + ResourceSpans.SCOPE_SPANS, + scopeMap, + InstrumentationScopeSpansStatelessMarshaler.INSTANCE, + context, + SCOPE_SPAN_SIZE_CALCULATOR_KEY); + + size += + StatelessMarshalerUtil.sizeStringWithContext( + ResourceSpans.SCHEMA_URL, resource.getSchemaUrl(), context); + + return size; + } +} diff --git a/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/traces/SpanEventStatelessMarshaler.java b/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/traces/SpanEventStatelessMarshaler.java new file mode 100644 index 00000000000..ef09f065749 --- /dev/null +++ b/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/traces/SpanEventStatelessMarshaler.java @@ -0,0 +1,49 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.exporter.internal.otlp.traces; + +import io.opentelemetry.exporter.internal.marshal.MarshalerContext; +import io.opentelemetry.exporter.internal.marshal.MarshalerUtil; +import io.opentelemetry.exporter.internal.marshal.Serializer; +import io.opentelemetry.exporter.internal.marshal.StatelessMarshaler; +import io.opentelemetry.exporter.internal.marshal.StatelessMarshalerUtil; +import io.opentelemetry.exporter.internal.otlp.KeyValueStatelessMarshaler; +import io.opentelemetry.proto.trace.v1.internal.Span; +import io.opentelemetry.sdk.trace.data.EventData; +import java.io.IOException; + +/** See {@link SpanEventMarshaler}. */ +final class SpanEventStatelessMarshaler implements StatelessMarshaler { + static final SpanEventStatelessMarshaler INSTANCE = new SpanEventStatelessMarshaler(); + + @Override + public void writeTo(Serializer output, EventData event, MarshalerContext context) + throws IOException { + output.serializeFixed64(Span.Event.TIME_UNIX_NANO, event.getEpochNanos()); + output.serializeStringWithContext(Span.Event.NAME, event.getName(), context); + output.serializeRepeatedMessageWithContext( + Span.Event.ATTRIBUTES, event.getAttributes(), KeyValueStatelessMarshaler.INSTANCE, context); + int droppedAttributesCount = event.getTotalAttributeCount() - event.getAttributes().size(); + output.serializeUInt32(Span.Event.DROPPED_ATTRIBUTES_COUNT, droppedAttributesCount); + } + + @Override + public int getBinarySerializedSize(EventData event, MarshalerContext context) { + int size = 0; + size += MarshalerUtil.sizeFixed64(Span.Event.TIME_UNIX_NANO, event.getEpochNanos()); + size += StatelessMarshalerUtil.sizeStringWithContext(Span.Event.NAME, event.getName(), context); + size += + StatelessMarshalerUtil.sizeRepeatedMessageWithContext( + Span.Event.ATTRIBUTES, + event.getAttributes(), + KeyValueStatelessMarshaler.INSTANCE, + context); + int droppedAttributesCount = event.getTotalAttributeCount() - event.getAttributes().size(); + size += MarshalerUtil.sizeUInt32(Span.Event.DROPPED_ATTRIBUTES_COUNT, droppedAttributesCount); + + return size; + } +} diff --git a/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/traces/SpanLinkMarshaler.java b/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/traces/SpanLinkMarshaler.java index 01310713009..86db5e2c983 100644 --- a/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/traces/SpanLinkMarshaler.java +++ b/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/traces/SpanLinkMarshaler.java @@ -5,7 +5,7 @@ package io.opentelemetry.exporter.internal.otlp.traces; -import static io.opentelemetry.api.trace.propagation.internal.W3CTraceContextEncoding.encodeTraceState; +import static io.opentelemetry.exporter.internal.otlp.traces.SpanMarshaler.encodeTraceState; import io.opentelemetry.api.trace.TraceFlags; import io.opentelemetry.api.trace.TraceState; @@ -16,12 +16,11 @@ import io.opentelemetry.proto.trace.v1.internal.Span; import io.opentelemetry.sdk.trace.data.LinkData; import java.io.IOException; -import java.nio.charset.StandardCharsets; import java.util.List; final class SpanLinkMarshaler extends MarshalerWithSize { private static final SpanLinkMarshaler[] EMPTY = new SpanLinkMarshaler[0]; - private static final byte[] EMPTY_BYTES = new byte[0]; + private final String traceId; private final String spanId; private final byte[] traceStateUtf8; @@ -46,11 +45,7 @@ static SpanLinkMarshaler[] createRepeated(List links) { // Visible for testing static SpanLinkMarshaler create(LinkData link) { - TraceState traceState = link.getSpanContext().getTraceState(); - byte[] traceStateUtf8 = - traceState.isEmpty() - ? EMPTY_BYTES - : encodeTraceState(traceState).getBytes(StandardCharsets.UTF_8); + byte[] traceStateUtf8 = encodeSpanLinkTraceState(link); return new SpanLinkMarshaler( link.getSpanContext().getTraceId(), @@ -118,4 +113,9 @@ private static int calculateSize( Span.Link.FLAGS, SpanFlags.withParentIsRemoteFlags(flags, isLinkContextRemote)); return size; } + + static byte[] encodeSpanLinkTraceState(LinkData link) { + TraceState traceState = link.getSpanContext().getTraceState(); + return encodeTraceState(traceState); + } } diff --git a/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/traces/SpanLinkStatelessMarshaler.java b/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/traces/SpanLinkStatelessMarshaler.java new file mode 100644 index 00000000000..2b711d8e96c --- /dev/null +++ b/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/traces/SpanLinkStatelessMarshaler.java @@ -0,0 +1,65 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.exporter.internal.otlp.traces; + +import static io.opentelemetry.exporter.internal.otlp.traces.SpanLinkMarshaler.encodeSpanLinkTraceState; + +import io.opentelemetry.exporter.internal.marshal.MarshalerContext; +import io.opentelemetry.exporter.internal.marshal.MarshalerUtil; +import io.opentelemetry.exporter.internal.marshal.Serializer; +import io.opentelemetry.exporter.internal.marshal.StatelessMarshaler; +import io.opentelemetry.exporter.internal.marshal.StatelessMarshalerUtil; +import io.opentelemetry.exporter.internal.otlp.KeyValueStatelessMarshaler; +import io.opentelemetry.proto.trace.v1.internal.Span; +import io.opentelemetry.sdk.trace.data.LinkData; +import java.io.IOException; + +/** See {@link SpanLinkMarshaler}. */ +final class SpanLinkStatelessMarshaler implements StatelessMarshaler { + static final SpanLinkStatelessMarshaler INSTANCE = new SpanLinkStatelessMarshaler(); + + @Override + public void writeTo(Serializer output, LinkData link, MarshalerContext context) + throws IOException { + output.serializeTraceId(Span.Link.TRACE_ID, link.getSpanContext().getTraceId(), context); + output.serializeSpanId(Span.Link.SPAN_ID, link.getSpanContext().getSpanId(), context); + output.serializeString(Span.Link.TRACE_STATE, context.getData(byte[].class)); + output.serializeRepeatedMessageWithContext( + Span.Link.ATTRIBUTES, link.getAttributes(), KeyValueStatelessMarshaler.INSTANCE, context); + int droppedAttributesCount = link.getTotalAttributeCount() - link.getAttributes().size(); + output.serializeUInt32(Span.Link.DROPPED_ATTRIBUTES_COUNT, droppedAttributesCount); + output.serializeFixed32( + Span.Link.FLAGS, + SpanFlags.withParentIsRemoteFlags( + link.getSpanContext().getTraceFlags(), link.getSpanContext().isRemote())); + } + + @Override + public int getBinarySerializedSize(LinkData link, MarshalerContext context) { + byte[] traceStateUtf8 = encodeSpanLinkTraceState(link); + context.addData(traceStateUtf8); + + int size = 0; + size += MarshalerUtil.sizeTraceId(Span.Link.TRACE_ID, link.getSpanContext().getTraceId()); + size += MarshalerUtil.sizeSpanId(Span.Link.SPAN_ID, link.getSpanContext().getSpanId()); + size += MarshalerUtil.sizeBytes(Span.Link.TRACE_STATE, traceStateUtf8); + size += + StatelessMarshalerUtil.sizeRepeatedMessageWithContext( + Span.Link.ATTRIBUTES, + link.getAttributes(), + KeyValueStatelessMarshaler.INSTANCE, + context); + int droppedAttributesCount = link.getTotalAttributeCount() - link.getAttributes().size(); + size += MarshalerUtil.sizeUInt32(Span.Link.DROPPED_ATTRIBUTES_COUNT, droppedAttributesCount); + size += + MarshalerUtil.sizeFixed32( + Span.Link.FLAGS, + SpanFlags.withParentIsRemoteFlags( + link.getSpanContext().getTraceFlags(), link.getSpanContext().isRemote())); + + return size; + } +} diff --git a/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/traces/SpanMarshaler.java b/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/traces/SpanMarshaler.java index 15e310c1ac7..2e862c6cc69 100644 --- a/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/traces/SpanMarshaler.java +++ b/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/traces/SpanMarshaler.java @@ -5,11 +5,10 @@ package io.opentelemetry.exporter.internal.otlp.traces; -import static io.opentelemetry.api.trace.propagation.internal.W3CTraceContextEncoding.encodeTraceState; - import io.opentelemetry.api.trace.SpanKind; import io.opentelemetry.api.trace.TraceFlags; import io.opentelemetry.api.trace.TraceState; +import io.opentelemetry.api.trace.propagation.internal.W3CTraceContextEncoding; import io.opentelemetry.exporter.internal.marshal.MarshalerUtil; import io.opentelemetry.exporter.internal.marshal.MarshalerWithSize; import io.opentelemetry.exporter.internal.marshal.ProtoEnumInfo; @@ -54,11 +53,7 @@ static SpanMarshaler create(SpanData spanData) { ? spanData.getParentSpanContext().getSpanId() : null; - TraceState traceState = spanData.getSpanContext().getTraceState(); - byte[] traceStateUtf8 = - traceState.isEmpty() - ? EMPTY_BYTES - : encodeTraceState(traceState).getBytes(StandardCharsets.UTF_8); + byte[] traceStateUtf8 = encodeSpanTraceState(spanData); return new SpanMarshaler( spanData.getSpanContext().getTraceId(), @@ -226,4 +221,15 @@ static ProtoEnumInfo toProtoSpanKind(SpanKind kind) { // NB: Should not be possible with aligned versions. return Span.SpanKind.SPAN_KIND_UNSPECIFIED; } + + static byte[] encodeSpanTraceState(SpanData span) { + TraceState traceState = span.getSpanContext().getTraceState(); + return encodeTraceState(traceState); + } + + static byte[] encodeTraceState(TraceState traceState) { + return traceState.isEmpty() + ? EMPTY_BYTES + : W3CTraceContextEncoding.encodeTraceState(traceState).getBytes(StandardCharsets.UTF_8); + } } diff --git a/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/traces/SpanStatelessMarshaler.java b/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/traces/SpanStatelessMarshaler.java new file mode 100644 index 00000000000..80703cf628d --- /dev/null +++ b/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/traces/SpanStatelessMarshaler.java @@ -0,0 +1,117 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.exporter.internal.otlp.traces; + +import static io.opentelemetry.exporter.internal.otlp.traces.SpanMarshaler.encodeSpanTraceState; +import static io.opentelemetry.exporter.internal.otlp.traces.SpanMarshaler.toProtoSpanKind; + +import io.opentelemetry.exporter.internal.marshal.MarshalerContext; +import io.opentelemetry.exporter.internal.marshal.MarshalerUtil; +import io.opentelemetry.exporter.internal.marshal.Serializer; +import io.opentelemetry.exporter.internal.marshal.StatelessMarshaler; +import io.opentelemetry.exporter.internal.marshal.StatelessMarshalerUtil; +import io.opentelemetry.exporter.internal.otlp.KeyValueStatelessMarshaler; +import io.opentelemetry.proto.trace.v1.internal.Span; +import io.opentelemetry.sdk.trace.data.SpanData; +import java.io.IOException; + +/** See {@link SpanMarshaler}. */ +final class SpanStatelessMarshaler implements StatelessMarshaler { + static final SpanStatelessMarshaler INSTANCE = new SpanStatelessMarshaler(); + + @Override + public void writeTo(Serializer output, SpanData span, MarshalerContext context) + throws IOException { + output.serializeTraceId(Span.TRACE_ID, span.getTraceId(), context); + output.serializeSpanId(Span.SPAN_ID, span.getSpanId(), context); + + byte[] traceStateUtf8 = context.getData(byte[].class); + output.serializeString(Span.TRACE_STATE, traceStateUtf8); + String parentSpanId = + span.getParentSpanContext().isValid() ? span.getParentSpanContext().getSpanId() : null; + output.serializeSpanId(Span.PARENT_SPAN_ID, parentSpanId, context); + + output.serializeStringWithContext(Span.NAME, span.getName(), context); + output.serializeEnum(Span.KIND, toProtoSpanKind(span.getKind())); + + output.serializeFixed64(Span.START_TIME_UNIX_NANO, span.getStartEpochNanos()); + output.serializeFixed64(Span.END_TIME_UNIX_NANO, span.getEndEpochNanos()); + + output.serializeRepeatedMessageWithContext( + Span.ATTRIBUTES, span.getAttributes(), KeyValueStatelessMarshaler.INSTANCE, context); + int droppedAttributesCount = span.getTotalAttributeCount() - span.getAttributes().size(); + output.serializeUInt32(Span.DROPPED_ATTRIBUTES_COUNT, droppedAttributesCount); + + output.serializeRepeatedMessageWithContext( + Span.EVENTS, span.getEvents(), SpanEventStatelessMarshaler.INSTANCE, context); + int droppedEventsCount = span.getTotalRecordedEvents() - span.getEvents().size(); + output.serializeUInt32(Span.DROPPED_EVENTS_COUNT, droppedEventsCount); + + output.serializeRepeatedMessageWithContext( + Span.LINKS, span.getLinks(), SpanLinkStatelessMarshaler.INSTANCE, context); + int droppedLinksCount = span.getTotalRecordedLinks() - span.getLinks().size(); + output.serializeUInt32(Span.DROPPED_LINKS_COUNT, droppedLinksCount); + + output.serializeMessageWithContext( + Span.STATUS, span.getStatus(), SpanStatusStatelessMarshaler.INSTANCE, context); + + output.serializeFixed32( + Span.FLAGS, + SpanFlags.withParentIsRemoteFlags( + span.getSpanContext().getTraceFlags(), span.getParentSpanContext().isRemote())); + } + + @Override + public int getBinarySerializedSize(SpanData span, MarshalerContext context) { + int size = 0; + size += MarshalerUtil.sizeTraceId(Span.TRACE_ID, span.getTraceId()); + size += MarshalerUtil.sizeSpanId(Span.SPAN_ID, span.getSpanId()); + + byte[] traceStateUtf8 = encodeSpanTraceState(span); + context.addData(traceStateUtf8); + + size += MarshalerUtil.sizeBytes(Span.TRACE_STATE, traceStateUtf8); + String parentSpanId = + span.getParentSpanContext().isValid() ? span.getParentSpanContext().getSpanId() : null; + size += MarshalerUtil.sizeSpanId(Span.PARENT_SPAN_ID, parentSpanId); + + size += StatelessMarshalerUtil.sizeStringWithContext(Span.NAME, span.getName(), context); + size += MarshalerUtil.sizeEnum(Span.KIND, toProtoSpanKind(span.getKind())); + + size += MarshalerUtil.sizeFixed64(Span.START_TIME_UNIX_NANO, span.getStartEpochNanos()); + size += MarshalerUtil.sizeFixed64(Span.END_TIME_UNIX_NANO, span.getEndEpochNanos()); + + size += + StatelessMarshalerUtil.sizeRepeatedMessageWithContext( + Span.ATTRIBUTES, span.getAttributes(), KeyValueStatelessMarshaler.INSTANCE, context); + int droppedAttributesCount = span.getTotalAttributeCount() - span.getAttributes().size(); + size += MarshalerUtil.sizeUInt32(Span.DROPPED_ATTRIBUTES_COUNT, droppedAttributesCount); + + size += + StatelessMarshalerUtil.sizeRepeatedMessageWithContext( + Span.EVENTS, span.getEvents(), SpanEventStatelessMarshaler.INSTANCE, context); + int droppedEventsCount = span.getTotalRecordedEvents() - span.getEvents().size(); + size += MarshalerUtil.sizeUInt32(Span.DROPPED_EVENTS_COUNT, droppedEventsCount); + + size += + StatelessMarshalerUtil.sizeRepeatedMessageWithContext( + Span.LINKS, span.getLinks(), SpanLinkStatelessMarshaler.INSTANCE, context); + int droppedLinksCount = span.getTotalRecordedLinks() - span.getLinks().size(); + size += MarshalerUtil.sizeUInt32(Span.DROPPED_LINKS_COUNT, droppedLinksCount); + + size += + StatelessMarshalerUtil.sizeMessageWithContext( + Span.STATUS, span.getStatus(), SpanStatusStatelessMarshaler.INSTANCE, context); + + size += + MarshalerUtil.sizeFixed32( + Span.FLAGS, + SpanFlags.withParentIsRemoteFlags( + span.getSpanContext().getTraceFlags(), span.getParentSpanContext().isRemote())); + + return size; + } +} diff --git a/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/traces/SpanStatusMarshaler.java b/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/traces/SpanStatusMarshaler.java index 0809e85c978..981bf481005 100644 --- a/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/traces/SpanStatusMarshaler.java +++ b/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/traces/SpanStatusMarshaler.java @@ -19,12 +19,7 @@ final class SpanStatusMarshaler extends MarshalerWithSize { private final byte[] descriptionUtf8; static SpanStatusMarshaler create(StatusData status) { - ProtoEnumInfo protoStatusCode = Status.StatusCode.STATUS_CODE_UNSET; - if (status.getStatusCode() == StatusCode.OK) { - protoStatusCode = Status.StatusCode.STATUS_CODE_OK; - } else if (status.getStatusCode() == StatusCode.ERROR) { - protoStatusCode = Status.StatusCode.STATUS_CODE_ERROR; - } + ProtoEnumInfo protoStatusCode = toProtoSpanStatus(status); byte[] description = MarshalerUtil.toBytes(status.getDescription()); return new SpanStatusMarshaler(protoStatusCode, description); } @@ -47,4 +42,14 @@ private static int computeSize(ProtoEnumInfo protoStatusCode, byte[] description size += MarshalerUtil.sizeEnum(Status.CODE, protoStatusCode); return size; } + + static ProtoEnumInfo toProtoSpanStatus(StatusData status) { + ProtoEnumInfo protoStatusCode = Status.StatusCode.STATUS_CODE_UNSET; + if (status.getStatusCode() == StatusCode.OK) { + protoStatusCode = Status.StatusCode.STATUS_CODE_OK; + } else if (status.getStatusCode() == StatusCode.ERROR) { + protoStatusCode = Status.StatusCode.STATUS_CODE_ERROR; + } + return protoStatusCode; + } } diff --git a/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/traces/SpanStatusStatelessMarshaler.java b/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/traces/SpanStatusStatelessMarshaler.java new file mode 100644 index 00000000000..9b6907ccdef --- /dev/null +++ b/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/traces/SpanStatusStatelessMarshaler.java @@ -0,0 +1,45 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.exporter.internal.otlp.traces; + +import static io.opentelemetry.exporter.internal.otlp.traces.SpanStatusMarshaler.toProtoSpanStatus; + +import io.opentelemetry.exporter.internal.marshal.MarshalerContext; +import io.opentelemetry.exporter.internal.marshal.MarshalerUtil; +import io.opentelemetry.exporter.internal.marshal.ProtoEnumInfo; +import io.opentelemetry.exporter.internal.marshal.Serializer; +import io.opentelemetry.exporter.internal.marshal.StatelessMarshaler; +import io.opentelemetry.proto.trace.v1.internal.Status; +import io.opentelemetry.sdk.trace.data.StatusData; +import java.io.IOException; + +/** See {@link SpanStatusMarshaler}. */ +final class SpanStatusStatelessMarshaler implements StatelessMarshaler { + static final SpanStatusStatelessMarshaler INSTANCE = new SpanStatusStatelessMarshaler(); + + @Override + public void writeTo(Serializer output, StatusData status, MarshalerContext context) + throws IOException { + ProtoEnumInfo protoStatusCode = toProtoSpanStatus(status); + byte[] descriptionUtf8 = context.getData(byte[].class); + + output.serializeString(Status.MESSAGE, descriptionUtf8); + output.serializeEnum(Status.CODE, protoStatusCode); + } + + @Override + public int getBinarySerializedSize(StatusData status, MarshalerContext context) { + ProtoEnumInfo protoStatusCode = toProtoSpanStatus(status); + byte[] descriptionUtf8 = MarshalerUtil.toBytes(status.getDescription()); + context.addData(descriptionUtf8); + + int size = 0; + size += MarshalerUtil.sizeBytes(Status.MESSAGE, descriptionUtf8); + size += MarshalerUtil.sizeEnum(Status.CODE, protoStatusCode); + + return size; + } +} diff --git a/exporters/otlp/common/src/test/java/io/opentelemetry/exporter/internal/otlp/traces/LowAllocationTraceRequestMarshalerTest.java b/exporters/otlp/common/src/test/java/io/opentelemetry/exporter/internal/otlp/traces/LowAllocationTraceRequestMarshalerTest.java new file mode 100644 index 00000000000..e868373d0ca --- /dev/null +++ b/exporters/otlp/common/src/test/java/io/opentelemetry/exporter/internal/otlp/traces/LowAllocationTraceRequestMarshalerTest.java @@ -0,0 +1,159 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.exporter.internal.otlp.traces; + +import static org.assertj.core.api.Assertions.assertThat; + +import io.opentelemetry.api.common.AttributeKey; +import io.opentelemetry.api.common.Attributes; +import io.opentelemetry.api.trace.SpanContext; +import io.opentelemetry.api.trace.SpanKind; +import io.opentelemetry.api.trace.TraceFlags; +import io.opentelemetry.api.trace.TraceState; +import io.opentelemetry.sdk.common.InstrumentationScopeInfo; +import io.opentelemetry.sdk.resources.Resource; +import io.opentelemetry.sdk.testing.trace.TestSpanData; +import io.opentelemetry.sdk.trace.data.EventData; +import io.opentelemetry.sdk.trace.data.LinkData; +import io.opentelemetry.sdk.trace.data.SpanData; +import io.opentelemetry.sdk.trace.data.StatusData; +import java.io.ByteArrayOutputStream; +import java.nio.charset.StandardCharsets; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import org.junit.jupiter.api.Test; + +class LowAllocationTraceRequestMarshalerTest { + + private static final AttributeKey KEY_BOOL = AttributeKey.booleanKey("key_bool"); + private static final AttributeKey KEY_STRING = AttributeKey.stringKey("key_string"); + private static final AttributeKey KEY_INT = AttributeKey.longKey("key_int"); + private static final AttributeKey KEY_DOUBLE = AttributeKey.doubleKey("key_double"); + private static final AttributeKey> KEY_STRING_ARRAY = + AttributeKey.stringArrayKey("key_string_array"); + private static final AttributeKey> KEY_LONG_ARRAY = + AttributeKey.longArrayKey("key_long_array"); + private static final AttributeKey> KEY_DOUBLE_ARRAY = + AttributeKey.doubleArrayKey("key_double_array"); + private static final AttributeKey> KEY_BOOLEAN_ARRAY = + AttributeKey.booleanArrayKey("key_boolean_array"); + private static final AttributeKey LINK_ATTR_KEY = AttributeKey.stringKey("link_attr_key"); + + private static final Resource RESOURCE = + Resource.create( + Attributes.builder() + .put(KEY_BOOL, true) + .put(KEY_STRING, "string") + .put(KEY_INT, 100L) + .put(KEY_DOUBLE, 100.3) + .put(KEY_STRING_ARRAY, Arrays.asList("string", "string")) + .put(KEY_LONG_ARRAY, Arrays.asList(12L, 23L)) + .put(KEY_DOUBLE_ARRAY, Arrays.asList(12.3, 23.1)) + .put(KEY_BOOLEAN_ARRAY, Arrays.asList(true, false)) + .build()); + + private static final InstrumentationScopeInfo INSTRUMENTATION_SCOPE_INFO = + InstrumentationScopeInfo.create("name"); + private static final String TRACE_ID = "7b2e170db4df2d593ddb4ddf2ddf2d59"; + private static final String SPAN_ID = "170d3ddb4d23e81f"; + private static final SpanContext SPAN_CONTEXT = + SpanContext.create(TRACE_ID, SPAN_ID, TraceFlags.getSampled(), TraceState.getDefault()); + + private final List spanDataList = createSpanDataList(); + + private static List createSpanDataList() { + List spanDataList = new ArrayList<>(); + for (int i = 0; i < 5; i++) { + spanDataList.add(createSpanData()); + } + return spanDataList; + } + + private static SpanData createSpanData() { + return TestSpanData.builder() + .setResource(RESOURCE) + .setInstrumentationScopeInfo(INSTRUMENTATION_SCOPE_INFO) + .setHasEnded(true) + .setSpanContext(SPAN_CONTEXT) + .setParentSpanContext(SpanContext.getInvalid()) + .setName("GET /api/endpoint") + .setKind(SpanKind.SERVER) + .setStartEpochNanos(12345) + .setEndEpochNanos(12349) + .setAttributes( + Attributes.builder() + .put(KEY_BOOL, true) + .put(KEY_STRING, "string") + .put(KEY_INT, 100L) + .put(KEY_DOUBLE, 100.3) + .build()) + .setTotalAttributeCount(2) + .setEvents( + Arrays.asList( + EventData.create(12347, "my_event_1", Attributes.empty()), + EventData.create(12348, "my_event_2", Attributes.of(KEY_INT, 1234L)), + EventData.create(12349, "my_event_3", Attributes.empty()))) + .setTotalRecordedEvents(4) + .setLinks( + Arrays.asList( + LinkData.create(SPAN_CONTEXT), + LinkData.create(SPAN_CONTEXT, Attributes.of(LINK_ATTR_KEY, "value")))) + .setTotalRecordedLinks(3) + .setStatus(StatusData.ok()) + .build(); + } + + @Test + void validateOutput() throws Exception { + byte[] result; + { + TraceRequestMarshaler requestMarshaler = TraceRequestMarshaler.create(spanDataList); + ByteArrayOutputStream customOutput = + new ByteArrayOutputStream(requestMarshaler.getBinarySerializedSize()); + requestMarshaler.writeBinaryTo(customOutput); + result = customOutput.toByteArray(); + } + + byte[] lowAllocationResult; + { + LowAllocationTraceRequestMarshaler requestMarshaler = + new LowAllocationTraceRequestMarshaler(); + requestMarshaler.initialize(spanDataList); + ByteArrayOutputStream customOutput = + new ByteArrayOutputStream(requestMarshaler.getBinarySerializedSize()); + requestMarshaler.writeBinaryTo(customOutput); + lowAllocationResult = customOutput.toByteArray(); + } + + assertThat(lowAllocationResult).isEqualTo(result); + } + + @Test + void validateJsonOutput() throws Exception { + String result; + { + TraceRequestMarshaler requestMarshaler = TraceRequestMarshaler.create(spanDataList); + ByteArrayOutputStream customOutput = + new ByteArrayOutputStream(requestMarshaler.getBinarySerializedSize()); + requestMarshaler.writeJsonTo(customOutput); + result = new String(customOutput.toByteArray(), StandardCharsets.UTF_8); + } + + String lowAllocationResult; + { + LowAllocationTraceRequestMarshaler requestMarshaler = + new LowAllocationTraceRequestMarshaler(); + requestMarshaler.initialize(spanDataList); + ByteArrayOutputStream customOutput = + new ByteArrayOutputStream(requestMarshaler.getBinarySerializedSize()); + requestMarshaler.writeJsonTo(customOutput); + lowAllocationResult = new String(customOutput.toByteArray(), StandardCharsets.UTF_8); + } + + assertThat(lowAllocationResult).isEqualTo(result); + } +} diff --git a/exporters/otlp/common/src/test/java/io/opentelemetry/exporter/internal/otlp/traces/TraceRequestMarshalerTest.java b/exporters/otlp/common/src/test/java/io/opentelemetry/exporter/internal/otlp/traces/TraceRequestMarshalerTest.java index 8ace6d3231a..464a6f0433a 100644 --- a/exporters/otlp/common/src/test/java/io/opentelemetry/exporter/internal/otlp/traces/TraceRequestMarshalerTest.java +++ b/exporters/otlp/common/src/test/java/io/opentelemetry/exporter/internal/otlp/traces/TraceRequestMarshalerTest.java @@ -27,6 +27,9 @@ import io.opentelemetry.api.trace.TraceId; import io.opentelemetry.api.trace.TraceState; import io.opentelemetry.exporter.internal.marshal.Marshaler; +import io.opentelemetry.exporter.internal.marshal.MarshalerContext; +import io.opentelemetry.exporter.internal.marshal.Serializer; +import io.opentelemetry.exporter.internal.marshal.StatelessMarshaler; import io.opentelemetry.proto.common.v1.AnyValue; import io.opentelemetry.proto.common.v1.ArrayValue; import io.opentelemetry.proto.common.v1.InstrumentationScope; @@ -40,6 +43,7 @@ import io.opentelemetry.sdk.testing.trace.TestSpanData; import io.opentelemetry.sdk.trace.data.EventData; import io.opentelemetry.sdk.trace.data.LinkData; +import io.opentelemetry.sdk.trace.data.SpanData; import io.opentelemetry.sdk.trace.data.StatusData; import java.io.ByteArrayOutputStream; import java.io.IOException; @@ -49,6 +53,8 @@ import java.util.Collections; import java.util.Locale; import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.EnumSource; class TraceRequestMarshalerTest { @@ -116,12 +122,13 @@ void toProtoResourceSpans() { .build()); } - @Test - void toProtoSpan() { + @ParameterizedTest + @EnumSource(MarshalerSource.class) + void toProtoSpan(MarshalerSource marshalerSource) { Span protoSpan = parse( Span.getDefaultInstance(), - SpanMarshaler.create( + marshalerSource.create( TestSpanData.builder() .setHasEnded(true) .setSpanContext(SPAN_CONTEXT) @@ -245,12 +252,13 @@ void toProtoSpan() { .isEqualTo(Status.newBuilder().setCode(STATUS_CODE_OK).build()); } - @Test - void toProtoSpan_withRemoteParent() { + @ParameterizedTest + @EnumSource(MarshalerSource.class) + void toProtoSpan_withRemoteParent(MarshalerSource marshalerSource) { Span protoSpan = parse( Span.getDefaultInstance(), - SpanMarshaler.create( + marshalerSource.create( TestSpanData.builder() .setHasEnded(true) .setSpanContext(SPAN_CONTEXT) @@ -292,9 +300,10 @@ void toProtoSpanKind() { .isEqualTo(io.opentelemetry.proto.trace.v1.internal.Span.SpanKind.SPAN_KIND_CONSUMER); } - @Test - void toProtoStatus() { - assertThat(parse(Status.getDefaultInstance(), SpanStatusMarshaler.create(StatusData.unset()))) + @ParameterizedTest + @EnumSource(MarshalerSource.class) + void toProtoStatus(MarshalerSource marshalerSource) { + assertThat(parse(Status.getDefaultInstance(), marshalerSource.create(StatusData.unset()))) .isEqualTo(Status.newBuilder().setCode(STATUS_CODE_UNSET).build()); assertThat( parse( @@ -313,12 +322,13 @@ void toProtoStatus() { .isEqualTo(Status.newBuilder().setCode(STATUS_CODE_OK).setMessage("OK_OVERRIDE").build()); } - @Test - void toProtoSpanEvent_WithoutAttributes() { + @ParameterizedTest + @EnumSource(MarshalerSource.class) + void toProtoSpanEvent_WithoutAttributes(MarshalerSource marshalerSource) { assertThat( parse( Span.Event.getDefaultInstance(), - SpanEventMarshaler.create( + marshalerSource.create( EventData.create(12345, "test_without_attributes", Attributes.empty())))) .isEqualTo( Span.Event.newBuilder() @@ -327,12 +337,13 @@ void toProtoSpanEvent_WithoutAttributes() { .build()); } - @Test - void toProtoSpanEvent_WithAttributes() { + @ParameterizedTest + @EnumSource(MarshalerSource.class) + void toProtoSpanEvent_WithAttributes(MarshalerSource marshalerSource) { assertThat( parse( Span.Event.getDefaultInstance(), - SpanEventMarshaler.create( + marshalerSource.create( EventData.create( 12345, "test_with_attributes", @@ -351,12 +362,13 @@ void toProtoSpanEvent_WithAttributes() { .build()); } - @Test - void toProtoSpanLink_WithoutAttributes() { + @ParameterizedTest + @EnumSource(MarshalerSource.class) + void toProtoSpanLink_WithoutAttributes(MarshalerSource marshalerSource) { assertThat( parse( Span.Link.getDefaultInstance(), - SpanLinkMarshaler.create(LinkData.create(SPAN_CONTEXT)))) + marshalerSource.create(LinkData.create(SPAN_CONTEXT)))) .isEqualTo( Span.Link.newBuilder() .setTraceId(ByteString.copyFrom(TRACE_ID_BYTES)) @@ -368,12 +380,13 @@ void toProtoSpanLink_WithoutAttributes() { .build()); } - @Test - void toProtoSpanLink_WithRemoteContext() { + @ParameterizedTest + @EnumSource(MarshalerSource.class) + void toProtoSpanLink_WithRemoteContext(MarshalerSource marshalerSource) { assertThat( parse( Span.Link.getDefaultInstance(), - SpanLinkMarshaler.create(LinkData.create(PARENT_SPAN_CONTEXT)))) + marshalerSource.create(LinkData.create(PARENT_SPAN_CONTEXT)))) .isEqualTo( Span.Link.newBuilder() .setTraceId(ByteString.copyFrom(TRACE_ID_BYTES)) @@ -384,12 +397,13 @@ void toProtoSpanLink_WithRemoteContext() { .build()); } - @Test - void toProtoSpanLink_WithAttributes() { + @ParameterizedTest + @EnumSource(MarshalerSource.class) + void toProtoSpanLink_WithAttributes(MarshalerSource marshalerSource) { assertThat( parse( Span.Link.getDefaultInstance(), - SpanLinkMarshaler.create( + marshalerSource.create( LinkData.create( SPAN_CONTEXT, Attributes.of(stringKey("key_string"), "string"), 5)))) .isEqualTo( @@ -494,7 +508,6 @@ private static byte[] toByteArray(Marshaler marshaler) { } private static String toJson(Marshaler marshaler) { - ByteArrayOutputStream bos = new ByteArrayOutputStream(); try { marshaler.writeJsonTo(bos); @@ -503,4 +516,75 @@ private static String toJson(Marshaler marshaler) { } return new String(bos.toByteArray(), StandardCharsets.UTF_8); } + + private static Marshaler createMarshaler(StatelessMarshaler marshaler, T data) { + return new Marshaler() { + private final MarshalerContext context = new MarshalerContext(); + private final int size = marshaler.getBinarySerializedSize(data, context); + + @Override + public int getBinarySerializedSize() { + return size; + } + + @Override + protected void writeTo(Serializer output) throws IOException { + context.resetReadIndex(); + marshaler.writeTo(output, data, context); + } + }; + } + + private enum MarshalerSource { + MARSHALER { + @Override + Marshaler create(SpanData spanData) { + return SpanMarshaler.create(spanData); + } + + @Override + Marshaler create(StatusData statusData) { + return SpanStatusMarshaler.create(statusData); + } + + @Override + Marshaler create(EventData eventData) { + return SpanEventMarshaler.create(eventData); + } + + @Override + Marshaler create(LinkData linkData) { + return SpanLinkMarshaler.create(linkData); + } + }, + LOW_ALLOCATION_MARSHALER { + @Override + Marshaler create(SpanData spanData) { + return createMarshaler(SpanStatelessMarshaler.INSTANCE, spanData); + } + + @Override + Marshaler create(StatusData statusData) { + return createMarshaler(SpanStatusStatelessMarshaler.INSTANCE, statusData); + } + + @Override + Marshaler create(EventData eventData) { + return createMarshaler(SpanEventStatelessMarshaler.INSTANCE, eventData); + } + + @Override + Marshaler create(LinkData linkData) { + return createMarshaler(SpanLinkStatelessMarshaler.INSTANCE, linkData); + } + }; + + abstract Marshaler create(SpanData spanData); + + abstract Marshaler create(StatusData statusData); + + abstract Marshaler create(EventData eventData); + + abstract Marshaler create(LinkData linkData); + } } From bd920870685497c1ece80e5e2ed12edde0a830e9 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 1 May 2024 08:37:58 -0700 Subject: [PATCH 377/901] Update errorProneVersion to v2.27.0 (#6412) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Co-authored-by: John K Watson --- dependencyManagement/build.gradle.kts | 2 +- .../sdk/autoconfigure/AutoConfiguredOpenTelemetrySdkTest.java | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index 02fdaa123b5..bfb6e33cac8 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -25,7 +25,7 @@ val DEPENDENCY_BOMS = listOf( ) val autoValueVersion = "1.10.4" -val errorProneVersion = "2.26.1" +val errorProneVersion = "2.27.0" val jmhVersion = "1.37" // Mockito 5.x.x requires Java 11 https://github.com/mockito/mockito/releases/tag/v5.0.0 val mockitoVersion = "4.11.0" diff --git a/sdk-extensions/autoconfigure/src/test/java/io/opentelemetry/sdk/autoconfigure/AutoConfiguredOpenTelemetrySdkTest.java b/sdk-extensions/autoconfigure/src/test/java/io/opentelemetry/sdk/autoconfigure/AutoConfiguredOpenTelemetrySdkTest.java index 37cafb9bdfa..f74b248c04d 100644 --- a/sdk-extensions/autoconfigure/src/test/java/io/opentelemetry/sdk/autoconfigure/AutoConfiguredOpenTelemetrySdkTest.java +++ b/sdk-extensions/autoconfigure/src/test/java/io/opentelemetry/sdk/autoconfigure/AutoConfiguredOpenTelemetrySdkTest.java @@ -282,8 +282,8 @@ void builder_addSpanExporterCustomizer() { void builder_addSpanProcessorCustomizer() { SpanProcessor mockProcessor1 = Mockito.mock(SpanProcessor.class); SpanProcessor mockProcessor2 = Mockito.mock(SpanProcessor.class); - doReturn(true).when(mockProcessor2).isStartRequired(); - doReturn(true).when(mockProcessor2).isEndRequired(); + when(mockProcessor2.isStartRequired()).thenReturn(true); + when(mockProcessor2.isEndRequired()).thenReturn(true); Mockito.lenient().doReturn(CompletableResultCode.ofSuccess()).when(mockProcessor2).shutdown(); Mockito.lenient().when(spanExporter1.shutdown()).thenReturn(CompletableResultCode.ofSuccess()); From 9b67fe09dc1e2eea922330accdbb26c4b9bc8a13 Mon Sep 17 00:00:00 2001 From: jack-berg <34418638+jack-berg@users.noreply.github.com> Date: Wed, 1 May 2024 11:24:17 -0500 Subject: [PATCH 378/901] Use low precision Clock#now when computing timestamp for exemplars (#6417) --- .../opentelemetry-sdk-common.txt | 4 +- .../sdk/common/SystemClockTest.java | 29 +++++++++++- .../io/opentelemetry/sdk/common/Clock.java | 18 ++++++++ .../opentelemetry/sdk/common/SystemClock.java | 11 ++++- .../sdk/metrics/ExemplarClockBenchmarks.java | 44 +++++++++++++++++++ .../internal/exemplar/ReservoirCell.java | 4 +- 6 files changed, 104 insertions(+), 6 deletions(-) create mode 100644 sdk/metrics/src/jmh/java/io/opentelemetry/sdk/metrics/ExemplarClockBenchmarks.java diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-common.txt b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-common.txt index df26146497b..71f05afd4d1 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-common.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-common.txt @@ -1,2 +1,4 @@ Comparing source compatibility of against -No changes. \ No newline at end of file +*** MODIFIED INTERFACE: PUBLIC ABSTRACT io.opentelemetry.sdk.common.Clock (not serializable) + === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 + +++ NEW METHOD: PUBLIC(+) long now(boolean) diff --git a/sdk/all/src/test/java/io/opentelemetry/sdk/common/SystemClockTest.java b/sdk/all/src/test/java/io/opentelemetry/sdk/common/SystemClockTest.java index 5472a6a99e1..6078d3234f4 100644 --- a/sdk/all/src/test/java/io/opentelemetry/sdk/common/SystemClockTest.java +++ b/sdk/all/src/test/java/io/opentelemetry/sdk/common/SystemClockTest.java @@ -18,7 +18,7 @@ class SystemClockTest { @EnabledOnJre(JRE.JAVA_8) @Test - void millisPrecision() { + void now_millisPrecision() { // If we test many times, we can be fairly sure we didn't just get lucky with having a rounded // result on a higher than expected precision timestamp. for (int i = 0; i < 100; i++) { @@ -29,7 +29,7 @@ void millisPrecision() { @DisabledOnJre(JRE.JAVA_8) @Test - void microsPrecision() { + void now_microsPrecision() { // If we test many times, we can be fairly sure we get at least one timestamp that isn't // coincidentally rounded to millis precision. int numHasMicros = 0; @@ -41,4 +41,29 @@ void microsPrecision() { } assertThat(numHasMicros).isNotZero(); } + + @Test + void now_lowPrecision() { + // If we test many times, we can be fairly sure we didn't just get lucky with having a rounded + // result on a higher than expected precision timestamp. + for (int i = 0; i < 100; i++) { + long now = SystemClock.getInstance().now(false); + assertThat(now % 1000000).isZero(); + } + } + + @DisabledOnJre(JRE.JAVA_8) + @Test + void now_highPrecision() { + // If we test many times, we can be fairly sure we get at least one timestamp that isn't + // coincidentally rounded to millis precision. + int numHasMicros = 0; + for (int i = 0; i < 100; i++) { + long now = SystemClock.getInstance().now(true); + if (now % 1000000 != 0) { + numHasMicros++; + } + } + assertThat(numHasMicros).isNotZero(); + } } diff --git a/sdk/common/src/main/java/io/opentelemetry/sdk/common/Clock.java b/sdk/common/src/main/java/io/opentelemetry/sdk/common/Clock.java index 9c61dce3271..44a5e02eee6 100644 --- a/sdk/common/src/main/java/io/opentelemetry/sdk/common/Clock.java +++ b/sdk/common/src/main/java/io/opentelemetry/sdk/common/Clock.java @@ -34,9 +34,27 @@ static Clock getDefault() { * // Spend time... * long durationNanos = clock.now() - startNanos; * } + * + *

      Calling this is equivalent to calling {@link #now(boolean)} with {@code highPrecision=true}. */ long now(); + /** + * Returns the current epoch timestamp in nanos from this clock. + * + *

      This overload of {@link #now()} includes a {@code highPrecision} argument which specifies + * whether the implementation should attempt to resolve higher precision at the potential expense + * of performance. For example, in java 9+ its sometimes possible to resolve ns precision higher + * than the ms precision of {@link System#currentTimeMillis()}, but doing so incurs a performance + * penalty which some callers may wish to avoid. In contrast, we don't currently know if resolving + * ns precision is possible in java 8, regardless of the value of {@code highPrecision}. + * + *

      See {@link #now()} javadoc for details on usage. + */ + default long now(boolean highPrecision) { + return now(); + } + /** * Returns a time measurement with nanosecond precision that can only be used to calculate elapsed * time. diff --git a/sdk/common/src/main/java/io/opentelemetry/sdk/common/SystemClock.java b/sdk/common/src/main/java/io/opentelemetry/sdk/common/SystemClock.java index 23265b3b5b4..3131f6834e0 100644 --- a/sdk/common/src/main/java/io/opentelemetry/sdk/common/SystemClock.java +++ b/sdk/common/src/main/java/io/opentelemetry/sdk/common/SystemClock.java @@ -6,6 +6,7 @@ package io.opentelemetry.sdk.common; import io.opentelemetry.sdk.internal.JavaVersionSpecific; +import java.util.concurrent.TimeUnit; import javax.annotation.concurrent.ThreadSafe; /** @@ -26,7 +27,15 @@ static Clock getInstance() { @Override public long now() { - return JavaVersionSpecific.get().currentTimeNanos(); + return now(true); + } + + @Override + public long now(boolean highPrecision) { + if (highPrecision) { + return JavaVersionSpecific.get().currentTimeNanos(); + } + return TimeUnit.MILLISECONDS.toNanos(System.currentTimeMillis()); } @Override diff --git a/sdk/metrics/src/jmh/java/io/opentelemetry/sdk/metrics/ExemplarClockBenchmarks.java b/sdk/metrics/src/jmh/java/io/opentelemetry/sdk/metrics/ExemplarClockBenchmarks.java new file mode 100644 index 00000000000..28d0c855134 --- /dev/null +++ b/sdk/metrics/src/jmh/java/io/opentelemetry/sdk/metrics/ExemplarClockBenchmarks.java @@ -0,0 +1,44 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.sdk.metrics; + +import io.opentelemetry.sdk.common.Clock; +import java.util.concurrent.TimeUnit; +import org.openjdk.jmh.annotations.Benchmark; +import org.openjdk.jmh.annotations.BenchmarkMode; +import org.openjdk.jmh.annotations.Fork; +import org.openjdk.jmh.annotations.Measurement; +import org.openjdk.jmh.annotations.Mode; +import org.openjdk.jmh.annotations.OutputTimeUnit; +import org.openjdk.jmh.annotations.Warmup; + +/** + * {@code io.opentelemetry.sdk.metrics.internal.exemplar.ReservoirCell} relies on {@link Clock} to + * obtain the measurement time when storing exemplar values. This benchmark illustrates the + * performance impact of using the higher precision {@link Clock#now()} instead of {@link + * Clock#now(boolean)} with {@code highPrecision=false}. + */ +@BenchmarkMode({Mode.AverageTime}) +@OutputTimeUnit(TimeUnit.NANOSECONDS) +@Warmup(iterations = 5, time = 1) +@Measurement(iterations = 10, time = 1) +@Fork(1) +public class ExemplarClockBenchmarks { + + private static final Clock clock = Clock.getDefault(); + + @SuppressWarnings("ReturnValueIgnored") + @Benchmark + public void now_lowPrecision() { + clock.now(false); + } + + @SuppressWarnings("ReturnValueIgnored") + @Benchmark + public void now_highPrecision() { + clock.now(true); + } +} diff --git a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/exemplar/ReservoirCell.java b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/exemplar/ReservoirCell.java index 1adf684531a..4fd63edcd80 100644 --- a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/exemplar/ReservoirCell.java +++ b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/exemplar/ReservoirCell.java @@ -68,8 +68,8 @@ synchronized void recordDoubleMeasurement(double value, Attributes attributes, C private void offerMeasurement(Attributes attributes, Context context) { this.attributes = attributes; - // Note: It may make sense in the future to attempt to pull this from an active span. - this.recordTime = clock.now(); + // High precision time is not worth the additional performance expense it incurs for exemplars + this.recordTime = clock.now(/* highPrecision= */ false); Span current = Span.fromContext(context); if (current.getSpanContext().isValid()) { this.spanContext = current.getSpanContext(); From b5699ade3b62466c3eef079dc37b9468df093dce Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 1 May 2024 18:11:28 -0700 Subject: [PATCH 379/901] Update errorProneVersion to v2.27.1 (#6420) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- dependencyManagement/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index bfb6e33cac8..77bac2b7ffc 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -25,7 +25,7 @@ val DEPENDENCY_BOMS = listOf( ) val autoValueVersion = "1.10.4" -val errorProneVersion = "2.27.0" +val errorProneVersion = "2.27.1" val jmhVersion = "1.37" // Mockito 5.x.x requires Java 11 https://github.com/mockito/mockito/releases/tag/v5.0.0 val mockitoVersion = "4.11.0" From 68efd95b58f1f5aaa974ecf9e866cd4d9e16d68f Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 2 May 2024 11:42:00 -0700 Subject: [PATCH 380/901] Update dependency com.google.guava:guava to v33.2.0-jre (#6424) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- buildSrc/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts index 6815e635564..eae3657671a 100644 --- a/buildSrc/build.gradle.kts +++ b/buildSrc/build.gradle.kts @@ -55,7 +55,7 @@ dependencies { // When updating, update above in plugins too implementation("com.diffplug.spotless:spotless-plugin-gradle:6.25.0") // Needed for japicmp but not automatically brought in for some reason. - implementation("com.google.guava:guava:33.1.0-jre") + implementation("com.google.guava:guava:33.2.0-jre") implementation("com.squareup:javapoet:1.13.0") implementation("com.squareup.wire:wire-compiler") implementation("com.squareup.wire:wire-gradle-plugin") From 414cc7be5d21643e18d403f6ca972932a8112a26 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 2 May 2024 11:42:26 -0700 Subject: [PATCH 381/901] Update dependency com.google.guava:guava-bom to v33.2.0-jre (#6425) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- dependencyManagement/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index 77bac2b7ffc..c9f38c912fe 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -9,7 +9,7 @@ rootProject.extra["versions"] = dependencyVersions val DEPENDENCY_BOMS = listOf( "com.fasterxml.jackson:jackson-bom:2.17.0", - "com.google.guava:guava-bom:33.1.0-jre", + "com.google.guava:guava-bom:33.2.0-jre", "com.google.protobuf:protobuf-bom:3.25.3", "com.linecorp.armeria:armeria-bom:1.28.4", "com.squareup.okhttp3:okhttp-bom:4.12.0", From 83224d70790b478f084206dbac6817ca8df3b752 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 3 May 2024 07:49:17 -0700 Subject: [PATCH 382/901] Update dependency com.google.api.grpc:proto-google-common-protos to v2.39.0 (#6426) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- dependencyManagement/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index c9f38c912fe..54d27b77be1 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -55,7 +55,7 @@ val DEPENDENCIES = listOf( "io.prometheus:simpleclient_httpserver:${prometheusClientVersion}", "javax.annotation:javax.annotation-api:1.3.2", "com.github.stefanbirkner:system-rules:1.19.0", - "com.google.api.grpc:proto-google-common-protos:2.38.0", + "com.google.api.grpc:proto-google-common-protos:2.39.0", "com.google.code.findbugs:jsr305:3.0.2", "com.google.guava:guava-beta-checker:1.0", "com.sun.net.httpserver:http:20070405", From f8e6358b024e0856d17617020e8a6ce5e44bbc70 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 3 May 2024 09:47:58 -0700 Subject: [PATCH 383/901] Update dependency com.uber.nullaway:nullaway to v0.10.26 (#6428) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- dependencyManagement/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index 54d27b77be1..af88ba93dfd 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -60,7 +60,7 @@ val DEPENDENCIES = listOf( "com.google.guava:guava-beta-checker:1.0", "com.sun.net.httpserver:http:20070405", "com.tngtech.archunit:archunit-junit5:1.3.0", - "com.uber.nullaway:nullaway:0.10.25", + "com.uber.nullaway:nullaway:0.10.26", "edu.berkeley.cs.jqf:jqf-fuzz:1.7", // jqf-fuzz version 1.8+ requires Java 11+ "eu.rekawek.toxiproxy:toxiproxy-java:2.1.7", "io.github.netmikey.logunit:logunit-jul:2.0.0", From 2db5bb88d381ec9a36c4869986a17edf2858398b Mon Sep 17 00:00:00 2001 From: Lauri Tulmin Date: Fri, 3 May 2024 23:47:47 +0300 Subject: [PATCH 384/901] Marshal span status description without allocation (#6423) --- .../otlp/traces/SpanStatusStatelessMarshaler.java | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/traces/SpanStatusStatelessMarshaler.java b/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/traces/SpanStatusStatelessMarshaler.java index 9b6907ccdef..ba37729d636 100644 --- a/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/traces/SpanStatusStatelessMarshaler.java +++ b/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/traces/SpanStatusStatelessMarshaler.java @@ -12,6 +12,7 @@ import io.opentelemetry.exporter.internal.marshal.ProtoEnumInfo; import io.opentelemetry.exporter.internal.marshal.Serializer; import io.opentelemetry.exporter.internal.marshal.StatelessMarshaler; +import io.opentelemetry.exporter.internal.marshal.StatelessMarshalerUtil; import io.opentelemetry.proto.trace.v1.internal.Status; import io.opentelemetry.sdk.trace.data.StatusData; import java.io.IOException; @@ -24,20 +25,19 @@ final class SpanStatusStatelessMarshaler implements StatelessMarshaler Date: Sun, 5 May 2024 09:37:32 -0700 Subject: [PATCH 385/901] Update dependency com.fasterxml.jackson:jackson-bom to v2.17.1 (#6432) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- dependencyManagement/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index af88ba93dfd..146a71a2787 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -8,7 +8,7 @@ val dependencyVersions = hashMapOf() rootProject.extra["versions"] = dependencyVersions val DEPENDENCY_BOMS = listOf( - "com.fasterxml.jackson:jackson-bom:2.17.0", + "com.fasterxml.jackson:jackson-bom:2.17.1", "com.google.guava:guava-bom:33.2.0-jre", "com.google.protobuf:protobuf-bom:3.25.3", "com.linecorp.armeria:armeria-bom:1.28.4", From 996c9c321a5b1d2df5107a8a4c3f14c4073ee890 Mon Sep 17 00:00:00 2001 From: Lauri Tulmin Date: Tue, 7 May 2024 17:56:01 +0300 Subject: [PATCH 386/901] Low allocation OTLP metrics marshaler (#6422) --- .../MetricsRequestMarshalerBenchmark.java | 44 +- .../otlp/metrics/ExemplarMarshaler.java | 22 +- .../metrics/ExemplarStatelessMarshaler.java | 93 ++++ .../ExponentialHistogramBucketsMarshaler.java | 2 +- ...ialHistogramBucketsStatelessMarshaler.java | 47 ++ ...lHistogramDataPointStatelessMarshaler.java | 113 +++++ ...xponentialHistogramStatelessMarshaler.java | 58 +++ .../otlp/metrics/GaugeStatelessMarshaler.java | 47 ++ .../HistogramDataPointStatelessMarshaler.java | 84 ++++ .../metrics/HistogramStatelessMarshaler.java | 55 +++ ...ntationScopeMetricsStatelessMarshaler.java | 66 +++ .../LowAllocationMetricsRequestMarshaler.java | 107 +++++ .../metrics/MetricStatelessMarshaler.java | 212 +++++++++ .../metrics/NumberDataPointMarshaler.java | 19 +- .../NumberDataPointStatelessMarshaler.java | 78 ++++ .../ResourceMetricsStatelessMarshaler.java | 83 ++++ .../otlp/metrics/SumStatelessMarshaler.java | 56 +++ .../SummaryDataPointStatelessMarshaler.java | 67 +++ .../metrics/SummaryStatelessMarshaler.java | 44 ++ .../metrics/ValueAtQuantileMarshaler.java | 2 +- .../ValueAtQuantileStatelessMarshaler.java | 32 ++ ...AllocationMetricsRequestMarshalerTest.java | 408 ++++++++++++++++++ .../metrics/MetricsRequestMarshalerTest.java | 233 +++++++--- .../traces/TraceRequestMarshalerTest.java | 4 +- 24 files changed, 1897 insertions(+), 79 deletions(-) create mode 100644 exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/metrics/ExemplarStatelessMarshaler.java create mode 100644 exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/metrics/ExponentialHistogramBucketsStatelessMarshaler.java create mode 100644 exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/metrics/ExponentialHistogramDataPointStatelessMarshaler.java create mode 100644 exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/metrics/ExponentialHistogramStatelessMarshaler.java create mode 100644 exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/metrics/GaugeStatelessMarshaler.java create mode 100644 exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/metrics/HistogramDataPointStatelessMarshaler.java create mode 100644 exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/metrics/HistogramStatelessMarshaler.java create mode 100644 exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/metrics/InstrumentationScopeMetricsStatelessMarshaler.java create mode 100644 exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/metrics/LowAllocationMetricsRequestMarshaler.java create mode 100644 exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/metrics/MetricStatelessMarshaler.java create mode 100644 exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/metrics/NumberDataPointStatelessMarshaler.java create mode 100644 exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/metrics/ResourceMetricsStatelessMarshaler.java create mode 100644 exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/metrics/SumStatelessMarshaler.java create mode 100644 exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/metrics/SummaryDataPointStatelessMarshaler.java create mode 100644 exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/metrics/SummaryStatelessMarshaler.java create mode 100644 exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/metrics/ValueAtQuantileStatelessMarshaler.java create mode 100644 exporters/otlp/common/src/test/java/io/opentelemetry/exporter/internal/otlp/metrics/LowAllocationMetricsRequestMarshalerTest.java diff --git a/exporters/otlp/common/src/jmh/java/io/opentelemetry/exporter/internal/otlp/MetricsRequestMarshalerBenchmark.java b/exporters/otlp/common/src/jmh/java/io/opentelemetry/exporter/internal/otlp/MetricsRequestMarshalerBenchmark.java index e284357e401..95d652c3533 100644 --- a/exporters/otlp/common/src/jmh/java/io/opentelemetry/exporter/internal/otlp/MetricsRequestMarshalerBenchmark.java +++ b/exporters/otlp/common/src/jmh/java/io/opentelemetry/exporter/internal/otlp/MetricsRequestMarshalerBenchmark.java @@ -13,6 +13,7 @@ import io.opentelemetry.api.metrics.LongCounter; import io.opentelemetry.api.metrics.LongUpDownCounter; import io.opentelemetry.api.metrics.Meter; +import io.opentelemetry.exporter.internal.otlp.metrics.LowAllocationMetricsRequestMarshaler; import io.opentelemetry.exporter.internal.otlp.metrics.MetricsRequestMarshaler; import io.opentelemetry.sdk.metrics.SdkMeterProvider; import io.opentelemetry.sdk.metrics.data.MetricData; @@ -38,6 +39,9 @@ public class MetricsRequestMarshalerBenchmark { private static final Collection METRICS; + private static final LowAllocationMetricsRequestMarshaler MARSHALER = + new LowAllocationMetricsRequestMarshaler(); + private static final TestOutputStream OUTPUT = new TestOutputStream(); static { InMemoryMetricReader metricReader = InMemoryMetricReader.create(); @@ -116,10 +120,42 @@ public class MetricsRequestMarshalerBenchmark { } @Benchmark - public TestOutputStream marshaler() throws IOException { + public int marshalStateful() throws IOException { MetricsRequestMarshaler marshaler = MetricsRequestMarshaler.create(METRICS); - TestOutputStream bos = new TestOutputStream(); - marshaler.writeBinaryTo(bos); - return bos; + OUTPUT.reset(); + marshaler.writeBinaryTo(OUTPUT); + return OUTPUT.getCount(); + } + + @Benchmark + public int marshalStatefulJson() throws IOException { + MetricsRequestMarshaler marshaler = MetricsRequestMarshaler.create(METRICS); + OUTPUT.reset(); + marshaler.writeJsonTo(OUTPUT); + return OUTPUT.getCount(); + } + + @Benchmark + public int marshalStateless() throws IOException { + MARSHALER.initialize(METRICS); + try { + OUTPUT.reset(); + MARSHALER.writeBinaryTo(OUTPUT); + return OUTPUT.getCount(); + } finally { + MARSHALER.reset(); + } + } + + @Benchmark + public int marshalStatelessJson() throws IOException { + MARSHALER.initialize(METRICS); + try { + OUTPUT.reset(); + MARSHALER.writeJsonTo(OUTPUT); + return OUTPUT.getCount(); + } finally { + MARSHALER.reset(); + } } } diff --git a/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/metrics/ExemplarMarshaler.java b/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/metrics/ExemplarMarshaler.java index 8d16c9e40d7..1e0ec8d25cb 100644 --- a/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/metrics/ExemplarMarshaler.java +++ b/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/metrics/ExemplarMarshaler.java @@ -37,22 +37,15 @@ static ExemplarMarshaler[] createRepeated(List exemplars return marshalers; } - private static ExemplarMarshaler create(ExemplarData exemplar) { + // Visible for testing + static ExemplarMarshaler create(ExemplarData exemplar) { KeyValueMarshaler[] attributeMarshalers = KeyValueMarshaler.createForAttributes(exemplar.getFilteredAttributes()); - ProtoFieldInfo valueField; - if (exemplar instanceof LongExemplarData) { - valueField = io.opentelemetry.proto.metrics.v1.internal.Exemplar.AS_INT; - } else { - assert exemplar instanceof DoubleExemplarData; - valueField = io.opentelemetry.proto.metrics.v1.internal.Exemplar.AS_DOUBLE; - } - return new ExemplarMarshaler( exemplar.getEpochNanos(), exemplar, - valueField, + toProtoExemplarValueType(exemplar), exemplar.getSpanContext(), attributeMarshalers); } @@ -121,4 +114,13 @@ private static int calculateSize( filteredAttributeMarshalers); return size; } + + static ProtoFieldInfo toProtoExemplarValueType(ExemplarData exemplar) { + if (exemplar instanceof LongExemplarData) { + return io.opentelemetry.proto.metrics.v1.internal.Exemplar.AS_INT; + } else { + assert exemplar instanceof DoubleExemplarData; + return io.opentelemetry.proto.metrics.v1.internal.Exemplar.AS_DOUBLE; + } + } } diff --git a/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/metrics/ExemplarStatelessMarshaler.java b/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/metrics/ExemplarStatelessMarshaler.java new file mode 100644 index 00000000000..3982b697ee0 --- /dev/null +++ b/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/metrics/ExemplarStatelessMarshaler.java @@ -0,0 +1,93 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.exporter.internal.otlp.metrics; + +import static io.opentelemetry.exporter.internal.otlp.metrics.ExemplarMarshaler.toProtoExemplarValueType; + +import io.opentelemetry.api.trace.SpanContext; +import io.opentelemetry.exporter.internal.marshal.MarshalerContext; +import io.opentelemetry.exporter.internal.marshal.MarshalerUtil; +import io.opentelemetry.exporter.internal.marshal.ProtoFieldInfo; +import io.opentelemetry.exporter.internal.marshal.Serializer; +import io.opentelemetry.exporter.internal.marshal.StatelessMarshaler; +import io.opentelemetry.exporter.internal.marshal.StatelessMarshalerUtil; +import io.opentelemetry.exporter.internal.otlp.KeyValueStatelessMarshaler; +import io.opentelemetry.sdk.metrics.data.DoubleExemplarData; +import io.opentelemetry.sdk.metrics.data.ExemplarData; +import io.opentelemetry.sdk.metrics.data.LongExemplarData; +import java.io.IOException; + +/** See {@link ExemplarMarshaler}. */ +final class ExemplarStatelessMarshaler implements StatelessMarshaler { + static final ExemplarStatelessMarshaler INSTANCE = new ExemplarStatelessMarshaler(); + + private ExemplarStatelessMarshaler() {} + + @Override + public void writeTo(Serializer output, ExemplarData exemplar, MarshalerContext context) + throws IOException { + output.serializeFixed64( + io.opentelemetry.proto.metrics.v1.internal.Exemplar.TIME_UNIX_NANO, + exemplar.getEpochNanos()); + ProtoFieldInfo valueField = toProtoExemplarValueType(exemplar); + if (valueField == io.opentelemetry.proto.metrics.v1.internal.Exemplar.AS_INT) { + output.serializeFixed64Optional(valueField, ((LongExemplarData) exemplar).getValue()); + } else { + output.serializeDoubleOptional(valueField, ((DoubleExemplarData) exemplar).getValue()); + } + SpanContext spanContext = exemplar.getSpanContext(); + if (spanContext.isValid()) { + output.serializeSpanId( + io.opentelemetry.proto.metrics.v1.internal.Exemplar.SPAN_ID, + spanContext.getSpanId(), + context); + output.serializeTraceId( + io.opentelemetry.proto.metrics.v1.internal.Exemplar.TRACE_ID, + spanContext.getTraceId(), + context); + } + output.serializeRepeatedMessageWithContext( + io.opentelemetry.proto.metrics.v1.internal.Exemplar.FILTERED_ATTRIBUTES, + exemplar.getFilteredAttributes(), + KeyValueStatelessMarshaler.INSTANCE, + context); + } + + @Override + public int getBinarySerializedSize(ExemplarData exemplar, MarshalerContext context) { + int size = 0; + size += + MarshalerUtil.sizeFixed64( + io.opentelemetry.proto.metrics.v1.internal.Exemplar.TIME_UNIX_NANO, + exemplar.getEpochNanos()); + ProtoFieldInfo valueField = toProtoExemplarValueType(exemplar); + if (valueField == io.opentelemetry.proto.metrics.v1.internal.Exemplar.AS_INT) { + size += + MarshalerUtil.sizeFixed64Optional(valueField, ((LongExemplarData) exemplar).getValue()); + } else { + size += + MarshalerUtil.sizeDoubleOptional(valueField, ((DoubleExemplarData) exemplar).getValue()); + } + SpanContext spanContext = exemplar.getSpanContext(); + if (spanContext.isValid()) { + size += + MarshalerUtil.sizeSpanId( + io.opentelemetry.proto.metrics.v1.internal.Exemplar.SPAN_ID, spanContext.getSpanId()); + size += + MarshalerUtil.sizeTraceId( + io.opentelemetry.proto.metrics.v1.internal.Exemplar.TRACE_ID, + spanContext.getTraceId()); + } + size += + StatelessMarshalerUtil.sizeRepeatedMessageWithContext( + io.opentelemetry.proto.metrics.v1.internal.Exemplar.FILTERED_ATTRIBUTES, + exemplar.getFilteredAttributes(), + KeyValueStatelessMarshaler.INSTANCE, + context); + + return size; + } +} diff --git a/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/metrics/ExponentialHistogramBucketsMarshaler.java b/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/metrics/ExponentialHistogramBucketsMarshaler.java index 1f5affce3c0..01cbee4c1b7 100644 --- a/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/metrics/ExponentialHistogramBucketsMarshaler.java +++ b/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/metrics/ExponentialHistogramBucketsMarshaler.java @@ -45,7 +45,7 @@ protected void writeTo(Serializer output) throws IOException { } } - private static int calculateSize(int offset, List counts) { + static int calculateSize(int offset, List counts) { int size = 0; size += MarshalerUtil.sizeSInt32(ExponentialHistogramDataPoint.Buckets.OFFSET, offset); if (counts instanceof DynamicPrimitiveLongList) { diff --git a/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/metrics/ExponentialHistogramBucketsStatelessMarshaler.java b/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/metrics/ExponentialHistogramBucketsStatelessMarshaler.java new file mode 100644 index 00000000000..01626906b42 --- /dev/null +++ b/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/metrics/ExponentialHistogramBucketsStatelessMarshaler.java @@ -0,0 +1,47 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.exporter.internal.otlp.metrics; + +import io.opentelemetry.exporter.internal.marshal.MarshalerContext; +import io.opentelemetry.exporter.internal.marshal.Serializer; +import io.opentelemetry.exporter.internal.marshal.StatelessMarshaler; +import io.opentelemetry.proto.metrics.v1.internal.ExponentialHistogramDataPoint; +import io.opentelemetry.sdk.internal.DynamicPrimitiveLongList; +import io.opentelemetry.sdk.internal.PrimitiveLongList; +import io.opentelemetry.sdk.metrics.data.ExponentialHistogramBuckets; +import java.io.IOException; +import java.util.List; + +/** See {@link ExponentialHistogramBucketsMarshaler}. */ +final class ExponentialHistogramBucketsStatelessMarshaler + implements StatelessMarshaler { + static final ExponentialHistogramBucketsStatelessMarshaler INSTANCE = + new ExponentialHistogramBucketsStatelessMarshaler(); + + private ExponentialHistogramBucketsStatelessMarshaler() {} + + @Override + public void writeTo( + Serializer output, ExponentialHistogramBuckets buckets, MarshalerContext context) + throws IOException { + output.serializeSInt32(ExponentialHistogramDataPoint.Buckets.OFFSET, buckets.getOffset()); + List counts = buckets.getBucketCounts(); + if (counts instanceof DynamicPrimitiveLongList) { + output.serializeRepeatedUInt64( + ExponentialHistogramDataPoint.Buckets.BUCKET_COUNTS, (DynamicPrimitiveLongList) counts); + } else { + output.serializeRepeatedUInt64( + ExponentialHistogramDataPoint.Buckets.BUCKET_COUNTS, PrimitiveLongList.toArray(counts)); + } + } + + @Override + public int getBinarySerializedSize( + ExponentialHistogramBuckets buckets, MarshalerContext context) { + return ExponentialHistogramBucketsMarshaler.calculateSize( + buckets.getOffset(), buckets.getBucketCounts()); + } +} diff --git a/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/metrics/ExponentialHistogramDataPointStatelessMarshaler.java b/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/metrics/ExponentialHistogramDataPointStatelessMarshaler.java new file mode 100644 index 00000000000..23117aab5d5 --- /dev/null +++ b/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/metrics/ExponentialHistogramDataPointStatelessMarshaler.java @@ -0,0 +1,113 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.exporter.internal.otlp.metrics; + +import io.opentelemetry.exporter.internal.marshal.MarshalerContext; +import io.opentelemetry.exporter.internal.marshal.MarshalerUtil; +import io.opentelemetry.exporter.internal.marshal.Serializer; +import io.opentelemetry.exporter.internal.marshal.StatelessMarshaler; +import io.opentelemetry.exporter.internal.marshal.StatelessMarshalerUtil; +import io.opentelemetry.exporter.internal.otlp.KeyValueStatelessMarshaler; +import io.opentelemetry.proto.metrics.v1.internal.ExponentialHistogramDataPoint; +import io.opentelemetry.sdk.metrics.data.ExponentialHistogramPointData; +import java.io.IOException; + +/** See {@link ExponentialHistogramDataPointMarshaler}. */ +final class ExponentialHistogramDataPointStatelessMarshaler + implements StatelessMarshaler { + static final ExponentialHistogramDataPointStatelessMarshaler INSTANCE = + new ExponentialHistogramDataPointStatelessMarshaler(); + + private ExponentialHistogramDataPointStatelessMarshaler() {} + + @Override + public void writeTo( + Serializer output, ExponentialHistogramPointData point, MarshalerContext context) + throws IOException { + output.serializeFixed64( + ExponentialHistogramDataPoint.START_TIME_UNIX_NANO, point.getStartEpochNanos()); + output.serializeFixed64(ExponentialHistogramDataPoint.TIME_UNIX_NANO, point.getEpochNanos()); + output.serializeFixed64(ExponentialHistogramDataPoint.COUNT, point.getCount()); + output.serializeDouble(ExponentialHistogramDataPoint.SUM, point.getSum()); + if (point.hasMin()) { + output.serializeDoubleOptional(ExponentialHistogramDataPoint.MIN, point.getMin()); + } + if (point.hasMax()) { + output.serializeDoubleOptional(ExponentialHistogramDataPoint.MAX, point.getMax()); + } + output.serializeSInt32(ExponentialHistogramDataPoint.SCALE, point.getScale()); + output.serializeFixed64(ExponentialHistogramDataPoint.ZERO_COUNT, point.getZeroCount()); + output.serializeMessageWithContext( + ExponentialHistogramDataPoint.POSITIVE, + point.getPositiveBuckets(), + ExponentialHistogramBucketsStatelessMarshaler.INSTANCE, + context); + output.serializeMessageWithContext( + ExponentialHistogramDataPoint.NEGATIVE, + point.getNegativeBuckets(), + ExponentialHistogramBucketsStatelessMarshaler.INSTANCE, + context); + output.serializeRepeatedMessageWithContext( + ExponentialHistogramDataPoint.EXEMPLARS, + point.getExemplars(), + ExemplarStatelessMarshaler.INSTANCE, + context); + output.serializeRepeatedMessageWithContext( + ExponentialHistogramDataPoint.ATTRIBUTES, + point.getAttributes(), + KeyValueStatelessMarshaler.INSTANCE, + context); + } + + @Override + public int getBinarySerializedSize( + ExponentialHistogramPointData point, MarshalerContext context) { + int size = 0; + size += + MarshalerUtil.sizeFixed64( + ExponentialHistogramDataPoint.START_TIME_UNIX_NANO, point.getStartEpochNanos()); + size += + MarshalerUtil.sizeFixed64( + ExponentialHistogramDataPoint.TIME_UNIX_NANO, point.getEpochNanos()); + size += MarshalerUtil.sizeFixed64(ExponentialHistogramDataPoint.COUNT, point.getCount()); + size += MarshalerUtil.sizeDouble(ExponentialHistogramDataPoint.SUM, point.getSum()); + if (point.hasMin()) { + size += MarshalerUtil.sizeDoubleOptional(ExponentialHistogramDataPoint.MIN, point.getMin()); + } + if (point.hasMax()) { + size += MarshalerUtil.sizeDoubleOptional(ExponentialHistogramDataPoint.MAX, point.getMax()); + } + size += MarshalerUtil.sizeSInt32(ExponentialHistogramDataPoint.SCALE, point.getScale()); + size += + MarshalerUtil.sizeFixed64(ExponentialHistogramDataPoint.ZERO_COUNT, point.getZeroCount()); + size += + StatelessMarshalerUtil.sizeMessageWithContext( + ExponentialHistogramDataPoint.POSITIVE, + point.getPositiveBuckets(), + ExponentialHistogramBucketsStatelessMarshaler.INSTANCE, + context); + size += + StatelessMarshalerUtil.sizeMessageWithContext( + ExponentialHistogramDataPoint.NEGATIVE, + point.getNegativeBuckets(), + ExponentialHistogramBucketsStatelessMarshaler.INSTANCE, + context); + size += + StatelessMarshalerUtil.sizeRepeatedMessageWithContext( + ExponentialHistogramDataPoint.EXEMPLARS, + point.getExemplars(), + ExemplarStatelessMarshaler.INSTANCE, + context); + size += + StatelessMarshalerUtil.sizeRepeatedMessageWithContext( + ExponentialHistogramDataPoint.ATTRIBUTES, + point.getAttributes(), + KeyValueStatelessMarshaler.INSTANCE, + context); + + return size; + } +} diff --git a/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/metrics/ExponentialHistogramStatelessMarshaler.java b/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/metrics/ExponentialHistogramStatelessMarshaler.java new file mode 100644 index 00000000000..240f616a113 --- /dev/null +++ b/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/metrics/ExponentialHistogramStatelessMarshaler.java @@ -0,0 +1,58 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.exporter.internal.otlp.metrics; + +import io.opentelemetry.exporter.internal.marshal.MarshalerContext; +import io.opentelemetry.exporter.internal.marshal.MarshalerUtil; +import io.opentelemetry.exporter.internal.marshal.Serializer; +import io.opentelemetry.exporter.internal.marshal.StatelessMarshaler; +import io.opentelemetry.exporter.internal.marshal.StatelessMarshalerUtil; +import io.opentelemetry.proto.metrics.v1.internal.ExponentialHistogram; +import io.opentelemetry.sdk.metrics.data.ExponentialHistogramData; +import java.io.IOException; + +/** See {@link ExponentialHistogramMarshaler}. */ +final class ExponentialHistogramStatelessMarshaler + implements StatelessMarshaler { + static final ExponentialHistogramStatelessMarshaler INSTANCE = + new ExponentialHistogramStatelessMarshaler(); + private static final MarshalerContext.Key DATA_POINT_SIZE_CALCULATOR_KEY = MarshalerContext.key(); + private static final MarshalerContext.Key DATA_POINT_WRITER_KEY = MarshalerContext.key(); + + private ExponentialHistogramStatelessMarshaler() {} + + @Override + public void writeTo( + Serializer output, ExponentialHistogramData histogram, MarshalerContext context) + throws IOException { + output.serializeRepeatedMessageWithContext( + ExponentialHistogram.DATA_POINTS, + histogram.getPoints(), + ExponentialHistogramDataPointStatelessMarshaler.INSTANCE, + context, + DATA_POINT_WRITER_KEY); + output.serializeEnum( + ExponentialHistogram.AGGREGATION_TEMPORALITY, + MetricsMarshalerUtil.mapToTemporality(histogram.getAggregationTemporality())); + } + + @Override + public int getBinarySerializedSize(ExponentialHistogramData histogram, MarshalerContext context) { + int size = 0; + size += + StatelessMarshalerUtil.sizeRepeatedMessageWithContext( + ExponentialHistogram.DATA_POINTS, + histogram.getPoints(), + ExponentialHistogramDataPointStatelessMarshaler.INSTANCE, + context, + DATA_POINT_SIZE_CALCULATOR_KEY); + size += + MarshalerUtil.sizeEnum( + ExponentialHistogram.AGGREGATION_TEMPORALITY, + MetricsMarshalerUtil.mapToTemporality(histogram.getAggregationTemporality())); + return size; + } +} diff --git a/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/metrics/GaugeStatelessMarshaler.java b/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/metrics/GaugeStatelessMarshaler.java new file mode 100644 index 00000000000..4db29e74e1c --- /dev/null +++ b/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/metrics/GaugeStatelessMarshaler.java @@ -0,0 +1,47 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.exporter.internal.otlp.metrics; + +import io.opentelemetry.exporter.internal.marshal.MarshalerContext; +import io.opentelemetry.exporter.internal.marshal.Serializer; +import io.opentelemetry.exporter.internal.marshal.StatelessMarshaler; +import io.opentelemetry.exporter.internal.marshal.StatelessMarshalerUtil; +import io.opentelemetry.proto.metrics.v1.internal.Gauge; +import io.opentelemetry.sdk.metrics.data.GaugeData; +import io.opentelemetry.sdk.metrics.data.PointData; +import java.io.IOException; + +/** See {@link GaugeMarshaler}. */ +final class GaugeStatelessMarshaler implements StatelessMarshaler> { + static final GaugeStatelessMarshaler INSTANCE = new GaugeStatelessMarshaler(); + private static final MarshalerContext.Key DATA_POINT_SIZE_CALCULATOR_KEY = MarshalerContext.key(); + private static final MarshalerContext.Key DATA_POINT_WRITER_KEY = MarshalerContext.key(); + + private GaugeStatelessMarshaler() {} + + @Override + public void writeTo( + Serializer output, GaugeData gauge, MarshalerContext context) + throws IOException { + output.serializeRepeatedMessageWithContext( + Gauge.DATA_POINTS, + gauge.getPoints(), + NumberDataPointStatelessMarshaler.INSTANCE, + context, + DATA_POINT_WRITER_KEY); + } + + @Override + public int getBinarySerializedSize( + GaugeData gauge, MarshalerContext context) { + return StatelessMarshalerUtil.sizeRepeatedMessageWithContext( + Gauge.DATA_POINTS, + gauge.getPoints(), + NumberDataPointStatelessMarshaler.INSTANCE, + context, + DATA_POINT_SIZE_CALCULATOR_KEY); + } +} diff --git a/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/metrics/HistogramDataPointStatelessMarshaler.java b/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/metrics/HistogramDataPointStatelessMarshaler.java new file mode 100644 index 00000000000..2102aa8bf35 --- /dev/null +++ b/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/metrics/HistogramDataPointStatelessMarshaler.java @@ -0,0 +1,84 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.exporter.internal.otlp.metrics; + +import io.opentelemetry.exporter.internal.marshal.MarshalerContext; +import io.opentelemetry.exporter.internal.marshal.MarshalerUtil; +import io.opentelemetry.exporter.internal.marshal.Serializer; +import io.opentelemetry.exporter.internal.marshal.StatelessMarshaler; +import io.opentelemetry.exporter.internal.marshal.StatelessMarshalerUtil; +import io.opentelemetry.exporter.internal.otlp.KeyValueStatelessMarshaler; +import io.opentelemetry.proto.metrics.v1.internal.HistogramDataPoint; +import io.opentelemetry.sdk.metrics.data.HistogramPointData; +import java.io.IOException; + +/** See {@link HistogramDataPointMarshaler}. */ +final class HistogramDataPointStatelessMarshaler implements StatelessMarshaler { + static final HistogramDataPointStatelessMarshaler INSTANCE = + new HistogramDataPointStatelessMarshaler(); + + private HistogramDataPointStatelessMarshaler() {} + + @Override + public void writeTo(Serializer output, HistogramPointData point, MarshalerContext context) + throws IOException { + output.serializeFixed64(HistogramDataPoint.START_TIME_UNIX_NANO, point.getStartEpochNanos()); + output.serializeFixed64(HistogramDataPoint.TIME_UNIX_NANO, point.getEpochNanos()); + output.serializeFixed64(HistogramDataPoint.COUNT, point.getCount()); + output.serializeDoubleOptional(HistogramDataPoint.SUM, point.getSum()); + if (point.hasMin()) { + output.serializeDoubleOptional(HistogramDataPoint.MIN, point.getMin()); + } + if (point.hasMax()) { + output.serializeDoubleOptional(HistogramDataPoint.MAX, point.getMax()); + } + output.serializeRepeatedFixed64(HistogramDataPoint.BUCKET_COUNTS, point.getCounts()); + output.serializeRepeatedDouble(HistogramDataPoint.EXPLICIT_BOUNDS, point.getBoundaries()); + output.serializeRepeatedMessageWithContext( + HistogramDataPoint.EXEMPLARS, + point.getExemplars(), + ExemplarStatelessMarshaler.INSTANCE, + context); + output.serializeRepeatedMessageWithContext( + HistogramDataPoint.ATTRIBUTES, + point.getAttributes(), + KeyValueStatelessMarshaler.INSTANCE, + context); + } + + @Override + public int getBinarySerializedSize(HistogramPointData point, MarshalerContext context) { + int size = 0; + size += + MarshalerUtil.sizeFixed64( + HistogramDataPoint.START_TIME_UNIX_NANO, point.getStartEpochNanos()); + size += MarshalerUtil.sizeFixed64(HistogramDataPoint.TIME_UNIX_NANO, point.getEpochNanos()); + size += MarshalerUtil.sizeFixed64(HistogramDataPoint.COUNT, point.getCount()); + size += MarshalerUtil.sizeDoubleOptional(HistogramDataPoint.SUM, point.getSum()); + if (point.hasMin()) { + size += MarshalerUtil.sizeDoubleOptional(HistogramDataPoint.MIN, point.getMin()); + } + if (point.hasMax()) { + size += MarshalerUtil.sizeDoubleOptional(HistogramDataPoint.MAX, point.getMax()); + } + size += MarshalerUtil.sizeRepeatedFixed64(HistogramDataPoint.BUCKET_COUNTS, point.getCounts()); + size += + MarshalerUtil.sizeRepeatedDouble(HistogramDataPoint.EXPLICIT_BOUNDS, point.getBoundaries()); + size += + StatelessMarshalerUtil.sizeRepeatedMessageWithContext( + HistogramDataPoint.EXEMPLARS, + point.getExemplars(), + ExemplarStatelessMarshaler.INSTANCE, + context); + size += + StatelessMarshalerUtil.sizeRepeatedMessageWithContext( + HistogramDataPoint.ATTRIBUTES, + point.getAttributes(), + KeyValueStatelessMarshaler.INSTANCE, + context); + return size; + } +} diff --git a/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/metrics/HistogramStatelessMarshaler.java b/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/metrics/HistogramStatelessMarshaler.java new file mode 100644 index 00000000000..2e3f65e188a --- /dev/null +++ b/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/metrics/HistogramStatelessMarshaler.java @@ -0,0 +1,55 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.exporter.internal.otlp.metrics; + +import io.opentelemetry.exporter.internal.marshal.MarshalerContext; +import io.opentelemetry.exporter.internal.marshal.MarshalerUtil; +import io.opentelemetry.exporter.internal.marshal.Serializer; +import io.opentelemetry.exporter.internal.marshal.StatelessMarshaler; +import io.opentelemetry.exporter.internal.marshal.StatelessMarshalerUtil; +import io.opentelemetry.proto.metrics.v1.internal.Histogram; +import io.opentelemetry.sdk.metrics.data.HistogramData; +import java.io.IOException; + +/** See {@link HistogramMarshaler}. */ +final class HistogramStatelessMarshaler implements StatelessMarshaler { + static final HistogramStatelessMarshaler INSTANCE = new HistogramStatelessMarshaler(); + private static final MarshalerContext.Key DATA_POINT_SIZE_CALCULATOR_KEY = MarshalerContext.key(); + private static final MarshalerContext.Key DATA_POINT_WRITER_KEY = MarshalerContext.key(); + + private HistogramStatelessMarshaler() {} + + @Override + public void writeTo(Serializer output, HistogramData histogram, MarshalerContext context) + throws IOException { + output.serializeRepeatedMessageWithContext( + Histogram.DATA_POINTS, + histogram.getPoints(), + HistogramDataPointStatelessMarshaler.INSTANCE, + context, + DATA_POINT_WRITER_KEY); + output.serializeEnum( + Histogram.AGGREGATION_TEMPORALITY, + MetricsMarshalerUtil.mapToTemporality(histogram.getAggregationTemporality())); + } + + @Override + public int getBinarySerializedSize(HistogramData histogram, MarshalerContext context) { + int size = 0; + size += + StatelessMarshalerUtil.sizeRepeatedMessageWithContext( + Histogram.DATA_POINTS, + histogram.getPoints(), + HistogramDataPointStatelessMarshaler.INSTANCE, + context, + DATA_POINT_SIZE_CALCULATOR_KEY); + size += + MarshalerUtil.sizeEnum( + Histogram.AGGREGATION_TEMPORALITY, + MetricsMarshalerUtil.mapToTemporality(histogram.getAggregationTemporality())); + return size; + } +} diff --git a/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/metrics/InstrumentationScopeMetricsStatelessMarshaler.java b/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/metrics/InstrumentationScopeMetricsStatelessMarshaler.java new file mode 100644 index 00000000000..1be87dbdd1e --- /dev/null +++ b/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/metrics/InstrumentationScopeMetricsStatelessMarshaler.java @@ -0,0 +1,66 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.exporter.internal.otlp.metrics; + +import io.opentelemetry.exporter.internal.marshal.MarshalerContext; +import io.opentelemetry.exporter.internal.marshal.MarshalerUtil; +import io.opentelemetry.exporter.internal.marshal.Serializer; +import io.opentelemetry.exporter.internal.marshal.StatelessMarshaler2; +import io.opentelemetry.exporter.internal.marshal.StatelessMarshalerUtil; +import io.opentelemetry.exporter.internal.otlp.InstrumentationScopeMarshaler; +import io.opentelemetry.proto.metrics.v1.internal.ScopeMetrics; +import io.opentelemetry.proto.trace.v1.internal.ScopeSpans; +import io.opentelemetry.sdk.common.InstrumentationScopeInfo; +import io.opentelemetry.sdk.metrics.data.MetricData; +import java.io.IOException; +import java.util.List; + +/** See {@link InstrumentationScopeMetricsMarshaler}. */ +final class InstrumentationScopeMetricsStatelessMarshaler + implements StatelessMarshaler2> { + static final InstrumentationScopeMetricsStatelessMarshaler INSTANCE = + new InstrumentationScopeMetricsStatelessMarshaler(); + + private InstrumentationScopeMetricsStatelessMarshaler() {} + + @Override + public void writeTo( + Serializer output, + InstrumentationScopeInfo instrumentationScope, + List metrics, + MarshalerContext context) + throws IOException { + InstrumentationScopeMarshaler instrumentationScopeMarshaler = + context.getData(InstrumentationScopeMarshaler.class); + + output.serializeMessage(ScopeMetrics.SCOPE, instrumentationScopeMarshaler); + output.serializeRepeatedMessageWithContext( + ScopeMetrics.METRICS, metrics, MetricStatelessMarshaler.INSTANCE, context); + output.serializeStringWithContext( + ScopeMetrics.SCHEMA_URL, instrumentationScope.getSchemaUrl(), context); + } + + @Override + public int getBinarySerializedSize( + InstrumentationScopeInfo instrumentationScope, + List metrics, + MarshalerContext context) { + InstrumentationScopeMarshaler instrumentationScopeMarshaler = + InstrumentationScopeMarshaler.create(instrumentationScope); + context.addData(instrumentationScopeMarshaler); + + int size = 0; + size += MarshalerUtil.sizeMessage(ScopeMetrics.SCOPE, instrumentationScopeMarshaler); + size += + StatelessMarshalerUtil.sizeRepeatedMessageWithContext( + ScopeMetrics.METRICS, metrics, MetricStatelessMarshaler.INSTANCE, context); + size += + StatelessMarshalerUtil.sizeStringWithContext( + ScopeSpans.SCHEMA_URL, instrumentationScope.getSchemaUrl(), context); + + return size; + } +} diff --git a/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/metrics/LowAllocationMetricsRequestMarshaler.java b/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/metrics/LowAllocationMetricsRequestMarshaler.java new file mode 100644 index 00000000000..704642dc35a --- /dev/null +++ b/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/metrics/LowAllocationMetricsRequestMarshaler.java @@ -0,0 +1,107 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.exporter.internal.otlp.metrics; + +import io.opentelemetry.exporter.internal.marshal.Marshaler; +import io.opentelemetry.exporter.internal.marshal.MarshalerContext; +import io.opentelemetry.exporter.internal.marshal.Serializer; +import io.opentelemetry.exporter.internal.marshal.StatelessMarshalerUtil; +import io.opentelemetry.proto.collector.metrics.v1.internal.ExportMetricsServiceRequest; +import io.opentelemetry.sdk.common.InstrumentationScopeInfo; +import io.opentelemetry.sdk.metrics.data.MetricData; +import io.opentelemetry.sdk.resources.Resource; +import java.io.IOException; +import java.util.Collection; +import java.util.Collections; +import java.util.List; +import java.util.Map; + +/** + * {@link Marshaler} to convert SDK {@link MetricData} to OTLP ExportMetricsServiceRequest. See + * {@link MetricsRequestMarshaler}. + * + *

      Example usage: + * + *

      {@code
      + * void marshal(LowAllocationMetricsRequestMarshaler requestMarshaler, OutputStream output,
      + *     Collection metricDataList) throws IOException {
      + *   requestMarshaler.initialize(metricDataList);
      + *   try {
      + *     requestMarshaler.writeBinaryTo(output);
      + *   } finally {
      + *     requestMarshaler.reset();
      + *   }
      + * }
      + * }
      + * + *

      This class is internal and is hence not for public use. Its APIs are unstable and can change + * at any time. + */ +public final class LowAllocationMetricsRequestMarshaler extends Marshaler { + private static final MarshalerContext.Key RESOURCE_METRIC_SIZE_CALCULATOR_KEY = + MarshalerContext.key(); + private static final MarshalerContext.Key RESOURCE_METRIC_WRITER_KEY = MarshalerContext.key(); + + private final MarshalerContext context = new MarshalerContext(); + + @SuppressWarnings("NullAway") + private Map>> resourceAndScopeMap; + + private int size; + + public void initialize(Collection metricDataList) { + resourceAndScopeMap = groupByResourceAndScope(context, metricDataList); + size = calculateSize(context, resourceAndScopeMap); + } + + public void reset() { + context.reset(); + } + + @Override + public int getBinarySerializedSize() { + return size; + } + + @Override + public void writeTo(Serializer output) throws IOException { + // serializing can be retried, reset the indexes, so we could call writeTo multiple times + context.resetReadIndex(); + output.serializeRepeatedMessageWithContext( + ExportMetricsServiceRequest.RESOURCE_METRICS, + resourceAndScopeMap, + ResourceMetricsStatelessMarshaler.INSTANCE, + context, + RESOURCE_METRIC_WRITER_KEY); + } + + private static int calculateSize( + MarshalerContext context, + Map>> resourceAndScopeMap) { + return StatelessMarshalerUtil.sizeRepeatedMessageWithContext( + ExportMetricsServiceRequest.RESOURCE_METRICS, + resourceAndScopeMap, + ResourceMetricsStatelessMarshaler.INSTANCE, + context, + RESOURCE_METRIC_SIZE_CALCULATOR_KEY); + } + + private static Map>> + groupByResourceAndScope(MarshalerContext context, Collection metricDataList) { + + if (metricDataList.isEmpty()) { + return Collections.emptyMap(); + } + + return StatelessMarshalerUtil.groupByResourceAndScope( + metricDataList, + // TODO(anuraaga): Replace with an internal SdkData type of interface that exposes these + // two. + MetricData::getResource, + MetricData::getInstrumentationScopeInfo, + context); + } +} diff --git a/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/metrics/MetricStatelessMarshaler.java b/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/metrics/MetricStatelessMarshaler.java new file mode 100644 index 00000000000..4a2868ebe2c --- /dev/null +++ b/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/metrics/MetricStatelessMarshaler.java @@ -0,0 +1,212 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.exporter.internal.otlp.metrics; + +import static io.opentelemetry.sdk.metrics.data.MetricDataType.DOUBLE_GAUGE; +import static io.opentelemetry.sdk.metrics.data.MetricDataType.DOUBLE_SUM; +import static io.opentelemetry.sdk.metrics.data.MetricDataType.EXPONENTIAL_HISTOGRAM; +import static io.opentelemetry.sdk.metrics.data.MetricDataType.HISTOGRAM; +import static io.opentelemetry.sdk.metrics.data.MetricDataType.LONG_GAUGE; +import static io.opentelemetry.sdk.metrics.data.MetricDataType.LONG_SUM; +import static io.opentelemetry.sdk.metrics.data.MetricDataType.SUMMARY; + +import io.opentelemetry.exporter.internal.marshal.MarshalerContext; +import io.opentelemetry.exporter.internal.marshal.Serializer; +import io.opentelemetry.exporter.internal.marshal.StatelessMarshaler; +import io.opentelemetry.exporter.internal.marshal.StatelessMarshalerUtil; +import io.opentelemetry.proto.metrics.v1.internal.Metric; +import io.opentelemetry.sdk.metrics.data.MetricData; +import io.opentelemetry.sdk.metrics.data.MetricDataType; +import java.io.IOException; +import java.util.EnumMap; +import java.util.Map; + +/** See {@link MetricMarshaler}. */ +final class MetricStatelessMarshaler implements StatelessMarshaler { + static final MetricStatelessMarshaler INSTANCE = new MetricStatelessMarshaler(); + private static final Map> METRIC_MARSHALERS = + new EnumMap<>(MetricDataType.class); + + static { + METRIC_MARSHALERS.put( + LONG_GAUGE, + new StatelessMarshaler() { + @Override + public int getBinarySerializedSize(MetricData metricData, MarshalerContext context) { + return StatelessMarshalerUtil.sizeMessageWithContext( + Metric.GAUGE, + metricData.getLongGaugeData(), + GaugeStatelessMarshaler.INSTANCE, + context); + } + + @Override + public void writeTo(Serializer output, MetricData metric, MarshalerContext context) + throws IOException { + output.serializeMessageWithContext( + Metric.GAUGE, metric.getLongGaugeData(), GaugeStatelessMarshaler.INSTANCE, context); + } + }); + METRIC_MARSHALERS.put( + DOUBLE_GAUGE, + new StatelessMarshaler() { + @Override + public int getBinarySerializedSize(MetricData metricData, MarshalerContext context) { + return StatelessMarshalerUtil.sizeMessageWithContext( + Metric.GAUGE, + metricData.getDoubleGaugeData(), + GaugeStatelessMarshaler.INSTANCE, + context); + } + + @Override + public void writeTo(Serializer output, MetricData metric, MarshalerContext context) + throws IOException { + output.serializeMessageWithContext( + Metric.GAUGE, + metric.getDoubleGaugeData(), + GaugeStatelessMarshaler.INSTANCE, + context); + } + }); + METRIC_MARSHALERS.put( + LONG_SUM, + new StatelessMarshaler() { + @Override + public int getBinarySerializedSize(MetricData metricData, MarshalerContext context) { + return StatelessMarshalerUtil.sizeMessageWithContext( + Metric.SUM, metricData.getLongSumData(), SumStatelessMarshaler.INSTANCE, context); + } + + @Override + public void writeTo(Serializer output, MetricData metric, MarshalerContext context) + throws IOException { + output.serializeMessageWithContext( + Metric.SUM, metric.getLongSumData(), SumStatelessMarshaler.INSTANCE, context); + } + }); + METRIC_MARSHALERS.put( + DOUBLE_SUM, + new StatelessMarshaler() { + @Override + public int getBinarySerializedSize(MetricData metricData, MarshalerContext context) { + return StatelessMarshalerUtil.sizeMessageWithContext( + Metric.SUM, metricData.getDoubleSumData(), SumStatelessMarshaler.INSTANCE, context); + } + + @Override + public void writeTo(Serializer output, MetricData metric, MarshalerContext context) + throws IOException { + output.serializeMessageWithContext( + Metric.SUM, metric.getDoubleSumData(), SumStatelessMarshaler.INSTANCE, context); + } + }); + METRIC_MARSHALERS.put( + SUMMARY, + new StatelessMarshaler() { + @Override + public int getBinarySerializedSize(MetricData metricData, MarshalerContext context) { + return StatelessMarshalerUtil.sizeMessageWithContext( + Metric.SUMMARY, + metricData.getSummaryData(), + SummaryStatelessMarshaler.INSTANCE, + context); + } + + @Override + public void writeTo(Serializer output, MetricData metric, MarshalerContext context) + throws IOException { + output.serializeMessageWithContext( + Metric.SUMMARY, + metric.getSummaryData(), + SummaryStatelessMarshaler.INSTANCE, + context); + } + }); + METRIC_MARSHALERS.put( + HISTOGRAM, + new StatelessMarshaler() { + @Override + public int getBinarySerializedSize(MetricData metricData, MarshalerContext context) { + return StatelessMarshalerUtil.sizeMessageWithContext( + Metric.HISTOGRAM, + metricData.getHistogramData(), + HistogramStatelessMarshaler.INSTANCE, + context); + } + + @Override + public void writeTo(Serializer output, MetricData metric, MarshalerContext context) + throws IOException { + output.serializeMessageWithContext( + Metric.HISTOGRAM, + metric.getHistogramData(), + HistogramStatelessMarshaler.INSTANCE, + context); + } + }); + METRIC_MARSHALERS.put( + EXPONENTIAL_HISTOGRAM, + new StatelessMarshaler() { + @Override + public int getBinarySerializedSize(MetricData metricData, MarshalerContext context) { + return StatelessMarshalerUtil.sizeMessageWithContext( + Metric.EXPONENTIAL_HISTOGRAM, + metricData.getExponentialHistogramData(), + ExponentialHistogramStatelessMarshaler.INSTANCE, + context); + } + + @Override + public void writeTo(Serializer output, MetricData metric, MarshalerContext context) + throws IOException { + output.serializeMessageWithContext( + Metric.EXPONENTIAL_HISTOGRAM, + metric.getExponentialHistogramData(), + ExponentialHistogramStatelessMarshaler.INSTANCE, + context); + } + }); + } + + private MetricStatelessMarshaler() {} + + @Override + public void writeTo(Serializer output, MetricData metric, MarshalerContext context) + throws IOException { + StatelessMarshaler metricMarshaler = METRIC_MARSHALERS.get(metric.getType()); + if (metricMarshaler == null) { + // Someone not using BOM to align versions as we require. Just skip the metric. + return; + } + + output.serializeStringWithContext(Metric.NAME, metric.getName(), context); + output.serializeStringWithContext(Metric.DESCRIPTION, metric.getDescription(), context); + output.serializeStringWithContext(Metric.UNIT, metric.getUnit(), context); + + metricMarshaler.writeTo(output, metric, context); + } + + @Override + public int getBinarySerializedSize(MetricData metric, MarshalerContext context) { + StatelessMarshaler metricMarshaler = METRIC_MARSHALERS.get(metric.getType()); + if (metricMarshaler == null) { + // Someone not using BOM to align versions as we require. Just skip the metric. + return 0; + } + + int size = 0; + size += StatelessMarshalerUtil.sizeStringWithContext(Metric.NAME, metric.getName(), context); + size += + StatelessMarshalerUtil.sizeStringWithContext( + Metric.DESCRIPTION, metric.getDescription(), context); + size += StatelessMarshalerUtil.sizeStringWithContext(Metric.UNIT, metric.getUnit(), context); + + size += metricMarshaler.getBinarySerializedSize(metric, context); + + return size; + } +} diff --git a/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/metrics/NumberDataPointMarshaler.java b/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/metrics/NumberDataPointMarshaler.java index 51a432096cd..7edd3a76a8f 100644 --- a/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/metrics/NumberDataPointMarshaler.java +++ b/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/metrics/NumberDataPointMarshaler.java @@ -42,19 +42,11 @@ static NumberDataPointMarshaler create(PointData point) { KeyValueMarshaler[] attributeMarshalers = KeyValueMarshaler.createForAttributes(point.getAttributes()); - ProtoFieldInfo valueField; - if (point instanceof LongPointData) { - valueField = NumberDataPoint.AS_INT; - } else { - assert point instanceof DoublePointData; - valueField = NumberDataPoint.AS_DOUBLE; - } - return new NumberDataPointMarshaler( point.getStartEpochNanos(), point.getEpochNanos(), point, - valueField, + toProtoPointValueType(point), exemplarMarshalers, attributeMarshalers); } @@ -107,4 +99,13 @@ private static int calculateSize( size += MarshalerUtil.sizeRepeatedMessage(NumberDataPoint.ATTRIBUTES, attributes); return size; } + + static ProtoFieldInfo toProtoPointValueType(PointData pointData) { + if (pointData instanceof LongPointData) { + return NumberDataPoint.AS_INT; + } else { + assert pointData instanceof DoublePointData; + return NumberDataPoint.AS_DOUBLE; + } + } } diff --git a/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/metrics/NumberDataPointStatelessMarshaler.java b/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/metrics/NumberDataPointStatelessMarshaler.java new file mode 100644 index 00000000000..2981e8cd598 --- /dev/null +++ b/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/metrics/NumberDataPointStatelessMarshaler.java @@ -0,0 +1,78 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.exporter.internal.otlp.metrics; + +import static io.opentelemetry.exporter.internal.otlp.metrics.NumberDataPointMarshaler.toProtoPointValueType; + +import io.opentelemetry.exporter.internal.marshal.MarshalerContext; +import io.opentelemetry.exporter.internal.marshal.MarshalerUtil; +import io.opentelemetry.exporter.internal.marshal.ProtoFieldInfo; +import io.opentelemetry.exporter.internal.marshal.Serializer; +import io.opentelemetry.exporter.internal.marshal.StatelessMarshaler; +import io.opentelemetry.exporter.internal.marshal.StatelessMarshalerUtil; +import io.opentelemetry.exporter.internal.otlp.KeyValueStatelessMarshaler; +import io.opentelemetry.proto.metrics.v1.internal.NumberDataPoint; +import io.opentelemetry.sdk.metrics.data.DoublePointData; +import io.opentelemetry.sdk.metrics.data.LongPointData; +import io.opentelemetry.sdk.metrics.data.PointData; +import java.io.IOException; + +/** See {@link NumberDataPointMarshaler}. */ +final class NumberDataPointStatelessMarshaler implements StatelessMarshaler { + static final NumberDataPointStatelessMarshaler INSTANCE = new NumberDataPointStatelessMarshaler(); + + private NumberDataPointStatelessMarshaler() {} + + @Override + public void writeTo(Serializer output, PointData point, MarshalerContext context) + throws IOException { + output.serializeFixed64(NumberDataPoint.START_TIME_UNIX_NANO, point.getStartEpochNanos()); + output.serializeFixed64(NumberDataPoint.TIME_UNIX_NANO, point.getEpochNanos()); + ProtoFieldInfo valueField = toProtoPointValueType(point); + if (valueField == NumberDataPoint.AS_INT) { + output.serializeFixed64Optional(valueField, ((LongPointData) point).getValue()); + } else { + output.serializeDoubleOptional(valueField, ((DoublePointData) point).getValue()); + } + output.serializeRepeatedMessageWithContext( + NumberDataPoint.EXEMPLARS, + point.getExemplars(), + ExemplarStatelessMarshaler.INSTANCE, + context); + output.serializeRepeatedMessageWithContext( + NumberDataPoint.ATTRIBUTES, + point.getAttributes(), + KeyValueStatelessMarshaler.INSTANCE, + context); + } + + @Override + public int getBinarySerializedSize(PointData point, MarshalerContext context) { + int size = 0; + size += + MarshalerUtil.sizeFixed64(NumberDataPoint.START_TIME_UNIX_NANO, point.getStartEpochNanos()); + size += MarshalerUtil.sizeFixed64(NumberDataPoint.TIME_UNIX_NANO, point.getEpochNanos()); + ProtoFieldInfo valueField = toProtoPointValueType(point); + if (valueField == NumberDataPoint.AS_INT) { + size += MarshalerUtil.sizeFixed64Optional(valueField, ((LongPointData) point).getValue()); + } else { + size += MarshalerUtil.sizeDoubleOptional(valueField, ((DoublePointData) point).getValue()); + } + size += + StatelessMarshalerUtil.sizeRepeatedMessageWithContext( + NumberDataPoint.EXEMPLARS, + point.getExemplars(), + ExemplarStatelessMarshaler.INSTANCE, + context); + size += + StatelessMarshalerUtil.sizeRepeatedMessageWithContext( + NumberDataPoint.ATTRIBUTES, + point.getAttributes(), + KeyValueStatelessMarshaler.INSTANCE, + context); + return size; + } +} diff --git a/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/metrics/ResourceMetricsStatelessMarshaler.java b/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/metrics/ResourceMetricsStatelessMarshaler.java new file mode 100644 index 00000000000..e25ab330587 --- /dev/null +++ b/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/metrics/ResourceMetricsStatelessMarshaler.java @@ -0,0 +1,83 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.exporter.internal.otlp.metrics; + +import io.opentelemetry.exporter.internal.marshal.MarshalerContext; +import io.opentelemetry.exporter.internal.marshal.MarshalerUtil; +import io.opentelemetry.exporter.internal.marshal.Serializer; +import io.opentelemetry.exporter.internal.marshal.StatelessMarshaler2; +import io.opentelemetry.exporter.internal.marshal.StatelessMarshalerUtil; +import io.opentelemetry.exporter.internal.otlp.ResourceMarshaler; +import io.opentelemetry.proto.metrics.v1.internal.ResourceMetrics; +import io.opentelemetry.sdk.common.InstrumentationScopeInfo; +import io.opentelemetry.sdk.metrics.data.MetricData; +import io.opentelemetry.sdk.resources.Resource; +import java.io.IOException; +import java.util.List; +import java.util.Map; + +/** + * A Marshaler of ResourceMetrics. See {@link ResourceMetricsMarshaler}. + * + *

      This class is internal and is hence not for public use. Its APIs are unstable and can change + * at any time. + */ +public final class ResourceMetricsStatelessMarshaler + implements StatelessMarshaler2>> { + static final ResourceMetricsStatelessMarshaler INSTANCE = new ResourceMetricsStatelessMarshaler(); + private static final MarshalerContext.Key SCOPE_METRIC_WRITER_KEY = MarshalerContext.key(); + private static final MarshalerContext.Key SCOPE_METRIC_SIZE_CALCULATOR_KEY = + MarshalerContext.key(); + + private ResourceMetricsStatelessMarshaler() {} + + @Override + public void writeTo( + Serializer output, + Resource resource, + Map> scopeMap, + MarshalerContext context) + throws IOException { + ResourceMarshaler resourceMarshaler = context.getData(ResourceMarshaler.class); + output.serializeMessage(ResourceMetrics.RESOURCE, resourceMarshaler); + + output.serializeRepeatedMessageWithContext( + ResourceMetrics.SCOPE_METRICS, + scopeMap, + InstrumentationScopeMetricsStatelessMarshaler.INSTANCE, + context, + SCOPE_METRIC_WRITER_KEY); + + output.serializeStringWithContext(ResourceMetrics.SCHEMA_URL, resource.getSchemaUrl(), context); + } + + @Override + public int getBinarySerializedSize( + Resource resource, + Map> scopeMap, + MarshalerContext context) { + + int size = 0; + + ResourceMarshaler resourceMarshaler = ResourceMarshaler.create(resource); + context.addData(resourceMarshaler); + size += MarshalerUtil.sizeMessage(ResourceMetrics.RESOURCE, resourceMarshaler); + + size += + StatelessMarshalerUtil.sizeRepeatedMessageWithContext( + ResourceMetrics.SCOPE_METRICS, + scopeMap, + InstrumentationScopeMetricsStatelessMarshaler.INSTANCE, + context, + SCOPE_METRIC_SIZE_CALCULATOR_KEY); + + size += + StatelessMarshalerUtil.sizeStringWithContext( + ResourceMetrics.SCHEMA_URL, resource.getSchemaUrl(), context); + + return size; + } +} diff --git a/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/metrics/SumStatelessMarshaler.java b/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/metrics/SumStatelessMarshaler.java new file mode 100644 index 00000000000..9a4ce569bee --- /dev/null +++ b/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/metrics/SumStatelessMarshaler.java @@ -0,0 +1,56 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.exporter.internal.otlp.metrics; + +import io.opentelemetry.exporter.internal.marshal.MarshalerContext; +import io.opentelemetry.exporter.internal.marshal.MarshalerUtil; +import io.opentelemetry.exporter.internal.marshal.Serializer; +import io.opentelemetry.exporter.internal.marshal.StatelessMarshaler; +import io.opentelemetry.exporter.internal.marshal.StatelessMarshalerUtil; +import io.opentelemetry.proto.metrics.v1.internal.Sum; +import io.opentelemetry.sdk.metrics.data.PointData; +import io.opentelemetry.sdk.metrics.data.SumData; +import java.io.IOException; + +/** See {@link SumMarshaler}. */ +final class SumStatelessMarshaler implements StatelessMarshaler> { + static final SumStatelessMarshaler INSTANCE = new SumStatelessMarshaler(); + private static final MarshalerContext.Key DATA_POINT_SIZE_CALCULATOR_KEY = MarshalerContext.key(); + private static final MarshalerContext.Key DATA_POINT_WRITER_KEY = MarshalerContext.key(); + + @Override + public void writeTo(Serializer output, SumData sum, MarshalerContext context) + throws IOException { + output.serializeRepeatedMessageWithContext( + Sum.DATA_POINTS, + sum.getPoints(), + NumberDataPointStatelessMarshaler.INSTANCE, + context, + DATA_POINT_WRITER_KEY); + output.serializeEnum( + Sum.AGGREGATION_TEMPORALITY, + MetricsMarshalerUtil.mapToTemporality(sum.getAggregationTemporality())); + output.serializeBool(Sum.IS_MONOTONIC, sum.isMonotonic()); + } + + @Override + public int getBinarySerializedSize(SumData sum, MarshalerContext context) { + int size = 0; + size += + StatelessMarshalerUtil.sizeRepeatedMessageWithContext( + Sum.DATA_POINTS, + sum.getPoints(), + NumberDataPointStatelessMarshaler.INSTANCE, + context, + DATA_POINT_SIZE_CALCULATOR_KEY); + size += + MarshalerUtil.sizeEnum( + Sum.AGGREGATION_TEMPORALITY, + MetricsMarshalerUtil.mapToTemporality(sum.getAggregationTemporality())); + size += MarshalerUtil.sizeBool(Sum.IS_MONOTONIC, sum.isMonotonic()); + return size; + } +} diff --git a/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/metrics/SummaryDataPointStatelessMarshaler.java b/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/metrics/SummaryDataPointStatelessMarshaler.java new file mode 100644 index 00000000000..d8d611c12fb --- /dev/null +++ b/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/metrics/SummaryDataPointStatelessMarshaler.java @@ -0,0 +1,67 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.exporter.internal.otlp.metrics; + +import io.opentelemetry.exporter.internal.marshal.MarshalerContext; +import io.opentelemetry.exporter.internal.marshal.MarshalerUtil; +import io.opentelemetry.exporter.internal.marshal.Serializer; +import io.opentelemetry.exporter.internal.marshal.StatelessMarshaler; +import io.opentelemetry.exporter.internal.marshal.StatelessMarshalerUtil; +import io.opentelemetry.exporter.internal.otlp.KeyValueStatelessMarshaler; +import io.opentelemetry.proto.metrics.v1.internal.SummaryDataPoint; +import io.opentelemetry.sdk.metrics.data.SummaryPointData; +import java.io.IOException; + +/** See {@link SummaryDataPointMarshaler}. */ +final class SummaryDataPointStatelessMarshaler implements StatelessMarshaler { + static final SummaryDataPointStatelessMarshaler INSTANCE = + new SummaryDataPointStatelessMarshaler(); + + private SummaryDataPointStatelessMarshaler() {} + + @Override + public void writeTo(Serializer output, SummaryPointData point, MarshalerContext context) + throws IOException { + output.serializeFixed64(SummaryDataPoint.START_TIME_UNIX_NANO, point.getStartEpochNanos()); + output.serializeFixed64(SummaryDataPoint.TIME_UNIX_NANO, point.getEpochNanos()); + output.serializeFixed64(SummaryDataPoint.COUNT, point.getCount()); + output.serializeDouble(SummaryDataPoint.SUM, point.getSum()); + output.serializeRepeatedMessageWithContext( + SummaryDataPoint.QUANTILE_VALUES, + point.getValues(), + ValueAtQuantileStatelessMarshaler.INSTANCE, + context); + output.serializeRepeatedMessageWithContext( + SummaryDataPoint.ATTRIBUTES, + point.getAttributes(), + KeyValueStatelessMarshaler.INSTANCE, + context); + } + + @Override + public int getBinarySerializedSize(SummaryPointData point, MarshalerContext context) { + int size = 0; + size += + MarshalerUtil.sizeFixed64( + SummaryDataPoint.START_TIME_UNIX_NANO, point.getStartEpochNanos()); + size += MarshalerUtil.sizeFixed64(SummaryDataPoint.TIME_UNIX_NANO, point.getEpochNanos()); + size += MarshalerUtil.sizeFixed64(SummaryDataPoint.COUNT, point.getCount()); + size += MarshalerUtil.sizeDouble(SummaryDataPoint.SUM, point.getSum()); + size += + StatelessMarshalerUtil.sizeRepeatedMessageWithContext( + SummaryDataPoint.QUANTILE_VALUES, + point.getValues(), + ValueAtQuantileStatelessMarshaler.INSTANCE, + context); + size += + StatelessMarshalerUtil.sizeRepeatedMessageWithContext( + SummaryDataPoint.ATTRIBUTES, + point.getAttributes(), + KeyValueStatelessMarshaler.INSTANCE, + context); + return size; + } +} diff --git a/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/metrics/SummaryStatelessMarshaler.java b/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/metrics/SummaryStatelessMarshaler.java new file mode 100644 index 00000000000..b15984592b8 --- /dev/null +++ b/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/metrics/SummaryStatelessMarshaler.java @@ -0,0 +1,44 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.exporter.internal.otlp.metrics; + +import io.opentelemetry.exporter.internal.marshal.MarshalerContext; +import io.opentelemetry.exporter.internal.marshal.Serializer; +import io.opentelemetry.exporter.internal.marshal.StatelessMarshaler; +import io.opentelemetry.exporter.internal.marshal.StatelessMarshalerUtil; +import io.opentelemetry.proto.metrics.v1.internal.Summary; +import io.opentelemetry.sdk.metrics.data.SummaryData; +import java.io.IOException; + +/** See {@link SummaryMarshaler}. */ +final class SummaryStatelessMarshaler implements StatelessMarshaler { + static final SummaryStatelessMarshaler INSTANCE = new SummaryStatelessMarshaler(); + private static final MarshalerContext.Key DATA_POINT_SIZE_CALCULATOR_KEY = MarshalerContext.key(); + private static final MarshalerContext.Key DATA_POINT_WRITER_KEY = MarshalerContext.key(); + + private SummaryStatelessMarshaler() {} + + @Override + public void writeTo(Serializer output, SummaryData summary, MarshalerContext context) + throws IOException { + output.serializeRepeatedMessageWithContext( + Summary.DATA_POINTS, + summary.getPoints(), + SummaryDataPointStatelessMarshaler.INSTANCE, + context, + DATA_POINT_WRITER_KEY); + } + + @Override + public int getBinarySerializedSize(SummaryData summary, MarshalerContext context) { + return StatelessMarshalerUtil.sizeRepeatedMessageWithContext( + Summary.DATA_POINTS, + summary.getPoints(), + SummaryDataPointStatelessMarshaler.INSTANCE, + context, + DATA_POINT_SIZE_CALCULATOR_KEY); + } +} diff --git a/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/metrics/ValueAtQuantileMarshaler.java b/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/metrics/ValueAtQuantileMarshaler.java index 6f9ec38ef61..1c2e6ba09db 100644 --- a/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/metrics/ValueAtQuantileMarshaler.java +++ b/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/metrics/ValueAtQuantileMarshaler.java @@ -42,7 +42,7 @@ public void writeTo(Serializer output) throws IOException { output.serializeDouble(SummaryDataPoint.ValueAtQuantile.VALUE, value); } - private static int calculateSize(double quantile, double value) { + static int calculateSize(double quantile, double value) { int size = 0; size += MarshalerUtil.sizeDouble(SummaryDataPoint.ValueAtQuantile.QUANTILE, quantile); size += MarshalerUtil.sizeDouble(SummaryDataPoint.ValueAtQuantile.VALUE, value); diff --git a/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/metrics/ValueAtQuantileStatelessMarshaler.java b/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/metrics/ValueAtQuantileStatelessMarshaler.java new file mode 100644 index 00000000000..ba1f0347865 --- /dev/null +++ b/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/metrics/ValueAtQuantileStatelessMarshaler.java @@ -0,0 +1,32 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.exporter.internal.otlp.metrics; + +import io.opentelemetry.exporter.internal.marshal.MarshalerContext; +import io.opentelemetry.exporter.internal.marshal.Serializer; +import io.opentelemetry.exporter.internal.marshal.StatelessMarshaler; +import io.opentelemetry.proto.metrics.v1.internal.SummaryDataPoint; +import io.opentelemetry.sdk.metrics.data.ValueAtQuantile; +import java.io.IOException; + +/** See {@link ValueAtQuantileMarshaler}. */ +final class ValueAtQuantileStatelessMarshaler implements StatelessMarshaler { + static final ValueAtQuantileStatelessMarshaler INSTANCE = new ValueAtQuantileStatelessMarshaler(); + + private ValueAtQuantileStatelessMarshaler() {} + + @Override + public void writeTo(Serializer output, ValueAtQuantile value, MarshalerContext context) + throws IOException { + output.serializeDouble(SummaryDataPoint.ValueAtQuantile.QUANTILE, value.getQuantile()); + output.serializeDouble(SummaryDataPoint.ValueAtQuantile.VALUE, value.getValue()); + } + + @Override + public int getBinarySerializedSize(ValueAtQuantile value, MarshalerContext context) { + return ValueAtQuantileMarshaler.calculateSize(value.getQuantile(), value.getValue()); + } +} diff --git a/exporters/otlp/common/src/test/java/io/opentelemetry/exporter/internal/otlp/metrics/LowAllocationMetricsRequestMarshalerTest.java b/exporters/otlp/common/src/test/java/io/opentelemetry/exporter/internal/otlp/metrics/LowAllocationMetricsRequestMarshalerTest.java new file mode 100644 index 00000000000..3efc938993f --- /dev/null +++ b/exporters/otlp/common/src/test/java/io/opentelemetry/exporter/internal/otlp/metrics/LowAllocationMetricsRequestMarshalerTest.java @@ -0,0 +1,408 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.exporter.internal.otlp.metrics; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.jupiter.api.Named.named; +import static org.junit.jupiter.params.provider.Arguments.arguments; + +import io.opentelemetry.api.common.AttributeKey; +import io.opentelemetry.api.common.Attributes; +import io.opentelemetry.api.metrics.DoubleCounter; +import io.opentelemetry.api.metrics.DoubleHistogram; +import io.opentelemetry.api.metrics.DoubleUpDownCounter; +import io.opentelemetry.api.metrics.LongCounter; +import io.opentelemetry.api.metrics.LongHistogram; +import io.opentelemetry.api.metrics.LongUpDownCounter; +import io.opentelemetry.api.metrics.MeterProvider; +import io.opentelemetry.api.trace.SpanContext; +import io.opentelemetry.api.trace.TraceFlags; +import io.opentelemetry.api.trace.TraceState; +import io.opentelemetry.exporter.internal.marshal.Marshaler; +import io.opentelemetry.exporter.internal.marshal.MarshalerContext; +import io.opentelemetry.exporter.internal.marshal.MarshalerWithSize; +import io.opentelemetry.exporter.internal.marshal.Serializer; +import io.opentelemetry.sdk.metrics.Aggregation; +import io.opentelemetry.sdk.metrics.InstrumentSelector; +import io.opentelemetry.sdk.metrics.SdkMeterProvider; +import io.opentelemetry.sdk.metrics.View; +import io.opentelemetry.sdk.metrics.data.ExemplarData; +import io.opentelemetry.sdk.metrics.data.MetricData; +import io.opentelemetry.sdk.metrics.data.SummaryData; +import io.opentelemetry.sdk.metrics.data.SummaryPointData; +import io.opentelemetry.sdk.metrics.data.ValueAtQuantile; +import io.opentelemetry.sdk.metrics.internal.data.ImmutableDoubleExemplarData; +import io.opentelemetry.sdk.metrics.internal.data.ImmutableLongExemplarData; +import io.opentelemetry.sdk.metrics.internal.data.ImmutableSummaryData; +import io.opentelemetry.sdk.metrics.internal.data.ImmutableSummaryPointData; +import io.opentelemetry.sdk.metrics.internal.data.ImmutableValueAtQuantile; +import io.opentelemetry.sdk.resources.Resource; +import io.opentelemetry.sdk.testing.exporter.InMemoryMetricReader; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.nio.charset.StandardCharsets; +import java.util.Arrays; +import java.util.Collection; +import java.util.List; +import java.util.function.Consumer; +import java.util.stream.Stream; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtensionContext; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.ArgumentsProvider; +import org.junit.jupiter.params.provider.ArgumentsSource; + +class LowAllocationMetricsRequestMarshalerTest { + + @ParameterizedTest + @ArgumentsSource(MetricsProvider.class) + void validateOutput(Collection metrics) throws Exception { + byte[] result; + { + MetricsRequestMarshaler requestMarshaler = MetricsRequestMarshaler.create(metrics); + ByteArrayOutputStream customOutput = + new ByteArrayOutputStream(requestMarshaler.getBinarySerializedSize()); + requestMarshaler.writeBinaryTo(customOutput); + result = customOutput.toByteArray(); + } + + byte[] lowAllocationResult; + { + LowAllocationMetricsRequestMarshaler requestMarshaler = + new LowAllocationMetricsRequestMarshaler(); + requestMarshaler.initialize(metrics); + ByteArrayOutputStream customOutput = + new ByteArrayOutputStream(requestMarshaler.getBinarySerializedSize()); + requestMarshaler.writeBinaryTo(customOutput); + lowAllocationResult = customOutput.toByteArray(); + } + + assertThat(lowAllocationResult).isEqualTo(result); + } + + @ParameterizedTest + @ArgumentsSource(MetricsProvider.class) + void validateJsonOutput(Collection metrics) throws Exception { + String result; + { + MetricsRequestMarshaler requestMarshaler = MetricsRequestMarshaler.create(metrics); + ByteArrayOutputStream customOutput = + new ByteArrayOutputStream(requestMarshaler.getBinarySerializedSize()); + requestMarshaler.writeJsonTo(customOutput); + result = new String(customOutput.toByteArray(), StandardCharsets.UTF_8); + } + + String lowAllocationResult; + { + LowAllocationMetricsRequestMarshaler requestMarshaler = + new LowAllocationMetricsRequestMarshaler(); + requestMarshaler.initialize(metrics); + ByteArrayOutputStream customOutput = + new ByteArrayOutputStream(requestMarshaler.getBinarySerializedSize()); + requestMarshaler.writeJsonTo(customOutput); + lowAllocationResult = new String(customOutput.toByteArray(), StandardCharsets.UTF_8); + } + + assertThat(lowAllocationResult).isEqualTo(result); + } + + @ParameterizedTest + @ArgumentsSource(ExemplarProvider.class) + void validateExemplar(ExemplarData exemplar) throws Exception { + byte[] result; + { + Marshaler marshaler = ExemplarMarshaler.create(exemplar); + ByteArrayOutputStream customOutput = + new ByteArrayOutputStream(marshaler.getBinarySerializedSize()); + marshaler.writeBinaryTo(customOutput); + result = customOutput.toByteArray(); + } + + byte[] lowAllocationResult; + { + MarshalerContext context = new MarshalerContext(); + class TestMarshaler extends MarshalerWithSize { + + protected TestMarshaler() { + super(ExemplarStatelessMarshaler.INSTANCE.getBinarySerializedSize(exemplar, context)); + } + + @Override + protected void writeTo(Serializer output) throws IOException { + ExemplarStatelessMarshaler.INSTANCE.writeTo(output, exemplar, context); + } + } + Marshaler marshaler = new TestMarshaler(); + ByteArrayOutputStream customOutput = + new ByteArrayOutputStream(marshaler.getBinarySerializedSize()); + marshaler.writeBinaryTo(customOutput); + lowAllocationResult = customOutput.toByteArray(); + } + + assertThat(lowAllocationResult).isEqualTo(result); + } + + @Test + void validateSummary() throws Exception { + List percentileValues = + Arrays.asList(ImmutableValueAtQuantile.create(3.0, 4.0)); + List points = + Arrays.asList( + ImmutableSummaryPointData.create( + 12345, 12346, Attributes.empty(), 1, 2.0, percentileValues)); + SummaryData summary = ImmutableSummaryData.create(points); + + byte[] result; + { + Marshaler marshaler = SummaryMarshaler.create(summary); + ByteArrayOutputStream customOutput = + new ByteArrayOutputStream(marshaler.getBinarySerializedSize()); + marshaler.writeBinaryTo(customOutput); + result = customOutput.toByteArray(); + } + + byte[] lowAllocationResult; + { + MarshalerContext context = new MarshalerContext(); + class TestMarshaler extends MarshalerWithSize { + + protected TestMarshaler() { + super(SummaryStatelessMarshaler.INSTANCE.getBinarySerializedSize(summary, context)); + } + + @Override + protected void writeTo(Serializer output) throws IOException { + SummaryStatelessMarshaler.INSTANCE.writeTo(output, summary, context); + } + } + Marshaler marshaler = new TestMarshaler(); + ByteArrayOutputStream customOutput = + new ByteArrayOutputStream(marshaler.getBinarySerializedSize()); + marshaler.writeBinaryTo(customOutput); + lowAllocationResult = customOutput.toByteArray(); + } + + assertThat(lowAllocationResult).isEqualTo(result); + } + + private static Collection metrics(Consumer metricProducer) { + InMemoryMetricReader metricReader = InMemoryMetricReader.create(); + SdkMeterProvider meterProvider = + SdkMeterProvider.builder() + .registerMetricReader(metricReader) + .registerView( + InstrumentSelector.builder().setName("exponentialhistogram").build(), + View.builder() + .setAggregation(Aggregation.base2ExponentialBucketHistogram()) + .build()) + .setResource( + Resource.create( + Attributes.builder() + .put(AttributeKey.booleanKey("key_bool"), true) + .put(AttributeKey.stringKey("key_string"), "string") + .put(AttributeKey.longKey("key_int"), 100L) + .put(AttributeKey.doubleKey("key_double"), 100.3) + .put( + AttributeKey.stringArrayKey("key_string_array"), + Arrays.asList("string", "string")) + .put(AttributeKey.longArrayKey("key_long_array"), Arrays.asList(12L, 23L)) + .put( + AttributeKey.doubleArrayKey("key_double_array"), + Arrays.asList(12.3, 23.1)) + .put( + AttributeKey.booleanArrayKey("key_boolean_array"), + Arrays.asList(true, false)) + .build())) + .build(); + metricProducer.accept(meterProvider); + + return metricReader.collectAllMetrics(); + } + + private static class MetricsProvider implements ArgumentsProvider { + @Override + public Stream provideArguments(ExtensionContext context) { + return Stream.of( + arguments( + named( + "long gauge", + metrics( + meterProvider -> + meterProvider + .get("long gauge") + .gaugeBuilder("gauge") + .setDescription("gauge description") + .setUnit("unit") + .ofLongs() + .buildWithCallback( + measurement -> + measurement.record( + 5, + Attributes.of( + AttributeKey.stringKey("key"), "value")))))), + arguments( + named( + "long counter", + metrics( + meterProvider -> { + LongCounter longCounter = + meterProvider + .get("long counter") + .counterBuilder("counter") + .setDescription("counter description") + .setUnit("unit") + .build(); + longCounter.add(1); + longCounter.add(2, Attributes.of(AttributeKey.longKey("lives"), 9L)); + longCounter.add(3); + }))), + arguments( + named( + "long updowncounter", + metrics( + meterProvider -> { + LongUpDownCounter longUpDownCounter = + meterProvider + .get("long updowncounter") + .upDownCounterBuilder("updowncounter") + .setDescription("updowncounter description") + .setUnit("unit") + .build(); + longUpDownCounter.add(1); + longUpDownCounter.add( + -1, Attributes.of(AttributeKey.booleanKey("on"), true)); + longUpDownCounter.add(1); + }))), + arguments( + named( + "double gauge", + metrics( + meterProvider -> + meterProvider + .get("double gauge") + .gaugeBuilder("doublegauge") + .setDescription("doublegauge") + .setUnit("unit") + .buildWithCallback(measurement -> measurement.record(5.0))))), + arguments( + named( + "double counter", + metrics( + meterProvider -> { + DoubleCounter doubleCounter = + meterProvider + .get("double counter") + .counterBuilder("doublecounter") + .ofDoubles() + .build(); + doubleCounter.add(1.0); + doubleCounter.add(2.0); + }))), + arguments( + named( + "double updowncounter", + metrics( + meterProvider -> { + DoubleUpDownCounter doubleUpDownCounter = + meterProvider + .get("double updowncounter") + .upDownCounterBuilder("doubleupdown") + .ofDoubles() + .build(); + doubleUpDownCounter.add(1.0); + doubleUpDownCounter.add(-1.0); + }))), + arguments( + named( + "double histogram", + metrics( + meterProvider -> { + DoubleHistogram histogram = + meterProvider + .get("double histogram") + .histogramBuilder("histogram") + .build(); + histogram.record(1.0); + histogram.record(2.0); + histogram.record(3.0); + histogram.record(4.0); + histogram.record(5.0); + }))), + arguments( + named( + "long histogram", + metrics( + meterProvider -> { + LongHistogram histogram = + meterProvider + .get("long histogram") + .histogramBuilder("histogram") + .ofLongs() + .build(); + histogram.record(1); + histogram.record(2); + histogram.record(3); + histogram.record(4); + histogram.record(5); + }))), + arguments( + named( + "double exponential histogram", + metrics( + meterProvider -> { + DoubleHistogram histogram = + meterProvider + .get("double exponential histogram") + .histogramBuilder("exponentialhistogram") + .build(); + histogram.record(1.0); + histogram.record(2.0); + histogram.record(3.0); + histogram.record(4.0); + histogram.record(5.0); + }))), + arguments( + named( + "long exponential histogram", + metrics( + meterProvider -> { + DoubleHistogram histogram = + meterProvider + .get("long exponential histogram") + .histogramBuilder("exponentialhistogram") + .build(); + histogram.record(1); + histogram.record(2); + histogram.record(3); + histogram.record(4); + histogram.record(5); + })))); + } + } + + private static class ExemplarProvider implements ArgumentsProvider { + @Override + public Stream provideArguments(ExtensionContext context) { + SpanContext spanContext = + SpanContext.create( + "7b2e170db4df2d593ddb4ddf2ddf2d59", + "170d3ddb4d23e81f", + TraceFlags.getSampled(), + TraceState.getDefault()); + + return Stream.of( + arguments( + named( + "double exemplar", + ImmutableDoubleExemplarData.create(Attributes.empty(), 12345, spanContext, 5.0))), + arguments( + named( + "long exemplar", + ImmutableLongExemplarData.create(Attributes.empty(), 12345, spanContext, 5)))); + } + } +} diff --git a/exporters/otlp/common/src/test/java/io/opentelemetry/exporter/internal/otlp/metrics/MetricsRequestMarshalerTest.java b/exporters/otlp/common/src/test/java/io/opentelemetry/exporter/internal/otlp/metrics/MetricsRequestMarshalerTest.java index 2e0de0ac239..e2f6563b942 100644 --- a/exporters/otlp/common/src/test/java/io/opentelemetry/exporter/internal/otlp/metrics/MetricsRequestMarshalerTest.java +++ b/exporters/otlp/common/src/test/java/io/opentelemetry/exporter/internal/otlp/metrics/MetricsRequestMarshalerTest.java @@ -22,6 +22,9 @@ import io.opentelemetry.api.trace.TraceFlags; import io.opentelemetry.api.trace.TraceState; import io.opentelemetry.exporter.internal.marshal.Marshaler; +import io.opentelemetry.exporter.internal.marshal.MarshalerContext; +import io.opentelemetry.exporter.internal.marshal.Serializer; +import io.opentelemetry.exporter.internal.marshal.StatelessMarshaler; import io.opentelemetry.proto.collector.metrics.v1.ExportMetricsServiceRequest; import io.opentelemetry.proto.common.v1.AnyValue; import io.opentelemetry.proto.common.v1.InstrumentationScope; @@ -75,7 +78,8 @@ import java.util.List; import java.util.Locale; import java.util.stream.Collectors; -import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.EnumSource; // Fill deprecated APIs before removing them after users get a chance to migrate. class MetricsRequestMarshalerTest { @@ -86,10 +90,12 @@ private static AnyValue stringValue(String v) { return AnyValue.newBuilder().setStringValue(v).build(); } - @Test - void dataPoint_withDefaultValues() { + @ParameterizedTest + @EnumSource(MarshalerSource.class) + void dataPoint_withDefaultValues(MarshalerSource marshalerSource) { assertThat( toNumberDataPoints( + marshalerSource, singletonList( ImmutableLongPointData.create( 123, @@ -132,6 +138,7 @@ void dataPoint_withDefaultValues() { assertThat( toNumberDataPoints( + marshalerSource, singletonList( ImmutableDoublePointData.create( 123, @@ -173,11 +180,13 @@ void dataPoint_withDefaultValues() { .build()); } - @Test - void longDataPoints() { - assertThat(toNumberDataPoints(Collections.emptyList())).isEmpty(); + @ParameterizedTest + @EnumSource(MarshalerSource.class) + void longDataPoints(MarshalerSource marshalerSource) { + assertThat(toNumberDataPoints(marshalerSource, Collections.emptyList())).isEmpty(); assertThat( toNumberDataPoints( + marshalerSource, singletonList( ImmutableLongPointData.create( 123, @@ -219,6 +228,7 @@ void longDataPoints() { .build()); assertThat( toNumberDataPoints( + marshalerSource, ImmutableList.of( ImmutableLongPointData.create(123, 456, Attributes.empty(), 5), ImmutableLongPointData.create(321, 654, KV_ATTR, 7)))) @@ -238,11 +248,13 @@ void longDataPoints() { .build()); } - @Test - void doubleDataPoints() { - assertThat(toNumberDataPoints(Collections.emptyList())).isEmpty(); + @ParameterizedTest + @EnumSource(MarshalerSource.class) + void doubleDataPoints(MarshalerSource marshalerSource) { + assertThat(toNumberDataPoints(marshalerSource, Collections.emptyList())).isEmpty(); assertThat( toNumberDataPoints( + marshalerSource, singletonList(ImmutableDoublePointData.create(123, 456, KV_ATTR, 5.1)))) .containsExactly( NumberDataPoint.newBuilder() @@ -255,6 +267,7 @@ void doubleDataPoints() { .build()); assertThat( toNumberDataPoints( + marshalerSource, ImmutableList.of( ImmutableDoublePointData.create(123, 456, Attributes.empty(), 5.1), ImmutableDoublePointData.create(321, 654, KV_ATTR, 7.1)))) @@ -274,10 +287,12 @@ void doubleDataPoints() { .build()); } - @Test - void summaryDataPoints() { + @ParameterizedTest + @EnumSource(MarshalerSource.class) + void summaryDataPoints(MarshalerSource marshalerSource) { assertThat( toSummaryDataPoints( + marshalerSource, singletonList( ImmutableSummaryPointData.create( 123, @@ -303,6 +318,7 @@ void summaryDataPoints() { .build()); assertThat( toSummaryDataPoints( + marshalerSource, ImmutableList.of( ImmutableSummaryPointData.create( 123, 456, Attributes.empty(), 7, 15.3, Collections.emptyList()), @@ -343,10 +359,12 @@ void summaryDataPoints() { .build()); } - @Test - void histogramDataPoints() { + @ParameterizedTest + @EnumSource(MarshalerSource.class) + void histogramDataPoints(MarshalerSource marshalerSource) { assertThat( toHistogramDataPoints( + marshalerSource, ImmutableList.of( ImmutableHistogramPointData.create( 123, @@ -418,10 +436,12 @@ void histogramDataPoints() { .build()); } - @Test - void exponentialHistogramDataPoints() { + @ParameterizedTest + @EnumSource(MarshalerSource.class) + void exponentialHistogramDataPoints(MarshalerSource marshalerSource) { assertThat( toExponentialHistogramDataPoints( + marshalerSource, ImmutableList.of( ImmutableExponentialHistogramPointData.create( 0, @@ -512,10 +532,12 @@ void exponentialHistogramDataPoints() { } @SuppressWarnings("PointlessArithmeticExpression") - @Test - void exponentialHistogramReusableDataPoints() { + @ParameterizedTest + @EnumSource(MarshalerSource.class) + void exponentialHistogramReusableDataPoints(MarshalerSource marshalerSource) { assertThat( toExponentialHistogramDataPoints( + marshalerSource, ImmutableList.of( new MutableExponentialHistogramPointData() .set( @@ -610,10 +632,12 @@ void exponentialHistogramReusableDataPoints() { .build()); } - @Test - void toProtoMetric_monotonic() { + @ParameterizedTest + @EnumSource(MarshalerSource.class) + void toProtoMetric_monotonic(MarshalerSource marshalerSource) { assertThat( toProtoMetric( + marshalerSource, ImmutableMetricData.createLongSum( Resource.empty(), InstrumentationScopeInfo.empty(), @@ -649,6 +673,7 @@ void toProtoMetric_monotonic() { .build()); assertThat( toProtoMetric( + marshalerSource, ImmutableMetricData.createDoubleSum( Resource.empty(), InstrumentationScopeInfo.empty(), @@ -684,10 +709,12 @@ void toProtoMetric_monotonic() { .build()); } - @Test - void toProtoMetric_nonMonotonic() { + @ParameterizedTest + @EnumSource(MarshalerSource.class) + void toProtoMetric_nonMonotonic(MarshalerSource marshalerSource) { assertThat( toProtoMetric( + marshalerSource, ImmutableMetricData.createLongSum( Resource.empty(), InstrumentationScopeInfo.empty(), @@ -723,6 +750,7 @@ void toProtoMetric_nonMonotonic() { .build()); assertThat( toProtoMetric( + marshalerSource, ImmutableMetricData.createDoubleSum( Resource.empty(), InstrumentationScopeInfo.empty(), @@ -758,10 +786,12 @@ void toProtoMetric_nonMonotonic() { .build()); } - @Test - void toProtoMetric_gauges() { + @ParameterizedTest + @EnumSource(MarshalerSource.class) + void toProtoMetric_gauges(MarshalerSource marshalerSource) { assertThat( toProtoMetric( + marshalerSource, ImmutableMetricData.createLongGauge( Resource.empty(), InstrumentationScopeInfo.empty(), @@ -793,6 +823,7 @@ void toProtoMetric_gauges() { .build()); assertThat( toProtoMetric( + marshalerSource, ImmutableMetricData.createDoubleGauge( Resource.empty(), InstrumentationScopeInfo.empty(), @@ -824,10 +855,12 @@ void toProtoMetric_gauges() { .build()); } - @Test - void toProtoMetric_summary() { + @ParameterizedTest + @EnumSource(MarshalerSource.class) + void toProtoMetric_summary(MarshalerSource marshalerSource) { assertThat( toProtoMetric( + marshalerSource, ImmutableMetricData.createDoubleSummary( Resource.empty(), InstrumentationScopeInfo.empty(), @@ -879,10 +912,12 @@ void toProtoMetric_summary() { .build()); } - @Test - void toProtoMetric_histogram() { + @ParameterizedTest + @EnumSource(MarshalerSource.class) + void toProtoMetric_histogram(MarshalerSource marshalerSource) { assertThat( toProtoMetric( + marshalerSource, ImmutableMetricData.createDoubleHistogram( Resource.empty(), InstrumentationScopeInfo.empty(), @@ -931,10 +966,12 @@ void toProtoMetric_histogram() { .build()); } - @Test - void toProtoMetric_exponentialHistogram() { + @ParameterizedTest + @EnumSource(MarshalerSource.class) + void toProtoMetric_exponentialHistogram(MarshalerSource marshalerSource) { assertThat( toProtoMetric( + marshalerSource, ImmutableMetricData.createExponentialHistogram( Resource.empty(), InstrumentationScopeInfo.empty(), @@ -1001,8 +1038,9 @@ void toProtoMetric_exponentialHistogram() { .build()); } - @Test - void protoResourceMetrics() { + @ParameterizedTest + @EnumSource(MarshalerSource.class) + void protoResourceMetrics(MarshalerSource marshalerSource) { Resource resource = Resource.create(Attributes.of(stringKey("ka"), "va"), "http://resource.url"); io.opentelemetry.proto.resource.v1.Resource resourceProto = @@ -1057,6 +1095,7 @@ void protoResourceMetrics() { assertThat( toProtoResourceMetrics( + marshalerSource, ImmutableList.of( ImmutableMetricData.createDoubleSum( resource, @@ -1130,55 +1169,48 @@ void protoResourceMetrics() { }); } - private static List toNumberDataPoints(Collection points) { + private static List toNumberDataPoints( + MarshalerSource marshalerSource, Collection points) { return points.stream() - .map( - point -> - parse(NumberDataPoint.getDefaultInstance(), NumberDataPointMarshaler.create(point))) + .map(point -> parse(NumberDataPoint.getDefaultInstance(), marshalerSource.create(point))) .collect(Collectors.toList()); } - private static List toSummaryDataPoints(Collection points) { + private static List toSummaryDataPoints( + MarshalerSource marshalerSource, Collection points) { return points.stream() - .map( - point -> - parse( - SummaryDataPoint.getDefaultInstance(), SummaryDataPointMarshaler.create(point))) + .map(point -> parse(SummaryDataPoint.getDefaultInstance(), marshalerSource.create(point))) .collect(Collectors.toList()); } private static List toHistogramDataPoints( - Collection points) { + MarshalerSource marshalerSource, Collection points) { return points.stream() - .map( - point -> - parse( - HistogramDataPoint.getDefaultInstance(), - HistogramDataPointMarshaler.create(point))) + .map(point -> parse(HistogramDataPoint.getDefaultInstance(), marshalerSource.create(point))) .collect(Collectors.toList()); } private static List toExponentialHistogramDataPoints( - Collection points) { + MarshalerSource marshalerSource, Collection points) { return points.stream() .map( point -> parse( ExponentialHistogramDataPoint.getDefaultInstance(), - ExponentialHistogramDataPointMarshaler.create(point))) + marshalerSource.create(point))) .collect(Collectors.toList()); } - private static Metric toProtoMetric(MetricData metricData) { - return parse(Metric.getDefaultInstance(), MetricMarshaler.create(metricData)); + private static Metric toProtoMetric(MarshalerSource marshalerSource, MetricData metricData) { + return parse(Metric.getDefaultInstance(), marshalerSource.create(metricData)); } private static List toProtoResourceMetrics( - Collection metricDataList) { + MarshalerSource marshalerSource, Collection metricDataList) { ExportMetricsServiceRequest exportRequest = parse( ExportMetricsServiceRequest.getDefaultInstance(), - MetricsRequestMarshaler.create(metricDataList)); + marshalerSource.create(metricDataList)); return exportRequest.getResourceMetricsList(); } @@ -1264,4 +1296,101 @@ private static String toJson(Marshaler marshaler) { } return new String(bos.toByteArray(), StandardCharsets.UTF_8); } + + private static Marshaler createMarshaler(StatelessMarshaler marshaler, T data) { + return new Marshaler() { + private final MarshalerContext context = new MarshalerContext(); + private final int size = marshaler.getBinarySerializedSize(data, context); + + @Override + public int getBinarySerializedSize() { + return size; + } + + @Override + protected void writeTo(Serializer output) throws IOException { + context.resetReadIndex(); + marshaler.writeTo(output, data, context); + } + }; + } + + private enum MarshalerSource { + STATEFUL_MARSHALER { + @Override + Marshaler create(PointData point) { + return NumberDataPointMarshaler.create(point); + } + + @Override + Marshaler create(SummaryPointData point) { + return SummaryDataPointMarshaler.create(point); + } + + @Override + Marshaler create(HistogramPointData point) { + return HistogramDataPointMarshaler.create(point); + } + + @Override + Marshaler create(ExponentialHistogramPointData point) { + return ExponentialHistogramDataPointMarshaler.create(point); + } + + @Override + Marshaler create(MetricData metric) { + return MetricMarshaler.create(metric); + } + + @Override + Marshaler create(Collection metricDataList) { + return MetricsRequestMarshaler.create(metricDataList); + } + }, + STATELESS_MARSHALER { + @Override + Marshaler create(PointData point) { + return createMarshaler(NumberDataPointStatelessMarshaler.INSTANCE, point); + } + + @Override + Marshaler create(SummaryPointData point) { + return createMarshaler(SummaryDataPointStatelessMarshaler.INSTANCE, point); + } + + @Override + Marshaler create(HistogramPointData point) { + return createMarshaler(HistogramDataPointStatelessMarshaler.INSTANCE, point); + } + + @Override + Marshaler create(ExponentialHistogramPointData point) { + return createMarshaler(ExponentialHistogramDataPointStatelessMarshaler.INSTANCE, point); + } + + @Override + Marshaler create(MetricData metric) { + return createMarshaler(MetricStatelessMarshaler.INSTANCE, metric); + } + + @Override + Marshaler create(Collection metricDataList) { + LowAllocationMetricsRequestMarshaler marshaler = new LowAllocationMetricsRequestMarshaler(); + marshaler.initialize(metricDataList); + return marshaler; + } + }; + + abstract Marshaler create(PointData point); + + abstract Marshaler create(SummaryPointData point); + + abstract Marshaler create(HistogramPointData point); + + abstract Marshaler create(ExponentialHistogramPointData point); + + abstract Marshaler create(MetricData metric); + + abstract Marshaler create(Collection metricDataList); + } } diff --git a/exporters/otlp/common/src/test/java/io/opentelemetry/exporter/internal/otlp/traces/TraceRequestMarshalerTest.java b/exporters/otlp/common/src/test/java/io/opentelemetry/exporter/internal/otlp/traces/TraceRequestMarshalerTest.java index 464a6f0433a..9e00b634783 100644 --- a/exporters/otlp/common/src/test/java/io/opentelemetry/exporter/internal/otlp/traces/TraceRequestMarshalerTest.java +++ b/exporters/otlp/common/src/test/java/io/opentelemetry/exporter/internal/otlp/traces/TraceRequestMarshalerTest.java @@ -536,7 +536,7 @@ protected void writeTo(Serializer output) throws IOException { } private enum MarshalerSource { - MARSHALER { + STATEFUL_MARSHALER { @Override Marshaler create(SpanData spanData) { return SpanMarshaler.create(spanData); @@ -557,7 +557,7 @@ Marshaler create(LinkData linkData) { return SpanLinkMarshaler.create(linkData); } }, - LOW_ALLOCATION_MARSHALER { + STATELESS_MARSHALER { @Override Marshaler create(SpanData spanData) { return createMarshaler(SpanStatelessMarshaler.INSTANCE, spanData); From 2454765174c4049c347152e330cc6efc8907d107 Mon Sep 17 00:00:00 2001 From: Lauri Tulmin Date: Tue, 7 May 2024 17:56:53 +0300 Subject: [PATCH 387/901] Add private constructors for stateless marshalers (#6434) --- .../exporter/internal/otlp/BoolAnyValueStatelessMarshaler.java | 2 ++ .../internal/otlp/DoubleAnyValueStatelessMarshaler.java | 2 ++ .../exporter/internal/otlp/IntAnyValueStatelessMarshaler.java | 2 ++ .../internal/otlp/StringAnyValueStatelessMarshaler.java | 2 ++ .../traces/InstrumentationScopeSpansStatelessMarshaler.java | 2 ++ .../internal/otlp/traces/ResourceSpansStatelessMarshaler.java | 2 ++ .../internal/otlp/traces/SpanEventStatelessMarshaler.java | 2 ++ .../internal/otlp/traces/SpanLinkStatelessMarshaler.java | 2 ++ .../exporter/internal/otlp/traces/SpanStatelessMarshaler.java | 2 ++ .../internal/otlp/traces/SpanStatusStatelessMarshaler.java | 2 ++ 10 files changed, 20 insertions(+) diff --git a/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/BoolAnyValueStatelessMarshaler.java b/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/BoolAnyValueStatelessMarshaler.java index da05b557c8f..950aaa39f7d 100644 --- a/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/BoolAnyValueStatelessMarshaler.java +++ b/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/BoolAnyValueStatelessMarshaler.java @@ -16,6 +16,8 @@ final class BoolAnyValueStatelessMarshaler implements StatelessMarshaler { static final BoolAnyValueStatelessMarshaler INSTANCE = new BoolAnyValueStatelessMarshaler(); + private BoolAnyValueStatelessMarshaler() {} + @Override public void writeTo(Serializer output, Boolean value, MarshalerContext context) throws IOException { diff --git a/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/DoubleAnyValueStatelessMarshaler.java b/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/DoubleAnyValueStatelessMarshaler.java index 879116d3f0f..7403b241ab2 100644 --- a/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/DoubleAnyValueStatelessMarshaler.java +++ b/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/DoubleAnyValueStatelessMarshaler.java @@ -16,6 +16,8 @@ final class DoubleAnyValueStatelessMarshaler implements StatelessMarshaler { static final DoubleAnyValueStatelessMarshaler INSTANCE = new DoubleAnyValueStatelessMarshaler(); + private DoubleAnyValueStatelessMarshaler() {} + @Override public void writeTo(Serializer output, Double value, MarshalerContext context) throws IOException { diff --git a/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/IntAnyValueStatelessMarshaler.java b/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/IntAnyValueStatelessMarshaler.java index c1b97dd02a4..407a586ec80 100644 --- a/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/IntAnyValueStatelessMarshaler.java +++ b/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/IntAnyValueStatelessMarshaler.java @@ -16,6 +16,8 @@ final class IntAnyValueStatelessMarshaler implements StatelessMarshaler { static final IntAnyValueStatelessMarshaler INSTANCE = new IntAnyValueStatelessMarshaler(); + private IntAnyValueStatelessMarshaler() {} + @Override public void writeTo(Serializer output, Long value, MarshalerContext context) throws IOException { output.writeInt64(AnyValue.INT_VALUE, value); diff --git a/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/StringAnyValueStatelessMarshaler.java b/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/StringAnyValueStatelessMarshaler.java index 59924ae4dbc..9d9af0b5d0c 100644 --- a/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/StringAnyValueStatelessMarshaler.java +++ b/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/StringAnyValueStatelessMarshaler.java @@ -21,6 +21,8 @@ final class StringAnyValueStatelessMarshaler implements StatelessMarshaler { static final StringAnyValueStatelessMarshaler INSTANCE = new StringAnyValueStatelessMarshaler(); + private StringAnyValueStatelessMarshaler() {} + @Override public void writeTo(Serializer output, String value, MarshalerContext context) throws IOException { diff --git a/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/traces/InstrumentationScopeSpansStatelessMarshaler.java b/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/traces/InstrumentationScopeSpansStatelessMarshaler.java index 7bfdcb75adb..decec18ea79 100644 --- a/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/traces/InstrumentationScopeSpansStatelessMarshaler.java +++ b/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/traces/InstrumentationScopeSpansStatelessMarshaler.java @@ -23,6 +23,8 @@ final class InstrumentationScopeSpansStatelessMarshaler static final InstrumentationScopeSpansStatelessMarshaler INSTANCE = new InstrumentationScopeSpansStatelessMarshaler(); + private InstrumentationScopeSpansStatelessMarshaler() {} + @Override public void writeTo( Serializer output, diff --git a/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/traces/ResourceSpansStatelessMarshaler.java b/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/traces/ResourceSpansStatelessMarshaler.java index de2aa078f0e..7ae30feb91d 100644 --- a/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/traces/ResourceSpansStatelessMarshaler.java +++ b/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/traces/ResourceSpansStatelessMarshaler.java @@ -31,6 +31,8 @@ public final class ResourceSpansStatelessMarshaler private static final MarshalerContext.Key SCOPE_SPAN_WRITER_KEY = MarshalerContext.key(); private static final MarshalerContext.Key SCOPE_SPAN_SIZE_CALCULATOR_KEY = MarshalerContext.key(); + private ResourceSpansStatelessMarshaler() {} + @Override public void writeTo( Serializer output, diff --git a/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/traces/SpanEventStatelessMarshaler.java b/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/traces/SpanEventStatelessMarshaler.java index ef09f065749..491b8d44c30 100644 --- a/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/traces/SpanEventStatelessMarshaler.java +++ b/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/traces/SpanEventStatelessMarshaler.java @@ -19,6 +19,8 @@ final class SpanEventStatelessMarshaler implements StatelessMarshaler { static final SpanEventStatelessMarshaler INSTANCE = new SpanEventStatelessMarshaler(); + private SpanEventStatelessMarshaler() {} + @Override public void writeTo(Serializer output, EventData event, MarshalerContext context) throws IOException { diff --git a/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/traces/SpanLinkStatelessMarshaler.java b/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/traces/SpanLinkStatelessMarshaler.java index 2b711d8e96c..0ed091096de 100644 --- a/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/traces/SpanLinkStatelessMarshaler.java +++ b/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/traces/SpanLinkStatelessMarshaler.java @@ -21,6 +21,8 @@ final class SpanLinkStatelessMarshaler implements StatelessMarshaler { static final SpanLinkStatelessMarshaler INSTANCE = new SpanLinkStatelessMarshaler(); + private SpanLinkStatelessMarshaler() {} + @Override public void writeTo(Serializer output, LinkData link, MarshalerContext context) throws IOException { diff --git a/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/traces/SpanStatelessMarshaler.java b/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/traces/SpanStatelessMarshaler.java index 80703cf628d..40adefd143d 100644 --- a/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/traces/SpanStatelessMarshaler.java +++ b/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/traces/SpanStatelessMarshaler.java @@ -22,6 +22,8 @@ final class SpanStatelessMarshaler implements StatelessMarshaler { static final SpanStatelessMarshaler INSTANCE = new SpanStatelessMarshaler(); + private SpanStatelessMarshaler() {} + @Override public void writeTo(Serializer output, SpanData span, MarshalerContext context) throws IOException { diff --git a/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/traces/SpanStatusStatelessMarshaler.java b/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/traces/SpanStatusStatelessMarshaler.java index ba37729d636..0609c0e6829 100644 --- a/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/traces/SpanStatusStatelessMarshaler.java +++ b/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/traces/SpanStatusStatelessMarshaler.java @@ -21,6 +21,8 @@ final class SpanStatusStatelessMarshaler implements StatelessMarshaler { static final SpanStatusStatelessMarshaler INSTANCE = new SpanStatusStatelessMarshaler(); + private SpanStatusStatelessMarshaler() {} + @Override public void writeTo(Serializer output, StatusData status, MarshalerContext context) throws IOException { From 2e746690a904a629e6e37aa4b2220b75dfe91b92 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 7 May 2024 08:22:33 -0700 Subject: [PATCH 388/901] Update dependency org.jetbrains.kotlin:kotlin-gradle-plugin to v1.9.24 (#6435) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- buildSrc/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts index eae3657671a..67daf216b29 100644 --- a/buildSrc/build.gradle.kts +++ b/buildSrc/build.gradle.kts @@ -65,7 +65,7 @@ dependencies { implementation("me.champeau.jmh:jmh-gradle-plugin:0.7.2") implementation("net.ltgt.gradle:gradle-errorprone-plugin:3.1.0") implementation("net.ltgt.gradle:gradle-nullaway-plugin:2.0.0") - implementation("org.jetbrains.kotlin:kotlin-gradle-plugin:1.9.23") + implementation("org.jetbrains.kotlin:kotlin-gradle-plugin:1.9.24") implementation("org.owasp:dependency-check-gradle:9.1.0") implementation("ru.vyarus:gradle-animalsniffer-plugin:1.7.1") } From a745d60e8d78f051f3ceb4ccbf2c9a6016e57986 Mon Sep 17 00:00:00 2001 From: John Bley Date: Tue, 7 May 2024 11:42:15 -0400 Subject: [PATCH 389/901] Use standard ArrayList size rather than max number of links for initial span links allocation (#6252) --- .../io/opentelemetry/sdk/trace/SdkSpan.java | 2 +- .../opentelemetry/sdk/trace/SdkSpanTest.java | 41 +++++++++++++++++++ 2 files changed, 42 insertions(+), 1 deletion(-) diff --git a/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/SdkSpan.java b/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/SdkSpan.java index e70359aa46d..5011b5a3d7d 100644 --- a/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/SdkSpan.java +++ b/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/SdkSpan.java @@ -468,7 +468,7 @@ public Span addLink(SpanContext spanContext, Attributes attributes) { return this; } if (links == null) { - links = new ArrayList<>(spanLimits.getMaxNumberOfLinks()); + links = new ArrayList<>(); } if (links.size() < spanLimits.getMaxNumberOfLinks()) { links.add(link); diff --git a/sdk/trace/src/test/java/io/opentelemetry/sdk/trace/SdkSpanTest.java b/sdk/trace/src/test/java/io/opentelemetry/sdk/trace/SdkSpanTest.java index 13defbdca82..df56d05a07e 100644 --- a/sdk/trace/src/test/java/io/opentelemetry/sdk/trace/SdkSpanTest.java +++ b/sdk/trace/src/test/java/io/opentelemetry/sdk/trace/SdkSpanTest.java @@ -15,6 +15,7 @@ import static io.opentelemetry.api.common.AttributeKey.stringKey; import static java.util.stream.Collectors.joining; import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatCode; import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.never; @@ -911,6 +912,46 @@ void addLink() { } } + @Test + void addLink_InvalidArgs() { + SdkSpan span = createTestSpan(SpanKind.INTERNAL); + assertThatCode(() -> span.addLink(null)).doesNotThrowAnyException(); + assertThatCode(() -> span.addLink(SpanContext.getInvalid())).doesNotThrowAnyException(); + assertThatCode(() -> span.addLink(null, null)).doesNotThrowAnyException(); + assertThatCode(() -> span.addLink(SpanContext.getInvalid(), Attributes.empty())) + .doesNotThrowAnyException(); + } + + @Test + void addLink_FaultIn() { + SdkSpan span = + SdkSpan.startSpan( + spanContext, + SPAN_NAME, + instrumentationScopeInfo, + SpanKind.INTERNAL, + Span.getInvalid(), + Context.root(), + SpanLimits.getDefault(), + spanProcessor, + testClock, + resource, + null, + null, // exercises the fault-in path + 0, + 0); + SdkSpan linkedSpan = createTestSpan(SpanKind.INTERNAL); + span.addLink(linkedSpan.getSpanContext()); + + SpanData spanData = span.toSpanData(); + assertThat(spanData.getTotalRecordedLinks()).isEqualTo(1); + assertThat(spanData.getLinks()) + .satisfiesExactly( + link -> { + assertThat(link.getSpanContext()).isEqualTo(linkedSpan.getSpanContext()); + }); + } + @Test void droppingAttributes() { int maxNumberOfAttributes = 8; From af46b5e4a9824f080717e175abec884827c20b48 Mon Sep 17 00:00:00 2001 From: oliver zhang Date: Thu, 9 May 2024 22:42:45 +0800 Subject: [PATCH 390/901] change variable name (#6439) --- .../java/io/opentelemetry/sdk/trace/MultiSpanProcessor.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/MultiSpanProcessor.java b/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/MultiSpanProcessor.java index 705351e83f5..a06b4b69579 100644 --- a/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/MultiSpanProcessor.java +++ b/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/MultiSpanProcessor.java @@ -35,9 +35,9 @@ static SpanProcessor create(List spanProcessorList) { } @Override - public void onStart(Context parentContext, ReadWriteSpan readableSpan) { + public void onStart(Context parentContext, ReadWriteSpan readWriteSpan) { for (SpanProcessor spanProcessor : spanProcessorsStart) { - spanProcessor.onStart(parentContext, readableSpan); + spanProcessor.onStart(parentContext, readWriteSpan); } } From 417f82c3ca24defe833aa9ca43522d586dc464ff Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 9 May 2024 07:54:45 -0700 Subject: [PATCH 391/901] Update dependency org.testcontainers:testcontainers-bom to v1.19.8 (#6437) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- dependencyManagement/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index 146a71a2787..8ee8f2c535e 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -20,7 +20,7 @@ val DEPENDENCY_BOMS = listOf( "io.zipkin.reporter2:zipkin-reporter-bom:3.4.0", "org.assertj:assertj-bom:3.25.3", "org.junit:junit-bom:5.10.2", - "org.testcontainers:testcontainers-bom:1.19.7", + "org.testcontainers:testcontainers-bom:1.19.8", "org.snakeyaml:snakeyaml-engine:2.7" ) From 529730606442c0be1472e070f163e9e40c07a99f Mon Sep 17 00:00:00 2001 From: jack-berg <34418638+jack-berg@users.noreply.github.com> Date: Thu, 9 May 2024 10:34:51 -0500 Subject: [PATCH 392/901] Add Lauri to approvers (#6440) --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index e81854004ac..87fd636d2c7 100644 --- a/README.md +++ b/README.md @@ -304,6 +304,7 @@ Approvers ([@open-telemetry/java-approvers](https://github.com/orgs/open-telemet - [Jason Plumb](https://github.com/breedx-splk), Splunk - [Josh Suereth](https://github.com/jsuereth), Google +- [Lauri Tulmin](https://github.com/laurit), Splunk - [Trask Stalnaker](https://github.com/trask), Microsoft *Find more about the approver role in [community repository](https://github.com/open-telemetry/community/blob/master/community-membership.md#approver).* From 715211e98b65c21a2d0ef74d8113f297ece430b0 Mon Sep 17 00:00:00 2001 From: jack-berg <34418638+jack-berg@users.noreply.github.com> Date: Thu, 9 May 2024 10:47:14 -0500 Subject: [PATCH 393/901] Low allocation OTLP logs marshaler (#6429) --- .../otlp/LogsRequestMarshalerBenchmark.java | 148 ++++++++++++++++++ .../otlp/AnyValueStatelessMarshaler.java | 110 +++++++++++++ .../otlp/ArrayAnyValueStatelessMarshaler.java | 80 ++-------- ...ributeArrayAnyValueStatelessMarshaler.java | 89 +++++++++++ .../AttributeKeyValueStatelessMarshaler.java | 145 +++++++++++++++++ .../otlp/BytesAnyValueStatelessMarshaler.java | 36 +++++ ...eyValueListAnyValueStatelessMarshaler.java | 38 +++++ .../otlp/KeyValueStatelessMarshaler.java | 128 +++------------ .../otlp/StringAnyValueMarshaler.java | 8 +- ...umentationScopeLogsStatelessMarshaler.java | 63 ++++++++ .../otlp/logs/LogStatelessMarshaler.java | 147 +++++++++++++++++ .../LowAllocationLogsRequestMarshaler.java | 107 +++++++++++++ .../logs/ResourceLogsStatelessMarshaler.java | 80 ++++++++++ .../traces/SpanEventStatelessMarshaler.java | 9 +- .../traces/SpanLinkStatelessMarshaler.java | 9 +- .../otlp/traces/SpanStatelessMarshaler.java | 12 +- .../internal/otlp/AnyValueMarshalerTest.java | 32 +++- .../otlp/logs/LogsRequestMarshalerTest.java | 57 ++++++- .../LowAllocationLogRequestMarshalerTest.java | 142 +++++++++++++++++ 19 files changed, 1245 insertions(+), 195 deletions(-) create mode 100644 exporters/otlp/common/src/jmh/java/io/opentelemetry/exporter/internal/otlp/LogsRequestMarshalerBenchmark.java create mode 100644 exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/AnyValueStatelessMarshaler.java create mode 100644 exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/AttributeArrayAnyValueStatelessMarshaler.java create mode 100644 exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/AttributeKeyValueStatelessMarshaler.java create mode 100644 exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/BytesAnyValueStatelessMarshaler.java create mode 100644 exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/KeyValueListAnyValueStatelessMarshaler.java create mode 100644 exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/logs/InstrumentationScopeLogsStatelessMarshaler.java create mode 100644 exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/logs/LogStatelessMarshaler.java create mode 100644 exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/logs/LowAllocationLogsRequestMarshaler.java create mode 100644 exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/logs/ResourceLogsStatelessMarshaler.java create mode 100644 exporters/otlp/common/src/test/java/io/opentelemetry/exporter/internal/otlp/logs/LowAllocationLogRequestMarshalerTest.java diff --git a/exporters/otlp/common/src/jmh/java/io/opentelemetry/exporter/internal/otlp/LogsRequestMarshalerBenchmark.java b/exporters/otlp/common/src/jmh/java/io/opentelemetry/exporter/internal/otlp/LogsRequestMarshalerBenchmark.java new file mode 100644 index 00000000000..289f6f77845 --- /dev/null +++ b/exporters/otlp/common/src/jmh/java/io/opentelemetry/exporter/internal/otlp/LogsRequestMarshalerBenchmark.java @@ -0,0 +1,148 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.exporter.internal.otlp; + +import io.opentelemetry.api.common.AttributeKey; +import io.opentelemetry.api.common.Attributes; +import io.opentelemetry.api.incubator.events.EventLogger; +import io.opentelemetry.api.incubator.logs.AnyValue; +import io.opentelemetry.api.logs.Logger; +import io.opentelemetry.api.logs.Severity; +import io.opentelemetry.exporter.internal.otlp.logs.LogsRequestMarshaler; +import io.opentelemetry.exporter.internal.otlp.logs.LowAllocationLogsRequestMarshaler; +import io.opentelemetry.sdk.logs.SdkLoggerProvider; +import io.opentelemetry.sdk.logs.data.LogRecordData; +import io.opentelemetry.sdk.logs.export.SimpleLogRecordProcessor; +import io.opentelemetry.sdk.logs.internal.SdkEventLoggerProvider; +import io.opentelemetry.sdk.resources.Resource; +import io.opentelemetry.sdk.testing.exporter.InMemoryLogRecordExporter; +import java.io.IOException; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.concurrent.TimeUnit; +import org.openjdk.jmh.annotations.Benchmark; +import org.openjdk.jmh.annotations.BenchmarkMode; +import org.openjdk.jmh.annotations.Fork; +import org.openjdk.jmh.annotations.Measurement; +import org.openjdk.jmh.annotations.Mode; +import org.openjdk.jmh.annotations.OutputTimeUnit; +import org.openjdk.jmh.annotations.Warmup; + +@BenchmarkMode({Mode.AverageTime}) +@OutputTimeUnit(TimeUnit.MICROSECONDS) +@Warmup(iterations = 5, time = 1) +@Measurement(iterations = 10, time = 1) +@Fork(1) +public class LogsRequestMarshalerBenchmark { + + private static final Collection LOGS; + private static final LowAllocationLogsRequestMarshaler MARSHALER = + new LowAllocationLogsRequestMarshaler(); + private static final TestOutputStream OUTPUT = new TestOutputStream(); + + static { + InMemoryLogRecordExporter logRecordExporter = InMemoryLogRecordExporter.create(); + SdkLoggerProvider loggerProvider = + SdkLoggerProvider.builder() + .setResource( + Resource.create( + Attributes.builder() + .put(AttributeKey.booleanKey("key_bool"), true) + .put(AttributeKey.stringKey("key_string"), "string") + .put(AttributeKey.longKey("key_int"), 100L) + .put(AttributeKey.doubleKey("key_double"), 100.3) + .put( + AttributeKey.stringArrayKey("key_string_array"), + Arrays.asList("string", "string")) + .put(AttributeKey.longArrayKey("key_long_array"), Arrays.asList(12L, 23L)) + .put( + AttributeKey.doubleArrayKey("key_double_array"), + Arrays.asList(12.3, 23.1)) + .put( + AttributeKey.booleanArrayKey("key_boolean_array"), + Arrays.asList(true, false)) + .build())) + .addLogRecordProcessor(SimpleLogRecordProcessor.create(logRecordExporter)) + .build(); + + Logger logger1 = loggerProvider.get("logger"); + logger1 + .logRecordBuilder() + .setBody("Hello world from this log...") + .setAllAttributes( + Attributes.builder() + .put("key_bool", true) + .put("key_String", "string") + .put("key_int", 100L) + .put("key_double", 100.3) + .build()) + .setSeverity(Severity.INFO) + .setSeverityText("INFO") + .emit(); + + SdkEventLoggerProvider eventLoggerProvider = SdkEventLoggerProvider.create(loggerProvider); + EventLogger eventLogger = eventLoggerProvider.get("event-logger"); + eventLogger + .builder("namespace.my-event-name") + // Helper methods to set primitive types + .put("stringKey", "value") + .put("longKey", 1L) + .put("doubleKey", 1.0) + .put("boolKey", true) + // Helper methods to set primitive array types + .put("stringArrKey", "value1", "value2") + .put("longArrKey", 1L, 2L) + .put("doubleArrKey", 1.0, 2.0) + .put("boolArrKey", true, false) + // Set AnyValue types to encode complex data + .put( + "anyValueKey", AnyValue.of(Collections.singletonMap("childKey1", AnyValue.of("value")))) + .emit(); + + LOGS = logRecordExporter.getFinishedLogRecordItems(); + } + + @Benchmark + public int marshalStateful() throws IOException { + LogsRequestMarshaler marshaler = LogsRequestMarshaler.create(LOGS); + OUTPUT.reset(); + marshaler.writeBinaryTo(OUTPUT); + return OUTPUT.getCount(); + } + + @Benchmark + public int marshalStatefulJson() throws IOException { + LogsRequestMarshaler marshaler = LogsRequestMarshaler.create(LOGS); + OUTPUT.reset(); + marshaler.writeJsonTo(OUTPUT); + return OUTPUT.getCount(); + } + + @Benchmark + public int marshalStateless() throws IOException { + MARSHALER.initialize(LOGS); + try { + OUTPUT.reset(); + MARSHALER.writeBinaryTo(OUTPUT); + return OUTPUT.getCount(); + } finally { + MARSHALER.reset(); + } + } + + @Benchmark + public int marshalStatelessJson() throws IOException { + MARSHALER.initialize(LOGS); + try { + OUTPUT.reset(); + MARSHALER.writeJsonTo(OUTPUT); + return OUTPUT.getCount(); + } finally { + MARSHALER.reset(); + } + } +} diff --git a/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/AnyValueStatelessMarshaler.java b/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/AnyValueStatelessMarshaler.java new file mode 100644 index 00000000000..f9cbb05589f --- /dev/null +++ b/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/AnyValueStatelessMarshaler.java @@ -0,0 +1,110 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.exporter.internal.otlp; + +import io.opentelemetry.api.incubator.logs.AnyValue; +import io.opentelemetry.api.incubator.logs.KeyAnyValue; +import io.opentelemetry.exporter.internal.marshal.MarshalerContext; +import io.opentelemetry.exporter.internal.marshal.Serializer; +import io.opentelemetry.exporter.internal.marshal.StatelessMarshaler; +import io.opentelemetry.exporter.internal.marshal.StatelessMarshalerUtil; +import java.io.IOException; +import java.nio.ByteBuffer; +import java.util.List; + +/** + * A Marshaler of key value pairs. See {@link AnyValueMarshaler}. + * + *

      This class is internal and is hence not for public use. Its APIs are unstable and can change + * at any time. + */ +public final class AnyValueStatelessMarshaler implements StatelessMarshaler> { + + public static final AnyValueStatelessMarshaler INSTANCE = new AnyValueStatelessMarshaler(); + + private AnyValueStatelessMarshaler() {} + + @SuppressWarnings("unchecked") + @Override + public void writeTo(Serializer output, AnyValue value, MarshalerContext context) + throws IOException { + switch (value.getType()) { + case STRING: + StringAnyValueStatelessMarshaler.INSTANCE.writeTo( + output, (String) value.getValue(), context); + return; + case BOOLEAN: + BoolAnyValueStatelessMarshaler.INSTANCE.writeTo( + output, (Boolean) value.getValue(), context); + return; + case LONG: + IntAnyValueStatelessMarshaler.INSTANCE.writeTo(output, (Long) value.getValue(), context); + return; + case DOUBLE: + DoubleAnyValueStatelessMarshaler.INSTANCE.writeTo( + output, (Double) value.getValue(), context); + return; + case ARRAY: + output.serializeMessageWithContext( + io.opentelemetry.proto.common.v1.internal.AnyValue.ARRAY_VALUE, + (List>) value.getValue(), + ArrayAnyValueStatelessMarshaler.INSTANCE, + context); + return; + case KEY_VALUE_LIST: + output.serializeMessageWithContext( + io.opentelemetry.proto.common.v1.internal.AnyValue.KVLIST_VALUE, + (List) value.getValue(), + KeyValueListAnyValueStatelessMarshaler.INSTANCE, + context); + return; + case BYTES: + BytesAnyValueStatelessMarshaler.INSTANCE.writeTo( + output, (ByteBuffer) value.getValue(), context); + return; + } + // Error prone ensures the switch statement is complete, otherwise only can happen with + // unaligned versions which are not supported. + throw new IllegalArgumentException("Unsupported value type."); + } + + @SuppressWarnings("unchecked") + @Override + public int getBinarySerializedSize(AnyValue value, MarshalerContext context) { + switch (value.getType()) { + case STRING: + return StringAnyValueStatelessMarshaler.INSTANCE.getBinarySerializedSize( + (String) value.getValue(), context); + case BOOLEAN: + return BoolAnyValueStatelessMarshaler.INSTANCE.getBinarySerializedSize( + (Boolean) value.getValue(), context); + case LONG: + return IntAnyValueStatelessMarshaler.INSTANCE.getBinarySerializedSize( + (Long) value.getValue(), context); + case DOUBLE: + return DoubleAnyValueStatelessMarshaler.INSTANCE.getBinarySerializedSize( + (Double) value.getValue(), context); + case ARRAY: + return StatelessMarshalerUtil.sizeMessageWithContext( + io.opentelemetry.proto.common.v1.internal.AnyValue.ARRAY_VALUE, + (List>) value.getValue(), + ArrayAnyValueStatelessMarshaler.INSTANCE, + context); + case KEY_VALUE_LIST: + return StatelessMarshalerUtil.sizeMessageWithContext( + io.opentelemetry.proto.common.v1.internal.AnyValue.KVLIST_VALUE, + (List) value.getValue(), + KeyValueListAnyValueStatelessMarshaler.INSTANCE, + context); + case BYTES: + return BytesAnyValueStatelessMarshaler.INSTANCE.getBinarySerializedSize( + (ByteBuffer) value.getValue(), context); + } + // Error prone ensures the switch statement is complete, otherwise only can happen with + // unaligned versions which are not supported. + throw new IllegalArgumentException("Unsupported value type."); + } +} diff --git a/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/ArrayAnyValueStatelessMarshaler.java b/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/ArrayAnyValueStatelessMarshaler.java index 87e2bd3eb7a..a558953514c 100644 --- a/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/ArrayAnyValueStatelessMarshaler.java +++ b/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/ArrayAnyValueStatelessMarshaler.java @@ -5,84 +5,32 @@ package io.opentelemetry.exporter.internal.otlp; -import io.opentelemetry.api.common.AttributeType; +import io.opentelemetry.api.incubator.logs.AnyValue; import io.opentelemetry.exporter.internal.marshal.MarshalerContext; import io.opentelemetry.exporter.internal.marshal.Serializer; -import io.opentelemetry.exporter.internal.marshal.StatelessMarshaler2; +import io.opentelemetry.exporter.internal.marshal.StatelessMarshaler; import io.opentelemetry.exporter.internal.marshal.StatelessMarshalerUtil; import io.opentelemetry.proto.common.v1.internal.ArrayValue; import java.io.IOException; import java.util.List; -/** See {@link ArrayAnyValueMarshaler}. */ -// TODO: add support for List> -final class ArrayAnyValueStatelessMarshaler - implements StatelessMarshaler2> { - static final ArrayAnyValueStatelessMarshaler INSTANCE = - new ArrayAnyValueStatelessMarshaler<>(); +/** A Marshaler of key value pairs. See {@link ArrayAnyValueMarshaler}. */ +final class ArrayAnyValueStatelessMarshaler implements StatelessMarshaler>> { + + static final ArrayAnyValueStatelessMarshaler INSTANCE = new ArrayAnyValueStatelessMarshaler(); + + private ArrayAnyValueStatelessMarshaler() {} - @SuppressWarnings("unchecked") @Override - public void writeTo(Serializer output, AttributeType type, List list, MarshalerContext context) + public void writeTo(Serializer output, List> value, MarshalerContext context) throws IOException { - switch (type) { - case STRING_ARRAY: - output.serializeRepeatedMessageWithContext( - ArrayValue.VALUES, - (List) list, - StringAnyValueStatelessMarshaler.INSTANCE, - context); - return; - case LONG_ARRAY: - output.serializeRepeatedMessageWithContext( - ArrayValue.VALUES, (List) list, IntAnyValueStatelessMarshaler.INSTANCE, context); - return; - case BOOLEAN_ARRAY: - output.serializeRepeatedMessageWithContext( - ArrayValue.VALUES, - (List) list, - BoolAnyValueStatelessMarshaler.INSTANCE, - context); - return; - case DOUBLE_ARRAY: - output.serializeRepeatedMessageWithContext( - ArrayValue.VALUES, - (List) list, - DoubleAnyValueStatelessMarshaler.INSTANCE, - context); - return; - default: - throw new IllegalArgumentException("Unsupported attribute type."); - } + output.serializeRepeatedMessageWithContext( + ArrayValue.VALUES, value, AnyValueStatelessMarshaler.INSTANCE, context); } - @SuppressWarnings("unchecked") @Override - public int getBinarySerializedSize(AttributeType type, List list, MarshalerContext context) { - switch (type) { - case STRING_ARRAY: - return StatelessMarshalerUtil.sizeRepeatedMessageWithContext( - ArrayValue.VALUES, - (List) list, - StringAnyValueStatelessMarshaler.INSTANCE, - context); - case LONG_ARRAY: - return StatelessMarshalerUtil.sizeRepeatedMessageWithContext( - ArrayValue.VALUES, (List) list, IntAnyValueStatelessMarshaler.INSTANCE, context); - case BOOLEAN_ARRAY: - return StatelessMarshalerUtil.sizeRepeatedMessageWithContext( - ArrayValue.VALUES, - (List) list, - BoolAnyValueStatelessMarshaler.INSTANCE, - context); - case DOUBLE_ARRAY: - return StatelessMarshalerUtil.sizeRepeatedMessageWithContext( - ArrayValue.VALUES, - (List) list, - DoubleAnyValueStatelessMarshaler.INSTANCE, - context); - default: - throw new IllegalArgumentException("Unsupported attribute type."); - } + public int getBinarySerializedSize(List> value, MarshalerContext context) { + return StatelessMarshalerUtil.sizeRepeatedMessageWithContext( + ArrayValue.VALUES, value, AnyValueStatelessMarshaler.INSTANCE, context); } } diff --git a/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/AttributeArrayAnyValueStatelessMarshaler.java b/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/AttributeArrayAnyValueStatelessMarshaler.java new file mode 100644 index 00000000000..db92ca1e7dc --- /dev/null +++ b/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/AttributeArrayAnyValueStatelessMarshaler.java @@ -0,0 +1,89 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.exporter.internal.otlp; + +import io.opentelemetry.api.common.AttributeType; +import io.opentelemetry.exporter.internal.marshal.MarshalerContext; +import io.opentelemetry.exporter.internal.marshal.Serializer; +import io.opentelemetry.exporter.internal.marshal.StatelessMarshaler2; +import io.opentelemetry.exporter.internal.marshal.StatelessMarshalerUtil; +import io.opentelemetry.proto.common.v1.internal.ArrayValue; +import java.io.IOException; +import java.util.List; + +/** See {@link ArrayAnyValueMarshaler}. */ +final class AttributeArrayAnyValueStatelessMarshaler + implements StatelessMarshaler2> { + static final AttributeArrayAnyValueStatelessMarshaler INSTANCE = + new AttributeArrayAnyValueStatelessMarshaler<>(); + + private AttributeArrayAnyValueStatelessMarshaler() {} + + @SuppressWarnings("unchecked") + @Override + public void writeTo(Serializer output, AttributeType type, List list, MarshalerContext context) + throws IOException { + switch (type) { + case STRING_ARRAY: + output.serializeRepeatedMessageWithContext( + ArrayValue.VALUES, + (List) list, + StringAnyValueStatelessMarshaler.INSTANCE, + context); + return; + case LONG_ARRAY: + output.serializeRepeatedMessageWithContext( + ArrayValue.VALUES, (List) list, IntAnyValueStatelessMarshaler.INSTANCE, context); + return; + case BOOLEAN_ARRAY: + output.serializeRepeatedMessageWithContext( + ArrayValue.VALUES, + (List) list, + BoolAnyValueStatelessMarshaler.INSTANCE, + context); + return; + case DOUBLE_ARRAY: + output.serializeRepeatedMessageWithContext( + ArrayValue.VALUES, + (List) list, + DoubleAnyValueStatelessMarshaler.INSTANCE, + context); + return; + default: + throw new IllegalArgumentException("Unsupported attribute type."); + } + } + + @SuppressWarnings("unchecked") + @Override + public int getBinarySerializedSize(AttributeType type, List list, MarshalerContext context) { + switch (type) { + case STRING_ARRAY: + return StatelessMarshalerUtil.sizeRepeatedMessageWithContext( + ArrayValue.VALUES, + (List) list, + StringAnyValueStatelessMarshaler.INSTANCE, + context); + case LONG_ARRAY: + return StatelessMarshalerUtil.sizeRepeatedMessageWithContext( + ArrayValue.VALUES, (List) list, IntAnyValueStatelessMarshaler.INSTANCE, context); + case BOOLEAN_ARRAY: + return StatelessMarshalerUtil.sizeRepeatedMessageWithContext( + ArrayValue.VALUES, + (List) list, + BoolAnyValueStatelessMarshaler.INSTANCE, + context); + case DOUBLE_ARRAY: + return StatelessMarshalerUtil.sizeRepeatedMessageWithContext( + ArrayValue.VALUES, + (List) list, + DoubleAnyValueStatelessMarshaler.INSTANCE, + context); + default: + throw new IllegalArgumentException("Unsupported attribute type."); + } + } +} diff --git a/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/AttributeKeyValueStatelessMarshaler.java b/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/AttributeKeyValueStatelessMarshaler.java new file mode 100644 index 00000000000..3fb1f7c25f6 --- /dev/null +++ b/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/AttributeKeyValueStatelessMarshaler.java @@ -0,0 +1,145 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.exporter.internal.otlp; + +import io.opentelemetry.api.common.AttributeKey; +import io.opentelemetry.api.common.AttributeType; +import io.opentelemetry.api.internal.InternalAttributeKeyImpl; +import io.opentelemetry.exporter.internal.marshal.MarshalerContext; +import io.opentelemetry.exporter.internal.marshal.MarshalerUtil; +import io.opentelemetry.exporter.internal.marshal.Serializer; +import io.opentelemetry.exporter.internal.marshal.StatelessMarshaler2; +import io.opentelemetry.exporter.internal.marshal.StatelessMarshalerUtil; +import io.opentelemetry.proto.common.v1.internal.AnyValue; +import io.opentelemetry.proto.common.v1.internal.KeyValue; +import java.io.IOException; +import java.util.List; + +/** + * A Marshaler of key value pairs. See {@link KeyValueMarshaler}. + * + *

      This class is internal and is hence not for public use. Its APIs are unstable and can change + * at any time. + */ +public final class AttributeKeyValueStatelessMarshaler + implements StatelessMarshaler2, Object> { + public static final AttributeKeyValueStatelessMarshaler INSTANCE = + new AttributeKeyValueStatelessMarshaler(); + private static final byte[] EMPTY_BYTES = new byte[0]; + + private AttributeKeyValueStatelessMarshaler() {} + + @Override + public void writeTo( + Serializer output, AttributeKey attributeKey, Object value, MarshalerContext context) + throws IOException { + if (attributeKey.getKey().isEmpty()) { + output.serializeString(KeyValue.KEY, EMPTY_BYTES); + } else if (attributeKey instanceof InternalAttributeKeyImpl) { + byte[] keyUtf8 = ((InternalAttributeKeyImpl) attributeKey).getKeyUtf8(); + output.serializeString(KeyValue.KEY, keyUtf8); + } else { + output.serializeStringWithContext(KeyValue.KEY, attributeKey.getKey(), context); + } + output.serializeMessageWithContext( + KeyValue.VALUE, attributeKey, value, ValueStatelessMarshaler.INSTANCE, context); + } + + @Override + public int getBinarySerializedSize( + AttributeKey attributeKey, Object value, MarshalerContext context) { + int size = 0; + if (!attributeKey.getKey().isEmpty()) { + if (attributeKey instanceof InternalAttributeKeyImpl) { + byte[] keyUtf8 = ((InternalAttributeKeyImpl) attributeKey).getKeyUtf8(); + size += MarshalerUtil.sizeBytes(KeyValue.KEY, keyUtf8); + } else { + return StatelessMarshalerUtil.sizeStringWithContext( + KeyValue.KEY, attributeKey.getKey(), context); + } + } + size += + StatelessMarshalerUtil.sizeMessageWithContext( + KeyValue.VALUE, attributeKey, value, ValueStatelessMarshaler.INSTANCE, context); + + return size; + } + + private static class ValueStatelessMarshaler + implements StatelessMarshaler2, Object> { + static final ValueStatelessMarshaler INSTANCE = new ValueStatelessMarshaler(); + + @SuppressWarnings("unchecked") + @Override + public int getBinarySerializedSize( + AttributeKey attributeKey, Object value, MarshalerContext context) { + AttributeType attributeType = attributeKey.getType(); + switch (attributeType) { + case STRING: + return StringAnyValueStatelessMarshaler.INSTANCE.getBinarySerializedSize( + (String) value, context); + case LONG: + return IntAnyValueStatelessMarshaler.INSTANCE.getBinarySerializedSize( + (Long) value, context); + case BOOLEAN: + return BoolAnyValueStatelessMarshaler.INSTANCE.getBinarySerializedSize( + (Boolean) value, context); + case DOUBLE: + return DoubleAnyValueStatelessMarshaler.INSTANCE.getBinarySerializedSize( + (Double) value, context); + case STRING_ARRAY: + case LONG_ARRAY: + case BOOLEAN_ARRAY: + case DOUBLE_ARRAY: + return StatelessMarshalerUtil.sizeMessageWithContext( + AnyValue.ARRAY_VALUE, + attributeType, + (List) value, + AttributeArrayAnyValueStatelessMarshaler.INSTANCE, + context); + } + // Error prone ensures the switch statement is complete, otherwise only can happen with + // unaligned versions which are not supported. + throw new IllegalArgumentException("Unsupported attribute type."); + } + + @SuppressWarnings("unchecked") + @Override + public void writeTo( + Serializer output, AttributeKey attributeKey, Object value, MarshalerContext context) + throws IOException { + AttributeType attributeType = attributeKey.getType(); + switch (attributeType) { + case STRING: + StringAnyValueStatelessMarshaler.INSTANCE.writeTo(output, (String) value, context); + return; + case LONG: + IntAnyValueStatelessMarshaler.INSTANCE.writeTo(output, (Long) value, context); + return; + case BOOLEAN: + BoolAnyValueStatelessMarshaler.INSTANCE.writeTo(output, (Boolean) value, context); + return; + case DOUBLE: + DoubleAnyValueStatelessMarshaler.INSTANCE.writeTo(output, (Double) value, context); + return; + case STRING_ARRAY: + case LONG_ARRAY: + case BOOLEAN_ARRAY: + case DOUBLE_ARRAY: + output.serializeMessageWithContext( + AnyValue.ARRAY_VALUE, + attributeType, + (List) value, + AttributeArrayAnyValueStatelessMarshaler.INSTANCE, + context); + return; + } + // Error prone ensures the switch statement is complete, otherwise only can happen with + // unaligned versions which are not supported. + throw new IllegalArgumentException("Unsupported attribute type."); + } + } +} diff --git a/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/BytesAnyValueStatelessMarshaler.java b/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/BytesAnyValueStatelessMarshaler.java new file mode 100644 index 00000000000..767ff8b8176 --- /dev/null +++ b/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/BytesAnyValueStatelessMarshaler.java @@ -0,0 +1,36 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.exporter.internal.otlp; + +import io.opentelemetry.exporter.internal.marshal.CodedOutputStream; +import io.opentelemetry.exporter.internal.marshal.MarshalerContext; +import io.opentelemetry.exporter.internal.marshal.Serializer; +import io.opentelemetry.exporter.internal.marshal.StatelessMarshaler; +import io.opentelemetry.proto.common.v1.internal.AnyValue; +import java.io.IOException; +import java.nio.ByteBuffer; + +/** See {@link BytesAnyValueMarshaler}. */ +final class BytesAnyValueStatelessMarshaler implements StatelessMarshaler { + static final BytesAnyValueStatelessMarshaler INSTANCE = new BytesAnyValueStatelessMarshaler(); + + private BytesAnyValueStatelessMarshaler() {} + + @Override + public void writeTo(Serializer output, ByteBuffer value, MarshalerContext context) + throws IOException { + byte[] bytes = context.getData(byte[].class); + output.writeBytes(AnyValue.BYTES_VALUE, bytes); + } + + @Override + public int getBinarySerializedSize(ByteBuffer value, MarshalerContext context) { + byte[] bytes = new byte[value.remaining()]; + value.get(bytes); + context.addData(bytes); + return AnyValue.BYTES_VALUE.getTagSize() + CodedOutputStream.computeByteArraySizeNoTag(bytes); + } +} diff --git a/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/KeyValueListAnyValueStatelessMarshaler.java b/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/KeyValueListAnyValueStatelessMarshaler.java new file mode 100644 index 00000000000..854eb2cea6e --- /dev/null +++ b/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/KeyValueListAnyValueStatelessMarshaler.java @@ -0,0 +1,38 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.exporter.internal.otlp; + +import io.opentelemetry.api.incubator.logs.KeyAnyValue; +import io.opentelemetry.exporter.internal.marshal.MarshalerContext; +import io.opentelemetry.exporter.internal.marshal.Serializer; +import io.opentelemetry.exporter.internal.marshal.StatelessMarshaler; +import io.opentelemetry.exporter.internal.marshal.StatelessMarshalerUtil; +import io.opentelemetry.proto.common.v1.internal.KeyValueList; +import java.io.IOException; +import java.util.List; + +/** A Marshaler of key value pairs. See {@link KeyValueListAnyValueMarshaler}. */ +final class KeyValueListAnyValueStatelessMarshaler + implements StatelessMarshaler> { + + static final KeyValueListAnyValueStatelessMarshaler INSTANCE = + new KeyValueListAnyValueStatelessMarshaler(); + + private KeyValueListAnyValueStatelessMarshaler() {} + + @Override + public void writeTo(Serializer output, List value, MarshalerContext context) + throws IOException { + output.serializeRepeatedMessageWithContext( + KeyValueList.VALUES, value, KeyValueStatelessMarshaler.INSTANCE, context); + } + + @Override + public int getBinarySerializedSize(List value, MarshalerContext context) { + return StatelessMarshalerUtil.sizeRepeatedMessageWithContext( + KeyValueList.VALUES, value, KeyValueStatelessMarshaler.INSTANCE, context); + } +} diff --git a/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/KeyValueStatelessMarshaler.java b/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/KeyValueStatelessMarshaler.java index 5714912d2d0..0f14f0d354c 100644 --- a/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/KeyValueStatelessMarshaler.java +++ b/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/KeyValueStatelessMarshaler.java @@ -5,138 +5,46 @@ package io.opentelemetry.exporter.internal.otlp; -import io.opentelemetry.api.common.AttributeKey; -import io.opentelemetry.api.common.AttributeType; -import io.opentelemetry.api.internal.InternalAttributeKeyImpl; +import io.opentelemetry.api.incubator.logs.KeyAnyValue; import io.opentelemetry.exporter.internal.marshal.MarshalerContext; -import io.opentelemetry.exporter.internal.marshal.MarshalerUtil; import io.opentelemetry.exporter.internal.marshal.Serializer; -import io.opentelemetry.exporter.internal.marshal.StatelessMarshaler2; +import io.opentelemetry.exporter.internal.marshal.StatelessMarshaler; import io.opentelemetry.exporter.internal.marshal.StatelessMarshalerUtil; -import io.opentelemetry.proto.common.v1.internal.AnyValue; import io.opentelemetry.proto.common.v1.internal.KeyValue; import java.io.IOException; -import java.util.List; -/** - * A Marshaler of key value pairs. See {@link KeyValueMarshaler}. - * - *

      This class is internal and is hence not for public use. Its APIs are unstable and can change - * at any time. - */ -public final class KeyValueStatelessMarshaler - implements StatelessMarshaler2, Object> { - public static final KeyValueStatelessMarshaler INSTANCE = new KeyValueStatelessMarshaler(); +/** A Marshaler of key value pairs. See {@link AnyValueMarshaler}. */ +final class KeyValueStatelessMarshaler implements StatelessMarshaler { + + static final KeyValueStatelessMarshaler INSTANCE = new KeyValueStatelessMarshaler(); private static final byte[] EMPTY_BYTES = new byte[0]; + private KeyValueStatelessMarshaler() {} + @Override - public void writeTo( - Serializer output, AttributeKey attributeKey, Object value, MarshalerContext context) + public void writeTo(Serializer output, KeyAnyValue value, MarshalerContext context) throws IOException { - if (attributeKey.getKey().isEmpty()) { + String key = value.getKey(); + if (key.isEmpty()) { output.serializeString(KeyValue.KEY, EMPTY_BYTES); - } else if (attributeKey instanceof InternalAttributeKeyImpl) { - byte[] keyUtf8 = ((InternalAttributeKeyImpl) attributeKey).getKeyUtf8(); - output.serializeString(KeyValue.KEY, keyUtf8); } else { - output.serializeStringWithContext(KeyValue.KEY, attributeKey.getKey(), context); + output.serializeStringWithContext(KeyValue.KEY, key, context); } output.serializeMessageWithContext( - KeyValue.VALUE, attributeKey, value, ValueStatelessMarshaler.INSTANCE, context); + KeyValue.VALUE, value.getAnyValue(), AnyValueStatelessMarshaler.INSTANCE, context); } @Override - public int getBinarySerializedSize( - AttributeKey attributeKey, Object value, MarshalerContext context) { + public int getBinarySerializedSize(KeyAnyValue value, MarshalerContext context) { int size = 0; - if (!attributeKey.getKey().isEmpty()) { - if (attributeKey instanceof InternalAttributeKeyImpl) { - byte[] keyUtf8 = ((InternalAttributeKeyImpl) attributeKey).getKeyUtf8(); - size += MarshalerUtil.sizeBytes(KeyValue.KEY, keyUtf8); - } else { - return StatelessMarshalerUtil.sizeStringWithContext( - KeyValue.KEY, attributeKey.getKey(), context); - } + String key = value.getKey(); + if (!key.isEmpty()) { + size += StatelessMarshalerUtil.sizeStringWithContext(KeyValue.KEY, key, context); } size += StatelessMarshalerUtil.sizeMessageWithContext( - KeyValue.VALUE, attributeKey, value, ValueStatelessMarshaler.INSTANCE, context); + KeyValue.VALUE, value.getAnyValue(), AnyValueStatelessMarshaler.INSTANCE, context); return size; } - - private static class ValueStatelessMarshaler - implements StatelessMarshaler2, Object> { - static final ValueStatelessMarshaler INSTANCE = new ValueStatelessMarshaler(); - - @SuppressWarnings("unchecked") - @Override - public int getBinarySerializedSize( - AttributeKey attributeKey, Object value, MarshalerContext context) { - AttributeType attributeType = attributeKey.getType(); - switch (attributeType) { - case STRING: - return StringAnyValueStatelessMarshaler.INSTANCE.getBinarySerializedSize( - (String) value, context); - case LONG: - return IntAnyValueStatelessMarshaler.INSTANCE.getBinarySerializedSize( - (Long) value, context); - case BOOLEAN: - return BoolAnyValueStatelessMarshaler.INSTANCE.getBinarySerializedSize( - (Boolean) value, context); - case DOUBLE: - return DoubleAnyValueStatelessMarshaler.INSTANCE.getBinarySerializedSize( - (Double) value, context); - case STRING_ARRAY: - case LONG_ARRAY: - case BOOLEAN_ARRAY: - case DOUBLE_ARRAY: - return StatelessMarshalerUtil.sizeMessageWithContext( - AnyValue.ARRAY_VALUE, - attributeType, - (List) value, - ArrayAnyValueStatelessMarshaler.INSTANCE, - context); - } - // Error prone ensures the switch statement is complete, otherwise only can happen with - // unaligned versions which are not supported. - throw new IllegalArgumentException("Unsupported attribute type."); - } - - @SuppressWarnings("unchecked") - @Override - public void writeTo( - Serializer output, AttributeKey attributeKey, Object value, MarshalerContext context) - throws IOException { - AttributeType attributeType = attributeKey.getType(); - switch (attributeType) { - case STRING: - StringAnyValueStatelessMarshaler.INSTANCE.writeTo(output, (String) value, context); - return; - case LONG: - IntAnyValueStatelessMarshaler.INSTANCE.writeTo(output, (Long) value, context); - return; - case BOOLEAN: - BoolAnyValueStatelessMarshaler.INSTANCE.writeTo(output, (Boolean) value, context); - return; - case DOUBLE: - DoubleAnyValueStatelessMarshaler.INSTANCE.writeTo(output, (Double) value, context); - return; - case STRING_ARRAY: - case LONG_ARRAY: - case BOOLEAN_ARRAY: - case DOUBLE_ARRAY: - output.serializeMessageWithContext( - AnyValue.ARRAY_VALUE, - attributeType, - (List) value, - ArrayAnyValueStatelessMarshaler.INSTANCE, - context); - return; - } - // Error prone ensures the switch statement is complete, otherwise only can happen with - // unaligned versions which are not supported. - throw new IllegalArgumentException("Unsupported attribute type."); - } - } } diff --git a/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/StringAnyValueMarshaler.java b/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/StringAnyValueMarshaler.java index e62c55d2da1..cc7bf4527c6 100644 --- a/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/StringAnyValueMarshaler.java +++ b/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/StringAnyValueMarshaler.java @@ -33,12 +33,16 @@ static MarshalerWithSize create(String value) { @Override public void writeTo(Serializer output) throws IOException { - // Do not call serialize* method because we always have to write the message tag even if the - // value is empty since it's a oneof. + if (valueUtf8.length == 0) { + return; + } output.writeString(AnyValue.STRING_VALUE, valueUtf8); } private static int calculateSize(byte[] valueUtf8) { + if (valueUtf8.length == 0) { + return 0; + } return AnyValue.STRING_VALUE.getTagSize() + CodedOutputStream.computeByteArraySizeNoTag(valueUtf8); } diff --git a/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/logs/InstrumentationScopeLogsStatelessMarshaler.java b/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/logs/InstrumentationScopeLogsStatelessMarshaler.java new file mode 100644 index 00000000000..60789604b3e --- /dev/null +++ b/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/logs/InstrumentationScopeLogsStatelessMarshaler.java @@ -0,0 +1,63 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.exporter.internal.otlp.logs; + +import io.opentelemetry.exporter.internal.marshal.MarshalerContext; +import io.opentelemetry.exporter.internal.marshal.MarshalerUtil; +import io.opentelemetry.exporter.internal.marshal.Serializer; +import io.opentelemetry.exporter.internal.marshal.StatelessMarshaler2; +import io.opentelemetry.exporter.internal.marshal.StatelessMarshalerUtil; +import io.opentelemetry.exporter.internal.otlp.InstrumentationScopeMarshaler; +import io.opentelemetry.proto.logs.v1.internal.ScopeLogs; +import io.opentelemetry.sdk.common.InstrumentationScopeInfo; +import io.opentelemetry.sdk.logs.data.LogRecordData; +import java.io.IOException; +import java.util.List; + +/** See {@link InstrumentationScopeLogsMarshaler}. */ +final class InstrumentationScopeLogsStatelessMarshaler + implements StatelessMarshaler2> { + static final InstrumentationScopeLogsStatelessMarshaler INSTANCE = + new InstrumentationScopeLogsStatelessMarshaler(); + + @Override + public void writeTo( + Serializer output, + InstrumentationScopeInfo instrumentationScope, + List logs, + MarshalerContext context) + throws IOException { + InstrumentationScopeMarshaler instrumentationScopeMarshaler = + context.getData(InstrumentationScopeMarshaler.class); + + output.serializeMessage(ScopeLogs.SCOPE, instrumentationScopeMarshaler); + output.serializeRepeatedMessageWithContext( + ScopeLogs.LOG_RECORDS, logs, LogStatelessMarshaler.INSTANCE, context); + output.serializeStringWithContext( + ScopeLogs.SCHEMA_URL, instrumentationScope.getSchemaUrl(), context); + } + + @Override + public int getBinarySerializedSize( + InstrumentationScopeInfo instrumentationScope, + List logs, + MarshalerContext context) { + InstrumentationScopeMarshaler instrumentationScopeMarshaler = + InstrumentationScopeMarshaler.create(instrumentationScope); + context.addData(instrumentationScopeMarshaler); + + int size = 0; + size += MarshalerUtil.sizeMessage(ScopeLogs.SCOPE, instrumentationScopeMarshaler); + size += + StatelessMarshalerUtil.sizeRepeatedMessageWithContext( + ScopeLogs.LOG_RECORDS, logs, LogStatelessMarshaler.INSTANCE, context); + size += + StatelessMarshalerUtil.sizeStringWithContext( + ScopeLogs.SCHEMA_URL, instrumentationScope.getSchemaUrl(), context); + + return size; + } +} diff --git a/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/logs/LogStatelessMarshaler.java b/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/logs/LogStatelessMarshaler.java new file mode 100644 index 00000000000..68d524b4341 --- /dev/null +++ b/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/logs/LogStatelessMarshaler.java @@ -0,0 +1,147 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.exporter.internal.otlp.logs; + +import static io.opentelemetry.exporter.internal.otlp.logs.LogMarshaler.toProtoSeverityNumber; + +import io.opentelemetry.api.incubator.logs.AnyValue; +import io.opentelemetry.api.trace.SpanContext; +import io.opentelemetry.api.trace.SpanId; +import io.opentelemetry.api.trace.TraceId; +import io.opentelemetry.exporter.internal.marshal.MarshalerContext; +import io.opentelemetry.exporter.internal.marshal.MarshalerUtil; +import io.opentelemetry.exporter.internal.marshal.Serializer; +import io.opentelemetry.exporter.internal.marshal.StatelessMarshaler; +import io.opentelemetry.exporter.internal.marshal.StatelessMarshalerUtil; +import io.opentelemetry.exporter.internal.otlp.AnyValueStatelessMarshaler; +import io.opentelemetry.exporter.internal.otlp.AttributeKeyValueStatelessMarshaler; +import io.opentelemetry.proto.logs.v1.internal.LogRecord; +import io.opentelemetry.sdk.logs.data.Body; +import io.opentelemetry.sdk.logs.data.LogRecordData; +import io.opentelemetry.sdk.logs.internal.AnyValueBody; +import java.io.IOException; + +/** See {@link LogMarshaler}. */ +final class LogStatelessMarshaler implements StatelessMarshaler { + private static final String INVALID_TRACE_ID = TraceId.getInvalid(); + private static final String INVALID_SPAN_ID = SpanId.getInvalid(); + static final LogStatelessMarshaler INSTANCE = new LogStatelessMarshaler(); + + @Override + public void writeTo(Serializer output, LogRecordData log, MarshalerContext context) + throws IOException { + output.serializeFixed64(LogRecord.TIME_UNIX_NANO, log.getTimestampEpochNanos()); + output.serializeFixed64( + LogRecord.OBSERVED_TIME_UNIX_NANO, log.getObservedTimestampEpochNanos()); + output.serializeEnum(LogRecord.SEVERITY_NUMBER, toProtoSeverityNumber(log.getSeverity())); + output.serializeStringWithContext(LogRecord.SEVERITY_TEXT, log.getSeverityText(), context); + output.serializeMessageWithContext( + LogRecord.BODY, log.getBody(), BodyMarshaler.INSTANCE, context); + output.serializeRepeatedMessageWithContext( + LogRecord.ATTRIBUTES, + log.getAttributes(), + AttributeKeyValueStatelessMarshaler.INSTANCE, + context); + int droppedAttributesCount = log.getTotalAttributeCount() - log.getAttributes().size(); + output.serializeUInt32(LogRecord.DROPPED_ATTRIBUTES_COUNT, droppedAttributesCount); + + SpanContext spanContext = log.getSpanContext(); + output.serializeFixed32(LogRecord.FLAGS, spanContext.getTraceFlags().asByte()); + if (!spanContext.getTraceId().equals(INVALID_TRACE_ID)) { + output.serializeTraceId(LogRecord.TRACE_ID, spanContext.getTraceId(), context); + } + if (!spanContext.getSpanId().equals(INVALID_SPAN_ID)) { + output.serializeSpanId(LogRecord.SPAN_ID, spanContext.getSpanId(), context); + } + } + + @Override + public int getBinarySerializedSize(LogRecordData log, MarshalerContext context) { + int size = 0; + + size += MarshalerUtil.sizeFixed64(LogRecord.TIME_UNIX_NANO, log.getTimestampEpochNanos()); + size += + MarshalerUtil.sizeFixed64( + LogRecord.OBSERVED_TIME_UNIX_NANO, log.getObservedTimestampEpochNanos()); + size += + MarshalerUtil.sizeEnum(LogRecord.SEVERITY_NUMBER, toProtoSeverityNumber(log.getSeverity())); + size += + StatelessMarshalerUtil.sizeStringWithContext( + LogRecord.SEVERITY_TEXT, log.getSeverityText(), context); + size += + StatelessMarshalerUtil.sizeMessageWithContext( + LogRecord.BODY, log.getBody(), BodyMarshaler.INSTANCE, context); + size += + StatelessMarshalerUtil.sizeRepeatedMessageWithContext( + LogRecord.ATTRIBUTES, + log.getAttributes(), + AttributeKeyValueStatelessMarshaler.INSTANCE, + context); + int droppedAttributesCount = log.getTotalAttributeCount() - log.getAttributes().size(); + size += MarshalerUtil.sizeUInt32(LogRecord.DROPPED_ATTRIBUTES_COUNT, droppedAttributesCount); + + SpanContext spanContext = log.getSpanContext(); + size += MarshalerUtil.sizeFixed32(LogRecord.FLAGS, spanContext.getTraceFlags().asByte()); + if (!spanContext.getTraceId().equals(INVALID_TRACE_ID)) { + size += MarshalerUtil.sizeTraceId(LogRecord.TRACE_ID, spanContext.getTraceId()); + } + if (!spanContext.getSpanId().equals(INVALID_SPAN_ID)) { + size += MarshalerUtil.sizeSpanId(LogRecord.SPAN_ID, spanContext.getSpanId()); + } + + return size; + } + + private static class BodyMarshaler implements StatelessMarshaler { + + private static final BodyMarshaler INSTANCE = new BodyMarshaler(); + private static final AnyValue EMPTY_BODY = AnyValue.of(""); + + private BodyMarshaler() {} + + @Override + public void writeTo(Serializer output, Body value, MarshalerContext context) + throws IOException { + AnyValue anyValue; + if (value instanceof AnyValueBody) { + anyValue = ((AnyValueBody) value).asAnyValue(); + } else { + switch (value.getType()) { + case STRING: + anyValue = context.getData(AnyValue.class); + break; + case EMPTY: + anyValue = EMPTY_BODY; + break; + default: + throw new IllegalStateException("Unsupported Body type: " + value.getType()); + } + } + AnyValueStatelessMarshaler.INSTANCE.writeTo(output, anyValue, context); + } + + @Override + public int getBinarySerializedSize(Body value, MarshalerContext context) { + AnyValue anyValue; + if (value instanceof AnyValueBody) { + anyValue = ((AnyValueBody) value).asAnyValue(); + } else { + switch (value.getType()) { + case STRING: + anyValue = AnyValue.of(value.asString()); + context.addData(anyValue); + break; + case EMPTY: + anyValue = EMPTY_BODY; + break; + default: + throw new IllegalStateException("Unsupported Body type: " + value.getType()); + } + } + return AnyValueStatelessMarshaler.INSTANCE.getBinarySerializedSize(anyValue, context); + } + } +} diff --git a/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/logs/LowAllocationLogsRequestMarshaler.java b/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/logs/LowAllocationLogsRequestMarshaler.java new file mode 100644 index 00000000000..f3bee53f061 --- /dev/null +++ b/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/logs/LowAllocationLogsRequestMarshaler.java @@ -0,0 +1,107 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.exporter.internal.otlp.logs; + +import io.opentelemetry.exporter.internal.marshal.Marshaler; +import io.opentelemetry.exporter.internal.marshal.MarshalerContext; +import io.opentelemetry.exporter.internal.marshal.Serializer; +import io.opentelemetry.exporter.internal.marshal.StatelessMarshalerUtil; +import io.opentelemetry.proto.collector.logs.v1.internal.ExportLogsServiceRequest; +import io.opentelemetry.sdk.common.InstrumentationScopeInfo; +import io.opentelemetry.sdk.logs.data.LogRecordData; +import io.opentelemetry.sdk.resources.Resource; +import java.io.IOException; +import java.util.Collection; +import java.util.Collections; +import java.util.List; +import java.util.Map; + +/** + * {@link Marshaler} to convert SDK {@link LogRecordData} to OTLP ExportLogsServiceRequest. See + * {@link LogsRequestMarshaler}. + * + *

      Example usage: + * + *

      {@code
      + * void marshal(LowAllocationLogRequestMarshaler requestMarshaler, OutputStream output,
      + *     List logDataList) throws IOException {
      + *   requestMarshaler.initialize(logDataList);
      + *   try {
      + *     requestMarshaler.writeBinaryTo(output);
      + *   } finally {
      + *     requestMarshaler.reset();
      + *   }
      + * }
      + * }
      + * + *

      This class is internal and is hence not for public use. Its APIs are unstable and can change + * at any time. + */ +public final class LowAllocationLogsRequestMarshaler extends Marshaler { + private static final MarshalerContext.Key RESOURCE_LOG_SIZE_CALCULATOR_KEY = + MarshalerContext.key(); + private static final MarshalerContext.Key RESOURCE_LOG_WRITER_KEY = MarshalerContext.key(); + + private final MarshalerContext context = new MarshalerContext(); + + @SuppressWarnings("NullAway") + private Map>> resourceAndScopeMap; + + private int size; + + public void initialize(Collection logDataList) { + resourceAndScopeMap = groupByResourceAndScope(context, logDataList); + size = calculateSize(context, resourceAndScopeMap); + } + + public void reset() { + context.reset(); + } + + @Override + public int getBinarySerializedSize() { + return size; + } + + @Override + public void writeTo(Serializer output) throws IOException { + // serializing can be retried, reset the indexes, so we could call writeTo multiple times + context.resetReadIndex(); + output.serializeRepeatedMessageWithContext( + ExportLogsServiceRequest.RESOURCE_LOGS, + resourceAndScopeMap, + ResourceLogsStatelessMarshaler.INSTANCE, + context, + RESOURCE_LOG_WRITER_KEY); + } + + private static int calculateSize( + MarshalerContext context, + Map>> resourceAndScopeMap) { + return StatelessMarshalerUtil.sizeRepeatedMessageWithContext( + ExportLogsServiceRequest.RESOURCE_LOGS, + resourceAndScopeMap, + ResourceLogsStatelessMarshaler.INSTANCE, + context, + RESOURCE_LOG_SIZE_CALCULATOR_KEY); + } + + private static Map>> + groupByResourceAndScope(MarshalerContext context, Collection logDataList) { + + if (logDataList.isEmpty()) { + return Collections.emptyMap(); + } + + return StatelessMarshalerUtil.groupByResourceAndScope( + logDataList, + // TODO(anuraaga): Replace with an internal SdkData type of interface that exposes these + // two. + LogRecordData::getResource, + LogRecordData::getInstrumentationScopeInfo, + context); + } +} diff --git a/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/logs/ResourceLogsStatelessMarshaler.java b/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/logs/ResourceLogsStatelessMarshaler.java new file mode 100644 index 00000000000..ba128c880c7 --- /dev/null +++ b/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/logs/ResourceLogsStatelessMarshaler.java @@ -0,0 +1,80 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.exporter.internal.otlp.logs; + +import io.opentelemetry.exporter.internal.marshal.MarshalerContext; +import io.opentelemetry.exporter.internal.marshal.MarshalerUtil; +import io.opentelemetry.exporter.internal.marshal.Serializer; +import io.opentelemetry.exporter.internal.marshal.StatelessMarshaler2; +import io.opentelemetry.exporter.internal.marshal.StatelessMarshalerUtil; +import io.opentelemetry.exporter.internal.otlp.ResourceMarshaler; +import io.opentelemetry.proto.logs.v1.internal.ResourceLogs; +import io.opentelemetry.sdk.common.InstrumentationScopeInfo; +import io.opentelemetry.sdk.logs.data.LogRecordData; +import io.opentelemetry.sdk.resources.Resource; +import java.io.IOException; +import java.util.List; +import java.util.Map; + +/** + * A Marshaler of ResourceLogs. See {@link ResourceLogsMarshaler}. + * + *

      This class is internal and is hence not for public use. Its APIs are unstable and can change + * at any time. + */ +public final class ResourceLogsStatelessMarshaler + implements StatelessMarshaler2>> { + static final ResourceLogsStatelessMarshaler INSTANCE = new ResourceLogsStatelessMarshaler(); + private static final MarshalerContext.Key SCOPE_LOG_WRITER_KEY = MarshalerContext.key(); + private static final MarshalerContext.Key SCOPE_LOG_SIZE_CALCULATOR_KEY = MarshalerContext.key(); + + @Override + public void writeTo( + Serializer output, + Resource resource, + Map> scopeMap, + MarshalerContext context) + throws IOException { + ResourceMarshaler resourceMarshaler = context.getData(ResourceMarshaler.class); + output.serializeMessage(ResourceLogs.RESOURCE, resourceMarshaler); + + output.serializeRepeatedMessageWithContext( + ResourceLogs.SCOPE_LOGS, + scopeMap, + InstrumentationScopeLogsStatelessMarshaler.INSTANCE, + context, + SCOPE_LOG_WRITER_KEY); + + output.serializeStringWithContext(ResourceLogs.SCHEMA_URL, resource.getSchemaUrl(), context); + } + + @Override + public int getBinarySerializedSize( + Resource resource, + Map> scopeMap, + MarshalerContext context) { + + int size = 0; + + ResourceMarshaler resourceMarshaler = ResourceMarshaler.create(resource); + context.addData(resourceMarshaler); + size += MarshalerUtil.sizeMessage(ResourceLogs.RESOURCE, resourceMarshaler); + + size += + StatelessMarshalerUtil.sizeRepeatedMessageWithContext( + ResourceLogs.SCOPE_LOGS, + scopeMap, + InstrumentationScopeLogsStatelessMarshaler.INSTANCE, + context, + SCOPE_LOG_SIZE_CALCULATOR_KEY); + + size += + StatelessMarshalerUtil.sizeStringWithContext( + ResourceLogs.SCHEMA_URL, resource.getSchemaUrl(), context); + + return size; + } +} diff --git a/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/traces/SpanEventStatelessMarshaler.java b/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/traces/SpanEventStatelessMarshaler.java index 491b8d44c30..a1878c3099b 100644 --- a/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/traces/SpanEventStatelessMarshaler.java +++ b/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/traces/SpanEventStatelessMarshaler.java @@ -10,7 +10,7 @@ import io.opentelemetry.exporter.internal.marshal.Serializer; import io.opentelemetry.exporter.internal.marshal.StatelessMarshaler; import io.opentelemetry.exporter.internal.marshal.StatelessMarshalerUtil; -import io.opentelemetry.exporter.internal.otlp.KeyValueStatelessMarshaler; +import io.opentelemetry.exporter.internal.otlp.AttributeKeyValueStatelessMarshaler; import io.opentelemetry.proto.trace.v1.internal.Span; import io.opentelemetry.sdk.trace.data.EventData; import java.io.IOException; @@ -27,7 +27,10 @@ public void writeTo(Serializer output, EventData event, MarshalerContext context output.serializeFixed64(Span.Event.TIME_UNIX_NANO, event.getEpochNanos()); output.serializeStringWithContext(Span.Event.NAME, event.getName(), context); output.serializeRepeatedMessageWithContext( - Span.Event.ATTRIBUTES, event.getAttributes(), KeyValueStatelessMarshaler.INSTANCE, context); + Span.Event.ATTRIBUTES, + event.getAttributes(), + AttributeKeyValueStatelessMarshaler.INSTANCE, + context); int droppedAttributesCount = event.getTotalAttributeCount() - event.getAttributes().size(); output.serializeUInt32(Span.Event.DROPPED_ATTRIBUTES_COUNT, droppedAttributesCount); } @@ -41,7 +44,7 @@ public int getBinarySerializedSize(EventData event, MarshalerContext context) { StatelessMarshalerUtil.sizeRepeatedMessageWithContext( Span.Event.ATTRIBUTES, event.getAttributes(), - KeyValueStatelessMarshaler.INSTANCE, + AttributeKeyValueStatelessMarshaler.INSTANCE, context); int droppedAttributesCount = event.getTotalAttributeCount() - event.getAttributes().size(); size += MarshalerUtil.sizeUInt32(Span.Event.DROPPED_ATTRIBUTES_COUNT, droppedAttributesCount); diff --git a/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/traces/SpanLinkStatelessMarshaler.java b/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/traces/SpanLinkStatelessMarshaler.java index 0ed091096de..86d3aef37fb 100644 --- a/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/traces/SpanLinkStatelessMarshaler.java +++ b/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/traces/SpanLinkStatelessMarshaler.java @@ -12,7 +12,7 @@ import io.opentelemetry.exporter.internal.marshal.Serializer; import io.opentelemetry.exporter.internal.marshal.StatelessMarshaler; import io.opentelemetry.exporter.internal.marshal.StatelessMarshalerUtil; -import io.opentelemetry.exporter.internal.otlp.KeyValueStatelessMarshaler; +import io.opentelemetry.exporter.internal.otlp.AttributeKeyValueStatelessMarshaler; import io.opentelemetry.proto.trace.v1.internal.Span; import io.opentelemetry.sdk.trace.data.LinkData; import java.io.IOException; @@ -30,7 +30,10 @@ public void writeTo(Serializer output, LinkData link, MarshalerContext context) output.serializeSpanId(Span.Link.SPAN_ID, link.getSpanContext().getSpanId(), context); output.serializeString(Span.Link.TRACE_STATE, context.getData(byte[].class)); output.serializeRepeatedMessageWithContext( - Span.Link.ATTRIBUTES, link.getAttributes(), KeyValueStatelessMarshaler.INSTANCE, context); + Span.Link.ATTRIBUTES, + link.getAttributes(), + AttributeKeyValueStatelessMarshaler.INSTANCE, + context); int droppedAttributesCount = link.getTotalAttributeCount() - link.getAttributes().size(); output.serializeUInt32(Span.Link.DROPPED_ATTRIBUTES_COUNT, droppedAttributesCount); output.serializeFixed32( @@ -52,7 +55,7 @@ public int getBinarySerializedSize(LinkData link, MarshalerContext context) { StatelessMarshalerUtil.sizeRepeatedMessageWithContext( Span.Link.ATTRIBUTES, link.getAttributes(), - KeyValueStatelessMarshaler.INSTANCE, + AttributeKeyValueStatelessMarshaler.INSTANCE, context); int droppedAttributesCount = link.getTotalAttributeCount() - link.getAttributes().size(); size += MarshalerUtil.sizeUInt32(Span.Link.DROPPED_ATTRIBUTES_COUNT, droppedAttributesCount); diff --git a/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/traces/SpanStatelessMarshaler.java b/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/traces/SpanStatelessMarshaler.java index 40adefd143d..acfa5cae85a 100644 --- a/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/traces/SpanStatelessMarshaler.java +++ b/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/traces/SpanStatelessMarshaler.java @@ -13,7 +13,7 @@ import io.opentelemetry.exporter.internal.marshal.Serializer; import io.opentelemetry.exporter.internal.marshal.StatelessMarshaler; import io.opentelemetry.exporter.internal.marshal.StatelessMarshalerUtil; -import io.opentelemetry.exporter.internal.otlp.KeyValueStatelessMarshaler; +import io.opentelemetry.exporter.internal.otlp.AttributeKeyValueStatelessMarshaler; import io.opentelemetry.proto.trace.v1.internal.Span; import io.opentelemetry.sdk.trace.data.SpanData; import java.io.IOException; @@ -43,7 +43,10 @@ public void writeTo(Serializer output, SpanData span, MarshalerContext context) output.serializeFixed64(Span.END_TIME_UNIX_NANO, span.getEndEpochNanos()); output.serializeRepeatedMessageWithContext( - Span.ATTRIBUTES, span.getAttributes(), KeyValueStatelessMarshaler.INSTANCE, context); + Span.ATTRIBUTES, + span.getAttributes(), + AttributeKeyValueStatelessMarshaler.INSTANCE, + context); int droppedAttributesCount = span.getTotalAttributeCount() - span.getAttributes().size(); output.serializeUInt32(Span.DROPPED_ATTRIBUTES_COUNT, droppedAttributesCount); @@ -88,7 +91,10 @@ public int getBinarySerializedSize(SpanData span, MarshalerContext context) { size += StatelessMarshalerUtil.sizeRepeatedMessageWithContext( - Span.ATTRIBUTES, span.getAttributes(), KeyValueStatelessMarshaler.INSTANCE, context); + Span.ATTRIBUTES, + span.getAttributes(), + AttributeKeyValueStatelessMarshaler.INSTANCE, + context); int droppedAttributesCount = span.getTotalAttributeCount() - span.getAttributes().size(); size += MarshalerUtil.sizeUInt32(Span.DROPPED_ATTRIBUTES_COUNT, droppedAttributesCount); diff --git a/exporters/otlp/common/src/test/java/io/opentelemetry/exporter/internal/otlp/AnyValueMarshalerTest.java b/exporters/otlp/common/src/test/java/io/opentelemetry/exporter/internal/otlp/AnyValueMarshalerTest.java index 9514249defb..cd56af8fd84 100644 --- a/exporters/otlp/common/src/test/java/io/opentelemetry/exporter/internal/otlp/AnyValueMarshalerTest.java +++ b/exporters/otlp/common/src/test/java/io/opentelemetry/exporter/internal/otlp/AnyValueMarshalerTest.java @@ -15,7 +15,10 @@ import com.google.protobuf.util.JsonFormat; import io.opentelemetry.api.incubator.logs.KeyAnyValue; import io.opentelemetry.exporter.internal.marshal.Marshaler; +import io.opentelemetry.exporter.internal.marshal.MarshalerContext; import io.opentelemetry.exporter.internal.marshal.MarshalerWithSize; +import io.opentelemetry.exporter.internal.marshal.Serializer; +import io.opentelemetry.exporter.internal.marshal.StatelessMarshaler; import io.opentelemetry.proto.common.v1.AnyValue; import io.opentelemetry.proto.common.v1.ArrayValue; import io.opentelemetry.proto.common.v1.KeyValue; @@ -35,13 +38,22 @@ class AnyValueMarshalerTest { @ParameterizedTest @MethodSource("serializeAnyValueArgs") - void anyValueString( + void anyValueString_StatefulMarshaler( io.opentelemetry.api.incubator.logs.AnyValue anyValue, AnyValue expectedSerializedValue) { MarshalerWithSize marshaler = AnyValueMarshaler.create(anyValue); AnyValue serializedValue = parse(AnyValue.getDefaultInstance(), marshaler); assertThat(serializedValue).isEqualTo(expectedSerializedValue); } + @ParameterizedTest + @MethodSource("serializeAnyValueArgs") + void anyValueString_StatelessMarshaler( + io.opentelemetry.api.incubator.logs.AnyValue anyValue, AnyValue expectedSerializedValue) { + Marshaler marshaler = createMarshaler(AnyValueStatelessMarshaler.INSTANCE, anyValue); + AnyValue serializedValue = parse(AnyValue.getDefaultInstance(), marshaler); + assertThat(serializedValue).isEqualTo(expectedSerializedValue); + } + private static Stream serializeAnyValueArgs() { return Stream.of( // primitives @@ -167,4 +179,22 @@ private static String toJson(Marshaler marshaler) { } return new String(bos.toByteArray(), StandardCharsets.UTF_8); } + + private static Marshaler createMarshaler(StatelessMarshaler marshaler, T data) { + return new Marshaler() { + private final MarshalerContext context = new MarshalerContext(); + private final int size = marshaler.getBinarySerializedSize(data, context); + + @Override + public int getBinarySerializedSize() { + return size; + } + + @Override + protected void writeTo(Serializer output) throws IOException { + context.resetReadIndex(); + marshaler.writeTo(output, data, context); + } + }; + } } diff --git a/exporters/otlp/common/src/test/java/io/opentelemetry/exporter/internal/otlp/logs/LogsRequestMarshalerTest.java b/exporters/otlp/common/src/test/java/io/opentelemetry/exporter/internal/otlp/logs/LogsRequestMarshalerTest.java index 306cfe1ea14..9c01ddc7aed 100644 --- a/exporters/otlp/common/src/test/java/io/opentelemetry/exporter/internal/otlp/logs/LogsRequestMarshalerTest.java +++ b/exporters/otlp/common/src/test/java/io/opentelemetry/exporter/internal/otlp/logs/LogsRequestMarshalerTest.java @@ -21,6 +21,9 @@ import io.opentelemetry.api.trace.TraceId; import io.opentelemetry.api.trace.TraceState; import io.opentelemetry.exporter.internal.marshal.Marshaler; +import io.opentelemetry.exporter.internal.marshal.MarshalerContext; +import io.opentelemetry.exporter.internal.marshal.Serializer; +import io.opentelemetry.exporter.internal.marshal.StatelessMarshaler; import io.opentelemetry.proto.common.v1.AnyValue; import io.opentelemetry.proto.common.v1.InstrumentationScope; import io.opentelemetry.proto.common.v1.KeyValue; @@ -28,6 +31,7 @@ import io.opentelemetry.proto.logs.v1.ResourceLogs; import io.opentelemetry.proto.logs.v1.ScopeLogs; import io.opentelemetry.sdk.common.InstrumentationScopeInfo; +import io.opentelemetry.sdk.logs.data.LogRecordData; import io.opentelemetry.sdk.resources.Resource; import io.opentelemetry.sdk.testing.logs.TestLogRecordData; import java.io.ByteArrayOutputStream; @@ -39,6 +43,8 @@ import java.util.Locale; import java.util.concurrent.TimeUnit; import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.EnumSource; class LogsRequestMarshalerTest { private static final byte[] TRACE_ID_BYTES = @@ -95,12 +101,13 @@ void toProtoResourceLogs() { .build()); } - @Test - void toProtoLogRecord() { + @ParameterizedTest + @EnumSource(MarshalerSource.class) + void toProtoLogRecord(MarshalerSource marshalerSource) { LogRecord logRecord = parse( LogRecord.getDefaultInstance(), - LogMarshaler.create( + marshalerSource.create( TestLogRecordData.builder() .setResource( Resource.create(Attributes.builder().put("testKey", "testValue").build())) @@ -133,12 +140,13 @@ void toProtoLogRecord() { assertThat(logRecord.getObservedTimeUnixNano()).isEqualTo(6789); } - @Test - void toProtoLogRecord_MinimalFields() { + @ParameterizedTest + @EnumSource(MarshalerSource.class) + void toProtoLogRecord_MinimalFields(MarshalerSource marshalerSource) { LogRecord logRecord = parse( LogRecord.getDefaultInstance(), - LogMarshaler.create( + marshalerSource.create( TestLogRecordData.builder() .setResource( Resource.create(Attributes.builder().put("testKey", "testValue").build())) @@ -153,7 +161,7 @@ void toProtoLogRecord_MinimalFields() { assertThat(logRecord.getSeverityText()).isBlank(); assertThat(logRecord.getSeverityNumber().getNumber()) .isEqualTo(Severity.UNDEFINED_SEVERITY_NUMBER.getSeverityNumber()); - assertThat(logRecord.getBody()).isEqualTo(AnyValue.newBuilder().setStringValue("").build()); + assertThat(logRecord.getBody()).isEqualTo(AnyValue.newBuilder().build()); assertThat(logRecord.getAttributesList()).isEmpty(); assertThat(logRecord.getDroppedAttributesCount()).isZero(); assertThat(logRecord.getTimeUnixNano()).isEqualTo(12345); @@ -239,4 +247,39 @@ private static String toJson(Marshaler marshaler) { } return new String(bos.toByteArray(), StandardCharsets.UTF_8); } + + private static Marshaler createMarshaler(StatelessMarshaler marshaler, T data) { + return new Marshaler() { + private final MarshalerContext context = new MarshalerContext(); + private final int size = marshaler.getBinarySerializedSize(data, context); + + @Override + public int getBinarySerializedSize() { + return size; + } + + @Override + protected void writeTo(Serializer output) throws IOException { + context.resetReadIndex(); + marshaler.writeTo(output, data, context); + } + }; + } + + private enum MarshalerSource { + MARSHALER { + @Override + Marshaler create(LogRecordData logData) { + return LogMarshaler.create(logData); + } + }, + LOW_ALLOCATION_MARSHALER { + @Override + Marshaler create(LogRecordData logData) { + return createMarshaler(LogStatelessMarshaler.INSTANCE, logData); + } + }; + + abstract Marshaler create(LogRecordData logData); + } } diff --git a/exporters/otlp/common/src/test/java/io/opentelemetry/exporter/internal/otlp/logs/LowAllocationLogRequestMarshalerTest.java b/exporters/otlp/common/src/test/java/io/opentelemetry/exporter/internal/otlp/logs/LowAllocationLogRequestMarshalerTest.java new file mode 100644 index 00000000000..4890e02dd66 --- /dev/null +++ b/exporters/otlp/common/src/test/java/io/opentelemetry/exporter/internal/otlp/logs/LowAllocationLogRequestMarshalerTest.java @@ -0,0 +1,142 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.exporter.internal.otlp.logs; + +import static org.assertj.core.api.Assertions.assertThat; + +import io.opentelemetry.api.common.AttributeKey; +import io.opentelemetry.api.common.Attributes; +import io.opentelemetry.api.logs.Severity; +import io.opentelemetry.api.trace.SpanContext; +import io.opentelemetry.api.trace.TraceFlags; +import io.opentelemetry.api.trace.TraceState; +import io.opentelemetry.sdk.common.InstrumentationScopeInfo; +import io.opentelemetry.sdk.logs.data.LogRecordData; +import io.opentelemetry.sdk.resources.Resource; +import io.opentelemetry.sdk.testing.logs.TestLogRecordData; +import java.io.ByteArrayOutputStream; +import java.nio.charset.StandardCharsets; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.concurrent.TimeUnit; +import org.junit.jupiter.api.Test; + +class LowAllocationLogRequestMarshalerTest { + + private static final AttributeKey KEY_BOOL = AttributeKey.booleanKey("key_bool"); + private static final AttributeKey KEY_STRING = AttributeKey.stringKey("key_string"); + private static final AttributeKey KEY_INT = AttributeKey.longKey("key_int"); + private static final AttributeKey KEY_DOUBLE = AttributeKey.doubleKey("key_double"); + private static final AttributeKey> KEY_STRING_ARRAY = + AttributeKey.stringArrayKey("key_string_array"); + private static final AttributeKey> KEY_LONG_ARRAY = + AttributeKey.longArrayKey("key_long_array"); + private static final AttributeKey> KEY_DOUBLE_ARRAY = + AttributeKey.doubleArrayKey("key_double_array"); + private static final AttributeKey> KEY_BOOLEAN_ARRAY = + AttributeKey.booleanArrayKey("key_boolean_array"); + private static final String BODY = "Hello world from this log..."; + + private static final Resource RESOURCE = + Resource.create( + Attributes.builder() + .put(KEY_BOOL, true) + .put(KEY_STRING, "string") + .put(KEY_INT, 100L) + .put(KEY_DOUBLE, 100.3) + .put(KEY_STRING_ARRAY, Arrays.asList("string", "string")) + .put(KEY_LONG_ARRAY, Arrays.asList(12L, 23L)) + .put(KEY_DOUBLE_ARRAY, Arrays.asList(12.3, 23.1)) + .put(KEY_BOOLEAN_ARRAY, Arrays.asList(true, false)) + .build()); + + private static final InstrumentationScopeInfo INSTRUMENTATION_SCOPE_INFO = + InstrumentationScopeInfo.create("name"); + private static final String TRACE_ID = "7b2e170db4df2d593ddb4ddf2ddf2d59"; + private static final String SPAN_ID = "170d3ddb4d23e81f"; + private static final SpanContext SPAN_CONTEXT = + SpanContext.create(TRACE_ID, SPAN_ID, TraceFlags.getSampled(), TraceState.getDefault()); + + private final List logRecordDataList = createLogRecordDataList(); + + private static List createLogRecordDataList() { + List logRecordDataList = new ArrayList<>(); + for (int i = 0; i < 5; i++) { + logRecordDataList.add(createLogRecordData()); + } + return logRecordDataList; + } + + private static LogRecordData createLogRecordData() { + return TestLogRecordData.builder() + .setResource(RESOURCE) + .setInstrumentationScopeInfo(INSTRUMENTATION_SCOPE_INFO) + .setBody(BODY) + .setSeverity(Severity.INFO) + .setSeverityText("INFO") + .setSpanContext(SPAN_CONTEXT) + .setAttributes( + Attributes.builder() + .put(KEY_BOOL, true) + .put(KEY_STRING, "string") + .put(KEY_INT, 100L) + .put(KEY_DOUBLE, 100.3) + .build()) + .setTotalAttributeCount(2) + .setTimestamp(12345, TimeUnit.NANOSECONDS) + .setObservedTimestamp(6789, TimeUnit.NANOSECONDS) + .build(); + } + + @Test + void validateOutput() throws Exception { + byte[] result; + { + LogsRequestMarshaler requestMarshaler = LogsRequestMarshaler.create(logRecordDataList); + ByteArrayOutputStream customOutput = + new ByteArrayOutputStream(requestMarshaler.getBinarySerializedSize()); + requestMarshaler.writeBinaryTo(customOutput); + result = customOutput.toByteArray(); + } + + byte[] lowAllocationResult; + { + LowAllocationLogsRequestMarshaler requestMarshaler = new LowAllocationLogsRequestMarshaler(); + requestMarshaler.initialize(logRecordDataList); + ByteArrayOutputStream customOutput = + new ByteArrayOutputStream(requestMarshaler.getBinarySerializedSize()); + requestMarshaler.writeBinaryTo(customOutput); + lowAllocationResult = customOutput.toByteArray(); + } + + assertThat(lowAllocationResult).isEqualTo(result); + } + + @Test + void validateJsonOutput() throws Exception { + String result; + { + LogsRequestMarshaler requestMarshaler = LogsRequestMarshaler.create(logRecordDataList); + ByteArrayOutputStream customOutput = + new ByteArrayOutputStream(requestMarshaler.getBinarySerializedSize()); + requestMarshaler.writeJsonTo(customOutput); + result = new String(customOutput.toByteArray(), StandardCharsets.UTF_8); + } + + String lowAllocationResult; + { + LowAllocationLogsRequestMarshaler requestMarshaler = new LowAllocationLogsRequestMarshaler(); + requestMarshaler.initialize(logRecordDataList); + ByteArrayOutputStream customOutput = + new ByteArrayOutputStream(requestMarshaler.getBinarySerializedSize()); + requestMarshaler.writeJsonTo(customOutput); + lowAllocationResult = new String(customOutput.toByteArray(), StandardCharsets.UTF_8); + } + + assertThat(lowAllocationResult).isEqualTo(result); + } +} From 0d2d67efe4b2bd9c75e15349adda53dafcf1f09b Mon Sep 17 00:00:00 2001 From: jack-berg <34418638+jack-berg@users.noreply.github.com> Date: Thu, 9 May 2024 12:51:53 -0500 Subject: [PATCH 394/901] Add memory mode support to OTLP exporters (#6430) --- .../otlp/trace/OltpExporterBenchmark.java | 3 +- .../http/logs/OtlpHttpLogRecordExporter.java | 45 +++++++++++++--- .../OtlpHttpLogRecordExporterBuilder.java | 21 ++++++-- .../http/metrics/OtlpHttpMetricExporter.java | 33 +++++++++--- .../OtlpHttpMetricExporterBuilder.java | 7 ++- .../otlp/http/trace/OtlpHttpSpanExporter.java | 45 +++++++++++++--- .../trace/OtlpHttpSpanExporterBuilder.java | 21 ++++++-- .../otlp/internal/OtlpConfigUtil.java | 52 +++++++++++++++++-- .../OtlpLogRecordExporterProvider.java | 7 +++ .../internal/OtlpMetricExporterProvider.java | 6 +-- .../internal/OtlpSpanExporterProvider.java | 8 ++- .../otlp/logs/MarshalerLogsServiceGrpc.java | 30 +++++------ .../otlp/logs/OtlpGrpcLogRecordExporter.java | 41 ++++++++++++--- .../OtlpGrpcLogRecordExporterBuilder.java | 22 ++++++-- .../exporter/otlp/logs/OtlpGrpcLogUtil.java | 19 +++++++ .../metrics/MarshalerMetricsServiceGrpc.java | 29 +++++------ .../otlp/metrics/OtlpGrpcMetricExporter.java | 30 +++++++++-- .../OtlpGrpcMetricExporterBuilder.java | 7 ++- .../otlp/metrics/OtlpGrpcMetricUtil.java | 2 +- .../otlp/trace/MarshalerTraceServiceGrpc.java | 19 ++++--- .../otlp/trace/OtlpGrpcSpanExporter.java | 42 ++++++++++++--- .../trace/OtlpGrpcSpanExporterBuilder.java | 22 ++++++-- .../exporter/otlp/trace/OtlpGrpcSpanUtil.java | 19 +++++++ .../OtlpLogRecordExporterProviderTest.java | 7 +++ .../OtlpSpanExporterProviderTest.java | 8 +++ .../OtlpHttpSpanExporterOkHttpSenderTest.java | 30 +++++++++++ .../otlp/traces/OtlpGrpcSpanExporterTest.java | 26 ++++++++++ .../otlp/KeyValueStatelessMarshaler.java | 4 +- .../metrics/ExemplarStatelessMarshaler.java | 6 +-- ...lHistogramDataPointStatelessMarshaler.java | 6 +-- .../HistogramDataPointStatelessMarshaler.java | 6 +-- .../NumberDataPointStatelessMarshaler.java | 6 +-- .../SummaryDataPointStatelessMarshaler.java | 6 +-- .../OtlpExporterIntegrationTest.java | 4 +- 34 files changed, 499 insertions(+), 140 deletions(-) create mode 100644 exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/logs/OtlpGrpcLogUtil.java create mode 100644 exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/trace/OtlpGrpcSpanUtil.java diff --git a/exporters/otlp/all/src/jmh/java/io/opentelemetry/exporter/otlp/trace/OltpExporterBenchmark.java b/exporters/otlp/all/src/jmh/java/io/opentelemetry/exporter/otlp/trace/OltpExporterBenchmark.java index ba6492547c7..5dc9f2107c8 100644 --- a/exporters/otlp/all/src/jmh/java/io/opentelemetry/exporter/otlp/trace/OltpExporterBenchmark.java +++ b/exporters/otlp/all/src/jmh/java/io/opentelemetry/exporter/otlp/trace/OltpExporterBenchmark.java @@ -15,6 +15,7 @@ import io.opentelemetry.exporter.internal.grpc.GrpcExporter; import io.opentelemetry.exporter.internal.http.HttpExporter; import io.opentelemetry.exporter.internal.http.HttpExporterBuilder; +import io.opentelemetry.exporter.internal.marshal.Marshaler; import io.opentelemetry.exporter.internal.otlp.traces.TraceRequestMarshaler; import io.opentelemetry.exporter.sender.grpc.managedchannel.internal.UpstreamGrpcSender; import io.opentelemetry.exporter.sender.okhttp.internal.OkHttpGrpcSender; @@ -67,7 +68,7 @@ public void export( private static ManagedChannel defaultGrpcChannel; - private static GrpcExporter upstreamGrpcExporter; + private static GrpcExporter upstreamGrpcExporter; private static GrpcExporter okhttpGrpcSender; private static HttpExporter httpExporter; diff --git a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/logs/OtlpHttpLogRecordExporter.java b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/logs/OtlpHttpLogRecordExporter.java index de48a358f41..4f3202ceb99 100644 --- a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/logs/OtlpHttpLogRecordExporter.java +++ b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/logs/OtlpHttpLogRecordExporter.java @@ -7,11 +7,17 @@ import io.opentelemetry.exporter.internal.http.HttpExporter; import io.opentelemetry.exporter.internal.http.HttpExporterBuilder; +import io.opentelemetry.exporter.internal.marshal.Marshaler; import io.opentelemetry.exporter.internal.otlp.logs.LogsRequestMarshaler; +import io.opentelemetry.exporter.internal.otlp.logs.LowAllocationLogsRequestMarshaler; import io.opentelemetry.sdk.common.CompletableResultCode; +import io.opentelemetry.sdk.common.export.MemoryMode; import io.opentelemetry.sdk.logs.data.LogRecordData; import io.opentelemetry.sdk.logs.export.LogRecordExporter; +import java.util.ArrayDeque; import java.util.Collection; +import java.util.Deque; +import java.util.StringJoiner; import javax.annotation.concurrent.ThreadSafe; /** @@ -22,14 +28,18 @@ @ThreadSafe public final class OtlpHttpLogRecordExporter implements LogRecordExporter { - private final HttpExporterBuilder builder; - private final HttpExporter delegate; + private final Deque marshalerPool = new ArrayDeque<>(); + private final HttpExporterBuilder builder; + private final HttpExporter delegate; + private final MemoryMode memoryMode; OtlpHttpLogRecordExporter( - HttpExporterBuilder builder, - HttpExporter delegate) { + HttpExporterBuilder builder, + HttpExporter delegate, + MemoryMode memoryMode) { this.builder = builder; this.delegate = delegate; + this.memoryMode = memoryMode; } /** @@ -61,7 +71,7 @@ public static OtlpHttpLogRecordExporterBuilder builder() { * @since 1.29.0 */ public OtlpHttpLogRecordExporterBuilder toBuilder() { - return new OtlpHttpLogRecordExporterBuilder(builder.copy()); + return new OtlpHttpLogRecordExporterBuilder(builder.copy(), memoryMode); } /** @@ -72,8 +82,24 @@ public OtlpHttpLogRecordExporterBuilder toBuilder() { */ @Override public CompletableResultCode export(Collection logs) { - LogsRequestMarshaler exportRequest = LogsRequestMarshaler.create(logs); - return delegate.export(exportRequest, logs.size()); + if (memoryMode == MemoryMode.REUSABLE_DATA) { + LowAllocationLogsRequestMarshaler marshaler = marshalerPool.poll(); + if (marshaler == null) { + marshaler = new LowAllocationLogsRequestMarshaler(); + } + LowAllocationLogsRequestMarshaler exportMarshaler = marshaler; + exportMarshaler.initialize(logs); + return delegate + .export(exportMarshaler, logs.size()) + .whenComplete( + () -> { + exportMarshaler.reset(); + marshalerPool.add(exportMarshaler); + }); + } + // MemoryMode == MemoryMode.IMMUTABLE_DATA + LogsRequestMarshaler request = LogsRequestMarshaler.create(logs); + return delegate.export(request, logs.size()); } @Override @@ -89,6 +115,9 @@ public CompletableResultCode shutdown() { @Override public String toString() { - return "OtlpHttpLogRecordExporter{" + builder.toString(false) + "}"; + StringJoiner joiner = new StringJoiner(", ", "OtlpHttpLogRecordExporter{", "}"); + joiner.add(builder.toString(false)); + joiner.add("memoryMode=" + memoryMode); + return joiner.toString(); } } diff --git a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/logs/OtlpHttpLogRecordExporterBuilder.java b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/logs/OtlpHttpLogRecordExporterBuilder.java index 4d330c42546..619914f26e3 100644 --- a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/logs/OtlpHttpLogRecordExporterBuilder.java +++ b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/logs/OtlpHttpLogRecordExporterBuilder.java @@ -14,8 +14,9 @@ import io.opentelemetry.exporter.internal.compression.CompressorProvider; import io.opentelemetry.exporter.internal.compression.CompressorUtil; import io.opentelemetry.exporter.internal.http.HttpExporterBuilder; -import io.opentelemetry.exporter.internal.otlp.logs.LogsRequestMarshaler; +import io.opentelemetry.exporter.internal.marshal.Marshaler; import io.opentelemetry.exporter.otlp.internal.OtlpUserAgent; +import io.opentelemetry.sdk.common.export.MemoryMode; import io.opentelemetry.sdk.common.export.ProxyOptions; import io.opentelemetry.sdk.common.export.RetryPolicy; import java.time.Duration; @@ -33,16 +34,19 @@ public final class OtlpHttpLogRecordExporterBuilder { private static final String DEFAULT_ENDPOINT = "http://localhost:4318/v1/logs"; + private static final MemoryMode DEFAULT_MEMORY_MODE = MemoryMode.IMMUTABLE_DATA; - private final HttpExporterBuilder delegate; + private final HttpExporterBuilder delegate; + private MemoryMode memoryMode; - OtlpHttpLogRecordExporterBuilder(HttpExporterBuilder delegate) { + OtlpHttpLogRecordExporterBuilder(HttpExporterBuilder delegate, MemoryMode memoryMode) { this.delegate = delegate; + this.memoryMode = memoryMode; OtlpUserAgent.addUserAgentHeader(delegate::addConstantHeaders); } OtlpHttpLogRecordExporterBuilder() { - this(new HttpExporterBuilder<>("otlp", "log", DEFAULT_ENDPOINT)); + this(new HttpExporterBuilder<>("otlp", "log", DEFAULT_ENDPOINT), DEFAULT_MEMORY_MODE); } /** @@ -206,12 +210,19 @@ public OtlpHttpLogRecordExporterBuilder setMeterProvider( return this; } + /** Set the {@link MemoryMode}. */ + OtlpHttpLogRecordExporterBuilder setMemoryMode(MemoryMode memoryMode) { + requireNonNull(memoryMode, "memoryMode"); + this.memoryMode = memoryMode; + return this; + } + /** * Constructs a new instance of the exporter based on the builder's values. * * @return a new exporter's instance */ public OtlpHttpLogRecordExporter build() { - return new OtlpHttpLogRecordExporter(delegate, delegate.build()); + return new OtlpHttpLogRecordExporter(delegate, delegate.build(), memoryMode); } } diff --git a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/metrics/OtlpHttpMetricExporter.java b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/metrics/OtlpHttpMetricExporter.java index e361bb5d2da..1634d47fee5 100644 --- a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/metrics/OtlpHttpMetricExporter.java +++ b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/metrics/OtlpHttpMetricExporter.java @@ -7,6 +7,8 @@ import io.opentelemetry.exporter.internal.http.HttpExporter; import io.opentelemetry.exporter.internal.http.HttpExporterBuilder; +import io.opentelemetry.exporter.internal.marshal.Marshaler; +import io.opentelemetry.exporter.internal.otlp.metrics.LowAllocationMetricsRequestMarshaler; import io.opentelemetry.exporter.internal.otlp.metrics.MetricsRequestMarshaler; import io.opentelemetry.sdk.common.CompletableResultCode; import io.opentelemetry.sdk.common.export.MemoryMode; @@ -17,7 +19,9 @@ import io.opentelemetry.sdk.metrics.export.AggregationTemporalitySelector; import io.opentelemetry.sdk.metrics.export.DefaultAggregationSelector; import io.opentelemetry.sdk.metrics.export.MetricExporter; +import java.util.ArrayDeque; import java.util.Collection; +import java.util.Deque; import java.util.StringJoiner; import javax.annotation.concurrent.ThreadSafe; @@ -29,15 +33,16 @@ @ThreadSafe public final class OtlpHttpMetricExporter implements MetricExporter { - private final HttpExporterBuilder builder; - private final HttpExporter delegate; + private final Deque marshalerPool = new ArrayDeque<>(); + private final HttpExporterBuilder builder; + private final HttpExporter delegate; private final AggregationTemporalitySelector aggregationTemporalitySelector; private final DefaultAggregationSelector defaultAggregationSelector; private final MemoryMode memoryMode; OtlpHttpMetricExporter( - HttpExporterBuilder builder, - HttpExporter delegate, + HttpExporterBuilder builder, + HttpExporter delegate, AggregationTemporalitySelector aggregationTemporalitySelector, DefaultAggregationSelector defaultAggregationSelector, MemoryMode memoryMode) { @@ -103,8 +108,24 @@ public MemoryMode getMemoryMode() { */ @Override public CompletableResultCode export(Collection metrics) { - MetricsRequestMarshaler exportRequest = MetricsRequestMarshaler.create(metrics); - return delegate.export(exportRequest, metrics.size()); + if (memoryMode == MemoryMode.REUSABLE_DATA) { + LowAllocationMetricsRequestMarshaler marshaler = marshalerPool.poll(); + if (marshaler == null) { + marshaler = new LowAllocationMetricsRequestMarshaler(); + } + LowAllocationMetricsRequestMarshaler exportMarshaler = marshaler; + exportMarshaler.initialize(metrics); + return delegate + .export(exportMarshaler, metrics.size()) + .whenComplete( + () -> { + exportMarshaler.reset(); + marshalerPool.add(exportMarshaler); + }); + } + // MemoryMode == MemoryMode.IMMUTABLE_DATA + MetricsRequestMarshaler request = MetricsRequestMarshaler.create(metrics); + return delegate.export(request, metrics.size()); } /** diff --git a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/metrics/OtlpHttpMetricExporterBuilder.java b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/metrics/OtlpHttpMetricExporterBuilder.java index 8390d5e03b3..e3b23aa77e0 100644 --- a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/metrics/OtlpHttpMetricExporterBuilder.java +++ b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/metrics/OtlpHttpMetricExporterBuilder.java @@ -13,7 +13,7 @@ import io.opentelemetry.exporter.internal.compression.CompressorProvider; import io.opentelemetry.exporter.internal.compression.CompressorUtil; import io.opentelemetry.exporter.internal.http.HttpExporterBuilder; -import io.opentelemetry.exporter.internal.otlp.metrics.MetricsRequestMarshaler; +import io.opentelemetry.exporter.internal.marshal.Marshaler; import io.opentelemetry.exporter.otlp.internal.OtlpUserAgent; import io.opentelemetry.sdk.common.export.MemoryMode; import io.opentelemetry.sdk.common.export.ProxyOptions; @@ -42,7 +42,7 @@ public final class OtlpHttpMetricExporterBuilder { AggregationTemporalitySelector.alwaysCumulative(); private static final MemoryMode DEFAULT_MEMORY_MODE = MemoryMode.IMMUTABLE_DATA; - private final HttpExporterBuilder delegate; + private final HttpExporterBuilder delegate; private AggregationTemporalitySelector aggregationTemporalitySelector = DEFAULT_AGGREGATION_TEMPORALITY_SELECTOR; @@ -50,8 +50,7 @@ public final class OtlpHttpMetricExporterBuilder { DefaultAggregationSelector.getDefault(); private MemoryMode memoryMode; - OtlpHttpMetricExporterBuilder( - HttpExporterBuilder delegate, MemoryMode memoryMode) { + OtlpHttpMetricExporterBuilder(HttpExporterBuilder delegate, MemoryMode memoryMode) { this.delegate = delegate; this.memoryMode = memoryMode; delegate.setMeterProvider(MeterProvider::noop); diff --git a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/trace/OtlpHttpSpanExporter.java b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/trace/OtlpHttpSpanExporter.java index d693090e316..86d4016adb6 100644 --- a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/trace/OtlpHttpSpanExporter.java +++ b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/trace/OtlpHttpSpanExporter.java @@ -7,11 +7,17 @@ import io.opentelemetry.exporter.internal.http.HttpExporter; import io.opentelemetry.exporter.internal.http.HttpExporterBuilder; +import io.opentelemetry.exporter.internal.marshal.Marshaler; +import io.opentelemetry.exporter.internal.otlp.traces.LowAllocationTraceRequestMarshaler; import io.opentelemetry.exporter.internal.otlp.traces.TraceRequestMarshaler; import io.opentelemetry.sdk.common.CompletableResultCode; +import io.opentelemetry.sdk.common.export.MemoryMode; import io.opentelemetry.sdk.trace.data.SpanData; import io.opentelemetry.sdk.trace.export.SpanExporter; +import java.util.ArrayDeque; import java.util.Collection; +import java.util.Deque; +import java.util.StringJoiner; import javax.annotation.concurrent.ThreadSafe; /** @@ -22,14 +28,18 @@ @ThreadSafe public final class OtlpHttpSpanExporter implements SpanExporter { - private final HttpExporterBuilder builder; - private final HttpExporter delegate; + private final Deque marshalerPool = new ArrayDeque<>(); + private final HttpExporterBuilder builder; + private final HttpExporter delegate; + private final MemoryMode memoryMode; OtlpHttpSpanExporter( - HttpExporterBuilder builder, - HttpExporter delegate) { + HttpExporterBuilder builder, + HttpExporter delegate, + MemoryMode memoryMode) { this.builder = builder; this.delegate = delegate; + this.memoryMode = memoryMode; } /** @@ -61,7 +71,7 @@ public static OtlpHttpSpanExporterBuilder builder() { * @since 1.29.0 */ public OtlpHttpSpanExporterBuilder toBuilder() { - return new OtlpHttpSpanExporterBuilder(builder.copy()); + return new OtlpHttpSpanExporterBuilder(builder.copy(), memoryMode); } /** @@ -72,8 +82,24 @@ public OtlpHttpSpanExporterBuilder toBuilder() { */ @Override public CompletableResultCode export(Collection spans) { - TraceRequestMarshaler exportRequest = TraceRequestMarshaler.create(spans); - return delegate.export(exportRequest, spans.size()); + if (memoryMode == MemoryMode.REUSABLE_DATA) { + LowAllocationTraceRequestMarshaler marshaler = marshalerPool.poll(); + if (marshaler == null) { + marshaler = new LowAllocationTraceRequestMarshaler(); + } + LowAllocationTraceRequestMarshaler exportMarshaler = marshaler; + exportMarshaler.initialize(spans); + return delegate + .export(exportMarshaler, spans.size()) + .whenComplete( + () -> { + exportMarshaler.reset(); + marshalerPool.add(exportMarshaler); + }); + } + // MemoryMode == MemoryMode.IMMUTABLE_DATA + TraceRequestMarshaler request = TraceRequestMarshaler.create(spans); + return delegate.export(request, spans.size()); } /** @@ -94,6 +120,9 @@ public CompletableResultCode shutdown() { @Override public String toString() { - return "OtlpHttpSpanExporter{" + builder.toString(false) + "}"; + StringJoiner joiner = new StringJoiner(", ", "OtlpHttpSpanExporter{", "}"); + joiner.add(builder.toString(false)); + joiner.add("memoryMode=" + memoryMode); + return joiner.toString(); } } diff --git a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/trace/OtlpHttpSpanExporterBuilder.java b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/trace/OtlpHttpSpanExporterBuilder.java index e5039c61907..1c735001ebf 100644 --- a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/trace/OtlpHttpSpanExporterBuilder.java +++ b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/trace/OtlpHttpSpanExporterBuilder.java @@ -14,8 +14,9 @@ import io.opentelemetry.exporter.internal.compression.CompressorProvider; import io.opentelemetry.exporter.internal.compression.CompressorUtil; import io.opentelemetry.exporter.internal.http.HttpExporterBuilder; -import io.opentelemetry.exporter.internal.otlp.traces.TraceRequestMarshaler; +import io.opentelemetry.exporter.internal.marshal.Marshaler; import io.opentelemetry.exporter.otlp.internal.OtlpUserAgent; +import io.opentelemetry.sdk.common.export.MemoryMode; import io.opentelemetry.sdk.common.export.ProxyOptions; import io.opentelemetry.sdk.common.export.RetryPolicy; import java.time.Duration; @@ -33,16 +34,19 @@ public final class OtlpHttpSpanExporterBuilder { private static final String DEFAULT_ENDPOINT = "http://localhost:4318/v1/traces"; + private static final MemoryMode DEFAULT_MEMORY_MODE = MemoryMode.IMMUTABLE_DATA; - private final HttpExporterBuilder delegate; + private final HttpExporterBuilder delegate; + private MemoryMode memoryMode; - OtlpHttpSpanExporterBuilder(HttpExporterBuilder delegate) { + OtlpHttpSpanExporterBuilder(HttpExporterBuilder delegate, MemoryMode memoryMode) { this.delegate = delegate; + this.memoryMode = memoryMode; OtlpUserAgent.addUserAgentHeader(delegate::addConstantHeaders); } OtlpHttpSpanExporterBuilder() { - this(new HttpExporterBuilder<>("otlp", "span", DEFAULT_ENDPOINT)); + this(new HttpExporterBuilder<>("otlp", "span", DEFAULT_ENDPOINT), DEFAULT_MEMORY_MODE); } /** @@ -207,12 +211,19 @@ public OtlpHttpSpanExporterBuilder setMeterProvider( return this; } + /** Set the {@link MemoryMode}. */ + OtlpHttpSpanExporterBuilder setMemoryMode(MemoryMode memoryMode) { + requireNonNull(memoryMode, "memoryMode"); + this.memoryMode = memoryMode; + return this; + } + /** * Constructs a new instance of the exporter based on the builder's values. * * @return a new exporter's instance */ public OtlpHttpSpanExporter build() { - return new OtlpHttpSpanExporter(delegate, delegate.build()); + return new OtlpHttpSpanExporter(delegate, delegate.build(), memoryMode); } } diff --git a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/OtlpConfigUtil.java b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/OtlpConfigUtil.java index 5bd08742b09..c06d5f1f60e 100644 --- a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/OtlpConfigUtil.java +++ b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/OtlpConfigUtil.java @@ -7,8 +7,12 @@ import static io.opentelemetry.sdk.metrics.Aggregation.explicitBucketHistogram; +import io.opentelemetry.exporter.otlp.http.logs.OtlpHttpLogRecordExporterBuilder; import io.opentelemetry.exporter.otlp.http.metrics.OtlpHttpMetricExporterBuilder; +import io.opentelemetry.exporter.otlp.http.trace.OtlpHttpSpanExporterBuilder; +import io.opentelemetry.exporter.otlp.logs.OtlpGrpcLogRecordExporterBuilder; import io.opentelemetry.exporter.otlp.metrics.OtlpGrpcMetricExporterBuilder; +import io.opentelemetry.exporter.otlp.trace.OtlpGrpcSpanExporterBuilder; import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties; import io.opentelemetry.sdk.autoconfigure.spi.ConfigurationException; import io.opentelemetry.sdk.common.export.MemoryMode; @@ -212,12 +216,12 @@ public static void configureOtlpHistogramDefaultAggregation( } /** - * Calls {@code #setMemoryMode} on the {@code Otlp{Protocol}MetricExporterBuilder} with the {@code - * memoryMode}. + * Calls {@code #setMemoryMode} on the {@code Otlp{Protocol}{Signal}ExporterBuilder} with the + * {@code memoryMode}. */ - public static void setMemoryModeOnOtlpMetricExporterBuilder( - Object builder, MemoryMode memoryMode) { + public static void setMemoryModeOnOtlpExporterBuilder(Object builder, MemoryMode memoryMode) { try { + // Metrics if (builder instanceof OtlpGrpcMetricExporterBuilder) { // Calling getDeclaredMethod causes all private methods to be read, which causes a // ClassNotFoundException when running with the OkHttHttpProvider as the private @@ -237,9 +241,47 @@ public static void setMemoryModeOnOtlpMetricExporterBuilder( "setMemoryMode", MemoryMode.class); method.setAccessible(true); method.invoke(builder, memoryMode); + } else if (builder instanceof OtlpGrpcSpanExporterBuilder) { + // Calling getDeclaredMethod causes all private methods to be read, which causes a + // ClassNotFoundException when running with the OkHttHttpProvider as the private + // setManagedChanel(io.grpc.ManagedChannel) is reached and io.grpc.ManagedChannel is not on + // the classpath. io.opentelemetry.exporter.otlp.trace.OtlpGrpcSpanUtil provides a layer + // of indirection which avoids scanning the OtlpGrpcSpanExporterBuilder private methods. + Class otlpGrpcMetricUtil = + Class.forName("io.opentelemetry.exporter.otlp.trace.OtlpGrpcSpanUtil"); + Method method = + otlpGrpcMetricUtil.getDeclaredMethod( + "setMemoryMode", OtlpGrpcSpanExporterBuilder.class, MemoryMode.class); + method.setAccessible(true); + method.invoke(null, builder, memoryMode); + } else if (builder instanceof OtlpHttpSpanExporterBuilder) { + Method method = + OtlpHttpSpanExporterBuilder.class.getDeclaredMethod("setMemoryMode", MemoryMode.class); + method.setAccessible(true); + method.invoke(builder, memoryMode); + } else if (builder instanceof OtlpGrpcLogRecordExporterBuilder) { + // Calling getDeclaredMethod causes all private methods to be read, which causes a + // ClassNotFoundException when running with the OkHttHttpProvider as the private + // setManagedChanel(io.grpc.ManagedChannel) is reached and io.grpc.ManagedChannel is not on + // the classpath. io.opentelemetry.exporter.otlp.logs.OtlpGrpcLogUtil provides a layer + // of indirection which avoids scanning the OtlpGrpcLogRecordExporterBuilder private + // methods. + Class otlpGrpcMetricUtil = + Class.forName("io.opentelemetry.exporter.otlp.logs.OtlpGrpcLogUtil"); + Method method = + otlpGrpcMetricUtil.getDeclaredMethod( + "setMemoryMode", OtlpGrpcLogRecordExporterBuilder.class, MemoryMode.class); + method.setAccessible(true); + method.invoke(null, builder, memoryMode); + } else if (builder instanceof OtlpHttpLogRecordExporterBuilder) { + Method method = + OtlpHttpLogRecordExporterBuilder.class.getDeclaredMethod( + "setMemoryMode", MemoryMode.class); + method.setAccessible(true); + method.invoke(builder, memoryMode); } else { throw new IllegalArgumentException( - "Can only set memory mode on OtlpHttpMetricExporterBuilder and OtlpGrpcMetricExporterBuilder."); + "Cannot set memory mode. Unrecognized OTLP exporter builder"); } } catch (NoSuchMethodException | InvocationTargetException diff --git a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/OtlpLogRecordExporterProvider.java b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/OtlpLogRecordExporterProvider.java index 1694189d69b..04cf661b58b 100644 --- a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/OtlpLogRecordExporterProvider.java +++ b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/OtlpLogRecordExporterProvider.java @@ -10,6 +10,7 @@ import static io.opentelemetry.exporter.otlp.internal.OtlpConfigUtil.PROTOCOL_HTTP_PROTOBUF; import io.opentelemetry.api.metrics.MeterProvider; +import io.opentelemetry.exporter.internal.ExporterBuilderUtil; import io.opentelemetry.exporter.otlp.http.logs.OtlpHttpLogRecordExporter; import io.opentelemetry.exporter.otlp.http.logs.OtlpHttpLogRecordExporterBuilder; import io.opentelemetry.exporter.otlp.logs.OtlpGrpcLogRecordExporter; @@ -53,6 +54,9 @@ public LogRecordExporter createExporter(ConfigProperties config) { builder::setClientTls, builder::setRetryPolicy); builder.setMeterProvider(meterProviderRef::get); + ExporterBuilderUtil.configureExporterMemoryMode( + config, + memoryMode -> OtlpConfigUtil.setMemoryModeOnOtlpExporterBuilder(builder, memoryMode)); return builder.build(); } else if (protocol.equals(PROTOCOL_GRPC)) { @@ -69,6 +73,9 @@ public LogRecordExporter createExporter(ConfigProperties config) { builder::setClientTls, builder::setRetryPolicy); builder.setMeterProvider(meterProviderRef::get); + ExporterBuilderUtil.configureExporterMemoryMode( + config, + memoryMode -> OtlpConfigUtil.setMemoryModeOnOtlpExporterBuilder(builder, memoryMode)); return builder.build(); } diff --git a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/OtlpMetricExporterProvider.java b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/OtlpMetricExporterProvider.java index cfea314f028..490f4044bea 100644 --- a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/OtlpMetricExporterProvider.java +++ b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/OtlpMetricExporterProvider.java @@ -51,8 +51,7 @@ public MetricExporter createExporter(ConfigProperties config) { config, builder::setDefaultAggregationSelector); ExporterBuilderUtil.configureExporterMemoryMode( config, - memoryMode -> - OtlpConfigUtil.setMemoryModeOnOtlpMetricExporterBuilder(builder, memoryMode)); + memoryMode -> OtlpConfigUtil.setMemoryModeOnOtlpExporterBuilder(builder, memoryMode)); return builder.build(); } else if (protocol.equals(PROTOCOL_GRPC)) { @@ -74,8 +73,7 @@ public MetricExporter createExporter(ConfigProperties config) { config, builder::setDefaultAggregationSelector); ExporterBuilderUtil.configureExporterMemoryMode( config, - memoryMode -> - OtlpConfigUtil.setMemoryModeOnOtlpMetricExporterBuilder(builder, memoryMode)); + memoryMode -> OtlpConfigUtil.setMemoryModeOnOtlpExporterBuilder(builder, memoryMode)); return builder.build(); } diff --git a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/OtlpSpanExporterProvider.java b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/OtlpSpanExporterProvider.java index b4b8731b1bd..bdf9633a441 100644 --- a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/OtlpSpanExporterProvider.java +++ b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/OtlpSpanExporterProvider.java @@ -10,6 +10,7 @@ import static io.opentelemetry.exporter.otlp.internal.OtlpConfigUtil.PROTOCOL_HTTP_PROTOBUF; import io.opentelemetry.api.metrics.MeterProvider; +import io.opentelemetry.exporter.internal.ExporterBuilderUtil; import io.opentelemetry.exporter.otlp.http.trace.OtlpHttpSpanExporter; import io.opentelemetry.exporter.otlp.http.trace.OtlpHttpSpanExporterBuilder; import io.opentelemetry.exporter.otlp.trace.OtlpGrpcSpanExporter; @@ -52,7 +53,9 @@ public SpanExporter createExporter(ConfigProperties config) { builder::setClientTls, builder::setRetryPolicy); builder.setMeterProvider(meterProviderRef::get); - + ExporterBuilderUtil.configureExporterMemoryMode( + config, + memoryMode -> OtlpConfigUtil.setMemoryModeOnOtlpExporterBuilder(builder, memoryMode)); return builder.build(); } else if (protocol.equals(PROTOCOL_GRPC)) { OtlpGrpcSpanExporterBuilder builder = grpcBuilder(); @@ -68,6 +71,9 @@ public SpanExporter createExporter(ConfigProperties config) { builder::setClientTls, builder::setRetryPolicy); builder.setMeterProvider(meterProviderRef::get); + ExporterBuilderUtil.configureExporterMemoryMode( + config, + memoryMode -> OtlpConfigUtil.setMemoryModeOnOtlpExporterBuilder(builder, memoryMode)); return builder.build(); } diff --git a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/logs/MarshalerLogsServiceGrpc.java b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/logs/MarshalerLogsServiceGrpc.java index 06d7da50bff..451e5abae32 100644 --- a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/logs/MarshalerLogsServiceGrpc.java +++ b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/logs/MarshalerLogsServiceGrpc.java @@ -14,7 +14,7 @@ import io.grpc.stub.ClientCalls; import io.opentelemetry.exporter.internal.grpc.MarshalerInputStream; import io.opentelemetry.exporter.internal.grpc.MarshalerServiceStub; -import io.opentelemetry.exporter.internal.otlp.logs.LogsRequestMarshaler; +import io.opentelemetry.exporter.internal.marshal.Marshaler; import java.io.InputStream; import javax.annotation.Nullable; @@ -23,15 +23,15 @@ final class MarshalerLogsServiceGrpc { private static final String SERVICE_NAME = "opentelemetry.proto.collector.logs.v1.LogsService"; - private static final MethodDescriptor.Marshaller REQUEST_MARSHALLER = - new MethodDescriptor.Marshaller() { + private static final MethodDescriptor.Marshaller REQUEST_MARSHALLER = + new MethodDescriptor.Marshaller() { @Override - public InputStream stream(LogsRequestMarshaler value) { + public InputStream stream(Marshaler value) { return new MarshalerInputStream(value); } @Override - public LogsRequestMarshaler parse(InputStream stream) { + public Marshaler parse(InputStream stream) { throw new UnsupportedOperationException("Only for serializing"); } }; @@ -49,14 +49,13 @@ public ExportLogsServiceResponse parse(InputStream stream) { } }; - private static final MethodDescriptor - getExportMethod = - MethodDescriptor.newBuilder() - .setType(MethodDescriptor.MethodType.UNARY) - .setFullMethodName(generateFullMethodName(SERVICE_NAME, "Export")) - .setRequestMarshaller(REQUEST_MARSHALLER) - .setResponseMarshaller(RESPONSE_MARSHALER) - .build(); + private static final MethodDescriptor getExportMethod = + MethodDescriptor.newBuilder() + .setType(MethodDescriptor.MethodType.UNARY) + .setFullMethodName(generateFullMethodName(SERVICE_NAME, "Export")) + .setRequestMarshaller(REQUEST_MARSHALLER) + .setResponseMarshaller(RESPONSE_MARSHALER) + .build(); static LogsServiceFutureStub newFutureStub(Channel channel, @Nullable String authorityOverride) { return LogsServiceFutureStub.newStub( @@ -65,8 +64,7 @@ static LogsServiceFutureStub newFutureStub(Channel channel, @Nullable String aut } static final class LogsServiceFutureStub - extends MarshalerServiceStub< - LogsRequestMarshaler, ExportLogsServiceResponse, LogsServiceFutureStub> { + extends MarshalerServiceStub { private LogsServiceFutureStub(Channel channel, CallOptions callOptions) { super(channel, callOptions); } @@ -78,7 +76,7 @@ protected MarshalerLogsServiceGrpc.LogsServiceFutureStub build( } @Override - public ListenableFuture export(LogsRequestMarshaler request) { + public ListenableFuture export(Marshaler request) { return ClientCalls.futureUnaryCall( getChannel().newCall(getExportMethod, getCallOptions()), request); } diff --git a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/logs/OtlpGrpcLogRecordExporter.java b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/logs/OtlpGrpcLogRecordExporter.java index a97a9553d13..efde0010450 100644 --- a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/logs/OtlpGrpcLogRecordExporter.java +++ b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/logs/OtlpGrpcLogRecordExporter.java @@ -7,11 +7,17 @@ import io.opentelemetry.exporter.internal.grpc.GrpcExporter; import io.opentelemetry.exporter.internal.grpc.GrpcExporterBuilder; +import io.opentelemetry.exporter.internal.marshal.Marshaler; import io.opentelemetry.exporter.internal.otlp.logs.LogsRequestMarshaler; +import io.opentelemetry.exporter.internal.otlp.logs.LowAllocationLogsRequestMarshaler; import io.opentelemetry.sdk.common.CompletableResultCode; +import io.opentelemetry.sdk.common.export.MemoryMode; import io.opentelemetry.sdk.logs.data.LogRecordData; import io.opentelemetry.sdk.logs.export.LogRecordExporter; +import java.util.ArrayDeque; import java.util.Collection; +import java.util.Deque; +import java.util.StringJoiner; import javax.annotation.concurrent.ThreadSafe; /** @@ -22,8 +28,10 @@ @ThreadSafe public final class OtlpGrpcLogRecordExporter implements LogRecordExporter { - private final GrpcExporterBuilder builder; - private final GrpcExporter delegate; + private final Deque marshalerPool = new ArrayDeque<>(); + private final GrpcExporterBuilder builder; + private final GrpcExporter delegate; + private final MemoryMode memoryMode; /** * Returns a new {@link OtlpGrpcLogRecordExporter} using the default values. @@ -47,10 +55,12 @@ public static OtlpGrpcLogRecordExporterBuilder builder() { } OtlpGrpcLogRecordExporter( - GrpcExporterBuilder builder, - GrpcExporter delegate) { + GrpcExporterBuilder builder, + GrpcExporter delegate, + MemoryMode memoryMode) { this.builder = builder; this.delegate = delegate; + this.memoryMode = memoryMode; } /** @@ -61,7 +71,7 @@ public static OtlpGrpcLogRecordExporterBuilder builder() { * @since 1.29.0 */ public OtlpGrpcLogRecordExporterBuilder toBuilder() { - return new OtlpGrpcLogRecordExporterBuilder(builder.copy()); + return new OtlpGrpcLogRecordExporterBuilder(builder.copy(), memoryMode); } /** @@ -72,6 +82,22 @@ public OtlpGrpcLogRecordExporterBuilder toBuilder() { */ @Override public CompletableResultCode export(Collection logs) { + if (memoryMode == MemoryMode.REUSABLE_DATA) { + LowAllocationLogsRequestMarshaler marshaler = marshalerPool.poll(); + if (marshaler == null) { + marshaler = new LowAllocationLogsRequestMarshaler(); + } + LowAllocationLogsRequestMarshaler exportMarshaler = marshaler; + exportMarshaler.initialize(logs); + return delegate + .export(exportMarshaler, logs.size()) + .whenComplete( + () -> { + exportMarshaler.reset(); + marshalerPool.add(exportMarshaler); + }); + } + // MemoryMode == MemoryMode.IMMUTABLE_DATA LogsRequestMarshaler request = LogsRequestMarshaler.create(logs); return delegate.export(request, logs.size()); } @@ -92,6 +118,9 @@ public CompletableResultCode shutdown() { @Override public String toString() { - return "OtlpGrpcLogRecordExporter{" + builder.toString(false) + "}"; + StringJoiner joiner = new StringJoiner(", ", "OtlpGrpcLogRecordExporter{", "}"); + joiner.add(builder.toString(false)); + joiner.add("memoryMode=" + memoryMode); + return joiner.toString(); } } diff --git a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/logs/OtlpGrpcLogRecordExporterBuilder.java b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/logs/OtlpGrpcLogRecordExporterBuilder.java index df5f4769588..58cfc8e3c61 100644 --- a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/logs/OtlpGrpcLogRecordExporterBuilder.java +++ b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/logs/OtlpGrpcLogRecordExporterBuilder.java @@ -15,8 +15,9 @@ import io.opentelemetry.exporter.internal.compression.CompressorProvider; import io.opentelemetry.exporter.internal.compression.CompressorUtil; import io.opentelemetry.exporter.internal.grpc.GrpcExporterBuilder; -import io.opentelemetry.exporter.internal.otlp.logs.LogsRequestMarshaler; +import io.opentelemetry.exporter.internal.marshal.Marshaler; import io.opentelemetry.exporter.otlp.internal.OtlpUserAgent; +import io.opentelemetry.sdk.common.export.MemoryMode; import io.opentelemetry.sdk.common.export.RetryPolicy; import java.net.URI; import java.time.Duration; @@ -41,12 +42,15 @@ public final class OtlpGrpcLogRecordExporterBuilder { private static final String DEFAULT_ENDPOINT_URL = "http://localhost:4317"; private static final URI DEFAULT_ENDPOINT = URI.create(DEFAULT_ENDPOINT_URL); private static final long DEFAULT_TIMEOUT_SECS = 10; + private static final MemoryMode DEFAULT_MEMORY_MODE = MemoryMode.IMMUTABLE_DATA; // Visible for testing - final GrpcExporterBuilder delegate; + final GrpcExporterBuilder delegate; + private MemoryMode memoryMode; - OtlpGrpcLogRecordExporterBuilder(GrpcExporterBuilder delegate) { + OtlpGrpcLogRecordExporterBuilder(GrpcExporterBuilder delegate, MemoryMode memoryMode) { this.delegate = delegate; + this.memoryMode = memoryMode; OtlpUserAgent.addUserAgentHeader(delegate::addConstantHeader); } @@ -58,7 +62,8 @@ public final class OtlpGrpcLogRecordExporterBuilder { DEFAULT_TIMEOUT_SECS, DEFAULT_ENDPOINT, () -> MarshalerLogsServiceGrpc::newFutureStub, - GRPC_ENDPOINT_PATH)); + GRPC_ENDPOINT_PATH), + DEFAULT_MEMORY_MODE); } /** @@ -238,12 +243,19 @@ public OtlpGrpcLogRecordExporterBuilder setMeterProvider( return this; } + /** Set the {@link MemoryMode}. */ + OtlpGrpcLogRecordExporterBuilder setMemoryMode(MemoryMode memoryMode) { + requireNonNull(memoryMode, "memoryMode"); + this.memoryMode = memoryMode; + return this; + } + /** * Constructs a new instance of the exporter based on the builder's values. * * @return a new exporter's instance */ public OtlpGrpcLogRecordExporter build() { - return new OtlpGrpcLogRecordExporter(delegate, delegate.build()); + return new OtlpGrpcLogRecordExporter(delegate, delegate.build(), memoryMode); } } diff --git a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/logs/OtlpGrpcLogUtil.java b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/logs/OtlpGrpcLogUtil.java new file mode 100644 index 00000000000..1602514e8d5 --- /dev/null +++ b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/logs/OtlpGrpcLogUtil.java @@ -0,0 +1,19 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.exporter.otlp.logs; + +import io.opentelemetry.exporter.otlp.internal.OtlpConfigUtil; +import io.opentelemetry.sdk.common.export.MemoryMode; + +final class OtlpGrpcLogUtil { + + private OtlpGrpcLogUtil() {} + + /** See {@link OtlpConfigUtil#setMemoryModeOnOtlpExporterBuilder(Object, MemoryMode)}. */ + static void setMemoryMode(OtlpGrpcLogRecordExporterBuilder builder, MemoryMode memoryMode) { + builder.setMemoryMode(memoryMode); + } +} diff --git a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/metrics/MarshalerMetricsServiceGrpc.java b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/metrics/MarshalerMetricsServiceGrpc.java index 240ad81beb2..af70c6bd175 100644 --- a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/metrics/MarshalerMetricsServiceGrpc.java +++ b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/metrics/MarshalerMetricsServiceGrpc.java @@ -14,7 +14,7 @@ import io.grpc.stub.ClientCalls; import io.opentelemetry.exporter.internal.grpc.MarshalerInputStream; import io.opentelemetry.exporter.internal.grpc.MarshalerServiceStub; -import io.opentelemetry.exporter.internal.otlp.metrics.MetricsRequestMarshaler; +import io.opentelemetry.exporter.internal.marshal.Marshaler; import java.io.InputStream; import javax.annotation.Nullable; @@ -24,15 +24,15 @@ final class MarshalerMetricsServiceGrpc { private static final String SERVICE_NAME = "opentelemetry.proto.collector.metrics.v1.MetricsService"; - private static final MethodDescriptor.Marshaller REQUEST_MARSHALLER = - new MethodDescriptor.Marshaller() { + private static final MethodDescriptor.Marshaller REQUEST_MARSHALLER = + new MethodDescriptor.Marshaller() { @Override - public InputStream stream(MetricsRequestMarshaler value) { + public InputStream stream(Marshaler value) { return new MarshalerInputStream(value); } @Override - public MetricsRequestMarshaler parse(InputStream stream) { + public Marshaler parse(InputStream stream) { throw new UnsupportedOperationException("Only for serializing"); } }; @@ -51,14 +51,13 @@ public ExportMetricsServiceResponse parse(InputStream stream) { } }; - private static final MethodDescriptor - getExportMethod = - MethodDescriptor.newBuilder() - .setType(MethodDescriptor.MethodType.UNARY) - .setFullMethodName(generateFullMethodName(SERVICE_NAME, "Export")) - .setRequestMarshaller(REQUEST_MARSHALLER) - .setResponseMarshaller(RESPONSE_MARSHALER) - .build(); + private static final MethodDescriptor getExportMethod = + MethodDescriptor.newBuilder() + .setType(MethodDescriptor.MethodType.UNARY) + .setFullMethodName(generateFullMethodName(SERVICE_NAME, "Export")) + .setRequestMarshaller(REQUEST_MARSHALLER) + .setResponseMarshaller(RESPONSE_MARSHALER) + .build(); static MetricsServiceFutureStub newFutureStub( Channel channel, @Nullable String authorityOverride) { @@ -69,7 +68,7 @@ static MetricsServiceFutureStub newFutureStub( static final class MetricsServiceFutureStub extends MarshalerServiceStub< - MetricsRequestMarshaler, ExportMetricsServiceResponse, MetricsServiceFutureStub> { + Marshaler, ExportMetricsServiceResponse, MetricsServiceFutureStub> { private MetricsServiceFutureStub(Channel channel, CallOptions callOptions) { super(channel, callOptions); } @@ -81,7 +80,7 @@ protected MarshalerMetricsServiceGrpc.MetricsServiceFutureStub build( } @Override - public ListenableFuture export(MetricsRequestMarshaler request) { + public ListenableFuture export(Marshaler request) { return ClientCalls.futureUnaryCall( getChannel().newCall(getExportMethod, getCallOptions()), request); } diff --git a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/metrics/OtlpGrpcMetricExporter.java b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/metrics/OtlpGrpcMetricExporter.java index eeeba0773b7..1a9d3ed20e2 100644 --- a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/metrics/OtlpGrpcMetricExporter.java +++ b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/metrics/OtlpGrpcMetricExporter.java @@ -7,6 +7,8 @@ import io.opentelemetry.exporter.internal.grpc.GrpcExporter; import io.opentelemetry.exporter.internal.grpc.GrpcExporterBuilder; +import io.opentelemetry.exporter.internal.marshal.Marshaler; +import io.opentelemetry.exporter.internal.otlp.metrics.LowAllocationMetricsRequestMarshaler; import io.opentelemetry.exporter.internal.otlp.metrics.MetricsRequestMarshaler; import io.opentelemetry.sdk.common.CompletableResultCode; import io.opentelemetry.sdk.common.export.MemoryMode; @@ -17,7 +19,9 @@ import io.opentelemetry.sdk.metrics.export.AggregationTemporalitySelector; import io.opentelemetry.sdk.metrics.export.DefaultAggregationSelector; import io.opentelemetry.sdk.metrics.export.MetricExporter; +import java.util.ArrayDeque; import java.util.Collection; +import java.util.Deque; import java.util.StringJoiner; import javax.annotation.concurrent.ThreadSafe; @@ -29,8 +33,9 @@ @ThreadSafe public final class OtlpGrpcMetricExporter implements MetricExporter { - private final GrpcExporterBuilder builder; - private final GrpcExporter delegate; + private final Deque marshalerPool = new ArrayDeque<>(); + private final GrpcExporterBuilder builder; + private final GrpcExporter delegate; private final AggregationTemporalitySelector aggregationTemporalitySelector; private final DefaultAggregationSelector defaultAggregationSelector; private final MemoryMode memoryMode; @@ -57,8 +62,8 @@ public static OtlpGrpcMetricExporterBuilder builder() { } OtlpGrpcMetricExporter( - GrpcExporterBuilder builder, - GrpcExporter delegate, + GrpcExporterBuilder builder, + GrpcExporter delegate, AggregationTemporalitySelector aggregationTemporalitySelector, DefaultAggregationSelector defaultAggregationSelector, MemoryMode memoryMode) { @@ -103,8 +108,23 @@ public MemoryMode getMemoryMode() { */ @Override public CompletableResultCode export(Collection metrics) { + if (memoryMode == MemoryMode.REUSABLE_DATA) { + LowAllocationMetricsRequestMarshaler marshaler = marshalerPool.poll(); + if (marshaler == null) { + marshaler = new LowAllocationMetricsRequestMarshaler(); + } + LowAllocationMetricsRequestMarshaler exportMarshaler = marshaler; + exportMarshaler.initialize(metrics); + return delegate + .export(exportMarshaler, metrics.size()) + .whenComplete( + () -> { + exportMarshaler.reset(); + marshalerPool.add(exportMarshaler); + }); + } + // MemoryMode == MemoryMode.IMMUTABLE_DATA MetricsRequestMarshaler request = MetricsRequestMarshaler.create(metrics); - return delegate.export(request, metrics.size()); } diff --git a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/metrics/OtlpGrpcMetricExporterBuilder.java b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/metrics/OtlpGrpcMetricExporterBuilder.java index 782907cd27c..343e2a5dd9b 100644 --- a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/metrics/OtlpGrpcMetricExporterBuilder.java +++ b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/metrics/OtlpGrpcMetricExporterBuilder.java @@ -14,7 +14,7 @@ import io.opentelemetry.exporter.internal.compression.CompressorProvider; import io.opentelemetry.exporter.internal.compression.CompressorUtil; import io.opentelemetry.exporter.internal.grpc.GrpcExporterBuilder; -import io.opentelemetry.exporter.internal.otlp.metrics.MetricsRequestMarshaler; +import io.opentelemetry.exporter.internal.marshal.Marshaler; import io.opentelemetry.exporter.otlp.internal.OtlpUserAgent; import io.opentelemetry.sdk.common.export.MemoryMode; import io.opentelemetry.sdk.common.export.RetryPolicy; @@ -50,7 +50,7 @@ public final class OtlpGrpcMetricExporterBuilder { private static final MemoryMode DEFAULT_MEMORY_MODE = MemoryMode.IMMUTABLE_DATA; // Visible for testing - final GrpcExporterBuilder delegate; + final GrpcExporterBuilder delegate; private AggregationTemporalitySelector aggregationTemporalitySelector = DEFAULT_AGGREGATION_TEMPORALITY_SELECTOR; @@ -59,8 +59,7 @@ public final class OtlpGrpcMetricExporterBuilder { DefaultAggregationSelector.getDefault(); private MemoryMode memoryMode; - OtlpGrpcMetricExporterBuilder( - GrpcExporterBuilder delegate, MemoryMode memoryMode) { + OtlpGrpcMetricExporterBuilder(GrpcExporterBuilder delegate, MemoryMode memoryMode) { this.delegate = delegate; this.memoryMode = memoryMode; delegate.setMeterProvider(MeterProvider::noop); diff --git a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/metrics/OtlpGrpcMetricUtil.java b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/metrics/OtlpGrpcMetricUtil.java index f99243cb0ba..7d4080b87ef 100644 --- a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/metrics/OtlpGrpcMetricUtil.java +++ b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/metrics/OtlpGrpcMetricUtil.java @@ -12,7 +12,7 @@ final class OtlpGrpcMetricUtil { private OtlpGrpcMetricUtil() {} - /** See {@link OtlpConfigUtil#setMemoryModeOnOtlpMetricExporterBuilder(Object, MemoryMode)}. */ + /** See {@link OtlpConfigUtil#setMemoryModeOnOtlpExporterBuilder(Object, MemoryMode)}. */ static void setMemoryMode(OtlpGrpcMetricExporterBuilder builder, MemoryMode memoryMode) { builder.setMemoryMode(memoryMode); } diff --git a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/trace/MarshalerTraceServiceGrpc.java b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/trace/MarshalerTraceServiceGrpc.java index 973bc37cb39..784eae98a49 100644 --- a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/trace/MarshalerTraceServiceGrpc.java +++ b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/trace/MarshalerTraceServiceGrpc.java @@ -10,7 +10,7 @@ import io.grpc.MethodDescriptor; import io.opentelemetry.exporter.internal.grpc.MarshalerInputStream; import io.opentelemetry.exporter.internal.grpc.MarshalerServiceStub; -import io.opentelemetry.exporter.internal.otlp.traces.TraceRequestMarshaler; +import io.opentelemetry.exporter.internal.marshal.Marshaler; import java.io.InputStream; import javax.annotation.Nullable; @@ -19,15 +19,15 @@ final class MarshalerTraceServiceGrpc { private static final String SERVICE_NAME = "opentelemetry.proto.collector.trace.v1.TraceService"; - private static final MethodDescriptor.Marshaller REQUEST_MARSHALLER = - new MethodDescriptor.Marshaller() { + private static final MethodDescriptor.Marshaller REQUEST_MARSHALLER = + new MethodDescriptor.Marshaller() { @Override - public InputStream stream(TraceRequestMarshaler value) { + public InputStream stream(Marshaler value) { return new MarshalerInputStream(value); } @Override - public TraceRequestMarshaler parse(InputStream stream) { + public Marshaler parse(InputStream stream) { throw new UnsupportedOperationException("Only for serializing"); } }; @@ -45,9 +45,9 @@ public ExportTraceServiceResponse parse(InputStream stream) { } }; - private static final io.grpc.MethodDescriptor + private static final io.grpc.MethodDescriptor getExportMethod = - io.grpc.MethodDescriptor.newBuilder() + io.grpc.MethodDescriptor.newBuilder() .setType(io.grpc.MethodDescriptor.MethodType.UNARY) .setFullMethodName(generateFullMethodName(SERVICE_NAME, "Export")) .setRequestMarshaller(REQUEST_MARSHALLER) @@ -62,8 +62,7 @@ static TraceServiceFutureStub newFutureStub( } static final class TraceServiceFutureStub - extends MarshalerServiceStub< - TraceRequestMarshaler, ExportTraceServiceResponse, TraceServiceFutureStub> { + extends MarshalerServiceStub { private TraceServiceFutureStub(io.grpc.Channel channel, io.grpc.CallOptions callOptions) { super(channel, callOptions); } @@ -76,7 +75,7 @@ protected MarshalerTraceServiceGrpc.TraceServiceFutureStub build( @Override public com.google.common.util.concurrent.ListenableFuture export( - TraceRequestMarshaler request) { + Marshaler request) { return io.grpc.stub.ClientCalls.futureUnaryCall( getChannel().newCall(getExportMethod, getCallOptions()), request); } diff --git a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/trace/OtlpGrpcSpanExporter.java b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/trace/OtlpGrpcSpanExporter.java index a249c25e76f..a2c29d87bc1 100644 --- a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/trace/OtlpGrpcSpanExporter.java +++ b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/trace/OtlpGrpcSpanExporter.java @@ -7,19 +7,27 @@ import io.opentelemetry.exporter.internal.grpc.GrpcExporter; import io.opentelemetry.exporter.internal.grpc.GrpcExporterBuilder; +import io.opentelemetry.exporter.internal.marshal.Marshaler; +import io.opentelemetry.exporter.internal.otlp.traces.LowAllocationTraceRequestMarshaler; import io.opentelemetry.exporter.internal.otlp.traces.TraceRequestMarshaler; import io.opentelemetry.sdk.common.CompletableResultCode; +import io.opentelemetry.sdk.common.export.MemoryMode; import io.opentelemetry.sdk.trace.data.SpanData; import io.opentelemetry.sdk.trace.export.SpanExporter; +import java.util.ArrayDeque; import java.util.Collection; +import java.util.Deque; +import java.util.StringJoiner; import javax.annotation.concurrent.ThreadSafe; /** Exports spans using OTLP via gRPC, using OpenTelemetry's protobuf model. */ @ThreadSafe public final class OtlpGrpcSpanExporter implements SpanExporter { - private final GrpcExporterBuilder builder; - private final GrpcExporter delegate; + private final Deque marshalerPool = new ArrayDeque<>(); + private final GrpcExporterBuilder builder; + private final GrpcExporter delegate; + private final MemoryMode memoryMode; /** * Returns a new {@link OtlpGrpcSpanExporter} using the default values. @@ -43,10 +51,12 @@ public static OtlpGrpcSpanExporterBuilder builder() { } OtlpGrpcSpanExporter( - GrpcExporterBuilder builder, - GrpcExporter delegate) { + GrpcExporterBuilder builder, + GrpcExporter delegate, + MemoryMode memoryMode) { this.builder = builder; this.delegate = delegate; + this.memoryMode = memoryMode; } /** @@ -57,7 +67,7 @@ public static OtlpGrpcSpanExporterBuilder builder() { * @since 1.29.0 */ public OtlpGrpcSpanExporterBuilder toBuilder() { - return new OtlpGrpcSpanExporterBuilder(builder.copy()); + return new OtlpGrpcSpanExporterBuilder(builder.copy(), memoryMode); } /** @@ -68,8 +78,23 @@ public OtlpGrpcSpanExporterBuilder toBuilder() { */ @Override public CompletableResultCode export(Collection spans) { + if (memoryMode == MemoryMode.REUSABLE_DATA) { + LowAllocationTraceRequestMarshaler marshaler = marshalerPool.poll(); + if (marshaler == null) { + marshaler = new LowAllocationTraceRequestMarshaler(); + } + LowAllocationTraceRequestMarshaler exportMarshaler = marshaler; + exportMarshaler.initialize(spans); + return delegate + .export(exportMarshaler, spans.size()) + .whenComplete( + () -> { + exportMarshaler.reset(); + marshalerPool.add(exportMarshaler); + }); + } + // MemoryMode == MemoryMode.IMMUTABLE_DATA TraceRequestMarshaler request = TraceRequestMarshaler.create(spans); - return delegate.export(request, spans.size()); } @@ -94,6 +119,9 @@ public CompletableResultCode shutdown() { @Override public String toString() { - return "OtlpGrpcSpanExporter{" + builder.toString(false) + "}"; + StringJoiner joiner = new StringJoiner(", ", "OtlpGrpcSpanExporter{", "}"); + joiner.add(builder.toString(false)); + joiner.add("memoryMode=" + memoryMode); + return joiner.toString(); } } diff --git a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/trace/OtlpGrpcSpanExporterBuilder.java b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/trace/OtlpGrpcSpanExporterBuilder.java index 9f48078b701..20ad734da43 100644 --- a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/trace/OtlpGrpcSpanExporterBuilder.java +++ b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/trace/OtlpGrpcSpanExporterBuilder.java @@ -15,8 +15,9 @@ import io.opentelemetry.exporter.internal.compression.CompressorProvider; import io.opentelemetry.exporter.internal.compression.CompressorUtil; import io.opentelemetry.exporter.internal.grpc.GrpcExporterBuilder; -import io.opentelemetry.exporter.internal.otlp.traces.TraceRequestMarshaler; +import io.opentelemetry.exporter.internal.marshal.Marshaler; import io.opentelemetry.exporter.otlp.internal.OtlpUserAgent; +import io.opentelemetry.sdk.common.export.MemoryMode; import io.opentelemetry.sdk.common.export.RetryPolicy; import java.net.URI; import java.time.Duration; @@ -37,12 +38,15 @@ public final class OtlpGrpcSpanExporterBuilder { private static final String DEFAULT_ENDPOINT_URL = "http://localhost:4317"; private static final URI DEFAULT_ENDPOINT = URI.create(DEFAULT_ENDPOINT_URL); private static final long DEFAULT_TIMEOUT_SECS = 10; + private static final MemoryMode DEFAULT_MEMORY_MODE = MemoryMode.IMMUTABLE_DATA; // Visible for testing - final GrpcExporterBuilder delegate; + final GrpcExporterBuilder delegate; + private MemoryMode memoryMode; - OtlpGrpcSpanExporterBuilder(GrpcExporterBuilder delegate) { + OtlpGrpcSpanExporterBuilder(GrpcExporterBuilder delegate, MemoryMode memoryMode) { this.delegate = delegate; + this.memoryMode = memoryMode; OtlpUserAgent.addUserAgentHeader(delegate::addConstantHeader); } @@ -54,7 +58,8 @@ public final class OtlpGrpcSpanExporterBuilder { DEFAULT_TIMEOUT_SECS, DEFAULT_ENDPOINT, () -> MarshalerTraceServiceGrpc::newFutureStub, - GRPC_ENDPOINT_PATH)); + GRPC_ENDPOINT_PATH), + DEFAULT_MEMORY_MODE); } /** @@ -235,12 +240,19 @@ public OtlpGrpcSpanExporterBuilder setMeterProvider( return this; } + /** Set the {@link MemoryMode}. */ + OtlpGrpcSpanExporterBuilder setMemoryMode(MemoryMode memoryMode) { + requireNonNull(memoryMode, "memoryMode"); + this.memoryMode = memoryMode; + return this; + } + /** * Constructs a new instance of the exporter based on the builder's values. * * @return a new exporter's instance */ public OtlpGrpcSpanExporter build() { - return new OtlpGrpcSpanExporter(delegate, delegate.build()); + return new OtlpGrpcSpanExporter(delegate, delegate.build(), memoryMode); } } diff --git a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/trace/OtlpGrpcSpanUtil.java b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/trace/OtlpGrpcSpanUtil.java new file mode 100644 index 00000000000..25955ffa265 --- /dev/null +++ b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/trace/OtlpGrpcSpanUtil.java @@ -0,0 +1,19 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.exporter.otlp.trace; + +import io.opentelemetry.exporter.otlp.internal.OtlpConfigUtil; +import io.opentelemetry.sdk.common.export.MemoryMode; + +final class OtlpGrpcSpanUtil { + + private OtlpGrpcSpanUtil() {} + + /** See {@link OtlpConfigUtil#setMemoryModeOnOtlpExporterBuilder(Object, MemoryMode)}. */ + static void setMemoryMode(OtlpGrpcSpanExporterBuilder builder, MemoryMode memoryMode) { + builder.setMemoryMode(memoryMode); + } +} diff --git a/exporters/otlp/all/src/test/java/io/opentelemetry/exporter/otlp/internal/OtlpLogRecordExporterProviderTest.java b/exporters/otlp/all/src/test/java/io/opentelemetry/exporter/otlp/internal/OtlpLogRecordExporterProviderTest.java index 8bfb90e1714..5619ddf5aa4 100644 --- a/exporters/otlp/all/src/test/java/io/opentelemetry/exporter/otlp/internal/OtlpLogRecordExporterProviderTest.java +++ b/exporters/otlp/all/src/test/java/io/opentelemetry/exporter/otlp/internal/OtlpLogRecordExporterProviderTest.java @@ -20,6 +20,7 @@ import io.opentelemetry.exporter.otlp.logs.OtlpGrpcLogRecordExporterBuilder; import io.opentelemetry.sdk.autoconfigure.spi.ConfigurationException; import io.opentelemetry.sdk.autoconfigure.spi.internal.DefaultConfigProperties; +import io.opentelemetry.sdk.common.export.MemoryMode; import io.opentelemetry.sdk.logs.export.LogRecordExporter; import java.io.IOException; import java.nio.file.Files; @@ -127,6 +128,7 @@ void createExporter_GrpcDefaults() { verify(grpcBuilder, never()).setTrustedCertificates(any()); verify(grpcBuilder, never()).setClientTls(any(), any()); assertThat(grpcBuilder).extracting("delegate").extracting("retryPolicy").isNull(); + assertThat(exporter).extracting("memoryMode").isEqualTo(MemoryMode.IMMUTABLE_DATA); } Mockito.verifyNoInteractions(httpBuilder); } @@ -176,6 +178,7 @@ void createExporter_GrpcWithSignalConfiguration() throws CertificateEncodingExce config.put("otel.exporter.otlp.logs.compression", "gzip"); config.put("otel.exporter.otlp.timeout", "1s"); config.put("otel.exporter.otlp.logs.timeout", "15s"); + config.put("otel.java.experimental.exporter.memory_mode", "reusable_data"); try (LogRecordExporter exporter = provider.createExporter(DefaultConfigProperties.createFromMap(config))) { @@ -188,6 +191,7 @@ void createExporter_GrpcWithSignalConfiguration() throws CertificateEncodingExce verify(grpcBuilder).setTrustedCertificates(serverTls.certificate().getEncoded()); verify(grpcBuilder) .setClientTls(clientTls.privateKey().getEncoded(), clientTls.certificate().getEncoded()); + assertThat(exporter).extracting("memoryMode").isEqualTo(MemoryMode.REUSABLE_DATA); } Mockito.verifyNoInteractions(httpBuilder); } @@ -207,6 +211,7 @@ void createExporter_HttpDefaults() { verify(httpBuilder, never()).setTrustedCertificates(any()); verify(httpBuilder, never()).setClientTls(any(), any()); assertThat(httpBuilder).extracting("delegate").extracting("retryPolicy").isNull(); + assertThat(exporter).extracting("memoryMode").isEqualTo(MemoryMode.IMMUTABLE_DATA); } Mockito.verifyNoInteractions(grpcBuilder); } @@ -259,6 +264,7 @@ void createExporter_HttpWithSignalConfiguration() throws CertificateEncodingExce config.put("otel.exporter.otlp.logs.compression", "gzip"); config.put("otel.exporter.otlp.timeout", "1s"); config.put("otel.exporter.otlp.logs.timeout", "15s"); + config.put("otel.java.experimental.exporter.memory_mode", "reusable_data"); try (LogRecordExporter exporter = provider.createExporter(DefaultConfigProperties.createFromMap(config))) { @@ -271,6 +277,7 @@ void createExporter_HttpWithSignalConfiguration() throws CertificateEncodingExce verify(httpBuilder).setTrustedCertificates(serverTls.certificate().getEncoded()); verify(httpBuilder) .setClientTls(clientTls.privateKey().getEncoded(), clientTls.certificate().getEncoded()); + assertThat(exporter).extracting("memoryMode").isEqualTo(MemoryMode.REUSABLE_DATA); } Mockito.verifyNoInteractions(grpcBuilder); } diff --git a/exporters/otlp/all/src/test/java/io/opentelemetry/exporter/otlp/internal/OtlpSpanExporterProviderTest.java b/exporters/otlp/all/src/test/java/io/opentelemetry/exporter/otlp/internal/OtlpSpanExporterProviderTest.java index 1918408e75b..b2b67b56b61 100644 --- a/exporters/otlp/all/src/test/java/io/opentelemetry/exporter/otlp/internal/OtlpSpanExporterProviderTest.java +++ b/exporters/otlp/all/src/test/java/io/opentelemetry/exporter/otlp/internal/OtlpSpanExporterProviderTest.java @@ -20,6 +20,7 @@ import io.opentelemetry.exporter.otlp.trace.OtlpGrpcSpanExporterBuilder; import io.opentelemetry.sdk.autoconfigure.spi.ConfigurationException; import io.opentelemetry.sdk.autoconfigure.spi.internal.DefaultConfigProperties; +import io.opentelemetry.sdk.common.export.MemoryMode; import io.opentelemetry.sdk.trace.export.SpanExporter; import java.io.IOException; import java.nio.file.Files; @@ -128,6 +129,7 @@ void createExporter_GrpcDefaults() { verify(grpcBuilder, never()).setTrustedCertificates(any()); verify(grpcBuilder, never()).setClientTls(any(), any()); assertThat(grpcBuilder).extracting("delegate").extracting("retryPolicy").isNull(); + assertThat(exporter).extracting("memoryMode").isEqualTo(MemoryMode.IMMUTABLE_DATA); } Mockito.verifyNoInteractions(httpBuilder); } @@ -177,6 +179,7 @@ void createExporter_GrpcWithSignalConfiguration() throws CertificateEncodingExce config.put("otel.exporter.otlp.traces.compression", "gzip"); config.put("otel.exporter.otlp.timeout", "1s"); config.put("otel.exporter.otlp.traces.timeout", "15s"); + config.put("otel.java.experimental.exporter.memory_mode", "reusable_data"); try (SpanExporter exporter = provider.createExporter(DefaultConfigProperties.createFromMap(config))) { @@ -189,6 +192,7 @@ void createExporter_GrpcWithSignalConfiguration() throws CertificateEncodingExce verify(grpcBuilder).setTrustedCertificates(serverTls.certificate().getEncoded()); verify(grpcBuilder) .setClientTls(clientTls.privateKey().getEncoded(), clientTls.certificate().getEncoded()); + assertThat(exporter).extracting("memoryMode").isEqualTo(MemoryMode.REUSABLE_DATA); } Mockito.verifyNoInteractions(httpBuilder); } @@ -208,6 +212,7 @@ void createExporter_HttpDefaults() { verify(httpBuilder, never()).setTrustedCertificates(any()); verify(httpBuilder, never()).setClientTls(any(), any()); assertThat(httpBuilder).extracting("delegate").extracting("retryPolicy").isNull(); + assertThat(exporter).extracting("memoryMode").isEqualTo(MemoryMode.IMMUTABLE_DATA); } Mockito.verifyNoInteractions(grpcBuilder); } @@ -239,6 +244,7 @@ void createExporter_HttpWithGeneralConfiguration() throws CertificateEncodingExc verify(httpBuilder) .setClientTls(clientTls.privateKey().getEncoded(), clientTls.certificate().getEncoded()); assertThat(httpBuilder).extracting("delegate").extracting("retryPolicy").isNotNull(); + assertThat(exporter).extracting("memoryMode").isEqualTo(MemoryMode.IMMUTABLE_DATA); } Mockito.verifyNoInteractions(grpcBuilder); } @@ -262,6 +268,7 @@ void createExporter_HttpWithSignalConfiguration() throws CertificateEncodingExce config.put("otel.exporter.otlp.traces.compression", "gzip"); config.put("otel.exporter.otlp.timeout", "1s"); config.put("otel.exporter.otlp.traces.timeout", "15s"); + config.put("otel.java.experimental.exporter.memory_mode", "reusable_data"); try (SpanExporter exporter = provider.createExporter(DefaultConfigProperties.createFromMap(config))) { @@ -274,6 +281,7 @@ void createExporter_HttpWithSignalConfiguration() throws CertificateEncodingExce verify(httpBuilder).setTrustedCertificates(serverTls.certificate().getEncoded()); verify(httpBuilder) .setClientTls(clientTls.privateKey().getEncoded(), clientTls.certificate().getEncoded()); + assertThat(exporter).extracting("memoryMode").isEqualTo(MemoryMode.REUSABLE_DATA); } Mockito.verifyNoInteractions(grpcBuilder); } diff --git a/exporters/otlp/all/src/testDefaultSender/java/io/opentelemetry/exporter/otlp/http/trace/OtlpHttpSpanExporterOkHttpSenderTest.java b/exporters/otlp/all/src/testDefaultSender/java/io/opentelemetry/exporter/otlp/http/trace/OtlpHttpSpanExporterOkHttpSenderTest.java index 4752832bbc0..dbe9f9a816a 100644 --- a/exporters/otlp/all/src/testDefaultSender/java/io/opentelemetry/exporter/otlp/http/trace/OtlpHttpSpanExporterOkHttpSenderTest.java +++ b/exporters/otlp/all/src/testDefaultSender/java/io/opentelemetry/exporter/otlp/http/trace/OtlpHttpSpanExporterOkHttpSenderTest.java @@ -5,6 +5,8 @@ package io.opentelemetry.exporter.otlp.http.trace; +import static org.assertj.core.api.Assertions.assertThat; + import io.opentelemetry.exporter.internal.marshal.Marshaler; import io.opentelemetry.exporter.internal.otlp.traces.ResourceSpansMarshaler; import io.opentelemetry.exporter.otlp.testing.internal.AbstractHttpTelemetryExporterTest; @@ -14,7 +16,10 @@ import io.opentelemetry.exporter.otlp.testing.internal.TelemetryExporterBuilder; import io.opentelemetry.proto.trace.v1.ResourceSpans; import io.opentelemetry.sdk.trace.data.SpanData; +import io.opentelemetry.sdk.trace.export.SpanExporter; import java.util.List; +import java.util.concurrent.TimeUnit; +import org.junit.jupiter.api.Test; class OtlpHttpSpanExporterOkHttpSenderTest extends AbstractHttpTelemetryExporterTest { @@ -23,6 +28,31 @@ protected OtlpHttpSpanExporterOkHttpSenderTest() { super("span", "/v1/traces", ResourceSpans.getDefaultInstance()); } + /** Test configuration specific to metric exporter. */ + @Test + void stringRepresentation() { + try (SpanExporter spanExporter = OtlpHttpSpanExporter.builder().build()) { + assertThat(spanExporter.toString()) + .matches( + "OtlpHttpSpanExporter\\{" + + "exporterName=otlp, " + + "type=span, " + + "endpoint=http://localhost:4318/v1/traces, " + + "timeoutNanos=" + + TimeUnit.SECONDS.toNanos(10) + + ", " + + "proxyOptions=null, " + + "compressorEncoding=null, " + + "connectTimeoutNanos=" + + TimeUnit.SECONDS.toNanos(10) + + ", " + + "exportAsJson=false, " + + "headers=Headers\\{User-Agent=OBFUSCATED\\}, " + + "memoryMode=IMMUTABLE_DATA" + + "\\}"); + } + } + @Override protected TelemetryExporterBuilder exporterBuilder() { return new HttpSpanExporterBuilderWrapper(OtlpHttpSpanExporter.builder()); diff --git a/exporters/otlp/all/src/testDefaultSender/java/io/opentelemetry/exporter/otlp/traces/OtlpGrpcSpanExporterTest.java b/exporters/otlp/all/src/testDefaultSender/java/io/opentelemetry/exporter/otlp/traces/OtlpGrpcSpanExporterTest.java index a74b5e39977..05b8523ebd4 100644 --- a/exporters/otlp/all/src/testDefaultSender/java/io/opentelemetry/exporter/otlp/traces/OtlpGrpcSpanExporterTest.java +++ b/exporters/otlp/all/src/testDefaultSender/java/io/opentelemetry/exporter/otlp/traces/OtlpGrpcSpanExporterTest.java @@ -17,8 +17,10 @@ import io.opentelemetry.exporter.sender.okhttp.internal.OkHttpGrpcSender; import io.opentelemetry.proto.trace.v1.ResourceSpans; import io.opentelemetry.sdk.trace.data.SpanData; +import io.opentelemetry.sdk.trace.export.SpanExporter; import java.io.Closeable; import java.util.List; +import java.util.concurrent.TimeUnit; import org.junit.jupiter.api.Test; class OtlpGrpcSpanExporterTest extends AbstractGrpcTelemetryExporterTest { @@ -27,6 +29,30 @@ class OtlpGrpcSpanExporterTest extends AbstractGrpcTelemetryExporterTest { +public final class KeyValueStatelessMarshaler implements StatelessMarshaler { - static final KeyValueStatelessMarshaler INSTANCE = new KeyValueStatelessMarshaler(); + public static final KeyValueStatelessMarshaler INSTANCE = new KeyValueStatelessMarshaler(); private static final byte[] EMPTY_BYTES = new byte[0]; private KeyValueStatelessMarshaler() {} diff --git a/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/metrics/ExemplarStatelessMarshaler.java b/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/metrics/ExemplarStatelessMarshaler.java index 3982b697ee0..9959beb7160 100644 --- a/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/metrics/ExemplarStatelessMarshaler.java +++ b/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/metrics/ExemplarStatelessMarshaler.java @@ -14,7 +14,7 @@ import io.opentelemetry.exporter.internal.marshal.Serializer; import io.opentelemetry.exporter.internal.marshal.StatelessMarshaler; import io.opentelemetry.exporter.internal.marshal.StatelessMarshalerUtil; -import io.opentelemetry.exporter.internal.otlp.KeyValueStatelessMarshaler; +import io.opentelemetry.exporter.internal.otlp.AttributeKeyValueStatelessMarshaler; import io.opentelemetry.sdk.metrics.data.DoubleExemplarData; import io.opentelemetry.sdk.metrics.data.ExemplarData; import io.opentelemetry.sdk.metrics.data.LongExemplarData; @@ -52,7 +52,7 @@ public void writeTo(Serializer output, ExemplarData exemplar, MarshalerContext c output.serializeRepeatedMessageWithContext( io.opentelemetry.proto.metrics.v1.internal.Exemplar.FILTERED_ATTRIBUTES, exemplar.getFilteredAttributes(), - KeyValueStatelessMarshaler.INSTANCE, + AttributeKeyValueStatelessMarshaler.INSTANCE, context); } @@ -85,7 +85,7 @@ public int getBinarySerializedSize(ExemplarData exemplar, MarshalerContext conte StatelessMarshalerUtil.sizeRepeatedMessageWithContext( io.opentelemetry.proto.metrics.v1.internal.Exemplar.FILTERED_ATTRIBUTES, exemplar.getFilteredAttributes(), - KeyValueStatelessMarshaler.INSTANCE, + AttributeKeyValueStatelessMarshaler.INSTANCE, context); return size; diff --git a/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/metrics/ExponentialHistogramDataPointStatelessMarshaler.java b/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/metrics/ExponentialHistogramDataPointStatelessMarshaler.java index 23117aab5d5..bbf2a1d6881 100644 --- a/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/metrics/ExponentialHistogramDataPointStatelessMarshaler.java +++ b/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/metrics/ExponentialHistogramDataPointStatelessMarshaler.java @@ -10,7 +10,7 @@ import io.opentelemetry.exporter.internal.marshal.Serializer; import io.opentelemetry.exporter.internal.marshal.StatelessMarshaler; import io.opentelemetry.exporter.internal.marshal.StatelessMarshalerUtil; -import io.opentelemetry.exporter.internal.otlp.KeyValueStatelessMarshaler; +import io.opentelemetry.exporter.internal.otlp.AttributeKeyValueStatelessMarshaler; import io.opentelemetry.proto.metrics.v1.internal.ExponentialHistogramDataPoint; import io.opentelemetry.sdk.metrics.data.ExponentialHistogramPointData; import java.io.IOException; @@ -58,7 +58,7 @@ public void writeTo( output.serializeRepeatedMessageWithContext( ExponentialHistogramDataPoint.ATTRIBUTES, point.getAttributes(), - KeyValueStatelessMarshaler.INSTANCE, + AttributeKeyValueStatelessMarshaler.INSTANCE, context); } @@ -105,7 +105,7 @@ public int getBinarySerializedSize( StatelessMarshalerUtil.sizeRepeatedMessageWithContext( ExponentialHistogramDataPoint.ATTRIBUTES, point.getAttributes(), - KeyValueStatelessMarshaler.INSTANCE, + AttributeKeyValueStatelessMarshaler.INSTANCE, context); return size; diff --git a/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/metrics/HistogramDataPointStatelessMarshaler.java b/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/metrics/HistogramDataPointStatelessMarshaler.java index 2102aa8bf35..c078a9739f4 100644 --- a/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/metrics/HistogramDataPointStatelessMarshaler.java +++ b/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/metrics/HistogramDataPointStatelessMarshaler.java @@ -10,7 +10,7 @@ import io.opentelemetry.exporter.internal.marshal.Serializer; import io.opentelemetry.exporter.internal.marshal.StatelessMarshaler; import io.opentelemetry.exporter.internal.marshal.StatelessMarshalerUtil; -import io.opentelemetry.exporter.internal.otlp.KeyValueStatelessMarshaler; +import io.opentelemetry.exporter.internal.otlp.AttributeKeyValueStatelessMarshaler; import io.opentelemetry.proto.metrics.v1.internal.HistogramDataPoint; import io.opentelemetry.sdk.metrics.data.HistogramPointData; import java.io.IOException; @@ -45,7 +45,7 @@ public void writeTo(Serializer output, HistogramPointData point, MarshalerContex output.serializeRepeatedMessageWithContext( HistogramDataPoint.ATTRIBUTES, point.getAttributes(), - KeyValueStatelessMarshaler.INSTANCE, + AttributeKeyValueStatelessMarshaler.INSTANCE, context); } @@ -77,7 +77,7 @@ public int getBinarySerializedSize(HistogramPointData point, MarshalerContext co StatelessMarshalerUtil.sizeRepeatedMessageWithContext( HistogramDataPoint.ATTRIBUTES, point.getAttributes(), - KeyValueStatelessMarshaler.INSTANCE, + AttributeKeyValueStatelessMarshaler.INSTANCE, context); return size; } diff --git a/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/metrics/NumberDataPointStatelessMarshaler.java b/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/metrics/NumberDataPointStatelessMarshaler.java index 2981e8cd598..c907d59a7e7 100644 --- a/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/metrics/NumberDataPointStatelessMarshaler.java +++ b/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/metrics/NumberDataPointStatelessMarshaler.java @@ -13,7 +13,7 @@ import io.opentelemetry.exporter.internal.marshal.Serializer; import io.opentelemetry.exporter.internal.marshal.StatelessMarshaler; import io.opentelemetry.exporter.internal.marshal.StatelessMarshalerUtil; -import io.opentelemetry.exporter.internal.otlp.KeyValueStatelessMarshaler; +import io.opentelemetry.exporter.internal.otlp.AttributeKeyValueStatelessMarshaler; import io.opentelemetry.proto.metrics.v1.internal.NumberDataPoint; import io.opentelemetry.sdk.metrics.data.DoublePointData; import io.opentelemetry.sdk.metrics.data.LongPointData; @@ -45,7 +45,7 @@ public void writeTo(Serializer output, PointData point, MarshalerContext context output.serializeRepeatedMessageWithContext( NumberDataPoint.ATTRIBUTES, point.getAttributes(), - KeyValueStatelessMarshaler.INSTANCE, + AttributeKeyValueStatelessMarshaler.INSTANCE, context); } @@ -71,7 +71,7 @@ public int getBinarySerializedSize(PointData point, MarshalerContext context) { StatelessMarshalerUtil.sizeRepeatedMessageWithContext( NumberDataPoint.ATTRIBUTES, point.getAttributes(), - KeyValueStatelessMarshaler.INSTANCE, + AttributeKeyValueStatelessMarshaler.INSTANCE, context); return size; } diff --git a/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/metrics/SummaryDataPointStatelessMarshaler.java b/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/metrics/SummaryDataPointStatelessMarshaler.java index d8d611c12fb..bcd2306bb13 100644 --- a/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/metrics/SummaryDataPointStatelessMarshaler.java +++ b/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/metrics/SummaryDataPointStatelessMarshaler.java @@ -10,7 +10,7 @@ import io.opentelemetry.exporter.internal.marshal.Serializer; import io.opentelemetry.exporter.internal.marshal.StatelessMarshaler; import io.opentelemetry.exporter.internal.marshal.StatelessMarshalerUtil; -import io.opentelemetry.exporter.internal.otlp.KeyValueStatelessMarshaler; +import io.opentelemetry.exporter.internal.otlp.AttributeKeyValueStatelessMarshaler; import io.opentelemetry.proto.metrics.v1.internal.SummaryDataPoint; import io.opentelemetry.sdk.metrics.data.SummaryPointData; import java.io.IOException; @@ -37,7 +37,7 @@ public void writeTo(Serializer output, SummaryPointData point, MarshalerContext output.serializeRepeatedMessageWithContext( SummaryDataPoint.ATTRIBUTES, point.getAttributes(), - KeyValueStatelessMarshaler.INSTANCE, + AttributeKeyValueStatelessMarshaler.INSTANCE, context); } @@ -60,7 +60,7 @@ public int getBinarySerializedSize(SummaryPointData point, MarshalerContext cont StatelessMarshalerUtil.sizeRepeatedMessageWithContext( SummaryDataPoint.ATTRIBUTES, point.getAttributes(), - KeyValueStatelessMarshaler.INSTANCE, + AttributeKeyValueStatelessMarshaler.INSTANCE, context); return size; } diff --git a/integration-tests/otlp/src/main/java/io/opentelemetry/integrationtest/OtlpExporterIntegrationTest.java b/integration-tests/otlp/src/main/java/io/opentelemetry/integrationtest/OtlpExporterIntegrationTest.java index 1339734f5b8..5310162ec60 100644 --- a/integration-tests/otlp/src/main/java/io/opentelemetry/integrationtest/OtlpExporterIntegrationTest.java +++ b/integration-tests/otlp/src/main/java/io/opentelemetry/integrationtest/OtlpExporterIntegrationTest.java @@ -350,7 +350,7 @@ void testOtlpGrpcMetricExport(String compression) { @EnumSource(MemoryMode.class) void testOtlpGrpcMetricExport_memoryMode(MemoryMode memoryMode) { OtlpGrpcMetricExporterBuilder builder = OtlpGrpcMetricExporter.builder(); - OtlpConfigUtil.setMemoryModeOnOtlpMetricExporterBuilder(builder, memoryMode); + OtlpConfigUtil.setMemoryModeOnOtlpExporterBuilder(builder, memoryMode); MetricExporter exporter = builder @@ -403,7 +403,7 @@ void testOtlpHttpMetricExport(String compression) { @EnumSource(MemoryMode.class) void testOtlpHttpMetricExport_memoryMode(MemoryMode memoryMode) { OtlpHttpMetricExporterBuilder builder = OtlpHttpMetricExporter.builder(); - OtlpConfigUtil.setMemoryModeOnOtlpMetricExporterBuilder(builder, memoryMode); + OtlpConfigUtil.setMemoryModeOnOtlpExporterBuilder(builder, memoryMode); MetricExporter exporter = builder From ca798212a262c414efd2d729d2abe52765e0b3f5 Mon Sep 17 00:00:00 2001 From: Takamasa Matsui <59013192+tkmsaaaam@users.noreply.github.com> Date: Fri, 10 May 2024 03:05:04 +0900 Subject: [PATCH 395/901] Restrict space-only keys (#6431) --- .../api/baggage/propagation/W3CBaggagePropagator.java | 2 +- .../api/baggage/propagation/W3CBaggagePropagatorTest.java | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/api/all/src/main/java/io/opentelemetry/api/baggage/propagation/W3CBaggagePropagator.java b/api/all/src/main/java/io/opentelemetry/api/baggage/propagation/W3CBaggagePropagator.java index 9701214e506..150be6e4fdd 100644 --- a/api/all/src/main/java/io/opentelemetry/api/baggage/propagation/W3CBaggagePropagator.java +++ b/api/all/src/main/java/io/opentelemetry/api/baggage/propagation/W3CBaggagePropagator.java @@ -127,7 +127,7 @@ private static boolean baggageIsInvalid(String key, BaggageEntry baggageEntry) { * @return whether the name is valid. */ private static boolean isValidBaggageKey(String name) { - return name != null && !name.isEmpty() && StringUtils.isPrintableString(name); + return name != null && !name.trim().isEmpty() && StringUtils.isPrintableString(name); } /** diff --git a/api/all/src/test/java/io/opentelemetry/api/baggage/propagation/W3CBaggagePropagatorTest.java b/api/all/src/test/java/io/opentelemetry/api/baggage/propagation/W3CBaggagePropagatorTest.java index 3fbf7bf5297..e775ed04f1e 100644 --- a/api/all/src/test/java/io/opentelemetry/api/baggage/propagation/W3CBaggagePropagatorTest.java +++ b/api/all/src/test/java/io/opentelemetry/api/baggage/propagation/W3CBaggagePropagatorTest.java @@ -448,6 +448,7 @@ void inject() { .put("\2ab\3cd", "wacky key nonprintable") .put(null, "null key") .put("nullvalue", null) + .put(" ", "key is only space") .build(); W3CBaggagePropagator propagator = W3CBaggagePropagator.getInstance(); Map carrier = new HashMap<>(); From c7d472ad367fa7140f695e9942ba4268f21f0672 Mon Sep 17 00:00:00 2001 From: jack-berg <34418638+jack-berg@users.noreply.github.com> Date: Thu, 9 May 2024 13:10:53 -0500 Subject: [PATCH 396/901] Stabilize synchronous gauge (#6419) --- .../api/metrics/DefaultMeter.java | 43 ++++++++- .../api}/metrics/DoubleGauge.java | 12 ++- .../api/metrics/DoubleGaugeBuilder.java | 16 ++++ .../opentelemetry/api}/metrics/LongGauge.java | 12 ++- .../api/metrics/LongGaugeBuilder.java | 16 ++++ .../api/metrics/DefaultMeterTest.java | 27 ++++++ .../metrics/ExtendedDoubleGaugeBuilder.java | 12 --- .../metrics/ExtendedLongGaugeBuilder.java | 12 --- .../metrics/ExtendedMetricsApiUsageTest.java | 42 --------- .../current_vs_latest/opentelemetry-api.txt | 19 +++- .../opentelemetry-sdk-metrics.txt | 3 + .../sdk/metrics/InstrumentType.java | 1 + .../sdk/metrics/SdkDoubleGauge.java | 16 ++-- .../sdk/metrics/SdkLongGauge.java | 16 ++-- .../internal/view/DefaultAggregation.java | 1 + .../internal/view/LastValueAggregation.java | 35 ++++++-- .../sdk/metrics/AggregationTest.java | 7 ++ .../sdk/metrics/SdkDoubleGaugeTest.java | 80 +++++++++++++---- .../sdk/metrics/SdkLongGaugeTest.java | 90 ++++++++++++++----- .../AggregationTemporalitySelectorTest.java | 12 ++- .../DefaultAggregationSelectorTest.java | 10 ++- 21 files changed, 346 insertions(+), 136 deletions(-) rename api/{incubator/src/main/java/io/opentelemetry/api/incubator => all/src/main/java/io/opentelemetry/api}/metrics/DoubleGauge.java (61%) rename api/{incubator/src/main/java/io/opentelemetry/api/incubator => all/src/main/java/io/opentelemetry/api}/metrics/LongGauge.java (61%) diff --git a/api/all/src/main/java/io/opentelemetry/api/metrics/DefaultMeter.java b/api/all/src/main/java/io/opentelemetry/api/metrics/DefaultMeter.java index 9cab67f239d..fff36ae9cbb 100644 --- a/api/all/src/main/java/io/opentelemetry/api/metrics/DefaultMeter.java +++ b/api/all/src/main/java/io/opentelemetry/api/metrics/DefaultMeter.java @@ -320,8 +320,10 @@ public LongHistogram build() { } private static class NoopDoubleGaugeBuilder implements DoubleGaugeBuilder { - private static final ObservableDoubleGauge NOOP = new ObservableDoubleGauge() {}; + private static final ObservableDoubleGauge NOOP_OBSERVABLE_GAUGE = + new ObservableDoubleGauge() {}; private static final LongGaugeBuilder NOOP_LONG_GAUGE_BUILDER = new NoopLongGaugeBuilder(); + private static final NoopDoubleGauge NOOP_GAUGE = new NoopDoubleGauge(); @Override public DoubleGaugeBuilder setDescription(String description) { @@ -340,17 +342,34 @@ public LongGaugeBuilder ofLongs() { @Override public ObservableDoubleGauge buildWithCallback(Consumer callback) { - return NOOP; + return NOOP_OBSERVABLE_GAUGE; } @Override public ObservableDoubleMeasurement buildObserver() { return NOOP_OBSERVABLE_DOUBLE_MEASUREMENT; } + + @Override + public DoubleGauge build() { + return NOOP_GAUGE; + } + } + + private static class NoopDoubleGauge implements DoubleGauge { + @Override + public void set(double value) {} + + @Override + public void set(double value, Attributes attributes) {} + + @Override + public void set(double value, Attributes attributes, Context context) {} } private static class NoopLongGaugeBuilder implements LongGaugeBuilder { - private static final ObservableLongGauge NOOP = new ObservableLongGauge() {}; + private static final ObservableLongGauge NOOP_OBSERVABLE_GAUGE = new ObservableLongGauge() {}; + private static final NoopLongGauge NOOP_GAUGE = new NoopLongGauge(); @Override public LongGaugeBuilder setDescription(String description) { @@ -364,13 +383,29 @@ public LongGaugeBuilder setUnit(String unit) { @Override public ObservableLongGauge buildWithCallback(Consumer callback) { - return NOOP; + return NOOP_OBSERVABLE_GAUGE; } @Override public ObservableLongMeasurement buildObserver() { return NOOP_OBSERVABLE_LONG_MEASUREMENT; } + + @Override + public LongGauge build() { + return NOOP_GAUGE; + } + } + + private static class NoopLongGauge implements LongGauge { + @Override + public void set(long value) {} + + @Override + public void set(long value, Attributes attributes) {} + + @Override + public void set(long value, Attributes attributes, Context context) {} } private static class NoopObservableDoubleMeasurement implements ObservableDoubleMeasurement { diff --git a/api/incubator/src/main/java/io/opentelemetry/api/incubator/metrics/DoubleGauge.java b/api/all/src/main/java/io/opentelemetry/api/metrics/DoubleGauge.java similarity index 61% rename from api/incubator/src/main/java/io/opentelemetry/api/incubator/metrics/DoubleGauge.java rename to api/all/src/main/java/io/opentelemetry/api/metrics/DoubleGauge.java index cee57ce6618..ee42b44aa7f 100644 --- a/api/incubator/src/main/java/io/opentelemetry/api/incubator/metrics/DoubleGauge.java +++ b/api/all/src/main/java/io/opentelemetry/api/metrics/DoubleGauge.java @@ -3,9 +3,10 @@ * SPDX-License-Identifier: Apache-2.0 */ -package io.opentelemetry.api.incubator.metrics; +package io.opentelemetry.api.metrics; import io.opentelemetry.api.common.Attributes; +import io.opentelemetry.context.Context; import javax.annotation.concurrent.ThreadSafe; /** A gauge instrument that synchronously records {@code double} values. */ @@ -26,5 +27,12 @@ public interface DoubleGauge { */ void set(double value, Attributes attributes); - // TODO(jack-berg): should we add overload with Context argument? + /** + * Records a value with a set of attributes. + * + * @param value The current gauge value. + * @param attributes A set of attributes to associate with the value. + * @param context The explicit context to associate with this measurement. + */ + void set(double value, Attributes attributes, Context context); } diff --git a/api/all/src/main/java/io/opentelemetry/api/metrics/DoubleGaugeBuilder.java b/api/all/src/main/java/io/opentelemetry/api/metrics/DoubleGaugeBuilder.java index f73f0133d66..98e4855d220 100644 --- a/api/all/src/main/java/io/opentelemetry/api/metrics/DoubleGaugeBuilder.java +++ b/api/all/src/main/java/io/opentelemetry/api/metrics/DoubleGaugeBuilder.java @@ -65,4 +65,20 @@ public interface DoubleGaugeBuilder { default ObservableDoubleMeasurement buildObserver() { return DefaultMeter.getInstance().gaugeBuilder("noop").buildObserver(); } + + /** + * Builds and returns a DoubleGauge instrument with the configuration. + * + *

      NOTE: This produces a synchronous gauge which records gauge values as they occur. Most users + * will want to instead register an {@link #buildWithCallback(Consumer)} to asynchronously observe + * the value of the gauge when metrics are collected. + * + *

      If using the OpenTelemetry SDK, by default gauges use last value aggregation, such that only + * the value of the last recorded measurement is exported. + * + * @return The DoubleGauge instrument. + */ + default DoubleGauge build() { + return DefaultMeter.getInstance().gaugeBuilder("noop").build(); + } } diff --git a/api/incubator/src/main/java/io/opentelemetry/api/incubator/metrics/LongGauge.java b/api/all/src/main/java/io/opentelemetry/api/metrics/LongGauge.java similarity index 61% rename from api/incubator/src/main/java/io/opentelemetry/api/incubator/metrics/LongGauge.java rename to api/all/src/main/java/io/opentelemetry/api/metrics/LongGauge.java index abc0d00c691..22b940eaa9f 100644 --- a/api/incubator/src/main/java/io/opentelemetry/api/incubator/metrics/LongGauge.java +++ b/api/all/src/main/java/io/opentelemetry/api/metrics/LongGauge.java @@ -3,9 +3,10 @@ * SPDX-License-Identifier: Apache-2.0 */ -package io.opentelemetry.api.incubator.metrics; +package io.opentelemetry.api.metrics; import io.opentelemetry.api.common.Attributes; +import io.opentelemetry.context.Context; import javax.annotation.concurrent.ThreadSafe; /** A gauge instrument that synchronously records {@code long} values. */ @@ -26,5 +27,12 @@ public interface LongGauge { */ void set(long value, Attributes attributes); - // TODO(jack-berg): should we add overload with Context argument? + /** + * Records a value with a set of attributes. + * + * @param value The current gauge value. + * @param attributes A set of attributes to associate with the value. + * @param context The explicit context to associate with this measurement. + */ + void set(long value, Attributes attributes, Context context); } diff --git a/api/all/src/main/java/io/opentelemetry/api/metrics/LongGaugeBuilder.java b/api/all/src/main/java/io/opentelemetry/api/metrics/LongGaugeBuilder.java index b4eb490906f..7c0fd0e0af2 100644 --- a/api/all/src/main/java/io/opentelemetry/api/metrics/LongGaugeBuilder.java +++ b/api/all/src/main/java/io/opentelemetry/api/metrics/LongGaugeBuilder.java @@ -62,4 +62,20 @@ public interface LongGaugeBuilder { default ObservableLongMeasurement buildObserver() { return DefaultMeter.getInstance().gaugeBuilder("noop").ofLongs().buildObserver(); } + + /** + * Builds and returns a LongGauge instrument with the configuration. + * + *

      NOTE: This produces a synchronous gauge which records gauge values as they occur. Most users + * will want to instead register an {@link #buildWithCallback(Consumer)} to asynchronously observe + * the value of the gauge when metrics are collected. + * + *

      If using the OpenTelemetry SDK, by default gauges use last value aggregation, such that only + * the value of the last recorded measurement is exported. + * + * @return The LongGauge instrument. + */ + default LongGauge build() { + return DefaultMeter.getInstance().gaugeBuilder("noop").ofLongs().build(); + } } diff --git a/api/all/src/test/java/io/opentelemetry/api/metrics/DefaultMeterTest.java b/api/all/src/test/java/io/opentelemetry/api/metrics/DefaultMeterTest.java index a42b194f81a..fd9884bdad7 100644 --- a/api/all/src/test/java/io/opentelemetry/api/metrics/DefaultMeterTest.java +++ b/api/all/src/test/java/io/opentelemetry/api/metrics/DefaultMeterTest.java @@ -93,6 +93,20 @@ void noopDoubleHistogram_doesNotThrow() { histogram.record(1.0e-1, Attributes.of(stringKey("thing"), "car"), Context.current()); } + @Test + void noopLongGauage_doesNotThrow() { + LongGauge gauge = + METER + .gaugeBuilder("temperature") + .ofLongs() + .setDescription("The current temperature") + .setUnit("C") + .build(); + gauge.set(1); + gauge.set(2, Attributes.of(stringKey("thing"), "engine")); + gauge.set(2, Attributes.of(stringKey("thing"), "engine"), Context.current()); + } + @Test void noopObservableLongGauage_doesNotThrow() { METER @@ -107,6 +121,19 @@ void noopObservableLongGauage_doesNotThrow() { }); } + @Test + void noopDoubleGauage_doesNotThrow() { + DoubleGauge gauge = + METER + .gaugeBuilder("temperature") + .setDescription("The current temperature") + .setUnit("C") + .build(); + gauge.set(1); + gauge.set(2, Attributes.of(stringKey("thing"), "engine")); + gauge.set(2, Attributes.of(stringKey("thing"), "engine"), Context.current()); + } + @Test void noopObservableDoubleGauage_doesNotThrow() { METER diff --git a/api/incubator/src/main/java/io/opentelemetry/api/incubator/metrics/ExtendedDoubleGaugeBuilder.java b/api/incubator/src/main/java/io/opentelemetry/api/incubator/metrics/ExtendedDoubleGaugeBuilder.java index 852acc27f5a..eb576559609 100644 --- a/api/incubator/src/main/java/io/opentelemetry/api/incubator/metrics/ExtendedDoubleGaugeBuilder.java +++ b/api/incubator/src/main/java/io/opentelemetry/api/incubator/metrics/ExtendedDoubleGaugeBuilder.java @@ -8,22 +8,10 @@ import io.opentelemetry.api.common.AttributeKey; import io.opentelemetry.api.metrics.DoubleGaugeBuilder; import java.util.List; -import java.util.function.Consumer; /** Extended {@link DoubleGaugeBuilder} with experimental APIs. */ public interface ExtendedDoubleGaugeBuilder extends DoubleGaugeBuilder { - /** - * Builds and returns a DoubleGauge instrument with the configuration. - * - *

      NOTE: This produces a synchronous gauge which records gauge values as they occur. Most users - * will want to instead register an {@link #buildWithCallback(Consumer)} to asynchronously observe - * the value of the gauge when metrics are collected. - * - * @return The DoubleGauge instrument. - */ - DoubleGauge build(); - /** * Specify the attribute advice, which suggests the recommended set of attribute keys to be used * for this gauge. diff --git a/api/incubator/src/main/java/io/opentelemetry/api/incubator/metrics/ExtendedLongGaugeBuilder.java b/api/incubator/src/main/java/io/opentelemetry/api/incubator/metrics/ExtendedLongGaugeBuilder.java index 44d557e4303..db05e0958f3 100644 --- a/api/incubator/src/main/java/io/opentelemetry/api/incubator/metrics/ExtendedLongGaugeBuilder.java +++ b/api/incubator/src/main/java/io/opentelemetry/api/incubator/metrics/ExtendedLongGaugeBuilder.java @@ -8,22 +8,10 @@ import io.opentelemetry.api.common.AttributeKey; import io.opentelemetry.api.metrics.LongGaugeBuilder; import java.util.List; -import java.util.function.Consumer; /** Extended {@link LongGaugeBuilder} with experimental APIs. */ public interface ExtendedLongGaugeBuilder extends LongGaugeBuilder { - /** - * Builds and returns a LongGauge instrument with the configuration. - * - *

      NOTE: This produces a synchronous gauge which records gauge values as they occur. Most users - * will want to instead register an {@link #buildWithCallback(Consumer)} to asynchronously observe - * the value of the gauge when metrics are collected. - * - * @return The LongGauge instrument. - */ - LongGauge build(); - /** * Specify the attribute advice, which suggests the recommended set of attribute keys to be used * for this gauge. diff --git a/api/incubator/src/test/java/io/opentelemetry/api/incubator/metrics/ExtendedMetricsApiUsageTest.java b/api/incubator/src/test/java/io/opentelemetry/api/incubator/metrics/ExtendedMetricsApiUsageTest.java index ea219c1cc70..5ae6297a2c7 100644 --- a/api/incubator/src/test/java/io/opentelemetry/api/incubator/metrics/ExtendedMetricsApiUsageTest.java +++ b/api/incubator/src/test/java/io/opentelemetry/api/incubator/metrics/ExtendedMetricsApiUsageTest.java @@ -23,48 +23,6 @@ /** Demonstrating usage of extended Metrics API. */ class ExtendedMetricsApiUsageTest { - @Test - void synchronousGaugeUsage() { - // Setup SdkMeterProvider - InMemoryMetricReader reader = InMemoryMetricReader.create(); - SdkMeterProvider meterProvider = - SdkMeterProvider.builder() - // Default resource used for demonstration purposes - .setResource(Resource.getDefault()) - // In-memory reader used for demonstration purposes - .registerMetricReader(reader) - .build(); - - // Get a Meter for a scope - Meter meter = meterProvider.get("org.foo.my-scope"); - - // Cast GaugeBuilder to ExtendedDoubleGaugeBuilder - DoubleGauge gauge = ((ExtendedDoubleGaugeBuilder) meter.gaugeBuilder("my-gauge")).build(); - - // Call set synchronously to set the value - gauge.set(1.0, Attributes.builder().put("key", "value1").build()); - gauge.set(2.0, Attributes.builder().put("key", "value2").build()); - - assertThat(reader.collectAllMetrics()) - .satisfiesExactly( - metricData -> - assertThat(metricData) - .hasName("my-gauge") - .hasDoubleGaugeSatisfying( - gaugeAssert -> - gaugeAssert.hasPointsSatisfying( - point -> - point - .hasValue(1.0) - .hasAttributes( - Attributes.builder().put("key", "value1").build()), - point -> - point - .hasValue(2.0) - .hasAttributes( - Attributes.builder().put("key", "value2").build())))); - } - @Test void attributesAdvice() { // Setup SdkMeterProvider diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-api.txt b/docs/apidiffs/current_vs_latest/opentelemetry-api.txt index df26146497b..d050fbe201a 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-api.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-api.txt @@ -1,2 +1,19 @@ Comparing source compatibility of against -No changes. \ No newline at end of file ++++ NEW INTERFACE: PUBLIC(+) ABSTRACT(+) io.opentelemetry.api.metrics.DoubleGauge (not serializable) + +++ CLASS FILE FORMAT VERSION: 52.0 <- n.a. + +++ NEW SUPERCLASS: java.lang.Object + +++ NEW METHOD: PUBLIC(+) ABSTRACT(+) void set(double) + +++ NEW METHOD: PUBLIC(+) ABSTRACT(+) void set(double, io.opentelemetry.api.common.Attributes) + +++ NEW METHOD: PUBLIC(+) ABSTRACT(+) void set(double, io.opentelemetry.api.common.Attributes, io.opentelemetry.context.Context) +*** MODIFIED INTERFACE: PUBLIC ABSTRACT io.opentelemetry.api.metrics.DoubleGaugeBuilder (not serializable) + === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 + +++ NEW METHOD: PUBLIC(+) io.opentelemetry.api.metrics.DoubleGauge build() ++++ NEW INTERFACE: PUBLIC(+) ABSTRACT(+) io.opentelemetry.api.metrics.LongGauge (not serializable) + +++ CLASS FILE FORMAT VERSION: 52.0 <- n.a. + +++ NEW SUPERCLASS: java.lang.Object + +++ NEW METHOD: PUBLIC(+) ABSTRACT(+) void set(long) + +++ NEW METHOD: PUBLIC(+) ABSTRACT(+) void set(long, io.opentelemetry.api.common.Attributes) + +++ NEW METHOD: PUBLIC(+) ABSTRACT(+) void set(long, io.opentelemetry.api.common.Attributes, io.opentelemetry.context.Context) +*** MODIFIED INTERFACE: PUBLIC ABSTRACT io.opentelemetry.api.metrics.LongGaugeBuilder (not serializable) + === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 + +++ NEW METHOD: PUBLIC(+) io.opentelemetry.api.metrics.LongGauge build() diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-metrics.txt b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-metrics.txt index 37f807adf9b..ef9c86f56b8 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-metrics.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-metrics.txt @@ -5,3 +5,6 @@ Comparing source compatibility of against *** MODIFIED INTERFACE: PUBLIC ABSTRACT io.opentelemetry.sdk.metrics.export.DefaultAggregationSelector (not serializable) === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 +++ NEW METHOD: PUBLIC(+) STATIC(+) java.lang.String asString(io.opentelemetry.sdk.metrics.export.DefaultAggregationSelector) +*** MODIFIED ENUM: PUBLIC FINAL io.opentelemetry.sdk.metrics.InstrumentType (compatible) + === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 + +++ NEW FIELD: PUBLIC(+) STATIC(+) FINAL(+) io.opentelemetry.sdk.metrics.InstrumentType GAUGE diff --git a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/InstrumentType.java b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/InstrumentType.java index d2218ec8773..b876d00cf56 100644 --- a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/InstrumentType.java +++ b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/InstrumentType.java @@ -17,4 +17,5 @@ public enum InstrumentType { OBSERVABLE_COUNTER, OBSERVABLE_UP_DOWN_COUNTER, OBSERVABLE_GAUGE, + GAUGE, } diff --git a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkDoubleGauge.java b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkDoubleGauge.java index 1de8fa341cf..1c834b18e10 100644 --- a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkDoubleGauge.java +++ b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkDoubleGauge.java @@ -7,8 +7,8 @@ import io.opentelemetry.api.common.AttributeKey; import io.opentelemetry.api.common.Attributes; -import io.opentelemetry.api.incubator.metrics.DoubleGauge; import io.opentelemetry.api.incubator.metrics.ExtendedDoubleGaugeBuilder; +import io.opentelemetry.api.metrics.DoubleGauge; import io.opentelemetry.api.metrics.DoubleGaugeBuilder; import io.opentelemetry.api.metrics.LongGaugeBuilder; import io.opentelemetry.api.metrics.ObservableDoubleGauge; @@ -31,8 +31,13 @@ private SdkDoubleGauge(InstrumentDescriptor descriptor, WriteableMetricStorage s } @Override - public void set(double increment, Attributes attributes) { - storage.recordDouble(increment, attributes, Context.root()); + public void set(double value, Attributes attributes) { + storage.recordDouble(value, attributes, Context.current()); + } + + @Override + public void set(double value, Attributes attributes, Context context) { + storage.recordDouble(value, attributes, context); } @Override @@ -48,11 +53,10 @@ static final class SdkDoubleGaugeBuilder implements ExtendedDoubleGaugeBuilder { MeterSharedState meterSharedState, String name) { - // TODO: use InstrumentType.GAUGE when available builder = new InstrumentBuilder( name, - InstrumentType.OBSERVABLE_GAUGE, + InstrumentType.GAUGE, InstrumentValueType.DOUBLE, meterProviderSharedState, meterSharedState); @@ -88,13 +92,11 @@ public LongGaugeBuilder ofLongs() { @Override public ObservableDoubleGauge buildWithCallback(Consumer callback) { - // TODO: use InstrumentType.GAUGE when available return builder.buildDoubleAsynchronousInstrument(InstrumentType.OBSERVABLE_GAUGE, callback); } @Override public ObservableDoubleMeasurement buildObserver() { - // TODO: use InstrumentType.GAUGE when available return builder.buildObservableMeasurement(InstrumentType.OBSERVABLE_GAUGE); } diff --git a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkLongGauge.java b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkLongGauge.java index 92d9e84d098..ad7db428bdf 100644 --- a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkLongGauge.java +++ b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkLongGauge.java @@ -8,7 +8,7 @@ import io.opentelemetry.api.common.AttributeKey; import io.opentelemetry.api.common.Attributes; import io.opentelemetry.api.incubator.metrics.ExtendedLongGaugeBuilder; -import io.opentelemetry.api.incubator.metrics.LongGauge; +import io.opentelemetry.api.metrics.LongGauge; import io.opentelemetry.api.metrics.LongGaugeBuilder; import io.opentelemetry.api.metrics.ObservableLongGauge; import io.opentelemetry.api.metrics.ObservableLongMeasurement; @@ -31,8 +31,13 @@ private SdkLongGauge(InstrumentDescriptor descriptor, WriteableMetricStorage sto } @Override - public void set(long increment, Attributes attributes) { - storage.recordLong(increment, attributes, Context.root()); + public void set(long value, Attributes attributes) { + storage.recordLong(value, attributes, Context.current()); + } + + @Override + public void set(long value, Attributes attributes, Context context) { + storage.recordLong(value, attributes, context); } @Override @@ -52,11 +57,10 @@ static final class SdkLongGaugeBuilder implements ExtendedLongGaugeBuilder { String unit, Advice.AdviceBuilder adviceBuilder) { - // TODO: use InstrumentType.GAUGE when available builder = new InstrumentBuilder( name, - InstrumentType.OBSERVABLE_GAUGE, + InstrumentType.GAUGE, InstrumentValueType.LONG, meterProviderSharedState, sharedState) @@ -90,13 +94,11 @@ public ExtendedLongGaugeBuilder setAttributesAdvice(List> attrib @Override public ObservableLongGauge buildWithCallback(Consumer callback) { - // TODO: use InstrumentType.GAUGE when available return builder.buildLongAsynchronousInstrument(InstrumentType.OBSERVABLE_GAUGE, callback); } @Override public ObservableLongMeasurement buildObserver() { - // TODO: use InstrumentType.GAUGE when available return builder.buildObservableMeasurement(InstrumentType.OBSERVABLE_GAUGE); } diff --git a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/view/DefaultAggregation.java b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/view/DefaultAggregation.java index bbcecc08e1d..494e486c333 100644 --- a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/view/DefaultAggregation.java +++ b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/view/DefaultAggregation.java @@ -50,6 +50,7 @@ private static Aggregation resolve(InstrumentDescriptor instrument, boolean with } return ExplicitBucketHistogramAggregation.getDefault(); case OBSERVABLE_GAUGE: + case GAUGE: return LastValueAggregation.getInstance(); } logger.log(Level.WARNING, "Unable to find default aggregation for instrument: " + instrument); diff --git a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/view/LastValueAggregation.java b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/view/LastValueAggregation.java index 7dac6c6241d..693af692c93 100644 --- a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/view/LastValueAggregation.java +++ b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/view/LastValueAggregation.java @@ -5,10 +5,14 @@ package io.opentelemetry.sdk.metrics.internal.view; +import io.opentelemetry.sdk.common.Clock; import io.opentelemetry.sdk.common.export.MemoryMode; +import io.opentelemetry.sdk.internal.RandomSupplier; import io.opentelemetry.sdk.metrics.Aggregation; import io.opentelemetry.sdk.metrics.InstrumentType; +import io.opentelemetry.sdk.metrics.data.DoubleExemplarData; import io.opentelemetry.sdk.metrics.data.ExemplarData; +import io.opentelemetry.sdk.metrics.data.LongExemplarData; import io.opentelemetry.sdk.metrics.data.PointData; import io.opentelemetry.sdk.metrics.internal.aggregator.Aggregator; import io.opentelemetry.sdk.metrics.internal.aggregator.AggregatorFactory; @@ -17,6 +21,7 @@ import io.opentelemetry.sdk.metrics.internal.descriptor.InstrumentDescriptor; import io.opentelemetry.sdk.metrics.internal.exemplar.ExemplarFilter; import io.opentelemetry.sdk.metrics.internal.exemplar.ExemplarReservoir; +import java.util.function.Supplier; /** * Last-value aggregation configuration. @@ -44,18 +49,38 @@ public Aggregator createAggr // For the initial version we do not sample exemplars on gauges. switch (instrumentDescriptor.getValueType()) { case LONG: - return (Aggregator) - new LongLastValueAggregator(ExemplarReservoir::longNoSamples, memoryMode); + { + Supplier> reservoirFactory = + () -> + ExemplarReservoir.filtered( + exemplarFilter, + ExemplarReservoir.longFixedSizeReservoir( + Clock.getDefault(), + Runtime.getRuntime().availableProcessors(), + RandomSupplier.platformDefault())); + return (Aggregator) new LongLastValueAggregator(reservoirFactory, memoryMode); + } case DOUBLE: - return (Aggregator) - new DoubleLastValueAggregator(ExemplarReservoir::doubleNoSamples, memoryMode); + { + Supplier> reservoirFactory = + () -> + ExemplarReservoir.filtered( + exemplarFilter, + ExemplarReservoir.doubleFixedSizeReservoir( + Clock.getDefault(), + Runtime.getRuntime().availableProcessors(), + RandomSupplier.platformDefault())); + return (Aggregator) new DoubleLastValueAggregator(reservoirFactory, memoryMode); + } } throw new IllegalArgumentException("Invalid instrument value type"); } @Override public boolean isCompatibleWithInstrument(InstrumentDescriptor instrumentDescriptor) { - return instrumentDescriptor.getType() == InstrumentType.OBSERVABLE_GAUGE; + InstrumentType instrumentType = instrumentDescriptor.getType(); + return instrumentType == InstrumentType.OBSERVABLE_GAUGE + || instrumentType == InstrumentType.GAUGE; } @Override diff --git a/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/AggregationTest.java b/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/AggregationTest.java index 7606b321c9a..be2502ec054 100644 --- a/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/AggregationTest.java +++ b/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/AggregationTest.java @@ -51,11 +51,13 @@ void aggregationIsCompatible() { InstrumentDescriptor observableUpDownCounter = descriptorForType(InstrumentType.OBSERVABLE_UP_DOWN_COUNTER); InstrumentDescriptor observableGauge = descriptorForType(InstrumentType.OBSERVABLE_GAUGE); + InstrumentDescriptor gauge = descriptorForType(InstrumentType.GAUGE); InstrumentDescriptor histogram = descriptorForType(InstrumentType.HISTOGRAM); AggregatorFactory defaultAggregation = ((AggregatorFactory) Aggregation.defaultAggregation()); assertThat(defaultAggregation.isCompatibleWithInstrument(counter)).isTrue(); assertThat(defaultAggregation.isCompatibleWithInstrument(observableCounter)).isTrue(); + assertThat(defaultAggregation.isCompatibleWithInstrument(gauge)).isTrue(); assertThat(defaultAggregation.isCompatibleWithInstrument(upDownCounter)).isTrue(); assertThat(defaultAggregation.isCompatibleWithInstrument(observableUpDownCounter)).isTrue(); assertThat(defaultAggregation.isCompatibleWithInstrument(observableGauge)).isTrue(); @@ -64,6 +66,7 @@ void aggregationIsCompatible() { AggregatorFactory drop = ((AggregatorFactory) Aggregation.drop()); assertThat(drop.isCompatibleWithInstrument(counter)).isTrue(); assertThat(drop.isCompatibleWithInstrument(observableCounter)).isTrue(); + assertThat(drop.isCompatibleWithInstrument(gauge)).isTrue(); assertThat(drop.isCompatibleWithInstrument(upDownCounter)).isTrue(); assertThat(drop.isCompatibleWithInstrument(observableUpDownCounter)).isTrue(); assertThat(drop.isCompatibleWithInstrument(observableGauge)).isTrue(); @@ -75,6 +78,7 @@ void aggregationIsCompatible() { assertThat(sum.isCompatibleWithInstrument(upDownCounter)).isTrue(); assertThat(sum.isCompatibleWithInstrument(observableUpDownCounter)).isTrue(); assertThat(sum.isCompatibleWithInstrument(observableGauge)).isFalse(); + assertThat(sum.isCompatibleWithInstrument(gauge)).isFalse(); assertThat(sum.isCompatibleWithInstrument(histogram)).isTrue(); AggregatorFactory explicitHistogram = @@ -84,6 +88,7 @@ void aggregationIsCompatible() { assertThat(explicitHistogram.isCompatibleWithInstrument(upDownCounter)).isFalse(); assertThat(explicitHistogram.isCompatibleWithInstrument(observableUpDownCounter)).isFalse(); assertThat(explicitHistogram.isCompatibleWithInstrument(observableGauge)).isFalse(); + assertThat(explicitHistogram.isCompatibleWithInstrument(gauge)).isFalse(); assertThat(explicitHistogram.isCompatibleWithInstrument(histogram)).isTrue(); AggregatorFactory exponentialHistogram = @@ -93,6 +98,7 @@ void aggregationIsCompatible() { assertThat(exponentialHistogram.isCompatibleWithInstrument(upDownCounter)).isFalse(); assertThat(exponentialHistogram.isCompatibleWithInstrument(observableUpDownCounter)).isFalse(); assertThat(exponentialHistogram.isCompatibleWithInstrument(observableGauge)).isFalse(); + assertThat(exponentialHistogram.isCompatibleWithInstrument(gauge)).isFalse(); assertThat(exponentialHistogram.isCompatibleWithInstrument(histogram)).isTrue(); AggregatorFactory lastValue = ((AggregatorFactory) Aggregation.lastValue()); @@ -101,6 +107,7 @@ void aggregationIsCompatible() { assertThat(lastValue.isCompatibleWithInstrument(upDownCounter)).isFalse(); assertThat(lastValue.isCompatibleWithInstrument(observableUpDownCounter)).isFalse(); assertThat(lastValue.isCompatibleWithInstrument(observableGauge)).isTrue(); + assertThat(lastValue.isCompatibleWithInstrument(gauge)).isTrue(); assertThat(lastValue.isCompatibleWithInstrument(histogram)).isFalse(); } diff --git a/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/SdkDoubleGaugeTest.java b/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/SdkDoubleGaugeTest.java index 802029d8448..61c0d3ad0b9 100644 --- a/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/SdkDoubleGaugeTest.java +++ b/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/SdkDoubleGaugeTest.java @@ -11,10 +11,12 @@ import static org.assertj.core.api.Assertions.assertThatThrownBy; import io.opentelemetry.api.common.Attributes; -import io.opentelemetry.api.incubator.metrics.DoubleGauge; -import io.opentelemetry.api.incubator.metrics.ExtendedDoubleGaugeBuilder; +import io.opentelemetry.api.metrics.DoubleGauge; import io.opentelemetry.api.metrics.Meter; import io.opentelemetry.api.metrics.ObservableDoubleGauge; +import io.opentelemetry.api.trace.Span; +import io.opentelemetry.api.trace.Tracer; +import io.opentelemetry.context.Scope; import io.opentelemetry.internal.testing.slf4j.SuppressLogger; import io.opentelemetry.sdk.common.InstrumentationScopeInfo; import io.opentelemetry.sdk.metrics.internal.state.DefaultSynchronousMetricStorage; @@ -22,7 +24,9 @@ import io.opentelemetry.sdk.resources.Resource; import io.opentelemetry.sdk.testing.exporter.InMemoryMetricReader; import io.opentelemetry.sdk.testing.time.TestClock; +import io.opentelemetry.sdk.trace.SdkTracerProvider; import java.time.Duration; +import java.util.Collections; import java.util.stream.IntStream; import org.junit.jupiter.api.Test; @@ -47,11 +51,7 @@ class SdkDoubleGaugeTest { @Test void set_PreventNullAttributes() { - assertThatThrownBy( - () -> - ((ExtendedDoubleGaugeBuilder) sdkMeter.gaugeBuilder("testGauge")) - .build() - .set(1.0, null)) + assertThatThrownBy(() -> sdkMeter.gaugeBuilder("testGauge").build().set(1.0, null)) .isInstanceOf(NullPointerException.class) .hasMessage("attributes"); } @@ -59,7 +59,7 @@ void set_PreventNullAttributes() { @Test @SuppressLogger(DefaultSynchronousMetricStorage.class) void set_NaN() { - DoubleGauge gauge = ((ExtendedDoubleGaugeBuilder) sdkMeter.gaugeBuilder("testGauge")).build(); + DoubleGauge gauge = sdkMeter.gaugeBuilder("testGauge").build(); gauge.set(Double.NaN); assertThat(cumulativeReader.collectAllMetrics()).hasSize(0); } @@ -93,16 +93,14 @@ void observable_NaN() { @Test void collectMetrics_NoRecords() { - ((ExtendedDoubleGaugeBuilder) sdkMeter.gaugeBuilder("testGauge")).build(); + sdkMeter.gaugeBuilder("testGauge").build(); assertThat(cumulativeReader.collectAllMetrics()).isEmpty(); } @Test void collectMetrics_WithEmptyAttributes() { DoubleGauge doubleGauge = - ((ExtendedDoubleGaugeBuilder) - sdkMeter.gaugeBuilder("testGauge").setDescription("description").setUnit("K")) - .build(); + sdkMeter.gaugeBuilder("testGauge").setDescription("description").setUnit("K").build(); testClock.advance(Duration.ofNanos(SECOND_NANOS)); doubleGauge.set(12d, Attributes.empty()); doubleGauge.set(13d); @@ -126,11 +124,59 @@ void collectMetrics_WithEmptyAttributes() { .hasValue(13d)))); } + @Test + void collectMetrics_WithExemplars() { + InMemoryMetricReader reader = InMemoryMetricReader.create(); + SdkMeterProvider sdkMeterProvider = + SdkMeterProvider.builder() + .setClock(testClock) + .setResource(RESOURCE) + .registerView( + InstrumentSelector.builder().setName("*").build(), + View.builder().setAttributeFilter(Collections.emptySet()).build()) + .registerMetricReader(reader) + .build(); + Meter sdkMeter = sdkMeterProvider.get(getClass().getName()); + DoubleGauge doubleGauge = + sdkMeter.gaugeBuilder("testGauge").setDescription("description").setUnit("K").build(); + + SdkTracerProvider tracerProvider = SdkTracerProvider.builder().build(); + Tracer tracer = tracerProvider.get("foo"); + + Span span = tracer.spanBuilder("span").startSpan(); + try (Scope unused = span.makeCurrent()) { + doubleGauge.set(12d, Attributes.builder().put("key", "value").build()); + } + + assertThat(reader.collectAllMetrics()) + .satisfiesExactly( + metric -> + assertThat(metric) + .hasResource(RESOURCE) + .hasInstrumentationScope(INSTRUMENTATION_SCOPE_INFO) + .hasName("testGauge") + .hasDescription("description") + .hasUnit("K") + .hasDoubleGaugeSatisfying( + gauge -> + gauge.hasPointsSatisfying( + point -> + point + .hasValue(12d) + .hasExemplarsSatisfying( + exemplar -> + exemplar + .hasValue(12d) + .hasFilteredAttributes( + Attributes.builder() + .put("key", "value") + .build()))))); + } + @Test void collectMetrics_WithMultipleCollects() { long startTime = testClock.now(); - DoubleGauge doubleGauge = - ((ExtendedDoubleGaugeBuilder) sdkMeter.gaugeBuilder("testGauge")).build(); + DoubleGauge doubleGauge = sdkMeter.gaugeBuilder("testGauge").build(); doubleGauge.set(12.1d, Attributes.empty()); doubleGauge.set(123.3d, Attributes.builder().put("K", "V").build()); doubleGauge.set(21.4d, Attributes.empty()); @@ -228,8 +274,7 @@ void collectMetrics_WithMultipleCollects() { @Test void stressTest() { - DoubleGauge doubleGauge = - ((ExtendedDoubleGaugeBuilder) sdkMeter.gaugeBuilder("testGauge")).build(); + DoubleGauge doubleGauge = sdkMeter.gaugeBuilder("testGauge").build(); StressTestRunner.Builder stressTestBuilder = StressTestRunner.builder().setCollectionIntervalMs(100); @@ -268,8 +313,7 @@ void stressTest() { void stressTest_WithDifferentLabelSet() { String[] keys = {"Key_1", "Key_2", "Key_3", "Key_4"}; String[] values = {"Value_1", "Value_2", "Value_3", "Value_4"}; - DoubleGauge doubleGauge = - ((ExtendedDoubleGaugeBuilder) sdkMeter.gaugeBuilder("testGauge")).build(); + DoubleGauge doubleGauge = sdkMeter.gaugeBuilder("testGauge").build(); StressTestRunner.Builder stressTestBuilder = StressTestRunner.builder().setCollectionIntervalMs(100); diff --git a/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/SdkLongGaugeTest.java b/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/SdkLongGaugeTest.java index e3bd54ab4d5..0a117e48d82 100644 --- a/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/SdkLongGaugeTest.java +++ b/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/SdkLongGaugeTest.java @@ -11,15 +11,19 @@ import static org.assertj.core.api.Assertions.assertThatThrownBy; import io.opentelemetry.api.common.Attributes; -import io.opentelemetry.api.incubator.metrics.ExtendedLongGaugeBuilder; -import io.opentelemetry.api.incubator.metrics.LongGauge; +import io.opentelemetry.api.metrics.LongGauge; import io.opentelemetry.api.metrics.Meter; import io.opentelemetry.api.metrics.ObservableLongGauge; +import io.opentelemetry.api.trace.Span; +import io.opentelemetry.api.trace.Tracer; +import io.opentelemetry.context.Scope; import io.opentelemetry.sdk.common.InstrumentationScopeInfo; import io.opentelemetry.sdk.resources.Resource; import io.opentelemetry.sdk.testing.exporter.InMemoryMetricReader; import io.opentelemetry.sdk.testing.time.TestClock; +import io.opentelemetry.sdk.trace.SdkTracerProvider; import java.time.Duration; +import java.util.Collections; import java.util.stream.IntStream; import org.assertj.core.api.Assertions; import org.junit.jupiter.api.Test; @@ -45,11 +49,7 @@ class SdkLongGaugeTest { @Test void set_PreventNullAttributes() { - assertThatThrownBy( - () -> - ((ExtendedLongGaugeBuilder) sdkMeter.gaugeBuilder("testGauge").ofLongs()) - .build() - .set(1, null)) + assertThatThrownBy(() -> sdkMeter.gaugeBuilder("testGauge").ofLongs().build().set(1, null)) .isInstanceOf(NullPointerException.class) .hasMessage("attributes"); } @@ -77,19 +77,18 @@ void observable_RemoveCallback() { @Test void collectMetrics_NoRecords() { - ((ExtendedLongGaugeBuilder) sdkMeter.gaugeBuilder("testGauge").ofLongs()).build(); + sdkMeter.gaugeBuilder("testGauge").ofLongs().build(); assertThat(cumulativeReader.collectAllMetrics()).isEmpty(); } @Test void collectMetrics_WithEmptyAttributes() { LongGauge longGauge = - ((ExtendedLongGaugeBuilder) - sdkMeter - .gaugeBuilder("testGauge") - .ofLongs() - .setDescription("description") - .setUnit("K")) + sdkMeter + .gaugeBuilder("testGauge") + .ofLongs() + .setDescription("description") + .setUnit("K") .build(); testClock.advance(Duration.ofNanos(SECOND_NANOS)); longGauge.set(12, Attributes.empty()); @@ -114,11 +113,64 @@ void collectMetrics_WithEmptyAttributes() { .hasValue(13)))); } + @Test + void collectMetrics_WithExemplars() { + InMemoryMetricReader reader = InMemoryMetricReader.create(); + SdkMeterProvider sdkMeterProvider = + SdkMeterProvider.builder() + .setClock(testClock) + .setResource(RESOURCE) + .registerView( + InstrumentSelector.builder().setName("*").build(), + View.builder().setAttributeFilter(Collections.emptySet()).build()) + .registerMetricReader(reader) + .build(); + Meter sdkMeter = sdkMeterProvider.get(getClass().getName()); + LongGauge longGauge = + sdkMeter + .gaugeBuilder("testGauge") + .setDescription("description") + .setUnit("K") + .ofLongs() + .build(); + + SdkTracerProvider tracerProvider = SdkTracerProvider.builder().build(); + Tracer tracer = tracerProvider.get("foo"); + + Span span = tracer.spanBuilder("span").startSpan(); + try (Scope unused = span.makeCurrent()) { + longGauge.set(12L, Attributes.builder().put("key", "value").build()); + } + + assertThat(reader.collectAllMetrics()) + .satisfiesExactly( + metric -> + assertThat(metric) + .hasResource(RESOURCE) + .hasInstrumentationScope(INSTRUMENTATION_SCOPE_INFO) + .hasName("testGauge") + .hasDescription("description") + .hasUnit("K") + .hasLongGaugeSatisfying( + gauge -> + gauge.hasPointsSatisfying( + point -> + point + .hasValue(12L) + .hasExemplarsSatisfying( + exemplar -> + exemplar + .hasValue(12L) + .hasFilteredAttributes( + Attributes.builder() + .put("key", "value") + .build()))))); + } + @Test void collectMetrics_WithMultipleCollects() { long startTime = testClock.now(); - LongGauge longGauge = - ((ExtendedLongGaugeBuilder) sdkMeter.gaugeBuilder("testGauge").ofLongs()).build(); + LongGauge longGauge = sdkMeter.gaugeBuilder("testGauge").ofLongs().build(); longGauge.set(12, Attributes.empty()); longGauge.set(12, Attributes.builder().put("K", "V").build()); longGauge.set(21, Attributes.empty()); @@ -216,8 +268,7 @@ void collectMetrics_WithMultipleCollects() { @Test void stressTest() { - LongGauge longGauge = - ((ExtendedLongGaugeBuilder) sdkMeter.gaugeBuilder("testGauge").ofLongs()).build(); + LongGauge longGauge = sdkMeter.gaugeBuilder("testGauge").ofLongs().build(); StressTestRunner.Builder stressTestBuilder = StressTestRunner.builder().setCollectionIntervalMs(100); @@ -256,8 +307,7 @@ void stressTest() { void stressTest_WithDifferentLabelSet() { String[] keys = {"Key_1", "Key_2", "Key_3", "Key_4"}; String[] values = {"Value_1", "Value_2", "Value_3", "Value_4"}; - LongGauge longGauge = - ((ExtendedLongGaugeBuilder) sdkMeter.gaugeBuilder("testGauge").ofLongs()).build(); + LongGauge longGauge = sdkMeter.gaugeBuilder("testGauge").ofLongs().build(); StressTestRunner.Builder stressTestBuilder = StressTestRunner.builder().setCollectionIntervalMs(100); diff --git a/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/export/AggregationTemporalitySelectorTest.java b/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/export/AggregationTemporalitySelectorTest.java index 30bb02d5db3..fb821ce388e 100644 --- a/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/export/AggregationTemporalitySelectorTest.java +++ b/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/export/AggregationTemporalitySelectorTest.java @@ -28,6 +28,8 @@ void alwaysCumulative() { .isEqualTo(AggregationTemporality.CUMULATIVE); assertThat(selector.getAggregationTemporality(InstrumentType.OBSERVABLE_UP_DOWN_COUNTER)) .isEqualTo(AggregationTemporality.CUMULATIVE); + assertThat(selector.getAggregationTemporality(InstrumentType.GAUGE)) + .isEqualTo(AggregationTemporality.CUMULATIVE); } @Test @@ -45,6 +47,8 @@ void deltaPreferred() { .isEqualTo(AggregationTemporality.CUMULATIVE); assertThat(selector.getAggregationTemporality(InstrumentType.OBSERVABLE_UP_DOWN_COUNTER)) .isEqualTo(AggregationTemporality.CUMULATIVE); + assertThat(selector.getAggregationTemporality(InstrumentType.GAUGE)) + .isEqualTo(AggregationTemporality.DELTA); } @Test @@ -62,6 +66,8 @@ void lowMemory() { .isEqualTo(AggregationTemporality.CUMULATIVE); assertThat(selector.getAggregationTemporality(InstrumentType.OBSERVABLE_UP_DOWN_COUNTER)) .isEqualTo(AggregationTemporality.CUMULATIVE); + assertThat(selector.getAggregationTemporality(InstrumentType.GAUGE)) + .isEqualTo(AggregationTemporality.DELTA); } @Test @@ -76,7 +82,8 @@ void stringRepresentation() { + "HISTOGRAM=CUMULATIVE, " + "OBSERVABLE_COUNTER=CUMULATIVE, " + "OBSERVABLE_UP_DOWN_COUNTER=CUMULATIVE, " - + "OBSERVABLE_GAUGE=CUMULATIVE" + + "OBSERVABLE_GAUGE=CUMULATIVE, " + + "GAUGE=CUMULATIVE" + "}"); assertThat( AggregationTemporalitySelector.asString( @@ -88,7 +95,8 @@ void stringRepresentation() { + "HISTOGRAM=DELTA, " + "OBSERVABLE_COUNTER=DELTA, " + "OBSERVABLE_UP_DOWN_COUNTER=CUMULATIVE, " - + "OBSERVABLE_GAUGE=DELTA" + + "OBSERVABLE_GAUGE=DELTA, " + + "GAUGE=DELTA" + "}"); } } diff --git a/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/export/DefaultAggregationSelectorTest.java b/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/export/DefaultAggregationSelectorTest.java index 53bd0fbc0b0..1cbf0649c7a 100644 --- a/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/export/DefaultAggregationSelectorTest.java +++ b/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/export/DefaultAggregationSelectorTest.java @@ -45,6 +45,8 @@ void with() { .isEqualTo(Aggregation.defaultAggregation()); assertThat(selector1.getDefaultAggregation(InstrumentType.OBSERVABLE_GAUGE)) .isEqualTo(Aggregation.defaultAggregation()); + assertThat(selector1.getDefaultAggregation(InstrumentType.GAUGE)) + .isEqualTo(Aggregation.defaultAggregation()); DefaultAggregationSelector selector2 = selector1.with(InstrumentType.COUNTER, Aggregation.drop()); @@ -60,6 +62,8 @@ void with() { .isEqualTo(Aggregation.defaultAggregation()); assertThat(selector2.getDefaultAggregation(InstrumentType.OBSERVABLE_GAUGE)) .isEqualTo(Aggregation.defaultAggregation()); + assertThat(selector2.getDefaultAggregation(InstrumentType.GAUGE)) + .isEqualTo(Aggregation.defaultAggregation()); } @Test @@ -72,7 +76,8 @@ void stringRepresentation() { + "HISTOGRAM=default, " + "OBSERVABLE_COUNTER=default, " + "OBSERVABLE_UP_DOWN_COUNTER=default, " - + "OBSERVABLE_GAUGE=default" + + "OBSERVABLE_GAUGE=default, " + + "GAUGE=default" + "}"); assertThat( DefaultAggregationSelector.asString( @@ -85,7 +90,8 @@ void stringRepresentation() { + "HISTOGRAM=base2_exponential_bucket_histogram, " + "OBSERVABLE_COUNTER=default, " + "OBSERVABLE_UP_DOWN_COUNTER=default, " - + "OBSERVABLE_GAUGE=default" + + "OBSERVABLE_GAUGE=default, " + + "GAUGE=default" + "}"); } } From a855e1296eec307f8f52e90089c2edf92f4825b3 Mon Sep 17 00:00:00 2001 From: Trask Stalnaker Date: Thu, 9 May 2024 11:23:44 -0700 Subject: [PATCH 397/901] Mention branch protection ordering (#6406) Co-authored-by: Jack Berg --- .github/repository-settings.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.github/repository-settings.md b/.github/repository-settings.md index 7e777d110b6..874eebfab7a 100644 --- a/.github/repository-settings.md +++ b/.github/repository-settings.md @@ -17,6 +17,11 @@ Repository settings in addition to what's documented already at ## Branch protections +The order of branch protection rules +[can be important](https://docs.github.com/en/repositories/configuring-branches-and-merges-in-your-repository/defining-the-mergeability-of-pull-requests/managing-a-branch-protection-rule#about-branch-protection-rules). +The branch protection rules below should be added before the `**/**` branch protection rule +(this may require deleting the `**/**` rule and recreating it at the end). + ### `main` * Require branches to be up to date before merging: UNCHECKED From 67fcea3846eb18753935c35edd0b94e32df563df Mon Sep 17 00:00:00 2001 From: jack-berg <34418638+jack-berg@users.noreply.github.com> Date: Fri, 10 May 2024 10:06:14 -0500 Subject: [PATCH 398/901] Prepare for 1.38.0 release (#6441) Co-authored-by: Trask Stalnaker --- CHANGELOG.md | 83 +++++++++++++++++++ .../api/metrics/DoubleGauge.java | 6 +- .../api/metrics/DoubleGaugeBuilder.java | 1 + .../opentelemetry/api/metrics/LongGauge.java | 6 +- .../api/metrics/LongGaugeBuilder.java | 1 + .../io/opentelemetry/sdk/common/Clock.java | 2 + .../sdk/metrics/InstrumentType.java | 4 + .../AggregationTemporalitySelector.java | 2 + .../export/DefaultAggregationSelector.java | 2 + .../opentelemetry/sdk/trace/ReadableSpan.java | 1 + 10 files changed, 106 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7e7f629103b..f6c156536d2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,89 @@ ## Unreleased +### API + +* Stabilize synchronous gauge + ([#6419](https://github.com/open-telemetry/opentelemetry-java/pull/6419)) + +#### Incubator + +* Add put(AttributeKey, T) overload to EventBuilder + ([#6331](https://github.com/open-telemetry/opentelemetry-java/pull/6331)) + +#### Baggage + +* Baggage filters space-only keys + ([#6431](https://github.com/open-telemetry/opentelemetry-java/pull/6431)) + +### SDK + +* Add experimental scope config to enable / disable scopes (i.e. meter, logger, tracer) + ([#6375](https://github.com/open-telemetry/opentelemetry-java/pull/6375)) + +#### Traces + +* Add ReadableSpan#getAttributes + ([#6382](https://github.com/open-telemetry/opentelemetry-java/pull/6382)) +* Use standard ArrayList size rather than max number of links for initial span links allocation + ([#6252](https://github.com/open-telemetry/opentelemetry-java/pull/6252)) + +#### Metrics + +* Use low precision Clock#now when computing timestamp for exemplars + ([#6417](https://github.com/open-telemetry/opentelemetry-java/pull/6417)) +* Update invalid instrument name log message now that forward slash `/` is valid + ([#6343](https://github.com/open-telemetry/opentelemetry-java/pull/6343)) + +#### Exporters + +* Introduce low allocation OTLP marshalers. If using autoconfigure, opt in + via `OTEL_JAVA_EXPERIMENTAL_EXPORTER_MEMORY_MODE=REUSABLE_DATA`. + * Low allocation OTLP logs marshaler + ([#6429](https://github.com/open-telemetry/opentelemetry-java/pull/6429)) + * Low allocation OTLP metrics marshaler + ([#6422](https://github.com/open-telemetry/opentelemetry-java/pull/6422)) + * Low allocation OTLP trace marshaler + ([#6410](https://github.com/open-telemetry/opentelemetry-java/pull/6410)) + * Add memory mode support to OTLP exporters + ([#6430](https://github.com/open-telemetry/opentelemetry-java/pull/6430)) + * Marshal span status description without allocation + ([#6423](https://github.com/open-telemetry/opentelemetry-java/pull/6423)) + * Add private constructors for stateless marshalers + ([#6434](https://github.com/open-telemetry/opentelemetry-java/pull/6434)) +* Mark opentelemetry-exporter-sender-jdk stable + ([#6357](https://github.com/open-telemetry/opentelemetry-java/pull/6357)) +* PrometheusHttpServer prevent concurrent reads when reusable memory mode + ([#6371](https://github.com/open-telemetry/opentelemetry-java/pull/6371)) +* Ignore TLS components (SSLContext, TrustManager, KeyManager) if plain HTTP protocol is used for + exporting + ([#6329](https://github.com/open-telemetry/opentelemetry-java/pull/6329)) +* Add is_remote_parent span flags to OTLP exported Spans and SpanLinks + ([#6388](https://github.com/open-telemetry/opentelemetry-java/pull/6388)) +* Add missing fields to OTLP metric exporters `toString()` + ([#6402](https://github.com/open-telemetry/opentelemetry-java/pull/6402)) + +#### Extensions + +* Rename otel.config.file to otel.experimental.config.file for autoconfigure + ([#6396](https://github.com/open-telemetry/opentelemetry-java/pull/6396)) + +### OpenCensus Shim + +* Fix opencensus shim spanBuilderWithRemoteParent behavior + ([#6415](https://github.com/open-telemetry/opentelemetry-java/pull/6415)) + +### Tooling + +* Add additional API incubator docs + ([#6356](https://github.com/open-telemetry/opentelemetry-java/pull/6356)) +* Run build on java 21 + ([#6370](https://github.com/open-telemetry/opentelemetry-java/pull/6370)) +* Fix running tests with java 8 on macos + ([#6411](https://github.com/open-telemetry/opentelemetry-java/pull/6411)) +* Move away from deprecated gradle enterprise APIs + ([#6363](https://github.com/open-telemetry/opentelemetry-java/pull/6363)) + ## Version 1.37.0 (2024-04-05) **NOTICE:** This release contains a significant restructuring of the experimental event API and the API incubator artifact. Please read the notes in the `API -> Incubator` section carefully. diff --git a/api/all/src/main/java/io/opentelemetry/api/metrics/DoubleGauge.java b/api/all/src/main/java/io/opentelemetry/api/metrics/DoubleGauge.java index ee42b44aa7f..a755ff25b16 100644 --- a/api/all/src/main/java/io/opentelemetry/api/metrics/DoubleGauge.java +++ b/api/all/src/main/java/io/opentelemetry/api/metrics/DoubleGauge.java @@ -9,7 +9,11 @@ import io.opentelemetry.context.Context; import javax.annotation.concurrent.ThreadSafe; -/** A gauge instrument that synchronously records {@code double} values. */ +/** + * A gauge instrument that synchronously records {@code double} values. + * + * @since 1.38.0 + */ @ThreadSafe public interface DoubleGauge { /** diff --git a/api/all/src/main/java/io/opentelemetry/api/metrics/DoubleGaugeBuilder.java b/api/all/src/main/java/io/opentelemetry/api/metrics/DoubleGaugeBuilder.java index 98e4855d220..b0ea8b939fa 100644 --- a/api/all/src/main/java/io/opentelemetry/api/metrics/DoubleGaugeBuilder.java +++ b/api/all/src/main/java/io/opentelemetry/api/metrics/DoubleGaugeBuilder.java @@ -77,6 +77,7 @@ default ObservableDoubleMeasurement buildObserver() { * the value of the last recorded measurement is exported. * * @return The DoubleGauge instrument. + * @since 1.38.0 */ default DoubleGauge build() { return DefaultMeter.getInstance().gaugeBuilder("noop").build(); diff --git a/api/all/src/main/java/io/opentelemetry/api/metrics/LongGauge.java b/api/all/src/main/java/io/opentelemetry/api/metrics/LongGauge.java index 22b940eaa9f..018f60e323b 100644 --- a/api/all/src/main/java/io/opentelemetry/api/metrics/LongGauge.java +++ b/api/all/src/main/java/io/opentelemetry/api/metrics/LongGauge.java @@ -9,7 +9,11 @@ import io.opentelemetry.context.Context; import javax.annotation.concurrent.ThreadSafe; -/** A gauge instrument that synchronously records {@code long} values. */ +/** + * A gauge instrument that synchronously records {@code long} values. + * + * @since 1.38.0 + */ @ThreadSafe public interface LongGauge { /** diff --git a/api/all/src/main/java/io/opentelemetry/api/metrics/LongGaugeBuilder.java b/api/all/src/main/java/io/opentelemetry/api/metrics/LongGaugeBuilder.java index 7c0fd0e0af2..f33c53155e7 100644 --- a/api/all/src/main/java/io/opentelemetry/api/metrics/LongGaugeBuilder.java +++ b/api/all/src/main/java/io/opentelemetry/api/metrics/LongGaugeBuilder.java @@ -74,6 +74,7 @@ default ObservableLongMeasurement buildObserver() { * the value of the last recorded measurement is exported. * * @return The LongGauge instrument. + * @since 1.38.0 */ default LongGauge build() { return DefaultMeter.getInstance().gaugeBuilder("noop").ofLongs().build(); diff --git a/sdk/common/src/main/java/io/opentelemetry/sdk/common/Clock.java b/sdk/common/src/main/java/io/opentelemetry/sdk/common/Clock.java index 44a5e02eee6..dab812ebe3b 100644 --- a/sdk/common/src/main/java/io/opentelemetry/sdk/common/Clock.java +++ b/sdk/common/src/main/java/io/opentelemetry/sdk/common/Clock.java @@ -50,6 +50,8 @@ static Clock getDefault() { * ns precision is possible in java 8, regardless of the value of {@code highPrecision}. * *

      See {@link #now()} javadoc for details on usage. + * + * @since 1.38.0 */ default long now(boolean highPrecision) { return now(); diff --git a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/InstrumentType.java b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/InstrumentType.java index b876d00cf56..6b87ce20c9c 100644 --- a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/InstrumentType.java +++ b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/InstrumentType.java @@ -10,6 +10,7 @@ * * @since 1.14.0 */ +@SuppressWarnings({"MissingSummary", "SummaryJavadoc"}) public enum InstrumentType { COUNTER, UP_DOWN_COUNTER, @@ -17,5 +18,8 @@ public enum InstrumentType { OBSERVABLE_COUNTER, OBSERVABLE_UP_DOWN_COUNTER, OBSERVABLE_GAUGE, + /** + * @since 1.38.0 + */ GAUGE, } diff --git a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/export/AggregationTemporalitySelector.java b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/export/AggregationTemporalitySelector.java index 0d0e4a85625..f50e2bc5676 100644 --- a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/export/AggregationTemporalitySelector.java +++ b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/export/AggregationTemporalitySelector.java @@ -81,6 +81,8 @@ static AggregationTemporalitySelector lowMemory() { /** * Returns a string representation of this selector, for using in {@link Object#toString()} * implementations. + * + * @since 1.38.0 */ static String asString(AggregationTemporalitySelector selector) { StringJoiner joiner = new StringJoiner(", ", "AggregationTemporalitySelector{", "}"); diff --git a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/export/DefaultAggregationSelector.java b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/export/DefaultAggregationSelector.java index 86a33440fc0..d6d3058abd9 100644 --- a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/export/DefaultAggregationSelector.java +++ b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/export/DefaultAggregationSelector.java @@ -64,6 +64,8 @@ default DefaultAggregationSelector with(InstrumentType instrumentType, Aggregati /** * Returns a string representation of this selector, for using in {@link Object#toString()} * implementations. + * + * @since 1.38.0 */ static String asString(DefaultAggregationSelector selector) { StringJoiner joiner = new StringJoiner(", ", "DefaultAggregationSelector{", "}"); diff --git a/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/ReadableSpan.java b/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/ReadableSpan.java index f59b87599c1..5e6ef1cf962 100644 --- a/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/ReadableSpan.java +++ b/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/ReadableSpan.java @@ -124,6 +124,7 @@ default InstrumentationScopeInfo getInstrumentationScopeInfo() { * #getAttribute(AttributeKey)}. * * @return the Span attributes, or {@link Attributes#empty()} if the span has no attributes. + * @since 1.38.0 */ default Attributes getAttributes() { return Attributes.empty(); From f4121777fe5b24adae18f7becbfd52554c651152 Mon Sep 17 00:00:00 2001 From: OpenTelemetry Bot <107717825+opentelemetrybot@users.noreply.github.com> Date: Fri, 10 May 2024 17:21:49 +0200 Subject: [PATCH 399/901] Update version to 1.39.0 (#6447) --- CHANGELOG.md | 2 ++ version.gradle.kts | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f6c156536d2..e785579b02c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,8 @@ ## Unreleased +## Version 1.38.0 (2024-05-10) + ### API * Stabilize synchronous gauge diff --git a/version.gradle.kts b/version.gradle.kts index bcb45a91233..1706c313297 100644 --- a/version.gradle.kts +++ b/version.gradle.kts @@ -1,7 +1,7 @@ val snapshot = true allprojects { - var ver = "1.38.0" + var ver = "1.39.0" val release = findProperty("otel.release") if (release != null) { ver += "-" + release From 0cf28e9dc9d612cd84f1b8d1a80f33b8d986e00e Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 10 May 2024 08:34:20 -0700 Subject: [PATCH 400/901] Update plugin com.gradle.develocity to v3.17.3 (#6445) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- settings.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/settings.gradle.kts b/settings.gradle.kts index 4c0a2099101..a58cf9d0513 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -1,7 +1,7 @@ pluginManagement { plugins { id("com.github.johnrengelman.shadow") version "8.1.1" - id("com.gradle.develocity") version "3.17.2" + id("com.gradle.develocity") version "3.17.3" id("de.undercouch.download") version "5.6.0" id("org.jsonschema2pojo") version "1.2.1" id("io.github.gradle-nexus.publish-plugin") version "2.0.0" From 9810e09a95a16ad9d38c5e338b2352f7e2e9c2f2 Mon Sep 17 00:00:00 2001 From: John Watson Date: Fri, 10 May 2024 11:26:04 -0700 Subject: [PATCH 401/901] GHA for generating the post-release pull request (#6449) --- .github/scripts/get-prior-version.sh | 22 +++++++ .../workflows/generate-post-release-pr.yml | 61 +++++++++++++++++++ 2 files changed, 83 insertions(+) create mode 100755 .github/scripts/get-prior-version.sh create mode 100644 .github/workflows/generate-post-release-pr.yml diff --git a/.github/scripts/get-prior-version.sh b/.github/scripts/get-prior-version.sh new file mode 100755 index 00000000000..ca4987f09ac --- /dev/null +++ b/.github/scripts/get-prior-version.sh @@ -0,0 +1,22 @@ +version=$(.github/scripts/get-version.sh) +if [[ $version =~ ^([0-9]+)\.([0-9]+)\.([0-9]+) ]]; then + major="${BASH_REMATCH[1]}" + minor="${BASH_REMATCH[2]}" + patch="${BASH_REMATCH[3]}" +else + echo "unexpected version: $version" + exit 1 +fi +if [[ $patch == 0 ]]; then + if [[ $minor == 0 ]]; then + prior_major=$((major - 1)) + prior_minor=$(grep -Po "^## Version $prior_major.\K[0-9]+" CHANGELOG.md | head -1) + prior_version="$prior_major.$prior_minor" + else + prior_version="$major.$((minor - 1)).0" + fi +else + prior_version="$major.$minor.$((patch - 1))" +fi + +echo $prior_version diff --git a/.github/workflows/generate-post-release-pr.yml b/.github/workflows/generate-post-release-pr.yml new file mode 100644 index 00000000000..ef1a61c8184 --- /dev/null +++ b/.github/workflows/generate-post-release-pr.yml @@ -0,0 +1,61 @@ +name: Generate Post-Release PR +on: + workflow_dispatch: + +jobs: + prereqs: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - name: Verify prerequisites + run: | + if [[ $GITHUB_REF_NAME != main ]]; then + echo this workflow should only be run against main + exit 1 + fi + + create-pull-request-against-main: + runs-on: ubuntu-latest + needs: + - prereqs + steps: + - uses: actions/checkout@v4 + + - name: Set environment variables + run: | + version=$(.github/scripts/get-version.sh) + if [[ $version =~ ^([0-9]+)\.([0-9]+)\.0$ ]]; then + major="${BASH_REMATCH[1]}" + minor="${BASH_REMATCH[2]}" + next_version="$major.$((minor + 1)).0" + else + echo "unexpected version: $version" + exit 1 + fi + echo "NEXT_VERSION=$next_version" >> $GITHUB_ENV + echo "VERSION=$version" >> $GITHUB_ENV + prior_version=$(.github/scripts/get-prior-version.sh) + echo "PRIOR_VERSION=$prior_version" >> $GITHUB_ENV + + - name: Use CLA approved github bot + run: .github/scripts/use-cla-approved-github-bot.sh + + - name: Create pull request against main + env: + # not using secrets.GITHUB_TOKEN since pull requests from that token do not run workflows + GH_TOKEN: ${{ secrets.OPENTELEMETRYBOT_GITHUB_TOKEN }} + run: | + ./gradlew updateVersionInDocs -Prelease.version=$VERSION + ./gradlew japicmp -PapiBaseVersion=$PRIOR_VERSION -PapiNewVersion=$VERSION + ./gradlew --refresh-dependencies japicmp + + message="Post release for version $VERSION" + body="Post-release updates for version \`$VERSION\`." + branch="opentelemetrybot/post-release-for-${VERSION}" + + git checkout -b $branch + git commit -a -m "$message" + git push --set-upstream origin $branch + gh pr create --title "$message" \ + --body "$body" \ + --base main From 2b5ac31a5b41705ba6e4f66b4a11b9699f4470b4 Mon Sep 17 00:00:00 2001 From: John Watson Date: Fri, 10 May 2024 12:37:58 -0700 Subject: [PATCH 402/901] install java when running the post-release PR generation (#6450) --- .github/workflows/generate-post-release-pr.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.github/workflows/generate-post-release-pr.yml b/.github/workflows/generate-post-release-pr.yml index ef1a61c8184..bcb4d5cff88 100644 --- a/.github/workflows/generate-post-release-pr.yml +++ b/.github/workflows/generate-post-release-pr.yml @@ -20,6 +20,12 @@ jobs: - prereqs steps: - uses: actions/checkout@v4 + - id: setup-java + name: Set up Java for build + uses: actions/setup-java@v4 + with: + distribution: temurin + java-version: 17 - name: Set environment variables run: | From 8d85b580b2ae868a259ebafea71c6f1ba999bbf1 Mon Sep 17 00:00:00 2001 From: John Watson Date: Fri, 10 May 2024 14:42:10 -0700 Subject: [PATCH 403/901] use the correct versions to regen the japicmp files (#6451) --- .../workflows/generate-post-release-pr.yml | 27 ++++++++++--------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/.github/workflows/generate-post-release-pr.yml b/.github/workflows/generate-post-release-pr.yml index bcb4d5cff88..2007a9425fe 100644 --- a/.github/workflows/generate-post-release-pr.yml +++ b/.github/workflows/generate-post-release-pr.yml @@ -30,19 +30,20 @@ jobs: - name: Set environment variables run: | version=$(.github/scripts/get-version.sh) - if [[ $version =~ ^([0-9]+)\.([0-9]+)\.0$ ]]; then + echo "VERSION=$version" >> $GITHUB_ENV + prior_version=$(.github/scripts/get-prior-version.sh) + echo "PRIOR_VERSION=$prior_version" >> $GITHUB_ENV + if [[ $prior_version =~ ^([0-9]+)\.([0-9]+)\.([0-9]+)$ ]]; then major="${BASH_REMATCH[1]}" minor="${BASH_REMATCH[2]}" - next_version="$major.$((minor + 1)).0" + patch="${BASH_REMATCH[3]}" + + two_releases_ago="$major.$((minor - 1)).$patch" else - echo "unexpected version: $version" + echo "unexpected prior version: $prior_version" exit 1 fi - echo "NEXT_VERSION=$next_version" >> $GITHUB_ENV - echo "VERSION=$version" >> $GITHUB_ENV - prior_version=$(.github/scripts/get-prior-version.sh) - echo "PRIOR_VERSION=$prior_version" >> $GITHUB_ENV - + echo "TWO_VERSIONS_AGO=$two_releases_ago" >> $GITHUB_ENV - name: Use CLA approved github bot run: .github/scripts/use-cla-approved-github-bot.sh @@ -51,13 +52,13 @@ jobs: # not using secrets.GITHUB_TOKEN since pull requests from that token do not run workflows GH_TOKEN: ${{ secrets.OPENTELEMETRYBOT_GITHUB_TOKEN }} run: | - ./gradlew updateVersionInDocs -Prelease.version=$VERSION - ./gradlew japicmp -PapiBaseVersion=$PRIOR_VERSION -PapiNewVersion=$VERSION + ./gradlew updateVersionInDocs -Prelease.version=$PRIOR_VERSION + ./gradlew japicmp -PapiBaseVersion=$TWO_VERSIONS_AGO -PapiNewVersion=$PRIOR_VERSION ./gradlew --refresh-dependencies japicmp - message="Post release for version $VERSION" - body="Post-release updates for version \`$VERSION\`." - branch="opentelemetrybot/post-release-for-${VERSION}" + message="Post release for version $PRIOR_VERSION" + body="Post-release updates for version \`$PRIOR_VERSION\`." + branch="opentelemetrybot/post-release-for-${PRIOR_VERSION}" git checkout -b $branch git commit -a -m "$message" From 672d154d049eb3401f5dcf76fc387b31bed1bdbe Mon Sep 17 00:00:00 2001 From: John Watson Date: Fri, 10 May 2024 14:58:47 -0700 Subject: [PATCH 404/901] add any new apidiff files to the resulting PR --- .github/workflows/generate-post-release-pr.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/generate-post-release-pr.yml b/.github/workflows/generate-post-release-pr.yml index 2007a9425fe..0087219076d 100644 --- a/.github/workflows/generate-post-release-pr.yml +++ b/.github/workflows/generate-post-release-pr.yml @@ -61,6 +61,7 @@ jobs: branch="opentelemetrybot/post-release-for-${PRIOR_VERSION}" git checkout -b $branch + git add docs/apidiffs git commit -a -m "$message" git push --set-upstream origin $branch gh pr create --title "$message" \ From 1049897b2f7a2f1cd3f4c0ef4fc42fb75727f859 Mon Sep 17 00:00:00 2001 From: OpenTelemetry Bot <107717825+opentelemetrybot@users.noreply.github.com> Date: Sat, 11 May 2024 03:16:15 +0200 Subject: [PATCH 405/901] Post release for version 1.38.0 (#6453) --- README.md | 70 +++++++++---------- .../1.38.0_vs_1.37.0/opentelemetry-api.txt | 19 +++++ .../opentelemetry-context.txt | 2 + .../opentelemetry-exporter-common.txt | 2 + .../opentelemetry-exporter-logging-otlp.txt | 2 + .../opentelemetry-exporter-logging.txt | 2 + .../opentelemetry-exporter-otlp-common.txt | 2 + .../opentelemetry-exporter-otlp.txt | 2 + ...y-exporter-sender-grpc-managed-channel.txt | 2 + .../opentelemetry-exporter-sender-jdk.txt | 2 + .../opentelemetry-exporter-sender-okhttp.txt | 2 + .../opentelemetry-exporter-zipkin.txt | 2 + .../opentelemetry-extension-kotlin.txt | 2 + ...ntelemetry-extension-trace-propagators.txt | 2 + .../opentelemetry-opentracing-shim.txt | 2 + .../opentelemetry-sdk-common.txt | 4 ++ ...emetry-sdk-extension-autoconfigure-spi.txt | 2 + ...ntelemetry-sdk-extension-autoconfigure.txt | 2 + ...ry-sdk-extension-jaeger-remote-sampler.txt | 2 + .../opentelemetry-sdk-logs.txt | 2 + .../opentelemetry-sdk-metrics.txt | 10 +++ .../opentelemetry-sdk-testing.txt | 2 + .../opentelemetry-sdk-trace.txt | 4 ++ .../1.38.0_vs_1.37.0/opentelemetry-sdk.txt | 2 + .../current_vs_latest/opentelemetry-api.txt | 19 +---- .../opentelemetry-sdk-common.txt | 4 +- .../opentelemetry-sdk-metrics.txt | 10 +-- .../opentelemetry-sdk-trace.txt | 4 +- 28 files changed, 114 insertions(+), 68 deletions(-) create mode 100644 docs/apidiffs/1.38.0_vs_1.37.0/opentelemetry-api.txt create mode 100644 docs/apidiffs/1.38.0_vs_1.37.0/opentelemetry-context.txt create mode 100644 docs/apidiffs/1.38.0_vs_1.37.0/opentelemetry-exporter-common.txt create mode 100644 docs/apidiffs/1.38.0_vs_1.37.0/opentelemetry-exporter-logging-otlp.txt create mode 100644 docs/apidiffs/1.38.0_vs_1.37.0/opentelemetry-exporter-logging.txt create mode 100644 docs/apidiffs/1.38.0_vs_1.37.0/opentelemetry-exporter-otlp-common.txt create mode 100644 docs/apidiffs/1.38.0_vs_1.37.0/opentelemetry-exporter-otlp.txt create mode 100644 docs/apidiffs/1.38.0_vs_1.37.0/opentelemetry-exporter-sender-grpc-managed-channel.txt create mode 100644 docs/apidiffs/1.38.0_vs_1.37.0/opentelemetry-exporter-sender-jdk.txt create mode 100644 docs/apidiffs/1.38.0_vs_1.37.0/opentelemetry-exporter-sender-okhttp.txt create mode 100644 docs/apidiffs/1.38.0_vs_1.37.0/opentelemetry-exporter-zipkin.txt create mode 100644 docs/apidiffs/1.38.0_vs_1.37.0/opentelemetry-extension-kotlin.txt create mode 100644 docs/apidiffs/1.38.0_vs_1.37.0/opentelemetry-extension-trace-propagators.txt create mode 100644 docs/apidiffs/1.38.0_vs_1.37.0/opentelemetry-opentracing-shim.txt create mode 100644 docs/apidiffs/1.38.0_vs_1.37.0/opentelemetry-sdk-common.txt create mode 100644 docs/apidiffs/1.38.0_vs_1.37.0/opentelemetry-sdk-extension-autoconfigure-spi.txt create mode 100644 docs/apidiffs/1.38.0_vs_1.37.0/opentelemetry-sdk-extension-autoconfigure.txt create mode 100644 docs/apidiffs/1.38.0_vs_1.37.0/opentelemetry-sdk-extension-jaeger-remote-sampler.txt create mode 100644 docs/apidiffs/1.38.0_vs_1.37.0/opentelemetry-sdk-logs.txt create mode 100644 docs/apidiffs/1.38.0_vs_1.37.0/opentelemetry-sdk-metrics.txt create mode 100644 docs/apidiffs/1.38.0_vs_1.37.0/opentelemetry-sdk-testing.txt create mode 100644 docs/apidiffs/1.38.0_vs_1.37.0/opentelemetry-sdk-trace.txt create mode 100644 docs/apidiffs/1.38.0_vs_1.37.0/opentelemetry-sdk.txt diff --git a/README.md b/README.md index 87fd636d2c7..d63671a7260 100644 --- a/README.md +++ b/README.md @@ -104,7 +104,7 @@ dependency versions in sync. io.opentelemetry opentelemetry-bom - 1.37.0 + 1.38.0 pom import @@ -123,7 +123,7 @@ dependency versions in sync. ```groovy dependencies { - implementation platform("io.opentelemetry:opentelemetry-bom:1.37.0") + implementation platform("io.opentelemetry:opentelemetry-bom:1.38.0") implementation('io.opentelemetry:opentelemetry-api') } ``` @@ -132,8 +132,8 @@ Note that if you want to use any artifacts that have not fully stabilized yet (s ```groovy dependencies { - implementation platform("io.opentelemetry:opentelemetry-bom:1.37.0") - implementation platform('io.opentelemetry:opentelemetry-bom-alpha:1.37.0-alpha') + implementation platform("io.opentelemetry:opentelemetry-bom:1.38.0") + implementation platform('io.opentelemetry:opentelemetry-bom-alpha:1.38.0-alpha') implementation('io.opentelemetry:opentelemetry-api') implementation('io.opentelemetry:opentelemetry-exporter-prometheus') @@ -161,7 +161,7 @@ We strongly recommend using our published BOM to keep all dependency versions in io.opentelemetry opentelemetry-bom - 1.38.0-SNAPSHOT + 1.39.0-SNAPSHOT pom import @@ -184,7 +184,7 @@ repositories { } dependencies { - implementation platform("io.opentelemetry:opentelemetry-bom:1.38.0-SNAPSHOT") + implementation platform("io.opentelemetry:opentelemetry-bom:1.39.0-SNAPSHOT") implementation('io.opentelemetry:opentelemetry-api') } ``` @@ -229,66 +229,66 @@ dependency as follows, replacing `{{artifact-id}}` with the value from the "Arti | Component | Description | Artifact ID | Version | Javadoc | |----------------------------------------------|----------------------------------------|---------------------------|-------------------------------------------------------------|---------| -| [Bill of Materials (BOM)](./bom) | Bill of materials for stable artifacts | `opentelemetry-bom` | 1.37.0 | N/A | -| [Alpha Bill of Materials (BOM)](./bom-alpha) | Bill of materials for alpha artifacts | `opentelemetry-bom-alpha` | 1.37.0-alpha | N/A | +| [Bill of Materials (BOM)](./bom) | Bill of materials for stable artifacts | `opentelemetry-bom` | 1.38.0 | N/A | +| [Alpha Bill of Materials (BOM)](./bom-alpha) | Bill of materials for alpha artifacts | `opentelemetry-bom-alpha` | 1.38.0-alpha | N/A | ### API | Component | Description | Artifact ID | Version | Javadoc | |-----------------------------------|--------------------------------------------------------------------------------------|-------------------------------|---------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| [API](./api/all) | OpenTelemetry API, including metrics, traces, baggage, context | `opentelemetry-api` | 1.37.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-api.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-api) | -| [API Incubator](./api/incubator) | API incubator, including pass through propagator, and extended tracer, and Event API | `opentelemetry-api-incubator` | 1.37.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-api-incubator.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-api-incubator) | -| [Context API](./context) | OpenTelemetry context API | `opentelemetry-context` | 1.37.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-context.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-context) | +| [API](./api/all) | OpenTelemetry API, including metrics, traces, baggage, context | `opentelemetry-api` | 1.38.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-api.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-api) | +| [API Incubator](./api/incubator) | API incubator, including pass through propagator, and extended tracer, and Event API | `opentelemetry-api-incubator` | 1.38.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-api-incubator.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-api-incubator) | +| [Context API](./context) | OpenTelemetry context API | `opentelemetry-context` | 1.38.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-context.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-context) | ### API Extensions | Component | Description | Artifact ID | Version | Javadoc | |---------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|---------------------------------------------|-------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| [Kotlin Extension](./extensions/kotlin) | Context extension for coroutines | `opentelemetry-extension-kotlin` | 1.37.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-extension-kotlin.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-extension-kotlin) | -| [Trace Propagators Extension](./extensions/trace-propagators) | Trace propagators, including B3, Jaeger, OT Trace | `opentelemetry-extension-trace-propagators` | 1.37.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-extension-trace-propagators.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-extension-trace-propagators) | +| [Kotlin Extension](./extensions/kotlin) | Context extension for coroutines | `opentelemetry-extension-kotlin` | 1.38.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-extension-kotlin.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-extension-kotlin) | +| [Trace Propagators Extension](./extensions/trace-propagators) | Trace propagators, including B3, Jaeger, OT Trace | `opentelemetry-extension-trace-propagators` | 1.38.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-extension-trace-propagators.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-extension-trace-propagators) | ### SDK | Component | Description | Artifact ID | Version | Javadoc | |------------------------------|--------------------------------------------------------|-----------------------------|---------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| [SDK](./sdk/all) | OpenTelemetry SDK, including metrics, traces, and logs | `opentelemetry-sdk` | 1.37.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk) | -| [Metrics SDK](./sdk/metrics) | OpenTelemetry metrics SDK | `opentelemetry-sdk-metrics` | 1.37.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-metrics.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-metrics) | -| [Trace SDK](./sdk/trace) | OpenTelemetry trace SDK | `opentelemetry-sdk-trace` | 1.37.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-trace.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-trace) | -| [Log SDK](./sdk/logs) | OpenTelemetry log SDK | `opentelemetry-sdk-logs` | 1.37.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-logs.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-logs) | -| [SDK Common](./sdk/common) | Shared SDK components | `opentelemetry-sdk-common` | 1.37.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-common.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-common) | -| [SDK Testing](./sdk/testing) | Components for testing OpenTelemetry instrumentation | `opentelemetry-sdk-testing` | 1.37.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-testing.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-testing) | +| [SDK](./sdk/all) | OpenTelemetry SDK, including metrics, traces, and logs | `opentelemetry-sdk` | 1.38.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk) | +| [Metrics SDK](./sdk/metrics) | OpenTelemetry metrics SDK | `opentelemetry-sdk-metrics` | 1.38.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-metrics.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-metrics) | +| [Trace SDK](./sdk/trace) | OpenTelemetry trace SDK | `opentelemetry-sdk-trace` | 1.38.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-trace.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-trace) | +| [Log SDK](./sdk/logs) | OpenTelemetry log SDK | `opentelemetry-sdk-logs` | 1.38.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-logs.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-logs) | +| [SDK Common](./sdk/common) | Shared SDK components | `opentelemetry-sdk-common` | 1.38.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-common.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-common) | +| [SDK Testing](./sdk/testing) | Components for testing OpenTelemetry instrumentation | `opentelemetry-sdk-testing` | 1.38.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-testing.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-testing) | ### SDK Exporters | Component | Description | Artifact ID | Version | Javadoc | |-----------------------------------------------------------------------|------------------------------------------------------------------------------|-------------------------------------------------------------------------|-------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| [OTLP Exporters](./exporters/otlp/all) | OTLP gRPC & HTTP exporters, including traces, metrics, and logs | `opentelemetry-exporter-otlp` | 1.37.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-otlp.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-otlp) | -| [OTLP Logging Exporters](./exporters/logging-otlp) | Logging exporters in OTLP JSON encoding, including traces, metrics, and logs | `opentelemetry-exporter-logging-otlp` | 1.37.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-logging-otlp.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-logging-otlp) | -| [OTLP Common](./exporters/otlp/common) | Shared OTLP components (internal) | `opentelemetry-exporter-otlp-common` | 1.37.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-otlp-common.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-otlp-common) | -| [Logging Exporter](./exporters/logging) | Logging exporters, including metrics, traces, and logs | `opentelemetry-exporter-logging` | 1.37.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-logging.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-logging) | -| [Zipkin Exporter](./exporters/zipkin) | Zipkin trace exporter | `opentelemetry-exporter-zipkin` | 1.37.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-zipkin.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-zipkin) | -| [Prometheus Exporter](./exporters/prometheus) | Prometheus metric exporter | `opentelemetry-exporter-prometheus` | 1.37.0-alpha | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-prometheus.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-prometheus) | -| [Exporter Common](./exporters/common) | Shared exporter components (internal) | `opentelemetry-exporter-common` | 1.37.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-common.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-common) | -| [OkHttp Sender](./exporters/sender/okhttp) | OkHttp implementation of HttpSender (internal) | `opentelemetry-exporter-sender-okhttp` | 1.37.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-sender-okhttp.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-sender-okhttp) | -| [JDK Sender](./exporters/sender/okhttp) | Java 11+ native HttpClient implementation of HttpSender (internal) | `opentelemetry-exporter-sender-jdk` TODO: remove `-alpha` after release | 1.37.0-alpha | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-sender-jdk.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-sender-jdk) | | -| [gRPC ManagedChannel Sender](./exporters/sender/grpc-managed-channel) | gRPC ManagedChannel implementation of GrpcSender (internal) | `opentelemetry-exporter-sender-grpc-managed-channel` | 1.37.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-sender-grpc-managed-channel.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-sender-grpc-managed-channel) | | +| [OTLP Exporters](./exporters/otlp/all) | OTLP gRPC & HTTP exporters, including traces, metrics, and logs | `opentelemetry-exporter-otlp` | 1.38.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-otlp.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-otlp) | +| [OTLP Logging Exporters](./exporters/logging-otlp) | Logging exporters in OTLP JSON encoding, including traces, metrics, and logs | `opentelemetry-exporter-logging-otlp` | 1.38.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-logging-otlp.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-logging-otlp) | +| [OTLP Common](./exporters/otlp/common) | Shared OTLP components (internal) | `opentelemetry-exporter-otlp-common` | 1.38.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-otlp-common.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-otlp-common) | +| [Logging Exporter](./exporters/logging) | Logging exporters, including metrics, traces, and logs | `opentelemetry-exporter-logging` | 1.38.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-logging.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-logging) | +| [Zipkin Exporter](./exporters/zipkin) | Zipkin trace exporter | `opentelemetry-exporter-zipkin` | 1.38.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-zipkin.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-zipkin) | +| [Prometheus Exporter](./exporters/prometheus) | Prometheus metric exporter | `opentelemetry-exporter-prometheus` | 1.38.0-alpha | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-prometheus.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-prometheus) | +| [Exporter Common](./exporters/common) | Shared exporter components (internal) | `opentelemetry-exporter-common` | 1.38.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-common.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-common) | +| [OkHttp Sender](./exporters/sender/okhttp) | OkHttp implementation of HttpSender (internal) | `opentelemetry-exporter-sender-okhttp` | 1.38.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-sender-okhttp.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-sender-okhttp) | +| [JDK Sender](./exporters/sender/okhttp) | Java 11+ native HttpClient implementation of HttpSender (internal) | `opentelemetry-exporter-sender-jdk` TODO: remove `-alpha` after release | 1.38.0-alpha | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-sender-jdk.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-sender-jdk) | | +| [gRPC ManagedChannel Sender](./exporters/sender/grpc-managed-channel) | gRPC ManagedChannel implementation of GrpcSender (internal) | `opentelemetry-exporter-sender-grpc-managed-channel` | 1.38.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-sender-grpc-managed-channel.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-sender-grpc-managed-channel) | | ### SDK Extensions | Component | Description | Artifact ID | Version | Javadoc | |-------------------------------------------------------------------------------|------------------------------------------------------------------------------------|-----------------------------------------------------|-------------------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| [SDK Autoconfigure](./sdk-extensions/autoconfigure) | Autoconfigure OpenTelemetry SDK from env vars, system properties, and SPI | `opentelemetry-sdk-extension-autoconfigure` | 1.37.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-extension-autoconfigure.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-extension-autoconfigure) | -| [SDK Autoconfigure SPI](./sdk-extensions/autoconfigure-spi) | Service Provider Interface (SPI) definitions for autoconfigure | `opentelemetry-sdk-extension-autoconfigure-spi` | 1.37.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-extension-autoconfigure-spi.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-extension-autoconfigure-spi) | -| [SDK Jaeger Remote Sampler Extension](./sdk-extensions/jaeger-remote-sampler) | Sampler which obtains sampling configuration from remote Jaeger server | `opentelemetry-sdk-extension-jaeger-remote-sampler` | 1.37.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-extension-jaeger-remote-sampler.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-extension-jaeger-remote-sampler) | -| [SDK Incubator](./sdk-extensions/incubator) | SDK incubator, including YAML based view configuration, LeakDetectingSpanProcessor | `opentelemetry-sdk-extension-incubator` | 1.37.0-alpha | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-extension-incubator.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-extension-incubator) | +| [SDK Autoconfigure](./sdk-extensions/autoconfigure) | Autoconfigure OpenTelemetry SDK from env vars, system properties, and SPI | `opentelemetry-sdk-extension-autoconfigure` | 1.38.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-extension-autoconfigure.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-extension-autoconfigure) | +| [SDK Autoconfigure SPI](./sdk-extensions/autoconfigure-spi) | Service Provider Interface (SPI) definitions for autoconfigure | `opentelemetry-sdk-extension-autoconfigure-spi` | 1.38.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-extension-autoconfigure-spi.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-extension-autoconfigure-spi) | +| [SDK Jaeger Remote Sampler Extension](./sdk-extensions/jaeger-remote-sampler) | Sampler which obtains sampling configuration from remote Jaeger server | `opentelemetry-sdk-extension-jaeger-remote-sampler` | 1.38.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-extension-jaeger-remote-sampler.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-extension-jaeger-remote-sampler) | +| [SDK Incubator](./sdk-extensions/incubator) | SDK incubator, including YAML based view configuration, LeakDetectingSpanProcessor | `opentelemetry-sdk-extension-incubator` | 1.38.0-alpha | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-extension-incubator.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-extension-incubator) | ### Shims | Component | Description | Artifact ID | Version | Javadoc | |----------------------------------------|--------------------------------------------------------------|----------------------------------|-------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| [OpenCensus Shim](./opencensus-shim) | Bridge opencensus metrics into the OpenTelemetry metrics SDK | `opentelemetry-opencensus-shim` | 1.37.0-alpha | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-opencensus-shim.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-opencensus-shim) | -| [OpenTracing Shim](./opentracing-shim) | Bridge opentracing spans into the OpenTelemetry trace API | `opentelemetry-opentracing-shim` | 1.37.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-opentracing-shim.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-opentracing-shim) | +| [OpenCensus Shim](./opencensus-shim) | Bridge opencensus metrics into the OpenTelemetry metrics SDK | `opentelemetry-opencensus-shim` | 1.38.0-alpha | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-opencensus-shim.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-opencensus-shim) | +| [OpenTracing Shim](./opentracing-shim) | Bridge opentracing spans into the OpenTelemetry trace API | `opentelemetry-opentracing-shim` | 1.38.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-opentracing-shim.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-opentracing-shim) | ## Contributing diff --git a/docs/apidiffs/1.38.0_vs_1.37.0/opentelemetry-api.txt b/docs/apidiffs/1.38.0_vs_1.37.0/opentelemetry-api.txt new file mode 100644 index 00000000000..d050fbe201a --- /dev/null +++ b/docs/apidiffs/1.38.0_vs_1.37.0/opentelemetry-api.txt @@ -0,0 +1,19 @@ +Comparing source compatibility of against ++++ NEW INTERFACE: PUBLIC(+) ABSTRACT(+) io.opentelemetry.api.metrics.DoubleGauge (not serializable) + +++ CLASS FILE FORMAT VERSION: 52.0 <- n.a. + +++ NEW SUPERCLASS: java.lang.Object + +++ NEW METHOD: PUBLIC(+) ABSTRACT(+) void set(double) + +++ NEW METHOD: PUBLIC(+) ABSTRACT(+) void set(double, io.opentelemetry.api.common.Attributes) + +++ NEW METHOD: PUBLIC(+) ABSTRACT(+) void set(double, io.opentelemetry.api.common.Attributes, io.opentelemetry.context.Context) +*** MODIFIED INTERFACE: PUBLIC ABSTRACT io.opentelemetry.api.metrics.DoubleGaugeBuilder (not serializable) + === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 + +++ NEW METHOD: PUBLIC(+) io.opentelemetry.api.metrics.DoubleGauge build() ++++ NEW INTERFACE: PUBLIC(+) ABSTRACT(+) io.opentelemetry.api.metrics.LongGauge (not serializable) + +++ CLASS FILE FORMAT VERSION: 52.0 <- n.a. + +++ NEW SUPERCLASS: java.lang.Object + +++ NEW METHOD: PUBLIC(+) ABSTRACT(+) void set(long) + +++ NEW METHOD: PUBLIC(+) ABSTRACT(+) void set(long, io.opentelemetry.api.common.Attributes) + +++ NEW METHOD: PUBLIC(+) ABSTRACT(+) void set(long, io.opentelemetry.api.common.Attributes, io.opentelemetry.context.Context) +*** MODIFIED INTERFACE: PUBLIC ABSTRACT io.opentelemetry.api.metrics.LongGaugeBuilder (not serializable) + === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 + +++ NEW METHOD: PUBLIC(+) io.opentelemetry.api.metrics.LongGauge build() diff --git a/docs/apidiffs/1.38.0_vs_1.37.0/opentelemetry-context.txt b/docs/apidiffs/1.38.0_vs_1.37.0/opentelemetry-context.txt new file mode 100644 index 00000000000..df26146497b --- /dev/null +++ b/docs/apidiffs/1.38.0_vs_1.37.0/opentelemetry-context.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of against +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.38.0_vs_1.37.0/opentelemetry-exporter-common.txt b/docs/apidiffs/1.38.0_vs_1.37.0/opentelemetry-exporter-common.txt new file mode 100644 index 00000000000..df26146497b --- /dev/null +++ b/docs/apidiffs/1.38.0_vs_1.37.0/opentelemetry-exporter-common.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of against +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.38.0_vs_1.37.0/opentelemetry-exporter-logging-otlp.txt b/docs/apidiffs/1.38.0_vs_1.37.0/opentelemetry-exporter-logging-otlp.txt new file mode 100644 index 00000000000..df26146497b --- /dev/null +++ b/docs/apidiffs/1.38.0_vs_1.37.0/opentelemetry-exporter-logging-otlp.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of against +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.38.0_vs_1.37.0/opentelemetry-exporter-logging.txt b/docs/apidiffs/1.38.0_vs_1.37.0/opentelemetry-exporter-logging.txt new file mode 100644 index 00000000000..df26146497b --- /dev/null +++ b/docs/apidiffs/1.38.0_vs_1.37.0/opentelemetry-exporter-logging.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of against +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.38.0_vs_1.37.0/opentelemetry-exporter-otlp-common.txt b/docs/apidiffs/1.38.0_vs_1.37.0/opentelemetry-exporter-otlp-common.txt new file mode 100644 index 00000000000..df26146497b --- /dev/null +++ b/docs/apidiffs/1.38.0_vs_1.37.0/opentelemetry-exporter-otlp-common.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of against +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.38.0_vs_1.37.0/opentelemetry-exporter-otlp.txt b/docs/apidiffs/1.38.0_vs_1.37.0/opentelemetry-exporter-otlp.txt new file mode 100644 index 00000000000..df26146497b --- /dev/null +++ b/docs/apidiffs/1.38.0_vs_1.37.0/opentelemetry-exporter-otlp.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of against +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.38.0_vs_1.37.0/opentelemetry-exporter-sender-grpc-managed-channel.txt b/docs/apidiffs/1.38.0_vs_1.37.0/opentelemetry-exporter-sender-grpc-managed-channel.txt new file mode 100644 index 00000000000..df26146497b --- /dev/null +++ b/docs/apidiffs/1.38.0_vs_1.37.0/opentelemetry-exporter-sender-grpc-managed-channel.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of against +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.38.0_vs_1.37.0/opentelemetry-exporter-sender-jdk.txt b/docs/apidiffs/1.38.0_vs_1.37.0/opentelemetry-exporter-sender-jdk.txt new file mode 100644 index 00000000000..df26146497b --- /dev/null +++ b/docs/apidiffs/1.38.0_vs_1.37.0/opentelemetry-exporter-sender-jdk.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of against +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.38.0_vs_1.37.0/opentelemetry-exporter-sender-okhttp.txt b/docs/apidiffs/1.38.0_vs_1.37.0/opentelemetry-exporter-sender-okhttp.txt new file mode 100644 index 00000000000..df26146497b --- /dev/null +++ b/docs/apidiffs/1.38.0_vs_1.37.0/opentelemetry-exporter-sender-okhttp.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of against +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.38.0_vs_1.37.0/opentelemetry-exporter-zipkin.txt b/docs/apidiffs/1.38.0_vs_1.37.0/opentelemetry-exporter-zipkin.txt new file mode 100644 index 00000000000..df26146497b --- /dev/null +++ b/docs/apidiffs/1.38.0_vs_1.37.0/opentelemetry-exporter-zipkin.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of against +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.38.0_vs_1.37.0/opentelemetry-extension-kotlin.txt b/docs/apidiffs/1.38.0_vs_1.37.0/opentelemetry-extension-kotlin.txt new file mode 100644 index 00000000000..df26146497b --- /dev/null +++ b/docs/apidiffs/1.38.0_vs_1.37.0/opentelemetry-extension-kotlin.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of against +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.38.0_vs_1.37.0/opentelemetry-extension-trace-propagators.txt b/docs/apidiffs/1.38.0_vs_1.37.0/opentelemetry-extension-trace-propagators.txt new file mode 100644 index 00000000000..df26146497b --- /dev/null +++ b/docs/apidiffs/1.38.0_vs_1.37.0/opentelemetry-extension-trace-propagators.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of against +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.38.0_vs_1.37.0/opentelemetry-opentracing-shim.txt b/docs/apidiffs/1.38.0_vs_1.37.0/opentelemetry-opentracing-shim.txt new file mode 100644 index 00000000000..df26146497b --- /dev/null +++ b/docs/apidiffs/1.38.0_vs_1.37.0/opentelemetry-opentracing-shim.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of against +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.38.0_vs_1.37.0/opentelemetry-sdk-common.txt b/docs/apidiffs/1.38.0_vs_1.37.0/opentelemetry-sdk-common.txt new file mode 100644 index 00000000000..71f05afd4d1 --- /dev/null +++ b/docs/apidiffs/1.38.0_vs_1.37.0/opentelemetry-sdk-common.txt @@ -0,0 +1,4 @@ +Comparing source compatibility of against +*** MODIFIED INTERFACE: PUBLIC ABSTRACT io.opentelemetry.sdk.common.Clock (not serializable) + === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 + +++ NEW METHOD: PUBLIC(+) long now(boolean) diff --git a/docs/apidiffs/1.38.0_vs_1.37.0/opentelemetry-sdk-extension-autoconfigure-spi.txt b/docs/apidiffs/1.38.0_vs_1.37.0/opentelemetry-sdk-extension-autoconfigure-spi.txt new file mode 100644 index 00000000000..df26146497b --- /dev/null +++ b/docs/apidiffs/1.38.0_vs_1.37.0/opentelemetry-sdk-extension-autoconfigure-spi.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of against +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.38.0_vs_1.37.0/opentelemetry-sdk-extension-autoconfigure.txt b/docs/apidiffs/1.38.0_vs_1.37.0/opentelemetry-sdk-extension-autoconfigure.txt new file mode 100644 index 00000000000..df26146497b --- /dev/null +++ b/docs/apidiffs/1.38.0_vs_1.37.0/opentelemetry-sdk-extension-autoconfigure.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of against +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.38.0_vs_1.37.0/opentelemetry-sdk-extension-jaeger-remote-sampler.txt b/docs/apidiffs/1.38.0_vs_1.37.0/opentelemetry-sdk-extension-jaeger-remote-sampler.txt new file mode 100644 index 00000000000..df26146497b --- /dev/null +++ b/docs/apidiffs/1.38.0_vs_1.37.0/opentelemetry-sdk-extension-jaeger-remote-sampler.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of against +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.38.0_vs_1.37.0/opentelemetry-sdk-logs.txt b/docs/apidiffs/1.38.0_vs_1.37.0/opentelemetry-sdk-logs.txt new file mode 100644 index 00000000000..df26146497b --- /dev/null +++ b/docs/apidiffs/1.38.0_vs_1.37.0/opentelemetry-sdk-logs.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of against +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.38.0_vs_1.37.0/opentelemetry-sdk-metrics.txt b/docs/apidiffs/1.38.0_vs_1.37.0/opentelemetry-sdk-metrics.txt new file mode 100644 index 00000000000..ef9c86f56b8 --- /dev/null +++ b/docs/apidiffs/1.38.0_vs_1.37.0/opentelemetry-sdk-metrics.txt @@ -0,0 +1,10 @@ +Comparing source compatibility of against +*** MODIFIED INTERFACE: PUBLIC ABSTRACT io.opentelemetry.sdk.metrics.export.AggregationTemporalitySelector (not serializable) + === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 + +++ NEW METHOD: PUBLIC(+) STATIC(+) java.lang.String asString(io.opentelemetry.sdk.metrics.export.AggregationTemporalitySelector) +*** MODIFIED INTERFACE: PUBLIC ABSTRACT io.opentelemetry.sdk.metrics.export.DefaultAggregationSelector (not serializable) + === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 + +++ NEW METHOD: PUBLIC(+) STATIC(+) java.lang.String asString(io.opentelemetry.sdk.metrics.export.DefaultAggregationSelector) +*** MODIFIED ENUM: PUBLIC FINAL io.opentelemetry.sdk.metrics.InstrumentType (compatible) + === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 + +++ NEW FIELD: PUBLIC(+) STATIC(+) FINAL(+) io.opentelemetry.sdk.metrics.InstrumentType GAUGE diff --git a/docs/apidiffs/1.38.0_vs_1.37.0/opentelemetry-sdk-testing.txt b/docs/apidiffs/1.38.0_vs_1.37.0/opentelemetry-sdk-testing.txt new file mode 100644 index 00000000000..df26146497b --- /dev/null +++ b/docs/apidiffs/1.38.0_vs_1.37.0/opentelemetry-sdk-testing.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of against +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.38.0_vs_1.37.0/opentelemetry-sdk-trace.txt b/docs/apidiffs/1.38.0_vs_1.37.0/opentelemetry-sdk-trace.txt new file mode 100644 index 00000000000..722ee3a950f --- /dev/null +++ b/docs/apidiffs/1.38.0_vs_1.37.0/opentelemetry-sdk-trace.txt @@ -0,0 +1,4 @@ +Comparing source compatibility of against +*** MODIFIED INTERFACE: PUBLIC ABSTRACT io.opentelemetry.sdk.trace.ReadableSpan (not serializable) + === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 + +++ NEW METHOD: PUBLIC(+) io.opentelemetry.api.common.Attributes getAttributes() diff --git a/docs/apidiffs/1.38.0_vs_1.37.0/opentelemetry-sdk.txt b/docs/apidiffs/1.38.0_vs_1.37.0/opentelemetry-sdk.txt new file mode 100644 index 00000000000..df26146497b --- /dev/null +++ b/docs/apidiffs/1.38.0_vs_1.37.0/opentelemetry-sdk.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of against +No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-api.txt b/docs/apidiffs/current_vs_latest/opentelemetry-api.txt index d050fbe201a..df26146497b 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-api.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-api.txt @@ -1,19 +1,2 @@ Comparing source compatibility of against -+++ NEW INTERFACE: PUBLIC(+) ABSTRACT(+) io.opentelemetry.api.metrics.DoubleGauge (not serializable) - +++ CLASS FILE FORMAT VERSION: 52.0 <- n.a. - +++ NEW SUPERCLASS: java.lang.Object - +++ NEW METHOD: PUBLIC(+) ABSTRACT(+) void set(double) - +++ NEW METHOD: PUBLIC(+) ABSTRACT(+) void set(double, io.opentelemetry.api.common.Attributes) - +++ NEW METHOD: PUBLIC(+) ABSTRACT(+) void set(double, io.opentelemetry.api.common.Attributes, io.opentelemetry.context.Context) -*** MODIFIED INTERFACE: PUBLIC ABSTRACT io.opentelemetry.api.metrics.DoubleGaugeBuilder (not serializable) - === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 - +++ NEW METHOD: PUBLIC(+) io.opentelemetry.api.metrics.DoubleGauge build() -+++ NEW INTERFACE: PUBLIC(+) ABSTRACT(+) io.opentelemetry.api.metrics.LongGauge (not serializable) - +++ CLASS FILE FORMAT VERSION: 52.0 <- n.a. - +++ NEW SUPERCLASS: java.lang.Object - +++ NEW METHOD: PUBLIC(+) ABSTRACT(+) void set(long) - +++ NEW METHOD: PUBLIC(+) ABSTRACT(+) void set(long, io.opentelemetry.api.common.Attributes) - +++ NEW METHOD: PUBLIC(+) ABSTRACT(+) void set(long, io.opentelemetry.api.common.Attributes, io.opentelemetry.context.Context) -*** MODIFIED INTERFACE: PUBLIC ABSTRACT io.opentelemetry.api.metrics.LongGaugeBuilder (not serializable) - === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 - +++ NEW METHOD: PUBLIC(+) io.opentelemetry.api.metrics.LongGauge build() +No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-common.txt b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-common.txt index 71f05afd4d1..df26146497b 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-common.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-common.txt @@ -1,4 +1,2 @@ Comparing source compatibility of against -*** MODIFIED INTERFACE: PUBLIC ABSTRACT io.opentelemetry.sdk.common.Clock (not serializable) - === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 - +++ NEW METHOD: PUBLIC(+) long now(boolean) +No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-metrics.txt b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-metrics.txt index ef9c86f56b8..df26146497b 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-metrics.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-metrics.txt @@ -1,10 +1,2 @@ Comparing source compatibility of against -*** MODIFIED INTERFACE: PUBLIC ABSTRACT io.opentelemetry.sdk.metrics.export.AggregationTemporalitySelector (not serializable) - === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 - +++ NEW METHOD: PUBLIC(+) STATIC(+) java.lang.String asString(io.opentelemetry.sdk.metrics.export.AggregationTemporalitySelector) -*** MODIFIED INTERFACE: PUBLIC ABSTRACT io.opentelemetry.sdk.metrics.export.DefaultAggregationSelector (not serializable) - === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 - +++ NEW METHOD: PUBLIC(+) STATIC(+) java.lang.String asString(io.opentelemetry.sdk.metrics.export.DefaultAggregationSelector) -*** MODIFIED ENUM: PUBLIC FINAL io.opentelemetry.sdk.metrics.InstrumentType (compatible) - === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 - +++ NEW FIELD: PUBLIC(+) STATIC(+) FINAL(+) io.opentelemetry.sdk.metrics.InstrumentType GAUGE +No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-trace.txt b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-trace.txt index 722ee3a950f..df26146497b 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-trace.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-trace.txt @@ -1,4 +1,2 @@ Comparing source compatibility of against -*** MODIFIED INTERFACE: PUBLIC ABSTRACT io.opentelemetry.sdk.trace.ReadableSpan (not serializable) - === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 - +++ NEW METHOD: PUBLIC(+) io.opentelemetry.api.common.Attributes getAttributes() +No changes. \ No newline at end of file From 9543a3451851d82f2f9d8e1b0cd78e2cc133b1a5 Mon Sep 17 00:00:00 2001 From: crossoverJie Date: Sat, 11 May 2024 09:17:31 +0800 Subject: [PATCH 406/901] Update otel.exporter.otlp.protocol default value (#6444) --- sdk-extensions/autoconfigure/README.md | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/sdk-extensions/autoconfigure/README.md b/sdk-extensions/autoconfigure/README.md index 2b0fc01960c..6fed9d1fe66 100644 --- a/sdk-extensions/autoconfigure/README.md +++ b/sdk-extensions/autoconfigure/README.md @@ -122,10 +122,10 @@ The [OpenTelemetry Protocol (OTLP)](https://github.com/open-telemetry/openteleme | otel.exporter.otlp.traces.timeout | OTEL_EXPORTER_OTLP_TRACES_TIMEOUT | The maximum waiting time, in milliseconds, allowed to send each OTLP trace batch. Default is `10000`. | | otel.exporter.otlp.metrics.timeout | OTEL_EXPORTER_OTLP_METRICS_TIMEOUT | The maximum waiting time, in milliseconds, allowed to send each OTLP metric batch. Default is `10000`. | | otel.exporter.otlp.logs.timeout | OTEL_EXPORTER_OTLP_LOGS_TIMEOUT | The maximum waiting time, in milliseconds, allowed to send each OTLP log batch. Default is `10000`. | -| otel.exporter.otlp.protocol | OTEL_EXPORTER_OTLP_PROTOCOL | The transport protocol to use on OTLP trace, metric, and log requests. Options include `grpc` and `http/protobuf`. Default is `grpc`. | -| otel.exporter.otlp.traces.protocol | OTEL_EXPORTER_OTLP_TRACES_PROTOCOL | The transport protocol to use on OTLP trace requests. Options include `grpc` and `http/protobuf`. Default is `grpc`. | -| otel.exporter.otlp.metrics.protocol | OTEL_EXPORTER_OTLP_METRICS_PROTOCOL | The transport protocol to use on OTLP metric requests. Options include `grpc` and `http/protobuf`. Default is `grpc`. | -| otel.exporter.otlp.logs.protocol | OTEL_EXPORTER_OTLP_LOGS_PROTOCOL | The transport protocol to use on OTLP log requests. Options include `grpc` and `http/protobuf`. Default is `grpc`. | +| otel.exporter.otlp.protocol | OTEL_EXPORTER_OTLP_PROTOCOL | The transport protocol to use on OTLP trace, metric, and log requests. Options include `grpc` and `http/protobuf`. Default is `grpc`.**[1]** | +| otel.exporter.otlp.traces.protocol | OTEL_EXPORTER_OTLP_TRACES_PROTOCOL | The transport protocol to use on OTLP trace requests. Options include `grpc` and `http/protobuf`. Default is `grpc`.**[1]** | +| otel.exporter.otlp.metrics.protocol | OTEL_EXPORTER_OTLP_METRICS_PROTOCOL | The transport protocol to use on OTLP metric requests. Options include `grpc` and `http/protobuf`. Default is `grpc`.**[1]** | +| otel.exporter.otlp.logs.protocol | OTEL_EXPORTER_OTLP_LOGS_PROTOCOL | The transport protocol to use on OTLP log requests. Options include `grpc` and `http/protobuf`. Default is `grpc`.**[1]** | | otel.exporter.otlp.metrics.temporality.preference | OTEL_EXPORTER_OTLP_METRICS_TEMPORALITY_PREFERENCE | The preferred output aggregation temporality. Options include `DELTA`, `LOWMEMORY`, and `CUMULATIVE`. If `CUMULATIVE`, all instruments will have cumulative temporality. If `DELTA`, counter (sync and async) and histograms will be delta, up down counters (sync and async) will be cumulative. If `LOWMEMORY`, sync counter and histograms will be delta, async counter and up down counters (sync and async) will be cumulative. Default is `CUMULATIVE`. | | otel.exporter.otlp.metrics.default.histogram.aggregation | OTEL_EXPORTER_OTLP_METRICS_DEFAULT_HISTOGRAM_AGGREGATION | The preferred default histogram aggregation. Options include `BASE2_EXPONENTIAL_BUCKET_HISTOGRAM` and `EXPLICIT_BUCKET_HISTOGRAM`. Default is `EXPLICIT_BUCKET_HISTOGRAM`. | | otel.experimental.exporter.otlp.retry.enabled | OTEL_EXPERIMENTAL_EXPORTER_OTLP_RETRY_ENABLED | If `true`, enable [experimental retry support](#otlp-exporter-retry). Default is `false`. | @@ -133,6 +133,8 @@ The [OpenTelemetry Protocol (OTLP)](https://github.com/open-telemetry/openteleme To configure the service name for the OTLP exporter, add the `service.name` key to the OpenTelemetry Resource ([see below](#opentelemetry-resource)), e.g. `OTEL_RESOURCE_ATTRIBUTES=service.name=myservice`. +**[1]**: NOTE: OpenTelemetry Java Agent 2.x uses `http/protobuf` by default. + ##### OTLP exporter retry [OTLP](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/protocol/otlp.md#otlpgrpc-response) requires that [transient](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/protocol/exporter.md#retry) errors be handled with a retry strategy. When retry is enabled, retryable gRPC status codes will be retried using an exponential backoff with jitter algorithm as described in the [gRPC Retry Design](https://github.com/grpc/proposal/blob/master/A6-client-retries.md#exponential-backoff). From 2e3e04c7e882722c52e1c56e4e8604e78594d87d Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 15 May 2024 18:54:22 -0700 Subject: [PATCH 407/901] Update dependency io.grpc:grpc-bom to v1.64.0 (#6461) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- dependencyManagement/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index 8ee8f2c535e..e83c8ad1b32 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -14,7 +14,7 @@ val DEPENDENCY_BOMS = listOf( "com.linecorp.armeria:armeria-bom:1.28.4", "com.squareup.okhttp3:okhttp-bom:4.12.0", "com.squareup.okio:okio-bom:3.9.0", // applies to transitive dependencies of okhttp - "io.grpc:grpc-bom:1.63.0", + "io.grpc:grpc-bom:1.64.0", "io.netty:netty-bom:4.1.109.Final", "io.zipkin.brave:brave-bom:6.0.3", "io.zipkin.reporter2:zipkin-reporter-bom:3.4.0", From d91b6e99d4e008cebd08e1ae3faa59c0e3e05766 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 16 May 2024 15:30:20 -0700 Subject: [PATCH 408/901] Update dependency com.google.api.grpc:proto-google-common-protos to v2.39.1 (#6463) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- dependencyManagement/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index e83c8ad1b32..7399101b3ab 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -55,7 +55,7 @@ val DEPENDENCIES = listOf( "io.prometheus:simpleclient_httpserver:${prometheusClientVersion}", "javax.annotation:javax.annotation-api:1.3.2", "com.github.stefanbirkner:system-rules:1.19.0", - "com.google.api.grpc:proto-google-common-protos:2.39.0", + "com.google.api.grpc:proto-google-common-protos:2.39.1", "com.google.code.findbugs:jsr305:3.0.2", "com.google.guava:guava-beta-checker:1.0", "com.sun.net.httpserver:http:20070405", From b1958e3fab5cd01a6273f56c809b263ceb74ec43 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 17 May 2024 09:38:46 -0700 Subject: [PATCH 409/901] Update dependency org.owasp:dependency-check-gradle to v9.2.0 (#6462) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- buildSrc/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts index 67daf216b29..b0bcac92a16 100644 --- a/buildSrc/build.gradle.kts +++ b/buildSrc/build.gradle.kts @@ -66,7 +66,7 @@ dependencies { implementation("net.ltgt.gradle:gradle-errorprone-plugin:3.1.0") implementation("net.ltgt.gradle:gradle-nullaway-plugin:2.0.0") implementation("org.jetbrains.kotlin:kotlin-gradle-plugin:1.9.24") - implementation("org.owasp:dependency-check-gradle:9.1.0") + implementation("org.owasp:dependency-check-gradle:9.2.0") implementation("ru.vyarus:gradle-animalsniffer-plugin:1.7.1") } From 37740b6c720be5205e1b51e32fd00bc2268e9ce6 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 18 May 2024 19:55:00 -0700 Subject: [PATCH 410/901] Update plugin com.gradle.develocity to v3.17.4 (#6465) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- settings.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/settings.gradle.kts b/settings.gradle.kts index a58cf9d0513..858eca24965 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -1,7 +1,7 @@ pluginManagement { plugins { id("com.github.johnrengelman.shadow") version "8.1.1" - id("com.gradle.develocity") version "3.17.3" + id("com.gradle.develocity") version "3.17.4" id("de.undercouch.download") version "5.6.0" id("org.jsonschema2pojo") version "1.2.1" id("io.github.gradle-nexus.publish-plugin") version "2.0.0" From 7953048fe02f5f841e091feff975e806007d8c28 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 18 May 2024 21:29:28 -0700 Subject: [PATCH 411/901] Update plugin org.graalvm.buildtools.native to v0.10.2 (#6466) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- settings.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/settings.gradle.kts b/settings.gradle.kts index 858eca24965..a5d95eb9bf7 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -5,7 +5,7 @@ pluginManagement { id("de.undercouch.download") version "5.6.0" id("org.jsonschema2pojo") version "1.2.1" id("io.github.gradle-nexus.publish-plugin") version "2.0.0" - id("org.graalvm.buildtools.native") version "0.10.1" + id("org.graalvm.buildtools.native") version "0.10.2" } } From c71c4d983cf2bf99f3d130ec50d131c07c47fd8a Mon Sep 17 00:00:00 2001 From: jack-berg <34418638+jack-berg@users.noreply.github.com> Date: Mon, 20 May 2024 14:39:41 -0500 Subject: [PATCH 412/901] =?UTF-8?q?Load=20file=20config=20YAML=20using=20c?= =?UTF-8?q?ore=20schema,=20ensure=20that=20env=20var=20substiut=E2=80=A6?= =?UTF-8?q?=20(#6436)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../fileconfig/FileConfiguration.java | 114 +++++++++++++----- .../FileConfigurationParseTest.java | 36 +++++- 2 files changed, 114 insertions(+), 36 deletions(-) diff --git a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/FileConfiguration.java b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/FileConfiguration.java index 061185c630d..94150a04b8a 100644 --- a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/FileConfiguration.java +++ b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/FileConfiguration.java @@ -24,9 +24,15 @@ import java.util.regex.Pattern; import org.snakeyaml.engine.v2.api.Load; import org.snakeyaml.engine.v2.api.LoadSettings; +import org.snakeyaml.engine.v2.common.ScalarStyle; import org.snakeyaml.engine.v2.constructor.StandardConstructor; +import org.snakeyaml.engine.v2.exceptions.ConstructorException; +import org.snakeyaml.engine.v2.exceptions.YamlEngineException; import org.snakeyaml.engine.v2.nodes.MappingNode; -import org.yaml.snakeyaml.Yaml; +import org.snakeyaml.engine.v2.nodes.Node; +import org.snakeyaml.engine.v2.nodes.NodeTuple; +import org.snakeyaml.engine.v2.nodes.ScalarNode; +import org.snakeyaml.engine.v2.schema.CoreSchema; /** * Configure {@link OpenTelemetrySdk} from YAML configuration files conforming to the schema in environmentVariables) { - LoadSettings settings = LoadSettings.builder().build(); + LoadSettings settings = LoadSettings.builder().setSchema(new CoreSchema()).build(); Load yaml = new Load(settings, new EnvSubstitutionConstructor(settings, environmentVariables)); return yaml.loadFromInputStream(inputStream); } @@ -145,52 +151,94 @@ static Object loadYaml(InputStream inputStream, Map environmentV */ private static final class EnvSubstitutionConstructor extends StandardConstructor { - // Yaml is not thread safe but this instance is always used on the same thread - private final Yaml yaml = new Yaml(); + // Load is not thread safe but this instance is always used on the same thread + private final Load load; private final Map environmentVariables; private EnvSubstitutionConstructor( LoadSettings loadSettings, Map environmentVariables) { super(loadSettings); + load = new Load(loadSettings); this.environmentVariables = environmentVariables; } + /** + * Implementation is same as {@link + * org.snakeyaml.engine.v2.constructor.BaseConstructor#constructMapping(MappingNode)} except we + * override the resolution of values with our custom {@link #constructValueObject(Node)}, which + * performs environment variable substitution. + */ @Override + @SuppressWarnings({"ReturnValueIgnored", "CatchingUnchecked"}) protected Map constructMapping(MappingNode node) { - // First call the super to construct mapping from MappingNode as usual - Map result = super.constructMapping(node); - - // Iterate through the map entries, and: - // 1. Identify entries which are scalar strings eligible for environment variable substitution - // 2. Apply environment variable substitution - // 3. Re-parse substituted value so it has correct type (i.e. yaml.load(newVal)) - for (Map.Entry entry : result.entrySet()) { - Object value = entry.getValue(); - if (!(value instanceof String)) { - continue; + Map mapping = settings.getDefaultMap().apply(node.getValue().size()); + List nodeValue = node.getValue(); + for (NodeTuple tuple : nodeValue) { + Node keyNode = tuple.getKeyNode(); + Object key = constructObject(keyNode); + if (key != null) { + try { + key.hashCode(); // check circular dependencies + } catch (Exception e) { + throw new ConstructorException( + "while constructing a mapping", + node.getStartMark(), + "found unacceptable key " + key, + tuple.getKeyNode().getStartMark(), + e); + } } - - String val = (String) value; - Matcher matcher = ENV_VARIABLE_REFERENCE.matcher(val); - if (!matcher.find()) { - continue; + Node valueNode = tuple.getValueNode(); + Object value = constructValueObject(valueNode); + if (keyNode.isRecursive()) { + if (settings.getAllowRecursiveKeys()) { + postponeMapFilling(mapping, key, value); + } else { + throw new YamlEngineException( + "Recursive key for mapping is detected but it is not configured to be allowed."); + } + } else { + mapping.put(key, value); } + } - int offset = 0; - StringBuilder newVal = new StringBuilder(); - do { - MatchResult matchResult = matcher.toMatchResult(); - String replacement = environmentVariables.getOrDefault(matcher.group(1), ""); - newVal.append(val, offset, matchResult.start()).append(replacement); - offset = matchResult.end(); - } while (matcher.find()); - if (offset != val.length()) { - newVal.append(val, offset, val.length()); - } - entry.setValue(yaml.load(newVal.toString())); + return mapping; + } + + private Object constructValueObject(Node node) { + Object value = constructObject(node); + if (!(node instanceof ScalarNode)) { + return value; + } + if (!(value instanceof String)) { + return value; + } + + String val = (String) value; + Matcher matcher = ENV_VARIABLE_REFERENCE.matcher(val); + if (!matcher.find()) { + return value; } - return result; + int offset = 0; + StringBuilder newVal = new StringBuilder(); + ScalarStyle scalarStyle = ((ScalarNode) node).getScalarStyle(); + do { + MatchResult matchResult = matcher.toMatchResult(); + String replacement = environmentVariables.getOrDefault(matcher.group(1), ""); + newVal.append(val, offset, matchResult.start()).append(replacement); + offset = matchResult.end(); + } while (matcher.find()); + if (offset != val.length()) { + newVal.append(val, offset, val.length()); + } + // If the value was double quoted, retain the double quotes so we don't change a value + // intended to be a string to a different type after environment variable substitution + if (scalarStyle == ScalarStyle.DOUBLE_QUOTED) { + newVal.insert(0, "\""); + newVal.append("\""); + } + return load.loadFromString(newVal.toString()); } } } diff --git a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/FileConfigurationParseTest.java b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/FileConfigurationParseTest.java index 8b0674109b8..bfb0fe09f1b 100644 --- a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/FileConfigurationParseTest.java +++ b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/FileConfigurationParseTest.java @@ -387,15 +387,36 @@ void parse_nullBoxedPrimitivesParsedToNull() { new Sampler().withTraceIdRatioBased(new TraceIdRatioBased())))); } + @ParameterizedTest + @MethodSource("coreSchemaValuesArgs") + void coreSchemaValues(String rawYaml, Object expectedYamlResult) { + Object yaml = + FileConfiguration.loadYaml( + new ByteArrayInputStream(rawYaml.getBytes(StandardCharsets.UTF_8)), + Collections.emptyMap()); + assertThat(yaml).isEqualTo(expectedYamlResult); + } + + @SuppressWarnings("unchecked") + private static java.util.stream.Stream coreSchemaValuesArgs() { + return java.util.stream.Stream.of( + Arguments.of("key1: 0o123\n", mapOf(entry("key1", 83))), + Arguments.of("key1: 0123\n", mapOf(entry("key1", 123))), + Arguments.of("key1: 0xdeadbeef\n", mapOf(entry("key1", 3735928559L))), + Arguments.of("key1: \"0xdeadbeef\"\n", mapOf(entry("key1", "0xdeadbeef")))); + } + @ParameterizedTest @MethodSource("envVarSubstitutionArgs") void envSubstituteAndLoadYaml(String rawYaml, Object expectedYamlResult) { Map environmentVariables = new HashMap<>(); environmentVariables.put("STR_1", "value1"); environmentVariables.put("STR_2", "value2"); + environmentVariables.put("EMPTY_STR", ""); environmentVariables.put("BOOL", "true"); environmentVariables.put("INT", "1"); environmentVariables.put("FLOAT", "1.1"); + environmentVariables.put("HEX", "0xdeadbeef"); Object yaml = FileConfiguration.loadYaml( @@ -412,6 +433,7 @@ private static java.util.stream.Stream envVarSubstitutionArgs() { Arguments.of("key1: ${BOOL}\n", mapOf(entry("key1", true))), Arguments.of("key1: ${INT}\n", mapOf(entry("key1", 1))), Arguments.of("key1: ${FLOAT}\n", mapOf(entry("key1", 1.1))), + Arguments.of("key1: ${HEX}\n", mapOf(entry("key1", 3735928559L))), Arguments.of( "key1: ${STR_1}\n" + "key2: value2\n", mapOf(entry("key1", "value1"), entry("key2", "value2"))), @@ -421,7 +443,8 @@ private static java.util.stream.Stream envVarSubstitutionArgs() { // Multiple environment variables referenced Arguments.of("key1: ${STR_1}${STR_2}\n", mapOf(entry("key1", "value1value2"))), Arguments.of("key1: ${STR_1} ${STR_2}\n", mapOf(entry("key1", "value1 value2"))), - // Undefined environment variable + // Undefined / empty environment variable + Arguments.of("key1: ${EMPTY_STR}\n", mapOf(entry("key1", null))), Arguments.of("key1: ${STR_3}\n", mapOf(entry("key1", null))), Arguments.of("key1: ${STR_1} ${STR_3}\n", mapOf(entry("key1", "value1"))), // Environment variable keys must match pattern: [a-zA-Z_]+[a-zA-Z0-9_]* @@ -432,7 +455,14 @@ private static java.util.stream.Stream envVarSubstitutionArgs() { "key1:\n ${STR_1}: value1\n", mapOf(entry("key1", mapOf(entry("${STR_1}", "value1"))))), Arguments.of( - "key1:\n - ${STR_1}\n", mapOf(entry("key1", Collections.singletonList("${STR_1}"))))); + "key1:\n - ${STR_1}\n", mapOf(entry("key1", Collections.singletonList("${STR_1}")))), + // Quoted environment variables + Arguments.of("key1: \"${HEX}\"\n", mapOf(entry("key1", "0xdeadbeef"))), + Arguments.of("key1: \"${STR_1}\"\n", mapOf(entry("key1", "value1"))), + Arguments.of("key1: \"${EMPTY_STR}\"\n", mapOf(entry("key1", ""))), + Arguments.of("key1: \"${BOOL}\"\n", mapOf(entry("key1", "true"))), + Arguments.of("key1: \"${INT}\"\n", mapOf(entry("key1", "1"))), + Arguments.of("key1: \"${FLOAT}\"\n", mapOf(entry("key1", "1.1")))); } private static Map.Entry entry(K key, @Nullable V value) { @@ -461,7 +491,7 @@ void read_WithEnvironmentVariables() { + " - batch:\n" + " exporter:\n" + " otlp:\n" - + " endpoint: \"${UNSET_ENV_VAR}\"\n"; + + " endpoint: ${UNSET_ENV_VAR}\n"; Map envVars = new HashMap<>(); envVars.put("OTEL_EXPORTER_OTLP_ENDPOINT", "http://collector:4317"); OpenTelemetryConfiguration model = From bb56b537abbd2ca9e501e132b642f5957f30d29f Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 22 May 2024 10:54:35 -0700 Subject: [PATCH 413/901] Update dependency io.netty:netty-bom to v4.1.110.Final (#6470) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- dependencyManagement/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index 7399101b3ab..c4080a12aa6 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -15,7 +15,7 @@ val DEPENDENCY_BOMS = listOf( "com.squareup.okhttp3:okhttp-bom:4.12.0", "com.squareup.okio:okio-bom:3.9.0", // applies to transitive dependencies of okhttp "io.grpc:grpc-bom:1.64.0", - "io.netty:netty-bom:4.1.109.Final", + "io.netty:netty-bom:4.1.110.Final", "io.zipkin.brave:brave-bom:6.0.3", "io.zipkin.reporter2:zipkin-reporter-bom:3.4.0", "org.assertj:assertj-bom:3.25.3", From a7644192707c4d584724d2bcb23046b01134ba3c Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 22 May 2024 11:17:34 -0700 Subject: [PATCH 414/901] Update dependency org.jetbrains.kotlin:kotlin-gradle-plugin to v2 (#6468) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- buildSrc/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts index b0bcac92a16..b967cbea765 100644 --- a/buildSrc/build.gradle.kts +++ b/buildSrc/build.gradle.kts @@ -65,7 +65,7 @@ dependencies { implementation("me.champeau.jmh:jmh-gradle-plugin:0.7.2") implementation("net.ltgt.gradle:gradle-errorprone-plugin:3.1.0") implementation("net.ltgt.gradle:gradle-nullaway-plugin:2.0.0") - implementation("org.jetbrains.kotlin:kotlin-gradle-plugin:1.9.24") + implementation("org.jetbrains.kotlin:kotlin-gradle-plugin:2.0.0") implementation("org.owasp:dependency-check-gradle:9.2.0") implementation("ru.vyarus:gradle-animalsniffer-plugin:1.7.1") } From b6c30bccacb103aa7531a193a55a7bb19d84038d Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sun, 26 May 2024 09:51:05 -0700 Subject: [PATCH 415/901] Update dependency org.assertj:assertj-bom to v3.26.0 (#6475) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- dependencyManagement/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index c4080a12aa6..0540139e7cf 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -18,7 +18,7 @@ val DEPENDENCY_BOMS = listOf( "io.netty:netty-bom:4.1.110.Final", "io.zipkin.brave:brave-bom:6.0.3", "io.zipkin.reporter2:zipkin-reporter-bom:3.4.0", - "org.assertj:assertj-bom:3.25.3", + "org.assertj:assertj-bom:3.26.0", "org.junit:junit-bom:5.10.2", "org.testcontainers:testcontainers-bom:1.19.8", "org.snakeyaml:snakeyaml-engine:2.7" From d3e3bdf6ec73dbe58e5cf6a1b736d82c746fa913 Mon Sep 17 00:00:00 2001 From: lizongwu Date: Tue, 28 May 2024 22:05:16 +0800 Subject: [PATCH 416/901] Start prometheus httpserver with daemon thread (#6472) --- .../exporter/prometheus/PrometheusHttpServer.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/exporters/prometheus/src/main/java/io/opentelemetry/exporter/prometheus/PrometheusHttpServer.java b/exporters/prometheus/src/main/java/io/opentelemetry/exporter/prometheus/PrometheusHttpServer.java index f815ea0ac54..ed5f1f7c1b1 100644 --- a/exporters/prometheus/src/main/java/io/opentelemetry/exporter/prometheus/PrometheusHttpServer.java +++ b/exporters/prometheus/src/main/java/io/opentelemetry/exporter/prometheus/PrometheusHttpServer.java @@ -12,6 +12,7 @@ import io.opentelemetry.sdk.common.CompletableResultCode; import io.opentelemetry.sdk.common.export.MemoryMode; +import io.opentelemetry.sdk.internal.DaemonThreadFactory; import io.opentelemetry.sdk.metrics.InstrumentType; import io.opentelemetry.sdk.metrics.data.AggregationTemporality; import io.opentelemetry.sdk.metrics.export.CollectionRegistration; @@ -75,7 +76,8 @@ public static PrometheusHttpServerBuilder builder() { // we configure prometheus with a single thread executor such that requests are handled // sequentially. if (memoryMode == MemoryMode.REUSABLE_DATA) { - executor = Executors.newSingleThreadExecutor(); + executor = + Executors.newSingleThreadExecutor(new DaemonThreadFactory("prometheus-http-server")); } try { this.httpServer = From dab1a6cc8f82250babf6cf8b8f9d06b89cc25343 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 28 May 2024 09:31:56 -0700 Subject: [PATCH 417/901] Update dependency checkstyle to v10.17.0 (#6477) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- buildSrc/src/main/kotlin/otel.java-conventions.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/buildSrc/src/main/kotlin/otel.java-conventions.gradle.kts b/buildSrc/src/main/kotlin/otel.java-conventions.gradle.kts index a1445ef80a3..f054d6fa89f 100644 --- a/buildSrc/src/main/kotlin/otel.java-conventions.gradle.kts +++ b/buildSrc/src/main/kotlin/otel.java-conventions.gradle.kts @@ -35,7 +35,7 @@ java { checkstyle { configDirectory.set(file("$rootDir/buildscripts/")) - toolVersion = "10.16.0" + toolVersion = "10.17.0" isIgnoreFailures = false configProperties["rootDir"] = rootDir } From a1c72d17e031be9c8ed037dd34e4f8bce0a626fd Mon Sep 17 00:00:00 2001 From: Kyle Moore Date: Tue, 28 May 2024 09:44:23 -0700 Subject: [PATCH 418/901] Normalize timestamps and file ordering in jars, making the outputs reproducible (#6471) --- buildSrc/src/main/kotlin/otel.java-conventions.gradle.kts | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/buildSrc/src/main/kotlin/otel.java-conventions.gradle.kts b/buildSrc/src/main/kotlin/otel.java-conventions.gradle.kts index f054d6fa89f..f651f5c3021 100644 --- a/buildSrc/src/main/kotlin/otel.java-conventions.gradle.kts +++ b/buildSrc/src/main/kotlin/otel.java-conventions.gradle.kts @@ -24,6 +24,13 @@ base { } } +// normalize timestamps and file ordering in jars, making the outputs reproducible +// see open-telemetry/opentelemetry-java#4488 +tasks.withType().configureEach { + isPreserveFileTimestamps = false + isReproducibleFileOrder = true +} + java { toolchain { languageVersion.set(JavaLanguageVersion.of(17)) From cdcc58cb87cd9ae546f285aa9e53428db1c7f9d8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20St=C3=A4ber?= Date: Tue, 28 May 2024 18:50:04 +0200 Subject: [PATCH 419/901] Update the Prometetheus metrics library (#6473) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Fabian Stäber --- dependencyManagement/build.gradle.kts | 2 +- .../prometheus/Otel2PrometheusConverter.java | 3 +-- .../prometheus/PrometheusUnitsHelper.java | 18 +++++++++++++++--- .../Otel2PrometheusConverterTest.java | 6 +++--- 4 files changed, 20 insertions(+), 9 deletions(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index 0540139e7cf..7849fd34d7f 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -70,7 +70,7 @@ val DEPENDENCIES = listOf( "io.opentelemetry.proto:opentelemetry-proto:1.2.0-alpha", "io.opentracing:opentracing-api:0.33.0", "io.opentracing:opentracing-noop:0.33.0", - "io.prometheus:prometheus-metrics-exporter-httpserver:1.2.1", + "io.prometheus:prometheus-metrics-exporter-httpserver:1.3.1", "junit:junit:4.13.2", "nl.jqno.equalsverifier:equalsverifier:3.16.1", "org.awaitility:awaitility:4.2.1", diff --git a/exporters/prometheus/src/main/java/io/opentelemetry/exporter/prometheus/Otel2PrometheusConverter.java b/exporters/prometheus/src/main/java/io/opentelemetry/exporter/prometheus/Otel2PrometheusConverter.java index 72dbaa446f5..e1cb84d9766 100644 --- a/exporters/prometheus/src/main/java/io/opentelemetry/exporter/prometheus/Otel2PrometheusConverter.java +++ b/exporters/prometheus/src/main/java/io/opentelemetry/exporter/prometheus/Otel2PrometheusConverter.java @@ -537,8 +537,7 @@ private static MetricMetadata convertMetadata(MetricData metricData) { String help = metricData.getDescription(); Unit unit = PrometheusUnitsHelper.convertUnit(metricData.getUnit()); if (unit != null && !name.endsWith(unit.toString())) { - // Need to re-sanitize metric name since unit may contain illegal characters - name = sanitizeMetricName(name + "_" + unit); + name = name + "_" + unit; } // Repeated __ are not allowed according to spec, although this is allowed in prometheus while (name.contains("__")) { diff --git a/exporters/prometheus/src/main/java/io/opentelemetry/exporter/prometheus/PrometheusUnitsHelper.java b/exporters/prometheus/src/main/java/io/opentelemetry/exporter/prometheus/PrometheusUnitsHelper.java index db0503eb3fb..b2a9c856992 100644 --- a/exporters/prometheus/src/main/java/io/opentelemetry/exporter/prometheus/PrometheusUnitsHelper.java +++ b/exporters/prometheus/src/main/java/io/opentelemetry/exporter/prometheus/PrometheusUnitsHelper.java @@ -5,6 +5,7 @@ package io.opentelemetry.exporter.prometheus; +import io.prometheus.metrics.model.snapshots.PrometheusNaming; import io.prometheus.metrics.model.snapshots.Unit; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; @@ -86,11 +87,22 @@ static Unit convertUnit(String otelUnit) { String part1 = pluralNames.getOrDefault(parts[0], parts[0]).trim(); String part2 = singularNames.getOrDefault(parts[1], parts[1]).trim(); if (part1.isEmpty()) { - return new Unit("per_" + part2); + return unitOrNull("per_" + part2); } else { - return new Unit(part1 + "_per_" + part2); + return unitOrNull(part1 + "_per_" + part2); } } - return new Unit(otelUnit); + return unitOrNull(otelUnit); + } + + @Nullable + private static Unit unitOrNull(String name) { + try { + return new Unit(PrometheusNaming.sanitizeUnitName(name)); + } catch (IllegalArgumentException e) { + // This happens if the name cannot be converted to a valid Prometheus unit name, + // for example if name is "total". + return null; + } } } diff --git a/exporters/prometheus/src/test/java/io/opentelemetry/exporter/prometheus/Otel2PrometheusConverterTest.java b/exporters/prometheus/src/test/java/io/opentelemetry/exporter/prometheus/Otel2PrometheusConverterTest.java index 26466c1e393..5b8dd270548 100644 --- a/exporters/prometheus/src/test/java/io/opentelemetry/exporter/prometheus/Otel2PrometheusConverterTest.java +++ b/exporters/prometheus/src/test/java/io/opentelemetry/exporter/prometheus/Otel2PrometheusConverterTest.java @@ -283,9 +283,9 @@ private static Stream metricMetadataArgs() { // if metric name ends with unit the unit is omitted - order matters Arguments.of( createSampleMetricData("metric_total_hertz", "hertz_total", MetricDataType.LONG_SUM), - "metric_total_hertz_hertz_total counter", - "metric_total_hertz_hertz_total description", - "metric_total_hertz_hertz_total"), + "metric_total_hertz_total counter", + "metric_total_hertz_total description", + "metric_total_hertz_total"), // metric name cannot start with a number Arguments.of( createSampleMetricData("2_metric_name", "By", MetricDataType.SUMMARY), From 0f99d70d982231783e86211f2054882ca95db631 Mon Sep 17 00:00:00 2001 From: jack-berg <34418638+jack-berg@users.noreply.github.com> Date: Wed, 29 May 2024 16:02:39 -0500 Subject: [PATCH 420/901] Remove android animalsniffer check from prometheus exporter (#6478) --- exporters/prometheus/build.gradle.kts | 2 -- 1 file changed, 2 deletions(-) diff --git a/exporters/prometheus/build.gradle.kts b/exporters/prometheus/build.gradle.kts index a1da9e7e243..b0e9809ebcc 100644 --- a/exporters/prometheus/build.gradle.kts +++ b/exporters/prometheus/build.gradle.kts @@ -1,8 +1,6 @@ plugins { id("otel.java-conventions") id("otel.publish-conventions") - - id("otel.animalsniffer-conventions") } description = "OpenTelemetry Prometheus Exporter" From 7da7037717a1bfcb730a77792e8059d11cf8e7af Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20St=C3=A4ber?= Date: Wed, 29 May 2024 23:41:53 +0200 Subject: [PATCH 421/901] Make /metrics the only Prometheus metrics endpoint (#6476) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Fabian Stäber Co-authored-by: Jack Berg --- .../prometheus/PrometheusHttpServer.java | 7 +-- .../PrometheusHttpServerBuilder.java | 22 ++++++++- .../prometheus/PrometheusHttpServerTest.java | 46 ++++++++++++++++++- 3 files changed, 69 insertions(+), 6 deletions(-) diff --git a/exporters/prometheus/src/main/java/io/opentelemetry/exporter/prometheus/PrometheusHttpServer.java b/exporters/prometheus/src/main/java/io/opentelemetry/exporter/prometheus/PrometheusHttpServer.java index ed5f1f7c1b1..0a306fccaa3 100644 --- a/exporters/prometheus/src/main/java/io/opentelemetry/exporter/prometheus/PrometheusHttpServer.java +++ b/exporters/prometheus/src/main/java/io/opentelemetry/exporter/prometheus/PrometheusHttpServer.java @@ -10,6 +10,7 @@ package io.opentelemetry.exporter.prometheus; +import com.sun.net.httpserver.HttpHandler; import io.opentelemetry.sdk.common.CompletableResultCode; import io.opentelemetry.sdk.common.export.MemoryMode; import io.opentelemetry.sdk.internal.DaemonThreadFactory; @@ -18,7 +19,6 @@ import io.opentelemetry.sdk.metrics.export.CollectionRegistration; import io.opentelemetry.sdk.metrics.export.MetricReader; import io.prometheus.metrics.exporter.httpserver.HTTPServer; -import io.prometheus.metrics.exporter.httpserver.MetricsHandler; import io.prometheus.metrics.model.registry.PrometheusRegistry; import java.io.IOException; import java.io.UncheckedIOException; @@ -64,7 +64,8 @@ public static PrometheusHttpServerBuilder builder() { PrometheusRegistry prometheusRegistry, boolean otelScopeEnabled, @Nullable Predicate allowedResourceAttributesFilter, - MemoryMode memoryMode) { + MemoryMode memoryMode, + @Nullable HttpHandler defaultHandler) { this.builder = builder; this.prometheusMetricReader = new PrometheusMetricReader(otelScopeEnabled, allowedResourceAttributesFilter); @@ -86,7 +87,7 @@ public static PrometheusHttpServerBuilder builder() { .port(port) .executorService(executor) .registry(prometheusRegistry) - .defaultHandler(new MetricsHandler(prometheusRegistry)) + .defaultHandler(defaultHandler) .buildAndStart(); } catch (IOException e) { throw new UncheckedIOException("Could not create Prometheus HTTP server", e); diff --git a/exporters/prometheus/src/main/java/io/opentelemetry/exporter/prometheus/PrometheusHttpServerBuilder.java b/exporters/prometheus/src/main/java/io/opentelemetry/exporter/prometheus/PrometheusHttpServerBuilder.java index 2be7dee6215..20f36fdf426 100644 --- a/exporters/prometheus/src/main/java/io/opentelemetry/exporter/prometheus/PrometheusHttpServerBuilder.java +++ b/exporters/prometheus/src/main/java/io/opentelemetry/exporter/prometheus/PrometheusHttpServerBuilder.java @@ -8,6 +8,7 @@ import static io.opentelemetry.api.internal.Utils.checkArgument; import static java.util.Objects.requireNonNull; +import com.sun.net.httpserver.HttpHandler; import io.opentelemetry.sdk.common.export.MemoryMode; import io.prometheus.metrics.model.registry.PrometheusRegistry; import java.util.concurrent.ExecutorService; @@ -29,6 +30,7 @@ public final class PrometheusHttpServerBuilder { @Nullable private Predicate allowedResourceAttributesFilter; @Nullable private ExecutorService executor; private MemoryMode memoryMode = DEFAULT_MEMORY_MODE; + @Nullable private HttpHandler defaultHandler; PrometheusHttpServerBuilder() {} @@ -107,6 +109,23 @@ public PrometheusHttpServerBuilder setMemoryMode(MemoryMode memoryMode) { return this; } + /** + * Override the default handler for serving the "/", "/**" endpoint. + * + *

      This can be used to serve metrics on additional paths besides the default "/metrics". For + * example: + * PrometheusHttpServer.builder() + * .setPrometheusRegistry(prometheusRegistry) + * .setDefaultHandler(new MetricsHandler(prometheusRegistry)) + * .build() + * + */ + public PrometheusHttpServerBuilder setDefaultHandler(HttpHandler defaultHandler) { + requireNonNull(defaultHandler, "defaultHandler"); + this.defaultHandler = defaultHandler; + return this; + } + /** * Returns a new {@link PrometheusHttpServer} with the configuration of this builder which can be * registered with a {@link io.opentelemetry.sdk.metrics.SdkMeterProvider}. @@ -120,6 +139,7 @@ public PrometheusHttpServer build() { prometheusRegistry, otelScopeEnabled, allowedResourceAttributesFilter, - memoryMode); + memoryMode, + defaultHandler); } } diff --git a/exporters/prometheus/src/test/java/io/opentelemetry/exporter/prometheus/PrometheusHttpServerTest.java b/exporters/prometheus/src/test/java/io/opentelemetry/exporter/prometheus/PrometheusHttpServerTest.java index 449cc4c5c4c..9b328493c1f 100644 --- a/exporters/prometheus/src/test/java/io/opentelemetry/exporter/prometheus/PrometheusHttpServerTest.java +++ b/exporters/prometheus/src/test/java/io/opentelemetry/exporter/prometheus/PrometheusHttpServerTest.java @@ -35,6 +35,7 @@ import io.opentelemetry.sdk.metrics.internal.data.ImmutableSumData; import io.opentelemetry.sdk.resources.Resource; import io.prometheus.metrics.exporter.httpserver.HTTPServer; +import io.prometheus.metrics.exporter.httpserver.MetricsHandler; import io.prometheus.metrics.model.registry.PrometheusRegistry; import java.io.ByteArrayInputStream; import java.io.IOException; @@ -229,7 +230,7 @@ void fetchOpenMetrics() { void fetchFiltered() { AggregatedHttpResponse response = client - .get("/?name[]=grpc_name_unit_total&name[]=bears_total&name[]=target_info") + .get("/metrics?name[]=grpc_name_unit_total&name[]=bears_total&name[]=target_info") .aggregate() .join(); assertThat(response.status()).isEqualTo(HttpStatus.OK); @@ -245,6 +246,47 @@ void fetchFiltered() { + "target_info{kr=\"vr\"} 1\n"); } + @Test + void fetchOverrideDefaultHandler() { + PrometheusRegistry registry = new PrometheusRegistry(); + try (PrometheusHttpServer prometheusServer = + PrometheusHttpServer.builder() + .setHost("localhost") + .setPort(0) + .setPrometheusRegistry(registry) + // Set the default handler to serve metrics on /** + .setDefaultHandler(new MetricsHandler(registry)) + .build()) { + prometheusServer.register( + new CollectionRegistration() { + @Override + public Collection collectAllMetrics() { + return metricData.get(); + } + }); + WebClient client = + WebClient.builder("http://localhost:" + prometheusServer.getAddress().getPort()) + .decorator(RetryingClient.newDecorator(RetryRule.failsafe())) + .build(); + + // Fetch metrics from / instead of /metrics + AggregatedHttpResponse response = client.get("/").aggregate().join(); + assertThat(response.status()).isEqualTo(HttpStatus.OK); + assertThat(response.headers().get(HttpHeaderNames.CONTENT_TYPE)) + .isEqualTo("text/plain; version=0.0.4; charset=utf-8"); + assertThat(response.contentUtf8()) + .isEqualTo( + "# HELP grpc_name_unit_total long_description\n" + + "# TYPE grpc_name_unit_total counter\n" + + "grpc_name_unit_total{kp=\"vp\",otel_scope_name=\"grpc\",otel_scope_version=\"version\"} 5.0\n" + + "# HELP http_name_unit_total double_description\n" + + "# TYPE http_name_unit_total counter\n" + + "http_name_unit_total{kp=\"vp\",otel_scope_name=\"http\",otel_scope_version=\"version\"} 3.5\n" + + "# TYPE target_info gauge\n" + + "target_info{kr=\"vr\"} 1\n"); + } + } + @SuppressWarnings("resource") @Test void fetchPrometheusCompressed() throws IOException { @@ -275,7 +317,7 @@ void fetchPrometheusCompressed() throws IOException { @SuppressWarnings("resource") @Test void fetchHead() { - AggregatedHttpResponse response = client.head("/").aggregate().join(); + AggregatedHttpResponse response = client.head("/metrics").aggregate().join(); assertThat(response.status()).isEqualTo(HttpStatus.OK); assertThat(response.headers().get(HttpHeaderNames.CONTENT_TYPE)) .isEqualTo("text/plain; version=0.0.4; charset=utf-8"); From f57906131ea85bae5ff1cbb87e398355a5c5020a Mon Sep 17 00:00:00 2001 From: jack-berg <34418638+jack-berg@users.noreply.github.com> Date: Thu, 30 May 2024 09:02:54 -0500 Subject: [PATCH 422/901] Make OTLP exporter memory mode API public (#6469) --- .../opentelemetry-exporter-otlp.txt | 19 +++- .../OtlpHttpLogRecordExporterBuilder.java | 9 +- .../OtlpHttpMetricExporterBuilder.java | 16 +++- .../trace/OtlpHttpSpanExporterBuilder.java | 9 +- .../otlp/internal/OtlpConfigUtil.java | 91 ++----------------- .../OtlpLogRecordExporterProvider.java | 13 +-- .../internal/OtlpMetricExporterProvider.java | 13 +-- .../internal/OtlpSpanExporterProvider.java | 14 +-- .../OtlpGrpcLogRecordExporterBuilder.java | 9 +- .../exporter/otlp/logs/OtlpGrpcLogUtil.java | 19 ---- .../OtlpGrpcMetricExporterBuilder.java | 16 +++- .../otlp/metrics/OtlpGrpcMetricUtil.java | 19 ---- .../trace/OtlpGrpcSpanExporterBuilder.java | 9 +- .../exporter/otlp/trace/OtlpGrpcSpanUtil.java | 19 ---- .../otlp/internal/OtlpConfigUtilTest.java | 1 + .../OtlpExporterIntegrationTest.java | 81 ++++++++++++++--- 16 files changed, 164 insertions(+), 193 deletions(-) delete mode 100644 exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/logs/OtlpGrpcLogUtil.java delete mode 100644 exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/metrics/OtlpGrpcMetricUtil.java delete mode 100644 exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/trace/OtlpGrpcSpanUtil.java diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-otlp.txt b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-otlp.txt index df26146497b..35bb9f3e97e 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-otlp.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-otlp.txt @@ -1,2 +1,19 @@ Comparing source compatibility of against -No changes. \ No newline at end of file +*** MODIFIED CLASS: PUBLIC FINAL io.opentelemetry.exporter.otlp.http.logs.OtlpHttpLogRecordExporterBuilder (not serializable) + === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 + *** MODIFIED METHOD: PUBLIC (<- PACKAGE_PROTECTED) io.opentelemetry.exporter.otlp.http.logs.OtlpHttpLogRecordExporterBuilder setMemoryMode(io.opentelemetry.sdk.common.export.MemoryMode) +*** MODIFIED CLASS: PUBLIC FINAL io.opentelemetry.exporter.otlp.http.metrics.OtlpHttpMetricExporterBuilder (not serializable) + === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 + *** MODIFIED METHOD: PUBLIC (<- PACKAGE_PROTECTED) io.opentelemetry.exporter.otlp.http.metrics.OtlpHttpMetricExporterBuilder setMemoryMode(io.opentelemetry.sdk.common.export.MemoryMode) +*** MODIFIED CLASS: PUBLIC FINAL io.opentelemetry.exporter.otlp.http.trace.OtlpHttpSpanExporterBuilder (not serializable) + === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 + *** MODIFIED METHOD: PUBLIC (<- PACKAGE_PROTECTED) io.opentelemetry.exporter.otlp.http.trace.OtlpHttpSpanExporterBuilder setMemoryMode(io.opentelemetry.sdk.common.export.MemoryMode) +*** MODIFIED CLASS: PUBLIC FINAL io.opentelemetry.exporter.otlp.logs.OtlpGrpcLogRecordExporterBuilder (not serializable) + === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 + *** MODIFIED METHOD: PUBLIC (<- PACKAGE_PROTECTED) io.opentelemetry.exporter.otlp.logs.OtlpGrpcLogRecordExporterBuilder setMemoryMode(io.opentelemetry.sdk.common.export.MemoryMode) +*** MODIFIED CLASS: PUBLIC FINAL io.opentelemetry.exporter.otlp.metrics.OtlpGrpcMetricExporterBuilder (not serializable) + === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 + *** MODIFIED METHOD: PUBLIC (<- PACKAGE_PROTECTED) io.opentelemetry.exporter.otlp.metrics.OtlpGrpcMetricExporterBuilder setMemoryMode(io.opentelemetry.sdk.common.export.MemoryMode) +*** MODIFIED CLASS: PUBLIC FINAL io.opentelemetry.exporter.otlp.trace.OtlpGrpcSpanExporterBuilder (not serializable) + === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 + *** MODIFIED METHOD: PUBLIC (<- PACKAGE_PROTECTED) io.opentelemetry.exporter.otlp.trace.OtlpGrpcSpanExporterBuilder setMemoryMode(io.opentelemetry.sdk.common.export.MemoryMode) diff --git a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/logs/OtlpHttpLogRecordExporterBuilder.java b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/logs/OtlpHttpLogRecordExporterBuilder.java index 619914f26e3..a2db5890439 100644 --- a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/logs/OtlpHttpLogRecordExporterBuilder.java +++ b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/logs/OtlpHttpLogRecordExporterBuilder.java @@ -210,8 +210,13 @@ public OtlpHttpLogRecordExporterBuilder setMeterProvider( return this; } - /** Set the {@link MemoryMode}. */ - OtlpHttpLogRecordExporterBuilder setMemoryMode(MemoryMode memoryMode) { + /** + * Set the {@link MemoryMode}. If unset, defaults to {@link #DEFAULT_MEMORY_MODE}. + * + *

      >When memory mode is {@link MemoryMode#REUSABLE_DATA}, serialization is optimized to reduce + * memory allocation. + */ + public OtlpHttpLogRecordExporterBuilder setMemoryMode(MemoryMode memoryMode) { requireNonNull(memoryMode, "memoryMode"); this.memoryMode = memoryMode; return this; diff --git a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/metrics/OtlpHttpMetricExporterBuilder.java b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/metrics/OtlpHttpMetricExporterBuilder.java index e3b23aa77e0..7046f65ebb1 100644 --- a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/metrics/OtlpHttpMetricExporterBuilder.java +++ b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/metrics/OtlpHttpMetricExporterBuilder.java @@ -19,10 +19,12 @@ import io.opentelemetry.sdk.common.export.ProxyOptions; import io.opentelemetry.sdk.common.export.RetryPolicy; import io.opentelemetry.sdk.metrics.InstrumentType; +import io.opentelemetry.sdk.metrics.data.MetricData; import io.opentelemetry.sdk.metrics.export.AggregationTemporalitySelector; import io.opentelemetry.sdk.metrics.export.DefaultAggregationSelector; import io.opentelemetry.sdk.metrics.export.MetricExporter; import java.time.Duration; +import java.util.Collection; import java.util.Map; import java.util.concurrent.TimeUnit; import java.util.function.Supplier; @@ -231,8 +233,18 @@ public OtlpHttpMetricExporterBuilder setProxyOptions(ProxyOptions proxyOptions) return this; } - /** Set the {@link MemoryMode}. */ - OtlpHttpMetricExporterBuilder setMemoryMode(MemoryMode memoryMode) { + /** + * Set the {@link MemoryMode}. If unset, defaults to {@link #DEFAULT_MEMORY_MODE}. + * + *

      >When memory mode is {@link MemoryMode#REUSABLE_DATA}, serialization is optimized to reduce + * memory allocation. Additionally, the value is used for {@link MetricExporter#getMemoryMode()}, + * which sends a signal to the metrics SDK to reuse memory when possible. This is safe and + * desirable for most use cases, but should be used with caution of wrapping and delegating to the + * exporter. It is not safe for the wrapping exporter to hold onto references to {@link + * MetricData} batches since the same data structures will be reused in subsequent calls to {@link + * MetricExporter#export(Collection)}. + */ + public OtlpHttpMetricExporterBuilder setMemoryMode(MemoryMode memoryMode) { requireNonNull(memoryMode, "memoryMode"); this.memoryMode = memoryMode; return this; diff --git a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/trace/OtlpHttpSpanExporterBuilder.java b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/trace/OtlpHttpSpanExporterBuilder.java index 1c735001ebf..db54626fc70 100644 --- a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/trace/OtlpHttpSpanExporterBuilder.java +++ b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/trace/OtlpHttpSpanExporterBuilder.java @@ -211,8 +211,13 @@ public OtlpHttpSpanExporterBuilder setMeterProvider( return this; } - /** Set the {@link MemoryMode}. */ - OtlpHttpSpanExporterBuilder setMemoryMode(MemoryMode memoryMode) { + /** + * Set the {@link MemoryMode}. If unset, defaults to {@link #DEFAULT_MEMORY_MODE}. + * + *

      >When memory mode is {@link MemoryMode#REUSABLE_DATA}, serialization is optimized to reduce + * memory allocation. + */ + public OtlpHttpSpanExporterBuilder setMemoryMode(MemoryMode memoryMode) { requireNonNull(memoryMode, "memoryMode"); this.memoryMode = memoryMode; return this; diff --git a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/OtlpConfigUtil.java b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/OtlpConfigUtil.java index c06d5f1f60e..2b387d06367 100644 --- a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/OtlpConfigUtil.java +++ b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/OtlpConfigUtil.java @@ -7,12 +7,7 @@ import static io.opentelemetry.sdk.metrics.Aggregation.explicitBucketHistogram; -import io.opentelemetry.exporter.otlp.http.logs.OtlpHttpLogRecordExporterBuilder; -import io.opentelemetry.exporter.otlp.http.metrics.OtlpHttpMetricExporterBuilder; -import io.opentelemetry.exporter.otlp.http.trace.OtlpHttpSpanExporterBuilder; -import io.opentelemetry.exporter.otlp.logs.OtlpGrpcLogRecordExporterBuilder; -import io.opentelemetry.exporter.otlp.metrics.OtlpGrpcMetricExporterBuilder; -import io.opentelemetry.exporter.otlp.trace.OtlpGrpcSpanExporterBuilder; +import io.opentelemetry.exporter.internal.ExporterBuilderUtil; import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties; import io.opentelemetry.sdk.autoconfigure.spi.ConfigurationException; import io.opentelemetry.sdk.common.export.MemoryMode; @@ -26,8 +21,6 @@ import java.io.File; import java.io.IOException; import java.io.RandomAccessFile; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; import java.net.MalformedURLException; import java.net.URL; import java.net.URLDecoder; @@ -62,6 +55,7 @@ public static String getOtlpProtocol(String dataType, ConfigProperties config) { } /** Invoke the setters with the OTLP configuration for the {@code dataType}. */ + @SuppressWarnings("TooManyParameters") public static void configureOtlpExporterBuilder( String dataType, ConfigProperties config, @@ -71,7 +65,8 @@ public static void configureOtlpExporterBuilder( Consumer setTimeout, Consumer setTrustedCertificates, BiConsumer setClientTls, - Consumer setRetryPolicy) { + Consumer setRetryPolicy, + Consumer setMemoryMode) { String protocol = getOtlpProtocol(dataType, config); boolean isHttpProtobuf = protocol.equals(PROTOCOL_HTTP_PROTOBUF); URL endpoint = @@ -161,6 +156,8 @@ public static void configureOtlpExporterBuilder( if (retryEnabled) { setRetryPolicy.accept(RetryPolicy.getDefault()); } + + ExporterBuilderUtil.configureExporterMemoryMode(config, setMemoryMode); } /** @@ -215,82 +212,6 @@ public static void configureOtlpHistogramDefaultAggregation( } } - /** - * Calls {@code #setMemoryMode} on the {@code Otlp{Protocol}{Signal}ExporterBuilder} with the - * {@code memoryMode}. - */ - public static void setMemoryModeOnOtlpExporterBuilder(Object builder, MemoryMode memoryMode) { - try { - // Metrics - if (builder instanceof OtlpGrpcMetricExporterBuilder) { - // Calling getDeclaredMethod causes all private methods to be read, which causes a - // ClassNotFoundException when running with the OkHttHttpProvider as the private - // setManagedChanel(io.grpc.ManagedChannel) is reached and io.grpc.ManagedChannel is not on - // the classpath. io.opentelemetry.exporter.otlp.metrics.OtlpGrpcMetricUtil provides a layer - // of indirection which avoids scanning the OtlpGrpcMetricExporterBuilder private methods. - Class otlpGrpcMetricUtil = - Class.forName("io.opentelemetry.exporter.otlp.metrics.OtlpGrpcMetricUtil"); - Method method = - otlpGrpcMetricUtil.getDeclaredMethod( - "setMemoryMode", OtlpGrpcMetricExporterBuilder.class, MemoryMode.class); - method.setAccessible(true); - method.invoke(null, builder, memoryMode); - } else if (builder instanceof OtlpHttpMetricExporterBuilder) { - Method method = - OtlpHttpMetricExporterBuilder.class.getDeclaredMethod( - "setMemoryMode", MemoryMode.class); - method.setAccessible(true); - method.invoke(builder, memoryMode); - } else if (builder instanceof OtlpGrpcSpanExporterBuilder) { - // Calling getDeclaredMethod causes all private methods to be read, which causes a - // ClassNotFoundException when running with the OkHttHttpProvider as the private - // setManagedChanel(io.grpc.ManagedChannel) is reached and io.grpc.ManagedChannel is not on - // the classpath. io.opentelemetry.exporter.otlp.trace.OtlpGrpcSpanUtil provides a layer - // of indirection which avoids scanning the OtlpGrpcSpanExporterBuilder private methods. - Class otlpGrpcMetricUtil = - Class.forName("io.opentelemetry.exporter.otlp.trace.OtlpGrpcSpanUtil"); - Method method = - otlpGrpcMetricUtil.getDeclaredMethod( - "setMemoryMode", OtlpGrpcSpanExporterBuilder.class, MemoryMode.class); - method.setAccessible(true); - method.invoke(null, builder, memoryMode); - } else if (builder instanceof OtlpHttpSpanExporterBuilder) { - Method method = - OtlpHttpSpanExporterBuilder.class.getDeclaredMethod("setMemoryMode", MemoryMode.class); - method.setAccessible(true); - method.invoke(builder, memoryMode); - } else if (builder instanceof OtlpGrpcLogRecordExporterBuilder) { - // Calling getDeclaredMethod causes all private methods to be read, which causes a - // ClassNotFoundException when running with the OkHttHttpProvider as the private - // setManagedChanel(io.grpc.ManagedChannel) is reached and io.grpc.ManagedChannel is not on - // the classpath. io.opentelemetry.exporter.otlp.logs.OtlpGrpcLogUtil provides a layer - // of indirection which avoids scanning the OtlpGrpcLogRecordExporterBuilder private - // methods. - Class otlpGrpcMetricUtil = - Class.forName("io.opentelemetry.exporter.otlp.logs.OtlpGrpcLogUtil"); - Method method = - otlpGrpcMetricUtil.getDeclaredMethod( - "setMemoryMode", OtlpGrpcLogRecordExporterBuilder.class, MemoryMode.class); - method.setAccessible(true); - method.invoke(null, builder, memoryMode); - } else if (builder instanceof OtlpHttpLogRecordExporterBuilder) { - Method method = - OtlpHttpLogRecordExporterBuilder.class.getDeclaredMethod( - "setMemoryMode", MemoryMode.class); - method.setAccessible(true); - method.invoke(builder, memoryMode); - } else { - throw new IllegalArgumentException( - "Cannot set memory mode. Unrecognized OTLP exporter builder"); - } - } catch (NoSuchMethodException - | InvocationTargetException - | IllegalAccessException - | ClassNotFoundException e) { - throw new IllegalStateException("Error calling setMemoryMode.", e); - } - } - private static URL createUrl(URL context, String spec) { try { return new URL(context, spec); diff --git a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/OtlpLogRecordExporterProvider.java b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/OtlpLogRecordExporterProvider.java index 04cf661b58b..67ed44c754a 100644 --- a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/OtlpLogRecordExporterProvider.java +++ b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/OtlpLogRecordExporterProvider.java @@ -10,7 +10,6 @@ import static io.opentelemetry.exporter.otlp.internal.OtlpConfigUtil.PROTOCOL_HTTP_PROTOBUF; import io.opentelemetry.api.metrics.MeterProvider; -import io.opentelemetry.exporter.internal.ExporterBuilderUtil; import io.opentelemetry.exporter.otlp.http.logs.OtlpHttpLogRecordExporter; import io.opentelemetry.exporter.otlp.http.logs.OtlpHttpLogRecordExporterBuilder; import io.opentelemetry.exporter.otlp.logs.OtlpGrpcLogRecordExporter; @@ -52,11 +51,9 @@ public LogRecordExporter createExporter(ConfigProperties config) { builder::setTimeout, builder::setTrustedCertificates, builder::setClientTls, - builder::setRetryPolicy); + builder::setRetryPolicy, + builder::setMemoryMode); builder.setMeterProvider(meterProviderRef::get); - ExporterBuilderUtil.configureExporterMemoryMode( - config, - memoryMode -> OtlpConfigUtil.setMemoryModeOnOtlpExporterBuilder(builder, memoryMode)); return builder.build(); } else if (protocol.equals(PROTOCOL_GRPC)) { @@ -71,11 +68,9 @@ public LogRecordExporter createExporter(ConfigProperties config) { builder::setTimeout, builder::setTrustedCertificates, builder::setClientTls, - builder::setRetryPolicy); + builder::setRetryPolicy, + builder::setMemoryMode); builder.setMeterProvider(meterProviderRef::get); - ExporterBuilderUtil.configureExporterMemoryMode( - config, - memoryMode -> OtlpConfigUtil.setMemoryModeOnOtlpExporterBuilder(builder, memoryMode)); return builder.build(); } diff --git a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/OtlpMetricExporterProvider.java b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/OtlpMetricExporterProvider.java index 490f4044bea..8103e9426cf 100644 --- a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/OtlpMetricExporterProvider.java +++ b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/OtlpMetricExporterProvider.java @@ -9,7 +9,6 @@ import static io.opentelemetry.exporter.otlp.internal.OtlpConfigUtil.PROTOCOL_GRPC; import static io.opentelemetry.exporter.otlp.internal.OtlpConfigUtil.PROTOCOL_HTTP_PROTOBUF; -import io.opentelemetry.exporter.internal.ExporterBuilderUtil; import io.opentelemetry.exporter.otlp.http.metrics.OtlpHttpMetricExporter; import io.opentelemetry.exporter.otlp.http.metrics.OtlpHttpMetricExporterBuilder; import io.opentelemetry.exporter.otlp.metrics.OtlpGrpcMetricExporter; @@ -44,14 +43,12 @@ public MetricExporter createExporter(ConfigProperties config) { builder::setTimeout, builder::setTrustedCertificates, builder::setClientTls, - builder::setRetryPolicy); + builder::setRetryPolicy, + builder::setMemoryMode); OtlpConfigUtil.configureOtlpAggregationTemporality( config, builder::setAggregationTemporalitySelector); OtlpConfigUtil.configureOtlpHistogramDefaultAggregation( config, builder::setDefaultAggregationSelector); - ExporterBuilderUtil.configureExporterMemoryMode( - config, - memoryMode -> OtlpConfigUtil.setMemoryModeOnOtlpExporterBuilder(builder, memoryMode)); return builder.build(); } else if (protocol.equals(PROTOCOL_GRPC)) { @@ -66,14 +63,12 @@ public MetricExporter createExporter(ConfigProperties config) { builder::setTimeout, builder::setTrustedCertificates, builder::setClientTls, - builder::setRetryPolicy); + builder::setRetryPolicy, + builder::setMemoryMode); OtlpConfigUtil.configureOtlpAggregationTemporality( config, builder::setAggregationTemporalitySelector); OtlpConfigUtil.configureOtlpHistogramDefaultAggregation( config, builder::setDefaultAggregationSelector); - ExporterBuilderUtil.configureExporterMemoryMode( - config, - memoryMode -> OtlpConfigUtil.setMemoryModeOnOtlpExporterBuilder(builder, memoryMode)); return builder.build(); } diff --git a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/OtlpSpanExporterProvider.java b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/OtlpSpanExporterProvider.java index bdf9633a441..e6fad237d85 100644 --- a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/OtlpSpanExporterProvider.java +++ b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/OtlpSpanExporterProvider.java @@ -10,7 +10,6 @@ import static io.opentelemetry.exporter.otlp.internal.OtlpConfigUtil.PROTOCOL_HTTP_PROTOBUF; import io.opentelemetry.api.metrics.MeterProvider; -import io.opentelemetry.exporter.internal.ExporterBuilderUtil; import io.opentelemetry.exporter.otlp.http.trace.OtlpHttpSpanExporter; import io.opentelemetry.exporter.otlp.http.trace.OtlpHttpSpanExporterBuilder; import io.opentelemetry.exporter.otlp.trace.OtlpGrpcSpanExporter; @@ -51,11 +50,10 @@ public SpanExporter createExporter(ConfigProperties config) { builder::setTimeout, builder::setTrustedCertificates, builder::setClientTls, - builder::setRetryPolicy); + builder::setRetryPolicy, + builder::setMemoryMode); builder.setMeterProvider(meterProviderRef::get); - ExporterBuilderUtil.configureExporterMemoryMode( - config, - memoryMode -> OtlpConfigUtil.setMemoryModeOnOtlpExporterBuilder(builder, memoryMode)); + return builder.build(); } else if (protocol.equals(PROTOCOL_GRPC)) { OtlpGrpcSpanExporterBuilder builder = grpcBuilder(); @@ -69,11 +67,9 @@ public SpanExporter createExporter(ConfigProperties config) { builder::setTimeout, builder::setTrustedCertificates, builder::setClientTls, - builder::setRetryPolicy); + builder::setRetryPolicy, + builder::setMemoryMode); builder.setMeterProvider(meterProviderRef::get); - ExporterBuilderUtil.configureExporterMemoryMode( - config, - memoryMode -> OtlpConfigUtil.setMemoryModeOnOtlpExporterBuilder(builder, memoryMode)); return builder.build(); } diff --git a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/logs/OtlpGrpcLogRecordExporterBuilder.java b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/logs/OtlpGrpcLogRecordExporterBuilder.java index 58cfc8e3c61..3131ae16ff0 100644 --- a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/logs/OtlpGrpcLogRecordExporterBuilder.java +++ b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/logs/OtlpGrpcLogRecordExporterBuilder.java @@ -243,8 +243,13 @@ public OtlpGrpcLogRecordExporterBuilder setMeterProvider( return this; } - /** Set the {@link MemoryMode}. */ - OtlpGrpcLogRecordExporterBuilder setMemoryMode(MemoryMode memoryMode) { + /** + * Set the {@link MemoryMode}. If unset, defaults to {@link #DEFAULT_MEMORY_MODE}. + * + *

      >When memory mode is {@link MemoryMode#REUSABLE_DATA}, serialization is optimized to reduce + * memory allocation. + */ + public OtlpGrpcLogRecordExporterBuilder setMemoryMode(MemoryMode memoryMode) { requireNonNull(memoryMode, "memoryMode"); this.memoryMode = memoryMode; return this; diff --git a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/logs/OtlpGrpcLogUtil.java b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/logs/OtlpGrpcLogUtil.java deleted file mode 100644 index 1602514e8d5..00000000000 --- a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/logs/OtlpGrpcLogUtil.java +++ /dev/null @@ -1,19 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package io.opentelemetry.exporter.otlp.logs; - -import io.opentelemetry.exporter.otlp.internal.OtlpConfigUtil; -import io.opentelemetry.sdk.common.export.MemoryMode; - -final class OtlpGrpcLogUtil { - - private OtlpGrpcLogUtil() {} - - /** See {@link OtlpConfigUtil#setMemoryModeOnOtlpExporterBuilder(Object, MemoryMode)}. */ - static void setMemoryMode(OtlpGrpcLogRecordExporterBuilder builder, MemoryMode memoryMode) { - builder.setMemoryMode(memoryMode); - } -} diff --git a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/metrics/OtlpGrpcMetricExporterBuilder.java b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/metrics/OtlpGrpcMetricExporterBuilder.java index 343e2a5dd9b..34887f7f267 100644 --- a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/metrics/OtlpGrpcMetricExporterBuilder.java +++ b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/metrics/OtlpGrpcMetricExporterBuilder.java @@ -19,11 +19,13 @@ import io.opentelemetry.sdk.common.export.MemoryMode; import io.opentelemetry.sdk.common.export.RetryPolicy; import io.opentelemetry.sdk.metrics.InstrumentType; +import io.opentelemetry.sdk.metrics.data.MetricData; import io.opentelemetry.sdk.metrics.export.AggregationTemporalitySelector; import io.opentelemetry.sdk.metrics.export.DefaultAggregationSelector; import io.opentelemetry.sdk.metrics.export.MetricExporter; import java.net.URI; import java.time.Duration; +import java.util.Collection; import java.util.Map; import java.util.concurrent.TimeUnit; import java.util.function.Supplier; @@ -264,8 +266,18 @@ public OtlpGrpcMetricExporterBuilder setRetryPolicy(RetryPolicy retryPolicy) { return this; } - /** Set the {@link MemoryMode}. */ - OtlpGrpcMetricExporterBuilder setMemoryMode(MemoryMode memoryMode) { + /** + * Set the {@link MemoryMode}. If unset, defaults to {@link #DEFAULT_MEMORY_MODE}. + * + *

      >When memory mode is {@link MemoryMode#REUSABLE_DATA}, serialization is optimized to reduce + * memory allocation. Additionally, the value is used for {@link MetricExporter#getMemoryMode()}, + * which sends a signal to the metrics SDK to reuse memory when possible. This is safe and + * desirable for most use cases, but should be used with caution of wrapping and delegating to the + * exporter. It is not safe for the wrapping exporter to hold onto references to {@link + * MetricData} batches since the same data structures will be reused in subsequent calls to {@link + * MetricExporter#export(Collection)}. + */ + public OtlpGrpcMetricExporterBuilder setMemoryMode(MemoryMode memoryMode) { requireNonNull(memoryMode, "memoryMode"); this.memoryMode = memoryMode; return this; diff --git a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/metrics/OtlpGrpcMetricUtil.java b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/metrics/OtlpGrpcMetricUtil.java deleted file mode 100644 index 7d4080b87ef..00000000000 --- a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/metrics/OtlpGrpcMetricUtil.java +++ /dev/null @@ -1,19 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package io.opentelemetry.exporter.otlp.metrics; - -import io.opentelemetry.exporter.otlp.internal.OtlpConfigUtil; -import io.opentelemetry.sdk.common.export.MemoryMode; - -final class OtlpGrpcMetricUtil { - - private OtlpGrpcMetricUtil() {} - - /** See {@link OtlpConfigUtil#setMemoryModeOnOtlpExporterBuilder(Object, MemoryMode)}. */ - static void setMemoryMode(OtlpGrpcMetricExporterBuilder builder, MemoryMode memoryMode) { - builder.setMemoryMode(memoryMode); - } -} diff --git a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/trace/OtlpGrpcSpanExporterBuilder.java b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/trace/OtlpGrpcSpanExporterBuilder.java index 20ad734da43..004c61021ad 100644 --- a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/trace/OtlpGrpcSpanExporterBuilder.java +++ b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/trace/OtlpGrpcSpanExporterBuilder.java @@ -240,8 +240,13 @@ public OtlpGrpcSpanExporterBuilder setMeterProvider( return this; } - /** Set the {@link MemoryMode}. */ - OtlpGrpcSpanExporterBuilder setMemoryMode(MemoryMode memoryMode) { + /** + * Set the {@link MemoryMode}. If unset, defaults to {@link #DEFAULT_MEMORY_MODE}. + * + *

      >When memory mode is {@link MemoryMode#REUSABLE_DATA}, serialization is optimized to reduce + * memory allocation. + */ + public OtlpGrpcSpanExporterBuilder setMemoryMode(MemoryMode memoryMode) { requireNonNull(memoryMode, "memoryMode"); this.memoryMode = memoryMode; return this; diff --git a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/trace/OtlpGrpcSpanUtil.java b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/trace/OtlpGrpcSpanUtil.java deleted file mode 100644 index 25955ffa265..00000000000 --- a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/trace/OtlpGrpcSpanUtil.java +++ /dev/null @@ -1,19 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package io.opentelemetry.exporter.otlp.trace; - -import io.opentelemetry.exporter.otlp.internal.OtlpConfigUtil; -import io.opentelemetry.sdk.common.export.MemoryMode; - -final class OtlpGrpcSpanUtil { - - private OtlpGrpcSpanUtil() {} - - /** See {@link OtlpConfigUtil#setMemoryModeOnOtlpExporterBuilder(Object, MemoryMode)}. */ - static void setMemoryMode(OtlpGrpcSpanExporterBuilder builder, MemoryMode memoryMode) { - builder.setMemoryMode(memoryMode); - } -} diff --git a/exporters/otlp/all/src/test/java/io/opentelemetry/exporter/otlp/internal/OtlpConfigUtilTest.java b/exporters/otlp/all/src/test/java/io/opentelemetry/exporter/otlp/internal/OtlpConfigUtilTest.java index b3b896018ba..5c678670519 100644 --- a/exporters/otlp/all/src/test/java/io/opentelemetry/exporter/otlp/internal/OtlpConfigUtilTest.java +++ b/exporters/otlp/all/src/test/java/io/opentelemetry/exporter/otlp/internal/OtlpConfigUtilTest.java @@ -325,6 +325,7 @@ private static String configureEndpoint(String dataType, Map pro value -> {}, value -> {}, (value1, value2) -> {}, + value -> {}, value -> {}); return endpoint.get(); diff --git a/integration-tests/otlp/src/main/java/io/opentelemetry/integrationtest/OtlpExporterIntegrationTest.java b/integration-tests/otlp/src/main/java/io/opentelemetry/integrationtest/OtlpExporterIntegrationTest.java index 5310162ec60..e90c9efe28f 100644 --- a/integration-tests/otlp/src/main/java/io/opentelemetry/integrationtest/OtlpExporterIntegrationTest.java +++ b/integration-tests/otlp/src/main/java/io/opentelemetry/integrationtest/OtlpExporterIntegrationTest.java @@ -38,12 +38,9 @@ import io.opentelemetry.context.Scope; import io.opentelemetry.exporter.otlp.http.logs.OtlpHttpLogRecordExporter; import io.opentelemetry.exporter.otlp.http.metrics.OtlpHttpMetricExporter; -import io.opentelemetry.exporter.otlp.http.metrics.OtlpHttpMetricExporterBuilder; import io.opentelemetry.exporter.otlp.http.trace.OtlpHttpSpanExporter; -import io.opentelemetry.exporter.otlp.internal.OtlpConfigUtil; import io.opentelemetry.exporter.otlp.logs.OtlpGrpcLogRecordExporter; import io.opentelemetry.exporter.otlp.metrics.OtlpGrpcMetricExporter; -import io.opentelemetry.exporter.otlp.metrics.OtlpGrpcMetricExporterBuilder; import io.opentelemetry.exporter.otlp.trace.OtlpGrpcSpanExporter; import io.opentelemetry.proto.collector.logs.v1.ExportLogsServiceRequest; import io.opentelemetry.proto.collector.logs.v1.ExportLogsServiceResponse; @@ -213,6 +210,22 @@ void testOtlpGrpcTraceExport(String compression) { testTraceExport(exporter); } + @ParameterizedTest + @EnumSource(MemoryMode.class) + void testOtlpGrpcTraceExport_memoryMode(MemoryMode memoryMode) { + SpanExporter exporter = + OtlpGrpcSpanExporter.builder() + .setEndpoint( + "http://" + + collector.getHost() + + ":" + + collector.getMappedPort(COLLECTOR_OTLP_GRPC_PORT)) + .setMemoryMode(memoryMode) + .build(); + + testTraceExport(exporter); + } + @Test void testOtlpGrpcTraceExport_mtls() throws Exception { SpanExporter exporter = @@ -246,6 +259,23 @@ void testOtlpHttpTraceExport(String compression) { testTraceExport(exporter); } + @ParameterizedTest + @EnumSource(MemoryMode.class) + void testOtlpHttpTraceExport_memoryMode(MemoryMode memoryMode) { + SpanExporter exporter = + OtlpHttpSpanExporter.builder() + .setEndpoint( + "http://" + + collector.getHost() + + ":" + + collector.getMappedPort(COLLECTOR_OTLP_HTTP_PORT) + + "/v1/traces") + .setMemoryMode(memoryMode) + .build(); + + testTraceExport(exporter); + } + @Test void testOtlpHttpTraceExport_mtls() throws Exception { SpanExporter exporter = @@ -349,16 +379,14 @@ void testOtlpGrpcMetricExport(String compression) { @ParameterizedTest @EnumSource(MemoryMode.class) void testOtlpGrpcMetricExport_memoryMode(MemoryMode memoryMode) { - OtlpGrpcMetricExporterBuilder builder = OtlpGrpcMetricExporter.builder(); - OtlpConfigUtil.setMemoryModeOnOtlpExporterBuilder(builder, memoryMode); - MetricExporter exporter = - builder + OtlpGrpcMetricExporter.builder() .setEndpoint( "http://" + collector.getHost() + ":" + collector.getMappedPort(COLLECTOR_OTLP_GRPC_PORT)) + .setMemoryMode(memoryMode) .build(); assertThat(exporter.getMemoryMode()).isEqualTo(memoryMode); @@ -402,17 +430,15 @@ void testOtlpHttpMetricExport(String compression) { @ParameterizedTest @EnumSource(MemoryMode.class) void testOtlpHttpMetricExport_memoryMode(MemoryMode memoryMode) { - OtlpHttpMetricExporterBuilder builder = OtlpHttpMetricExporter.builder(); - OtlpConfigUtil.setMemoryModeOnOtlpExporterBuilder(builder, memoryMode); - MetricExporter exporter = - builder + OtlpHttpMetricExporter.builder() .setEndpoint( "http://" + collector.getHost() + ":" + collector.getMappedPort(COLLECTOR_OTLP_HTTP_PORT) + "/v1/metrics") + .setMemoryMode(memoryMode) .build(); assertThat(exporter.getMemoryMode()).isEqualTo(memoryMode); @@ -516,6 +542,22 @@ void testOtlpGrpcLogExport(String compression) { testLogRecordExporter(otlpGrpcLogRecordExporter); } + @ParameterizedTest + @EnumSource(MemoryMode.class) + void testOtlpGrpcLogExport_memoryMode(MemoryMode memoryMode) { + LogRecordExporter otlpGrpcLogRecordExporter = + OtlpGrpcLogRecordExporter.builder() + .setEndpoint( + "http://" + + collector.getHost() + + ":" + + collector.getMappedPort(COLLECTOR_OTLP_GRPC_PORT)) + .setMemoryMode(memoryMode) + .build(); + + testLogRecordExporter(otlpGrpcLogRecordExporter); + } + @Test void testOtlpGrpcLogExport_mtls() throws Exception { LogRecordExporter exporter = @@ -549,6 +591,23 @@ void testOtlpHttpLogExport(String compression) { testLogRecordExporter(otlpHttpLogRecordExporter); } + @ParameterizedTest + @EnumSource(MemoryMode.class) + void testOtlpHttpLogExport_memoryMode(MemoryMode memoryMode) { + LogRecordExporter otlpHttpLogRecordExporter = + OtlpHttpLogRecordExporter.builder() + .setEndpoint( + "http://" + + collector.getHost() + + ":" + + collector.getMappedPort(COLLECTOR_OTLP_HTTP_PORT) + + "/v1/logs") + .setMemoryMode(memoryMode) + .build(); + + testLogRecordExporter(otlpHttpLogRecordExporter); + } + @Test void testOtlpHttpLogExport_mtls() throws Exception { LogRecordExporter exporter = From 788347e262b34ccf287a5b32a9976eb43e170c5f Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 30 May 2024 11:24:03 -0700 Subject: [PATCH 423/901] Update dependency org.jctools:jctools-core to v4.0.4 (#6481) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- dependencyManagement/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index 7849fd34d7f..660e9010c75 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -76,7 +76,7 @@ val DEPENDENCIES = listOf( "org.awaitility:awaitility:4.2.1", "org.bouncycastle:bcpkix-jdk15on:1.70", "org.codehaus.mojo:animal-sniffer-annotations:1.23", - "org.jctools:jctools-core:4.0.3", + "org.jctools:jctools-core:4.0.4", "org.junit-pioneer:junit-pioneer:1.9.1", "org.mock-server:mockserver-netty:5.15.0:shaded", "org.skyscreamer:jsonassert:1.5.1", From 809457d2b0b10b1983f9f0066ad1e1d8fce17af3 Mon Sep 17 00:00:00 2001 From: Jonathan Halliday Date: Mon, 3 Jun 2024 16:02:43 +0100 Subject: [PATCH 424/901] Add exporter data classes for experimental profiling signal type. (#6374) --- exporters/otlp/profiles/build.gradle.kts | 13 +++ exporters/otlp/profiles/gradle.properties | 1 + .../otlp/profiles/AggregationTemporality.java | 39 ++++++++ .../otlp/profiles/AttributeUnitData.java | 23 +++++ .../exporter/otlp/profiles/BuildIdKind.java | 20 ++++ .../exporter/otlp/profiles/FunctionData.java | 32 +++++++ .../exporter/otlp/profiles/LabelData.java | 33 +++++++ .../exporter/otlp/profiles/LineData.java | 26 ++++++ .../exporter/otlp/profiles/LinkData.java | 26 ++++++ .../exporter/otlp/profiles/LocationData.java | 45 +++++++++ .../exporter/otlp/profiles/MappingData.java | 54 +++++++++++ .../otlp/profiles/ProfileContainerData.java | 92 +++++++++++++++++++ .../exporter/otlp/profiles/ProfileData.java | 87 ++++++++++++++++++ .../exporter/otlp/profiles/SampleData.java | 55 +++++++++++ .../exporter/otlp/profiles/ValueTypeData.java | 27 ++++++ .../exporter/otlp/profiles/package-info.java | 10 ++ settings.gradle.kts | 1 + 17 files changed, 584 insertions(+) create mode 100644 exporters/otlp/profiles/build.gradle.kts create mode 100644 exporters/otlp/profiles/gradle.properties create mode 100644 exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/AggregationTemporality.java create mode 100644 exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/AttributeUnitData.java create mode 100644 exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/BuildIdKind.java create mode 100644 exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/FunctionData.java create mode 100644 exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/LabelData.java create mode 100644 exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/LineData.java create mode 100644 exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/LinkData.java create mode 100644 exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/LocationData.java create mode 100644 exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/MappingData.java create mode 100644 exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/ProfileContainerData.java create mode 100644 exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/ProfileData.java create mode 100644 exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/SampleData.java create mode 100644 exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/ValueTypeData.java create mode 100644 exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/package-info.java diff --git a/exporters/otlp/profiles/build.gradle.kts b/exporters/otlp/profiles/build.gradle.kts new file mode 100644 index 00000000000..8b22581662f --- /dev/null +++ b/exporters/otlp/profiles/build.gradle.kts @@ -0,0 +1,13 @@ +plugins { + id("otel.java-conventions") + id("otel.publish-conventions") + + id("otel.animalsniffer-conventions") +} + +description = "OpenTelemetry - Profiles Exporter" +otelJava.moduleName.set("io.opentelemetry.exporter.otlp.profiles") + +dependencies { + api(project(":sdk:common")) +} diff --git a/exporters/otlp/profiles/gradle.properties b/exporters/otlp/profiles/gradle.properties new file mode 100644 index 00000000000..4476ae57e31 --- /dev/null +++ b/exporters/otlp/profiles/gradle.properties @@ -0,0 +1 @@ +otel.release=alpha diff --git a/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/AggregationTemporality.java b/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/AggregationTemporality.java new file mode 100644 index 00000000000..4586a4652b1 --- /dev/null +++ b/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/AggregationTemporality.java @@ -0,0 +1,39 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.exporter.otlp.profiles; + +/** + * Specifies the method of aggregating metric values. + * + *

      TODO: This is intentionally not the same as metrics/AggregationTemporality. For profiles.proto + * 'v1experimental' version, this class is considered distinct from the pre-exiting + * AggregationTemporality in metrics.proto. As the profiles.proto stabilises, they may be refactored + * into a version in common.proto. Meanwhile the Java class structure reflects the .proto structure + * in making distinct entities. + * + *

      refs for refactoring discussion: + * + * @see + * "https://github.com/open-telemetry/opentelemetry-proto/blob/v1.3.0/opentelemetry/proto/metrics/v1/metrics.proto#L261" + * @see + * "https://github.com/open-telemetry/opentelemetry-proto/blob/v1.3.0/opentelemetry/proto/profiles/v1experimental/pprofextended.proto#L147" + * @see "https://github.com/open-telemetry/opentelemetry-proto/issues/547" + * @see "https://github.com/open-telemetry/opentelemetry-proto/pull/534#discussion_r1552403726" + * @see "profiles.proto::AggregationTemporality" + */ +public enum AggregationTemporality { + + /** + * DELTA is an AggregationTemporality for a profiler which reports changes since last report time. + */ + DELTA, + + /** + * CUMULATIVE is an AggregationTemporality for a profiler which reports changes since a fixed + * start time. + */ + CUMULATIVE +} diff --git a/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/AttributeUnitData.java b/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/AttributeUnitData.java new file mode 100644 index 00000000000..47f2403cbd4 --- /dev/null +++ b/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/AttributeUnitData.java @@ -0,0 +1,23 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.exporter.otlp.profiles; + +import javax.annotation.concurrent.Immutable; + +/** + * Represents a mapping between Attribute Keys and Units. + * + * @see "pprofextended.proto::AttributeUnit" + */ +@Immutable +public interface AttributeUnitData { + + /** Index into string table. */ + long getAttributeKey(); + + /** Index into string table. */ + long getUnitIndex(); +} diff --git a/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/BuildIdKind.java b/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/BuildIdKind.java new file mode 100644 index 00000000000..9852b623aed --- /dev/null +++ b/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/BuildIdKind.java @@ -0,0 +1,20 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.exporter.otlp.profiles; + +/** + * Indicates the semantics of the build_id field. + * + * @see "pprofextended.proto::BuildIdKind" + */ +public enum BuildIdKind { + + /** Linker-generated build ID, stored in the ELF binary notes. */ + LINKER, + + /** Build ID based on the content hash of the binary. */ + BINARY_HASH; +} diff --git a/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/FunctionData.java b/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/FunctionData.java new file mode 100644 index 00000000000..3f246ce4a02 --- /dev/null +++ b/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/FunctionData.java @@ -0,0 +1,32 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.exporter.otlp.profiles; + +import javax.annotation.concurrent.Immutable; + +/** + * Describes a function. + * + * @see "pprofextended.proto::Function" + */ +@Immutable +public interface FunctionData { + + /** Name of the function, in human-readable form if available. Index into string table. */ + long getNameIndex(); + + /** + * Name of the function, as identified by the system. For instance, it can be a C++ mangled name. + * Index into string table. + */ + long getSystemNameIndex(); + + /** Source file containing the function. Index into string table. */ + long getFilenameIndex(); + + /** Line number in source file. */ + long getStartLine(); +} diff --git a/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/LabelData.java b/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/LabelData.java new file mode 100644 index 00000000000..adc8787bae8 --- /dev/null +++ b/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/LabelData.java @@ -0,0 +1,33 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.exporter.otlp.profiles; + +import javax.annotation.concurrent.Immutable; + +/** + * Provides additional context for a sample, such as thread ID or allocation size, with optional + * units. + * + * @see "pprofextended.proto::Label" + */ +@Immutable +public interface LabelData { + + /** Index into string table. */ + long getKeyIndex(); + + /** String value of the label data, if applicable. Index into string table */ + long getStrIndex(); + + /** Numeric value of the label data, if applicable. */ + long getNum(); + + /** + * Specifies the units of num, applicable only if num is present. Use arbitrary string (for + * example, "requests") as a custom count unit. + */ + long getNumUnitIndex(); +} diff --git a/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/LineData.java b/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/LineData.java new file mode 100644 index 00000000000..b19e53cfa1e --- /dev/null +++ b/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/LineData.java @@ -0,0 +1,26 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.exporter.otlp.profiles; + +import javax.annotation.concurrent.Immutable; + +/** + * Details a specific line in a source code, linked to a function. + * + * @see "pprofextended.proto::Line" + */ +@Immutable +public interface LineData { + + /** The index of the corresponding Function for this line. Index into function table. */ + long getFunctionIndex(); + + /** Line number in source code. */ + long getLine(); + + /** Column number in source code. */ + long getColumn(); +} diff --git a/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/LinkData.java b/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/LinkData.java new file mode 100644 index 00000000000..dd76c9283b2 --- /dev/null +++ b/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/LinkData.java @@ -0,0 +1,26 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.exporter.otlp.profiles; + +import javax.annotation.concurrent.Immutable; + +/** + * A connection from a profile Sample to a trace Span. + * + * @see "pprofextended.proto::Link" + */ +@Immutable +public interface LinkData { + + /** + * Returns a unique identifier of a trace that this linked span is part of as 32 character + * lowercase hex String. + */ + String getTraceId(); + + /** Returns a unique identifier for the linked span, as 16 character lowercase hex String. */ + String getSpanId(); +} diff --git a/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/LocationData.java b/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/LocationData.java new file mode 100644 index 00000000000..d22ba65c55d --- /dev/null +++ b/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/LocationData.java @@ -0,0 +1,45 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.exporter.otlp.profiles; + +import java.util.List; +import javax.annotation.concurrent.Immutable; + +/** + * Describes a function. + * + * @see "pprofextended.proto::Location" + */ +@Immutable +public interface LocationData { + + /** + * The index of the corresponding profile.Mapping for this location. It can be unset if the + * mapping is unknown or not applicable for this profile type. + */ + long getMappingIndex(); + + /** The instruction address for this location, if available. */ + long getAddress(); + + /** + * Multiple line indicates this location has inlined functions, where the last entry represents + * the caller into which the preceding entries were inlined. + */ + List getLines(); + + /** + * Provides an indication that multiple symbols map to this location's address, for example due to + * identical code folding by the linker. + */ + boolean isFolded(); + + /** Type of frame (e.g. kernel, native, python, hotspot, php). Index into string table. */ + int getTypeIndex(); + + /** References to attributes in Profile.attribute_table. */ + List getAttributes(); +} diff --git a/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/MappingData.java b/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/MappingData.java new file mode 100644 index 00000000000..2b5e14a0c91 --- /dev/null +++ b/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/MappingData.java @@ -0,0 +1,54 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.exporter.otlp.profiles; + +import java.util.List; +import javax.annotation.concurrent.Immutable; + +/** + * Describes the mapping of a binary in memory. + * + * @see "pprofextended.proto::Mapping" + */ +@Immutable +public interface MappingData { + + /** Address at which the binary (or DLL) is loaded into memory. */ + long getMemoryStart(); + + /** The limit of the address range occupied by this mapping. */ + long getMemoryLimit(); + + /** Offset in the binary that corresponds to the first mapped address. */ + long getFileOffset(); + + /** + * The object this entry is loaded from. This can be a filename on disk for the main binary and + * shared libraries, or virtual abstraction like "[vdso]". Index into the string table. + */ + long getFilenameIndex(); + + /** + * Uniquely identifies a particular program version with high probability. e.g., for binaries + * generated by GNU tools, the contents of the .note.gnu.build-id field. Index into the string + * table. + */ + long getBuildIdIndex(); + + /** Specifies the kind of build id. See BuildIdKind enum for more details */ + BuildIdKind getBuildIdKind(); + + /** References to attributes in Profile.attribute_table. */ + List getAttributeIndices(); + + boolean hasFunctions(); + + boolean hasFilenames(); + + boolean hasLineNumbers(); + + boolean hasInlineFrames(); +} diff --git a/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/ProfileContainerData.java b/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/ProfileContainerData.java new file mode 100644 index 00000000000..f7e16f1ba0d --- /dev/null +++ b/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/ProfileContainerData.java @@ -0,0 +1,92 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.exporter.otlp.profiles; + +import io.opentelemetry.api.common.Attributes; +import io.opentelemetry.api.internal.OtelEncodingUtils; +import io.opentelemetry.sdk.common.InstrumentationScopeInfo; +import io.opentelemetry.sdk.resources.Resource; +import java.nio.ByteBuffer; +import javax.annotation.Nullable; +import javax.annotation.concurrent.Immutable; + +/** + * A ProfileContainer represents a single profile. It wraps pprof profile with OpenTelemetry + * specific metadata. + * + * @see "profiles.proto::ProfileContainer" + */ +@Immutable +public interface ProfileContainerData { + + /** Returns the resource of this profile. */ + Resource getResource(); + + /** Returns the instrumentation scope that generated this profile. */ + InstrumentationScopeInfo getInstrumentationScopeInfo(); + + /** + * Returns a globally unique identifier for a profile, as 32 character lowercase hex String. An ID + * with all zeroes is considered invalid. This field is required. + */ + String getProfileId(); + + /** + * Returns a globally unique identifier for a profile, as a 16 bytes array. An ID with all zeroes + * is considered invalid. This field is required. + */ + default byte[] getProfileIdBytes() { + return OtelEncodingUtils.bytesFromBase16(getProfileId(), 32); + } + + /** + * Returns the start time of the profile. Value is UNIX Epoch time in nanoseconds since 00:00:00 + * UTC on 1 January 1970. This field is semantically required and it is expected that end_time >= + * start_time. + */ + long getStartEpochNanos(); + + /** + * Returns the end time of the profile. Value is UNIX Epoch time in nanoseconds since 00:00:00 UTC + * on 1 January 1970. This field is semantically required and it is expected that end_time >= + * start_time. + */ + long getEndEpochNanos(); + + /** + * Returns profile-wide attributes. Attribute keys MUST be unique (it is not allowed to have more + * than one attribute with the same key). + * + * @see + * "https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/common/README.md#attribute" + */ + Attributes getAttributes(); + + /** + * Returns the total number of attributes that were recorded on this profile container. + * + *

      This number may be larger than the number of attributes that are attached to this profile + * container, if the total number recorded was greater than the configured maximum value. + */ + int getTotalAttributeCount(); + + /** + * Returns the format of the original payload. Common values are defined in semantic conventions. + * [required if original_payload is present] + */ + @Nullable + String getOriginalPayloadFormat(); + + /** + * Returns the original payload, in a profiler-native format e.g. JFR. Optional. Default behavior + * should be to not include the original payload. If the original payload is in pprof format, it + * SHOULD not be included in this field. + */ + ByteBuffer getOriginalPayload(); + + /** Returns an extended pprof profile. Required, even when originalPayload is also present. */ + ProfileData getProfile(); +} diff --git a/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/ProfileData.java b/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/ProfileData.java new file mode 100644 index 00000000000..63b26401de9 --- /dev/null +++ b/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/ProfileData.java @@ -0,0 +1,87 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.exporter.otlp.profiles; + +import io.opentelemetry.api.common.Attributes; +import java.util.List; +import javax.annotation.concurrent.Immutable; + +/** + * Represents a complete profile, including sample types, samples, mappings to binaries, locations, + * functions, string table, and additional metadata. + * + * @see "pprofextended.proto::Profile" + */ +@Immutable +public interface ProfileData { + + /** A description of the samples associated with each Sample.value. */ + List getSampleTypes(); + + /** The set of samples recorded in this profile. */ + List getSamples(); + + /** + * Mapping from address ranges to the image/binary/library mapped into that address range. + * mapping[0] will be the main binary. + */ + List getMappings(); + + /** Locations referenced by samples via location_indices. */ + List getLocations(); + + /** Array of locations referenced by samples. */ + List getLocationIndices(); + + /** Functions referenced by locations. */ + List getFunctions(); + + /** Lookup table for attributes. */ + Attributes getAttributes(); + + /** Represents a mapping between Attribute Keys and Units. */ + List getAttributeUnits(); + + /** Lookup table for links. */ + List getLinks(); + + /** + * A common table for strings referenced by various messages. string_table[0] must always be "". + */ + List getStringTable(); + + /** + * Frames with Function.function_name fully matching the following regexp will be dropped from the + * samples, along with their successors. Index into string table. + */ + long getDropFrames(); + + /** + * Frames with Function.function_name fully matching the following regexp will be kept, even if + * matching drop_frames pattern. Index into string table. + */ + long getKeepFrames(); + + /** Time of collection (UTC) represented as nanoseconds past the epoch. */ + long getTimeNanos(); + + /** Duration of the profile, if a duration makes sense. */ + long getDurationNanos(); + + /** + * The kind of events between sampled occurrences. e.g [ "cpu","cycles" ] or [ "heap","bytes" ] + */ + ValueTypeData getPeriodType(); + + /** The number of events between sampled occurrences. */ + long getPeriod(); + + /** Free-form text associated with the profile. Indices into string table. */ + List getComment(); + + /** Type of the preferred sample. Index into the string table. */ + long getDefaultSampleType(); +} diff --git a/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/SampleData.java b/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/SampleData.java new file mode 100644 index 00000000000..f5671511421 --- /dev/null +++ b/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/SampleData.java @@ -0,0 +1,55 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.exporter.otlp.profiles; + +import java.util.List; +import javax.annotation.concurrent.Immutable; + +/** + * Each Sample records values encountered in some program context. The program context is typically + * a stack trace, perhaps augmented with auxiliary information like the thread-id, some indicator of + * a higher level request being handled etc. + * + * @see "pprofextended.proto::Sample" + */ +@Immutable +public interface SampleData { + + /** + * locationsStartIndex along with locationsLength refers to a slice of locations in + * Profile.location. Supersedes locationIndices. + */ + long getLocationsStartIndex(); + + /** + * locationsLength along with locationsStartIndex refers to a slice of locations in + * Profile.location. locationIndices. + */ + long getLocationsLength(); + + /** + * reference to a 128bit id that uniquely identifies this stacktrace, globally. Index into the + * string table. + */ + int getStacktraceIdIndex(); + + /** + * The type and unit of each value is defined by the corresponding entry in Profile.sample_type. + */ + List getValues(); + + /** References to attributes in Profile.attribute_table. */ + List getAttributes(); + + /** Reference to link in Profile.link_table. */ + long getLink(); + + /** + * Timestamps associated with Sample represented in ms. These timestamps are expected to fall + * within the Profile's time range. + */ + List getTimestamps(); +} diff --git a/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/ValueTypeData.java b/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/ValueTypeData.java new file mode 100644 index 00000000000..22c18787b32 --- /dev/null +++ b/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/ValueTypeData.java @@ -0,0 +1,27 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.exporter.otlp.profiles; + +import javax.annotation.Nullable; +import javax.annotation.concurrent.Immutable; + +/** + * ValueType describes the type and units of a value, with an optional aggregation temporality. + * + * @see "pprofextended.proto::ValueType" + */ +@Immutable +public interface ValueTypeData { + + /** Index into string table. */ + long type(); + + /** Index into string table. */ + long unit(); + + @Nullable + AggregationTemporality aggregationTemporality(); +} diff --git a/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/package-info.java b/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/package-info.java new file mode 100644 index 00000000000..ec0107701b5 --- /dev/null +++ b/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/package-info.java @@ -0,0 +1,10 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +/** The data format to model profiles for export. */ +@ParametersAreNonnullByDefault +package io.opentelemetry.exporter.otlp.profiles; + +import javax.annotation.ParametersAreNonnullByDefault; diff --git a/settings.gradle.kts b/settings.gradle.kts index a5d95eb9bf7..3fc709b740d 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -39,6 +39,7 @@ include(":exporters:logging") include(":exporters:logging-otlp") include(":exporters:otlp:all") include(":exporters:otlp:common") +include(":exporters:otlp:profiles") include(":exporters:otlp:testing-internal") include(":exporters:prometheus") include(":exporters:zipkin") From d9cef81e298f93b2379aa87d96edacf834fd7fcc Mon Sep 17 00:00:00 2001 From: jack-berg <34418638+jack-berg@users.noreply.github.com> Date: Mon, 3 Jun 2024 12:49:41 -0500 Subject: [PATCH 425/901] Define dedicated file configuration SPI ComponentProvider (#6457) --- .../internal/PrometheusComponentProvider.java | 47 +++ ...toconfigure.spi.internal.ComponentProvider | 1 + .../spi/internal/ComponentProvider.java | 45 +++ .../internal/StructuredConfigProperties.java | 187 ++++++++++++ .../AutoConfiguredOpenTelemetrySdk.java | 27 +- ...AutoConfiguredOpenTelemetrySdkBuilder.java | 19 +- .../internal/AutoConfigureUtil.java | 28 +- .../autoconfigure/FileConfigurationTest.java | 31 +- .../incubator/fileconfig/FileConfigUtil.java | 56 ++++ .../fileconfig/FileConfiguration.java | 19 ++ .../fileconfig/MetricReaderFactory.java | 38 +-- .../YamlStructuredConfigProperties.java | 280 ++++++++++++++++++ .../fileconfig/MetricReaderFactoryTest.java | 27 +- .../YamlStructuredConfigPropertiesTest.java | 200 +++++++++++++ 14 files changed, 939 insertions(+), 66 deletions(-) create mode 100644 exporters/prometheus/src/main/java/io/opentelemetry/exporter/prometheus/internal/PrometheusComponentProvider.java create mode 100644 exporters/prometheus/src/main/resources/META-INF/services/io.opentelemetry.sdk.autoconfigure.spi.internal.ComponentProvider create mode 100644 sdk-extensions/autoconfigure-spi/src/main/java/io/opentelemetry/sdk/autoconfigure/spi/internal/ComponentProvider.java create mode 100644 sdk-extensions/autoconfigure-spi/src/main/java/io/opentelemetry/sdk/autoconfigure/spi/internal/StructuredConfigProperties.java create mode 100644 sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/YamlStructuredConfigProperties.java create mode 100644 sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/YamlStructuredConfigPropertiesTest.java diff --git a/exporters/prometheus/src/main/java/io/opentelemetry/exporter/prometheus/internal/PrometheusComponentProvider.java b/exporters/prometheus/src/main/java/io/opentelemetry/exporter/prometheus/internal/PrometheusComponentProvider.java new file mode 100644 index 00000000000..dc57d2bcbe3 --- /dev/null +++ b/exporters/prometheus/src/main/java/io/opentelemetry/exporter/prometheus/internal/PrometheusComponentProvider.java @@ -0,0 +1,47 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.exporter.prometheus.internal; + +import io.opentelemetry.exporter.prometheus.PrometheusHttpServer; +import io.opentelemetry.exporter.prometheus.PrometheusHttpServerBuilder; +import io.opentelemetry.sdk.autoconfigure.spi.internal.ComponentProvider; +import io.opentelemetry.sdk.autoconfigure.spi.internal.StructuredConfigProperties; +import io.opentelemetry.sdk.metrics.export.MetricReader; + +/** + * File configuration SPI implementation for {@link PrometheusHttpServer}. + * + *

      This class is internal and is hence not for public use. Its APIs are unstable and can change + * at any time. + */ +public class PrometheusComponentProvider implements ComponentProvider { + + @Override + public Class getType() { + return MetricReader.class; + } + + @Override + public String getName() { + return "prometheus"; + } + + @Override + public MetricReader create(StructuredConfigProperties config) { + PrometheusHttpServerBuilder prometheusBuilder = PrometheusHttpServer.builder(); + + Integer port = config.getInt("port"); + if (port != null) { + prometheusBuilder.setPort(port); + } + String host = config.getString("host"); + if (host != null) { + prometheusBuilder.setHost(host); + } + + return prometheusBuilder.build(); + } +} diff --git a/exporters/prometheus/src/main/resources/META-INF/services/io.opentelemetry.sdk.autoconfigure.spi.internal.ComponentProvider b/exporters/prometheus/src/main/resources/META-INF/services/io.opentelemetry.sdk.autoconfigure.spi.internal.ComponentProvider new file mode 100644 index 00000000000..f3c72966e4b --- /dev/null +++ b/exporters/prometheus/src/main/resources/META-INF/services/io.opentelemetry.sdk.autoconfigure.spi.internal.ComponentProvider @@ -0,0 +1 @@ +io.opentelemetry.exporter.prometheus.internal.PrometheusComponentProvider diff --git a/sdk-extensions/autoconfigure-spi/src/main/java/io/opentelemetry/sdk/autoconfigure/spi/internal/ComponentProvider.java b/sdk-extensions/autoconfigure-spi/src/main/java/io/opentelemetry/sdk/autoconfigure/spi/internal/ComponentProvider.java new file mode 100644 index 00000000000..344dc18267c --- /dev/null +++ b/sdk-extensions/autoconfigure-spi/src/main/java/io/opentelemetry/sdk/autoconfigure/spi/internal/ComponentProvider.java @@ -0,0 +1,45 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.sdk.autoconfigure.spi.internal; + +import io.opentelemetry.sdk.trace.export.SpanExporter; + +/** + * Provides configured instances of SDK extension components. {@link ComponentProvider} allows SDK + * extension components which are not part of the core SDK to be referenced in file based + * configuration. + * + * @param the type of the SDK extension component. See {@link #getType()}. + */ +// TODO (jack-berg): list the specific types which are supported in file configuration +public interface ComponentProvider { + + /** + * The type of SDK extension component. For example, if providing instances of a custom span + * exporter, the type would be {@link SpanExporter}. + */ + Class getType(); + + /** + * The name of the exporter, to be referenced in configuration files. For example, if providing + * instances of a custom span exporter for the "acme" protocol, the name might be "acme". + * + *

      This name MUST not be the same as any other component provider name which returns components + * of the same {@link #getType() type}. + */ + String getName(); + + /** + * Configure an instance of the SDK extension component according to the {@code config}. + * + * @param config the configuration provided where the component is referenced in a configuration + * file. + * @return an instance the SDK extension component + */ + // TODO (jack-berg): consider dynamic configuration use case before stabilizing in case that + // affects any API decisions + T create(StructuredConfigProperties config); +} diff --git a/sdk-extensions/autoconfigure-spi/src/main/java/io/opentelemetry/sdk/autoconfigure/spi/internal/StructuredConfigProperties.java b/sdk-extensions/autoconfigure-spi/src/main/java/io/opentelemetry/sdk/autoconfigure/spi/internal/StructuredConfigProperties.java new file mode 100644 index 00000000000..ad1e3b5de3c --- /dev/null +++ b/sdk-extensions/autoconfigure-spi/src/main/java/io/opentelemetry/sdk/autoconfigure/spi/internal/StructuredConfigProperties.java @@ -0,0 +1,187 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.sdk.autoconfigure.spi.internal; + +import static io.opentelemetry.api.internal.ConfigUtil.defaultIfNull; + +import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties; +import io.opentelemetry.sdk.autoconfigure.spi.ConfigurationException; +import java.util.List; +import java.util.Set; +import javax.annotation.Nullable; + +/** + * An interface for accessing structured configuration data. + * + *

      An instance of {@link StructuredConfigProperties} is equivalent to a YAML mapping node. It has accessors for + * reading scalar properties, {@link #getStructured(String)} for reading children which are + * themselves mappings, and {@link #getStructuredList(String)} for reading children which are + * sequences of mappings. + */ +public interface StructuredConfigProperties { + + /** + * Returns a {@link String} configuration property. + * + * @return null if the property has not been configured + * @throws ConfigurationException if the property is not a valid scalar string + */ + @Nullable + String getString(String name); + + /** + * Returns a {@link String} configuration property. + * + * @return a {@link String} configuration property or {@code defaultValue} if a property with + * {@code name} has not been configured + * @throws ConfigurationException if the property is not a valid scalar string + */ + default String getString(String name, String defaultValue) { + return defaultIfNull(getString(name), defaultValue); + } + + /** + * Returns a {@link Boolean} configuration property. Implementations should use the same rules as + * {@link Boolean#parseBoolean(String)} for handling the values. + * + * @return null if the property has not been configured + * @throws ConfigurationException if the property is not a valid scalar boolean + */ + @Nullable + Boolean getBoolean(String name); + + /** + * Returns a {@link Boolean} configuration property. + * + * @return a {@link Boolean} configuration property or {@code defaultValue} if a property with + * {@code name} has not been configured + * @throws ConfigurationException if the property is not a valid scalar boolean + */ + default boolean getBoolean(String name, boolean defaultValue) { + return defaultIfNull(getBoolean(name), defaultValue); + } + + /** + * Returns a {@link Integer} configuration property. + * + *

      If the underlying config property is {@link Long}, it is converted to {@link Integer} with + * {@link Long#intValue()} which may result in loss of precision. + * + * @return null if the property has not been configured + * @throws ConfigurationException if the property is not a valid scalar integer + */ + @Nullable + Integer getInt(String name); + + /** + * Returns a {@link Integer} configuration property. + * + *

      If the underlying config property is {@link Long}, it is converted to {@link Integer} with + * {@link Long#intValue()} which may result in loss of precision. + * + * @return a {@link Integer} configuration property or {@code defaultValue} if a property with + * {@code name} has not been configured + * @throws ConfigurationException if the property is not a valid scalar integer + */ + default int getInt(String name, int defaultValue) { + return defaultIfNull(getInt(name), defaultValue); + } + + /** + * Returns a {@link Long} configuration property. + * + * @return null if the property has not been configured + * @throws ConfigurationException if the property is not a valid scalar long + */ + @Nullable + Long getLong(String name); + + /** + * Returns a {@link Long} configuration property. + * + * @return a {@link Long} configuration property or {@code defaultValue} if a property with {@code + * name} has not been configured + * @throws ConfigurationException if the property is not a valid scalar long + */ + default long getLong(String name, long defaultValue) { + return defaultIfNull(getLong(name), defaultValue); + } + + /** + * Returns a {@link Double} configuration property. + * + * @return null if the property has not been configured + * @throws ConfigurationException if the property is not a valid scalar double + */ + @Nullable + Double getDouble(String name); + + /** + * Returns a {@link Double} configuration property. + * + * @return a {@link Double} configuration property or {@code defaultValue} if a property with + * {@code name} has not been configured + * @throws ConfigurationException if the property is not a valid scalar double + */ + default double getDouble(String name, double defaultValue) { + return defaultIfNull(getDouble(name), defaultValue); + } + + /** + * Returns a {@link List} configuration property. Empty values and values which do not map to the + * {@code scalarType} will be removed. + * + * @param name the property name + * @param scalarType the scalar type, one of {@link String}, {@link Boolean}, {@link Long} or + * {@link Double} + * @return a {@link List} configuration property, or null if the property has not been configured + * @throws ConfigurationException if the property is not a valid sequence of scalars, or if {@code + * scalarType} is not supported + */ + @Nullable + List getScalarList(String name, Class scalarType); + + /** + * Returns a {@link List} configuration property. Entries which are not strings are converted to + * their string representation. + * + * @see ConfigProperties#getList(String name) + * @return a {@link List} configuration property or {@code defaultValue} if a property with {@code + * name} has not been configured + * @throws ConfigurationException if the property is not a valid sequence of scalars + */ + default List getScalarList(String name, Class scalarType, List defaultValue) { + return defaultIfNull(getScalarList(name, scalarType), defaultValue); + } + + /** + * Returns a {@link StructuredConfigProperties} configuration property. + * + * @return a map-valued configuration property, or {@code null} if {@code name} has not been + * configured + * @throws ConfigurationException if the property is not a mapping + */ + @Nullable + StructuredConfigProperties getStructured(String name); + + /** + * Returns a list of {@link StructuredConfigProperties} configuration property. + * + * @return a list of map-valued configuration property, or {@code null} if {@code name} has not + * been configured + * @throws ConfigurationException if the property is not a sequence of mappings + */ + @Nullable + List getStructuredList(String name); + + /** + * Returns a set of all configuration property keys. + * + * @return the configuration property keys + */ + Set getPropertyKeys(); +} diff --git a/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/AutoConfiguredOpenTelemetrySdk.java b/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/AutoConfiguredOpenTelemetrySdk.java index 997df49062c..6751da7ad7f 100644 --- a/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/AutoConfiguredOpenTelemetrySdk.java +++ b/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/AutoConfiguredOpenTelemetrySdk.java @@ -10,7 +10,9 @@ import io.opentelemetry.api.OpenTelemetry; import io.opentelemetry.sdk.OpenTelemetrySdk; import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties; +import io.opentelemetry.sdk.autoconfigure.spi.internal.StructuredConfigProperties; import io.opentelemetry.sdk.resources.Resource; +import javax.annotation.Nullable; import javax.annotation.concurrent.Immutable; /** @@ -43,8 +45,12 @@ public static AutoConfiguredOpenTelemetrySdkBuilder builder() { } static AutoConfiguredOpenTelemetrySdk create( - OpenTelemetrySdk sdk, Resource resource, ConfigProperties config) { - return new AutoValue_AutoConfiguredOpenTelemetrySdk(sdk, resource, config); + OpenTelemetrySdk sdk, + Resource resource, + @Nullable ConfigProperties config, + @Nullable StructuredConfigProperties structuredConfigProperties) { + return new AutoValue_AutoConfiguredOpenTelemetrySdk( + sdk, resource, config, structuredConfigProperties); } /** @@ -60,8 +66,23 @@ static AutoConfiguredOpenTelemetrySdk create( /** Returns the {@link Resource} that was auto-configured. */ abstract Resource getResource(); - /** Returns the {@link ConfigProperties} used for auto-configuration. */ + /** + * Returns the {@link ConfigProperties} used for auto-configuration, or {@code null} if file + * configuration was used. + * + * @see #getStructuredConfig() + */ + @Nullable abstract ConfigProperties getConfig(); + /** + * Returns the {@link StructuredConfigProperties} used for auto-configuration, or {@code null} if + * file configuration was not used. + * + * @see #getConfig() + */ + @Nullable + abstract StructuredConfigProperties getStructuredConfig(); + AutoConfiguredOpenTelemetrySdk() {} } diff --git a/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/AutoConfiguredOpenTelemetrySdkBuilder.java b/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/AutoConfiguredOpenTelemetrySdkBuilder.java index 923f1535257..7fd5d515f4c 100644 --- a/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/AutoConfiguredOpenTelemetrySdkBuilder.java +++ b/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/AutoConfiguredOpenTelemetrySdkBuilder.java @@ -21,6 +21,7 @@ import io.opentelemetry.sdk.autoconfigure.spi.ConfigurationException; import io.opentelemetry.sdk.autoconfigure.spi.internal.AutoConfigureListener; import io.opentelemetry.sdk.autoconfigure.spi.internal.DefaultConfigProperties; +import io.opentelemetry.sdk.autoconfigure.spi.internal.StructuredConfigProperties; import io.opentelemetry.sdk.logs.LogRecordProcessor; import io.opentelemetry.sdk.logs.SdkLoggerProvider; import io.opentelemetry.sdk.logs.SdkLoggerProviderBuilder; @@ -505,7 +506,7 @@ public AutoConfiguredOpenTelemetrySdk build() { maybeSetAsGlobal(openTelemetrySdk); callAutoConfigureListeners(spiHelper, openTelemetrySdk); - return AutoConfiguredOpenTelemetrySdk.create(openTelemetrySdk, resource, config); + return AutoConfiguredOpenTelemetrySdk.create(openTelemetrySdk, resource, config, null); } catch (RuntimeException e) { logger.info( "Error encountered during autoconfiguration. Closing partially configured components."); @@ -546,11 +547,21 @@ private static AutoConfiguredOpenTelemetrySdk maybeConfigureFromFile(ConfigPrope try { Class configurationFactory = Class.forName("io.opentelemetry.sdk.extension.incubator.fileconfig.FileConfiguration"); - Method parseAndCreate = configurationFactory.getMethod("parseAndCreate", InputStream.class); - OpenTelemetrySdk sdk = (OpenTelemetrySdk) parseAndCreate.invoke(null, fis); + Method parse = configurationFactory.getMethod("parse", InputStream.class); + Object model = parse.invoke(null, fis); + Class openTelemetryConfiguration = + Class.forName( + "io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.OpenTelemetryConfiguration"); + Method create = configurationFactory.getMethod("create", openTelemetryConfiguration); + OpenTelemetrySdk sdk = (OpenTelemetrySdk) create.invoke(null, model); + Method toConfigProperties = + configurationFactory.getMethod("toConfigProperties", openTelemetryConfiguration); + StructuredConfigProperties structuredConfigProperties = + (StructuredConfigProperties) toConfigProperties.invoke(null, model); // Note: can't access file configuration resource without reflection so setting a dummy // resource - return AutoConfiguredOpenTelemetrySdk.create(sdk, Resource.getDefault(), config); + return AutoConfiguredOpenTelemetrySdk.create( + sdk, Resource.getDefault(), null, structuredConfigProperties); } catch (ClassNotFoundException | NoSuchMethodException | IllegalAccessException e) { throw new ConfigurationException( "Error configuring from file. Is opentelemetry-sdk-extension-incubator on the classpath?", diff --git a/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/internal/AutoConfigureUtil.java b/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/internal/AutoConfigureUtil.java index 8a50d782031..fe18ac8d41b 100644 --- a/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/internal/AutoConfigureUtil.java +++ b/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/internal/AutoConfigureUtil.java @@ -8,9 +8,11 @@ import io.opentelemetry.sdk.autoconfigure.AutoConfiguredOpenTelemetrySdk; import io.opentelemetry.sdk.autoconfigure.AutoConfiguredOpenTelemetrySdkBuilder; import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties; +import io.opentelemetry.sdk.autoconfigure.spi.internal.StructuredConfigProperties; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.function.Function; +import javax.annotation.Nullable; /** * This class is internal and is hence not for public use. Its APIs are unstable and can change at @@ -20,7 +22,12 @@ public final class AutoConfigureUtil { private AutoConfigureUtil() {} - /** Returns the {@link ConfigProperties} used for auto-configuration. */ + /** + * Returns the {@link ConfigProperties} used for auto-configuration. + * + * @return the config properties, or {@code null} if file based configuration is used + */ + @Nullable public static ConfigProperties getConfig( AutoConfiguredOpenTelemetrySdk autoConfiguredOpenTelemetrySdk) { try { @@ -33,6 +40,25 @@ public static ConfigProperties getConfig( } } + /** + * Returns the {@link StructuredConfigProperties} used for auto-configuration when file based + * configuration is used. + * + * @return the config properties, or {@code null} if file based configuration is NOT used + */ + @Nullable + public static StructuredConfigProperties getStructuredConfig( + AutoConfiguredOpenTelemetrySdk autoConfiguredOpenTelemetrySdk) { + try { + Method method = AutoConfiguredOpenTelemetrySdk.class.getDeclaredMethod("getStructuredConfig"); + method.setAccessible(true); + return (StructuredConfigProperties) method.invoke(autoConfiguredOpenTelemetrySdk); + } catch (NoSuchMethodException | InvocationTargetException | IllegalAccessException e) { + throw new IllegalStateException( + "Error calling getStructuredConfig on AutoConfiguredOpenTelemetrySdk", e); + } + } + /** Sets the {@link ComponentLoader} to be used in the auto-configuration process. */ public static AutoConfiguredOpenTelemetrySdkBuilder setComponentLoader( AutoConfiguredOpenTelemetrySdkBuilder builder, ComponentLoader componentLoader) { diff --git a/sdk-extensions/autoconfigure/src/testFullConfig/java/io/opentelemetry/sdk/autoconfigure/FileConfigurationTest.java b/sdk-extensions/autoconfigure/src/testFullConfig/java/io/opentelemetry/sdk/autoconfigure/FileConfigurationTest.java index a40884d032b..639f2955da3 100644 --- a/sdk-extensions/autoconfigure/src/testFullConfig/java/io/opentelemetry/sdk/autoconfigure/FileConfigurationTest.java +++ b/sdk-extensions/autoconfigure/src/testFullConfig/java/io/opentelemetry/sdk/autoconfigure/FileConfigurationTest.java @@ -6,7 +6,6 @@ package io.opentelemetry.sdk.autoconfigure; import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.assertThat; -import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.doReturn; @@ -29,6 +28,7 @@ import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties; import io.opentelemetry.sdk.autoconfigure.spi.ConfigurationException; import io.opentelemetry.sdk.autoconfigure.spi.internal.DefaultConfigProperties; +import io.opentelemetry.sdk.autoconfigure.spi.internal.StructuredConfigProperties; import io.opentelemetry.sdk.logs.internal.SdkEventLoggerProvider; import io.opentelemetry.sdk.resources.Resource; import io.opentelemetry.sdk.trace.SdkTracerProvider; @@ -67,7 +67,11 @@ void setup() throws IOException { + " processors:\n" + " - simple:\n" + " exporter:\n" - + " console: {}\n"; + + " console: {}\n" + + "other:\n" + + " str_key: str_value\n" + + " map_key:\n" + + " str_key1: str_value1\n"; configFilePath = tempDir.resolve("otel-config.yaml"); Files.write(configFilePath, yaml.getBytes(StandardCharsets.UTF_8)); GlobalOpenTelemetry.resetForTest(); @@ -183,4 +187,27 @@ void configFile_Error(@TempDir Path tempDir) throws IOException { .isInstanceOf(ConfigurationException.class) .hasMessage("Unrecognized span exporter(s): [foo]"); } + + @Test + void configFile_StructuredConfigProperties() { + ConfigProperties config = + DefaultConfigProperties.createFromMap( + Collections.singletonMap("otel.experimental.config.file", configFilePath.toString())); + + AutoConfiguredOpenTelemetrySdk autoConfiguredOpenTelemetrySdk = + AutoConfiguredOpenTelemetrySdk.builder().setConfig(config).setResultAsGlobal().build(); + OpenTelemetrySdk openTelemetrySdk = autoConfiguredOpenTelemetrySdk.getOpenTelemetrySdk(); + cleanup.addCloseable(openTelemetrySdk); + + // getConfig() should return ExtendedConfigProperties generic representation of the config file + StructuredConfigProperties structuredConfigProps = + autoConfiguredOpenTelemetrySdk.getStructuredConfig(); + assertThat(structuredConfigProps).isNotNull(); + StructuredConfigProperties otherProps = structuredConfigProps.getStructured("other"); + assertThat(otherProps).isNotNull(); + assertThat(otherProps.getString("str_key")).isEqualTo("str_value"); + StructuredConfigProperties otherMapKeyProps = otherProps.getStructured("map_key"); + assertThat(otherMapKeyProps).isNotNull(); + assertThat(otherMapKeyProps.getString("str_key1")).isEqualTo("str_value1"); + } } diff --git a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/FileConfigUtil.java b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/FileConfigUtil.java index f1c882a48b9..7b5bcd9ca2d 100644 --- a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/FileConfigUtil.java +++ b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/FileConfigUtil.java @@ -5,8 +5,14 @@ package io.opentelemetry.sdk.extension.incubator.fileconfig; +import io.opentelemetry.sdk.autoconfigure.internal.SpiHelper; +import io.opentelemetry.sdk.autoconfigure.spi.ConfigurationException; +import io.opentelemetry.sdk.autoconfigure.spi.internal.ComponentProvider; +import io.opentelemetry.sdk.autoconfigure.spi.internal.StructuredConfigProperties; import java.io.Closeable; import java.util.List; +import java.util.function.Function; +import java.util.stream.Collectors; import javax.annotation.Nullable; final class FileConfigUtil { @@ -27,4 +33,54 @@ static T assertNotNull(@Nullable T object, String description) { } return object; } + + /** + * Find a registered {@link ComponentProvider} which {@link ComponentProvider#getType()} matching + * {@code type}, {@link ComponentProvider#getName()} matching {@code name}, and call {@link + * ComponentProvider#create(StructuredConfigProperties)} with the given {@code model}. + * + * @throws ConfigurationException if no matching providers are found, or if multiple are found + * (i.e. conflict), or if {@link ComponentProvider#create(StructuredConfigProperties)} throws + */ + @SuppressWarnings({"unchecked", "rawtypes"}) + static T loadComponent(SpiHelper spiHelper, Class type, String name, Object model) { + // TODO(jack-berg): cache loaded component providers + List componentProviders = spiHelper.load(ComponentProvider.class); + List> matchedProviders = + componentProviders.stream() + .map( + (Function>) + componentProvider -> componentProvider) + .filter( + componentProvider -> + componentProvider.getType() == type && name.equals(componentProvider.getName())) + .collect(Collectors.toList()); + if (matchedProviders.isEmpty()) { + throw new ConfigurationException( + "No component provider detected for " + type.getName() + " with name \"" + name + "\"."); + } + if (matchedProviders.size() > 1) { + throw new ConfigurationException( + "Component provider conflict. Multiple providers detected for " + + type.getName() + + " with name \"" + + name + + "\": " + + componentProviders.stream() + .map(provider -> provider.getClass().getName()) + .collect(Collectors.joining(",", "[", "]"))); + } + // Exactly one matching component provider + ComponentProvider provider = (ComponentProvider) matchedProviders.get(0); + + // Map model to generic structured config properties + StructuredConfigProperties config = FileConfiguration.toConfigProperties(model); + + try { + return provider.create(config); + } catch (Throwable throwable) { + throw new ConfigurationException( + "Error configuring " + type.getName() + " with name \"" + name + "\"", throwable); + } + } } diff --git a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/FileConfiguration.java b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/FileConfiguration.java index 94150a04b8a..82888ed5735 100644 --- a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/FileConfiguration.java +++ b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/FileConfiguration.java @@ -7,10 +7,12 @@ import com.fasterxml.jackson.annotation.JsonSetter; import com.fasterxml.jackson.annotation.Nulls; +import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.databind.ObjectMapper; import io.opentelemetry.sdk.OpenTelemetrySdk; import io.opentelemetry.sdk.autoconfigure.internal.SpiHelper; import io.opentelemetry.sdk.autoconfigure.spi.ConfigurationException; +import io.opentelemetry.sdk.autoconfigure.spi.internal.StructuredConfigProperties; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.OpenTelemetryConfiguration; import java.io.Closeable; import java.io.IOException; @@ -138,6 +140,23 @@ static Object loadYaml(InputStream inputStream, Map environmentV return yaml.loadFromInputStream(inputStream); } + /** + * Convert the {@code model} to a generic {@link StructuredConfigProperties}, which can be used to + * read configuration not part of the model. + * + * @param model the configuration model + * @return a generic {@link StructuredConfigProperties} representation of the model + */ + public static StructuredConfigProperties toConfigProperties(OpenTelemetryConfiguration model) { + return toConfigProperties((Object) model); + } + + static StructuredConfigProperties toConfigProperties(Object model) { + Map configurationMap = + MAPPER.convertValue(model, new TypeReference>() {}); + return YamlStructuredConfigProperties.create(configurationMap); + } + /** * {@link StandardConstructor} which substitutes environment variables. * diff --git a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/MetricReaderFactory.java b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/MetricReaderFactory.java index bcaafd6c6e3..77750920cf2 100644 --- a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/MetricReaderFactory.java +++ b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/MetricReaderFactory.java @@ -5,12 +5,8 @@ package io.opentelemetry.sdk.extension.incubator.fileconfig; -import io.opentelemetry.sdk.autoconfigure.internal.NamedSpiManager; import io.opentelemetry.sdk.autoconfigure.internal.SpiHelper; -import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties; import io.opentelemetry.sdk.autoconfigure.spi.ConfigurationException; -import io.opentelemetry.sdk.autoconfigure.spi.internal.ConfigurableMetricReaderProvider; -import io.opentelemetry.sdk.autoconfigure.spi.internal.DefaultConfigProperties; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.MetricExporter; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.PeriodicMetricReader; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.Prometheus; @@ -19,9 +15,7 @@ import io.opentelemetry.sdk.metrics.export.PeriodicMetricReaderBuilder; import java.io.Closeable; import java.time.Duration; -import java.util.HashMap; import java.util.List; -import java.util.Map; import javax.annotation.Nullable; final class MetricReaderFactory @@ -77,25 +71,10 @@ public MetricReader create( } Prometheus prometheusModel = exporterModel.getPrometheus(); if (prometheusModel != null) { - // Translate from file configuration scheme to environment variable scheme. This is - // ultimately - // interpreted by PrometheusMetricReaderProvider, but we want to avoid the dependency on - // opentelemetry-exporter-prometheus - Map properties = new HashMap<>(); - if (prometheusModel.getHost() != null) { - properties.put("otel.exporter.prometheus.host", prometheusModel.getHost()); - } - if (prometheusModel.getPort() != null) { - properties.put( - "otel.exporter.prometheus.port", String.valueOf(prometheusModel.getPort())); - } - - ConfigProperties configProperties = DefaultConfigProperties.createFromMap(properties); - return FileConfigUtil.addAndReturn( - closeables, - FileConfigUtil.assertNotNull( - metricReaderSpiManager(configProperties, spiHelper).getByName("prometheus"), - "prometheus reader")); + MetricReader metricReader = + FileConfigUtil.loadComponent( + spiHelper, MetricReader.class, "prometheus", prometheusModel); + return FileConfigUtil.addAndReturn(closeables, metricReader); } throw new ConfigurationException("prometheus is the only currently supported pull reader"); @@ -103,13 +82,4 @@ public MetricReader create( return null; } - - private static NamedSpiManager - metricReaderSpiManager(ConfigProperties config, SpiHelper spiHelper) { - return spiHelper.loadConfigurable( - ConfigurableMetricReaderProvider.class, - ConfigurableMetricReaderProvider::getName, - ConfigurableMetricReaderProvider::createMetricReader, - config); - } } diff --git a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/YamlStructuredConfigProperties.java b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/YamlStructuredConfigProperties.java new file mode 100644 index 00000000000..6475bbe1698 --- /dev/null +++ b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/YamlStructuredConfigProperties.java @@ -0,0 +1,280 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.sdk.extension.incubator.fileconfig; + +import static java.util.stream.Collectors.joining; +import static java.util.stream.Collectors.toList; + +import io.opentelemetry.sdk.autoconfigure.spi.ConfigurationException; +import io.opentelemetry.sdk.autoconfigure.spi.internal.StructuredConfigProperties; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.OpenTelemetryConfiguration; +import java.util.Arrays; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.Set; +import java.util.StringJoiner; +import javax.annotation.Nullable; + +/** + * Implementation of {@link StructuredConfigProperties} which uses a file configuration model as a + * source. + * + * @see #getStructured(String) Accessing nested maps + * @see #getStructuredList(String) Accessing lists of maps + * @see FileConfiguration#toConfigProperties(Object) Converting configuration model to properties + */ +final class YamlStructuredConfigProperties implements StructuredConfigProperties { + + /** Values are {@link #isPrimitive(Object)}, {@link List} of scalars. */ + private final Map simpleEntries; + + private final Map> listEntries; + private final Map mapEntries; + + private YamlStructuredConfigProperties( + Map simpleEntries, + Map> listEntries, + Map mapEntries) { + this.simpleEntries = simpleEntries; + this.listEntries = listEntries; + this.mapEntries = mapEntries; + } + + /** + * Create a {@link YamlStructuredConfigProperties} from the {@code properties} map. + * + *

      {@code properties} is expected to be the output of YAML parsing (i.e. with Jackson {@link + * com.fasterxml.jackson.databind.ObjectMapper}), and have values which are scalars, lists of + * scalars, lists of maps, and maps. + * + * @see FileConfiguration#toConfigProperties(OpenTelemetryConfiguration) + */ + @SuppressWarnings("unchecked") + static YamlStructuredConfigProperties create(Map properties) { + Map simpleEntries = new HashMap<>(); + Map> listEntries = new HashMap<>(); + Map mapEntries = new HashMap<>(); + for (Map.Entry entry : properties.entrySet()) { + String key = entry.getKey(); + Object value = entry.getValue(); + if (isPrimitive(value)) { + simpleEntries.put(key, value); + continue; + } + if (isPrimitiveList(value)) { + simpleEntries.put(key, value); + continue; + } + if (isListOfMaps(value)) { + List list = + ((List>) value) + .stream().map(YamlStructuredConfigProperties::create).collect(toList()); + listEntries.put(key, list); + continue; + } + if (isMap(value)) { + YamlStructuredConfigProperties configProperties = + YamlStructuredConfigProperties.create((Map) value); + mapEntries.put(key, configProperties); + continue; + } + throw new ConfigurationException( + "Unable to initialize ExtendedConfigProperties. Key \"" + + key + + "\" has unrecognized object type " + + value.getClass().getName()); + } + return new YamlStructuredConfigProperties(simpleEntries, listEntries, mapEntries); + } + + private static boolean isPrimitiveList(Object object) { + if (object instanceof List) { + List list = (List) object; + return list.stream().allMatch(YamlStructuredConfigProperties::isPrimitive); + } + return false; + } + + private static boolean isPrimitive(Object object) { + return object instanceof String + || object instanceof Integer + || object instanceof Long + || object instanceof Float + || object instanceof Double + || object instanceof Boolean; + } + + private static boolean isListOfMaps(Object object) { + if (object instanceof List) { + List list = (List) object; + return list.stream() + .allMatch( + entry -> + entry instanceof Map + && ((Map) entry) + .keySet().stream().allMatch(key -> key instanceof String)); + } + return false; + } + + private static boolean isMap(Object object) { + if (object instanceof Map) { + Map map = (Map) object; + return map.keySet().stream().allMatch(entry -> entry instanceof String); + } + return false; + } + + @Nullable + @Override + public String getString(String name) { + return stringOrNull(simpleEntries.get(name)); + } + + @Nullable + @Override + public Boolean getBoolean(String name) { + return booleanOrNull(simpleEntries.get(name)); + } + + @Nullable + @Override + public Integer getInt(String name) { + Object value = simpleEntries.get(name); + if (value instanceof Integer) { + return (Integer) value; + } + if (value instanceof Long) { + return ((Long) value).intValue(); + } + return null; + } + + @Nullable + @Override + public Long getLong(String name) { + return longOrNull(simpleEntries.get(name)); + } + + @Nullable + @Override + public Double getDouble(String name) { + return doubleOrNull(simpleEntries.get(name)); + } + + private static final Set> SUPPORTED_SCALAR_TYPES = + Collections.unmodifiableSet( + new HashSet<>(Arrays.asList(String.class, Boolean.class, Long.class, Double.class))); + + @Nullable + @Override + @SuppressWarnings("unchecked") + public List getScalarList(String name, Class scalarType) { + if (!SUPPORTED_SCALAR_TYPES.contains(scalarType)) { + throw new ConfigurationException( + "Unsupported scalar type " + + scalarType.getName() + + ". Supported types include " + + SUPPORTED_SCALAR_TYPES.stream() + .map(Class::getName) + .collect(joining(",", "[", "]"))); + } + Object value = simpleEntries.get(name); + if (value instanceof List) { + return (List) + ((List) value) + .stream() + .map( + entry -> { + if (scalarType == String.class) { + return stringOrNull(entry); + } else if (scalarType == Boolean.class) { + return booleanOrNull(entry); + } else if (scalarType == Long.class) { + return longOrNull(entry); + } else if (scalarType == Double.class) { + return doubleOrNull(entry); + } + return null; + }) + .filter(Objects::nonNull) + .collect(toList()); + } + return null; + } + + @Nullable + private static String stringOrNull(@Nullable Object value) { + if (value instanceof String) { + return (String) value; + } + return null; + } + + @Nullable + private static Boolean booleanOrNull(@Nullable Object value) { + if (value instanceof Boolean) { + return (Boolean) value; + } + return null; + } + + @Nullable + private static Long longOrNull(@Nullable Object value) { + if (value instanceof Integer) { + return ((Integer) value).longValue(); + } + if (value instanceof Long) { + return (Long) value; + } + return null; + } + + @Nullable + private static Double doubleOrNull(@Nullable Object value) { + if (value instanceof Float) { + return ((Float) value).doubleValue(); + } + if (value instanceof Double) { + return (Double) value; + } + return null; + } + + @Nullable + @Override + public StructuredConfigProperties getStructured(String name) { + return mapEntries.get(name); + } + + @Nullable + @Override + public List getStructuredList(String name) { + return listEntries.get(name); + } + + @Override + public Set getPropertyKeys() { + Set keys = new HashSet<>(); + keys.addAll(simpleEntries.keySet()); + keys.addAll(listEntries.keySet()); + keys.addAll(mapEntries.keySet()); + return Collections.unmodifiableSet(keys); + } + + @Override + public String toString() { + StringJoiner joiner = new StringJoiner(", ", "YamlStructuredConfigProperties{", "}"); + simpleEntries.forEach((key, value) -> joiner.add(key + "=" + value)); + listEntries.forEach((key, value) -> joiner.add(key + "=" + value)); + mapEntries.forEach((key, value) -> joiner.add(key + "=" + value)); + return joiner.toString(); + } +} diff --git a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/MetricReaderFactoryTest.java b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/MetricReaderFactoryTest.java index 64da70549a1..3bd03e33c8d 100644 --- a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/MetricReaderFactoryTest.java +++ b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/MetricReaderFactoryTest.java @@ -6,10 +6,7 @@ package io.opentelemetry.sdk.extension.incubator.fileconfig; import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.assertThat; -import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.verify; @@ -18,9 +15,8 @@ import io.opentelemetry.exporter.prometheus.PrometheusHttpServer; import io.opentelemetry.internal.testing.CleanupExtension; import io.opentelemetry.sdk.autoconfigure.internal.SpiHelper; -import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties; import io.opentelemetry.sdk.autoconfigure.spi.ConfigurationException; -import io.opentelemetry.sdk.autoconfigure.spi.internal.ConfigurableMetricReaderProvider; +import io.opentelemetry.sdk.autoconfigure.spi.internal.ComponentProvider; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.MetricExporter; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.MetricReader; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.OtlpMetric; @@ -36,7 +32,6 @@ import java.util.List; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.RegisterExtension; -import org.mockito.ArgumentCaptor; class MetricReaderFactoryTest { @@ -141,14 +136,8 @@ void create_PullPrometheusDefault() throws IOException { cleanup.addCloseables(closeables); assertThat(reader.toString()).isEqualTo(expectedReader.toString()); - - ArgumentCaptor configCaptor = ArgumentCaptor.forClass(ConfigProperties.class); - verify(spiHelper) - .loadConfigurable( - eq(ConfigurableMetricReaderProvider.class), any(), any(), configCaptor.capture()); - ConfigProperties configProperties = configCaptor.getValue(); - assertThat(configProperties.getString("otel.exporter.prometheus.host")).isNull(); - assertThat(configProperties.getInt("otel.exporter.prometheus.port")).isEqualTo(port); + // TODO(jack-berg): validate prometheus component provider was invoked with correct arguments + verify(spiHelper).load(ComponentProvider.class); } @Test @@ -178,14 +167,8 @@ void create_PullPrometheusConfigured() throws IOException { cleanup.addCloseables(closeables); assertThat(reader.toString()).isEqualTo(expectedReader.toString()); - - ArgumentCaptor configCaptor = ArgumentCaptor.forClass(ConfigProperties.class); - verify(spiHelper) - .loadConfigurable( - eq(ConfigurableMetricReaderProvider.class), any(), any(), configCaptor.capture()); - ConfigProperties configProperties = configCaptor.getValue(); - assertThat(configProperties.getString("otel.exporter.prometheus.host")).isEqualTo("localhost"); - assertThat(configProperties.getInt("otel.exporter.prometheus.port")).isEqualTo(port); + // TODO(jack-berg): validate prometheus component provider was invoked with correct arguments + verify(spiHelper).load(ComponentProvider.class); } @Test diff --git a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/YamlStructuredConfigPropertiesTest.java b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/YamlStructuredConfigPropertiesTest.java new file mode 100644 index 00000000000..5c4f3d71333 --- /dev/null +++ b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/YamlStructuredConfigPropertiesTest.java @@ -0,0 +1,200 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.sdk.extension.incubator.fileconfig; + +import static org.assertj.core.api.Assertions.assertThat; + +import com.google.common.collect.ImmutableSet; +import io.opentelemetry.sdk.autoconfigure.spi.internal.StructuredConfigProperties; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.OpenTelemetryConfiguration; +import java.io.ByteArrayInputStream; +import java.nio.charset.StandardCharsets; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +class YamlStructuredConfigPropertiesTest { + + private static final String extendedSchema = + "file_format: \"0.1\"\n" + + "disabled: false\n" + + "\n" + + "resource:\n" + + " attributes:\n" + + " service.name: \"unknown_service\"\n" + + "\n" + + "other:\n" + + " str_key: str_value\n" + + " int_key: 1\n" + + " float_key: 1.1\n" + + " bool_key: true\n" + + " str_list_key: [val1, val2]\n" + + " int_list_key: [1, 2]\n" + + " float_list_key: [1.1, 2.2]\n" + + " bool_list_key: [true, false]\n" + + " mixed_list_key: [val1, 1, 1.1, true]\n" + + " map_key:\n" + + " str_key1: str_value1\n" + + " int_key1: 2\n" + + " map_key1:\n" + + " str_key2: str_value2\n" + + " int_key2: 3\n" + + " list_key:\n" + + " - str_key1: str_value1\n" + + " int_key1: 2\n" + + " map_key1:\n" + + " str_key2: str_value2\n" + + " int_key2: 3\n" + + " - str_key1: str_value1\n" + + " int_key1: 2"; + + private StructuredConfigProperties structuredConfigProps; + + @BeforeEach + void setup() { + OpenTelemetryConfiguration configuration = + FileConfiguration.parse( + new ByteArrayInputStream(extendedSchema.getBytes(StandardCharsets.UTF_8))); + structuredConfigProps = FileConfiguration.toConfigProperties(configuration); + } + + @Test + void configurationSchema() { + // Validate can read file configuration schema properties + assertThat(structuredConfigProps.getString("file_format")).isEqualTo("0.1"); + StructuredConfigProperties resourceProps = structuredConfigProps.getStructured("resource"); + assertThat(resourceProps).isNotNull(); + StructuredConfigProperties resourceAttributesProps = resourceProps.getStructured("attributes"); + assertThat(resourceAttributesProps).isNotNull(); + assertThat(resourceAttributesProps.getString("service.name")).isEqualTo("unknown_service"); + } + + @Test + void additionalProperties() { + assertThat(structuredConfigProps.getPropertyKeys()) + .isEqualTo(ImmutableSet.of("file_format", "disabled", "resource", "other")); + + // Validate can read properties not part of configuration schema + // .other + StructuredConfigProperties otherProps = structuredConfigProps.getStructured("other"); + assertThat(otherProps).isNotNull(); + assertThat(otherProps.getPropertyKeys()) + .isEqualTo( + ImmutableSet.of( + "str_key", + "int_key", + "float_key", + "bool_key", + "str_list_key", + "int_list_key", + "float_list_key", + "bool_list_key", + "mixed_list_key", + "map_key", + "list_key")); + assertThat(otherProps.getString("str_key")).isEqualTo("str_value"); + assertThat(otherProps.getInt("int_key")).isEqualTo(1); + assertThat(otherProps.getLong("int_key")).isEqualTo(1); + assertThat(otherProps.getDouble("float_key")).isEqualTo(1.1); + assertThat(otherProps.getBoolean("bool_key")).isTrue(); + assertThat(otherProps.getScalarList("str_list_key", String.class)) + .isEqualTo(Arrays.asList("val1", "val2")); + assertThat(otherProps.getScalarList("int_list_key", Long.class)) + .isEqualTo(Arrays.asList(1L, 2L)); + assertThat(otherProps.getScalarList("float_list_key", Double.class)) + .isEqualTo(Arrays.asList(1.1d, 2.2d)); + assertThat(otherProps.getScalarList("bool_list_key", Boolean.class)) + .isEqualTo(Arrays.asList(true, false)); + // If reading a scalar list which is mixed, entries which are not aligned with the requested + // type are filtered out + assertThat(otherProps.getScalarList("mixed_list_key", String.class)) + .isEqualTo(Collections.singletonList("val1")); + assertThat(otherProps.getScalarList("mixed_list_key", Long.class)) + .isEqualTo(Collections.singletonList(1L)); + assertThat(otherProps.getScalarList("mixed_list_key", Double.class)) + .isEqualTo(Collections.singletonList(1.1d)); + assertThat(otherProps.getScalarList("mixed_list_key", Boolean.class)) + .isEqualTo(Collections.singletonList(true)); + + // .other.map_key + StructuredConfigProperties otherMapKeyProps = otherProps.getStructured("map_key"); + assertThat(otherMapKeyProps).isNotNull(); + assertThat(otherMapKeyProps.getPropertyKeys()) + .isEqualTo(ImmutableSet.of("str_key1", "int_key1", "map_key1")); + assertThat(otherMapKeyProps.getString("str_key1")).isEqualTo("str_value1"); + assertThat(otherMapKeyProps.getInt("int_key1")).isEqualTo(2); + // other.map_key.map_key1 + StructuredConfigProperties otherMapKeyMapKey1Props = otherMapKeyProps.getStructured("map_key1"); + assertThat(otherMapKeyMapKey1Props).isNotNull(); + assertThat(otherMapKeyMapKey1Props.getPropertyKeys()) + .isEqualTo(ImmutableSet.of("str_key2", "int_key2")); + assertThat(otherMapKeyMapKey1Props.getString("str_key2")).isEqualTo("str_value2"); + assertThat(otherMapKeyMapKey1Props.getInt("int_key2")).isEqualTo(3); + + // .other.list_key + List listKey = otherProps.getStructuredList("list_key"); + assertThat(listKey).hasSize(2); + StructuredConfigProperties listKeyProps1 = listKey.get(0); + assertThat(listKeyProps1.getPropertyKeys()) + .isEqualTo(ImmutableSet.of("str_key1", "int_key1", "map_key1")); + assertThat(listKeyProps1.getString("str_key1")).isEqualTo("str_value1"); + assertThat(listKeyProps1.getInt("int_key1")).isEqualTo(2); + // .other.list_key[0] + StructuredConfigProperties listKeyProps1MapKeyProps = listKeyProps1.getStructured("map_key1"); + assertThat(listKeyProps1MapKeyProps).isNotNull(); + assertThat(listKeyProps1MapKeyProps.getPropertyKeys()) + .isEqualTo(ImmutableSet.of("str_key2", "int_key2")); + assertThat(listKeyProps1MapKeyProps.getString("str_key2")).isEqualTo("str_value2"); + assertThat(listKeyProps1MapKeyProps.getInt("int_key2")).isEqualTo(3); + // .other.list_key[1] + StructuredConfigProperties listKeyProps2 = listKey.get(1); + assertThat(listKeyProps2.getPropertyKeys()).isEqualTo(ImmutableSet.of("str_key1", "int_key1")); + assertThat(listKeyProps2.getString("str_key1")).isEqualTo("str_value1"); + assertThat(listKeyProps2.getInt("int_key1")).isEqualTo(2); + } + + @Test + void defaults() { + assertThat(structuredConfigProps.getString("foo", "bar")).isEqualTo("bar"); + assertThat(structuredConfigProps.getInt("foo", 1)).isEqualTo(1); + assertThat(structuredConfigProps.getLong("foo", 1)).isEqualTo(1); + assertThat(structuredConfigProps.getDouble("foo", 1.1)).isEqualTo(1.1); + assertThat(structuredConfigProps.getBoolean("foo", true)).isTrue(); + assertThat( + structuredConfigProps.getScalarList( + "foo", String.class, Collections.singletonList("bar"))) + .isEqualTo(Collections.singletonList("bar")); + } + + @Test + void missingKeys() { + assertThat(structuredConfigProps.getString("foo")).isNull(); + assertThat(structuredConfigProps.getInt("foo")).isNull(); + assertThat(structuredConfigProps.getLong("foo")).isNull(); + assertThat(structuredConfigProps.getDouble("foo")).isNull(); + assertThat(structuredConfigProps.getBoolean("foo")).isNull(); + assertThat(structuredConfigProps.getScalarList("foo", String.class)).isNull(); + assertThat(structuredConfigProps.getStructured("foo")).isNull(); + assertThat(structuredConfigProps.getStructuredList("foo")).isNull(); + } + + @Test + void wrongType() { + StructuredConfigProperties otherProps = structuredConfigProps.getStructured("other"); + assertThat(otherProps).isNotNull(); + + assertThat(otherProps.getString("int_key")).isNull(); + assertThat(otherProps.getInt("str_key")).isNull(); + assertThat(otherProps.getLong("str_key")).isNull(); + assertThat(otherProps.getDouble("str_key")).isNull(); + assertThat(otherProps.getBoolean("str_key")).isNull(); + assertThat(otherProps.getScalarList("str_key", String.class)).isNull(); + assertThat(otherProps.getStructured("str_key")).isNull(); + assertThat(otherProps.getStructuredList("str_key")).isNull(); + } +} From 56c18790795a25a41785b062669097c88a4d8ac2 Mon Sep 17 00:00:00 2001 From: Lauri Tulmin Date: Tue, 4 Jun 2024 01:14:20 +0300 Subject: [PATCH 426/901] Use unsafe to speed up string marshaling (#6433) --- exporters/common/build.gradle.kts | 4 + .../common/compile-stub/build.gradle.kts | 6 ++ .../src/main/java/sun/misc/Unsafe.java | 35 +++++++ .../internal/marshal/MarshalerContext.java | 11 ++- .../marshal/StatelessMarshalerUtil.java | 69 ++++++++++++-- .../internal/marshal/UnsafeAccess.java | 93 +++++++++++++++++++ .../internal/marshal/UnsafeString.java | 50 ++++++++++ .../StatelessMarshalerUtilFuzzTest.java | 47 ++++++++++ .../marshal/StatelessMarshalerUtilTest.java | 38 ++++---- .../internal/otlp/StringMarshalBenchmark.java | 83 ++++++++++------- .../internal/otlp/StringMarshalState.java | 2 +- settings.gradle.kts | 1 + 12 files changed, 375 insertions(+), 64 deletions(-) create mode 100644 exporters/common/compile-stub/build.gradle.kts create mode 100644 exporters/common/compile-stub/src/main/java/sun/misc/Unsafe.java create mode 100644 exporters/common/src/main/java/io/opentelemetry/exporter/internal/marshal/UnsafeAccess.java create mode 100644 exporters/common/src/main/java/io/opentelemetry/exporter/internal/marshal/UnsafeString.java create mode 100644 exporters/common/src/test/java/io/opentelemetry/exporter/internal/marshal/StatelessMarshalerUtilFuzzTest.java diff --git a/exporters/common/build.gradle.kts b/exporters/common/build.gradle.kts index b8868565287..f311510f83d 100644 --- a/exporters/common/build.gradle.kts +++ b/exporters/common/build.gradle.kts @@ -14,6 +14,7 @@ dependencies { api(project(":sdk-extensions:autoconfigure-spi")) compileOnly(project(":sdk:common")) + compileOnly(project(":exporters:common:compile-stub")) compileOnly("org.codehaus.mojo:animal-sniffer-annotations") @@ -22,6 +23,8 @@ dependencies { // We include helpers shared by gRPC exporters but do not want to impose these // dependency on all of our consumers. compileOnly("com.fasterxml.jackson.core:jackson-core") + // sun.misc.Unsafe from the JDK isn't found by the compiler, we provide our own trimmed down + // version that we can compile against. compileOnly("io.grpc:grpc-stub") testImplementation(project(":sdk:common")) @@ -31,6 +34,7 @@ dependencies { testImplementation("org.skyscreamer:jsonassert") testImplementation("com.google.api.grpc:proto-google-common-protos") testImplementation("io.grpc:grpc-testing") + testImplementation("edu.berkeley.cs.jqf:jqf-fuzz") testRuntimeOnly("io.grpc:grpc-netty-shaded") } diff --git a/exporters/common/compile-stub/build.gradle.kts b/exporters/common/compile-stub/build.gradle.kts new file mode 100644 index 00000000000..f93bd1883c9 --- /dev/null +++ b/exporters/common/compile-stub/build.gradle.kts @@ -0,0 +1,6 @@ +plugins { + id("otel.java-conventions") +} + +description = "OpenTelemetry Exporter Compile Stub" +otelJava.moduleName.set("io.opentelemetry.exporter.internal.compile-stub") diff --git a/exporters/common/compile-stub/src/main/java/sun/misc/Unsafe.java b/exporters/common/compile-stub/src/main/java/sun/misc/Unsafe.java new file mode 100644 index 00000000000..48b37ad371f --- /dev/null +++ b/exporters/common/compile-stub/src/main/java/sun/misc/Unsafe.java @@ -0,0 +1,35 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package sun.misc; + +import java.lang.reflect.Field; + +/** + * sun.misc.Unsafe from the JDK isn't found by the compiler, we provide our own trimmed down version + * that we can compile against. + */ +public class Unsafe { + + public long objectFieldOffset(Field f) { + return -1; + } + + public Object getObject(Object o, long offset) { + return null; + } + + public byte getByte(Object o, long offset) { + return 0; + } + + public int arrayBaseOffset(Class arrayClass) { + return 0; + } + + public long getLong(Object o, long offset) { + return 0; + } +} diff --git a/exporters/common/src/main/java/io/opentelemetry/exporter/internal/marshal/MarshalerContext.java b/exporters/common/src/main/java/io/opentelemetry/exporter/internal/marshal/MarshalerContext.java index fab949aeb71..a9f69459e47 100644 --- a/exporters/common/src/main/java/io/opentelemetry/exporter/internal/marshal/MarshalerContext.java +++ b/exporters/common/src/main/java/io/opentelemetry/exporter/internal/marshal/MarshalerContext.java @@ -24,6 +24,7 @@ */ public final class MarshalerContext { private final boolean marshalStringNoAllocation; + private final boolean marshalStringUnsafe; private int[] sizes = new int[16]; private int sizeReadIndex; @@ -32,19 +33,23 @@ public final class MarshalerContext { private int dataReadIndex; private int dataWriteIndex; - @SuppressWarnings("BooleanParameter") public MarshalerContext() { - this(true); + this(/* marshalStringNoAllocation= */ true, /* marshalStringUnsafe= */ true); } - public MarshalerContext(boolean marshalStringNoAllocation) { + public MarshalerContext(boolean marshalStringNoAllocation, boolean marshalStringUnsafe) { this.marshalStringNoAllocation = marshalStringNoAllocation; + this.marshalStringUnsafe = marshalStringUnsafe; } public boolean marshalStringNoAllocation() { return marshalStringNoAllocation; } + public boolean marshalStringUnsafe() { + return marshalStringUnsafe; + } + public void addSize(int size) { growSizeIfNeeded(); sizes[sizeWriteIndex++] = size; diff --git a/exporters/common/src/main/java/io/opentelemetry/exporter/internal/marshal/StatelessMarshalerUtil.java b/exporters/common/src/main/java/io/opentelemetry/exporter/internal/marshal/StatelessMarshalerUtil.java index 87c8b3d96bb..793f90cc9ae 100644 --- a/exporters/common/src/main/java/io/opentelemetry/exporter/internal/marshal/StatelessMarshalerUtil.java +++ b/exporters/common/src/main/java/io/opentelemetry/exporter/internal/marshal/StatelessMarshalerUtil.java @@ -299,16 +299,63 @@ public static int sizeMessageWithContext( } /** Returns the size of utf8 encoded string in bytes. */ - @SuppressWarnings("UnusedVariable") private static int getUtf8Size(String string, MarshalerContext context) { - return getUtf8Size(string); + return getUtf8Size(string, context.marshalStringUnsafe()); } // Visible for testing - static int getUtf8Size(String string) { + static int getUtf8Size(String string, boolean useUnsafe) { + if (useUnsafe && UnsafeString.isAvailable() && UnsafeString.isLatin1(string)) { + byte[] bytes = UnsafeString.getBytes(string); + // latin1 bytes with negative value (most significant bit set) are encoded as 2 bytes in utf8 + return string.length() + countNegative(bytes); + } + return encodedUtf8Length(string); } + // Inner loop can process at most 8 * 255 bytes without overflowing counter. To process more bytes + // inner loop has to be run multiple times. + private static final int MAX_INNER_LOOP_SIZE = 8 * 255; + // mask that selects only the most significant bit in every byte of the long + private static final long MOST_SIGNIFICANT_BIT_MASK = 0x8080808080808080L; + + /** Returns the count of bytes with negative value. */ + private static int countNegative(byte[] bytes) { + int count = 0; + int offset = 0; + // We are processing one long (8 bytes) at a time. In the inner loop we are keeping counts in a + // long where each byte in the long is a separate counter. Due to this the inner loop can + // process a maximum of 8*255 bytes at a time without overflow. + for (int i = 1; i <= bytes.length / MAX_INNER_LOOP_SIZE + 1; i++) { + long tmp = 0; // each byte in this long is a separate counter + int limit = Math.min(i * MAX_INNER_LOOP_SIZE, bytes.length & ~7); + for (; offset < limit; offset += 8) { + long value = UnsafeString.getLong(bytes, offset); + // Mask the value keeping only the most significant bit in each byte and then shift this bit + // to the position of the least significant bit in each byte. If the input byte was not + // negative then after this transformation it will be zero, if it was negative then it will + // be one. + tmp += (value & MOST_SIGNIFICANT_BIT_MASK) >>> 7; + } + // sum up counts + if (tmp != 0) { + for (int j = 0; j < 8; j++) { + count += (int) (tmp & 0xff); + tmp = tmp >>> 8; + } + } + } + + // Handle remaining bytes. Previous loop processes 8 bytes a time, if the input size is not + // divisible with 8 the remaining bytes are handled here. + for (int i = offset; i < bytes.length; i++) { + // same as if (bytes[i] < 0) count++; + count += bytes[i] >>> 31; + } + return count; + } + // adapted from // https://github.com/protocolbuffers/protobuf/blob/b618f6750aed641a23d5f26fbbaf654668846d24/java/core/src/main/java/com/google/protobuf/Utf8.java#L217 private static int encodedUtf8Length(String string) { @@ -376,14 +423,24 @@ private static int encodedUtf8LengthGeneral(String string, int start) { static void writeUtf8( CodedOutputStream output, String string, int utf8Length, MarshalerContext context) throws IOException { - writeUtf8(output, string, utf8Length); + writeUtf8(output, string, utf8Length, context.marshalStringUnsafe()); } // Visible for testing @SuppressWarnings("UnusedVariable") // utf8Length argument is added for future use - static void writeUtf8(CodedOutputStream output, String string, int utf8Length) + static void writeUtf8(CodedOutputStream output, String string, int utf8Length, boolean useUnsafe) throws IOException { - encodeUtf8(output, string); + // if the length of the latin1 string and the utf8 output are the same then the string must be + // composed of only 7bit characters and can be directly copied to the output + if (useUnsafe + && UnsafeString.isAvailable() + && string.length() == utf8Length + && UnsafeString.isLatin1(string)) { + byte[] bytes = UnsafeString.getBytes(string); + output.write(bytes, 0, bytes.length); + } else { + encodeUtf8(output, string); + } } // encode utf8 the same way as length is computed in encodedUtf8Length diff --git a/exporters/common/src/main/java/io/opentelemetry/exporter/internal/marshal/UnsafeAccess.java b/exporters/common/src/main/java/io/opentelemetry/exporter/internal/marshal/UnsafeAccess.java new file mode 100644 index 00000000000..a57e941d6dd --- /dev/null +++ b/exporters/common/src/main/java/io/opentelemetry/exporter/internal/marshal/UnsafeAccess.java @@ -0,0 +1,93 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.exporter.internal.marshal; + +import io.opentelemetry.api.internal.ConfigUtil; +import java.lang.reflect.Field; +import sun.misc.Unsafe; + +class UnsafeAccess { + private static final int MAX_ENABLED_JAVA_VERSION = 22; + private static final boolean available = checkUnsafe(); + + static boolean isAvailable() { + return available; + } + + private static boolean checkUnsafe() { + double javaVersion = getJavaVersion(); + boolean unsafeEnabled = + Boolean.parseBoolean( + ConfigUtil.getString( + "otel.java.experimental.exporter.unsafe.enabled", + javaVersion != -1 && javaVersion <= MAX_ENABLED_JAVA_VERSION ? "true" : "false")); + if (!unsafeEnabled) { + return false; + } + + try { + Class.forName("sun.misc.Unsafe", false, UnsafeAccess.class.getClassLoader()); + return UnsafeHolder.UNSAFE != null; + } catch (ClassNotFoundException e) { + return false; + } + } + + private static double getJavaVersion() { + String specVersion = System.getProperty("java.specification.version"); + if (specVersion != null) { + try { + return Double.parseDouble(specVersion); + } catch (NumberFormatException exception) { + // ignore + } + } + return -1; + } + + static long objectFieldOffset(Field field) { + return UnsafeHolder.UNSAFE.objectFieldOffset(field); + } + + static Object getObject(Object object, long offset) { + return UnsafeHolder.UNSAFE.getObject(object, offset); + } + + static byte getByte(Object object, long offset) { + return UnsafeHolder.UNSAFE.getByte(object, offset); + } + + static int arrayBaseOffset(Class arrayClass) { + return UnsafeHolder.UNSAFE.arrayBaseOffset(arrayClass); + } + + static long getLong(Object o, long offset) { + return UnsafeHolder.UNSAFE.getLong(o, offset); + } + + private UnsafeAccess() {} + + private static class UnsafeHolder { + public static final Unsafe UNSAFE; + + static { + UNSAFE = getUnsafe(); + } + + private UnsafeHolder() {} + + @SuppressWarnings("NullAway") + private static Unsafe getUnsafe() { + try { + Field field = Unsafe.class.getDeclaredField("theUnsafe"); + field.setAccessible(true); + return (Unsafe) field.get(null); + } catch (Exception ignored) { + return null; + } + } + } +} diff --git a/exporters/common/src/main/java/io/opentelemetry/exporter/internal/marshal/UnsafeString.java b/exporters/common/src/main/java/io/opentelemetry/exporter/internal/marshal/UnsafeString.java new file mode 100644 index 00000000000..c581e7525fb --- /dev/null +++ b/exporters/common/src/main/java/io/opentelemetry/exporter/internal/marshal/UnsafeString.java @@ -0,0 +1,50 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.exporter.internal.marshal; + +import java.lang.reflect.Field; + +class UnsafeString { + private static final long valueOffset = getStringFieldOffset("value", byte[].class); + private static final long coderOffset = getStringFieldOffset("coder", byte.class); + private static final int byteArrayBaseOffset = UnsafeAccess.arrayBaseOffset(byte[].class); + private static final boolean available = valueOffset != -1 && coderOffset != -1; + + static boolean isAvailable() { + return available; + } + + static boolean isLatin1(String string) { + // 0 represents latin1, 1 utf16 + return UnsafeAccess.getByte(string, coderOffset) == 0; + } + + static byte[] getBytes(String string) { + return (byte[]) UnsafeAccess.getObject(string, valueOffset); + } + + static long getLong(byte[] bytes, int index) { + return UnsafeAccess.getLong(bytes, byteArrayBaseOffset + index); + } + + private static long getStringFieldOffset(String fieldName, Class expectedType) { + if (!UnsafeAccess.isAvailable()) { + return -1; + } + + try { + Field field = String.class.getDeclaredField(fieldName); + if (field.getType() != expectedType) { + return -1; + } + return UnsafeAccess.objectFieldOffset(field); + } catch (Exception exception) { + return -1; + } + } + + private UnsafeString() {} +} diff --git a/exporters/common/src/test/java/io/opentelemetry/exporter/internal/marshal/StatelessMarshalerUtilFuzzTest.java b/exporters/common/src/test/java/io/opentelemetry/exporter/internal/marshal/StatelessMarshalerUtilFuzzTest.java new file mode 100644 index 00000000000..d8db6d2ed6c --- /dev/null +++ b/exporters/common/src/test/java/io/opentelemetry/exporter/internal/marshal/StatelessMarshalerUtilFuzzTest.java @@ -0,0 +1,47 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.exporter.internal.marshal; + +import static io.opentelemetry.exporter.internal.marshal.StatelessMarshalerUtil.getUtf8Size; +import static io.opentelemetry.exporter.internal.marshal.StatelessMarshalerUtilTest.testUtf8; +import static org.assertj.core.api.Assertions.assertThat; + +import edu.berkeley.cs.jqf.fuzz.Fuzz; +import edu.berkeley.cs.jqf.fuzz.JQF; +import edu.berkeley.cs.jqf.fuzz.junit.GuidedFuzzing; +import edu.berkeley.cs.jqf.fuzz.random.NoGuidance; +import java.nio.charset.StandardCharsets; +import org.junit.jupiter.api.Test; +import org.junit.runner.Result; +import org.junit.runner.RunWith; + +@SuppressWarnings("SystemOut") +class StatelessMarshalerUtilFuzzTest { + + @RunWith(JQF.class) + public static class EncodeUf8 { + + @Fuzz + public void encodeRandomString(String value) { + int utf8Size = value.getBytes(StandardCharsets.UTF_8).length; + assertThat(getUtf8Size(value, false)).isEqualTo(utf8Size); + assertThat(getUtf8Size(value, true)).isEqualTo(utf8Size); + assertThat(testUtf8(value, utf8Size, /* useUnsafe= */ false)).isEqualTo(value); + assertThat(testUtf8(value, utf8Size, /* useUnsafe= */ true)).isEqualTo(value); + } + } + + // driver methods to avoid having to use the vintage junit engine, and to enable increasing the + // number of iterations: + + @Test + void encodeUf8WithFuzzing() { + Result result = + GuidedFuzzing.run( + EncodeUf8.class, "encodeRandomString", new NoGuidance(10000, System.out), System.out); + assertThat(result.wasSuccessful()).isTrue(); + } +} diff --git a/exporters/common/src/test/java/io/opentelemetry/exporter/internal/marshal/StatelessMarshalerUtilTest.java b/exporters/common/src/test/java/io/opentelemetry/exporter/internal/marshal/StatelessMarshalerUtilTest.java index 6857589822e..c4eec43572d 100644 --- a/exporters/common/src/test/java/io/opentelemetry/exporter/internal/marshal/StatelessMarshalerUtilTest.java +++ b/exporters/common/src/test/java/io/opentelemetry/exporter/internal/marshal/StatelessMarshalerUtilTest.java @@ -13,31 +13,33 @@ import java.nio.charset.StandardCharsets; import java.util.Random; import org.junit.jupiter.api.RepeatedTest; -import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; class StatelessMarshalerUtilTest { - @Test + @ParameterizedTest + @ValueSource(strings = {"true", "false"}) @SuppressWarnings("AvoidEscapedUnicodeCharacters") - void encodeUtf8() { - assertThat(getUtf8Size("")).isEqualTo(0); - assertThat(testUtf8("", 0)).isEqualTo(""); + void encodeUtf8(boolean useUnsafe) { + assertThat(getUtf8Size("", useUnsafe)).isEqualTo(0); + assertThat(testUtf8("", 0, useUnsafe)).isEqualTo(""); - assertThat(getUtf8Size("a")).isEqualTo(1); - assertThat(testUtf8("a", 1)).isEqualTo("a"); + assertThat(getUtf8Size("a", useUnsafe)).isEqualTo(1); + assertThat(testUtf8("a", 1, useUnsafe)).isEqualTo("a"); - assertThat(getUtf8Size("©")).isEqualTo(2); - assertThat(testUtf8("©", 2)).isEqualTo("©"); + assertThat(getUtf8Size("©", useUnsafe)).isEqualTo(2); + assertThat(testUtf8("©", 2, useUnsafe)).isEqualTo("©"); - assertThat(getUtf8Size("∆")).isEqualTo(3); - assertThat(testUtf8("∆", 3)).isEqualTo("∆"); + assertThat(getUtf8Size("∆", useUnsafe)).isEqualTo(3); + assertThat(testUtf8("∆", 3, useUnsafe)).isEqualTo("∆"); - assertThat(getUtf8Size("😀")).isEqualTo(4); - assertThat(testUtf8("😀", 4)).isEqualTo("😀"); + assertThat(getUtf8Size("😀", useUnsafe)).isEqualTo(4); + assertThat(testUtf8("😀", 4, useUnsafe)).isEqualTo("😀"); // test that invalid characters are replaced with ? - assertThat(getUtf8Size("\uD83D😀\uDE00")).isEqualTo(6); - assertThat(testUtf8("\uD83D😀\uDE00", 6)).isEqualTo("?😀?"); + assertThat(getUtf8Size("\uD83D😀\uDE00", useUnsafe)).isEqualTo(6); + assertThat(testUtf8("\uD83D😀\uDE00", 6, useUnsafe)).isEqualTo("?😀?"); // the same invalid sequence as encoded by the jdk byte[] bytes = "\uD83D😀\uDE00".getBytes(StandardCharsets.UTF_8); @@ -52,13 +54,13 @@ void testUtf8SizeLatin1() { random.nextBytes(bytes); String string = new String(bytes, StandardCharsets.ISO_8859_1); int utf8Size = string.getBytes(StandardCharsets.UTF_8).length; - assertThat(getUtf8Size(string)).isEqualTo(utf8Size); + assertThat(getUtf8Size(string, true)).isEqualTo(utf8Size); } - private static String testUtf8(String string, int utf8Length) { + static String testUtf8(String string, int utf8Length, boolean useUnsafe) { try (ByteArrayOutputStream outputStream = new ByteArrayOutputStream()) { CodedOutputStream codedOutputStream = CodedOutputStream.newInstance(outputStream); - writeUtf8(codedOutputStream, string, utf8Length); + writeUtf8(codedOutputStream, string, utf8Length, useUnsafe); codedOutputStream.flush(); return new String(outputStream.toByteArray(), StandardCharsets.UTF_8); } catch (Exception exception) { diff --git a/exporters/otlp/common/src/jmh/java/io/opentelemetry/exporter/internal/otlp/StringMarshalBenchmark.java b/exporters/otlp/common/src/jmh/java/io/opentelemetry/exporter/internal/otlp/StringMarshalBenchmark.java index f375a200185..724f3976cec 100644 --- a/exporters/otlp/common/src/jmh/java/io/opentelemetry/exporter/internal/otlp/StringMarshalBenchmark.java +++ b/exporters/otlp/common/src/jmh/java/io/opentelemetry/exporter/internal/otlp/StringMarshalBenchmark.java @@ -25,80 +25,91 @@ @Measurement(iterations = 10, time = 1) @Fork(1) public class StringMarshalBenchmark { - private static final TestMarshaler MARSHALER = new TestMarshaler(); + private static final TestMarshaler MARSHALER_SAFE = new TestMarshaler(/* useUnsafe= */ false); + private static final TestMarshaler MARSHALER_UNSAFE = new TestMarshaler(/* useUnsafe= */ true); private static final TestOutputStream OUTPUT = new TestOutputStream(); @Benchmark @Threads(1) - public int marshalAsciiString(StringMarshalState state) throws IOException { - OUTPUT.reset(); - Marshaler marshaler = StringAnyValueMarshaler.create(state.asciiString); - marshaler.writeBinaryTo(OUTPUT); - return OUTPUT.getCount(); + public int marshalAsciiStringStateful(StringMarshalState state) throws IOException { + return marshalStateful(state.asciiString); } @Benchmark @Threads(1) - public int marshalLatin1String(StringMarshalState state) throws IOException { - OUTPUT.reset(); - Marshaler marshaler = StringAnyValueMarshaler.create(state.latin1String); - marshaler.writeBinaryTo(OUTPUT); - return OUTPUT.getCount(); + public int marshalLatin1StringStateful(StringMarshalState state) throws IOException { + return marshalStateful(state.latin1String); } @Benchmark @Threads(1) - public int marshalUnicodeString(StringMarshalState state) throws IOException { + public int marshalUnicodeStringStateful(StringMarshalState state) throws IOException { + return marshalStateful(state.unicodeString); + } + + private static int marshalStateful(String string) throws IOException { OUTPUT.reset(); - Marshaler marshaler = StringAnyValueMarshaler.create(state.unicodeString); + Marshaler marshaler = StringAnyValueMarshaler.create(string); marshaler.writeBinaryTo(OUTPUT); return OUTPUT.getCount(); } @Benchmark @Threads(1) - public int marshalAsciiStringLowAllocation(StringMarshalState state) throws IOException { - OUTPUT.reset(); - try { - MARSHALER.initialize(state.asciiString); - MARSHALER.writeBinaryTo(OUTPUT); - return OUTPUT.getCount(); - } finally { - MARSHALER.reset(); - } + public int marshalAsciiStringStatelessSafe(StringMarshalState state) throws IOException { + return marshalStateless(MARSHALER_SAFE, state.asciiString); } @Benchmark @Threads(1) - public int marshalLatin1StringLowAllocation(StringMarshalState state) throws IOException { - OUTPUT.reset(); - try { - MARSHALER.initialize(state.latin1String); - MARSHALER.writeBinaryTo(OUTPUT); - return OUTPUT.getCount(); - } finally { - MARSHALER.reset(); - } + public int marshalAsciiStringStatelessUnsafe(StringMarshalState state) throws IOException { + return marshalStateless(MARSHALER_UNSAFE, state.asciiString); + } + + @Benchmark + @Threads(1) + public int marshalLatin1StringStatelessSafe(StringMarshalState state) throws IOException { + return marshalStateless(MARSHALER_SAFE, state.latin1String); + } + + @Benchmark + @Threads(1) + public int marshalLatin1StringStatelessUnsafe(StringMarshalState state) throws IOException { + return marshalStateless(MARSHALER_UNSAFE, state.latin1String); } @Benchmark @Threads(1) - public int marshalUnicodeStringLowAllocation(StringMarshalState state) throws IOException { + public int marshalUnicodeStringStatelessSafe(StringMarshalState state) throws IOException { + return marshalStateless(MARSHALER_SAFE, state.unicodeString); + } + + @Benchmark + @Threads(1) + public int marshalUnicodeStringStatelessUnsafe(StringMarshalState state) throws IOException { + return marshalStateless(MARSHALER_UNSAFE, state.unicodeString); + } + + private static int marshalStateless(TestMarshaler marshaler, String string) throws IOException { OUTPUT.reset(); try { - MARSHALER.initialize(state.unicodeString); - MARSHALER.writeBinaryTo(OUTPUT); + marshaler.initialize(string); + marshaler.writeBinaryTo(OUTPUT); return OUTPUT.getCount(); } finally { - MARSHALER.reset(); + marshaler.reset(); } } private static class TestMarshaler extends Marshaler { - private final MarshalerContext context = new MarshalerContext(); + private final MarshalerContext context; private int size; private String value; + TestMarshaler(boolean useUnsafe) { + context = new MarshalerContext(/* marshalStringNoAllocation= */ true, useUnsafe); + } + public void initialize(String string) { value = string; size = StringAnyValueStatelessMarshaler.INSTANCE.getBinarySerializedSize(string, context); diff --git a/exporters/otlp/common/src/jmh/java/io/opentelemetry/exporter/internal/otlp/StringMarshalState.java b/exporters/otlp/common/src/jmh/java/io/opentelemetry/exporter/internal/otlp/StringMarshalState.java index 684b6c65080..4d7e3aacd18 100644 --- a/exporters/otlp/common/src/jmh/java/io/opentelemetry/exporter/internal/otlp/StringMarshalState.java +++ b/exporters/otlp/common/src/jmh/java/io/opentelemetry/exporter/internal/otlp/StringMarshalState.java @@ -13,7 +13,7 @@ @State(Scope.Benchmark) public class StringMarshalState { - @Param({"16", "512"}) + @Param("512") int stringSize; String asciiString; diff --git a/settings.gradle.kts b/settings.gradle.kts index 3fc709b740d..f919ccbefa4 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -32,6 +32,7 @@ include(":dependencyManagement") include(":extensions:kotlin") include(":extensions:trace-propagators") include(":exporters:common") +include(":exporters:common:compile-stub") include(":exporters:sender:grpc-managed-channel") include(":exporters:sender:jdk") include(":exporters:sender:okhttp") From 6d077c93441a78bfdafabb3ab0ca2129e065a105 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 4 Jun 2024 09:54:59 -0700 Subject: [PATCH 427/901] Update dependency com.google.guava:guava-bom to v33.2.1-jre (#6484) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- dependencyManagement/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index 660e9010c75..d8801027783 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -9,7 +9,7 @@ rootProject.extra["versions"] = dependencyVersions val DEPENDENCY_BOMS = listOf( "com.fasterxml.jackson:jackson-bom:2.17.1", - "com.google.guava:guava-bom:33.2.0-jre", + "com.google.guava:guava-bom:33.2.1-jre", "com.google.protobuf:protobuf-bom:3.25.3", "com.linecorp.armeria:armeria-bom:1.28.4", "com.squareup.okhttp3:okhttp-bom:4.12.0", From a7a26f9a17588b5e8b96c170abc2a201ef3fa1dd Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 4 Jun 2024 09:55:21 -0700 Subject: [PATCH 428/901] Update dependency com.google.guava:guava to v33.2.1-jre (#6483) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- buildSrc/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts index b967cbea765..9455ee7d2fb 100644 --- a/buildSrc/build.gradle.kts +++ b/buildSrc/build.gradle.kts @@ -55,7 +55,7 @@ dependencies { // When updating, update above in plugins too implementation("com.diffplug.spotless:spotless-plugin-gradle:6.25.0") // Needed for japicmp but not automatically brought in for some reason. - implementation("com.google.guava:guava:33.2.0-jre") + implementation("com.google.guava:guava:33.2.1-jre") implementation("com.squareup:javapoet:1.13.0") implementation("com.squareup.wire:wire-compiler") implementation("com.squareup.wire:wire-gradle-plugin") From aee034ae08a02ba15fab4b40f332428524aeab06 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 4 Jun 2024 09:57:47 -0700 Subject: [PATCH 429/901] Update dependency com.google.auto.value:auto-value-annotations to v1.11.0 (#6486) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- buildSrc/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts index 9455ee7d2fb..74a39541314 100644 --- a/buildSrc/build.gradle.kts +++ b/buildSrc/build.gradle.kts @@ -51,7 +51,7 @@ repositories { dependencies { implementation(enforcedPlatform("com.squareup.wire:wire-bom:4.9.9")) - implementation("com.google.auto.value:auto-value-annotations:1.10.4") + implementation("com.google.auto.value:auto-value-annotations:1.11.0") // When updating, update above in plugins too implementation("com.diffplug.spotless:spotless-plugin-gradle:6.25.0") // Needed for japicmp but not automatically brought in for some reason. From 80c8d35614e46d8bf7710552e268d39157ced444 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 4 Jun 2024 09:59:29 -0700 Subject: [PATCH 430/901] Update autoValueVersion to v1.11.0 (#6485) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- dependencyManagement/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index d8801027783..80d9c431d4c 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -24,7 +24,7 @@ val DEPENDENCY_BOMS = listOf( "org.snakeyaml:snakeyaml-engine:2.7" ) -val autoValueVersion = "1.10.4" +val autoValueVersion = "1.11.0" val errorProneVersion = "2.27.1" val jmhVersion = "1.37" // Mockito 5.x.x requires Java 11 https://github.com/mockito/mockito/releases/tag/v5.0.0 From 915cb4d0a1ad64d977cdf5fa253b57bd1ba839a6 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 4 Jun 2024 10:07:53 -0700 Subject: [PATCH 431/901] Update dependency com.uber.nullaway:nullaway to v0.11.0 (#6487) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- dependencyManagement/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index 80d9c431d4c..06ca46e9efb 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -60,7 +60,7 @@ val DEPENDENCIES = listOf( "com.google.guava:guava-beta-checker:1.0", "com.sun.net.httpserver:http:20070405", "com.tngtech.archunit:archunit-junit5:1.3.0", - "com.uber.nullaway:nullaway:0.10.26", + "com.uber.nullaway:nullaway:0.11.0", "edu.berkeley.cs.jqf:jqf-fuzz:1.7", // jqf-fuzz version 1.8+ requires Java 11+ "eu.rekawek.toxiproxy:toxiproxy-java:2.1.7", "io.github.netmikey.logunit:logunit-jul:2.0.0", From 88be482c8ef6670f72f8e4295f56042320a8a4ab Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 4 Jun 2024 10:08:49 -0700 Subject: [PATCH 432/901] Update dependency gradle to v8.8 (#6488) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- gradle/wrapper/gradle-wrapper.properties | 4 ++-- gradlew | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 381baa9cef1..8a1f6b97f47 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,7 +1,7 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionSha256Sum=544c35d6bd849ae8a5ed0bcea39ba677dc40f49df7d1835561582da2009b961d -distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip +distributionSha256Sum=a4b4158601f8636cdeeab09bd76afb640030bb5b144aafe261a5e8af027dc612 +distributionUrl=https\://services.gradle.org/distributions/gradle-8.8-bin.zip networkTimeout=10000 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME diff --git a/gradlew b/gradlew index 1aa94a42690..b740cf13397 100755 --- a/gradlew +++ b/gradlew @@ -55,7 +55,7 @@ # Darwin, MinGW, and NonStop. # # (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt # within the Gradle project. # # You can find Gradle at https://github.com/gradle/gradle/. From e15eedc1ed6a3b20bc42d2716e0ea443f3082946 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 4 Jun 2024 10:26:28 -0700 Subject: [PATCH 433/901] Update dependency com.google.api.grpc:proto-google-common-protos to v2.40.0 (#6490) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- dependencyManagement/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index 06ca46e9efb..cde8d030948 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -55,7 +55,7 @@ val DEPENDENCIES = listOf( "io.prometheus:simpleclient_httpserver:${prometheusClientVersion}", "javax.annotation:javax.annotation-api:1.3.2", "com.github.stefanbirkner:system-rules:1.19.0", - "com.google.api.grpc:proto-google-common-protos:2.39.1", + "com.google.api.grpc:proto-google-common-protos:2.40.0", "com.google.code.findbugs:jsr305:3.0.2", "com.google.guava:guava-beta-checker:1.0", "com.sun.net.httpserver:http:20070405", From a68349e2907c3cd7d7ba9d8eca3033f9e88aae2c Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 4 Jun 2024 10:31:05 -0700 Subject: [PATCH 434/901] Update errorProneVersion to v2.28.0 (#6489) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- dependencyManagement/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index cde8d030948..7c9b3064bae 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -25,7 +25,7 @@ val DEPENDENCY_BOMS = listOf( ) val autoValueVersion = "1.11.0" -val errorProneVersion = "2.27.1" +val errorProneVersion = "2.28.0" val jmhVersion = "1.37" // Mockito 5.x.x requires Java 11 https://github.com/mockito/mockito/releases/tag/v5.0.0 val mockitoVersion = "4.11.0" From 5a843989e2adbf34fd53e111bb31cfc5586b734c Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 4 Jun 2024 10:35:39 -0700 Subject: [PATCH 435/901] Update dependency org.jctools:jctools-core to v4.0.5 (#6500) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- dependencyManagement/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index 7c9b3064bae..ce3125859e9 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -76,7 +76,7 @@ val DEPENDENCIES = listOf( "org.awaitility:awaitility:4.2.1", "org.bouncycastle:bcpkix-jdk15on:1.70", "org.codehaus.mojo:animal-sniffer-annotations:1.23", - "org.jctools:jctools-core:4.0.4", + "org.jctools:jctools-core:4.0.5", "org.junit-pioneer:junit-pioneer:1.9.1", "org.mock-server:mockserver-netty:5.15.0:shaded", "org.skyscreamer:jsonassert:1.5.1", From 73646871e3b3b521d738fdccb7b491ef3f1f628f Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 4 Jun 2024 10:37:25 -0700 Subject: [PATCH 436/901] Update dependency net.ltgt.gradle:gradle-errorprone-plugin to v4 (#6501) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- buildSrc/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts index 74a39541314..d422f423107 100644 --- a/buildSrc/build.gradle.kts +++ b/buildSrc/build.gradle.kts @@ -63,7 +63,7 @@ dependencies { implementation("gradle.plugin.io.morethan.jmhreport:gradle-jmh-report:0.9.6") implementation("me.champeau.gradle:japicmp-gradle-plugin:0.4.2") implementation("me.champeau.jmh:jmh-gradle-plugin:0.7.2") - implementation("net.ltgt.gradle:gradle-errorprone-plugin:3.1.0") + implementation("net.ltgt.gradle:gradle-errorprone-plugin:4.0.0") implementation("net.ltgt.gradle:gradle-nullaway-plugin:2.0.0") implementation("org.jetbrains.kotlin:kotlin-gradle-plugin:2.0.0") implementation("org.owasp:dependency-check-gradle:9.2.0") From d0b463dd6f5760e05dc0220d10d1885f91450fb2 Mon Sep 17 00:00:00 2001 From: jack-berg <34418638+jack-berg@users.noreply.github.com> Date: Thu, 6 Jun 2024 09:42:01 -0500 Subject: [PATCH 437/901] Refactor ExtendedTracer, ExtendedSpanBuilder to reflect incubating API conventions (#6497) --- api/incubator/README.md | 174 +------------- .../incubator/trace/ExtendedSpanBuilder.java | 155 +------------ .../api/incubator/trace/ExtendedTracer.java | 44 ---- .../trace/ExtendedTraceApiUsageTest.java | 211 +++++++++++++++++ .../incubator/trace/ExtendedTracerTest.java | 214 ------------------ sdk/trace/build.gradle.kts | 2 + .../sdk/trace/SdkSpanBuilder.java | 67 +++++- 7 files changed, 295 insertions(+), 572 deletions(-) delete mode 100644 api/incubator/src/main/java/io/opentelemetry/api/incubator/trace/ExtendedTracer.java create mode 100644 api/incubator/src/test/java/io/opentelemetry/api/incubator/trace/ExtendedTraceApiUsageTest.java delete mode 100644 api/incubator/src/test/java/io/opentelemetry/api/incubator/trace/ExtendedTracerTest.java diff --git a/api/incubator/README.md b/api/incubator/README.md index 68769849e5c..068f54a3ca5 100644 --- a/api/incubator/README.md +++ b/api/incubator/README.md @@ -35,170 +35,10 @@ Features: See [ExtendedContextPropagatorsUsageTest](./src/test/java/io/opentelemetry/api/incubator/propagation/ExtendedContextPropagatorsUsageTest.java). -## ExtendedTracer - -Utility methods to make it easier to use the OpenTelemetry tracer. - -Here are some examples how the utility methods can help reduce boilerplate code. - -TODO: translate examples to test to ensure no java compilation issues. - -### Tracing a function - -Before: - - -```java -Span span = tracer.spanBuilder("reset_checkout").startSpan(); -String transactionId; -try (Scope scope = span.makeCurrent()) { - transactionId = resetCheckout(cartId); -} catch (Throwable e) { - span.setStatus(StatusCode.ERROR); - span.recordException(e); - throw e; // or throw new RuntimeException(e) - depending on your error handling strategy -} finally { - span.end(); -} -``` - - -After: - -```java -import io.opentelemetry.extension.incubator.trace.ExtendedTracer; - -ExtendedTracer extendedTracer = ExtendedTracer.create(tracer); -String transactionId = extendedTracer.spanBuilder("reset_checkout").startAndCall(() -> resetCheckout(cartId)); -``` - -If you want to set attributes on the span, you can use the `startAndCall` method on the span builder: - -```java -import io.opentelemetry.extension.incubator.trace.ExtendedTracer; - -ExtendedTracer extendedTracer = ExtendedTracer.create(tracer); -String transactionId = extendedTracer.spanBuilder("reset_checkout") - .setAttribute("foo", "bar") - .startAndCall(() -> resetCheckout(cartId)); -``` - -Note: - -- Use `startAndRun` instead of `startAndCall` if the function returns `void` (both on the tracer and span builder). -- Exceptions are re-thrown without modification - see [Exception handling](#exception-handling) - for more details. - -### Trace context propagation - -Before: - -```java -Map propagationHeaders = new HashMap<>(); -openTelemetry - .getPropagators() - .getTextMapPropagator() - .inject( - Context.current(), - propagationHeaders, - (map, key, value) -> { - if (map != null) { - map.put(key, value); - } - }); - -// add propagationHeaders to request headers and call checkout service -``` - - -```java -// in checkout service: get request headers into a Map requestHeaders -Map requestHeaders = new HashMap<>(); -String cartId = "cartId"; - -SpanBuilder spanBuilder = tracer.spanBuilder("checkout_cart"); - -TextMapGetter> TEXT_MAP_GETTER = - new TextMapGetter>() { - @Override - public Set keys(Map carrier) { - return carrier.keySet(); - } - - @Override - @Nullable - public String get(@Nullable Map carrier, String key) { - return carrier == null ? null : carrier.get(key); - } - }; - -Map normalizedTransport = - requestHeaders.entrySet().stream() - .collect( - Collectors.toMap( - entry -> entry.getKey().toLowerCase(Locale.ROOT), Map.Entry::getValue)); -Context newContext = openTelemetry - .getPropagators() - .getTextMapPropagator() - .extract(Context.current(), normalizedTransport, TEXT_MAP_GETTER); -String transactionId; -try (Scope ignore = newContext.makeCurrent()) { - Span span = spanBuilder.setSpanKind(SERVER).startSpan(); - try (Scope scope = span.makeCurrent()) { - transactionId = processCheckout(cartId); - } catch (Throwable e) { - span.setStatus(StatusCode.ERROR); - span.recordException(e); - throw e; // or throw new RuntimeException(e) - depending on your error handling strategy - } finally { - span.end(); - } -} -``` - - -After: - -```java -import io.opentelemetry.extension.incubator.propagation.ExtendedContextPropagators; - -Map propagationHeaders = - ExtendedContextPropagators.getTextMapPropagationContext(openTelemetry.getPropagators()); -// add propagationHeaders to request headers and call checkout service -``` - -```java -import io.opentelemetry.api.trace.SpanKind; -import io.opentelemetry.extension.incubator.trace.ExtendedTracer; - -// in checkout service: get request headers into a Map requestHeaders -Map requestHeaders = new HashMap<>(); -String cartId = "cartId"; - -ExtendedTracer extendedTracer = ExtendedTracer.create(tracer); -String transactionId = extendedTracer.spanBuilder("checkout_cart") - .setSpanKind(SpanKind.SERVER) - .setParentFrom(openTelemetry.getPropagators(), requestHeaders) - .startAndCall(() -> processCheckout(cartId)); -``` - -### Exception handling - -`ExtendedTracer` re-throws exceptions without modification. This means you can -catch exceptions around `ExtendedTracer` calls and handle them as you would without `ExtendedTracer`. - -When an exception is encountered during an `ExtendedTracer` call, the span is marked as error and -the exception is recorded. - -If you want to customize this behaviour, e.g. to only record the exception, because you are -able to recover from the error, you can call the overloaded method of `startAndCall` or -`startAndRun` that takes an exception handler: - -```java -import io.opentelemetry.api.trace.Span; -import io.opentelemetry.extension.incubator.trace.ExtendedTracer; - -ExtendedTracer extendedTracer = ExtendedTracer.create(tracer); -String transactionId = extendedTracer.spanBuilder("checkout_cart") - .startAndCall(() -> processCheckout(cartId), Span::recordException); -``` +## Extended Trace APIs + +Features: + +* Utility methods to reduce boilerplace using span API, including extracting context, and wrapping runnables / callables with spans + +See [ExtendedTraceApiUsageTest](./src/test/java/io/opentelemetry/api/incubator/trace/ExtendedTraceApiUsageTest.java). diff --git a/api/incubator/src/main/java/io/opentelemetry/api/incubator/trace/ExtendedSpanBuilder.java b/api/incubator/src/main/java/io/opentelemetry/api/incubator/trace/ExtendedSpanBuilder.java index 32f7a7a3d90..715b79f70c4 100644 --- a/api/incubator/src/main/java/io/opentelemetry/api/incubator/trace/ExtendedSpanBuilder.java +++ b/api/incubator/src/main/java/io/opentelemetry/api/incubator/trace/ExtendedSpanBuilder.java @@ -6,106 +6,14 @@ package io.opentelemetry.api.incubator.trace; import io.opentelemetry.api.OpenTelemetry; -import io.opentelemetry.api.common.AttributeKey; -import io.opentelemetry.api.common.Attributes; -import io.opentelemetry.api.incubator.propagation.ExtendedContextPropagators; import io.opentelemetry.api.trace.Span; import io.opentelemetry.api.trace.SpanBuilder; -import io.opentelemetry.api.trace.SpanContext; -import io.opentelemetry.api.trace.SpanKind; -import io.opentelemetry.api.trace.StatusCode; -import io.opentelemetry.context.Context; -import io.opentelemetry.context.Scope; import io.opentelemetry.context.propagation.ContextPropagators; -import java.time.Instant; import java.util.Map; -import java.util.concurrent.TimeUnit; import java.util.function.BiConsumer; -public final class ExtendedSpanBuilder implements SpanBuilder { - private final SpanBuilder delegate; - - ExtendedSpanBuilder(SpanBuilder delegate) { - this.delegate = delegate; - } - - @Override - public ExtendedSpanBuilder setParent(Context context) { - delegate.setParent(context); - return this; - } - - @Override - public ExtendedSpanBuilder setNoParent() { - delegate.setNoParent(); - return this; - } - - @Override - public ExtendedSpanBuilder addLink(SpanContext spanContext) { - delegate.addLink(spanContext); - return this; - } - - @Override - public ExtendedSpanBuilder addLink(SpanContext spanContext, Attributes attributes) { - delegate.addLink(spanContext, attributes); - return this; - } - - @Override - public ExtendedSpanBuilder setAttribute(String key, String value) { - delegate.setAttribute(key, value); - return this; - } - - @Override - public ExtendedSpanBuilder setAttribute(String key, long value) { - delegate.setAttribute(key, value); - return this; - } - - @Override - public ExtendedSpanBuilder setAttribute(String key, double value) { - delegate.setAttribute(key, value); - return this; - } - - @Override - public ExtendedSpanBuilder setAttribute(String key, boolean value) { - delegate.setAttribute(key, value); - return this; - } - - @Override - public ExtendedSpanBuilder setAttribute(AttributeKey key, T value) { - delegate.setAttribute(key, value); - return this; - } - - @Override - public ExtendedSpanBuilder setAllAttributes(Attributes attributes) { - delegate.setAllAttributes(attributes); - return this; - } - - @Override - public ExtendedSpanBuilder setSpanKind(SpanKind spanKind) { - delegate.setSpanKind(spanKind); - return this; - } - - @Override - public ExtendedSpanBuilder setStartTimestamp(long startTimestamp, TimeUnit unit) { - delegate.setStartTimestamp(startTimestamp, unit); - return this; - } - - @Override - public ExtendedSpanBuilder setStartTimestamp(Instant startTimestamp) { - delegate.setStartTimestamp(startTimestamp); - return this; - } +/** Extended {@link SpanBuilder} with experimental APIs. */ +public interface ExtendedSpanBuilder extends SpanBuilder { /** * Extract a span context from the given carrier and set it as parent of the span for {@link @@ -124,16 +32,7 @@ public ExtendedSpanBuilder setStartTimestamp(Instant startTimestamp) { * @param propagators provide the propagators from {@link OpenTelemetry#getPropagators()} * @param carrier the string map where to extract the span context from */ - public ExtendedSpanBuilder setParentFrom( - ContextPropagators propagators, Map carrier) { - setParent(ExtendedContextPropagators.extractTextMapPropagationContext(carrier, propagators)); - return this; - } - - @Override - public Span startSpan() { - return delegate.startSpan(); - } + ExtendedSpanBuilder setParentFrom(ContextPropagators propagators, Map carrier); /** * Runs the given {@link SpanCallable} inside of the span created by the given {@link @@ -147,9 +46,7 @@ public Span startSpan() { * @param the type of the exception * @return the result of the {@link SpanCallable} */ - public T startAndCall(SpanCallable spanCallable) throws E { - return startAndCall(spanCallable, ExtendedSpanBuilder::setSpanError); - } + T startAndCall(SpanCallable spanCallable) throws E; /** * Runs the given {@link SpanCallable} inside of the span created by the given {@link @@ -165,20 +62,8 @@ public T startAndCall(SpanCallable spanCallable) * @param the type of the exception * @return the result of the {@link SpanCallable} */ - public T startAndCall( - SpanCallable spanCallable, BiConsumer handleException) throws E { - Span span = startSpan(); - - //noinspection unused - try (Scope unused = span.makeCurrent()) { - return spanCallable.callInSpan(); - } catch (Throwable e) { - handleException.accept(span, e); - throw e; - } finally { - span.end(); - } - } + T startAndCall( + SpanCallable spanCallable, BiConsumer handleException) throws E; /** * Runs the given {@link SpanRunnable} inside of the span created by the given {@link @@ -190,10 +75,7 @@ public T startAndCall( * @param runnable the {@link SpanRunnable} to run * @param the type of the exception */ - @SuppressWarnings("NullAway") - public void startAndRun(SpanRunnable runnable) throws E { - startAndRun(runnable, ExtendedSpanBuilder::setSpanError); - } + void startAndRun(SpanRunnable runnable) throws E; /** * Runs the given {@link SpanRunnable} inside of the span created by the given {@link @@ -206,25 +88,6 @@ public void startAndRun(SpanRunnable runnable) throws E * @param runnable the {@link SpanRunnable} to run * @param the type of the exception */ - @SuppressWarnings("NullAway") - public void startAndRun( - SpanRunnable runnable, BiConsumer handleException) throws E { - startAndCall( - () -> { - runnable.runInSpan(); - return null; - }, - handleException); - } - - /** - * Marks a span as error. This is the default exception handler. - * - * @param span the span - * @param exception the exception that caused the error - */ - private static void setSpanError(Span span, Throwable exception) { - span.setStatus(StatusCode.ERROR); - span.recordException(exception); - } + void startAndRun( + SpanRunnable runnable, BiConsumer handleException) throws E; } diff --git a/api/incubator/src/main/java/io/opentelemetry/api/incubator/trace/ExtendedTracer.java b/api/incubator/src/main/java/io/opentelemetry/api/incubator/trace/ExtendedTracer.java deleted file mode 100644 index 86ed57df1df..00000000000 --- a/api/incubator/src/main/java/io/opentelemetry/api/incubator/trace/ExtendedTracer.java +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package io.opentelemetry.api.incubator.trace; - -import io.opentelemetry.api.trace.Tracer; - -/** - * Utility class to simplify tracing. - * - *

      The README - * explains the use cases in more detail. - */ -public final class ExtendedTracer implements Tracer { - - private final Tracer delegate; - - private ExtendedTracer(Tracer delegate) { - this.delegate = delegate; - } - - /** - * Creates a new instance of {@link ExtendedTracer}. - * - * @param delegate the {@link Tracer} to use - */ - public static ExtendedTracer create(Tracer delegate) { - return new ExtendedTracer(delegate); - } - - /** - * Creates a new {@link ExtendedSpanBuilder} with the given span name. - * - * @param spanName the name of the span - * @return the {@link ExtendedSpanBuilder} - */ - @Override - public ExtendedSpanBuilder spanBuilder(String spanName) { - return new ExtendedSpanBuilder(delegate.spanBuilder(spanName)); - } -} diff --git a/api/incubator/src/test/java/io/opentelemetry/api/incubator/trace/ExtendedTraceApiUsageTest.java b/api/incubator/src/test/java/io/opentelemetry/api/incubator/trace/ExtendedTraceApiUsageTest.java new file mode 100644 index 00000000000..18bc1ec78a8 --- /dev/null +++ b/api/incubator/src/test/java/io/opentelemetry/api/incubator/trace/ExtendedTraceApiUsageTest.java @@ -0,0 +1,211 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.api.incubator.trace; + +import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.assertThat; + +import io.opentelemetry.api.common.AttributeKey; +import io.opentelemetry.api.trace.Span; +import io.opentelemetry.api.trace.SpanContext; +import io.opentelemetry.api.trace.TraceFlags; +import io.opentelemetry.api.trace.TraceState; +import io.opentelemetry.api.trace.Tracer; +import io.opentelemetry.api.trace.propagation.W3CTraceContextPropagator; +import io.opentelemetry.context.Context; +import io.opentelemetry.context.propagation.ContextPropagators; +import io.opentelemetry.context.propagation.TextMapPropagator; +import io.opentelemetry.sdk.resources.Resource; +import io.opentelemetry.sdk.testing.exporter.InMemorySpanExporter; +import io.opentelemetry.sdk.trace.IdGenerator; +import io.opentelemetry.sdk.trace.SdkTracerProvider; +import io.opentelemetry.sdk.trace.data.StatusData; +import io.opentelemetry.sdk.trace.export.SimpleSpanProcessor; +import java.util.HashMap; +import java.util.Map; +import java.util.function.BiConsumer; +import org.junit.jupiter.api.Test; + +/** Demonstrating usage of extended Trace API. */ +class ExtendedTraceApiUsageTest { + + /** Demonstrates {@link ExtendedSpanBuilder#setParentFrom(ContextPropagators, Map)}. */ + @Test + void setParentFrom() { + // Setup SdkTracerProvider + InMemorySpanExporter spanExporter = InMemorySpanExporter.create(); + SdkTracerProvider tracerProvider = + SdkTracerProvider.builder() + // Default resource used for demonstration purposes + .setResource(Resource.getDefault()) + // SimpleSpanProcessor with InMemorySpanExporter used for demonstration purposes + .addSpanProcessor(SimpleSpanProcessor.create(spanExporter)) + .build(); + + // Setup ContextPropagators + ContextPropagators contextPropagators = + ContextPropagators.create( + TextMapPropagator.composite(W3CTraceContextPropagator.getInstance())); + + // Get a Tracer for a scope + Tracer tracer = tracerProvider.get("org.foo.my-scope"); + + // Populate a map with W3C trace context + Map contextCarrier = new HashMap<>(); + SpanContext remoteParentContext = + SpanContext.createFromRemoteParent( + IdGenerator.random().generateTraceId(), + IdGenerator.random().generateSpanId(), + TraceFlags.getSampled(), + TraceState.getDefault()); + W3CTraceContextPropagator.getInstance() + .inject( + Context.current().with(Span.wrap(remoteParentContext)), + contextCarrier, + (carrier, key, value) -> { + if (carrier != null) { + carrier.put(key, value); + } + }); + + // Set parent from the Map context carrier + ((ExtendedSpanBuilder) tracer.spanBuilder("local_root")) + .setParentFrom(contextPropagators, contextCarrier) + .startSpan() + .end(); + + // Verify the span has the correct parent context + assertThat(spanExporter.getFinishedSpanItems()) + .satisfiesExactly( + span -> + assertThat(span) + .hasName("local_root") + .hasParentSpanId(remoteParentContext.getSpanId()) + .hasTraceId(remoteParentContext.getTraceId())); + } + + /** + * Demonstrates {@link ExtendedSpanBuilder#startAndCall(SpanCallable)}, {@link + * ExtendedSpanBuilder#startAndCall(SpanCallable, BiConsumer)}, {@link + * ExtendedSpanBuilder#startAndRun(SpanRunnable)}, {@link + * ExtendedSpanBuilder#startAndRun(SpanRunnable, BiConsumer)}. + */ + @Test + void startAndCallOrRun() { + // Setup SdkTracerProvider + InMemorySpanExporter spanExporter = InMemorySpanExporter.create(); + SdkTracerProvider tracerProvider = + SdkTracerProvider.builder() + // Default resource used for demonstration purposes + .setResource(Resource.getDefault()) + // SimpleSpanProcessor with InMemorySpanExporter used for demonstration purposes + .addSpanProcessor(SimpleSpanProcessor.create(spanExporter)) + .build(); + + // Get a Tracer for a scope + Tracer tracer = tracerProvider.get("org.foo.my-scope"); + + // Wrap the resetCheckout method in a span + String cartId = + ((ExtendedSpanBuilder) tracer.spanBuilder("reset_checkout_and_return")) + .startAndCall(() -> resetCheckoutAndReturn("abc123", /* throwException= */ false)); + assertThat(cartId).isEqualTo("abc123"); + // ...or runnable variation + ((ExtendedSpanBuilder) tracer.spanBuilder("reset_checkout")) + .startAndRun(() -> resetCheckout("abc123", /* throwException= */ false)); + + // Wrap the resetCheckout method in a span; resetCheckout throws an exception + try { + ((ExtendedSpanBuilder) tracer.spanBuilder("reset_checkout_and_return")) + .startAndCall(() -> resetCheckoutAndReturn("def456", /* throwException= */ true)); + } catch (Throwable e) { + // Ignore expected exception + } + // ...or runnable variation + try { + ((ExtendedSpanBuilder) tracer.spanBuilder("reset_checkout")) + .startAndRun(() -> resetCheckout("def456", /* throwException= */ true)); + } catch (Throwable e) { + // Ignore expected exception + } + + // Wrap the resetCheckout method in a span; resetCheckout throws an exception; use custom error + // handler + try { + ((ExtendedSpanBuilder) tracer.spanBuilder("reset_checkout_and_return")) + .startAndCall( + () -> resetCheckoutAndReturn("ghi789", /* throwException= */ true), + (span, throwable) -> span.setAttribute("my-attribute", "error")); + } catch (Throwable e) { + // Ignore expected exception + } + // ...or runnable variation + try { + ((ExtendedSpanBuilder) tracer.spanBuilder("reset_checkout")) + .startAndRun( + () -> resetCheckout("ghi789", /* throwException= */ true), + (span, throwable) -> span.setAttribute("my-attribute", "error")); + } catch (Throwable e) { + // Ignore expected exception + } + + // Verify the spans are as expected + assertThat(spanExporter.getFinishedSpanItems()) + .satisfiesExactly( + span -> + assertThat(span) + .hasName("reset_checkout_and_return") + .hasAttribute(AttributeKey.stringKey("cartId"), "abc123") + .hasStatus(StatusData.unset()) + .hasTotalRecordedEvents(0), + span -> + assertThat(span) + .hasName("reset_checkout") + .hasAttribute(AttributeKey.stringKey("cartId"), "abc123") + .hasStatus(StatusData.unset()) + .hasTotalRecordedEvents(0), + span -> + assertThat(span) + .hasName("reset_checkout_and_return") + .hasAttribute(AttributeKey.stringKey("cartId"), "def456") + .hasStatus(StatusData.error()) + .hasEventsSatisfyingExactly(event -> event.hasName("exception")), + span -> + assertThat(span) + .hasName("reset_checkout") + .hasAttribute(AttributeKey.stringKey("cartId"), "def456") + .hasStatus(StatusData.error()) + .hasEventsSatisfyingExactly(event -> event.hasName("exception")), + span -> + assertThat(span) + .hasName("reset_checkout_and_return") + .hasAttribute(AttributeKey.stringKey("cartId"), "ghi789") + .hasAttribute(AttributeKey.stringKey("my-attribute"), "error") + .hasStatus(StatusData.unset()) + .hasTotalRecordedEvents(0), + span -> + assertThat(span) + .hasName("reset_checkout") + .hasAttribute(AttributeKey.stringKey("cartId"), "ghi789") + .hasAttribute(AttributeKey.stringKey("my-attribute"), "error") + .hasStatus(StatusData.unset()) + .hasTotalRecordedEvents(0)); + } + + private static String resetCheckoutAndReturn(String cartId, boolean throwException) { + Span.current().setAttribute("cartId", cartId); + if (throwException) { + throw new RuntimeException("Error!"); + } + return cartId; + } + + private static void resetCheckout(String cartId, boolean throwException) { + Span.current().setAttribute("cartId", cartId); + if (throwException) { + throw new RuntimeException("Error!"); + } + } +} diff --git a/api/incubator/src/test/java/io/opentelemetry/api/incubator/trace/ExtendedTracerTest.java b/api/incubator/src/test/java/io/opentelemetry/api/incubator/trace/ExtendedTracerTest.java deleted file mode 100644 index 20ad50ca0be..00000000000 --- a/api/incubator/src/test/java/io/opentelemetry/api/incubator/trace/ExtendedTracerTest.java +++ /dev/null @@ -1,214 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package io.opentelemetry.api.incubator.trace; - -import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.equalTo; -import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.satisfies; -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatException; -import static org.assertj.core.api.Assertions.assertThatIllegalStateException; -import static org.junit.jupiter.api.Named.named; - -import com.google.errorprone.annotations.Keep; -import io.opentelemetry.api.common.Attributes; -import io.opentelemetry.api.incubator.propagation.ExtendedContextPropagators; -import io.opentelemetry.api.trace.Span; -import io.opentelemetry.api.trace.SpanKind; -import io.opentelemetry.context.Context; -import io.opentelemetry.context.Scope; -import io.opentelemetry.context.propagation.ContextPropagators; -import io.opentelemetry.sdk.testing.assertj.SpanDataAssert; -import io.opentelemetry.sdk.testing.junit5.OpenTelemetryExtension; -import io.opentelemetry.sdk.trace.data.StatusData; -import io.opentelemetry.semconv.ClientAttributes; -import io.opentelemetry.semconv.ExceptionAttributes; -import java.time.Instant; -import java.util.Collections; -import java.util.Map; -import java.util.function.BiConsumer; -import java.util.stream.Stream; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.RegisterExtension; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.Arguments; -import org.junit.jupiter.params.provider.MethodSource; - -class ExtendedTracerTest { - - interface ThrowingBiConsumer { - void accept(T t, U u) throws Throwable; - } - - @RegisterExtension - static final OpenTelemetryExtension otelTesting = OpenTelemetryExtension.create(); - - private final ExtendedTracer extendedTracer = - ExtendedTracer.create(otelTesting.getOpenTelemetry().getTracer("test")); - - @Test - void wrapInSpan() { - assertThatIllegalStateException() - .isThrownBy( - () -> - extendedTracer - .spanBuilder("test") - .startAndRun( - () -> { - // runs in span - throw new IllegalStateException("ex"); - })); - - String result = - extendedTracer - .spanBuilder("another test") - .startAndCall( - () -> { - // runs in span - return "result"; - }); - assertThat(result).isEqualTo("result"); - - otelTesting - .assertTraces() - .hasTracesSatisfyingExactly( - trace -> - trace.hasSpansSatisfyingExactly( - span -> - span.hasName("test") - .hasStatus(StatusData.error()) - .hasEventsSatisfyingExactly( - event -> - event - .hasName("exception") - .hasAttributesSatisfyingExactly( - equalTo( - ExceptionAttributes.EXCEPTION_TYPE, - "java.lang.IllegalStateException"), - satisfies( - ExceptionAttributes.EXCEPTION_STACKTRACE, - string -> - string.contains( - "java.lang.IllegalStateException: ex")), - equalTo(ExceptionAttributes.EXCEPTION_MESSAGE, "ex")))), - trace -> trace.hasSpansSatisfyingExactly(a -> a.hasName("another test"))); - } - - @Test - void propagation() { - extendedTracer - .spanBuilder("parent") - .startAndRun( - () -> { - ContextPropagators propagators = otelTesting.getOpenTelemetry().getPropagators(); - Map propagationHeaders = - ExtendedContextPropagators.getTextMapPropagationContext(propagators); - assertThat(propagationHeaders).hasSize(1).containsKey("traceparent"); - - // make sure the parent span is not stored in a thread local anymore - Span invalid = Span.getInvalid(); - //noinspection unused - try (Scope unused = invalid.makeCurrent()) { - extendedTracer - .spanBuilder("child") - .setSpanKind(SpanKind.SERVER) - .setParent(Context.current()) - .setNoParent() - .setParentFrom(propagators, propagationHeaders) - .setAttribute( - "key", - "value") // any method can be called here on the span (and we increase the - // test coverage) - .setAttribute("key2", 0) - .setAttribute("key3", 0.0) - .setAttribute("key4", false) - .setAttribute(ClientAttributes.CLIENT_PORT, 1234L) - .addLink(invalid.getSpanContext()) - .addLink(invalid.getSpanContext(), Attributes.empty()) - .setAllAttributes(Attributes.empty()) - .setStartTimestamp(0, java.util.concurrent.TimeUnit.NANOSECONDS) - .setStartTimestamp(Instant.MIN) - .startAndRun(() -> {}); - } - }); - - otelTesting - .assertTraces() - .hasTracesSatisfyingExactly( - trace -> - trace.hasSpansSatisfyingExactly( - SpanDataAssert::hasNoParent, span -> span.hasParent(trace.getSpan(0)))); - } - - private static class ExtractAndRunParameter { - private final ThrowingBiConsumer> extractAndRun; - private final SpanKind wantKind; - private final StatusData wantStatus; - - private ExtractAndRunParameter( - ThrowingBiConsumer> extractAndRun, - SpanKind wantKind, - StatusData wantStatus) { - this.extractAndRun = extractAndRun; - this.wantKind = wantKind; - this.wantStatus = wantStatus; - } - } - - @Keep - private static Stream extractAndRun() { - BiConsumer ignoreException = - (span, throwable) -> { - // ignore - }; - return Stream.of( - Arguments.of( - named( - "server", - new ExtractAndRunParameter( - (t, c) -> - t.spanBuilder("span") - .setSpanKind(SpanKind.SERVER) - .setParentFrom( - otelTesting.getOpenTelemetry().getPropagators(), - Collections.emptyMap()) - .startAndCall(c), - SpanKind.SERVER, - StatusData.error()))), - Arguments.of( - named( - "server - ignore exception", - new ExtractAndRunParameter( - (t, c) -> - t.spanBuilder("span") - .setSpanKind(SpanKind.SERVER) - .setParentFrom( - otelTesting.getOpenTelemetry().getPropagators(), - Collections.emptyMap()) - .startAndCall(c, ignoreException), - SpanKind.SERVER, - StatusData.unset())))); - } - - @ParameterizedTest - @MethodSource - void extractAndRun(ExtractAndRunParameter parameter) { - assertThatException() - .isThrownBy( - () -> - parameter.extractAndRun.accept( - extendedTracer, - () -> { - throw new RuntimeException("ex"); - })); - - otelTesting - .assertTraces() - .hasTracesSatisfyingExactly( - trace -> - trace.hasSpansSatisfyingExactly( - span -> span.hasKind(parameter.wantKind).hasStatus(parameter.wantStatus))); - } -} diff --git a/sdk/trace/build.gradle.kts b/sdk/trace/build.gradle.kts index ae87071507a..34690eaeeca 100644 --- a/sdk/trace/build.gradle.kts +++ b/sdk/trace/build.gradle.kts @@ -22,6 +22,8 @@ dependencies { api(project(":api:all")) api(project(":sdk:common")) + implementation(project(":api:incubator")) + compileOnly(project(":sdk:trace-shaded-deps")) annotationProcessor("com.google.auto.value:auto-value") diff --git a/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/SdkSpanBuilder.java b/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/SdkSpanBuilder.java index fa823fa179a..1a9a946ae5b 100644 --- a/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/SdkSpanBuilder.java +++ b/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/SdkSpanBuilder.java @@ -12,14 +12,21 @@ import io.opentelemetry.api.common.AttributeKey; import io.opentelemetry.api.common.Attributes; +import io.opentelemetry.api.incubator.propagation.ExtendedContextPropagators; +import io.opentelemetry.api.incubator.trace.ExtendedSpanBuilder; +import io.opentelemetry.api.incubator.trace.SpanCallable; +import io.opentelemetry.api.incubator.trace.SpanRunnable; import io.opentelemetry.api.internal.ImmutableSpanContext; import io.opentelemetry.api.trace.Span; import io.opentelemetry.api.trace.SpanBuilder; import io.opentelemetry.api.trace.SpanContext; import io.opentelemetry.api.trace.SpanKind; +import io.opentelemetry.api.trace.StatusCode; import io.opentelemetry.api.trace.TraceFlags; import io.opentelemetry.api.trace.TraceState; import io.opentelemetry.context.Context; +import io.opentelemetry.context.Scope; +import io.opentelemetry.context.propagation.ContextPropagators; import io.opentelemetry.sdk.common.InstrumentationScopeInfo; import io.opentelemetry.sdk.internal.AttributeUtil; import io.opentelemetry.sdk.internal.AttributesMap; @@ -29,11 +36,13 @@ import java.util.ArrayList; import java.util.Collections; import java.util.List; +import java.util.Map; import java.util.concurrent.TimeUnit; +import java.util.function.BiConsumer; import javax.annotation.Nullable; /** {@link SdkSpanBuilder} is SDK implementation of {@link SpanBuilder}. */ -final class SdkSpanBuilder implements SpanBuilder { +final class SdkSpanBuilder implements ExtendedSpanBuilder { private final String spanName; private final InstrumentationScopeInfo instrumentationScopeInfo; @@ -163,6 +172,13 @@ public SpanBuilder setStartTimestamp(long startTimestamp, TimeUnit unit) { return this; } + @Override + public ExtendedSpanBuilder setParentFrom( + ContextPropagators propagators, Map carrier) { + setParent(ExtendedContextPropagators.extractTextMapPropagationContext(carrier, propagators)); + return this; + } + @Override @SuppressWarnings({"unchecked", "rawtypes"}) public Span startSpan() { @@ -234,6 +250,44 @@ public Span startSpan() { startEpochNanos); } + @Override + public T startAndCall(SpanCallable spanCallable) throws E { + return startAndCall(spanCallable, SdkSpanBuilder::setSpanError); + } + + @Override + public T startAndCall( + SpanCallable spanCallable, BiConsumer handleException) throws E { + Span span = startSpan(); + + //noinspection unused + try (Scope unused = span.makeCurrent()) { + return spanCallable.callInSpan(); + } catch (Throwable e) { + handleException.accept(span, e); + throw e; + } finally { + span.end(); + } + } + + @Override + public void startAndRun(SpanRunnable runnable) throws E { + startAndRun(runnable, SdkSpanBuilder::setSpanError); + } + + @SuppressWarnings("NullAway") + @Override + public void startAndRun( + SpanRunnable runnable, BiConsumer handleException) throws E { + startAndCall( + () -> { + runnable.runInSpan(); + return null; + }, + handleException); + } + private AttributesMap attributes() { AttributesMap attributes = this.attributes; if (attributes == null) { @@ -255,4 +309,15 @@ static boolean isRecording(SamplingDecision decision) { static boolean isSampled(SamplingDecision decision) { return SamplingDecision.RECORD_AND_SAMPLE.equals(decision); } + + /** + * Marks a span as error. This is the default exception handler. + * + * @param span the span + * @param exception the exception that caused the error + */ + private static void setSpanError(Span span, Throwable exception) { + span.setStatus(StatusCode.ERROR); + span.recordException(exception); + } } From 934da846f0733fd10872dedfef06019d026ca4d0 Mon Sep 17 00:00:00 2001 From: jack-berg <34418638+jack-berg@users.noreply.github.com> Date: Thu, 6 Jun 2024 16:10:50 -0500 Subject: [PATCH 438/901] Fix incubator docs (#6505) --- api/incubator/README.md | 1 - 1 file changed, 1 deletion(-) diff --git a/api/incubator/README.md b/api/incubator/README.md index 068f54a3ca5..84e10a2a78b 100644 --- a/api/incubator/README.md +++ b/api/incubator/README.md @@ -22,7 +22,6 @@ See [ExtendedLogsBridgeApiUsageTest](./src/test/java/io/opentelemetry/api/incuba Features: -* Synchronous gauge instrument * Attributes advice See [ExtendedMetricsApiUsageTest](./src/test/java/io/opentelemetry/api/incubator/metrics/ExtendedMetricsApiUsageTest.java). From edbb475957869ff35614fbfe7c127bda4fb248fc Mon Sep 17 00:00:00 2001 From: jack-berg <34418638+jack-berg@users.noreply.github.com> Date: Fri, 7 Jun 2024 06:40:17 -0500 Subject: [PATCH 439/901] Prepare 1.39.0 (#6506) Co-authored-by: Trask Stalnaker --- CHANGELOG.md | 42 +++++++++++++++++++ .../OtlpHttpLogRecordExporterBuilder.java | 4 +- .../OtlpHttpMetricExporterBuilder.java | 4 +- .../trace/OtlpHttpSpanExporterBuilder.java | 4 +- .../OtlpGrpcLogRecordExporterBuilder.java | 4 +- .../OtlpGrpcMetricExporterBuilder.java | 4 +- .../trace/OtlpGrpcSpanExporterBuilder.java | 4 +- exporters/otlp/profiles/build.gradle.kts | 3 +- 8 files changed, 62 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e785579b02c..2e95ba7035f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,48 @@ ## Unreleased +### API + +#### Incubator + +* BREAKING: Refactor ExtendedTracer, ExtendedSpanBuilder to reflect incubating API conventions + ([#6497](https://github.com/open-telemetry/opentelemetry-java/pull/6497)) + +### SDK + +#### Exporter + +* BREAKING: Serve prometheus metrics only on `/metrics` by default. To restore the previous behavior + and serve metrics on all paths, override the default handler + as [demonstrated here](https://github.com/open-telemetry/opentelemetry-java/blob/main/exporters/prometheus/src/test/java/io/opentelemetry/exporter/prometheus/PrometheusHttpServerTest.java#L251-L259). + ([#6476](https://github.com/open-telemetry/opentelemetry-java/pull/6476)) +* Make OTLP exporter memory mode API public + ([#6469](https://github.com/open-telemetry/opentelemetry-java/pull/6469)) +* Speed up OTLP string marshaling using sun.misc.Unsafe + ([#6433](https://github.com/open-telemetry/opentelemetry-java/pull/6433)) +* Add exporter data classes for experimental profiling signal type. + ([#6374](https://github.com/open-telemetry/opentelemetry-java/pull/6374)) +* Start prometheus http server with daemon thread + ([#6472](https://github.com/open-telemetry/opentelemetry-java/pull/6472)) +* Update the Prometheus metrics library and improve how units are included in metric names. + ([#6473](https://github.com/open-telemetry/opentelemetry-java/pull/6473)) +* Remove android animalsniffer check from prometheus exporter + ([#6478](https://github.com/open-telemetry/opentelemetry-java/pull/6478)) + +#### Extensions + +* Load file config YAML using core schema, ensure that env var substitution retains string types. + ([#6436](https://github.com/open-telemetry/opentelemetry-java/pull/6436)) +* Define dedicated file configuration SPI ComponentProvider + ([#6457](https://github.com/open-telemetry/opentelemetry-java/pull/6457)) + +### Tooling + +* Normalize timestamps and file ordering in jars, making the outputs reproducible + ([#6471](https://github.com/open-telemetry/opentelemetry-java/pull/6471)) +* GHA for generating the post-release pull request + ([#6449](https://github.com/open-telemetry/opentelemetry-java/pull/6449)) + ## Version 1.38.0 (2024-05-10) ### API diff --git a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/logs/OtlpHttpLogRecordExporterBuilder.java b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/logs/OtlpHttpLogRecordExporterBuilder.java index a2db5890439..364be52a6b3 100644 --- a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/logs/OtlpHttpLogRecordExporterBuilder.java +++ b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/logs/OtlpHttpLogRecordExporterBuilder.java @@ -213,8 +213,10 @@ public OtlpHttpLogRecordExporterBuilder setMeterProvider( /** * Set the {@link MemoryMode}. If unset, defaults to {@link #DEFAULT_MEMORY_MODE}. * - *

      >When memory mode is {@link MemoryMode#REUSABLE_DATA}, serialization is optimized to reduce + *

      When memory mode is {@link MemoryMode#REUSABLE_DATA}, serialization is optimized to reduce * memory allocation. + * + * @since 1.39.0 */ public OtlpHttpLogRecordExporterBuilder setMemoryMode(MemoryMode memoryMode) { requireNonNull(memoryMode, "memoryMode"); diff --git a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/metrics/OtlpHttpMetricExporterBuilder.java b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/metrics/OtlpHttpMetricExporterBuilder.java index 7046f65ebb1..539df4430be 100644 --- a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/metrics/OtlpHttpMetricExporterBuilder.java +++ b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/metrics/OtlpHttpMetricExporterBuilder.java @@ -236,13 +236,15 @@ public OtlpHttpMetricExporterBuilder setProxyOptions(ProxyOptions proxyOptions) /** * Set the {@link MemoryMode}. If unset, defaults to {@link #DEFAULT_MEMORY_MODE}. * - *

      >When memory mode is {@link MemoryMode#REUSABLE_DATA}, serialization is optimized to reduce + *

      When memory mode is {@link MemoryMode#REUSABLE_DATA}, serialization is optimized to reduce * memory allocation. Additionally, the value is used for {@link MetricExporter#getMemoryMode()}, * which sends a signal to the metrics SDK to reuse memory when possible. This is safe and * desirable for most use cases, but should be used with caution of wrapping and delegating to the * exporter. It is not safe for the wrapping exporter to hold onto references to {@link * MetricData} batches since the same data structures will be reused in subsequent calls to {@link * MetricExporter#export(Collection)}. + * + * @since 1.39.0 */ public OtlpHttpMetricExporterBuilder setMemoryMode(MemoryMode memoryMode) { requireNonNull(memoryMode, "memoryMode"); diff --git a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/trace/OtlpHttpSpanExporterBuilder.java b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/trace/OtlpHttpSpanExporterBuilder.java index db54626fc70..a05735ae092 100644 --- a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/trace/OtlpHttpSpanExporterBuilder.java +++ b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/trace/OtlpHttpSpanExporterBuilder.java @@ -214,8 +214,10 @@ public OtlpHttpSpanExporterBuilder setMeterProvider( /** * Set the {@link MemoryMode}. If unset, defaults to {@link #DEFAULT_MEMORY_MODE}. * - *

      >When memory mode is {@link MemoryMode#REUSABLE_DATA}, serialization is optimized to reduce + *

      When memory mode is {@link MemoryMode#REUSABLE_DATA}, serialization is optimized to reduce * memory allocation. + * + * @since 1.39.0 */ public OtlpHttpSpanExporterBuilder setMemoryMode(MemoryMode memoryMode) { requireNonNull(memoryMode, "memoryMode"); diff --git a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/logs/OtlpGrpcLogRecordExporterBuilder.java b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/logs/OtlpGrpcLogRecordExporterBuilder.java index 3131ae16ff0..0889105f7f7 100644 --- a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/logs/OtlpGrpcLogRecordExporterBuilder.java +++ b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/logs/OtlpGrpcLogRecordExporterBuilder.java @@ -246,8 +246,10 @@ public OtlpGrpcLogRecordExporterBuilder setMeterProvider( /** * Set the {@link MemoryMode}. If unset, defaults to {@link #DEFAULT_MEMORY_MODE}. * - *

      >When memory mode is {@link MemoryMode#REUSABLE_DATA}, serialization is optimized to reduce + *

      When memory mode is {@link MemoryMode#REUSABLE_DATA}, serialization is optimized to reduce * memory allocation. + * + * @since 1.39.0 */ public OtlpGrpcLogRecordExporterBuilder setMemoryMode(MemoryMode memoryMode) { requireNonNull(memoryMode, "memoryMode"); diff --git a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/metrics/OtlpGrpcMetricExporterBuilder.java b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/metrics/OtlpGrpcMetricExporterBuilder.java index 34887f7f267..51282d574f7 100644 --- a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/metrics/OtlpGrpcMetricExporterBuilder.java +++ b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/metrics/OtlpGrpcMetricExporterBuilder.java @@ -269,13 +269,15 @@ public OtlpGrpcMetricExporterBuilder setRetryPolicy(RetryPolicy retryPolicy) { /** * Set the {@link MemoryMode}. If unset, defaults to {@link #DEFAULT_MEMORY_MODE}. * - *

      >When memory mode is {@link MemoryMode#REUSABLE_DATA}, serialization is optimized to reduce + *

      When memory mode is {@link MemoryMode#REUSABLE_DATA}, serialization is optimized to reduce * memory allocation. Additionally, the value is used for {@link MetricExporter#getMemoryMode()}, * which sends a signal to the metrics SDK to reuse memory when possible. This is safe and * desirable for most use cases, but should be used with caution of wrapping and delegating to the * exporter. It is not safe for the wrapping exporter to hold onto references to {@link * MetricData} batches since the same data structures will be reused in subsequent calls to {@link * MetricExporter#export(Collection)}. + * + * @since 1.39.0 */ public OtlpGrpcMetricExporterBuilder setMemoryMode(MemoryMode memoryMode) { requireNonNull(memoryMode, "memoryMode"); diff --git a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/trace/OtlpGrpcSpanExporterBuilder.java b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/trace/OtlpGrpcSpanExporterBuilder.java index 004c61021ad..c2c631fd04a 100644 --- a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/trace/OtlpGrpcSpanExporterBuilder.java +++ b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/trace/OtlpGrpcSpanExporterBuilder.java @@ -243,8 +243,10 @@ public OtlpGrpcSpanExporterBuilder setMeterProvider( /** * Set the {@link MemoryMode}. If unset, defaults to {@link #DEFAULT_MEMORY_MODE}. * - *

      >When memory mode is {@link MemoryMode#REUSABLE_DATA}, serialization is optimized to reduce + *

      When memory mode is {@link MemoryMode#REUSABLE_DATA}, serialization is optimized to reduce * memory allocation. + * + * @since 1.39.0 */ public OtlpGrpcSpanExporterBuilder setMemoryMode(MemoryMode memoryMode) { requireNonNull(memoryMode, "memoryMode"); diff --git a/exporters/otlp/profiles/build.gradle.kts b/exporters/otlp/profiles/build.gradle.kts index 8b22581662f..a24e2a82739 100644 --- a/exporters/otlp/profiles/build.gradle.kts +++ b/exporters/otlp/profiles/build.gradle.kts @@ -1,6 +1,7 @@ plugins { id("otel.java-conventions") - id("otel.publish-conventions") + // TODO (jack-berg): uncomment when ready to publish + // id("otel.publish-conventions") id("otel.animalsniffer-conventions") } From be25f4ef0cedd42e27f5d88d3bb89606aa20f592 Mon Sep 17 00:00:00 2001 From: OpenTelemetry Bot <107717825+opentelemetrybot@users.noreply.github.com> Date: Fri, 7 Jun 2024 14:05:33 +0200 Subject: [PATCH 440/901] Update version to 1.40.0 (#6507) --- CHANGELOG.md | 2 ++ version.gradle.kts | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2e95ba7035f..d2fce9518f5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,8 @@ ## Unreleased +## Version 1.39.0 (2024-06-07) + ### API #### Incubator diff --git a/version.gradle.kts b/version.gradle.kts index 1706c313297..40c074ac478 100644 --- a/version.gradle.kts +++ b/version.gradle.kts @@ -1,7 +1,7 @@ val snapshot = true allprojects { - var ver = "1.39.0" + var ver = "1.40.0" val release = findProperty("otel.release") if (release != null) { ver += "-" + release From 5ad5b067f0f37db55dbb5d7a9c88695a408b06f7 Mon Sep 17 00:00:00 2001 From: OpenTelemetry Bot <107717825+opentelemetrybot@users.noreply.github.com> Date: Mon, 10 Jun 2024 05:04:13 +0200 Subject: [PATCH 441/901] Post release for version 1.39.0 (#6512) --- README.md | 70 +++++++++---------- .../1.39.0_vs_1.38.0/opentelemetry-api.txt | 2 + .../opentelemetry-context.txt | 2 + .../opentelemetry-exporter-common.txt | 2 + .../opentelemetry-exporter-logging-otlp.txt | 2 + .../opentelemetry-exporter-logging.txt | 2 + .../opentelemetry-exporter-otlp-common.txt | 2 + .../opentelemetry-exporter-otlp.txt | 19 +++++ ...y-exporter-sender-grpc-managed-channel.txt | 2 + .../opentelemetry-exporter-sender-jdk.txt | 2 + .../opentelemetry-exporter-sender-okhttp.txt | 2 + .../opentelemetry-exporter-zipkin.txt | 2 + .../opentelemetry-extension-kotlin.txt | 2 + ...ntelemetry-extension-trace-propagators.txt | 2 + .../opentelemetry-opentracing-shim.txt | 2 + .../opentelemetry-sdk-common.txt | 2 + ...emetry-sdk-extension-autoconfigure-spi.txt | 2 + ...ntelemetry-sdk-extension-autoconfigure.txt | 2 + ...ry-sdk-extension-jaeger-remote-sampler.txt | 2 + .../opentelemetry-sdk-logs.txt | 2 + .../opentelemetry-sdk-metrics.txt | 2 + .../opentelemetry-sdk-testing.txt | 2 + .../opentelemetry-sdk-trace.txt | 2 + .../1.39.0_vs_1.38.0/opentelemetry-sdk.txt | 2 + .../opentelemetry-exporter-otlp.txt | 19 +---- 25 files changed, 99 insertions(+), 53 deletions(-) create mode 100644 docs/apidiffs/1.39.0_vs_1.38.0/opentelemetry-api.txt create mode 100644 docs/apidiffs/1.39.0_vs_1.38.0/opentelemetry-context.txt create mode 100644 docs/apidiffs/1.39.0_vs_1.38.0/opentelemetry-exporter-common.txt create mode 100644 docs/apidiffs/1.39.0_vs_1.38.0/opentelemetry-exporter-logging-otlp.txt create mode 100644 docs/apidiffs/1.39.0_vs_1.38.0/opentelemetry-exporter-logging.txt create mode 100644 docs/apidiffs/1.39.0_vs_1.38.0/opentelemetry-exporter-otlp-common.txt create mode 100644 docs/apidiffs/1.39.0_vs_1.38.0/opentelemetry-exporter-otlp.txt create mode 100644 docs/apidiffs/1.39.0_vs_1.38.0/opentelemetry-exporter-sender-grpc-managed-channel.txt create mode 100644 docs/apidiffs/1.39.0_vs_1.38.0/opentelemetry-exporter-sender-jdk.txt create mode 100644 docs/apidiffs/1.39.0_vs_1.38.0/opentelemetry-exporter-sender-okhttp.txt create mode 100644 docs/apidiffs/1.39.0_vs_1.38.0/opentelemetry-exporter-zipkin.txt create mode 100644 docs/apidiffs/1.39.0_vs_1.38.0/opentelemetry-extension-kotlin.txt create mode 100644 docs/apidiffs/1.39.0_vs_1.38.0/opentelemetry-extension-trace-propagators.txt create mode 100644 docs/apidiffs/1.39.0_vs_1.38.0/opentelemetry-opentracing-shim.txt create mode 100644 docs/apidiffs/1.39.0_vs_1.38.0/opentelemetry-sdk-common.txt create mode 100644 docs/apidiffs/1.39.0_vs_1.38.0/opentelemetry-sdk-extension-autoconfigure-spi.txt create mode 100644 docs/apidiffs/1.39.0_vs_1.38.0/opentelemetry-sdk-extension-autoconfigure.txt create mode 100644 docs/apidiffs/1.39.0_vs_1.38.0/opentelemetry-sdk-extension-jaeger-remote-sampler.txt create mode 100644 docs/apidiffs/1.39.0_vs_1.38.0/opentelemetry-sdk-logs.txt create mode 100644 docs/apidiffs/1.39.0_vs_1.38.0/opentelemetry-sdk-metrics.txt create mode 100644 docs/apidiffs/1.39.0_vs_1.38.0/opentelemetry-sdk-testing.txt create mode 100644 docs/apidiffs/1.39.0_vs_1.38.0/opentelemetry-sdk-trace.txt create mode 100644 docs/apidiffs/1.39.0_vs_1.38.0/opentelemetry-sdk.txt diff --git a/README.md b/README.md index d63671a7260..91f3baecd0b 100644 --- a/README.md +++ b/README.md @@ -104,7 +104,7 @@ dependency versions in sync. io.opentelemetry opentelemetry-bom - 1.38.0 + 1.39.0 pom import @@ -123,7 +123,7 @@ dependency versions in sync. ```groovy dependencies { - implementation platform("io.opentelemetry:opentelemetry-bom:1.38.0") + implementation platform("io.opentelemetry:opentelemetry-bom:1.39.0") implementation('io.opentelemetry:opentelemetry-api') } ``` @@ -132,8 +132,8 @@ Note that if you want to use any artifacts that have not fully stabilized yet (s ```groovy dependencies { - implementation platform("io.opentelemetry:opentelemetry-bom:1.38.0") - implementation platform('io.opentelemetry:opentelemetry-bom-alpha:1.38.0-alpha') + implementation platform("io.opentelemetry:opentelemetry-bom:1.39.0") + implementation platform('io.opentelemetry:opentelemetry-bom-alpha:1.39.0-alpha') implementation('io.opentelemetry:opentelemetry-api') implementation('io.opentelemetry:opentelemetry-exporter-prometheus') @@ -161,7 +161,7 @@ We strongly recommend using our published BOM to keep all dependency versions in io.opentelemetry opentelemetry-bom - 1.39.0-SNAPSHOT + 1.40.0-SNAPSHOT pom import @@ -184,7 +184,7 @@ repositories { } dependencies { - implementation platform("io.opentelemetry:opentelemetry-bom:1.39.0-SNAPSHOT") + implementation platform("io.opentelemetry:opentelemetry-bom:1.40.0-SNAPSHOT") implementation('io.opentelemetry:opentelemetry-api') } ``` @@ -229,66 +229,66 @@ dependency as follows, replacing `{{artifact-id}}` with the value from the "Arti | Component | Description | Artifact ID | Version | Javadoc | |----------------------------------------------|----------------------------------------|---------------------------|-------------------------------------------------------------|---------| -| [Bill of Materials (BOM)](./bom) | Bill of materials for stable artifacts | `opentelemetry-bom` | 1.38.0 | N/A | -| [Alpha Bill of Materials (BOM)](./bom-alpha) | Bill of materials for alpha artifacts | `opentelemetry-bom-alpha` | 1.38.0-alpha | N/A | +| [Bill of Materials (BOM)](./bom) | Bill of materials for stable artifacts | `opentelemetry-bom` | 1.39.0 | N/A | +| [Alpha Bill of Materials (BOM)](./bom-alpha) | Bill of materials for alpha artifacts | `opentelemetry-bom-alpha` | 1.39.0-alpha | N/A | ### API | Component | Description | Artifact ID | Version | Javadoc | |-----------------------------------|--------------------------------------------------------------------------------------|-------------------------------|---------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| [API](./api/all) | OpenTelemetry API, including metrics, traces, baggage, context | `opentelemetry-api` | 1.38.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-api.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-api) | -| [API Incubator](./api/incubator) | API incubator, including pass through propagator, and extended tracer, and Event API | `opentelemetry-api-incubator` | 1.38.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-api-incubator.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-api-incubator) | -| [Context API](./context) | OpenTelemetry context API | `opentelemetry-context` | 1.38.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-context.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-context) | +| [API](./api/all) | OpenTelemetry API, including metrics, traces, baggage, context | `opentelemetry-api` | 1.39.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-api.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-api) | +| [API Incubator](./api/incubator) | API incubator, including pass through propagator, and extended tracer, and Event API | `opentelemetry-api-incubator` | 1.39.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-api-incubator.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-api-incubator) | +| [Context API](./context) | OpenTelemetry context API | `opentelemetry-context` | 1.39.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-context.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-context) | ### API Extensions | Component | Description | Artifact ID | Version | Javadoc | |---------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|---------------------------------------------|-------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| [Kotlin Extension](./extensions/kotlin) | Context extension for coroutines | `opentelemetry-extension-kotlin` | 1.38.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-extension-kotlin.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-extension-kotlin) | -| [Trace Propagators Extension](./extensions/trace-propagators) | Trace propagators, including B3, Jaeger, OT Trace | `opentelemetry-extension-trace-propagators` | 1.38.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-extension-trace-propagators.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-extension-trace-propagators) | +| [Kotlin Extension](./extensions/kotlin) | Context extension for coroutines | `opentelemetry-extension-kotlin` | 1.39.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-extension-kotlin.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-extension-kotlin) | +| [Trace Propagators Extension](./extensions/trace-propagators) | Trace propagators, including B3, Jaeger, OT Trace | `opentelemetry-extension-trace-propagators` | 1.39.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-extension-trace-propagators.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-extension-trace-propagators) | ### SDK | Component | Description | Artifact ID | Version | Javadoc | |------------------------------|--------------------------------------------------------|-----------------------------|---------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| [SDK](./sdk/all) | OpenTelemetry SDK, including metrics, traces, and logs | `opentelemetry-sdk` | 1.38.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk) | -| [Metrics SDK](./sdk/metrics) | OpenTelemetry metrics SDK | `opentelemetry-sdk-metrics` | 1.38.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-metrics.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-metrics) | -| [Trace SDK](./sdk/trace) | OpenTelemetry trace SDK | `opentelemetry-sdk-trace` | 1.38.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-trace.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-trace) | -| [Log SDK](./sdk/logs) | OpenTelemetry log SDK | `opentelemetry-sdk-logs` | 1.38.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-logs.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-logs) | -| [SDK Common](./sdk/common) | Shared SDK components | `opentelemetry-sdk-common` | 1.38.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-common.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-common) | -| [SDK Testing](./sdk/testing) | Components for testing OpenTelemetry instrumentation | `opentelemetry-sdk-testing` | 1.38.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-testing.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-testing) | +| [SDK](./sdk/all) | OpenTelemetry SDK, including metrics, traces, and logs | `opentelemetry-sdk` | 1.39.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk) | +| [Metrics SDK](./sdk/metrics) | OpenTelemetry metrics SDK | `opentelemetry-sdk-metrics` | 1.39.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-metrics.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-metrics) | +| [Trace SDK](./sdk/trace) | OpenTelemetry trace SDK | `opentelemetry-sdk-trace` | 1.39.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-trace.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-trace) | +| [Log SDK](./sdk/logs) | OpenTelemetry log SDK | `opentelemetry-sdk-logs` | 1.39.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-logs.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-logs) | +| [SDK Common](./sdk/common) | Shared SDK components | `opentelemetry-sdk-common` | 1.39.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-common.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-common) | +| [SDK Testing](./sdk/testing) | Components for testing OpenTelemetry instrumentation | `opentelemetry-sdk-testing` | 1.39.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-testing.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-testing) | ### SDK Exporters | Component | Description | Artifact ID | Version | Javadoc | |-----------------------------------------------------------------------|------------------------------------------------------------------------------|-------------------------------------------------------------------------|-------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| [OTLP Exporters](./exporters/otlp/all) | OTLP gRPC & HTTP exporters, including traces, metrics, and logs | `opentelemetry-exporter-otlp` | 1.38.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-otlp.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-otlp) | -| [OTLP Logging Exporters](./exporters/logging-otlp) | Logging exporters in OTLP JSON encoding, including traces, metrics, and logs | `opentelemetry-exporter-logging-otlp` | 1.38.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-logging-otlp.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-logging-otlp) | -| [OTLP Common](./exporters/otlp/common) | Shared OTLP components (internal) | `opentelemetry-exporter-otlp-common` | 1.38.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-otlp-common.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-otlp-common) | -| [Logging Exporter](./exporters/logging) | Logging exporters, including metrics, traces, and logs | `opentelemetry-exporter-logging` | 1.38.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-logging.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-logging) | -| [Zipkin Exporter](./exporters/zipkin) | Zipkin trace exporter | `opentelemetry-exporter-zipkin` | 1.38.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-zipkin.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-zipkin) | -| [Prometheus Exporter](./exporters/prometheus) | Prometheus metric exporter | `opentelemetry-exporter-prometheus` | 1.38.0-alpha | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-prometheus.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-prometheus) | -| [Exporter Common](./exporters/common) | Shared exporter components (internal) | `opentelemetry-exporter-common` | 1.38.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-common.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-common) | -| [OkHttp Sender](./exporters/sender/okhttp) | OkHttp implementation of HttpSender (internal) | `opentelemetry-exporter-sender-okhttp` | 1.38.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-sender-okhttp.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-sender-okhttp) | -| [JDK Sender](./exporters/sender/okhttp) | Java 11+ native HttpClient implementation of HttpSender (internal) | `opentelemetry-exporter-sender-jdk` TODO: remove `-alpha` after release | 1.38.0-alpha | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-sender-jdk.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-sender-jdk) | | -| [gRPC ManagedChannel Sender](./exporters/sender/grpc-managed-channel) | gRPC ManagedChannel implementation of GrpcSender (internal) | `opentelemetry-exporter-sender-grpc-managed-channel` | 1.38.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-sender-grpc-managed-channel.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-sender-grpc-managed-channel) | | +| [OTLP Exporters](./exporters/otlp/all) | OTLP gRPC & HTTP exporters, including traces, metrics, and logs | `opentelemetry-exporter-otlp` | 1.39.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-otlp.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-otlp) | +| [OTLP Logging Exporters](./exporters/logging-otlp) | Logging exporters in OTLP JSON encoding, including traces, metrics, and logs | `opentelemetry-exporter-logging-otlp` | 1.39.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-logging-otlp.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-logging-otlp) | +| [OTLP Common](./exporters/otlp/common) | Shared OTLP components (internal) | `opentelemetry-exporter-otlp-common` | 1.39.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-otlp-common.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-otlp-common) | +| [Logging Exporter](./exporters/logging) | Logging exporters, including metrics, traces, and logs | `opentelemetry-exporter-logging` | 1.39.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-logging.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-logging) | +| [Zipkin Exporter](./exporters/zipkin) | Zipkin trace exporter | `opentelemetry-exporter-zipkin` | 1.39.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-zipkin.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-zipkin) | +| [Prometheus Exporter](./exporters/prometheus) | Prometheus metric exporter | `opentelemetry-exporter-prometheus` | 1.39.0-alpha | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-prometheus.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-prometheus) | +| [Exporter Common](./exporters/common) | Shared exporter components (internal) | `opentelemetry-exporter-common` | 1.39.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-common.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-common) | +| [OkHttp Sender](./exporters/sender/okhttp) | OkHttp implementation of HttpSender (internal) | `opentelemetry-exporter-sender-okhttp` | 1.39.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-sender-okhttp.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-sender-okhttp) | +| [JDK Sender](./exporters/sender/okhttp) | Java 11+ native HttpClient implementation of HttpSender (internal) | `opentelemetry-exporter-sender-jdk` TODO: remove `-alpha` after release | 1.39.0-alpha | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-sender-jdk.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-sender-jdk) | | +| [gRPC ManagedChannel Sender](./exporters/sender/grpc-managed-channel) | gRPC ManagedChannel implementation of GrpcSender (internal) | `opentelemetry-exporter-sender-grpc-managed-channel` | 1.39.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-sender-grpc-managed-channel.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-sender-grpc-managed-channel) | | ### SDK Extensions | Component | Description | Artifact ID | Version | Javadoc | |-------------------------------------------------------------------------------|------------------------------------------------------------------------------------|-----------------------------------------------------|-------------------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| [SDK Autoconfigure](./sdk-extensions/autoconfigure) | Autoconfigure OpenTelemetry SDK from env vars, system properties, and SPI | `opentelemetry-sdk-extension-autoconfigure` | 1.38.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-extension-autoconfigure.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-extension-autoconfigure) | -| [SDK Autoconfigure SPI](./sdk-extensions/autoconfigure-spi) | Service Provider Interface (SPI) definitions for autoconfigure | `opentelemetry-sdk-extension-autoconfigure-spi` | 1.38.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-extension-autoconfigure-spi.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-extension-autoconfigure-spi) | -| [SDK Jaeger Remote Sampler Extension](./sdk-extensions/jaeger-remote-sampler) | Sampler which obtains sampling configuration from remote Jaeger server | `opentelemetry-sdk-extension-jaeger-remote-sampler` | 1.38.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-extension-jaeger-remote-sampler.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-extension-jaeger-remote-sampler) | -| [SDK Incubator](./sdk-extensions/incubator) | SDK incubator, including YAML based view configuration, LeakDetectingSpanProcessor | `opentelemetry-sdk-extension-incubator` | 1.38.0-alpha | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-extension-incubator.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-extension-incubator) | +| [SDK Autoconfigure](./sdk-extensions/autoconfigure) | Autoconfigure OpenTelemetry SDK from env vars, system properties, and SPI | `opentelemetry-sdk-extension-autoconfigure` | 1.39.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-extension-autoconfigure.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-extension-autoconfigure) | +| [SDK Autoconfigure SPI](./sdk-extensions/autoconfigure-spi) | Service Provider Interface (SPI) definitions for autoconfigure | `opentelemetry-sdk-extension-autoconfigure-spi` | 1.39.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-extension-autoconfigure-spi.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-extension-autoconfigure-spi) | +| [SDK Jaeger Remote Sampler Extension](./sdk-extensions/jaeger-remote-sampler) | Sampler which obtains sampling configuration from remote Jaeger server | `opentelemetry-sdk-extension-jaeger-remote-sampler` | 1.39.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-extension-jaeger-remote-sampler.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-extension-jaeger-remote-sampler) | +| [SDK Incubator](./sdk-extensions/incubator) | SDK incubator, including YAML based view configuration, LeakDetectingSpanProcessor | `opentelemetry-sdk-extension-incubator` | 1.39.0-alpha | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-extension-incubator.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-extension-incubator) | ### Shims | Component | Description | Artifact ID | Version | Javadoc | |----------------------------------------|--------------------------------------------------------------|----------------------------------|-------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| [OpenCensus Shim](./opencensus-shim) | Bridge opencensus metrics into the OpenTelemetry metrics SDK | `opentelemetry-opencensus-shim` | 1.38.0-alpha | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-opencensus-shim.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-opencensus-shim) | -| [OpenTracing Shim](./opentracing-shim) | Bridge opentracing spans into the OpenTelemetry trace API | `opentelemetry-opentracing-shim` | 1.38.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-opentracing-shim.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-opentracing-shim) | +| [OpenCensus Shim](./opencensus-shim) | Bridge opencensus metrics into the OpenTelemetry metrics SDK | `opentelemetry-opencensus-shim` | 1.39.0-alpha | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-opencensus-shim.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-opencensus-shim) | +| [OpenTracing Shim](./opentracing-shim) | Bridge opentracing spans into the OpenTelemetry trace API | `opentelemetry-opentracing-shim` | 1.39.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-opentracing-shim.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-opentracing-shim) | ## Contributing diff --git a/docs/apidiffs/1.39.0_vs_1.38.0/opentelemetry-api.txt b/docs/apidiffs/1.39.0_vs_1.38.0/opentelemetry-api.txt new file mode 100644 index 00000000000..df26146497b --- /dev/null +++ b/docs/apidiffs/1.39.0_vs_1.38.0/opentelemetry-api.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of against +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.39.0_vs_1.38.0/opentelemetry-context.txt b/docs/apidiffs/1.39.0_vs_1.38.0/opentelemetry-context.txt new file mode 100644 index 00000000000..df26146497b --- /dev/null +++ b/docs/apidiffs/1.39.0_vs_1.38.0/opentelemetry-context.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of against +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.39.0_vs_1.38.0/opentelemetry-exporter-common.txt b/docs/apidiffs/1.39.0_vs_1.38.0/opentelemetry-exporter-common.txt new file mode 100644 index 00000000000..df26146497b --- /dev/null +++ b/docs/apidiffs/1.39.0_vs_1.38.0/opentelemetry-exporter-common.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of against +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.39.0_vs_1.38.0/opentelemetry-exporter-logging-otlp.txt b/docs/apidiffs/1.39.0_vs_1.38.0/opentelemetry-exporter-logging-otlp.txt new file mode 100644 index 00000000000..df26146497b --- /dev/null +++ b/docs/apidiffs/1.39.0_vs_1.38.0/opentelemetry-exporter-logging-otlp.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of against +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.39.0_vs_1.38.0/opentelemetry-exporter-logging.txt b/docs/apidiffs/1.39.0_vs_1.38.0/opentelemetry-exporter-logging.txt new file mode 100644 index 00000000000..df26146497b --- /dev/null +++ b/docs/apidiffs/1.39.0_vs_1.38.0/opentelemetry-exporter-logging.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of against +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.39.0_vs_1.38.0/opentelemetry-exporter-otlp-common.txt b/docs/apidiffs/1.39.0_vs_1.38.0/opentelemetry-exporter-otlp-common.txt new file mode 100644 index 00000000000..df26146497b --- /dev/null +++ b/docs/apidiffs/1.39.0_vs_1.38.0/opentelemetry-exporter-otlp-common.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of against +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.39.0_vs_1.38.0/opentelemetry-exporter-otlp.txt b/docs/apidiffs/1.39.0_vs_1.38.0/opentelemetry-exporter-otlp.txt new file mode 100644 index 00000000000..35bb9f3e97e --- /dev/null +++ b/docs/apidiffs/1.39.0_vs_1.38.0/opentelemetry-exporter-otlp.txt @@ -0,0 +1,19 @@ +Comparing source compatibility of against +*** MODIFIED CLASS: PUBLIC FINAL io.opentelemetry.exporter.otlp.http.logs.OtlpHttpLogRecordExporterBuilder (not serializable) + === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 + *** MODIFIED METHOD: PUBLIC (<- PACKAGE_PROTECTED) io.opentelemetry.exporter.otlp.http.logs.OtlpHttpLogRecordExporterBuilder setMemoryMode(io.opentelemetry.sdk.common.export.MemoryMode) +*** MODIFIED CLASS: PUBLIC FINAL io.opentelemetry.exporter.otlp.http.metrics.OtlpHttpMetricExporterBuilder (not serializable) + === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 + *** MODIFIED METHOD: PUBLIC (<- PACKAGE_PROTECTED) io.opentelemetry.exporter.otlp.http.metrics.OtlpHttpMetricExporterBuilder setMemoryMode(io.opentelemetry.sdk.common.export.MemoryMode) +*** MODIFIED CLASS: PUBLIC FINAL io.opentelemetry.exporter.otlp.http.trace.OtlpHttpSpanExporterBuilder (not serializable) + === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 + *** MODIFIED METHOD: PUBLIC (<- PACKAGE_PROTECTED) io.opentelemetry.exporter.otlp.http.trace.OtlpHttpSpanExporterBuilder setMemoryMode(io.opentelemetry.sdk.common.export.MemoryMode) +*** MODIFIED CLASS: PUBLIC FINAL io.opentelemetry.exporter.otlp.logs.OtlpGrpcLogRecordExporterBuilder (not serializable) + === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 + *** MODIFIED METHOD: PUBLIC (<- PACKAGE_PROTECTED) io.opentelemetry.exporter.otlp.logs.OtlpGrpcLogRecordExporterBuilder setMemoryMode(io.opentelemetry.sdk.common.export.MemoryMode) +*** MODIFIED CLASS: PUBLIC FINAL io.opentelemetry.exporter.otlp.metrics.OtlpGrpcMetricExporterBuilder (not serializable) + === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 + *** MODIFIED METHOD: PUBLIC (<- PACKAGE_PROTECTED) io.opentelemetry.exporter.otlp.metrics.OtlpGrpcMetricExporterBuilder setMemoryMode(io.opentelemetry.sdk.common.export.MemoryMode) +*** MODIFIED CLASS: PUBLIC FINAL io.opentelemetry.exporter.otlp.trace.OtlpGrpcSpanExporterBuilder (not serializable) + === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 + *** MODIFIED METHOD: PUBLIC (<- PACKAGE_PROTECTED) io.opentelemetry.exporter.otlp.trace.OtlpGrpcSpanExporterBuilder setMemoryMode(io.opentelemetry.sdk.common.export.MemoryMode) diff --git a/docs/apidiffs/1.39.0_vs_1.38.0/opentelemetry-exporter-sender-grpc-managed-channel.txt b/docs/apidiffs/1.39.0_vs_1.38.0/opentelemetry-exporter-sender-grpc-managed-channel.txt new file mode 100644 index 00000000000..df26146497b --- /dev/null +++ b/docs/apidiffs/1.39.0_vs_1.38.0/opentelemetry-exporter-sender-grpc-managed-channel.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of against +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.39.0_vs_1.38.0/opentelemetry-exporter-sender-jdk.txt b/docs/apidiffs/1.39.0_vs_1.38.0/opentelemetry-exporter-sender-jdk.txt new file mode 100644 index 00000000000..df26146497b --- /dev/null +++ b/docs/apidiffs/1.39.0_vs_1.38.0/opentelemetry-exporter-sender-jdk.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of against +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.39.0_vs_1.38.0/opentelemetry-exporter-sender-okhttp.txt b/docs/apidiffs/1.39.0_vs_1.38.0/opentelemetry-exporter-sender-okhttp.txt new file mode 100644 index 00000000000..df26146497b --- /dev/null +++ b/docs/apidiffs/1.39.0_vs_1.38.0/opentelemetry-exporter-sender-okhttp.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of against +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.39.0_vs_1.38.0/opentelemetry-exporter-zipkin.txt b/docs/apidiffs/1.39.0_vs_1.38.0/opentelemetry-exporter-zipkin.txt new file mode 100644 index 00000000000..df26146497b --- /dev/null +++ b/docs/apidiffs/1.39.0_vs_1.38.0/opentelemetry-exporter-zipkin.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of against +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.39.0_vs_1.38.0/opentelemetry-extension-kotlin.txt b/docs/apidiffs/1.39.0_vs_1.38.0/opentelemetry-extension-kotlin.txt new file mode 100644 index 00000000000..df26146497b --- /dev/null +++ b/docs/apidiffs/1.39.0_vs_1.38.0/opentelemetry-extension-kotlin.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of against +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.39.0_vs_1.38.0/opentelemetry-extension-trace-propagators.txt b/docs/apidiffs/1.39.0_vs_1.38.0/opentelemetry-extension-trace-propagators.txt new file mode 100644 index 00000000000..df26146497b --- /dev/null +++ b/docs/apidiffs/1.39.0_vs_1.38.0/opentelemetry-extension-trace-propagators.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of against +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.39.0_vs_1.38.0/opentelemetry-opentracing-shim.txt b/docs/apidiffs/1.39.0_vs_1.38.0/opentelemetry-opentracing-shim.txt new file mode 100644 index 00000000000..df26146497b --- /dev/null +++ b/docs/apidiffs/1.39.0_vs_1.38.0/opentelemetry-opentracing-shim.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of against +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.39.0_vs_1.38.0/opentelemetry-sdk-common.txt b/docs/apidiffs/1.39.0_vs_1.38.0/opentelemetry-sdk-common.txt new file mode 100644 index 00000000000..df26146497b --- /dev/null +++ b/docs/apidiffs/1.39.0_vs_1.38.0/opentelemetry-sdk-common.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of against +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.39.0_vs_1.38.0/opentelemetry-sdk-extension-autoconfigure-spi.txt b/docs/apidiffs/1.39.0_vs_1.38.0/opentelemetry-sdk-extension-autoconfigure-spi.txt new file mode 100644 index 00000000000..df26146497b --- /dev/null +++ b/docs/apidiffs/1.39.0_vs_1.38.0/opentelemetry-sdk-extension-autoconfigure-spi.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of against +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.39.0_vs_1.38.0/opentelemetry-sdk-extension-autoconfigure.txt b/docs/apidiffs/1.39.0_vs_1.38.0/opentelemetry-sdk-extension-autoconfigure.txt new file mode 100644 index 00000000000..df26146497b --- /dev/null +++ b/docs/apidiffs/1.39.0_vs_1.38.0/opentelemetry-sdk-extension-autoconfigure.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of against +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.39.0_vs_1.38.0/opentelemetry-sdk-extension-jaeger-remote-sampler.txt b/docs/apidiffs/1.39.0_vs_1.38.0/opentelemetry-sdk-extension-jaeger-remote-sampler.txt new file mode 100644 index 00000000000..df26146497b --- /dev/null +++ b/docs/apidiffs/1.39.0_vs_1.38.0/opentelemetry-sdk-extension-jaeger-remote-sampler.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of against +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.39.0_vs_1.38.0/opentelemetry-sdk-logs.txt b/docs/apidiffs/1.39.0_vs_1.38.0/opentelemetry-sdk-logs.txt new file mode 100644 index 00000000000..df26146497b --- /dev/null +++ b/docs/apidiffs/1.39.0_vs_1.38.0/opentelemetry-sdk-logs.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of against +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.39.0_vs_1.38.0/opentelemetry-sdk-metrics.txt b/docs/apidiffs/1.39.0_vs_1.38.0/opentelemetry-sdk-metrics.txt new file mode 100644 index 00000000000..df26146497b --- /dev/null +++ b/docs/apidiffs/1.39.0_vs_1.38.0/opentelemetry-sdk-metrics.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of against +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.39.0_vs_1.38.0/opentelemetry-sdk-testing.txt b/docs/apidiffs/1.39.0_vs_1.38.0/opentelemetry-sdk-testing.txt new file mode 100644 index 00000000000..df26146497b --- /dev/null +++ b/docs/apidiffs/1.39.0_vs_1.38.0/opentelemetry-sdk-testing.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of against +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.39.0_vs_1.38.0/opentelemetry-sdk-trace.txt b/docs/apidiffs/1.39.0_vs_1.38.0/opentelemetry-sdk-trace.txt new file mode 100644 index 00000000000..df26146497b --- /dev/null +++ b/docs/apidiffs/1.39.0_vs_1.38.0/opentelemetry-sdk-trace.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of against +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.39.0_vs_1.38.0/opentelemetry-sdk.txt b/docs/apidiffs/1.39.0_vs_1.38.0/opentelemetry-sdk.txt new file mode 100644 index 00000000000..df26146497b --- /dev/null +++ b/docs/apidiffs/1.39.0_vs_1.38.0/opentelemetry-sdk.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of against +No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-otlp.txt b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-otlp.txt index 35bb9f3e97e..df26146497b 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-otlp.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-otlp.txt @@ -1,19 +1,2 @@ Comparing source compatibility of against -*** MODIFIED CLASS: PUBLIC FINAL io.opentelemetry.exporter.otlp.http.logs.OtlpHttpLogRecordExporterBuilder (not serializable) - === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 - *** MODIFIED METHOD: PUBLIC (<- PACKAGE_PROTECTED) io.opentelemetry.exporter.otlp.http.logs.OtlpHttpLogRecordExporterBuilder setMemoryMode(io.opentelemetry.sdk.common.export.MemoryMode) -*** MODIFIED CLASS: PUBLIC FINAL io.opentelemetry.exporter.otlp.http.metrics.OtlpHttpMetricExporterBuilder (not serializable) - === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 - *** MODIFIED METHOD: PUBLIC (<- PACKAGE_PROTECTED) io.opentelemetry.exporter.otlp.http.metrics.OtlpHttpMetricExporterBuilder setMemoryMode(io.opentelemetry.sdk.common.export.MemoryMode) -*** MODIFIED CLASS: PUBLIC FINAL io.opentelemetry.exporter.otlp.http.trace.OtlpHttpSpanExporterBuilder (not serializable) - === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 - *** MODIFIED METHOD: PUBLIC (<- PACKAGE_PROTECTED) io.opentelemetry.exporter.otlp.http.trace.OtlpHttpSpanExporterBuilder setMemoryMode(io.opentelemetry.sdk.common.export.MemoryMode) -*** MODIFIED CLASS: PUBLIC FINAL io.opentelemetry.exporter.otlp.logs.OtlpGrpcLogRecordExporterBuilder (not serializable) - === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 - *** MODIFIED METHOD: PUBLIC (<- PACKAGE_PROTECTED) io.opentelemetry.exporter.otlp.logs.OtlpGrpcLogRecordExporterBuilder setMemoryMode(io.opentelemetry.sdk.common.export.MemoryMode) -*** MODIFIED CLASS: PUBLIC FINAL io.opentelemetry.exporter.otlp.metrics.OtlpGrpcMetricExporterBuilder (not serializable) - === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 - *** MODIFIED METHOD: PUBLIC (<- PACKAGE_PROTECTED) io.opentelemetry.exporter.otlp.metrics.OtlpGrpcMetricExporterBuilder setMemoryMode(io.opentelemetry.sdk.common.export.MemoryMode) -*** MODIFIED CLASS: PUBLIC FINAL io.opentelemetry.exporter.otlp.trace.OtlpGrpcSpanExporterBuilder (not serializable) - === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 - *** MODIFIED METHOD: PUBLIC (<- PACKAGE_PROTECTED) io.opentelemetry.exporter.otlp.trace.OtlpGrpcSpanExporterBuilder setMemoryMode(io.opentelemetry.sdk.common.export.MemoryMode) +No changes. \ No newline at end of file From 7ee367a57f00205865b8f894e6317d92302d91c6 Mon Sep 17 00:00:00 2001 From: Shelby Huang <48885776+huange7@users.noreply.github.com> Date: Tue, 11 Jun 2024 02:34:37 +0800 Subject: [PATCH 442/901] Fix the JMH task execution failure. (#6495) --- sdk/trace/build.gradle.kts | 7 +++++++ .../java/io/opentelemetry/sdk/trace/ExporterBenchmark.java | 2 +- .../io/opentelemetry/sdk/trace/SpanPipelineBenchmark.java | 2 +- 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/sdk/trace/build.gradle.kts b/sdk/trace/build.gradle.kts index 34690eaeeca..2dc5c769508 100644 --- a/sdk/trace/build.gradle.kts +++ b/sdk/trace/build.gradle.kts @@ -50,6 +50,13 @@ dependencies { jmh(project(":exporters:otlp:common")) { isTransitive = false } + jmh(project(":exporters:common")) { + isTransitive = false + } + jmh(project(":exporters:sender:okhttp")) + jmh(project(":sdk-extensions:autoconfigure-spi")) { + isTransitive = false + } jmh("io.opentelemetry.proto:opentelemetry-proto") jmh("com.google.guava:guava") diff --git a/sdk/trace/src/jmh/java/io/opentelemetry/sdk/trace/ExporterBenchmark.java b/sdk/trace/src/jmh/java/io/opentelemetry/sdk/trace/ExporterBenchmark.java index 19ec7edfdbd..72abbe0541d 100644 --- a/sdk/trace/src/jmh/java/io/opentelemetry/sdk/trace/ExporterBenchmark.java +++ b/sdk/trace/src/jmh/java/io/opentelemetry/sdk/trace/ExporterBenchmark.java @@ -36,7 +36,7 @@ private ExporterBenchmark() {} @State(Scope.Benchmark) public abstract static class AbstractProcessorBenchmark { private static final DockerImageName OTLP_COLLECTOR_IMAGE = - DockerImageName.parse("otel/opentelemetry-collector-dev:latest"); + DockerImageName.parse("otel/opentelemetry-collector-contrib:latest"); protected static final int OTLP_PORT = 5678; private static final int HEALTH_CHECK_PORT = 13133; protected SdkSpanBuilder sdkSpanBuilder; diff --git a/sdk/trace/src/jmh/java/io/opentelemetry/sdk/trace/SpanPipelineBenchmark.java b/sdk/trace/src/jmh/java/io/opentelemetry/sdk/trace/SpanPipelineBenchmark.java index 03684d1a348..cbb9ee97b50 100644 --- a/sdk/trace/src/jmh/java/io/opentelemetry/sdk/trace/SpanPipelineBenchmark.java +++ b/sdk/trace/src/jmh/java/io/opentelemetry/sdk/trace/SpanPipelineBenchmark.java @@ -38,7 +38,7 @@ private SpanPipelineBenchmark() {} @State(Scope.Benchmark) public abstract static class AbstractProcessorBenchmark { private static final DockerImageName OTLP_COLLECTOR_IMAGE = - DockerImageName.parse("otel/opentelemetry-collector-dev:latest"); + DockerImageName.parse("otel/opentelemetry-collector-contrib:latest"); private static final int EXPOSED_PORT = 5678; private static final int HEALTH_CHECK_PORT = 13133; private Tracer tracer; From 4680146024b83892c14e5df4e08158f1f602c75c Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 11 Jun 2024 10:29:56 -0700 Subject: [PATCH 443/901] Update dependency io.netty:netty-bom to v4.1.111.Final (#6515) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- dependencyManagement/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index ce3125859e9..f0a4d801bc4 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -15,7 +15,7 @@ val DEPENDENCY_BOMS = listOf( "com.squareup.okhttp3:okhttp-bom:4.12.0", "com.squareup.okio:okio-bom:3.9.0", // applies to transitive dependencies of okhttp "io.grpc:grpc-bom:1.64.0", - "io.netty:netty-bom:4.1.110.Final", + "io.netty:netty-bom:4.1.111.Final", "io.zipkin.brave:brave-bom:6.0.3", "io.zipkin.reporter2:zipkin-reporter-bom:3.4.0", "org.assertj:assertj-bom:3.26.0", From a686280aaf839f562ec33a4586ac6fd7018a9838 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 12 Jun 2024 09:02:42 -0700 Subject: [PATCH 444/901] Update dependency com.linecorp.armeria:armeria-bom to v1.29.0 (#6516) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- dependencyManagement/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index f0a4d801bc4..735ac89c56e 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -11,7 +11,7 @@ val DEPENDENCY_BOMS = listOf( "com.fasterxml.jackson:jackson-bom:2.17.1", "com.google.guava:guava-bom:33.2.1-jre", "com.google.protobuf:protobuf-bom:3.25.3", - "com.linecorp.armeria:armeria-bom:1.28.4", + "com.linecorp.armeria:armeria-bom:1.29.0", "com.squareup.okhttp3:okhttp-bom:4.12.0", "com.squareup.okio:okio-bom:3.9.0", // applies to transitive dependencies of okhttp "io.grpc:grpc-bom:1.64.0", From cff8b81fd66c9f8ed4d4914128487f91cc990912 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 15 Jun 2024 10:47:39 -0700 Subject: [PATCH 445/901] Update plugin com.gradle.develocity to v3.17.5 (#6519) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- settings.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/settings.gradle.kts b/settings.gradle.kts index f919ccbefa4..f6a1bd2c7c2 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -1,7 +1,7 @@ pluginManagement { plugins { id("com.github.johnrengelman.shadow") version "8.1.1" - id("com.gradle.develocity") version "3.17.4" + id("com.gradle.develocity") version "3.17.5" id("de.undercouch.download") version "5.6.0" id("org.jsonschema2pojo") version "1.2.1" id("io.github.gradle-nexus.publish-plugin") version "2.0.0" From 0bc911dc0ad1fee535d0ae3b066496e9e4f4b7b6 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 15 Jun 2024 10:48:13 -0700 Subject: [PATCH 446/901] Update gradle/actions action to v3.4.1 (#6523) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/gradle-wrapper-validation.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/gradle-wrapper-validation.yml b/.github/workflows/gradle-wrapper-validation.yml index 7ae0a27e360..7de11e93878 100644 --- a/.github/workflows/gradle-wrapper-validation.yml +++ b/.github/workflows/gradle-wrapper-validation.yml @@ -13,4 +13,4 @@ jobs: steps: - uses: actions/checkout@v4 - - uses: gradle/actions/wrapper-validation@v3.3.2 + - uses: gradle/actions/wrapper-validation@v3.4.1 From 0750660f6f0ab4130b81647921b21dafd48cf417 Mon Sep 17 00:00:00 2001 From: Helen <56097766+heyams@users.noreply.github.com> Date: Sat, 15 Jun 2024 10:49:21 -0700 Subject: [PATCH 447/901] Fix #6499 Update dependency me.champeau.gradle:japicmp-gradle-plugin to v0.4.3 (#6522) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- buildSrc/build.gradle.kts | 2 +- docs/apidiffs/current_vs_latest/opentelemetry-api.txt | 2 +- docs/apidiffs/current_vs_latest/opentelemetry-context.txt | 2 +- .../current_vs_latest/opentelemetry-exporter-common.txt | 2 +- .../current_vs_latest/opentelemetry-exporter-logging-otlp.txt | 2 +- .../current_vs_latest/opentelemetry-exporter-logging.txt | 2 +- .../current_vs_latest/opentelemetry-exporter-otlp-common.txt | 2 +- docs/apidiffs/current_vs_latest/opentelemetry-exporter-otlp.txt | 2 +- .../opentelemetry-exporter-sender-grpc-managed-channel.txt | 2 +- .../current_vs_latest/opentelemetry-exporter-sender-jdk.txt | 2 +- .../current_vs_latest/opentelemetry-exporter-sender-okhttp.txt | 2 +- .../current_vs_latest/opentelemetry-exporter-zipkin.txt | 2 +- .../current_vs_latest/opentelemetry-extension-kotlin.txt | 2 +- .../opentelemetry-extension-trace-propagators.txt | 2 +- .../current_vs_latest/opentelemetry-opentracing-shim.txt | 2 +- docs/apidiffs/current_vs_latest/opentelemetry-sdk-common.txt | 2 +- .../opentelemetry-sdk-extension-autoconfigure-spi.txt | 2 +- .../opentelemetry-sdk-extension-autoconfigure.txt | 2 +- .../opentelemetry-sdk-extension-jaeger-remote-sampler.txt | 2 +- docs/apidiffs/current_vs_latest/opentelemetry-sdk-logs.txt | 2 +- docs/apidiffs/current_vs_latest/opentelemetry-sdk-metrics.txt | 2 +- docs/apidiffs/current_vs_latest/opentelemetry-sdk-testing.txt | 2 +- docs/apidiffs/current_vs_latest/opentelemetry-sdk-trace.txt | 2 +- docs/apidiffs/current_vs_latest/opentelemetry-sdk.txt | 2 +- 24 files changed, 24 insertions(+), 24 deletions(-) diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts index d422f423107..68542ea0b13 100644 --- a/buildSrc/build.gradle.kts +++ b/buildSrc/build.gradle.kts @@ -61,7 +61,7 @@ dependencies { implementation("com.squareup.wire:wire-gradle-plugin") implementation("gradle.plugin.com.google.protobuf:protobuf-gradle-plugin:0.8.18") implementation("gradle.plugin.io.morethan.jmhreport:gradle-jmh-report:0.9.6") - implementation("me.champeau.gradle:japicmp-gradle-plugin:0.4.2") + implementation("me.champeau.gradle:japicmp-gradle-plugin:0.4.3") implementation("me.champeau.jmh:jmh-gradle-plugin:0.7.2") implementation("net.ltgt.gradle:gradle-errorprone-plugin:4.0.0") implementation("net.ltgt.gradle:gradle-nullaway-plugin:2.0.0") diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-api.txt b/docs/apidiffs/current_vs_latest/opentelemetry-api.txt index df26146497b..e32147f2856 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-api.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-api.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of against +Comparing source compatibility of opentelemetry-api-1.40.0-SNAPSHOT.jar against opentelemetry-api-1.39.0.jar No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-context.txt b/docs/apidiffs/current_vs_latest/opentelemetry-context.txt index df26146497b..dcfcd70c5c3 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-context.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-context.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of against +Comparing source compatibility of opentelemetry-context-1.40.0-SNAPSHOT.jar against opentelemetry-context-1.39.0.jar No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-common.txt b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-common.txt index df26146497b..6d63e3d8981 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-common.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-common.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of against +Comparing source compatibility of opentelemetry-exporter-common-1.40.0-SNAPSHOT.jar against opentelemetry-exporter-common-1.39.0.jar No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-logging-otlp.txt b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-logging-otlp.txt index df26146497b..5c1ffa724e1 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-logging-otlp.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-logging-otlp.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of against +Comparing source compatibility of opentelemetry-exporter-logging-otlp-1.40.0-SNAPSHOT.jar against opentelemetry-exporter-logging-otlp-1.39.0.jar No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-logging.txt b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-logging.txt index df26146497b..026e973bff4 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-logging.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-logging.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of against +Comparing source compatibility of opentelemetry-exporter-logging-1.40.0-SNAPSHOT.jar against opentelemetry-exporter-logging-1.39.0.jar No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-otlp-common.txt b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-otlp-common.txt index df26146497b..32022b0aa4a 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-otlp-common.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-otlp-common.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of against +Comparing source compatibility of opentelemetry-exporter-otlp-common-1.40.0-SNAPSHOT.jar against opentelemetry-exporter-otlp-common-1.39.0.jar No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-otlp.txt b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-otlp.txt index df26146497b..4fd7c4935c7 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-otlp.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-otlp.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of against +Comparing source compatibility of opentelemetry-exporter-otlp-1.40.0-SNAPSHOT.jar against opentelemetry-exporter-otlp-1.39.0.jar No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-sender-grpc-managed-channel.txt b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-sender-grpc-managed-channel.txt index df26146497b..14420c0010c 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-sender-grpc-managed-channel.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-sender-grpc-managed-channel.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of against +Comparing source compatibility of opentelemetry-exporter-sender-grpc-managed-channel-1.40.0-SNAPSHOT.jar against opentelemetry-exporter-sender-grpc-managed-channel-1.39.0.jar No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-sender-jdk.txt b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-sender-jdk.txt index df26146497b..899cdf42152 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-sender-jdk.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-sender-jdk.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of against +Comparing source compatibility of opentelemetry-exporter-sender-jdk-1.40.0-SNAPSHOT.jar against opentelemetry-exporter-sender-jdk-1.39.0.jar No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-sender-okhttp.txt b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-sender-okhttp.txt index df26146497b..da7771432b3 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-sender-okhttp.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-sender-okhttp.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of against +Comparing source compatibility of opentelemetry-exporter-sender-okhttp-1.40.0-SNAPSHOT.jar against opentelemetry-exporter-sender-okhttp-1.39.0.jar No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-zipkin.txt b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-zipkin.txt index df26146497b..68035c9761c 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-zipkin.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-zipkin.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of against +Comparing source compatibility of opentelemetry-exporter-zipkin-1.40.0-SNAPSHOT.jar against opentelemetry-exporter-zipkin-1.39.0.jar No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-extension-kotlin.txt b/docs/apidiffs/current_vs_latest/opentelemetry-extension-kotlin.txt index df26146497b..814a922f02f 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-extension-kotlin.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-extension-kotlin.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of against +Comparing source compatibility of opentelemetry-extension-kotlin-1.40.0-SNAPSHOT.jar against opentelemetry-extension-kotlin-1.39.0.jar No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-extension-trace-propagators.txt b/docs/apidiffs/current_vs_latest/opentelemetry-extension-trace-propagators.txt index df26146497b..4546f8f90b3 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-extension-trace-propagators.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-extension-trace-propagators.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of against +Comparing source compatibility of opentelemetry-extension-trace-propagators-1.40.0-SNAPSHOT.jar against opentelemetry-extension-trace-propagators-1.39.0.jar No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-opentracing-shim.txt b/docs/apidiffs/current_vs_latest/opentelemetry-opentracing-shim.txt index df26146497b..bfb3ff8aa63 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-opentracing-shim.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-opentracing-shim.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of against +Comparing source compatibility of opentelemetry-opentracing-shim-1.40.0-SNAPSHOT.jar against opentelemetry-opentracing-shim-1.39.0.jar No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-common.txt b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-common.txt index df26146497b..3d7fc037c27 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-common.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-common.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of against +Comparing source compatibility of opentelemetry-sdk-common-1.40.0-SNAPSHOT.jar against opentelemetry-sdk-common-1.39.0.jar No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-extension-autoconfigure-spi.txt b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-extension-autoconfigure-spi.txt index df26146497b..99eb60df11e 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-extension-autoconfigure-spi.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-extension-autoconfigure-spi.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of against +Comparing source compatibility of opentelemetry-sdk-extension-autoconfigure-spi-1.40.0-SNAPSHOT.jar against opentelemetry-sdk-extension-autoconfigure-spi-1.39.0.jar No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-extension-autoconfigure.txt b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-extension-autoconfigure.txt index df26146497b..7db67fe5a50 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-extension-autoconfigure.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-extension-autoconfigure.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of against +Comparing source compatibility of opentelemetry-sdk-extension-autoconfigure-1.40.0-SNAPSHOT.jar against opentelemetry-sdk-extension-autoconfigure-1.39.0.jar No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-extension-jaeger-remote-sampler.txt b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-extension-jaeger-remote-sampler.txt index df26146497b..52e63913bff 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-extension-jaeger-remote-sampler.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-extension-jaeger-remote-sampler.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of against +Comparing source compatibility of opentelemetry-sdk-extension-jaeger-remote-sampler-1.40.0-SNAPSHOT.jar against opentelemetry-sdk-extension-jaeger-remote-sampler-1.39.0.jar No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-logs.txt b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-logs.txt index df26146497b..3c3dfe967a3 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-logs.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-logs.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of against +Comparing source compatibility of opentelemetry-sdk-logs-1.40.0-SNAPSHOT.jar against opentelemetry-sdk-logs-1.39.0.jar No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-metrics.txt b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-metrics.txt index df26146497b..9d61424af3a 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-metrics.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-metrics.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of against +Comparing source compatibility of opentelemetry-sdk-metrics-1.40.0-SNAPSHOT.jar against opentelemetry-sdk-metrics-1.39.0.jar No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-testing.txt b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-testing.txt index df26146497b..3170b05e569 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-testing.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-testing.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of against +Comparing source compatibility of opentelemetry-sdk-testing-1.40.0-SNAPSHOT.jar against opentelemetry-sdk-testing-1.39.0.jar No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-trace.txt b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-trace.txt index df26146497b..e7aa3363bcb 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-trace.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-trace.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of against +Comparing source compatibility of opentelemetry-sdk-trace-1.40.0-SNAPSHOT.jar against opentelemetry-sdk-trace-1.39.0.jar No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-sdk.txt b/docs/apidiffs/current_vs_latest/opentelemetry-sdk.txt index df26146497b..f9bf7be8ef4 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-sdk.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-sdk.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of against +Comparing source compatibility of opentelemetry-sdk-1.40.0-SNAPSHOT.jar against opentelemetry-sdk-1.39.0.jar No changes. \ No newline at end of file From b748a1dbafcfa1ed0b8094d18a6f6aad3bc07f2e Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 18 Jun 2024 19:31:34 -0700 Subject: [PATCH 448/901] Update docker/build-push-action action to v6 (#6525) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/build-tracecontext-testsuite.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build-tracecontext-testsuite.yml b/.github/workflows/build-tracecontext-testsuite.yml index abded031b00..3470424f594 100644 --- a/.github/workflows/build-tracecontext-testsuite.yml +++ b/.github/workflows/build-tracecontext-testsuite.yml @@ -23,7 +23,7 @@ jobs: password: ${{ secrets.GITHUB_TOKEN }} - name: Build and push - uses: docker/build-push-action@v5 + uses: docker/build-push-action@v6 with: context: integration-tests/tracecontext/docker push: true From 12eb62659d50750755c3f7533b6ed3c028cf5b8c Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 18 Jun 2024 20:52:04 -0700 Subject: [PATCH 449/901] Update gradle/actions action to v3.4.2 (#6527) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/gradle-wrapper-validation.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/gradle-wrapper-validation.yml b/.github/workflows/gradle-wrapper-validation.yml index 7de11e93878..4eb03862f58 100644 --- a/.github/workflows/gradle-wrapper-validation.yml +++ b/.github/workflows/gradle-wrapper-validation.yml @@ -13,4 +13,4 @@ jobs: steps: - uses: actions/checkout@v4 - - uses: gradle/actions/wrapper-validation@v3.4.1 + - uses: gradle/actions/wrapper-validation@v3.4.2 From cbac2020442434a8d00dcb24d60def318b1973bd Mon Sep 17 00:00:00 2001 From: ICTylor Date: Fri, 21 Jun 2024 17:57:56 +0200 Subject: [PATCH 450/901] Update README.md JDK Sender link to point to JDK sender instead of OkHttp one (#6532) --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 91f3baecd0b..2324558c1ae 100644 --- a/README.md +++ b/README.md @@ -271,7 +271,7 @@ dependency as follows, replacing `{{artifact-id}}` with the value from the "Arti | [Prometheus Exporter](./exporters/prometheus) | Prometheus metric exporter | `opentelemetry-exporter-prometheus` | 1.39.0-alpha | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-prometheus.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-prometheus) | | [Exporter Common](./exporters/common) | Shared exporter components (internal) | `opentelemetry-exporter-common` | 1.39.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-common.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-common) | | [OkHttp Sender](./exporters/sender/okhttp) | OkHttp implementation of HttpSender (internal) | `opentelemetry-exporter-sender-okhttp` | 1.39.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-sender-okhttp.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-sender-okhttp) | -| [JDK Sender](./exporters/sender/okhttp) | Java 11+ native HttpClient implementation of HttpSender (internal) | `opentelemetry-exporter-sender-jdk` TODO: remove `-alpha` after release | 1.39.0-alpha | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-sender-jdk.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-sender-jdk) | | +| [JDK Sender](./exporters/sender/jdk) | Java 11+ native HttpClient implementation of HttpSender (internal) | `opentelemetry-exporter-sender-jdk` TODO: remove `-alpha` after release | 1.39.0-alpha | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-sender-jdk.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-sender-jdk) | | | [gRPC ManagedChannel Sender](./exporters/sender/grpc-managed-channel) | gRPC ManagedChannel implementation of GrpcSender (internal) | `opentelemetry-exporter-sender-grpc-managed-channel` | 1.39.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-sender-grpc-managed-channel.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-sender-grpc-managed-channel) | | ### SDK Extensions From a09eff61004e1f1a2293357a5445c8c2b06b8329 Mon Sep 17 00:00:00 2001 From: Jay DeLuca Date: Mon, 24 Jun 2024 14:44:24 -0400 Subject: [PATCH 451/901] Reference configuration documentation on opentelemetry.io (#6491) Co-authored-by: jack-berg <34418638+jack-berg@users.noreply.github.com> --- CONTRIBUTING.md | 5 + ...uration.md => sdk-configuration-design.md} | 3 +- sdk-extensions/autoconfigure/README.md | 390 +----------------- 3 files changed, 9 insertions(+), 389 deletions(-) rename docs/{sdk-configuration.md => sdk-configuration-design.md} (99%) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 3b8c7b62f36..0eac89cb75d 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -183,6 +183,11 @@ in the guide for exceptions to the Javadoc requirement. * Our javadoc is available via [ javadoc.io}(https://javadoc.io/doc/io.opentelemetry/opentelemetry-api) +### SDK Configuration Documentation + +All changes to the SDK configuration options or autoconfigure module should be documented on +[opentelemetry.io](https://opentelemetry.io/docs/languages/java/configuration/). + ### AutoValue * Use [AutoValue](https://github.com/google/auto/tree/master/value), when possible, for any new diff --git a/docs/sdk-configuration.md b/docs/sdk-configuration-design.md similarity index 99% rename from docs/sdk-configuration.md rename to docs/sdk-configuration-design.md index 9476ad5a572..2ecc7f4341c 100644 --- a/docs/sdk-configuration.md +++ b/docs/sdk-configuration-design.md @@ -1,7 +1,8 @@ # 🚨 Archival Use Only! 🚨 > This is a historical design document and is not updated with evolving APIs. For up-to-date > examples of SDK configuration see the -> [documentation](https://opentelemetry.io/docs/java/manual_instrumentation/). +> [manual instrumentation documentation](https://opentelemetry.io/docs/languages/java/instrumentation/) +> and the [SDK configuration documentation](https://opentelemetry.io/docs/languages/java/configuration/). > This document is maintained here for historical purposes only, and it is intended to > help future readers to understand the rationale behind certain design decisions. diff --git a/sdk-extensions/autoconfigure/README.md b/sdk-extensions/autoconfigure/README.md index 6fed9d1fe66..8662e8b2c7f 100644 --- a/sdk-extensions/autoconfigure/README.md +++ b/sdk-extensions/autoconfigure/README.md @@ -3,392 +3,6 @@ This artifact implements environment-based autoconfiguration of the OpenTelemetry SDK. This can be an alternative to programmatic configuration using the normal SDK builders. -All options support being passed as Java system properties, e.g., `-Dotel.traces.exporter=zipkin` or -environment variables, e.g., `OTEL_TRACES_EXPORTER=zipkin`. -## Contents - - - - - -- [General Configuration](#general-configuration) - * [Disabling OpenTelemetrySdk](#disabling-opentelemetrysdk) - * [Exporters](#exporters) - + [OTLP exporter (span, metric, and log exporters)](#otlp-exporter-span-metric-and-log-exporters) - - [OTLP exporter retry](#otlp-exporter-retry) - + [Logging exporter](#logging-exporter) - + [Logging OTLP JSON exporter](#logging-otlp-json-exporter) - * [OpenTelemetry Resource](#opentelemetry-resource) - + [Resource Provider SPI](#resource-provider-spi) - + [Disabling Automatic ResourceProviders](#disabling-automatic-resourceproviders) - * [Attribute limits](#attribute-limits) - * [Propagator](#propagator) -- [Tracer provider](#tracer-provider) - * [Span exporters](#span-exporters) - + [Jaeger exporter](#jaeger-exporter) - + [Zipkin exporter](#zipkin-exporter) - * [Batch span processor](#batch-span-processor) - * [Sampler](#sampler) - * [Span limits](#span-limits) -- [Meter provider](#meter-provider) - * [Exemplars](#exemplars) - * [Periodic Metric Reader](#periodic-metric-reader) - * [Metric exporters](#metric-exporters) - + [Prometheus exporter](#prometheus-exporter) - * [Cardinality Limits](#cardinality-limits) -- [Logger provider](#logger-provider) - * [Batch log record processor](#batch-log-record-processor) -- [Customizing the OpenTelemetry SDK](#customizing-the-opentelemetry-sdk) -- [File Configuration](#file-configuration) - - - -## General Configuration - -See [Tracer provider](#tracer-provider), [Meter provider](#meter-provider), -and [Logger provider](#logger-provider) for signal specific configuration options. - -The autoconfigure module registers Java shutdown hooks to shut down the SDK when appropriate. Please -note that since this project uses java.util.logging for all of it's logging, some of that logging -may be suppressed during shutdown hooks. This is a bug in the JDK itself, and not something we can -control. If you require logging during shutdown hooks, please consider using `System.out` rather -than a logging framework that might shut itself down in a shutdown hook, thus suppressing your log -messages. See this [JDK bug](https://bugs.openjdk.java.net/browse/JDK-8161253) for more details. - -### Disabling OpenTelemetrySdk - -The OpenTelemetry SDK can be disabled entirely. If disabled, `AutoConfiguredOpenTelemetrySdk#getOpenTelemetrySdk()` will return a minimally configured instance (i.e. `OpenTelemetrySdk.builder().build()`). - -| System property | Environment variable | Purpose | -|-------------------|----------------------|----------------------------------------------------------------| -| otel.sdk.disabled | OTEL_SDK_DISABLED | If `true`, disable the OpenTelemetry SDK. Defaults to `false`. | - -### Exporters - -The following configuration properties are common to all exporters: - -| System property | Environment variable | Purpose | -|---------------------------------------------|---------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| otel.traces.exporter | OTEL_TRACES_EXPORTER | List of exporters to be used for tracing, separated by commas. Default is `otlp`. `none` means no autoconfigured exporter. | -| otel.metrics.exporter | OTEL_METRICS_EXPORTER | List of exporters to be used for metrics, separated by commas. Default is `otlp`. `none` means no autoconfigured exporter. | -| otel.logs.exporter | OTEL_LOGS_EXPORTER | List of exporters to be used for logging, separated by commas. Default is `otlp`. `none` means no autoconfigured exporter. | -| otel.java.experimental.exporter.memory_mode | OTEL_JAVA_EXPERIMENTAL_EXPORTER_MEMORY_MODE | If `reusable_data`, enable reusable memory mode (on exporters which support it) to reduce allocations. Default is `immutable_data`. This option is experimental and subject to change or removal.**[1]** | - -**[1]**: NOTE: The exporters which adhere -to `otel.java.experimental.exporter.memory_mode=reusable_data` -are `OtlpGrpcMetricExporter`, `OtlpHttpMetricExporter`, and `PrometheusHttpServer`. Support for -additional exporters may be added in the future. - - -#### OTLP exporter (span, metric, and log exporters) - -The [OpenTelemetry Protocol (OTLP)](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/protocol/otlp.md) span, metric, and log exporters - -| System property | Environment variable | Description | -|----------------------------------------------------------|----------------------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| otel.traces.exporter=otlp (default) | OTEL_TRACES_EXPORTER=otlp | Select the OpenTelemetry exporter for tracing (default) | -| otel.metrics.exporter=otlp (default) | OTEL_METRICS_EXPORTER=otlp | Select the OpenTelemetry exporter for metrics (default) | -| otel.logs.exporter=otlp (default) | OTEL_LOGS_EXPORTER=otlp | Select the OpenTelemetry exporter for logs (default) | -| otel.exporter.otlp.endpoint | OTEL_EXPORTER_OTLP_ENDPOINT | The OTLP traces, metrics, and logs endpoint to connect to. Must be a URL with a scheme of either `http` or `https` based on the use of TLS. If protocol is `http/protobuf` the version and signal will be appended to the path (e.g. `v1/traces`, `v1/metrics`, or `v1/logs`). Default is `http://localhost:4317` when protocol is `grpc`, and `http://localhost:4318/v1/{signal}` when protocol is `http/protobuf`. | -| otel.exporter.otlp.traces.endpoint | OTEL_EXPORTER_OTLP_TRACES_ENDPOINT | The OTLP traces endpoint to connect to. Must be a URL with a scheme of either `http` or `https` based on the use of TLS. Default is `http://localhost:4317` when protocol is `grpc`, and `http://localhost:4318/v1/traces` when protocol is `http/protobuf`. | -| otel.exporter.otlp.metrics.endpoint | OTEL_EXPORTER_OTLP_METRICS_ENDPOINT | The OTLP metrics endpoint to connect to. Must be a URL with a scheme of either `http` or `https` based on the use of TLS. Default is `http://localhost:4317` when protocol is `grpc`, and `http://localhost:4318/v1/metrics` when protocol is `http/protobuf`. | -| otel.exporter.otlp.logs.endpoint | OTEL_EXPORTER_OTLP_LOGS_ENDPOINT | The OTLP logs endpoint to connect to. Must be a URL with a scheme of either `http` or `https` based on the use of TLS. Default is `http://localhost:4317` when protocol is `grpc`, and `http://localhost:4318/v1/logs` when protocol is `http/protobuf`. | -| otel.exporter.otlp.certificate | OTEL_EXPORTER_OTLP_CERTIFICATE | The path to the file containing trusted certificates to use when verifying an OTLP trace, metric, or log server's TLS credentials. The file should contain one or more X.509 certificates in PEM format. By default the host platform's trusted root certificates are used. | -| otel.exporter.otlp.traces.certificate | OTEL_EXPORTER_OTLP_TRACES_CERTIFICATE | The path to the file containing trusted certificates to use when verifying an OTLP trace server's TLS credentials. The file should contain one or more X.509 certificates in PEM format. By default the host platform's trusted root certificates are used. | -| otel.exporter.otlp.metrics.certificate | OTEL_EXPORTER_OTLP_METRICS_CERTIFICATE | The path to the file containing trusted certificates to use when verifying an OTLP metric server's TLS credentials. The file should contain one or more X.509 certificates in PEM format. By default the host platform's trusted root certificates are used. | -| otel.exporter.otlp.logs.certificate | OTEL_EXPORTER_OTLP_LOGS_CERTIFICATE | The path to the file containing trusted certificates to use when verifying an OTLP log server's TLS credentials. The file should contain one or more X.509 certificates in PEM format. By default the host platform's trusted root certificates are used. | -| otel.exporter.otlp.client.key | OTEL_EXPORTER_OTLP_CLIENT_KEY | The path to the file containing private client key to use when verifying an OTLP trace, metric, or log client's TLS credentials. The file should contain one private key PKCS8 PEM format. By default no client key is used. | -| otel.exporter.otlp.traces.client.key | OTEL_EXPORTER_OTLP_TRACES_CLIENT_KEY | The path to the file containing private client key to use when verifying an OTLP trace client's TLS credentials. The file should contain one private key PKCS8 PEM format. By default no client key file is used. | -| otel.exporter.otlp.metrics.client.key | OTEL_EXPORTER_OTLP_METRICS_CLIENT_KEY | The path to the file containing private client key to use when verifying an OTLP metric client's TLS credentials. The file should contain one private key PKCS8 PEM format. By default no client key file is used. | -| otel.exporter.otlp.logs.client.key | OTEL_EXPORTER_OTLP_LOGS_CLIENT_KEY | The path to the file containing private client key to use when verifying an OTLP log client's TLS credentials. The file should contain one private key PKCS8 PEM format. By default no client key file is used. | -| otel.exporter.otlp.client.certificate | OTEL_EXPORTER_OTLP_CLIENT_CERTIFICATE | The path to the file containing trusted certificates to use when verifying an OTLP trace, metric, or log client's TLS credentials. The file should contain one or more X.509 certificates in PEM format. By default no chain file is used. | -| otel.exporter.otlp.traces.client.certificate | OTEL_EXPORTER_OTLP_TRACES_CLIENT_CERTIFICATE | The path to the file containing trusted certificates to use when verifying an OTLP trace server's TLS credentials. The file should contain one or more X.509 certificates in PEM format. By default no chain file is used. | -| otel.exporter.otlp.metrics.client.certificate | OTEL_EXPORTER_OTLP_METRICS_CLIENT_CERTIFICATE | The path to the file containing trusted certificates to use when verifying an OTLP metric server's TLS credentials. The file should contain one or more X.509 certificates in PEM format. By default no chain file is used. | -| otel.exporter.otlp.logs.client.certificate | OTEL_EXPORTER_OTLP_LOGS_CLIENT_CERTIFICATE | The path to the file containing trusted certificates to use when verifying an OTLP log server's TLS credentials. The file should contain one or more X.509 certificates in PEM format. By default no chain file is used. | -| otel.exporter.otlp.headers | OTEL_EXPORTER_OTLP_HEADERS | Key-value pairs separated by commas to pass as request headers on OTLP trace, metric, and log requests. | -| otel.exporter.otlp.traces.headers | OTEL_EXPORTER_OTLP_TRACES_HEADERS | Key-value pairs separated by commas to pass as request headers on OTLP trace requests. | -| otel.exporter.otlp.metrics.headers | OTEL_EXPORTER_OTLP_METRICS_HEADERS | Key-value pairs separated by commas to pass as request headers on OTLP metrics requests. | -| otel.exporter.otlp.logs.headers | OTEL_EXPORTER_OTLP_LOGS_HEADERS | Key-value pairs separated by commas to pass as request headers on OTLP logs requests. | -| otel.exporter.otlp.compression | OTEL_EXPORTER_OTLP_COMPRESSION | The compression type to use on OTLP trace, metric, and log requests. Options include `gzip`. By default no compression will be used. | -| otel.exporter.otlp.traces.compression | OTEL_EXPORTER_OTLP_TRACES_COMPRESSION | The compression type to use on OTLP trace requests. Options include `gzip`. By default no compression will be used. | -| otel.exporter.otlp.metrics.compression | OTEL_EXPORTER_OTLP_METRICS_COMPRESSION | The compression type to use on OTLP metric requests. Options include `gzip`. By default no compression will be used. | -| otel.exporter.otlp.logs.compression | OTEL_EXPORTER_OTLP_LOGS_COMPRESSION | The compression type to use on OTLP log requests. Options include `gzip`. By default no compression will be used. | -| otel.exporter.otlp.timeout | OTEL_EXPORTER_OTLP_TIMEOUT | The maximum waiting time, in milliseconds, allowed to send each OTLP trace, metric, and log batch. Default is `10000`. | -| otel.exporter.otlp.traces.timeout | OTEL_EXPORTER_OTLP_TRACES_TIMEOUT | The maximum waiting time, in milliseconds, allowed to send each OTLP trace batch. Default is `10000`. | -| otel.exporter.otlp.metrics.timeout | OTEL_EXPORTER_OTLP_METRICS_TIMEOUT | The maximum waiting time, in milliseconds, allowed to send each OTLP metric batch. Default is `10000`. | -| otel.exporter.otlp.logs.timeout | OTEL_EXPORTER_OTLP_LOGS_TIMEOUT | The maximum waiting time, in milliseconds, allowed to send each OTLP log batch. Default is `10000`. | -| otel.exporter.otlp.protocol | OTEL_EXPORTER_OTLP_PROTOCOL | The transport protocol to use on OTLP trace, metric, and log requests. Options include `grpc` and `http/protobuf`. Default is `grpc`.**[1]** | -| otel.exporter.otlp.traces.protocol | OTEL_EXPORTER_OTLP_TRACES_PROTOCOL | The transport protocol to use on OTLP trace requests. Options include `grpc` and `http/protobuf`. Default is `grpc`.**[1]** | -| otel.exporter.otlp.metrics.protocol | OTEL_EXPORTER_OTLP_METRICS_PROTOCOL | The transport protocol to use on OTLP metric requests. Options include `grpc` and `http/protobuf`. Default is `grpc`.**[1]** | -| otel.exporter.otlp.logs.protocol | OTEL_EXPORTER_OTLP_LOGS_PROTOCOL | The transport protocol to use on OTLP log requests. Options include `grpc` and `http/protobuf`. Default is `grpc`.**[1]** | -| otel.exporter.otlp.metrics.temporality.preference | OTEL_EXPORTER_OTLP_METRICS_TEMPORALITY_PREFERENCE | The preferred output aggregation temporality. Options include `DELTA`, `LOWMEMORY`, and `CUMULATIVE`. If `CUMULATIVE`, all instruments will have cumulative temporality. If `DELTA`, counter (sync and async) and histograms will be delta, up down counters (sync and async) will be cumulative. If `LOWMEMORY`, sync counter and histograms will be delta, async counter and up down counters (sync and async) will be cumulative. Default is `CUMULATIVE`. | -| otel.exporter.otlp.metrics.default.histogram.aggregation | OTEL_EXPORTER_OTLP_METRICS_DEFAULT_HISTOGRAM_AGGREGATION | The preferred default histogram aggregation. Options include `BASE2_EXPONENTIAL_BUCKET_HISTOGRAM` and `EXPLICIT_BUCKET_HISTOGRAM`. Default is `EXPLICIT_BUCKET_HISTOGRAM`. | -| otel.experimental.exporter.otlp.retry.enabled | OTEL_EXPERIMENTAL_EXPORTER_OTLP_RETRY_ENABLED | If `true`, enable [experimental retry support](#otlp-exporter-retry). Default is `false`. | - -To configure the service name for the OTLP exporter, add the `service.name` key -to the OpenTelemetry Resource ([see below](#opentelemetry-resource)), e.g. `OTEL_RESOURCE_ATTRIBUTES=service.name=myservice`. - -**[1]**: NOTE: OpenTelemetry Java Agent 2.x uses `http/protobuf` by default. - -##### OTLP exporter retry - -[OTLP](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/protocol/otlp.md#otlpgrpc-response) requires that [transient](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/protocol/exporter.md#retry) errors be handled with a retry strategy. When retry is enabled, retryable gRPC status codes will be retried using an exponential backoff with jitter algorithm as described in the [gRPC Retry Design](https://github.com/grpc/proposal/blob/master/A6-client-retries.md#exponential-backoff). - -The policy has the following configuration, which there is currently no way to customize. - -- `maxAttempts`: The maximum number of attempts, including the original request. Defaults to `5`. -- `initialBackoff`: The initial backoff duration. Defaults to `1s` -- `maxBackoff`: The maximum backoff duration. Defaults to `5s`. -- `backoffMultiplier` THe backoff multiplier. Defaults to `1.5`. - -#### Logging exporter - -The logging exporter prints the name of the span along with its attributes to stdout. It's mainly used for testing and debugging. - -| System property | Environment variable | Description | -|-------------------------------|-------------------------------|----------------------------------------------------------------------| -| otel.traces.exporter=console | OTEL_TRACES_EXPORTER=console | Select the logging exporter for tracing | -| otel.metrics.exporter=console | OTEL_METRICS_EXPORTER=console | Select the logging exporter for metrics | -| otel.logs.exporter=console | OTEL_LOGS_EXPORTER=console | Select the logging exporter for logs | - -The logging exporter is also set when `otel.traces.exporter`, `otel.metrics.exporter`, -or `otel.logs.exporter` is set to `logging`. `logging` is a deprecated alias for `console`, the -preferred value -as [defined in the specification](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/configuration/sdk-environment-variables.md#exporter-selection). - -#### Logging OTLP JSON exporter - -The logging-otlp exporter writes the telemetry data to the JUL logger in OLTP JSON form. It's a more verbose output mainly used for testing and debugging. - -| System property | Environment variable | Description | -|------------------------------------|------------------------------------|----------------------------------------------------| -| otel.traces.exporter=logging-otlp | OTEL_TRACES_EXPORTER=logging-otlp | Select the logging OTLP JSON exporter for tracing | -| otel.metrics.exporter=logging-otlp | OTEL_METRICS_EXPORTER=logging-otlp | Select the logging OTLP JSON exporter for metrics | -| otel.logs.exporter=logging-otlp | OTEL_LOGS_EXPORTER=logging-otlp | Select the logging OTLP JSON exporter for logs | - -**NOTE:** While the `OtlpJsonLogging{Signal}Exporters` are stable, specifying their use -via `otel.{signal}.exporter=logging-otlp` is experimental and subject to change or removal. - -### OpenTelemetry Resource - -The [OpenTelemetry Resource](https://github.com/open-telemetry/opentelemetry-specification/blob/master/specification/resource/sdk.md) -is a representation of the entity producing telemetry. - -| System property | Environment variable | Description | -|------------------------------------------|------------------------------------------|------------------------------------------------------------------------------------------------------------| -| otel.resource.attributes | OTEL_RESOURCE_ATTRIBUTES | Specify resource attributes in the following format: key1=val1,key2=val2,key3=val3 | -| otel.service.name | OTEL_SERVICE_NAME | Specify logical service name. Takes precedence over `service.name` defined with `otel.resource.attributes` | -| otel.experimental.resource.disabled-keys | OTEL_EXPERIMENTAL_RESOURCE_DISABLED_KEYS | Specify resource attribute keys that are filtered. | - -You almost always want to specify the [`service.name`](https://opentelemetry.io/docs/specs/semconv/resource/#service) for your application. -It corresponds to how you describe the application, for example `authservice` could be an application that authenticates requests, and `cats` could be an application that returns information about [cats](https://en.wikipedia.org/wiki/Cat). -You would specify that by setting service name property in one of the following ways: -* directly via `OTEL_SERVICE_NAME=authservice` or `-Dotel.service.name=cats` -* by `service.name` resource attribute like `OTEL_RESOURCE_ATTRIBUTES=service.name=authservice`, or `-Dotel.resource.attributes=service.name=cats,service.namespace=mammals`. - -If not specified, SDK defaults the service name to `unknown_service:java`. - -#### Resource Provider SPI - -The [autoconfigure-spi](https://github.com/open-telemetry/opentelemetry-java/tree/main/sdk-extensions/autoconfigure-spi) -SDK extension provides a ResourceProvider SPI that allows libraries to automatically provide -Resources, which are merged into a single Resource by the autoconfiguration module. You can create -your own ResourceProvider, or optionally use an artifact that includes built-in ResourceProviders: - -* [io.opentelemetry.instrumentation:opentelemetry-resources](https://github.com/open-telemetry/opentelemetry-java-instrumentation/tree/main/instrumentation/resources) - includes providers for - a [predefined set of common resources](https://github.com/open-telemetry/opentelemetry-java-instrumentation/tree/main/instrumentation/resources/library/src/main/java/io/opentelemetry/instrumentation/resources) -* [io.opentelemetry.contrib:opentelemetry-aws-resources](https://github.com/open-telemetry/opentelemetry-java-contrib/tree/main/aws-resources) - includes providers - for [common AWS resources](https://github.com/open-telemetry/opentelemetry-java-contrib/tree/main/aws-resources/src/main/java/io/opentelemetry/contrib/aws/resource) -* [io.opentelemetry.contrib:opentelemetry-gcp-resources](https://github.com/open-telemetry/opentelemetry-java-contrib/tree/main/gcp-resources) includes providers for [common GCP resources](https://github.com/open-telemetry/opentelemetry-java-contrib/tree/main/gcp-resources/src/main/java/io/opentelemetry/contrib/gcp/resource) - -#### Disabling Automatic ResourceProviders - -If you are using the `ResourceProvider` SPI (many instrumentation agent distributions include this automatically), -you can enable / disable one or more of them by using the following configuration items: - -| System property | Environment variable | Description | -|---------------------------------------|---------------------------------------|---------------------------------------------------------------------------------------------| -| otel.java.enabled.resource.providers | OTEL_JAVA_ENABLED_RESOURCE_PROVIDERS | Enables one or more `ResourceProvider` types. If unset, all resource providers are enabled. | -| otel.java.disabled.resource.providers | OTEL_JAVA_DISABLED_RESOURCE_PROVIDERS | Disables one or more `ResourceProvider` types | - -The value for these properties must be a comma separated list of fully qualified `ResourceProvider` classnames. -For example, if you don't want to expose the name of the operating system through the resource, you -can pass the following JVM argument: - -``` --Dotel.java.disabled.resource.providers=io.opentelemetry.instrumentation.resources.OsResourceProvider -``` - -### Attribute limits - -These properties can be used to control the maximum number and length of attributes. - -| System property | Environment variable | Description | -|-----------------------------------|-----------------------------------|----------------------------------------------------------------------------------------------------------| -| otel.attribute.value.length.limit | OTEL_ATTRIBUTE_VALUE_LENGTH_LIMIT | The maximum length of attribute values. Applies to spans and logs. By default there is no limit. | -| otel.attribute.count.limit | OTEL_ATTRIBUTE_COUNT_LIMIT | The maximum number of attributes. Applies to spans, span events, span links, and logs. Default is `128`. | - -### Propagator - -The propagators determine which distributed tracing header formats are used, and which baggage propagation header formats are used. - -| System property | Environment variable | Description | -|------------------|----------------------|---------------------------------------------------------------------------------------------------------------------------| -| otel.propagators | OTEL_PROPAGATORS | The propagators to be used. Use a comma-separated list for multiple propagators. Default is `tracecontext,baggage` (W3C). | - -Supported values are - -- `"tracecontext"`: [W3C Trace Context](https://www.w3.org/TR/trace-context/) (add `baggage` as well to include W3C baggage) -- `"baggage"`: [W3C Baggage](https://www.w3.org/TR/baggage/) -- `"b3"`: [B3 Single](https://github.com/openzipkin/b3-propagation#single-header) -- `"b3multi"`: [B3 Multi](https://github.com/openzipkin/b3-propagation#multiple-headers) -- `"jaeger"`: [Jaeger](https://www.jaegertracing.io/docs/1.21/client-libraries/#propagation-format) (includes Jaeger baggage) -- `"xray"`: [AWS X-Ray](https://docs.aws.amazon.com/xray/latest/devguide/xray-concepts.html#xray-concepts-tracingheader) -- `"ottrace"`: [OT Trace](https://github.com/opentracing?q=basic&type=&language=) - -## Tracer provider - -The following configuration options are specific to `SdkTracerProvider`. See [general configuration](#general-configuration) for general configuration. - -### Span exporters - -The following exporters are only available for the trace signal. See [exporters](#exporters) for general exporter configuration. - -#### Jaeger exporter - -The Jaeger exporters (artifacts `opentelemetry-exporter-jaeger` and `opentelemetry-exporter-jaeger-thrift`) were removed in the [1.35.0](https://github.com/open-telemetry/opentelemetry-java/releases/tag/v1.35.0) release (last published in `1.34.0`) and are no longer available in later versions of autoconfigure. - -Jaeger now has [native support for OTLP](https://opentelemetry.io/blog/2022/jaeger-native-otlp/), and users should export to jaeger using [OTLP](https://opentelemetry.io/docs/instrumentation/java/exporters/#otlp-dependencies) instead. - -#### Zipkin exporter - -The [Zipkin](https://zipkin.io/zipkin-api/) exporter. It sends JSON in [Zipkin format](https://zipkin.io/zipkin-api/#/default/post_spans) to a specified HTTP URL. - -| System property | Environment variable | Description | -|-------------------------------|-------------------------------|-----------------------------------------------------------------------------------------------------------------------| -| otel.traces.exporter=zipkin | OTEL_TRACES_EXPORTER=zipkin | Select the Zipkin exporter | -| otel.exporter.zipkin.endpoint | OTEL_EXPORTER_ZIPKIN_ENDPOINT | The Zipkin endpoint to connect to. Default is `http://localhost:9411/api/v2/spans`. Currently only HTTP is supported. | - -### Batch span processor - -| System property | Environment variable | Description | -|--------------------------------|--------------------------------|------------------------------------------------------------------------------------| -| otel.bsp.schedule.delay | OTEL_BSP_SCHEDULE_DELAY | The interval, in milliseconds, between two consecutive exports. Default is `5000`. | -| otel.bsp.max.queue.size | OTEL_BSP_MAX_QUEUE_SIZE | The maximum queue size. Default is `2048`. | -| otel.bsp.max.export.batch.size | OTEL_BSP_MAX_EXPORT_BATCH_SIZE | The maximum batch size. Default is `512`. | -| otel.bsp.export.timeout | OTEL_BSP_EXPORT_TIMEOUT | The maximum allowed time, in milliseconds, to export data. Default is `30000`. | - -### Sampler - -The sampler configures whether spans will be recorded for any call to `SpanBuilder.startSpan`. - -| System property | Environment variable | Description | -|-------------------------|-------------------------|-------------------------------------------------------------------------| -| otel.traces.sampler | OTEL_TRACES_SAMPLER | The sampler to use for tracing. Defaults to `parentbased_always_on` | -| otel.traces.sampler.arg | OTEL_TRACES_SAMPLER_ARG | An argument to the configured tracer if supported, for example a ratio. | - -Supported values for `otel.traces.sampler` are - -- "always_on": AlwaysOnSampler -- "always_off": AlwaysOffSampler -- "traceidratio": TraceIdRatioBased. `otel.traces.sampler.arg` sets the ratio. -- "parentbased_always_on": ParentBased(root=AlwaysOnSampler) -- "parentbased_always_off": ParentBased(root=AlwaysOffSampler) -- "parentbased_traceidratio": ParentBased(root=TraceIdRatioBased). `otel.traces.sampler.arg` sets the ratio. - -### Span limits - -See [attribute limits](#attribute-limits) for general attribute limit configuration. - -These properties can be used to control the maximum size of spans by placing limits on attributes, events, and links. - -| System property | Environment variable | Description | -|----------------------------------------|----------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------| -| otel.span.attribute.value.length.limit | OTEL_SPAN_ATTRIBUTE_VALUE_LENGTH_LIMIT | The maximum length of span attribute values. Takes precedence over `otel.attribute.value.length.limit`. By default there is no limit. | -| otel.span.attribute.count.limit | OTEL_SPAN_ATTRIBUTE_COUNT_LIMIT | The maximum number of attributes per span. Takes precedence over `otel.attribute.count.limit`. Default is `128`. | -| otel.span.event.count.limit | OTEL_SPAN_EVENT_COUNT_LIMIT | The maximum number of events per span. Default is `128`. | -| otel.span.link.count.limit | OTEL_SPAN_LINK_COUNT_LIMIT | The maximum number of links per span. Default is `128` | - -## Meter provider - -The following configuration options are specific to `SdkMeterProvider`. See [general configuration](#general-configuration) for general configuration. - -### Exemplars - -| System property | Environment variable | Description | -|------------------------------|------------------------------|-----------------------------------------------------------------------------------------------------------------| -| otel.metrics.exemplar.filter | OTEL_METRICS_EXEMPLAR_FILTER | The filter for exemplar sampling. Can be `ALWAYS_OFF`, `ALWAYS_ON` or `TRACE_BASED`. Default is `TRACE_BASED`. | - -### Periodic Metric Reader - -| System property | Environment variable | Description | -|-----------------------------|-----------------------------|----------------------------------------------------------------------------------------------| -| otel.metric.export.interval | OTEL_METRIC_EXPORT_INTERVAL | The interval, in milliseconds, between the start of two export attempts. Default is `60000`. | - -### Metric exporters - -The following exporters are only available for the metric signal. See [exporters](#exporters) for general exporter configuration. - -#### Prometheus exporter - -The [Prometheus](https://github.com/prometheus/docs/blob/master/content/docs/instrumenting/exposition_formats.md) exporter. - -| System property | Environment variable | Description | -|---------------------------------------------------------|---------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------| -| otel.metrics.exporter=prometheus | OTEL_METRICS_EXPORTER=prometheus | Select the Prometheus exporter | -| otel.exporter.prometheus.port | OTEL_EXPORTER_PROMETHEUS_PORT | The local port used to bind the prometheus metric server. Default is `9464`. | -| otel.exporter.prometheus.host | OTEL_EXPORTER_PROMETHEUS_HOST | The local address used to bind the prometheus metric server. Default is `0.0.0.0`. | - -Note that this is a pull exporter - it opens up a server on the local process listening on the specified host and port, which -a Prometheus server scrapes from. - -### Cardinality Limits - -| System property | Environment variable | Description | -|---------------------------------------------|---------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------| -| otel.experimental.metrics.cardinality.limit | OTEL_EXPERIMENTAL_METRICS_CARDINALITY_LIMIT | If set, configure experimental cardinality limit. The value dictates the maximum number of distinct points per metric. Default is `2000`. | - -## Logger provider - -The following configuration options are specific to `SdkLoggerProvider`. See [general configuration](#general-configuration) for general configuration. - -### Batch log record processor - -| System property | Environment variable | Description | -|---------------------------------|---------------------------------|------------------------------------------------------------------------------------| -| otel.blrp.schedule.delay | OTEL_BLRP_SCHEDULE_DELAY | The interval, in milliseconds, between two consecutive exports. Default is `1000`. | -| otel.blrp.max.queue.size | OTEL_BLRP_MAX_QUEUE_SIZE | The maximum queue size. Default is `2048`. | -| otel.blrp.max.export.batch.size | OTEL_BLRP_MAX_EXPORT_BATCH_SIZE | The maximum batch size. Default is `512`. | -| otel.blrp.export.timeout | OTEL_BLRP_EXPORT_TIMEOUT | The maximum allowed time, in milliseconds, to export data. Default is `30000`. | - -## Customizing the OpenTelemetry SDK - -Autoconfiguration exposes SPI [hooks](../autoconfigure-spi/src/main/java/io/opentelemetry/sdk/autoconfigure/spi) for customizing behavior programmatically as needed. -It's recommended to use the above configuration properties where possible, only implementing the SPI to add functionality not found in the -SDK by default. - -## File Configuration - -**Experimental**: File based configuration is experimental and subject to breaking changes. - -File configuration allows for configuration via a YAML as described -in [opentelemetry-configuration](https://github.com/open-telemetry/opentelemetry-configuration) -and [file configuration](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/configuration/file-configuration.md). - -To use, include `io.opentelemetry:opentelemetry-sdk-extension:incubator:` and specify the -path to the config file as described in the table below. - -| System property | Environment variable | Purpose | -|-------------------------------|-------------------------------|------------------------------------------------------------| -| otel.experimental.config.file | OTEL_EXPERIMENTAL_CONFIG_FILE | The path to the SDK configuration file. Defaults to unset. | - -NOTE: When a config file is specified, other environment variables described in this document along -with SPI [customizations](#customizing-the-opentelemetry-sdk) are ignored. The contents of the file -alone dictate SDK configuration. +The full documentation on the available configuration options has been moved to +[opentelemetry.io](https://opentelemetry.io/docs/languages/java/configuration/) From 0aacc55d1e3f5cc6dbb4f8fa26bcb657b01a7bc9 Mon Sep 17 00:00:00 2001 From: Trask Stalnaker Date: Mon, 24 Jun 2024 13:07:42 -0700 Subject: [PATCH 452/901] Narrow ExtendedSpanBuilder return types for chaining (#6514) --- .../incubator/trace/ExtendedSpanBuilder.java | 63 +++++++++++++++++++ .../trace/ExtendedTraceApiUsageTest.java | 1 + .../sdk/trace/SdkSpanBuilder.java | 22 +++---- 3 files changed, 75 insertions(+), 11 deletions(-) diff --git a/api/incubator/src/main/java/io/opentelemetry/api/incubator/trace/ExtendedSpanBuilder.java b/api/incubator/src/main/java/io/opentelemetry/api/incubator/trace/ExtendedSpanBuilder.java index 715b79f70c4..eec32904a4e 100644 --- a/api/incubator/src/main/java/io/opentelemetry/api/incubator/trace/ExtendedSpanBuilder.java +++ b/api/incubator/src/main/java/io/opentelemetry/api/incubator/trace/ExtendedSpanBuilder.java @@ -6,10 +6,17 @@ package io.opentelemetry.api.incubator.trace; import io.opentelemetry.api.OpenTelemetry; +import io.opentelemetry.api.common.AttributeKey; +import io.opentelemetry.api.common.Attributes; import io.opentelemetry.api.trace.Span; import io.opentelemetry.api.trace.SpanBuilder; +import io.opentelemetry.api.trace.SpanContext; +import io.opentelemetry.api.trace.SpanKind; +import io.opentelemetry.context.Context; import io.opentelemetry.context.propagation.ContextPropagators; +import java.time.Instant; import java.util.Map; +import java.util.concurrent.TimeUnit; import java.util.function.BiConsumer; /** Extended {@link SpanBuilder} with experimental APIs. */ @@ -90,4 +97,60 @@ T startAndCall( */ void startAndRun( SpanRunnable runnable, BiConsumer handleException) throws E; + + /** {@inheritDoc} */ + @Override + ExtendedSpanBuilder setParent(Context context); + + /** {@inheritDoc} */ + @Override + ExtendedSpanBuilder setNoParent(); + + /** {@inheritDoc} */ + @Override + ExtendedSpanBuilder addLink(SpanContext spanContext); + + /** {@inheritDoc} */ + @Override + ExtendedSpanBuilder addLink(SpanContext spanContext, Attributes attributes); + + /** {@inheritDoc} */ + @Override + ExtendedSpanBuilder setAttribute(String key, String value); + + /** {@inheritDoc} */ + @Override + ExtendedSpanBuilder setAttribute(String key, long value); + + /** {@inheritDoc} */ + @Override + ExtendedSpanBuilder setAttribute(String key, double value); + + /** {@inheritDoc} */ + @Override + ExtendedSpanBuilder setAttribute(String key, boolean value); + + /** {@inheritDoc} */ + @Override + ExtendedSpanBuilder setAttribute(AttributeKey key, T value); + + /** {@inheritDoc} */ + @Override + default ExtendedSpanBuilder setAllAttributes(Attributes attributes) { + return (ExtendedSpanBuilder) SpanBuilder.super.setAllAttributes(attributes); + } + + /** {@inheritDoc} */ + @Override + ExtendedSpanBuilder setSpanKind(SpanKind spanKind); + + /** {@inheritDoc} */ + @Override + ExtendedSpanBuilder setStartTimestamp(long startTimestamp, TimeUnit unit); + + /** {@inheritDoc} */ + @Override + default ExtendedSpanBuilder setStartTimestamp(Instant startTimestamp) { + return (ExtendedSpanBuilder) SpanBuilder.super.setStartTimestamp(startTimestamp); + } } diff --git a/api/incubator/src/test/java/io/opentelemetry/api/incubator/trace/ExtendedTraceApiUsageTest.java b/api/incubator/src/test/java/io/opentelemetry/api/incubator/trace/ExtendedTraceApiUsageTest.java index 18bc1ec78a8..3922cba7f8b 100644 --- a/api/incubator/src/test/java/io/opentelemetry/api/incubator/trace/ExtendedTraceApiUsageTest.java +++ b/api/incubator/src/test/java/io/opentelemetry/api/incubator/trace/ExtendedTraceApiUsageTest.java @@ -110,6 +110,7 @@ void startAndCallOrRun() { // Wrap the resetCheckout method in a span String cartId = ((ExtendedSpanBuilder) tracer.spanBuilder("reset_checkout_and_return")) + .setAttribute("key123", "val456") .startAndCall(() -> resetCheckoutAndReturn("abc123", /* throwException= */ false)); assertThat(cartId).isEqualTo("abc123"); // ...or runnable variation diff --git a/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/SdkSpanBuilder.java b/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/SdkSpanBuilder.java index 1a9a946ae5b..d637caa60da 100644 --- a/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/SdkSpanBuilder.java +++ b/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/SdkSpanBuilder.java @@ -68,7 +68,7 @@ final class SdkSpanBuilder implements ExtendedSpanBuilder { } @Override - public SpanBuilder setParent(Context context) { + public ExtendedSpanBuilder setParent(Context context) { if (context == null) { return this; } @@ -77,13 +77,13 @@ public SpanBuilder setParent(Context context) { } @Override - public SpanBuilder setNoParent() { + public ExtendedSpanBuilder setNoParent() { this.parent = Context.root(); return this; } @Override - public SpanBuilder setSpanKind(SpanKind spanKind) { + public ExtendedSpanBuilder setSpanKind(SpanKind spanKind) { if (spanKind == null) { return this; } @@ -92,7 +92,7 @@ public SpanBuilder setSpanKind(SpanKind spanKind) { } @Override - public SpanBuilder addLink(SpanContext spanContext) { + public ExtendedSpanBuilder addLink(SpanContext spanContext) { if (spanContext == null || !spanContext.isValid()) { return this; } @@ -101,7 +101,7 @@ public SpanBuilder addLink(SpanContext spanContext) { } @Override - public SpanBuilder addLink(SpanContext spanContext, Attributes attributes) { + public ExtendedSpanBuilder addLink(SpanContext spanContext, Attributes attributes) { if (spanContext == null || !spanContext.isValid()) { return this; } @@ -135,27 +135,27 @@ private void addLink(LinkData link) { } @Override - public SpanBuilder setAttribute(String key, String value) { + public ExtendedSpanBuilder setAttribute(String key, String value) { return setAttribute(stringKey(key), value); } @Override - public SpanBuilder setAttribute(String key, long value) { + public ExtendedSpanBuilder setAttribute(String key, long value) { return setAttribute(longKey(key), value); } @Override - public SpanBuilder setAttribute(String key, double value) { + public ExtendedSpanBuilder setAttribute(String key, double value) { return setAttribute(doubleKey(key), value); } @Override - public SpanBuilder setAttribute(String key, boolean value) { + public ExtendedSpanBuilder setAttribute(String key, boolean value) { return setAttribute(booleanKey(key), value); } @Override - public SpanBuilder setAttribute(AttributeKey key, T value) { + public ExtendedSpanBuilder setAttribute(AttributeKey key, T value) { if (key == null || key.getKey().isEmpty() || value == null) { return this; } @@ -164,7 +164,7 @@ public SpanBuilder setAttribute(AttributeKey key, T value) { } @Override - public SpanBuilder setStartTimestamp(long startTimestamp, TimeUnit unit) { + public ExtendedSpanBuilder setStartTimestamp(long startTimestamp, TimeUnit unit) { if (startTimestamp < 0 || unit == null) { return this; } From 9bfb81b66b38c4d2667239182fcb59ba23a0d749 Mon Sep 17 00:00:00 2001 From: jack-berg <34418638+jack-berg@users.noreply.github.com> Date: Wed, 26 Jun 2024 12:13:46 -0500 Subject: [PATCH 453/901] Fix CollectorIntegrationTest (#6537) --- .../exporter/prometheus/CollectorIntegrationTest.java | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/exporters/prometheus/src/test/java/io/opentelemetry/exporter/prometheus/CollectorIntegrationTest.java b/exporters/prometheus/src/test/java/io/opentelemetry/exporter/prometheus/CollectorIntegrationTest.java index c062f61bcc6..f58fdf722a2 100644 --- a/exporters/prometheus/src/test/java/io/opentelemetry/exporter/prometheus/CollectorIntegrationTest.java +++ b/exporters/prometheus/src/test/java/io/opentelemetry/exporter/prometheus/CollectorIntegrationTest.java @@ -134,9 +134,16 @@ void endToEnd() { // Resource attributes derived from the prometheus scrape config stringKeyValue("service.name", "app"), stringKeyValue("service.instance.id", "host.testcontainers.internal:" + prometheusPort), + // net.host.name, net.host.port and http.scheme are superseded by server.address, + // server.port, and url.scheme respectively and will be removed by default in a future + // collector release + // https://github.com/open-telemetry/opentelemetry-collector-contrib/pull/32829 stringKeyValue("net.host.name", "host.testcontainers.internal"), stringKeyValue("net.host.port", String.valueOf(prometheusPort)), stringKeyValue("http.scheme", "http"), + stringKeyValue("server.address", "host.testcontainers.internal"), + stringKeyValue("server.port", String.valueOf(prometheusPort)), + stringKeyValue("url.scheme", "http"), // Resource attributes from the metric SDK resource translated to target_info stringKeyValue( "service_name", From fe8a7f4baba19399d7d20ee817be5da876a14dd3 Mon Sep 17 00:00:00 2001 From: Sebastian Alfers Date: Wed, 26 Jun 2024 22:49:18 +0200 Subject: [PATCH 454/901] Fix typo in java doc for setRetryPolicy (#6503) Co-authored-by: Jack Berg --- .../otlp/http/logs/OtlpHttpLogRecordExporterBuilder.java | 2 +- .../otlp/http/metrics/OtlpHttpMetricExporterBuilder.java | 2 +- .../exporter/otlp/http/trace/OtlpHttpSpanExporterBuilder.java | 2 +- .../exporter/otlp/logs/OtlpGrpcLogRecordExporterBuilder.java | 2 +- .../exporter/otlp/metrics/OtlpGrpcMetricExporterBuilder.java | 2 +- .../exporter/otlp/trace/OtlpGrpcSpanExporterBuilder.java | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/logs/OtlpHttpLogRecordExporterBuilder.java b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/logs/OtlpHttpLogRecordExporterBuilder.java index 364be52a6b3..615f79fabe1 100644 --- a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/logs/OtlpHttpLogRecordExporterBuilder.java +++ b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/logs/OtlpHttpLogRecordExporterBuilder.java @@ -166,7 +166,7 @@ public OtlpHttpLogRecordExporterBuilder setSslContext( } /** - * Ses the retry policy. Retry is disabled by default. + * Set the retry policy. Retry is disabled by default. * * @since 1.28.0 */ diff --git a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/metrics/OtlpHttpMetricExporterBuilder.java b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/metrics/OtlpHttpMetricExporterBuilder.java index 539df4430be..f187d5a0696 100644 --- a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/metrics/OtlpHttpMetricExporterBuilder.java +++ b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/metrics/OtlpHttpMetricExporterBuilder.java @@ -212,7 +212,7 @@ public OtlpHttpMetricExporterBuilder setDefaultAggregationSelector( } /** - * Ses the retry policy. Retry is disabled by default. + * Set the retry policy. Retry is disabled by default. * * @since 1.28.0 */ diff --git a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/trace/OtlpHttpSpanExporterBuilder.java b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/trace/OtlpHttpSpanExporterBuilder.java index a05735ae092..6e5f27a8c5e 100644 --- a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/trace/OtlpHttpSpanExporterBuilder.java +++ b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/trace/OtlpHttpSpanExporterBuilder.java @@ -167,7 +167,7 @@ public OtlpHttpSpanExporterBuilder setSslContext( } /** - * Ses the retry policy. Retry is disabled by default. + * Set the retry policy. Retry is disabled by default. * * @since 1.28.0 */ diff --git a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/logs/OtlpGrpcLogRecordExporterBuilder.java b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/logs/OtlpGrpcLogRecordExporterBuilder.java index 0889105f7f7..ade585dbf70 100644 --- a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/logs/OtlpGrpcLogRecordExporterBuilder.java +++ b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/logs/OtlpGrpcLogRecordExporterBuilder.java @@ -210,7 +210,7 @@ public OtlpGrpcLogRecordExporterBuilder setHeaders(Supplier> } /** - * Ses the retry policy. Retry is disabled by default. + * Set the retry policy. Retry is disabled by default. * * @since 1.28.0 */ diff --git a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/metrics/OtlpGrpcMetricExporterBuilder.java b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/metrics/OtlpGrpcMetricExporterBuilder.java index 51282d574f7..5937d4a1f1a 100644 --- a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/metrics/OtlpGrpcMetricExporterBuilder.java +++ b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/metrics/OtlpGrpcMetricExporterBuilder.java @@ -256,7 +256,7 @@ public OtlpGrpcMetricExporterBuilder setDefaultAggregationSelector( } /** - * Ses the retry policy. Retry is disabled by default. + * Set the retry policy. Retry is disabled by default. * * @since 1.28.0 */ diff --git a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/trace/OtlpGrpcSpanExporterBuilder.java b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/trace/OtlpGrpcSpanExporterBuilder.java index c2c631fd04a..b6455d6c5a9 100644 --- a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/trace/OtlpGrpcSpanExporterBuilder.java +++ b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/trace/OtlpGrpcSpanExporterBuilder.java @@ -207,7 +207,7 @@ public OtlpGrpcSpanExporterBuilder setHeaders(Supplier> head } /** - * Ses the retry policy. Retry is disabled by default. + * Set the retry policy. Retry is disabled by default. * * @since 1.28.0 */ From 4086210ba9b0c98da7f83ab77f147d0d8f214bf5 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 27 Jun 2024 10:49:08 -0700 Subject: [PATCH 455/901] Update dependency org.junit:junit-bom to v5.10.3 (#6542) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- dependencyManagement/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index 735ac89c56e..21ed0758e28 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -19,7 +19,7 @@ val DEPENDENCY_BOMS = listOf( "io.zipkin.brave:brave-bom:6.0.3", "io.zipkin.reporter2:zipkin-reporter-bom:3.4.0", "org.assertj:assertj-bom:3.26.0", - "org.junit:junit-bom:5.10.2", + "org.junit:junit-bom:5.10.3", "org.testcontainers:testcontainers-bom:1.19.8", "org.snakeyaml:snakeyaml-engine:2.7" ) From 021e7fe4704cb209bf4b340c2061da232a33448d Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 28 Jun 2024 09:18:23 -0700 Subject: [PATCH 456/901] Update dependency io.grpc:grpc-bom to v1.65.0 (#6544) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- dependencyManagement/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index 21ed0758e28..da7efd95f2f 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -14,7 +14,7 @@ val DEPENDENCY_BOMS = listOf( "com.linecorp.armeria:armeria-bom:1.29.0", "com.squareup.okhttp3:okhttp-bom:4.12.0", "com.squareup.okio:okio-bom:3.9.0", // applies to transitive dependencies of okhttp - "io.grpc:grpc-bom:1.64.0", + "io.grpc:grpc-bom:1.65.0", "io.netty:netty-bom:4.1.111.Final", "io.zipkin.brave:brave-bom:6.0.3", "io.zipkin.reporter2:zipkin-reporter-bom:3.4.0", From ed46fa36d01d6e366eae70fc77ae6c46a162c39b Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 28 Jun 2024 09:21:03 -0700 Subject: [PATCH 457/901] Update dependency com.linecorp.armeria:armeria-bom to v1.29.1 (#6543) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- dependencyManagement/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index da7efd95f2f..be6e5fa7546 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -11,7 +11,7 @@ val DEPENDENCY_BOMS = listOf( "com.fasterxml.jackson:jackson-bom:2.17.1", "com.google.guava:guava-bom:33.2.1-jre", "com.google.protobuf:protobuf-bom:3.25.3", - "com.linecorp.armeria:armeria-bom:1.29.0", + "com.linecorp.armeria:armeria-bom:1.29.1", "com.squareup.okhttp3:okhttp-bom:4.12.0", "com.squareup.okio:okio-bom:3.9.0", // applies to transitive dependencies of okhttp "io.grpc:grpc-bom:1.65.0", From c1ff34c2bef1d13cde09ce3cc1021bbca314e43d Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 28 Jun 2024 12:44:33 -0700 Subject: [PATCH 458/901] Update dependency net.ltgt.gradle:gradle-errorprone-plugin to v4.0.1 (#6533) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- buildSrc/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts index 68542ea0b13..2006e0b7aeb 100644 --- a/buildSrc/build.gradle.kts +++ b/buildSrc/build.gradle.kts @@ -63,7 +63,7 @@ dependencies { implementation("gradle.plugin.io.morethan.jmhreport:gradle-jmh-report:0.9.6") implementation("me.champeau.gradle:japicmp-gradle-plugin:0.4.3") implementation("me.champeau.jmh:jmh-gradle-plugin:0.7.2") - implementation("net.ltgt.gradle:gradle-errorprone-plugin:4.0.0") + implementation("net.ltgt.gradle:gradle-errorprone-plugin:4.0.1") implementation("net.ltgt.gradle:gradle-nullaway-plugin:2.0.0") implementation("org.jetbrains.kotlin:kotlin-gradle-plugin:2.0.0") implementation("org.owasp:dependency-check-gradle:9.2.0") From 22aaae8d441fb38479ace65ff449b5521d537983 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 29 Jun 2024 15:43:36 -0700 Subject: [PATCH 459/901] Update dependency org.skyscreamer:jsonassert to v1.5.3 (#6535) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- dependencyManagement/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index be6e5fa7546..070606a7172 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -79,7 +79,7 @@ val DEPENDENCIES = listOf( "org.jctools:jctools-core:4.0.5", "org.junit-pioneer:junit-pioneer:1.9.1", "org.mock-server:mockserver-netty:5.15.0:shaded", - "org.skyscreamer:jsonassert:1.5.1", + "org.skyscreamer:jsonassert:1.5.3", "com.android.tools:desugar_jdk_libs:2.0.4", ) From b56af03b995f1d0da7a1bc91a9588600d02faabd Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 1 Jul 2024 15:45:39 -0500 Subject: [PATCH 460/901] Update dependency io.opentelemetry.proto:opentelemetry-proto to v1.3.1-alpha (#6442) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Co-authored-by: Jack Berg --- dependencyManagement/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index 070606a7172..3c7685c98fe 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -67,7 +67,7 @@ val DEPENDENCIES = listOf( "io.jaegertracing:jaeger-client:1.8.1", "io.opentelemetry.contrib:opentelemetry-aws-xray-propagator:1.29.0-alpha", "io.opentelemetry.semconv:opentelemetry-semconv-incubating:1.25.0-alpha", - "io.opentelemetry.proto:opentelemetry-proto:1.2.0-alpha", + "io.opentelemetry.proto:opentelemetry-proto:1.3.2-alpha", "io.opentracing:opentracing-api:0.33.0", "io.opentracing:opentracing-noop:0.33.0", "io.prometheus:prometheus-metrics-exporter-httpserver:1.3.1", From 9fd6bcae9e582ddbc8668974d7d0efb2984b6aaa Mon Sep 17 00:00:00 2001 From: jack-berg <34418638+jack-berg@users.noreply.github.com> Date: Tue, 2 Jul 2024 17:25:23 -0500 Subject: [PATCH 461/901] Fix build after recent collector release (#6548) --- .../src/test/resources/otel-config.yaml | 9 +++++---- .../otlp/src/main/resources/otel-config.yaml | 19 ++++++++++--------- 2 files changed, 15 insertions(+), 13 deletions(-) diff --git a/exporters/prometheus/src/test/resources/otel-config.yaml b/exporters/prometheus/src/test/resources/otel-config.yaml index 1db8afa45db..649f8ba6d12 100644 --- a/exporters/prometheus/src/test/resources/otel-config.yaml +++ b/exporters/prometheus/src/test/resources/otel-config.yaml @@ -1,5 +1,6 @@ extensions: - health_check: {} + health_check: + endpoint: 0.0.0.0:13133 receivers: prometheus: config: @@ -7,12 +8,12 @@ receivers: - job_name: 'app' scrape_interval: 1s static_configs: - - targets: ['$APP_ENDPOINT'] + - targets: ['${APP_ENDPOINT}'] exporters: logging: - verbosity: $LOGGING_EXPORTER_VERBOSITY + verbosity: ${LOGGING_EXPORTER_VERBOSITY} otlp: - endpoint: $OTLP_EXPORTER_ENDPOINT + endpoint: ${OTLP_EXPORTER_ENDPOINT} tls: insecure: true compression: none diff --git a/integration-tests/otlp/src/main/resources/otel-config.yaml b/integration-tests/otlp/src/main/resources/otel-config.yaml index a58cf409526..e554f766b8e 100644 --- a/integration-tests/otlp/src/main/resources/otel-config.yaml +++ b/integration-tests/otlp/src/main/resources/otel-config.yaml @@ -1,5 +1,6 @@ extensions: - health_check: {} + health_check: + endpoint: 0.0.0.0:13133 receivers: otlp: protocols: @@ -12,20 +13,20 @@ receivers: grpc: endpoint: 0.0.0.0:5317 tls: - client_ca_file: $MTLS_CLIENT_CERTIFICATE - cert_file: $MTLS_SERVER_CERTIFICATE - key_file: $MTLS_SERVER_KEY + client_ca_file: ${MTLS_CLIENT_CERTIFICATE} + cert_file: ${MTLS_SERVER_CERTIFICATE} + key_file: ${MTLS_SERVER_KEY} http: endpoint: 0.0.0.0:5318 tls: - client_ca_file: $MTLS_CLIENT_CERTIFICATE - cert_file: $MTLS_SERVER_CERTIFICATE - key_file: $MTLS_SERVER_KEY + client_ca_file: ${MTLS_CLIENT_CERTIFICATE} + cert_file: ${MTLS_SERVER_CERTIFICATE} + key_file: ${MTLS_SERVER_KEY} exporters: logging: - verbosity: $LOGGING_EXPORTER_VERBOSITY_LEVEL + verbosity: ${LOGGING_EXPORTER_VERBOSITY_LEVEL} otlp: - endpoint: $OTLP_EXPORTER_ENDPOINT + endpoint: ${OTLP_EXPORTER_ENDPOINT} tls: insecure: true compression: none From 1f7d6a507e4032dca9d13f8d8b113f37f1c999d4 Mon Sep 17 00:00:00 2001 From: jack-berg <34418638+jack-berg@users.noreply.github.com> Date: Wed, 3 Jul 2024 15:34:18 -0500 Subject: [PATCH 462/901] Add APIs to determine if tracer, logger, instruments are enabled (#6502) --- api/incubator/README.md | 3 + .../api/incubator/logs/ExtendedLogger.java | 23 +++ .../metrics/ExtendedDoubleCounter.java | 26 +++ .../metrics/ExtendedDoubleGauge.java | 26 +++ .../metrics/ExtendedDoubleHistogram.java | 26 +++ .../metrics/ExtendedDoubleUpDownCounter.java | 26 +++ .../metrics/ExtendedLongCounter.java | 27 +++ .../incubator/metrics/ExtendedLongGauge.java | 26 +++ .../metrics/ExtendedLongHistogram.java | 26 +++ .../metrics/ExtendedLongUpDownCounter.java | 26 +++ .../api/incubator/trace/ExtendedTracer.java | 23 +++ .../logs/ExtendedLogsBridgeApiUsageTest.java | 61 +++++++ .../metrics/ExtendedMetricsApiUsageTest.java | 56 +++++++ .../trace/ExtendedTraceApiUsageTest.java | 60 +++++++ .../io/opentelemetry/sdk/logs/SdkLogger.java | 14 +- .../sdk/logs/LoggerConfigTest.java | 5 + .../sdk/metrics/InstrumentBuilder.java | 14 +- .../sdk/metrics/SdkDoubleCounter.java | 16 +- .../sdk/metrics/SdkDoubleGauge.java | 16 +- .../sdk/metrics/SdkDoubleHistogram.java | 16 +- .../sdk/metrics/SdkDoubleUpDownCounter.java | 16 +- .../sdk/metrics/SdkLongCounter.java | 16 +- .../sdk/metrics/SdkLongGauge.java | 16 +- .../sdk/metrics/SdkLongHistogram.java | 16 +- .../sdk/metrics/SdkLongUpDownCounter.java | 15 +- .../opentelemetry/sdk/metrics/SdkMeter.java | 16 +- .../DefaultSynchronousMetricStorage.java | 5 + .../internal/state/EmptyMetricStorage.java | 5 + .../internal/state/MeterSharedState.java | 26 ++- .../state/MultiWritableMetricStorage.java | 10 ++ .../state/WriteableMetricStorage.java | 6 + .../sdk/metrics/InstrumentBuilderTest.java | 3 +- .../sdk/metrics/MeterConfigTest.java | 157 ++++++++++++++---- .../metrics/SdkObservableInstrumentTest.java | 7 +- .../state/MetricStorageRegistryTest.java | 5 + .../io/opentelemetry/sdk/trace/SdkTracer.java | 14 +- .../sdk/trace/TracerConfigTest.java | 5 + 37 files changed, 773 insertions(+), 81 deletions(-) create mode 100644 api/incubator/src/main/java/io/opentelemetry/api/incubator/logs/ExtendedLogger.java create mode 100644 api/incubator/src/main/java/io/opentelemetry/api/incubator/metrics/ExtendedDoubleCounter.java create mode 100644 api/incubator/src/main/java/io/opentelemetry/api/incubator/metrics/ExtendedDoubleGauge.java create mode 100644 api/incubator/src/main/java/io/opentelemetry/api/incubator/metrics/ExtendedDoubleHistogram.java create mode 100644 api/incubator/src/main/java/io/opentelemetry/api/incubator/metrics/ExtendedDoubleUpDownCounter.java create mode 100644 api/incubator/src/main/java/io/opentelemetry/api/incubator/metrics/ExtendedLongCounter.java create mode 100644 api/incubator/src/main/java/io/opentelemetry/api/incubator/metrics/ExtendedLongGauge.java create mode 100644 api/incubator/src/main/java/io/opentelemetry/api/incubator/metrics/ExtendedLongHistogram.java create mode 100644 api/incubator/src/main/java/io/opentelemetry/api/incubator/metrics/ExtendedLongUpDownCounter.java create mode 100644 api/incubator/src/main/java/io/opentelemetry/api/incubator/trace/ExtendedTracer.java diff --git a/api/incubator/README.md b/api/incubator/README.md index 84e10a2a78b..ccd4678df43 100644 --- a/api/incubator/README.md +++ b/api/incubator/README.md @@ -14,6 +14,7 @@ See [EventApiUsageTest](./src/test/java/io/opentelemetry/api/incubator/events/Ev Features: +* Check if logger is enabled before emitting logs to avoid uneccessary computation * Set AnyValue log record body with arbitrarily complex data See [ExtendedLogsBridgeApiUsageTest](./src/test/java/io/opentelemetry/api/incubator/logs/ExtendedLogsBridgeApiUsageTest.java). @@ -30,6 +31,7 @@ See [ExtendedMetricsApiUsageTest](./src/test/java/io/opentelemetry/api/incubator Features: +* Check if instrument is enabled before recording measurements to avoid uneccessary computation * Simplified injection / extraction of context See [ExtendedContextPropagatorsUsageTest](./src/test/java/io/opentelemetry/api/incubator/propagation/ExtendedContextPropagatorsUsageTest.java). @@ -38,6 +40,7 @@ See [ExtendedContextPropagatorsUsageTest](./src/test/java/io/opentelemetry/api/i Features: +* Check if tracer is enabled before starting spans to avoid uneccessary computation * Utility methods to reduce boilerplace using span API, including extracting context, and wrapping runnables / callables with spans See [ExtendedTraceApiUsageTest](./src/test/java/io/opentelemetry/api/incubator/trace/ExtendedTraceApiUsageTest.java). diff --git a/api/incubator/src/main/java/io/opentelemetry/api/incubator/logs/ExtendedLogger.java b/api/incubator/src/main/java/io/opentelemetry/api/incubator/logs/ExtendedLogger.java new file mode 100644 index 00000000000..db5e2a3b029 --- /dev/null +++ b/api/incubator/src/main/java/io/opentelemetry/api/incubator/logs/ExtendedLogger.java @@ -0,0 +1,23 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.api.incubator.logs; + +import io.opentelemetry.api.logs.Logger; + +/** Extended {@link Logger} with experimental APIs. */ +public interface ExtendedLogger extends Logger { + + /** + * Returns {@code true} if the logger is enabled. + * + *

      This allows callers to avoid unnecessary compute when nothing is consuming the data. Because + * the response is subject to change over the application, callers should call this before each + * call to {@link #logRecordBuilder()}. + */ + default boolean isEnabled() { + return true; + } +} diff --git a/api/incubator/src/main/java/io/opentelemetry/api/incubator/metrics/ExtendedDoubleCounter.java b/api/incubator/src/main/java/io/opentelemetry/api/incubator/metrics/ExtendedDoubleCounter.java new file mode 100644 index 00000000000..4345661ebe5 --- /dev/null +++ b/api/incubator/src/main/java/io/opentelemetry/api/incubator/metrics/ExtendedDoubleCounter.java @@ -0,0 +1,26 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.api.incubator.metrics; + +import io.opentelemetry.api.common.Attributes; +import io.opentelemetry.api.metrics.DoubleCounter; +import io.opentelemetry.context.Context; + +/** Extended {@link DoubleCounter} with experimental APIs. */ +public interface ExtendedDoubleCounter extends DoubleCounter { + + /** + * Returns {@code true} if the counter is enabled. + * + *

      This allows callers to avoid unnecessary compute when nothing is consuming the data. Because + * the response is subject to change over the application, callers should call this before each + * call to {@link #add(double)}, {@link #add(double, Attributes)}, or {@link #add(double, + * Attributes, Context)}. + */ + default boolean isEnabled() { + return true; + } +} diff --git a/api/incubator/src/main/java/io/opentelemetry/api/incubator/metrics/ExtendedDoubleGauge.java b/api/incubator/src/main/java/io/opentelemetry/api/incubator/metrics/ExtendedDoubleGauge.java new file mode 100644 index 00000000000..d9a56f7a391 --- /dev/null +++ b/api/incubator/src/main/java/io/opentelemetry/api/incubator/metrics/ExtendedDoubleGauge.java @@ -0,0 +1,26 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.api.incubator.metrics; + +import io.opentelemetry.api.common.Attributes; +import io.opentelemetry.api.metrics.DoubleGauge; +import io.opentelemetry.context.Context; + +/** Extended {@link DoubleGauge} with experimental APIs. */ +public interface ExtendedDoubleGauge extends DoubleGauge { + + /** + * Returns {@code true} if the gauge is enabled. + * + *

      This allows callers to avoid unnecessary compute when nothing is consuming the data. Because + * the response is subject to change over the application, callers should call this before each + * call to {@link #set(double)}, {@link #set(double, Attributes)}, or {@link #set(double, + * Attributes, Context)}. + */ + default boolean isEnabled() { + return true; + } +} diff --git a/api/incubator/src/main/java/io/opentelemetry/api/incubator/metrics/ExtendedDoubleHistogram.java b/api/incubator/src/main/java/io/opentelemetry/api/incubator/metrics/ExtendedDoubleHistogram.java new file mode 100644 index 00000000000..0a481afef2b --- /dev/null +++ b/api/incubator/src/main/java/io/opentelemetry/api/incubator/metrics/ExtendedDoubleHistogram.java @@ -0,0 +1,26 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.api.incubator.metrics; + +import io.opentelemetry.api.common.Attributes; +import io.opentelemetry.api.metrics.DoubleHistogram; +import io.opentelemetry.context.Context; + +/** Extended {@link DoubleHistogram} with experimental APIs. */ +public interface ExtendedDoubleHistogram extends DoubleHistogram { + + /** + * Returns {@code true} if the histogram is enabled. + * + *

      This allows callers to avoid unnecessary compute when nothing is consuming the data. Because + * the response is subject to change over the application, callers should call this before each + * call to {@link #record(double)}, {@link #record(double, Attributes)}, or {@link #record(double, + * Attributes, Context)}. + */ + default boolean isEnabled() { + return true; + } +} diff --git a/api/incubator/src/main/java/io/opentelemetry/api/incubator/metrics/ExtendedDoubleUpDownCounter.java b/api/incubator/src/main/java/io/opentelemetry/api/incubator/metrics/ExtendedDoubleUpDownCounter.java new file mode 100644 index 00000000000..6dbb91f1d6f --- /dev/null +++ b/api/incubator/src/main/java/io/opentelemetry/api/incubator/metrics/ExtendedDoubleUpDownCounter.java @@ -0,0 +1,26 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.api.incubator.metrics; + +import io.opentelemetry.api.common.Attributes; +import io.opentelemetry.api.metrics.DoubleUpDownCounter; +import io.opentelemetry.context.Context; + +/** Extended {@link DoubleUpDownCounter} with experimental APIs. */ +public interface ExtendedDoubleUpDownCounter extends DoubleUpDownCounter { + + /** + * Returns {@code true} if the up down counter is enabled. + * + *

      This allows callers to avoid unnecessary compute when nothing is consuming the data. Because + * the response is subject to change over the application, callers should call this before each + * call to {@link #add(double)}, {@link #add(double, Attributes)}, or {@link #add(double, + * Attributes, Context)}. + */ + default boolean isEnabled() { + return true; + } +} diff --git a/api/incubator/src/main/java/io/opentelemetry/api/incubator/metrics/ExtendedLongCounter.java b/api/incubator/src/main/java/io/opentelemetry/api/incubator/metrics/ExtendedLongCounter.java new file mode 100644 index 00000000000..0ff67a38fb9 --- /dev/null +++ b/api/incubator/src/main/java/io/opentelemetry/api/incubator/metrics/ExtendedLongCounter.java @@ -0,0 +1,27 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.api.incubator.metrics; + +import io.opentelemetry.api.common.Attributes; +import io.opentelemetry.api.metrics.DoubleCounter; +import io.opentelemetry.api.metrics.LongCounter; +import io.opentelemetry.context.Context; + +/** Extended {@link DoubleCounter} with experimental APIs. */ +public interface ExtendedLongCounter extends LongCounter { + + /** + * Returns {@code true} if the counter is enabled. + * + *

      This allows callers to avoid unnecessary compute when nothing is consuming the data. Because + * the response is subject to change over the application, callers should call this before each + * call to {@link #add(long)}, {@link #add(long, Attributes)}, or {@link #add(long, Attributes, + * Context)}. + */ + default boolean isEnabled() { + return true; + } +} diff --git a/api/incubator/src/main/java/io/opentelemetry/api/incubator/metrics/ExtendedLongGauge.java b/api/incubator/src/main/java/io/opentelemetry/api/incubator/metrics/ExtendedLongGauge.java new file mode 100644 index 00000000000..7a660d0e007 --- /dev/null +++ b/api/incubator/src/main/java/io/opentelemetry/api/incubator/metrics/ExtendedLongGauge.java @@ -0,0 +1,26 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.api.incubator.metrics; + +import io.opentelemetry.api.common.Attributes; +import io.opentelemetry.api.metrics.LongGauge; +import io.opentelemetry.context.Context; + +/** Extended {@link LongGauge} with experimental APIs. */ +public interface ExtendedLongGauge extends LongGauge { + + /** + * Returns {@code true} if the gauge is enabled. + * + *

      This allows callers to avoid unnecessary compute when nothing is consuming the data. Because + * the response is subject to change over the application, callers should call this before each + * call to {@link #set(long)}, {@link #set(long, Attributes)}, or {@link #set(long, Attributes, + * Context)}. + */ + default boolean isEnabled() { + return true; + } +} diff --git a/api/incubator/src/main/java/io/opentelemetry/api/incubator/metrics/ExtendedLongHistogram.java b/api/incubator/src/main/java/io/opentelemetry/api/incubator/metrics/ExtendedLongHistogram.java new file mode 100644 index 00000000000..d1cd303fb7d --- /dev/null +++ b/api/incubator/src/main/java/io/opentelemetry/api/incubator/metrics/ExtendedLongHistogram.java @@ -0,0 +1,26 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.api.incubator.metrics; + +import io.opentelemetry.api.common.Attributes; +import io.opentelemetry.api.metrics.LongHistogram; +import io.opentelemetry.context.Context; + +/** Extended {@link LongHistogram} with experimental APIs. */ +public interface ExtendedLongHistogram extends LongHistogram { + + /** + * Returns {@code true} if the histogram is enabled. + * + *

      This allows callers to avoid unnecessary compute when nothing is consuming the data. Because + * the response is subject to change over the application, callers should call this before each + * call to {@link #record(long)}, {@link #record(long, Attributes)}, or {@link #record(long, + * Attributes, Context)}. + */ + default boolean isEnabled() { + return true; + } +} diff --git a/api/incubator/src/main/java/io/opentelemetry/api/incubator/metrics/ExtendedLongUpDownCounter.java b/api/incubator/src/main/java/io/opentelemetry/api/incubator/metrics/ExtendedLongUpDownCounter.java new file mode 100644 index 00000000000..7327ed43842 --- /dev/null +++ b/api/incubator/src/main/java/io/opentelemetry/api/incubator/metrics/ExtendedLongUpDownCounter.java @@ -0,0 +1,26 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.api.incubator.metrics; + +import io.opentelemetry.api.common.Attributes; +import io.opentelemetry.api.metrics.LongUpDownCounter; +import io.opentelemetry.context.Context; + +/** Extended {@link LongUpDownCounter} with experimental APIs. */ +public interface ExtendedLongUpDownCounter extends LongUpDownCounter { + + /** + * Returns {@code true} if the up down counter is enabled. + * + *

      This allows callers to avoid unnecessary compute when nothing is consuming the data. Because + * the response is subject to change over the application, callers should call this before each + * call to {@link #add(long)}, {@link #add(long, Attributes)}, or {@link #add(long, Attributes, + * Context)}. + */ + default boolean isEnabled() { + return true; + } +} diff --git a/api/incubator/src/main/java/io/opentelemetry/api/incubator/trace/ExtendedTracer.java b/api/incubator/src/main/java/io/opentelemetry/api/incubator/trace/ExtendedTracer.java new file mode 100644 index 00000000000..cb2cae27c24 --- /dev/null +++ b/api/incubator/src/main/java/io/opentelemetry/api/incubator/trace/ExtendedTracer.java @@ -0,0 +1,23 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.api.incubator.trace; + +import io.opentelemetry.api.trace.Tracer; + +/** Extended {@link Tracer} with experimental APIs. */ +public interface ExtendedTracer extends Tracer { + + /** + * Returns {@code true} if the tracer is enabled. + * + *

      This allows callers to avoid unnecessary compute when nothing is consuming the data. Because + * the response is subject to change over the application, callers should call this before each + * call to {@link #spanBuilder(String)}. + */ + default boolean isEnabled() { + return true; + } +} diff --git a/api/incubator/src/test/java/io/opentelemetry/api/incubator/logs/ExtendedLogsBridgeApiUsageTest.java b/api/incubator/src/test/java/io/opentelemetry/api/incubator/logs/ExtendedLogsBridgeApiUsageTest.java index 7a1f82e64d0..7a3d7c82e17 100644 --- a/api/incubator/src/test/java/io/opentelemetry/api/incubator/logs/ExtendedLogsBridgeApiUsageTest.java +++ b/api/incubator/src/test/java/io/opentelemetry/api/incubator/logs/ExtendedLogsBridgeApiUsageTest.java @@ -5,21 +5,82 @@ package io.opentelemetry.api.incubator.logs; +import static io.opentelemetry.sdk.internal.ScopeConfiguratorBuilder.nameEquals; +import static io.opentelemetry.sdk.logs.internal.LoggerConfig.disabled; import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.assertThat; import com.google.common.collect.ImmutableMap; +import io.opentelemetry.api.common.Attributes; import io.opentelemetry.api.logs.Logger; import io.opentelemetry.sdk.logs.SdkLoggerProvider; +import io.opentelemetry.sdk.logs.SdkLoggerProviderBuilder; import io.opentelemetry.sdk.logs.export.SimpleLogRecordProcessor; import io.opentelemetry.sdk.logs.internal.AnyValueBody; +import io.opentelemetry.sdk.logs.internal.SdkLoggerProviderUtil; import io.opentelemetry.sdk.resources.Resource; import io.opentelemetry.sdk.testing.exporter.InMemoryLogRecordExporter; +import java.util.Random; import java.util.concurrent.TimeUnit; import org.junit.jupiter.api.Test; /** Demonstrating usage of extended Logs Bridge API. */ class ExtendedLogsBridgeApiUsageTest { + @Test + void loggerEnabled() { + // Setup SdkLoggerProvider + InMemoryLogRecordExporter exporter = InMemoryLogRecordExporter.create(); + SdkLoggerProviderBuilder loggerProviderBuilder = + SdkLoggerProvider.builder() + // Default resource used for demonstration purposes + .setResource(Resource.getDefault()) + // In-memory exporter used for demonstration purposes + .addLogRecordProcessor(SimpleLogRecordProcessor.create(exporter)); + // Disable loggerB + SdkLoggerProviderUtil.addLoggerConfiguratorCondition( + loggerProviderBuilder, nameEquals("loggerB"), disabled()); + SdkLoggerProvider loggerProvider = loggerProviderBuilder.build(); + + // Create loggerA and loggerB + ExtendedLogger loggerA = (ExtendedLogger) loggerProvider.get("loggerA"); + ExtendedLogger loggerB = (ExtendedLogger) loggerProvider.get("loggerB"); + + // Check if logger is enabled before emitting log and avoid unnecessary computation + if (loggerA.isEnabled()) { + loggerA + .logRecordBuilder() + .setBody("hello world!") + .setAllAttributes(Attributes.builder().put("result", flipCoin()).build()) + .emit(); + } + if (loggerB.isEnabled()) { + loggerB + .logRecordBuilder() + .setBody("hello world!") + .setAllAttributes(Attributes.builder().put("result", flipCoin()).build()) + .emit(); + } + + // loggerA is enabled, loggerB is disabled + assertThat(loggerA.isEnabled()).isTrue(); + assertThat(loggerB.isEnabled()).isFalse(); + + // Collected data only consists of logs from loggerA. Note, loggerB's logs would be + // omitted from the results even if logs were emitted. The check if enabled simply avoids + // unnecessary computation. + assertThat(exporter.getFinishedLogRecordItems()) + .allSatisfy( + logRecordData -> + assertThat(logRecordData.getInstrumentationScopeInfo().getName()) + .isEqualTo("loggerA")); + } + + private static final Random random = new Random(); + + private static String flipCoin() { + return random.nextBoolean() ? "heads" : "tails"; + } + @Test void extendedLogRecordBuilderUsage() { // Setup SdkLoggerProvider diff --git a/api/incubator/src/test/java/io/opentelemetry/api/incubator/metrics/ExtendedMetricsApiUsageTest.java b/api/incubator/src/test/java/io/opentelemetry/api/incubator/metrics/ExtendedMetricsApiUsageTest.java index 5ae6297a2c7..09cda254e18 100644 --- a/api/incubator/src/test/java/io/opentelemetry/api/incubator/metrics/ExtendedMetricsApiUsageTest.java +++ b/api/incubator/src/test/java/io/opentelemetry/api/incubator/metrics/ExtendedMetricsApiUsageTest.java @@ -5,6 +5,8 @@ package io.opentelemetry.api.incubator.metrics; +import static io.opentelemetry.sdk.internal.ScopeConfiguratorBuilder.nameEquals; +import static io.opentelemetry.sdk.metrics.internal.MeterConfig.disabled; import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.assertThat; import com.google.common.collect.ImmutableList; @@ -15,14 +17,68 @@ import io.opentelemetry.api.metrics.Meter; import io.opentelemetry.sdk.metrics.InstrumentSelector; import io.opentelemetry.sdk.metrics.SdkMeterProvider; +import io.opentelemetry.sdk.metrics.SdkMeterProviderBuilder; import io.opentelemetry.sdk.metrics.View; +import io.opentelemetry.sdk.metrics.internal.SdkMeterProviderUtil; import io.opentelemetry.sdk.resources.Resource; import io.opentelemetry.sdk.testing.exporter.InMemoryMetricReader; +import java.util.Random; import org.junit.jupiter.api.Test; /** Demonstrating usage of extended Metrics API. */ class ExtendedMetricsApiUsageTest { + @Test + void meterEnabled() { + // Setup SdkMeterProvider + InMemoryMetricReader reader = InMemoryMetricReader.create(); + SdkMeterProviderBuilder meterProviderBuilder = + SdkMeterProvider.builder() + // Default resource used for demonstration purposes + .setResource(Resource.getDefault()) + // In-memory reader used for demonstration purposes + .registerMetricReader(reader); + // Disable meterB + SdkMeterProviderUtil.addMeterConfiguratorCondition( + meterProviderBuilder, nameEquals("meterB"), disabled()); + SdkMeterProvider meterProvider = meterProviderBuilder.build(); + + // Create meterA and meterB, and corresponding instruments + Meter meterA = meterProvider.get("meterA"); + Meter meterB = meterProvider.get("meterB"); + ExtendedDoubleHistogram histogramA = + (ExtendedDoubleHistogram) meterA.histogramBuilder("histogramA").build(); + ExtendedDoubleHistogram histogramB = + (ExtendedDoubleHistogram) meterB.histogramBuilder("histogramB").build(); + + // Check if instrument is enabled before recording measurement and avoid unnecessary computation + if (histogramA.isEnabled()) { + histogramA.record(1.0, Attributes.builder().put("result", flipCoin()).build()); + } + if (histogramB.isEnabled()) { + histogramA.record(1.0, Attributes.builder().put("result", flipCoin()).build()); + } + + // histogramA is enabled since meterA is enabled, histogramB is disabled since meterB is + // disabled + assertThat(histogramA.isEnabled()).isTrue(); + assertThat(histogramB.isEnabled()).isFalse(); + + // Collected data only consists of metrics from meterA. Note, meterB's histogramB would be + // omitted from the results even if values were recorded. The check if enabled simply avoids + // unnecessary computation. + assertThat(reader.collectAllMetrics()) + .allSatisfy( + metric -> + assertThat(metric.getInstrumentationScopeInfo().getName()).isEqualTo("meterA")); + } + + private static final Random random = new Random(); + + private static String flipCoin() { + return random.nextBoolean() ? "heads" : "tails"; + } + @Test void attributesAdvice() { // Setup SdkMeterProvider diff --git a/api/incubator/src/test/java/io/opentelemetry/api/incubator/trace/ExtendedTraceApiUsageTest.java b/api/incubator/src/test/java/io/opentelemetry/api/incubator/trace/ExtendedTraceApiUsageTest.java index 3922cba7f8b..40bf10454de 100644 --- a/api/incubator/src/test/java/io/opentelemetry/api/incubator/trace/ExtendedTraceApiUsageTest.java +++ b/api/incubator/src/test/java/io/opentelemetry/api/incubator/trace/ExtendedTraceApiUsageTest.java @@ -5,9 +5,12 @@ package io.opentelemetry.api.incubator.trace; +import static io.opentelemetry.sdk.internal.ScopeConfiguratorBuilder.nameEquals; import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.assertThat; +import static io.opentelemetry.sdk.trace.internal.TracerConfig.disabled; import io.opentelemetry.api.common.AttributeKey; +import io.opentelemetry.api.common.Attributes; import io.opentelemetry.api.trace.Span; import io.opentelemetry.api.trace.SpanContext; import io.opentelemetry.api.trace.TraceFlags; @@ -21,16 +24,73 @@ import io.opentelemetry.sdk.testing.exporter.InMemorySpanExporter; import io.opentelemetry.sdk.trace.IdGenerator; import io.opentelemetry.sdk.trace.SdkTracerProvider; +import io.opentelemetry.sdk.trace.SdkTracerProviderBuilder; import io.opentelemetry.sdk.trace.data.StatusData; import io.opentelemetry.sdk.trace.export.SimpleSpanProcessor; +import io.opentelemetry.sdk.trace.internal.SdkTracerProviderUtil; import java.util.HashMap; import java.util.Map; +import java.util.Random; import java.util.function.BiConsumer; import org.junit.jupiter.api.Test; /** Demonstrating usage of extended Trace API. */ class ExtendedTraceApiUsageTest { + @Test + void tracerEnabled() { + // Setup SdkTracerProvider + InMemorySpanExporter exporter = InMemorySpanExporter.create(); + SdkTracerProviderBuilder tracerProviderBuilder = + SdkTracerProvider.builder() + // Default resource used for demonstration purposes + .setResource(Resource.getDefault()) + // In-memory exporter used for demonstration purposes + .addSpanProcessor(SimpleSpanProcessor.create(exporter)); + // Disable tracerB + SdkTracerProviderUtil.addTracerConfiguratorCondition( + tracerProviderBuilder, nameEquals("tracerB"), disabled()); + SdkTracerProvider tracerProvider = tracerProviderBuilder.build(); + + // Create tracerA and tracerB + ExtendedTracer tracerA = (ExtendedTracer) tracerProvider.get("tracerA"); + ExtendedTracer tracerB = (ExtendedTracer) tracerProvider.get("tracerB"); + + // Check if tracer is enabled before recording span and avoid unnecessary computation + if (tracerA.isEnabled()) { + tracerA + .spanBuilder("span name") + .startSpan() + .setAllAttributes(Attributes.builder().put("result", flipCoin()).build()) + .end(); + } + if (tracerB.isEnabled()) { + tracerB + .spanBuilder("span name") + .startSpan() + .setAllAttributes(Attributes.builder().put("result", flipCoin()).build()) + .end(); + } + + // tracerA is enabled, tracerB is disabled + assertThat(tracerA.isEnabled()).isTrue(); + assertThat(tracerB.isEnabled()).isFalse(); + + // Collected data only consists of spans from tracerA. Note, tracerB's spans would be + // omitted from the results even if spans were recorded. The check if enabled simply avoids + // unnecessary computation. + assertThat(exporter.getFinishedSpanItems()) + .allSatisfy( + spanData -> + assertThat(spanData.getInstrumentationScopeInfo().getName()).isEqualTo("tracerA")); + } + + private static final Random random = new Random(); + + private static String flipCoin() { + return random.nextBoolean() ? "heads" : "tails"; + } + /** Demonstrates {@link ExtendedSpanBuilder#setParentFrom(ContextPropagators, Map)}. */ @Test void setParentFrom() { diff --git a/sdk/logs/src/main/java/io/opentelemetry/sdk/logs/SdkLogger.java b/sdk/logs/src/main/java/io/opentelemetry/sdk/logs/SdkLogger.java index 74bad693bfa..72fb9f0b356 100644 --- a/sdk/logs/src/main/java/io/opentelemetry/sdk/logs/SdkLogger.java +++ b/sdk/logs/src/main/java/io/opentelemetry/sdk/logs/SdkLogger.java @@ -5,6 +5,7 @@ package io.opentelemetry.sdk.logs; +import io.opentelemetry.api.incubator.logs.ExtendedLogger; import io.opentelemetry.api.logs.LogRecordBuilder; import io.opentelemetry.api.logs.Logger; import io.opentelemetry.api.logs.LoggerProvider; @@ -12,13 +13,13 @@ import io.opentelemetry.sdk.logs.internal.LoggerConfig; /** SDK implementation of {@link Logger}. */ -final class SdkLogger implements Logger { +final class SdkLogger implements ExtendedLogger { private static final Logger NOOP_LOGGER = LoggerProvider.noop().get("noop"); private final LoggerSharedState loggerSharedState; private final InstrumentationScopeInfo instrumentationScopeInfo; - private final LoggerConfig loggerConfig; + private final boolean loggerEnabled; SdkLogger( LoggerSharedState loggerSharedState, @@ -26,12 +27,12 @@ final class SdkLogger implements Logger { LoggerConfig loggerConfig) { this.loggerSharedState = loggerSharedState; this.instrumentationScopeInfo = instrumentationScopeInfo; - this.loggerConfig = loggerConfig; + this.loggerEnabled = loggerConfig.isEnabled(); } @Override public LogRecordBuilder logRecordBuilder() { - if (loggerConfig.isEnabled()) { + if (loggerEnabled) { return new SdkLogRecordBuilder(loggerSharedState, instrumentationScopeInfo); } return NOOP_LOGGER.logRecordBuilder(); @@ -41,4 +42,9 @@ public LogRecordBuilder logRecordBuilder() { InstrumentationScopeInfo getInstrumentationScopeInfo() { return instrumentationScopeInfo; } + + @Override + public boolean isEnabled() { + return loggerEnabled; + } } diff --git a/sdk/logs/src/test/java/io/opentelemetry/sdk/logs/LoggerConfigTest.java b/sdk/logs/src/test/java/io/opentelemetry/sdk/logs/LoggerConfigTest.java index 371098267eb..f94b97388b4 100644 --- a/sdk/logs/src/test/java/io/opentelemetry/sdk/logs/LoggerConfigTest.java +++ b/sdk/logs/src/test/java/io/opentelemetry/sdk/logs/LoggerConfigTest.java @@ -11,6 +11,7 @@ import static io.opentelemetry.sdk.logs.internal.LoggerConfig.enabled; import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.assertThat; +import io.opentelemetry.api.incubator.logs.ExtendedLogger; import io.opentelemetry.api.logs.Logger; import io.opentelemetry.sdk.common.InstrumentationScopeInfo; import io.opentelemetry.sdk.internal.ScopeConfigurator; @@ -59,6 +60,10 @@ void disableScopes() { assertThat(logsByScope.get(InstrumentationScopeInfo.create("loggerB"))).isNull(); assertThat(logsByScope.get(InstrumentationScopeInfo.create("loggerC"))).hasSize(1); }); + // loggerA and loggerC are enabled, loggerB is disabled. + assertThat(((ExtendedLogger) loggerA).isEnabled()).isTrue(); + assertThat(((ExtendedLogger) loggerB).isEnabled()).isFalse(); + assertThat(((ExtendedLogger) loggerC).isEnabled()).isTrue(); } @ParameterizedTest diff --git a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/InstrumentBuilder.java b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/InstrumentBuilder.java index f1da522e15b..afed0778796 100644 --- a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/InstrumentBuilder.java +++ b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/InstrumentBuilder.java @@ -17,7 +17,6 @@ import io.opentelemetry.sdk.metrics.internal.state.WriteableMetricStorage; import java.util.Collections; import java.util.List; -import java.util.function.BiFunction; import java.util.function.Consumer; /** Helper to make implementing builders easier. */ @@ -65,12 +64,21 @@ T swapBuilder(SwapBuilder swapper) { meterProviderSharedState, meterSharedState, name, description, unit, adviceBuilder); } + @FunctionalInterface + interface SynchronousInstrumentConstructor { + + I createInstrument( + InstrumentDescriptor instrumentDescriptor, + MeterSharedState meterSharedState, + WriteableMetricStorage storage); + } + I buildSynchronousInstrument( - BiFunction instrumentFactory) { + SynchronousInstrumentConstructor instrumentFactory) { InstrumentDescriptor descriptor = newDescriptor(); WriteableMetricStorage storage = meterSharedState.registerSynchronousMetricStorage(descriptor, meterProviderSharedState); - return instrumentFactory.apply(descriptor, storage); + return instrumentFactory.createInstrument(descriptor, meterSharedState, storage); } SdkObservableInstrument buildDoubleAsynchronousInstrument( diff --git a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkDoubleCounter.java b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkDoubleCounter.java index d7aa5f47cad..5e4eb4a7ef5 100644 --- a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkDoubleCounter.java +++ b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkDoubleCounter.java @@ -7,8 +7,8 @@ import io.opentelemetry.api.common.AttributeKey; import io.opentelemetry.api.common.Attributes; +import io.opentelemetry.api.incubator.metrics.ExtendedDoubleCounter; import io.opentelemetry.api.incubator.metrics.ExtendedDoubleCounterBuilder; -import io.opentelemetry.api.metrics.DoubleCounter; import io.opentelemetry.api.metrics.DoubleCounterBuilder; import io.opentelemetry.api.metrics.ObservableDoubleCounter; import io.opentelemetry.api.metrics.ObservableDoubleMeasurement; @@ -24,14 +24,19 @@ import java.util.logging.Level; import java.util.logging.Logger; -final class SdkDoubleCounter extends AbstractInstrument implements DoubleCounter { +final class SdkDoubleCounter extends AbstractInstrument implements ExtendedDoubleCounter { private static final Logger logger = Logger.getLogger(SdkDoubleCounter.class.getName()); private final ThrottlingLogger throttlingLogger = new ThrottlingLogger(logger); + private final MeterSharedState meterSharedState; private final WriteableMetricStorage storage; - private SdkDoubleCounter(InstrumentDescriptor descriptor, WriteableMetricStorage storage) { + private SdkDoubleCounter( + InstrumentDescriptor descriptor, + MeterSharedState meterSharedState, + WriteableMetricStorage storage) { super(descriptor); + this.meterSharedState = meterSharedState; this.storage = storage; } @@ -58,6 +63,11 @@ public void add(double increment) { add(increment, Attributes.empty()); } + @Override + public boolean isEnabled() { + return meterSharedState.isMeterEnabled() && storage.isEnabled(); + } + static final class SdkDoubleCounterBuilder implements ExtendedDoubleCounterBuilder { private final InstrumentBuilder builder; diff --git a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkDoubleGauge.java b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkDoubleGauge.java index 1c834b18e10..8cc9d468257 100644 --- a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkDoubleGauge.java +++ b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkDoubleGauge.java @@ -7,8 +7,8 @@ import io.opentelemetry.api.common.AttributeKey; import io.opentelemetry.api.common.Attributes; +import io.opentelemetry.api.incubator.metrics.ExtendedDoubleGauge; import io.opentelemetry.api.incubator.metrics.ExtendedDoubleGaugeBuilder; -import io.opentelemetry.api.metrics.DoubleGauge; import io.opentelemetry.api.metrics.DoubleGaugeBuilder; import io.opentelemetry.api.metrics.LongGaugeBuilder; import io.opentelemetry.api.metrics.ObservableDoubleGauge; @@ -21,12 +21,17 @@ import java.util.List; import java.util.function.Consumer; -final class SdkDoubleGauge extends AbstractInstrument implements DoubleGauge { +final class SdkDoubleGauge extends AbstractInstrument implements ExtendedDoubleGauge { + private final MeterSharedState meterSharedState; private final WriteableMetricStorage storage; - private SdkDoubleGauge(InstrumentDescriptor descriptor, WriteableMetricStorage storage) { + private SdkDoubleGauge( + InstrumentDescriptor descriptor, + MeterSharedState meterSharedState, + WriteableMetricStorage storage) { super(descriptor); + this.meterSharedState = meterSharedState; this.storage = storage; } @@ -45,6 +50,11 @@ public void set(double increment) { set(increment, Attributes.empty()); } + @Override + public boolean isEnabled() { + return meterSharedState.isMeterEnabled() && storage.isEnabled(); + } + static final class SdkDoubleGaugeBuilder implements ExtendedDoubleGaugeBuilder { private final InstrumentBuilder builder; diff --git a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkDoubleHistogram.java b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkDoubleHistogram.java index 15dd7d2f8c7..4861a631ab7 100644 --- a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkDoubleHistogram.java +++ b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkDoubleHistogram.java @@ -7,8 +7,8 @@ import io.opentelemetry.api.common.AttributeKey; import io.opentelemetry.api.common.Attributes; +import io.opentelemetry.api.incubator.metrics.ExtendedDoubleHistogram; import io.opentelemetry.api.incubator.metrics.ExtendedDoubleHistogramBuilder; -import io.opentelemetry.api.metrics.DoubleHistogram; import io.opentelemetry.api.metrics.DoubleHistogramBuilder; import io.opentelemetry.api.metrics.LongHistogramBuilder; import io.opentelemetry.context.Context; @@ -23,14 +23,19 @@ import java.util.logging.Level; import java.util.logging.Logger; -final class SdkDoubleHistogram extends AbstractInstrument implements DoubleHistogram { +final class SdkDoubleHistogram extends AbstractInstrument implements ExtendedDoubleHistogram { private static final Logger logger = Logger.getLogger(SdkDoubleHistogram.class.getName()); private final ThrottlingLogger throttlingLogger = new ThrottlingLogger(logger); + private final MeterSharedState meterSharedState; private final WriteableMetricStorage storage; - private SdkDoubleHistogram(InstrumentDescriptor descriptor, WriteableMetricStorage storage) { + private SdkDoubleHistogram( + InstrumentDescriptor descriptor, + MeterSharedState meterSharedState, + WriteableMetricStorage storage) { super(descriptor); + this.meterSharedState = meterSharedState; this.storage = storage; } @@ -57,6 +62,11 @@ public void record(double value) { record(value, Attributes.empty()); } + @Override + public boolean isEnabled() { + return meterSharedState.isMeterEnabled() && storage.isEnabled(); + } + static final class SdkDoubleHistogramBuilder implements ExtendedDoubleHistogramBuilder { private final InstrumentBuilder builder; diff --git a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkDoubleUpDownCounter.java b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkDoubleUpDownCounter.java index 57188aa6a23..da6316d6b77 100644 --- a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkDoubleUpDownCounter.java +++ b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkDoubleUpDownCounter.java @@ -7,6 +7,7 @@ import io.opentelemetry.api.common.AttributeKey; import io.opentelemetry.api.common.Attributes; +import io.opentelemetry.api.incubator.metrics.ExtendedDoubleUpDownCounter; import io.opentelemetry.api.incubator.metrics.ExtendedDoubleUpDownCounterBuilder; import io.opentelemetry.api.metrics.DoubleUpDownCounter; import io.opentelemetry.api.metrics.DoubleUpDownCounterBuilder; @@ -21,12 +22,18 @@ import java.util.List; import java.util.function.Consumer; -final class SdkDoubleUpDownCounter extends AbstractInstrument implements DoubleUpDownCounter { +final class SdkDoubleUpDownCounter extends AbstractInstrument + implements ExtendedDoubleUpDownCounter { + private final MeterSharedState meterSharedState; private final WriteableMetricStorage storage; - private SdkDoubleUpDownCounter(InstrumentDescriptor descriptor, WriteableMetricStorage storage) { + private SdkDoubleUpDownCounter( + InstrumentDescriptor descriptor, + MeterSharedState meterSharedState, + WriteableMetricStorage storage) { super(descriptor); + this.meterSharedState = meterSharedState; this.storage = storage; } @@ -45,6 +52,11 @@ public void add(double increment) { add(increment, Attributes.empty()); } + @Override + public boolean isEnabled() { + return meterSharedState.isMeterEnabled() && storage.isEnabled(); + } + static final class SdkDoubleUpDownCounterBuilder implements ExtendedDoubleUpDownCounterBuilder { private final InstrumentBuilder builder; diff --git a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkLongCounter.java b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkLongCounter.java index 3847bf716f3..91b52fee7fd 100644 --- a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkLongCounter.java +++ b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkLongCounter.java @@ -7,9 +7,9 @@ import io.opentelemetry.api.common.AttributeKey; import io.opentelemetry.api.common.Attributes; +import io.opentelemetry.api.incubator.metrics.ExtendedLongCounter; import io.opentelemetry.api.incubator.metrics.ExtendedLongCounterBuilder; import io.opentelemetry.api.metrics.DoubleCounterBuilder; -import io.opentelemetry.api.metrics.LongCounter; import io.opentelemetry.api.metrics.LongCounterBuilder; import io.opentelemetry.api.metrics.ObservableLongCounter; import io.opentelemetry.api.metrics.ObservableLongMeasurement; @@ -24,15 +24,20 @@ import java.util.logging.Level; import java.util.logging.Logger; -final class SdkLongCounter extends AbstractInstrument implements LongCounter { +final class SdkLongCounter extends AbstractInstrument implements ExtendedLongCounter { private static final Logger logger = Logger.getLogger(SdkLongCounter.class.getName()); private final ThrottlingLogger throttlingLogger = new ThrottlingLogger(logger); + private final MeterSharedState meterSharedState; private final WriteableMetricStorage storage; - private SdkLongCounter(InstrumentDescriptor descriptor, WriteableMetricStorage storage) { + private SdkLongCounter( + InstrumentDescriptor descriptor, + MeterSharedState meterSharedState, + WriteableMetricStorage storage) { super(descriptor); + this.meterSharedState = meterSharedState; this.storage = storage; } @@ -59,6 +64,11 @@ public void add(long increment) { add(increment, Attributes.empty()); } + @Override + public boolean isEnabled() { + return meterSharedState.isMeterEnabled() && storage.isEnabled(); + } + static final class SdkLongCounterBuilder implements ExtendedLongCounterBuilder { private final InstrumentBuilder builder; diff --git a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkLongGauge.java b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkLongGauge.java index ad7db428bdf..62ab826df87 100644 --- a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkLongGauge.java +++ b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkLongGauge.java @@ -7,8 +7,8 @@ import io.opentelemetry.api.common.AttributeKey; import io.opentelemetry.api.common.Attributes; +import io.opentelemetry.api.incubator.metrics.ExtendedLongGauge; import io.opentelemetry.api.incubator.metrics.ExtendedLongGaugeBuilder; -import io.opentelemetry.api.metrics.LongGauge; import io.opentelemetry.api.metrics.LongGaugeBuilder; import io.opentelemetry.api.metrics.ObservableLongGauge; import io.opentelemetry.api.metrics.ObservableLongMeasurement; @@ -21,12 +21,17 @@ import java.util.List; import java.util.function.Consumer; -final class SdkLongGauge extends AbstractInstrument implements LongGauge { +final class SdkLongGauge extends AbstractInstrument implements ExtendedLongGauge { + private final MeterSharedState meterSharedState; private final WriteableMetricStorage storage; - private SdkLongGauge(InstrumentDescriptor descriptor, WriteableMetricStorage storage) { + private SdkLongGauge( + InstrumentDescriptor descriptor, + MeterSharedState meterSharedState, + WriteableMetricStorage storage) { super(descriptor); + this.meterSharedState = meterSharedState; this.storage = storage; } @@ -45,6 +50,11 @@ public void set(long increment) { set(increment, Attributes.empty()); } + @Override + public boolean isEnabled() { + return meterSharedState.isMeterEnabled() && storage.isEnabled(); + } + static final class SdkLongGaugeBuilder implements ExtendedLongGaugeBuilder { private final InstrumentBuilder builder; diff --git a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkLongHistogram.java b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkLongHistogram.java index b2975886565..ef8ee31e707 100644 --- a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkLongHistogram.java +++ b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkLongHistogram.java @@ -7,8 +7,8 @@ import io.opentelemetry.api.common.AttributeKey; import io.opentelemetry.api.common.Attributes; +import io.opentelemetry.api.incubator.metrics.ExtendedLongHistogram; import io.opentelemetry.api.incubator.metrics.ExtendedLongHistogramBuilder; -import io.opentelemetry.api.metrics.LongHistogram; import io.opentelemetry.api.metrics.LongHistogramBuilder; import io.opentelemetry.context.Context; import io.opentelemetry.sdk.internal.ThrottlingLogger; @@ -24,14 +24,19 @@ import java.util.logging.Logger; import java.util.stream.Collectors; -final class SdkLongHistogram extends AbstractInstrument implements LongHistogram { +final class SdkLongHistogram extends AbstractInstrument implements ExtendedLongHistogram { private static final Logger logger = Logger.getLogger(SdkLongHistogram.class.getName()); private final ThrottlingLogger throttlingLogger = new ThrottlingLogger(logger); + private final MeterSharedState meterSharedState; private final WriteableMetricStorage storage; - private SdkLongHistogram(InstrumentDescriptor descriptor, WriteableMetricStorage storage) { + private SdkLongHistogram( + InstrumentDescriptor descriptor, + MeterSharedState meterSharedState, + WriteableMetricStorage storage) { super(descriptor); + this.meterSharedState = meterSharedState; this.storage = storage; } @@ -58,6 +63,11 @@ public void record(long value) { record(value, Attributes.empty()); } + @Override + public boolean isEnabled() { + return meterSharedState.isMeterEnabled() && storage.isEnabled(); + } + static final class SdkLongHistogramBuilder implements ExtendedLongHistogramBuilder { private final InstrumentBuilder builder; diff --git a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkLongUpDownCounter.java b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkLongUpDownCounter.java index 4530f3b8405..a74ac786d1a 100644 --- a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkLongUpDownCounter.java +++ b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkLongUpDownCounter.java @@ -7,6 +7,7 @@ import io.opentelemetry.api.common.AttributeKey; import io.opentelemetry.api.common.Attributes; +import io.opentelemetry.api.incubator.metrics.ExtendedLongUpDownCounter; import io.opentelemetry.api.incubator.metrics.ExtendedLongUpDownCounterBuilder; import io.opentelemetry.api.metrics.DoubleUpDownCounterBuilder; import io.opentelemetry.api.metrics.LongUpDownCounter; @@ -21,12 +22,17 @@ import java.util.List; import java.util.function.Consumer; -final class SdkLongUpDownCounter extends AbstractInstrument implements LongUpDownCounter { +final class SdkLongUpDownCounter extends AbstractInstrument implements ExtendedLongUpDownCounter { + private final MeterSharedState meterSharedState; private final WriteableMetricStorage storage; - private SdkLongUpDownCounter(InstrumentDescriptor descriptor, WriteableMetricStorage storage) { + private SdkLongUpDownCounter( + InstrumentDescriptor descriptor, + MeterSharedState meterSharedState, + WriteableMetricStorage storage) { super(descriptor); + this.meterSharedState = meterSharedState; this.storage = storage; } @@ -45,6 +51,11 @@ public void add(long increment) { add(increment, Attributes.empty()); } + @Override + public boolean isEnabled() { + return meterSharedState.isMeterEnabled() && storage.isEnabled(); + } + static final class SdkLongUpDownCounterBuilder implements ExtendedLongUpDownCounterBuilder { private final InstrumentBuilder builder; diff --git a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkMeter.java b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkMeter.java index bb76fe6701a..da57ef3506c 100644 --- a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkMeter.java +++ b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkMeter.java @@ -56,7 +56,6 @@ final class SdkMeter implements Meter { private final InstrumentationScopeInfo instrumentationScopeInfo; private final MeterProviderSharedState meterProviderSharedState; private final MeterSharedState meterSharedState; - private final MeterConfig meterConfig; SdkMeter( MeterProviderSharedState meterProviderSharedState, @@ -65,8 +64,8 @@ final class SdkMeter implements Meter { MeterConfig meterConfig) { this.instrumentationScopeInfo = instrumentationScopeInfo; this.meterProviderSharedState = meterProviderSharedState; - this.meterSharedState = MeterSharedState.create(instrumentationScopeInfo, registeredReaders); - this.meterConfig = meterConfig; + this.meterSharedState = + MeterSharedState.create(instrumentationScopeInfo, registeredReaders, meterConfig); } // Visible for testing @@ -86,14 +85,14 @@ void resetForTest() { @Override public LongCounterBuilder counterBuilder(String name) { - return meterConfig.isEnabled() && checkValidInstrumentName(name) + return checkValidInstrumentName(name) ? new SdkLongCounter.SdkLongCounterBuilder(meterProviderSharedState, meterSharedState, name) : NOOP_METER.counterBuilder(NOOP_INSTRUMENT_NAME); } @Override public LongUpDownCounterBuilder upDownCounterBuilder(String name) { - return meterConfig.isEnabled() && checkValidInstrumentName(name) + return checkValidInstrumentName(name) ? new SdkLongUpDownCounter.SdkLongUpDownCounterBuilder( meterProviderSharedState, meterSharedState, name) : NOOP_METER.upDownCounterBuilder(NOOP_INSTRUMENT_NAME); @@ -101,7 +100,7 @@ public LongUpDownCounterBuilder upDownCounterBuilder(String name) { @Override public DoubleHistogramBuilder histogramBuilder(String name) { - return meterConfig.isEnabled() && checkValidInstrumentName(name) + return checkValidInstrumentName(name) ? new SdkDoubleHistogram.SdkDoubleHistogramBuilder( meterProviderSharedState, meterSharedState, name) : NOOP_METER.histogramBuilder(NOOP_INSTRUMENT_NAME); @@ -109,7 +108,7 @@ public DoubleHistogramBuilder histogramBuilder(String name) { @Override public DoubleGaugeBuilder gaugeBuilder(String name) { - return meterConfig.isEnabled() && checkValidInstrumentName(name) + return checkValidInstrumentName(name) ? new SdkDoubleGauge.SdkDoubleGaugeBuilder(meterProviderSharedState, meterSharedState, name) : NOOP_METER.gaugeBuilder(NOOP_INSTRUMENT_NAME); } @@ -119,9 +118,6 @@ public BatchCallback batchCallback( Runnable callback, ObservableMeasurement observableMeasurement, ObservableMeasurement... additionalMeasurements) { - if (!meterConfig.isEnabled()) { - return NOOP_METER.batchCallback(callback, observableMeasurement, additionalMeasurements); - } Set measurements = new HashSet<>(); measurements.add(observableMeasurement); Collections.addAll(measurements, additionalMeasurements); diff --git a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/state/DefaultSynchronousMetricStorage.java b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/state/DefaultSynchronousMetricStorage.java index 191223bfeac..c0deda9d068 100644 --- a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/state/DefaultSynchronousMetricStorage.java +++ b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/state/DefaultSynchronousMetricStorage.java @@ -131,6 +131,11 @@ public void recordDouble(double value, Attributes attributes, Context context) { } } + @Override + public boolean isEnabled() { + return true; + } + /** * Obtain the AggregatorHolder for recording measurements, re-reading the volatile * this.aggregatorHolder until we access one where recordsInProgress is even. Collect sets diff --git a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/state/EmptyMetricStorage.java b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/state/EmptyMetricStorage.java index d076178d193..faaa7087c76 100644 --- a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/state/EmptyMetricStorage.java +++ b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/state/EmptyMetricStorage.java @@ -39,4 +39,9 @@ public void recordLong(long value, Attributes attributes, Context context) {} @Override public void recordDouble(double value, Attributes attributes, Context context) {} + + @Override + public boolean isEnabled() { + return false; + } } diff --git a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/state/MeterSharedState.java b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/state/MeterSharedState.java index 64ecefd5385..30a3a838c45 100644 --- a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/state/MeterSharedState.java +++ b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/state/MeterSharedState.java @@ -11,11 +11,13 @@ import io.opentelemetry.sdk.common.InstrumentationScopeInfo; import io.opentelemetry.sdk.metrics.Aggregation; import io.opentelemetry.sdk.metrics.data.MetricData; +import io.opentelemetry.sdk.metrics.internal.MeterConfig; import io.opentelemetry.sdk.metrics.internal.descriptor.InstrumentDescriptor; import io.opentelemetry.sdk.metrics.internal.export.RegisteredReader; import io.opentelemetry.sdk.metrics.internal.view.RegisteredView; import java.util.ArrayList; import java.util.Collection; +import java.util.Collections; import java.util.List; import java.util.Map; import java.util.Objects; @@ -36,20 +38,25 @@ public class MeterSharedState { private final List callbackRegistrations = new ArrayList<>(); private final Map readerStorageRegistries; - private final InstrumentationScopeInfo instrumentationScopeInfo; + private final boolean meterEnabled; private MeterSharedState( - InstrumentationScopeInfo instrumentationScopeInfo, List registeredReaders) { + InstrumentationScopeInfo instrumentationScopeInfo, + List registeredReaders, + MeterConfig meterConfig) { this.instrumentationScopeInfo = instrumentationScopeInfo; this.readerStorageRegistries = registeredReaders.stream() .collect(toMap(Function.identity(), unused -> new MetricStorageRegistry())); + this.meterEnabled = meterConfig.isEnabled(); } public static MeterSharedState create( - InstrumentationScopeInfo instrumentationScopeInfo, List registeredReaders) { - return new MeterSharedState(instrumentationScopeInfo, registeredReaders); + InstrumentationScopeInfo instrumentationScopeInfo, + List registeredReaders, + MeterConfig meterConfig) { + return new MeterSharedState(instrumentationScopeInfo, registeredReaders, meterConfig); } /** @@ -81,11 +88,20 @@ public InstrumentationScopeInfo getInstrumentationScopeInfo() { return instrumentationScopeInfo; } + /** Returns {@code true} if the {@link MeterConfig#enabled()} of the meter is {@code true}. */ + public boolean isMeterEnabled() { + return meterEnabled; + } + /** Collects all metrics. */ public List collectAll( RegisteredReader registeredReader, MeterProviderSharedState meterProviderSharedState, long epochNanos) { + // Short circuit collection process if meter is disabled + if (!meterEnabled) { + return Collections.emptyList(); + } List currentRegisteredCallbacks; synchronized (callbackLock) { currentRegisteredCallbacks = new ArrayList<>(callbackRegistrations); @@ -113,7 +129,7 @@ public List collectAll( result.add(current); } } - return result; + return Collections.unmodifiableList(result); } } diff --git a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/state/MultiWritableMetricStorage.java b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/state/MultiWritableMetricStorage.java index 59632a9cc4a..700fee4c3fb 100644 --- a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/state/MultiWritableMetricStorage.java +++ b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/state/MultiWritableMetricStorage.java @@ -29,4 +29,14 @@ public void recordDouble(double value, Attributes attributes, Context context) { storage.recordDouble(value, attributes, context); } } + + @Override + public boolean isEnabled() { + for (WriteableMetricStorage storage : storages) { + if (storage.isEnabled()) { + return true; + } + } + return false; + } } diff --git a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/state/WriteableMetricStorage.java b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/state/WriteableMetricStorage.java index 77e2dd510b8..7191a63f1e0 100644 --- a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/state/WriteableMetricStorage.java +++ b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/state/WriteableMetricStorage.java @@ -22,4 +22,10 @@ public interface WriteableMetricStorage { /** Records a measurement. */ void recordDouble(double value, Attributes attributes, Context context); + + /** + * Returns {@code true} if the storage is actively recording measurements, and {@code false} + * otherwise (i.e. noop / empty metric storage is installed). + */ + boolean isEnabled(); } diff --git a/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/InstrumentBuilderTest.java b/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/InstrumentBuilderTest.java index a351c95d0e6..c6ef1957428 100644 --- a/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/InstrumentBuilderTest.java +++ b/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/InstrumentBuilderTest.java @@ -8,6 +8,7 @@ import static org.assertj.core.api.Assertions.assertThat; import io.opentelemetry.sdk.common.InstrumentationScopeInfo; +import io.opentelemetry.sdk.metrics.internal.MeterConfig; import io.opentelemetry.sdk.metrics.internal.descriptor.Advice; import io.opentelemetry.sdk.metrics.internal.exemplar.ExemplarFilter; import io.opentelemetry.sdk.metrics.internal.state.MeterProviderSharedState; @@ -24,7 +25,7 @@ class InstrumentBuilderTest { TestClock.create(), Resource.getDefault(), ExemplarFilter.alwaysOff(), 0); static final InstrumentationScopeInfo SCOPE = InstrumentationScopeInfo.create("scope-name"); public static final MeterSharedState METER_SHARED_STATE = - MeterSharedState.create(SCOPE, Collections.emptyList()); + MeterSharedState.create(SCOPE, Collections.emptyList(), MeterConfig.defaultConfig()); @Test void stringRepresentation() { diff --git a/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/MeterConfigTest.java b/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/MeterConfigTest.java index 3b78f2abd0d..aaaeaf5f85d 100644 --- a/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/MeterConfigTest.java +++ b/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/MeterConfigTest.java @@ -11,7 +11,16 @@ import static io.opentelemetry.sdk.metrics.internal.MeterConfig.disabled; import static io.opentelemetry.sdk.metrics.internal.MeterConfig.enabled; import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.assertThat; +import static java.util.stream.Collectors.groupingBy; +import io.opentelemetry.api.incubator.metrics.ExtendedDoubleCounter; +import io.opentelemetry.api.incubator.metrics.ExtendedDoubleGauge; +import io.opentelemetry.api.incubator.metrics.ExtendedDoubleHistogram; +import io.opentelemetry.api.incubator.metrics.ExtendedDoubleUpDownCounter; +import io.opentelemetry.api.incubator.metrics.ExtendedLongCounter; +import io.opentelemetry.api.incubator.metrics.ExtendedLongGauge; +import io.opentelemetry.api.incubator.metrics.ExtendedLongHistogram; +import io.opentelemetry.api.incubator.metrics.ExtendedLongUpDownCounter; import io.opentelemetry.api.metrics.Meter; import io.opentelemetry.sdk.common.InstrumentationScopeInfo; import io.opentelemetry.sdk.internal.ScopeConfigurator; @@ -20,7 +29,7 @@ import io.opentelemetry.sdk.testing.exporter.InMemoryMetricReader; import java.util.List; import java.util.Map; -import java.util.stream.Collectors; +import java.util.concurrent.atomic.AtomicLong; import java.util.stream.Stream; import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; @@ -37,50 +46,136 @@ void disableScopes() { // Disable meterB. Since meters are enabled by default, meterA and meterC are enabled. .addMeterConfiguratorCondition(nameEquals("meterB"), disabled()) .registerMetricReader(reader) + // Register drop aggregation for all instruments of meterD. Instruments are disabled if + // their relevant MeterConfig is disabled, or if there are no resolved views which + // consume the measurements. + .registerView( + InstrumentSelector.builder().setMeterName("meterD").build(), + View.builder().setAggregation(Aggregation.drop()).build()) .build(); Meter meterA = meterProvider.get("meterA"); Meter meterB = meterProvider.get("meterB"); Meter meterC = meterProvider.get("meterC"); + Meter meterD = meterProvider.get("meterD"); + AtomicLong meterAInvocations = new AtomicLong(); + AtomicLong meterBInvocations = new AtomicLong(); + AtomicLong meterCInvocations = new AtomicLong(); + AtomicLong meterDInvocations = new AtomicLong(); - meterA.counterBuilder("counterA").build().add(1); - meterA.counterBuilder("asyncCounterA").buildWithCallback(observable -> observable.record(1)); - meterA.upDownCounterBuilder("upDownCounterA").build().add(1); - meterA - .upDownCounterBuilder("asyncUpDownCounterA") - .buildWithCallback(observable -> observable.record(1)); - meterA.histogramBuilder("histogramA").build().record(1.0); - meterA.gaugeBuilder("gaugeA").buildWithCallback(observable -> observable.record(1.0)); - - meterB.counterBuilder("counterB").build().add(1); - meterB.counterBuilder("asyncCounterB").buildWithCallback(observable -> observable.record(1)); - meterB.upDownCounterBuilder("upDownCounterB").build().add(1); - meterB - .upDownCounterBuilder("asyncUpDownCounterB") - .buildWithCallback(observable -> observable.record(1)); - meterB.histogramBuilder("histogramB").build().record(1.0); - meterB.gaugeBuilder("gaugeB").buildWithCallback(observable -> observable.record(1.0)); - - meterC.counterBuilder("counterC").build().add(1); - meterC.counterBuilder("asyncCounterC").buildWithCallback(observable -> observable.record(1)); - meterC.upDownCounterBuilder("upDownCounterC").build().add(1); - meterC - .upDownCounterBuilder("asyncUpDownCounterC") - .buildWithCallback(observable -> observable.record(1)); - meterC.histogramBuilder("histogramC").build().record(1.0); - meterC.gaugeBuilder("gaugeC").buildWithCallback(observable -> observable.record(1.0)); + // Record measurements to each instrument type + recordToMeterInstruments(meterA, meterAInvocations); + recordToMeterInstruments(meterB, meterBInvocations); + recordToMeterInstruments(meterC, meterCInvocations); + recordToMeterInstruments(meterD, meterDInvocations); // Only metrics from meterA and meterC should be seen assertThat(reader.collectAllMetrics()) .satisfies( metrics -> { Map> metricsByScope = - metrics.stream() - .collect(Collectors.groupingBy(MetricData::getInstrumentationScopeInfo)); - assertThat(metricsByScope.get(InstrumentationScopeInfo.create("meterA"))).hasSize(6); + metrics.stream().collect(groupingBy(MetricData::getInstrumentationScopeInfo)); + assertThat(metricsByScope.get(InstrumentationScopeInfo.create("meterA"))).hasSize(14); assertThat(metricsByScope.get(InstrumentationScopeInfo.create("meterB"))).isNull(); - assertThat(metricsByScope.get(InstrumentationScopeInfo.create("meterC"))).hasSize(6); + assertThat(metricsByScope.get(InstrumentationScopeInfo.create("meterC"))).hasSize(14); + assertThat(metricsByScope.get(InstrumentationScopeInfo.create("meterD"))).isNull(); + }); + // Only async callbacks from meterA and meterC should be invoked + assertThat(meterAInvocations.get()).isPositive(); + assertThat(meterBInvocations.get()).isZero(); + assertThat(meterCInvocations.get()).isPositive(); + assertThat(meterDInvocations.get()).isZero(); + // Instruments from meterA and meterC are enabled, meterC is not enabled + assertMeterInstrumentsEnabled(meterA, /* expectedEnabled= */ true); + assertMeterInstrumentsEnabled(meterB, /* expectedEnabled= */ false); + assertMeterInstrumentsEnabled(meterC, /* expectedEnabled= */ true); + assertMeterInstrumentsEnabled(meterD, /* expectedEnabled= */ false); + } + + private static void recordToMeterInstruments(Meter meter, AtomicLong asyncInvocationsCount) { + meter.counterBuilder("longCounter").build().add(1); + meter.counterBuilder("doubleCounter").ofDoubles().build().add(1); + meter + .counterBuilder("asyncLongCounter") + .buildWithCallback( + observable -> { + asyncInvocationsCount.incrementAndGet(); + observable.record(1); + }); + meter + .counterBuilder("asyncDoubleCounter") + .ofDoubles() + .buildWithCallback( + observable -> { + asyncInvocationsCount.incrementAndGet(); + observable.record(1); }); + meter.upDownCounterBuilder("longUpDownCounter").build().add(1); + meter.upDownCounterBuilder("doubleUpDownCounter").ofDoubles().build().add(1); + meter + .upDownCounterBuilder("asyncLongUpDownCounter") + .buildWithCallback( + observable -> { + asyncInvocationsCount.incrementAndGet(); + observable.record(1); + }); + meter + .upDownCounterBuilder("asyncDoubleUpDownCounter") + .ofDoubles() + .buildWithCallback( + observable -> { + asyncInvocationsCount.incrementAndGet(); + observable.record(1); + }); + meter.histogramBuilder("doubleHistogram").build().record(1.0); + meter.histogramBuilder("longHistogram").ofLongs().build().record(1); + meter.gaugeBuilder("doubleGauge").build().set(1); + meter.gaugeBuilder("longGauge").ofLongs().build().set(1); + meter + .gaugeBuilder("asyncDoubleGauge") + .buildWithCallback( + observable -> { + asyncInvocationsCount.incrementAndGet(); + observable.record(1.0); + }); + meter + .gaugeBuilder("asyncLongGauge") + .ofLongs() + .buildWithCallback( + observable -> { + asyncInvocationsCount.incrementAndGet(); + observable.record(1); + }); + } + + private static void assertMeterInstrumentsEnabled(Meter meter, boolean expectedEnabled) { + assertThat( + ((ExtendedDoubleCounter) meter.counterBuilder("doubleCounter").ofDoubles().build()) + .isEnabled()) + .isEqualTo(expectedEnabled); + assertThat(((ExtendedLongCounter) meter.counterBuilder("longCounter").build()).isEnabled()) + .isEqualTo(expectedEnabled); + assertThat( + ((ExtendedDoubleUpDownCounter) + meter.upDownCounterBuilder("doubleUpDownCounter").ofDoubles().build()) + .isEnabled()) + .isEqualTo(expectedEnabled); + assertThat( + ((ExtendedLongUpDownCounter) meter.upDownCounterBuilder("longUpDownCounter").build()) + .isEnabled()) + .isEqualTo(expectedEnabled); + assertThat( + ((ExtendedDoubleHistogram) meter.histogramBuilder("doubleHistogram").build()) + .isEnabled()) + .isEqualTo(expectedEnabled); + assertThat( + ((ExtendedLongHistogram) meter.histogramBuilder("longHistogram").ofLongs().build()) + .isEnabled()) + .isEqualTo(expectedEnabled); + assertThat(((ExtendedDoubleGauge) meter.gaugeBuilder("doubleGauge").build()).isEnabled()) + .isEqualTo(expectedEnabled); + assertThat(((ExtendedLongGauge) meter.gaugeBuilder("longGauge").ofLongs().build()).isEnabled()) + .isEqualTo(expectedEnabled); } @ParameterizedTest diff --git a/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/SdkObservableInstrumentTest.java b/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/SdkObservableInstrumentTest.java index a2b9e60a60f..03e52331dc7 100644 --- a/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/SdkObservableInstrumentTest.java +++ b/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/SdkObservableInstrumentTest.java @@ -13,6 +13,7 @@ import io.github.netmikey.logunit.api.LogCapturer; import io.opentelemetry.internal.testing.slf4j.SuppressLogger; import io.opentelemetry.sdk.common.InstrumentationScopeInfo; +import io.opentelemetry.sdk.metrics.internal.MeterConfig; import io.opentelemetry.sdk.metrics.internal.descriptor.Advice; import io.opentelemetry.sdk.metrics.internal.descriptor.InstrumentDescriptor; import io.opentelemetry.sdk.metrics.internal.state.CallbackRegistration; @@ -36,7 +37,11 @@ class SdkObservableInstrumentTest { @BeforeEach void setup() { meterSharedState = - spy(MeterSharedState.create(InstrumentationScopeInfo.empty(), Collections.emptyList())); + spy( + MeterSharedState.create( + InstrumentationScopeInfo.empty(), + Collections.emptyList(), + MeterConfig.defaultConfig())); callbackRegistration = CallbackRegistration.create( Collections.singletonList( diff --git a/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/internal/state/MetricStorageRegistryTest.java b/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/internal/state/MetricStorageRegistryTest.java index 8b664ad5d3e..99a26106a78 100644 --- a/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/internal/state/MetricStorageRegistryTest.java +++ b/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/internal/state/MetricStorageRegistryTest.java @@ -114,5 +114,10 @@ public void recordLong(long value, Attributes attributes, Context context) {} @Override public void recordDouble(double value, Attributes attributes, Context context) {} + + @Override + public boolean isEnabled() { + return true; + } } } diff --git a/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/SdkTracer.java b/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/SdkTracer.java index a0b2704fc72..cd8c7ca2471 100644 --- a/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/SdkTracer.java +++ b/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/SdkTracer.java @@ -5,6 +5,7 @@ package io.opentelemetry.sdk.trace; +import io.opentelemetry.api.incubator.trace.ExtendedTracer; import io.opentelemetry.api.trace.SpanBuilder; import io.opentelemetry.api.trace.Tracer; import io.opentelemetry.api.trace.TracerProvider; @@ -12,13 +13,13 @@ import io.opentelemetry.sdk.trace.internal.TracerConfig; /** {@link SdkTracer} is SDK implementation of {@link Tracer}. */ -final class SdkTracer implements Tracer { +final class SdkTracer implements ExtendedTracer { static final String FALLBACK_SPAN_NAME = ""; private static final Tracer NOOP_TRACER = TracerProvider.noop().get("noop"); private final TracerSharedState sharedState; private final InstrumentationScopeInfo instrumentationScopeInfo; - private final TracerConfig tracerConfig; + private final boolean tracerEnabled; SdkTracer( TracerSharedState sharedState, @@ -26,12 +27,12 @@ final class SdkTracer implements Tracer { TracerConfig tracerConfig) { this.sharedState = sharedState; this.instrumentationScopeInfo = instrumentationScopeInfo; - this.tracerConfig = tracerConfig; + this.tracerEnabled = tracerConfig.isEnabled(); } @Override public SpanBuilder spanBuilder(String spanName) { - if (!tracerConfig.isEnabled()) { + if (!tracerEnabled) { return NOOP_TRACER.spanBuilder(spanName); } if (spanName == null || spanName.trim().isEmpty()) { @@ -49,4 +50,9 @@ public SpanBuilder spanBuilder(String spanName) { InstrumentationScopeInfo getInstrumentationScopeInfo() { return instrumentationScopeInfo; } + + @Override + public boolean isEnabled() { + return tracerEnabled; + } } diff --git a/sdk/trace/src/test/java/io/opentelemetry/sdk/trace/TracerConfigTest.java b/sdk/trace/src/test/java/io/opentelemetry/sdk/trace/TracerConfigTest.java index 4df99b4c999..4421185aeea 100644 --- a/sdk/trace/src/test/java/io/opentelemetry/sdk/trace/TracerConfigTest.java +++ b/sdk/trace/src/test/java/io/opentelemetry/sdk/trace/TracerConfigTest.java @@ -13,6 +13,7 @@ import static io.opentelemetry.sdk.trace.internal.TracerConfig.enabled; import io.opentelemetry.api.common.Attributes; +import io.opentelemetry.api.incubator.trace.ExtendedTracer; import io.opentelemetry.api.trace.Span; import io.opentelemetry.api.trace.SpanId; import io.opentelemetry.api.trace.Tracer; @@ -90,6 +91,10 @@ void disableScopes() throws InterruptedException { .hasSpanId(grandchild.getSpanContext().getSpanId()) .hasParentSpanId(parent.getSpanContext().getSpanId()) .hasAttributes(Attributes.builder().put("c", "1").build())); + // tracerA and tracerC are enabled, tracerB is disabled. + assertThat(((ExtendedTracer) tracerA).isEnabled()).isTrue(); + assertThat(((ExtendedTracer) tracerB).isEnabled()).isFalse(); + assertThat(((ExtendedTracer) tracerA).isEnabled()).isTrue(); } @ParameterizedTest From c48fe9427126809881b1c0698913f847025f4ea0 Mon Sep 17 00:00:00 2001 From: jack-berg <34418638+jack-berg@users.noreply.github.com> Date: Fri, 5 Jul 2024 12:07:00 -0500 Subject: [PATCH 463/901] Prepare changelog for 1.40.0 release (#6554) --- CHANGELOG.md | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index d2fce9518f5..65d98b97f55 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,22 @@ ## Unreleased +### API + +#### Incubator + +* Narrow ExtendedSpanBuilder return types for chaining + ([#6514](https://github.com/open-telemetry/opentelemetry-java/pull/6514)) +* Add APIs to determine if tracer, logger, instruments are enabled + ([#6502](https://github.com/open-telemetry/opentelemetry-java/pull/6502)) + +### SDK + +#### Extensions + +* Move autoconfigure docs to opentelemetry.io + ([#6491](https://github.com/open-telemetry/opentelemetry-java/pull/6491)) + ## Version 1.39.0 (2024-06-07) ### API From d7e7542c762fe64280bf668aabfa77c8ed814fdc Mon Sep 17 00:00:00 2001 From: OpenTelemetry Bot <107717825+opentelemetrybot@users.noreply.github.com> Date: Sat, 6 Jul 2024 00:19:49 +0200 Subject: [PATCH 464/901] Update version to 1.41.0 (#6555) Co-authored-by: Jack Berg --- CHANGELOG.md | 2 ++ docs/apidiffs/current_vs_latest/opentelemetry-api.txt | 2 +- docs/apidiffs/current_vs_latest/opentelemetry-context.txt | 2 +- .../current_vs_latest/opentelemetry-exporter-common.txt | 2 +- .../current_vs_latest/opentelemetry-exporter-logging-otlp.txt | 2 +- .../current_vs_latest/opentelemetry-exporter-logging.txt | 2 +- .../current_vs_latest/opentelemetry-exporter-otlp-common.txt | 2 +- docs/apidiffs/current_vs_latest/opentelemetry-exporter-otlp.txt | 2 +- .../opentelemetry-exporter-sender-grpc-managed-channel.txt | 2 +- .../current_vs_latest/opentelemetry-exporter-sender-jdk.txt | 2 +- .../current_vs_latest/opentelemetry-exporter-sender-okhttp.txt | 2 +- .../current_vs_latest/opentelemetry-exporter-zipkin.txt | 2 +- .../current_vs_latest/opentelemetry-extension-kotlin.txt | 2 +- .../opentelemetry-extension-trace-propagators.txt | 2 +- .../current_vs_latest/opentelemetry-opentracing-shim.txt | 2 +- docs/apidiffs/current_vs_latest/opentelemetry-sdk-common.txt | 2 +- .../opentelemetry-sdk-extension-autoconfigure-spi.txt | 2 +- .../opentelemetry-sdk-extension-autoconfigure.txt | 2 +- .../opentelemetry-sdk-extension-jaeger-remote-sampler.txt | 2 +- docs/apidiffs/current_vs_latest/opentelemetry-sdk-logs.txt | 2 +- docs/apidiffs/current_vs_latest/opentelemetry-sdk-metrics.txt | 2 +- docs/apidiffs/current_vs_latest/opentelemetry-sdk-testing.txt | 2 +- docs/apidiffs/current_vs_latest/opentelemetry-sdk-trace.txt | 2 +- docs/apidiffs/current_vs_latest/opentelemetry-sdk.txt | 2 +- version.gradle.kts | 2 +- 25 files changed, 26 insertions(+), 24 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 65d98b97f55..2bb8d74c282 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,8 @@ ## Unreleased +## Version 1.40.0 (2024-07-05) + ### API #### Incubator diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-api.txt b/docs/apidiffs/current_vs_latest/opentelemetry-api.txt index e32147f2856..308b2296bf9 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-api.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-api.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of opentelemetry-api-1.40.0-SNAPSHOT.jar against opentelemetry-api-1.39.0.jar +Comparing source compatibility of opentelemetry-api-1.41.0-SNAPSHOT.jar against opentelemetry-api-1.39.0.jar No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-context.txt b/docs/apidiffs/current_vs_latest/opentelemetry-context.txt index dcfcd70c5c3..fb98e2e4d33 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-context.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-context.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of opentelemetry-context-1.40.0-SNAPSHOT.jar against opentelemetry-context-1.39.0.jar +Comparing source compatibility of opentelemetry-context-1.41.0-SNAPSHOT.jar against opentelemetry-context-1.39.0.jar No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-common.txt b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-common.txt index 6d63e3d8981..3744deb0c83 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-common.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-common.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of opentelemetry-exporter-common-1.40.0-SNAPSHOT.jar against opentelemetry-exporter-common-1.39.0.jar +Comparing source compatibility of opentelemetry-exporter-common-1.41.0-SNAPSHOT.jar against opentelemetry-exporter-common-1.39.0.jar No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-logging-otlp.txt b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-logging-otlp.txt index 5c1ffa724e1..5552c072ca2 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-logging-otlp.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-logging-otlp.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of opentelemetry-exporter-logging-otlp-1.40.0-SNAPSHOT.jar against opentelemetry-exporter-logging-otlp-1.39.0.jar +Comparing source compatibility of opentelemetry-exporter-logging-otlp-1.41.0-SNAPSHOT.jar against opentelemetry-exporter-logging-otlp-1.39.0.jar No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-logging.txt b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-logging.txt index 026e973bff4..8228d777d48 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-logging.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-logging.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of opentelemetry-exporter-logging-1.40.0-SNAPSHOT.jar against opentelemetry-exporter-logging-1.39.0.jar +Comparing source compatibility of opentelemetry-exporter-logging-1.41.0-SNAPSHOT.jar against opentelemetry-exporter-logging-1.39.0.jar No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-otlp-common.txt b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-otlp-common.txt index 32022b0aa4a..e7c4c9aed92 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-otlp-common.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-otlp-common.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of opentelemetry-exporter-otlp-common-1.40.0-SNAPSHOT.jar against opentelemetry-exporter-otlp-common-1.39.0.jar +Comparing source compatibility of opentelemetry-exporter-otlp-common-1.41.0-SNAPSHOT.jar against opentelemetry-exporter-otlp-common-1.39.0.jar No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-otlp.txt b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-otlp.txt index 4fd7c4935c7..41930cf1924 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-otlp.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-otlp.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of opentelemetry-exporter-otlp-1.40.0-SNAPSHOT.jar against opentelemetry-exporter-otlp-1.39.0.jar +Comparing source compatibility of opentelemetry-exporter-otlp-1.41.0-SNAPSHOT.jar against opentelemetry-exporter-otlp-1.39.0.jar No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-sender-grpc-managed-channel.txt b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-sender-grpc-managed-channel.txt index 14420c0010c..c70533096ba 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-sender-grpc-managed-channel.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-sender-grpc-managed-channel.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of opentelemetry-exporter-sender-grpc-managed-channel-1.40.0-SNAPSHOT.jar against opentelemetry-exporter-sender-grpc-managed-channel-1.39.0.jar +Comparing source compatibility of opentelemetry-exporter-sender-grpc-managed-channel-1.41.0-SNAPSHOT.jar against opentelemetry-exporter-sender-grpc-managed-channel-1.39.0.jar No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-sender-jdk.txt b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-sender-jdk.txt index 899cdf42152..4cf59ce4902 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-sender-jdk.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-sender-jdk.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of opentelemetry-exporter-sender-jdk-1.40.0-SNAPSHOT.jar against opentelemetry-exporter-sender-jdk-1.39.0.jar +Comparing source compatibility of opentelemetry-exporter-sender-jdk-1.41.0-SNAPSHOT.jar against opentelemetry-exporter-sender-jdk-1.39.0.jar No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-sender-okhttp.txt b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-sender-okhttp.txt index da7771432b3..1d952ead0d4 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-sender-okhttp.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-sender-okhttp.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of opentelemetry-exporter-sender-okhttp-1.40.0-SNAPSHOT.jar against opentelemetry-exporter-sender-okhttp-1.39.0.jar +Comparing source compatibility of opentelemetry-exporter-sender-okhttp-1.41.0-SNAPSHOT.jar against opentelemetry-exporter-sender-okhttp-1.39.0.jar No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-zipkin.txt b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-zipkin.txt index 68035c9761c..c7f5c981a2f 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-zipkin.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-zipkin.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of opentelemetry-exporter-zipkin-1.40.0-SNAPSHOT.jar against opentelemetry-exporter-zipkin-1.39.0.jar +Comparing source compatibility of opentelemetry-exporter-zipkin-1.41.0-SNAPSHOT.jar against opentelemetry-exporter-zipkin-1.39.0.jar No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-extension-kotlin.txt b/docs/apidiffs/current_vs_latest/opentelemetry-extension-kotlin.txt index 814a922f02f..c0c356b5dfc 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-extension-kotlin.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-extension-kotlin.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of opentelemetry-extension-kotlin-1.40.0-SNAPSHOT.jar against opentelemetry-extension-kotlin-1.39.0.jar +Comparing source compatibility of opentelemetry-extension-kotlin-1.41.0-SNAPSHOT.jar against opentelemetry-extension-kotlin-1.39.0.jar No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-extension-trace-propagators.txt b/docs/apidiffs/current_vs_latest/opentelemetry-extension-trace-propagators.txt index 4546f8f90b3..a78eead783d 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-extension-trace-propagators.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-extension-trace-propagators.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of opentelemetry-extension-trace-propagators-1.40.0-SNAPSHOT.jar against opentelemetry-extension-trace-propagators-1.39.0.jar +Comparing source compatibility of opentelemetry-extension-trace-propagators-1.41.0-SNAPSHOT.jar against opentelemetry-extension-trace-propagators-1.39.0.jar No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-opentracing-shim.txt b/docs/apidiffs/current_vs_latest/opentelemetry-opentracing-shim.txt index bfb3ff8aa63..bede2d101f0 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-opentracing-shim.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-opentracing-shim.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of opentelemetry-opentracing-shim-1.40.0-SNAPSHOT.jar against opentelemetry-opentracing-shim-1.39.0.jar +Comparing source compatibility of opentelemetry-opentracing-shim-1.41.0-SNAPSHOT.jar against opentelemetry-opentracing-shim-1.39.0.jar No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-common.txt b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-common.txt index 3d7fc037c27..23807f0f3c7 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-common.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-common.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of opentelemetry-sdk-common-1.40.0-SNAPSHOT.jar against opentelemetry-sdk-common-1.39.0.jar +Comparing source compatibility of opentelemetry-sdk-common-1.41.0-SNAPSHOT.jar against opentelemetry-sdk-common-1.39.0.jar No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-extension-autoconfigure-spi.txt b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-extension-autoconfigure-spi.txt index 99eb60df11e..dc8461c0dca 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-extension-autoconfigure-spi.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-extension-autoconfigure-spi.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of opentelemetry-sdk-extension-autoconfigure-spi-1.40.0-SNAPSHOT.jar against opentelemetry-sdk-extension-autoconfigure-spi-1.39.0.jar +Comparing source compatibility of opentelemetry-sdk-extension-autoconfigure-spi-1.41.0-SNAPSHOT.jar against opentelemetry-sdk-extension-autoconfigure-spi-1.39.0.jar No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-extension-autoconfigure.txt b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-extension-autoconfigure.txt index 7db67fe5a50..6954fa20b94 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-extension-autoconfigure.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-extension-autoconfigure.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of opentelemetry-sdk-extension-autoconfigure-1.40.0-SNAPSHOT.jar against opentelemetry-sdk-extension-autoconfigure-1.39.0.jar +Comparing source compatibility of opentelemetry-sdk-extension-autoconfigure-1.41.0-SNAPSHOT.jar against opentelemetry-sdk-extension-autoconfigure-1.39.0.jar No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-extension-jaeger-remote-sampler.txt b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-extension-jaeger-remote-sampler.txt index 52e63913bff..e3049a3753a 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-extension-jaeger-remote-sampler.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-extension-jaeger-remote-sampler.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of opentelemetry-sdk-extension-jaeger-remote-sampler-1.40.0-SNAPSHOT.jar against opentelemetry-sdk-extension-jaeger-remote-sampler-1.39.0.jar +Comparing source compatibility of opentelemetry-sdk-extension-jaeger-remote-sampler-1.41.0-SNAPSHOT.jar against opentelemetry-sdk-extension-jaeger-remote-sampler-1.39.0.jar No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-logs.txt b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-logs.txt index 3c3dfe967a3..cc067d2fc33 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-logs.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-logs.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of opentelemetry-sdk-logs-1.40.0-SNAPSHOT.jar against opentelemetry-sdk-logs-1.39.0.jar +Comparing source compatibility of opentelemetry-sdk-logs-1.41.0-SNAPSHOT.jar against opentelemetry-sdk-logs-1.39.0.jar No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-metrics.txt b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-metrics.txt index 9d61424af3a..ebf7c920b20 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-metrics.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-metrics.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of opentelemetry-sdk-metrics-1.40.0-SNAPSHOT.jar against opentelemetry-sdk-metrics-1.39.0.jar +Comparing source compatibility of opentelemetry-sdk-metrics-1.41.0-SNAPSHOT.jar against opentelemetry-sdk-metrics-1.39.0.jar No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-testing.txt b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-testing.txt index 3170b05e569..5ccef55017a 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-testing.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-testing.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of opentelemetry-sdk-testing-1.40.0-SNAPSHOT.jar against opentelemetry-sdk-testing-1.39.0.jar +Comparing source compatibility of opentelemetry-sdk-testing-1.41.0-SNAPSHOT.jar against opentelemetry-sdk-testing-1.39.0.jar No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-trace.txt b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-trace.txt index e7aa3363bcb..a6370d09708 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-trace.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-trace.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of opentelemetry-sdk-trace-1.40.0-SNAPSHOT.jar against opentelemetry-sdk-trace-1.39.0.jar +Comparing source compatibility of opentelemetry-sdk-trace-1.41.0-SNAPSHOT.jar against opentelemetry-sdk-trace-1.39.0.jar No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-sdk.txt b/docs/apidiffs/current_vs_latest/opentelemetry-sdk.txt index f9bf7be8ef4..d50b1245e64 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-sdk.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-sdk.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of opentelemetry-sdk-1.40.0-SNAPSHOT.jar against opentelemetry-sdk-1.39.0.jar +Comparing source compatibility of opentelemetry-sdk-1.41.0-SNAPSHOT.jar against opentelemetry-sdk-1.39.0.jar No changes. \ No newline at end of file diff --git a/version.gradle.kts b/version.gradle.kts index 40c074ac478..290a72c8024 100644 --- a/version.gradle.kts +++ b/version.gradle.kts @@ -1,7 +1,7 @@ val snapshot = true allprojects { - var ver = "1.40.0" + var ver = "1.41.0" val release = findProperty("otel.release") if (release != null) { ver += "-" + release From 99c5b94004a4b9501ea23216adc1a16e79d51ff4 Mon Sep 17 00:00:00 2001 From: John Watson Date: Mon, 8 Jul 2024 08:45:35 -0700 Subject: [PATCH 465/901] Ignore the japicmp diff check for bot PRs (#6559) --- .github/workflows/build.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index fa2a758d8b5..8b928eee9f1 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -74,8 +74,8 @@ jobs: RUN_JMH_BASED_TESTS: ${{ matrix.jmh-based-tests }} - name: Check for diff - # The jApiCmp diff compares current to latest, which isn't appropriate for release branches - if: ${{ !startsWith(github.ref_name, 'release/') && !startsWith(github.base_ref, 'release/') }} + # The jApiCmp diff compares current to latest, which isn't appropriate for release branches, or for bot-generated PRs + if: ${{ !startsWith(github.ref_name, 'release/') && !startsWith(github.base_ref, 'release/') && (github.actor != 'opentelemetrybot') }} run: | # need to "git add" in case any generated files did not already exist git add docs/apidiffs From 50d307c46e3547fdcd060492b475f42935828c85 Mon Sep 17 00:00:00 2001 From: OpenTelemetry Bot <107717825+opentelemetrybot@users.noreply.github.com> Date: Mon, 8 Jul 2024 23:19:20 +0200 Subject: [PATCH 466/901] Post release for version 1.40.0 (#6562) --- README.md | 70 +++++++++---------- .../1.40.0_vs_1.39.0/opentelemetry-api.txt | 2 + .../opentelemetry-context.txt | 2 + .../opentelemetry-exporter-common.txt | 2 + .../opentelemetry-exporter-logging-otlp.txt | 2 + .../opentelemetry-exporter-logging.txt | 2 + .../opentelemetry-exporter-otlp-common.txt | 2 + .../opentelemetry-exporter-otlp.txt | 2 + ...y-exporter-sender-grpc-managed-channel.txt | 2 + .../opentelemetry-exporter-sender-jdk.txt | 2 + .../opentelemetry-exporter-sender-okhttp.txt | 2 + .../opentelemetry-exporter-zipkin.txt | 2 + .../opentelemetry-extension-kotlin.txt | 2 + ...ntelemetry-extension-trace-propagators.txt | 2 + .../opentelemetry-opentracing-shim.txt | 2 + .../opentelemetry-sdk-common.txt | 2 + ...emetry-sdk-extension-autoconfigure-spi.txt | 2 + ...ntelemetry-sdk-extension-autoconfigure.txt | 2 + ...ry-sdk-extension-jaeger-remote-sampler.txt | 2 + .../opentelemetry-sdk-logs.txt | 2 + .../opentelemetry-sdk-metrics.txt | 2 + .../opentelemetry-sdk-testing.txt | 2 + .../opentelemetry-sdk-trace.txt | 2 + .../1.40.0_vs_1.39.0/opentelemetry-sdk.txt | 2 + .../current_vs_latest/opentelemetry-api.txt | 2 +- .../opentelemetry-context.txt | 2 +- .../opentelemetry-exporter-common.txt | 2 +- .../opentelemetry-exporter-logging-otlp.txt | 2 +- .../opentelemetry-exporter-logging.txt | 2 +- .../opentelemetry-exporter-otlp-common.txt | 2 +- .../opentelemetry-exporter-otlp.txt | 2 +- ...y-exporter-sender-grpc-managed-channel.txt | 2 +- .../opentelemetry-exporter-sender-jdk.txt | 2 +- .../opentelemetry-exporter-sender-okhttp.txt | 2 +- .../opentelemetry-exporter-zipkin.txt | 2 +- .../opentelemetry-extension-kotlin.txt | 2 +- ...ntelemetry-extension-trace-propagators.txt | 2 +- .../opentelemetry-opentracing-shim.txt | 2 +- .../opentelemetry-sdk-common.txt | 2 +- ...emetry-sdk-extension-autoconfigure-spi.txt | 2 +- ...ntelemetry-sdk-extension-autoconfigure.txt | 2 +- ...ry-sdk-extension-jaeger-remote-sampler.txt | 2 +- .../opentelemetry-sdk-logs.txt | 2 +- .../opentelemetry-sdk-metrics.txt | 2 +- .../opentelemetry-sdk-testing.txt | 2 +- .../opentelemetry-sdk-trace.txt | 2 +- .../current_vs_latest/opentelemetry-sdk.txt | 2 +- 47 files changed, 104 insertions(+), 58 deletions(-) create mode 100644 docs/apidiffs/1.40.0_vs_1.39.0/opentelemetry-api.txt create mode 100644 docs/apidiffs/1.40.0_vs_1.39.0/opentelemetry-context.txt create mode 100644 docs/apidiffs/1.40.0_vs_1.39.0/opentelemetry-exporter-common.txt create mode 100644 docs/apidiffs/1.40.0_vs_1.39.0/opentelemetry-exporter-logging-otlp.txt create mode 100644 docs/apidiffs/1.40.0_vs_1.39.0/opentelemetry-exporter-logging.txt create mode 100644 docs/apidiffs/1.40.0_vs_1.39.0/opentelemetry-exporter-otlp-common.txt create mode 100644 docs/apidiffs/1.40.0_vs_1.39.0/opentelemetry-exporter-otlp.txt create mode 100644 docs/apidiffs/1.40.0_vs_1.39.0/opentelemetry-exporter-sender-grpc-managed-channel.txt create mode 100644 docs/apidiffs/1.40.0_vs_1.39.0/opentelemetry-exporter-sender-jdk.txt create mode 100644 docs/apidiffs/1.40.0_vs_1.39.0/opentelemetry-exporter-sender-okhttp.txt create mode 100644 docs/apidiffs/1.40.0_vs_1.39.0/opentelemetry-exporter-zipkin.txt create mode 100644 docs/apidiffs/1.40.0_vs_1.39.0/opentelemetry-extension-kotlin.txt create mode 100644 docs/apidiffs/1.40.0_vs_1.39.0/opentelemetry-extension-trace-propagators.txt create mode 100644 docs/apidiffs/1.40.0_vs_1.39.0/opentelemetry-opentracing-shim.txt create mode 100644 docs/apidiffs/1.40.0_vs_1.39.0/opentelemetry-sdk-common.txt create mode 100644 docs/apidiffs/1.40.0_vs_1.39.0/opentelemetry-sdk-extension-autoconfigure-spi.txt create mode 100644 docs/apidiffs/1.40.0_vs_1.39.0/opentelemetry-sdk-extension-autoconfigure.txt create mode 100644 docs/apidiffs/1.40.0_vs_1.39.0/opentelemetry-sdk-extension-jaeger-remote-sampler.txt create mode 100644 docs/apidiffs/1.40.0_vs_1.39.0/opentelemetry-sdk-logs.txt create mode 100644 docs/apidiffs/1.40.0_vs_1.39.0/opentelemetry-sdk-metrics.txt create mode 100644 docs/apidiffs/1.40.0_vs_1.39.0/opentelemetry-sdk-testing.txt create mode 100644 docs/apidiffs/1.40.0_vs_1.39.0/opentelemetry-sdk-trace.txt create mode 100644 docs/apidiffs/1.40.0_vs_1.39.0/opentelemetry-sdk.txt diff --git a/README.md b/README.md index 2324558c1ae..0e9f992ec2d 100644 --- a/README.md +++ b/README.md @@ -104,7 +104,7 @@ dependency versions in sync. io.opentelemetry opentelemetry-bom - 1.39.0 + 1.40.0 pom import @@ -123,7 +123,7 @@ dependency versions in sync. ```groovy dependencies { - implementation platform("io.opentelemetry:opentelemetry-bom:1.39.0") + implementation platform("io.opentelemetry:opentelemetry-bom:1.40.0") implementation('io.opentelemetry:opentelemetry-api') } ``` @@ -132,8 +132,8 @@ Note that if you want to use any artifacts that have not fully stabilized yet (s ```groovy dependencies { - implementation platform("io.opentelemetry:opentelemetry-bom:1.39.0") - implementation platform('io.opentelemetry:opentelemetry-bom-alpha:1.39.0-alpha') + implementation platform("io.opentelemetry:opentelemetry-bom:1.40.0") + implementation platform('io.opentelemetry:opentelemetry-bom-alpha:1.40.0-alpha') implementation('io.opentelemetry:opentelemetry-api') implementation('io.opentelemetry:opentelemetry-exporter-prometheus') @@ -161,7 +161,7 @@ We strongly recommend using our published BOM to keep all dependency versions in io.opentelemetry opentelemetry-bom - 1.40.0-SNAPSHOT + 1.41.0-SNAPSHOT pom import @@ -184,7 +184,7 @@ repositories { } dependencies { - implementation platform("io.opentelemetry:opentelemetry-bom:1.40.0-SNAPSHOT") + implementation platform("io.opentelemetry:opentelemetry-bom:1.41.0-SNAPSHOT") implementation('io.opentelemetry:opentelemetry-api') } ``` @@ -229,66 +229,66 @@ dependency as follows, replacing `{{artifact-id}}` with the value from the "Arti | Component | Description | Artifact ID | Version | Javadoc | |----------------------------------------------|----------------------------------------|---------------------------|-------------------------------------------------------------|---------| -| [Bill of Materials (BOM)](./bom) | Bill of materials for stable artifacts | `opentelemetry-bom` | 1.39.0 | N/A | -| [Alpha Bill of Materials (BOM)](./bom-alpha) | Bill of materials for alpha artifacts | `opentelemetry-bom-alpha` | 1.39.0-alpha | N/A | +| [Bill of Materials (BOM)](./bom) | Bill of materials for stable artifacts | `opentelemetry-bom` | 1.40.0 | N/A | +| [Alpha Bill of Materials (BOM)](./bom-alpha) | Bill of materials for alpha artifacts | `opentelemetry-bom-alpha` | 1.40.0-alpha | N/A | ### API | Component | Description | Artifact ID | Version | Javadoc | |-----------------------------------|--------------------------------------------------------------------------------------|-------------------------------|---------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| [API](./api/all) | OpenTelemetry API, including metrics, traces, baggage, context | `opentelemetry-api` | 1.39.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-api.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-api) | -| [API Incubator](./api/incubator) | API incubator, including pass through propagator, and extended tracer, and Event API | `opentelemetry-api-incubator` | 1.39.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-api-incubator.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-api-incubator) | -| [Context API](./context) | OpenTelemetry context API | `opentelemetry-context` | 1.39.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-context.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-context) | +| [API](./api/all) | OpenTelemetry API, including metrics, traces, baggage, context | `opentelemetry-api` | 1.40.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-api.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-api) | +| [API Incubator](./api/incubator) | API incubator, including pass through propagator, and extended tracer, and Event API | `opentelemetry-api-incubator` | 1.40.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-api-incubator.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-api-incubator) | +| [Context API](./context) | OpenTelemetry context API | `opentelemetry-context` | 1.40.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-context.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-context) | ### API Extensions | Component | Description | Artifact ID | Version | Javadoc | |---------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|---------------------------------------------|-------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| [Kotlin Extension](./extensions/kotlin) | Context extension for coroutines | `opentelemetry-extension-kotlin` | 1.39.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-extension-kotlin.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-extension-kotlin) | -| [Trace Propagators Extension](./extensions/trace-propagators) | Trace propagators, including B3, Jaeger, OT Trace | `opentelemetry-extension-trace-propagators` | 1.39.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-extension-trace-propagators.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-extension-trace-propagators) | +| [Kotlin Extension](./extensions/kotlin) | Context extension for coroutines | `opentelemetry-extension-kotlin` | 1.40.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-extension-kotlin.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-extension-kotlin) | +| [Trace Propagators Extension](./extensions/trace-propagators) | Trace propagators, including B3, Jaeger, OT Trace | `opentelemetry-extension-trace-propagators` | 1.40.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-extension-trace-propagators.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-extension-trace-propagators) | ### SDK | Component | Description | Artifact ID | Version | Javadoc | |------------------------------|--------------------------------------------------------|-----------------------------|---------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| [SDK](./sdk/all) | OpenTelemetry SDK, including metrics, traces, and logs | `opentelemetry-sdk` | 1.39.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk) | -| [Metrics SDK](./sdk/metrics) | OpenTelemetry metrics SDK | `opentelemetry-sdk-metrics` | 1.39.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-metrics.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-metrics) | -| [Trace SDK](./sdk/trace) | OpenTelemetry trace SDK | `opentelemetry-sdk-trace` | 1.39.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-trace.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-trace) | -| [Log SDK](./sdk/logs) | OpenTelemetry log SDK | `opentelemetry-sdk-logs` | 1.39.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-logs.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-logs) | -| [SDK Common](./sdk/common) | Shared SDK components | `opentelemetry-sdk-common` | 1.39.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-common.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-common) | -| [SDK Testing](./sdk/testing) | Components for testing OpenTelemetry instrumentation | `opentelemetry-sdk-testing` | 1.39.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-testing.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-testing) | +| [SDK](./sdk/all) | OpenTelemetry SDK, including metrics, traces, and logs | `opentelemetry-sdk` | 1.40.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk) | +| [Metrics SDK](./sdk/metrics) | OpenTelemetry metrics SDK | `opentelemetry-sdk-metrics` | 1.40.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-metrics.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-metrics) | +| [Trace SDK](./sdk/trace) | OpenTelemetry trace SDK | `opentelemetry-sdk-trace` | 1.40.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-trace.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-trace) | +| [Log SDK](./sdk/logs) | OpenTelemetry log SDK | `opentelemetry-sdk-logs` | 1.40.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-logs.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-logs) | +| [SDK Common](./sdk/common) | Shared SDK components | `opentelemetry-sdk-common` | 1.40.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-common.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-common) | +| [SDK Testing](./sdk/testing) | Components for testing OpenTelemetry instrumentation | `opentelemetry-sdk-testing` | 1.40.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-testing.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-testing) | ### SDK Exporters | Component | Description | Artifact ID | Version | Javadoc | |-----------------------------------------------------------------------|------------------------------------------------------------------------------|-------------------------------------------------------------------------|-------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| [OTLP Exporters](./exporters/otlp/all) | OTLP gRPC & HTTP exporters, including traces, metrics, and logs | `opentelemetry-exporter-otlp` | 1.39.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-otlp.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-otlp) | -| [OTLP Logging Exporters](./exporters/logging-otlp) | Logging exporters in OTLP JSON encoding, including traces, metrics, and logs | `opentelemetry-exporter-logging-otlp` | 1.39.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-logging-otlp.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-logging-otlp) | -| [OTLP Common](./exporters/otlp/common) | Shared OTLP components (internal) | `opentelemetry-exporter-otlp-common` | 1.39.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-otlp-common.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-otlp-common) | -| [Logging Exporter](./exporters/logging) | Logging exporters, including metrics, traces, and logs | `opentelemetry-exporter-logging` | 1.39.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-logging.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-logging) | -| [Zipkin Exporter](./exporters/zipkin) | Zipkin trace exporter | `opentelemetry-exporter-zipkin` | 1.39.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-zipkin.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-zipkin) | -| [Prometheus Exporter](./exporters/prometheus) | Prometheus metric exporter | `opentelemetry-exporter-prometheus` | 1.39.0-alpha | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-prometheus.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-prometheus) | -| [Exporter Common](./exporters/common) | Shared exporter components (internal) | `opentelemetry-exporter-common` | 1.39.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-common.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-common) | -| [OkHttp Sender](./exporters/sender/okhttp) | OkHttp implementation of HttpSender (internal) | `opentelemetry-exporter-sender-okhttp` | 1.39.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-sender-okhttp.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-sender-okhttp) | -| [JDK Sender](./exporters/sender/jdk) | Java 11+ native HttpClient implementation of HttpSender (internal) | `opentelemetry-exporter-sender-jdk` TODO: remove `-alpha` after release | 1.39.0-alpha | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-sender-jdk.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-sender-jdk) | | -| [gRPC ManagedChannel Sender](./exporters/sender/grpc-managed-channel) | gRPC ManagedChannel implementation of GrpcSender (internal) | `opentelemetry-exporter-sender-grpc-managed-channel` | 1.39.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-sender-grpc-managed-channel.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-sender-grpc-managed-channel) | | +| [OTLP Exporters](./exporters/otlp/all) | OTLP gRPC & HTTP exporters, including traces, metrics, and logs | `opentelemetry-exporter-otlp` | 1.40.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-otlp.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-otlp) | +| [OTLP Logging Exporters](./exporters/logging-otlp) | Logging exporters in OTLP JSON encoding, including traces, metrics, and logs | `opentelemetry-exporter-logging-otlp` | 1.40.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-logging-otlp.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-logging-otlp) | +| [OTLP Common](./exporters/otlp/common) | Shared OTLP components (internal) | `opentelemetry-exporter-otlp-common` | 1.40.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-otlp-common.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-otlp-common) | +| [Logging Exporter](./exporters/logging) | Logging exporters, including metrics, traces, and logs | `opentelemetry-exporter-logging` | 1.40.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-logging.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-logging) | +| [Zipkin Exporter](./exporters/zipkin) | Zipkin trace exporter | `opentelemetry-exporter-zipkin` | 1.40.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-zipkin.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-zipkin) | +| [Prometheus Exporter](./exporters/prometheus) | Prometheus metric exporter | `opentelemetry-exporter-prometheus` | 1.40.0-alpha | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-prometheus.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-prometheus) | +| [Exporter Common](./exporters/common) | Shared exporter components (internal) | `opentelemetry-exporter-common` | 1.40.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-common.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-common) | +| [OkHttp Sender](./exporters/sender/okhttp) | OkHttp implementation of HttpSender (internal) | `opentelemetry-exporter-sender-okhttp` | 1.40.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-sender-okhttp.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-sender-okhttp) | +| [JDK Sender](./exporters/sender/jdk) | Java 11+ native HttpClient implementation of HttpSender (internal) | `opentelemetry-exporter-sender-jdk` TODO: remove `-alpha` after release | 1.40.0-alpha | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-sender-jdk.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-sender-jdk) | | +| [gRPC ManagedChannel Sender](./exporters/sender/grpc-managed-channel) | gRPC ManagedChannel implementation of GrpcSender (internal) | `opentelemetry-exporter-sender-grpc-managed-channel` | 1.40.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-sender-grpc-managed-channel.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-sender-grpc-managed-channel) | | ### SDK Extensions | Component | Description | Artifact ID | Version | Javadoc | |-------------------------------------------------------------------------------|------------------------------------------------------------------------------------|-----------------------------------------------------|-------------------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| [SDK Autoconfigure](./sdk-extensions/autoconfigure) | Autoconfigure OpenTelemetry SDK from env vars, system properties, and SPI | `opentelemetry-sdk-extension-autoconfigure` | 1.39.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-extension-autoconfigure.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-extension-autoconfigure) | -| [SDK Autoconfigure SPI](./sdk-extensions/autoconfigure-spi) | Service Provider Interface (SPI) definitions for autoconfigure | `opentelemetry-sdk-extension-autoconfigure-spi` | 1.39.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-extension-autoconfigure-spi.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-extension-autoconfigure-spi) | -| [SDK Jaeger Remote Sampler Extension](./sdk-extensions/jaeger-remote-sampler) | Sampler which obtains sampling configuration from remote Jaeger server | `opentelemetry-sdk-extension-jaeger-remote-sampler` | 1.39.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-extension-jaeger-remote-sampler.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-extension-jaeger-remote-sampler) | -| [SDK Incubator](./sdk-extensions/incubator) | SDK incubator, including YAML based view configuration, LeakDetectingSpanProcessor | `opentelemetry-sdk-extension-incubator` | 1.39.0-alpha | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-extension-incubator.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-extension-incubator) | +| [SDK Autoconfigure](./sdk-extensions/autoconfigure) | Autoconfigure OpenTelemetry SDK from env vars, system properties, and SPI | `opentelemetry-sdk-extension-autoconfigure` | 1.40.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-extension-autoconfigure.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-extension-autoconfigure) | +| [SDK Autoconfigure SPI](./sdk-extensions/autoconfigure-spi) | Service Provider Interface (SPI) definitions for autoconfigure | `opentelemetry-sdk-extension-autoconfigure-spi` | 1.40.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-extension-autoconfigure-spi.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-extension-autoconfigure-spi) | +| [SDK Jaeger Remote Sampler Extension](./sdk-extensions/jaeger-remote-sampler) | Sampler which obtains sampling configuration from remote Jaeger server | `opentelemetry-sdk-extension-jaeger-remote-sampler` | 1.40.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-extension-jaeger-remote-sampler.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-extension-jaeger-remote-sampler) | +| [SDK Incubator](./sdk-extensions/incubator) | SDK incubator, including YAML based view configuration, LeakDetectingSpanProcessor | `opentelemetry-sdk-extension-incubator` | 1.40.0-alpha | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-extension-incubator.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-extension-incubator) | ### Shims | Component | Description | Artifact ID | Version | Javadoc | |----------------------------------------|--------------------------------------------------------------|----------------------------------|-------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| [OpenCensus Shim](./opencensus-shim) | Bridge opencensus metrics into the OpenTelemetry metrics SDK | `opentelemetry-opencensus-shim` | 1.39.0-alpha | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-opencensus-shim.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-opencensus-shim) | -| [OpenTracing Shim](./opentracing-shim) | Bridge opentracing spans into the OpenTelemetry trace API | `opentelemetry-opentracing-shim` | 1.39.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-opentracing-shim.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-opentracing-shim) | +| [OpenCensus Shim](./opencensus-shim) | Bridge opencensus metrics into the OpenTelemetry metrics SDK | `opentelemetry-opencensus-shim` | 1.40.0-alpha | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-opencensus-shim.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-opencensus-shim) | +| [OpenTracing Shim](./opentracing-shim) | Bridge opentracing spans into the OpenTelemetry trace API | `opentelemetry-opentracing-shim` | 1.40.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-opentracing-shim.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-opentracing-shim) | ## Contributing diff --git a/docs/apidiffs/1.40.0_vs_1.39.0/opentelemetry-api.txt b/docs/apidiffs/1.40.0_vs_1.39.0/opentelemetry-api.txt new file mode 100644 index 00000000000..ab4fa9fb021 --- /dev/null +++ b/docs/apidiffs/1.40.0_vs_1.39.0/opentelemetry-api.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of opentelemetry-api-1.40.0.jar against opentelemetry-api-1.39.0.jar +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.40.0_vs_1.39.0/opentelemetry-context.txt b/docs/apidiffs/1.40.0_vs_1.39.0/opentelemetry-context.txt new file mode 100644 index 00000000000..0e0c373df57 --- /dev/null +++ b/docs/apidiffs/1.40.0_vs_1.39.0/opentelemetry-context.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of opentelemetry-context-1.40.0.jar against opentelemetry-context-1.39.0.jar +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.40.0_vs_1.39.0/opentelemetry-exporter-common.txt b/docs/apidiffs/1.40.0_vs_1.39.0/opentelemetry-exporter-common.txt new file mode 100644 index 00000000000..8ebecc326a1 --- /dev/null +++ b/docs/apidiffs/1.40.0_vs_1.39.0/opentelemetry-exporter-common.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of opentelemetry-exporter-common-1.40.0.jar against opentelemetry-exporter-common-1.39.0.jar +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.40.0_vs_1.39.0/opentelemetry-exporter-logging-otlp.txt b/docs/apidiffs/1.40.0_vs_1.39.0/opentelemetry-exporter-logging-otlp.txt new file mode 100644 index 00000000000..a422f20359e --- /dev/null +++ b/docs/apidiffs/1.40.0_vs_1.39.0/opentelemetry-exporter-logging-otlp.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of opentelemetry-exporter-logging-otlp-1.40.0.jar against opentelemetry-exporter-logging-otlp-1.39.0.jar +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.40.0_vs_1.39.0/opentelemetry-exporter-logging.txt b/docs/apidiffs/1.40.0_vs_1.39.0/opentelemetry-exporter-logging.txt new file mode 100644 index 00000000000..5492a866052 --- /dev/null +++ b/docs/apidiffs/1.40.0_vs_1.39.0/opentelemetry-exporter-logging.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of opentelemetry-exporter-logging-1.40.0.jar against opentelemetry-exporter-logging-1.39.0.jar +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.40.0_vs_1.39.0/opentelemetry-exporter-otlp-common.txt b/docs/apidiffs/1.40.0_vs_1.39.0/opentelemetry-exporter-otlp-common.txt new file mode 100644 index 00000000000..74fcc72b9de --- /dev/null +++ b/docs/apidiffs/1.40.0_vs_1.39.0/opentelemetry-exporter-otlp-common.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of opentelemetry-exporter-otlp-common-1.40.0.jar against opentelemetry-exporter-otlp-common-1.39.0.jar +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.40.0_vs_1.39.0/opentelemetry-exporter-otlp.txt b/docs/apidiffs/1.40.0_vs_1.39.0/opentelemetry-exporter-otlp.txt new file mode 100644 index 00000000000..dc0babb48fd --- /dev/null +++ b/docs/apidiffs/1.40.0_vs_1.39.0/opentelemetry-exporter-otlp.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of opentelemetry-exporter-otlp-1.40.0.jar against opentelemetry-exporter-otlp-1.39.0.jar +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.40.0_vs_1.39.0/opentelemetry-exporter-sender-grpc-managed-channel.txt b/docs/apidiffs/1.40.0_vs_1.39.0/opentelemetry-exporter-sender-grpc-managed-channel.txt new file mode 100644 index 00000000000..f02a4d71f87 --- /dev/null +++ b/docs/apidiffs/1.40.0_vs_1.39.0/opentelemetry-exporter-sender-grpc-managed-channel.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of opentelemetry-exporter-sender-grpc-managed-channel-1.40.0.jar against opentelemetry-exporter-sender-grpc-managed-channel-1.39.0.jar +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.40.0_vs_1.39.0/opentelemetry-exporter-sender-jdk.txt b/docs/apidiffs/1.40.0_vs_1.39.0/opentelemetry-exporter-sender-jdk.txt new file mode 100644 index 00000000000..385c556dfb6 --- /dev/null +++ b/docs/apidiffs/1.40.0_vs_1.39.0/opentelemetry-exporter-sender-jdk.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of opentelemetry-exporter-sender-jdk-1.40.0.jar against opentelemetry-exporter-sender-jdk-1.39.0.jar +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.40.0_vs_1.39.0/opentelemetry-exporter-sender-okhttp.txt b/docs/apidiffs/1.40.0_vs_1.39.0/opentelemetry-exporter-sender-okhttp.txt new file mode 100644 index 00000000000..d325d58ea5d --- /dev/null +++ b/docs/apidiffs/1.40.0_vs_1.39.0/opentelemetry-exporter-sender-okhttp.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of opentelemetry-exporter-sender-okhttp-1.40.0.jar against opentelemetry-exporter-sender-okhttp-1.39.0.jar +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.40.0_vs_1.39.0/opentelemetry-exporter-zipkin.txt b/docs/apidiffs/1.40.0_vs_1.39.0/opentelemetry-exporter-zipkin.txt new file mode 100644 index 00000000000..8ee1e891c91 --- /dev/null +++ b/docs/apidiffs/1.40.0_vs_1.39.0/opentelemetry-exporter-zipkin.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of opentelemetry-exporter-zipkin-1.40.0.jar against opentelemetry-exporter-zipkin-1.39.0.jar +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.40.0_vs_1.39.0/opentelemetry-extension-kotlin.txt b/docs/apidiffs/1.40.0_vs_1.39.0/opentelemetry-extension-kotlin.txt new file mode 100644 index 00000000000..c038bdf240a --- /dev/null +++ b/docs/apidiffs/1.40.0_vs_1.39.0/opentelemetry-extension-kotlin.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of opentelemetry-extension-kotlin-1.40.0.jar against opentelemetry-extension-kotlin-1.39.0.jar +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.40.0_vs_1.39.0/opentelemetry-extension-trace-propagators.txt b/docs/apidiffs/1.40.0_vs_1.39.0/opentelemetry-extension-trace-propagators.txt new file mode 100644 index 00000000000..45091f1a06c --- /dev/null +++ b/docs/apidiffs/1.40.0_vs_1.39.0/opentelemetry-extension-trace-propagators.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of opentelemetry-extension-trace-propagators-1.40.0.jar against opentelemetry-extension-trace-propagators-1.39.0.jar +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.40.0_vs_1.39.0/opentelemetry-opentracing-shim.txt b/docs/apidiffs/1.40.0_vs_1.39.0/opentelemetry-opentracing-shim.txt new file mode 100644 index 00000000000..06013311639 --- /dev/null +++ b/docs/apidiffs/1.40.0_vs_1.39.0/opentelemetry-opentracing-shim.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of opentelemetry-opentracing-shim-1.40.0.jar against opentelemetry-opentracing-shim-1.39.0.jar +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.40.0_vs_1.39.0/opentelemetry-sdk-common.txt b/docs/apidiffs/1.40.0_vs_1.39.0/opentelemetry-sdk-common.txt new file mode 100644 index 00000000000..97c399bb7b7 --- /dev/null +++ b/docs/apidiffs/1.40.0_vs_1.39.0/opentelemetry-sdk-common.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of opentelemetry-sdk-common-1.40.0.jar against opentelemetry-sdk-common-1.39.0.jar +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.40.0_vs_1.39.0/opentelemetry-sdk-extension-autoconfigure-spi.txt b/docs/apidiffs/1.40.0_vs_1.39.0/opentelemetry-sdk-extension-autoconfigure-spi.txt new file mode 100644 index 00000000000..d6707767630 --- /dev/null +++ b/docs/apidiffs/1.40.0_vs_1.39.0/opentelemetry-sdk-extension-autoconfigure-spi.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of opentelemetry-sdk-extension-autoconfigure-spi-1.40.0.jar against opentelemetry-sdk-extension-autoconfigure-spi-1.39.0.jar +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.40.0_vs_1.39.0/opentelemetry-sdk-extension-autoconfigure.txt b/docs/apidiffs/1.40.0_vs_1.39.0/opentelemetry-sdk-extension-autoconfigure.txt new file mode 100644 index 00000000000..72c89c9f34c --- /dev/null +++ b/docs/apidiffs/1.40.0_vs_1.39.0/opentelemetry-sdk-extension-autoconfigure.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of opentelemetry-sdk-extension-autoconfigure-1.40.0.jar against opentelemetry-sdk-extension-autoconfigure-1.39.0.jar +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.40.0_vs_1.39.0/opentelemetry-sdk-extension-jaeger-remote-sampler.txt b/docs/apidiffs/1.40.0_vs_1.39.0/opentelemetry-sdk-extension-jaeger-remote-sampler.txt new file mode 100644 index 00000000000..edf13347673 --- /dev/null +++ b/docs/apidiffs/1.40.0_vs_1.39.0/opentelemetry-sdk-extension-jaeger-remote-sampler.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of opentelemetry-sdk-extension-jaeger-remote-sampler-1.40.0.jar against opentelemetry-sdk-extension-jaeger-remote-sampler-1.39.0.jar +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.40.0_vs_1.39.0/opentelemetry-sdk-logs.txt b/docs/apidiffs/1.40.0_vs_1.39.0/opentelemetry-sdk-logs.txt new file mode 100644 index 00000000000..04ad97a31ae --- /dev/null +++ b/docs/apidiffs/1.40.0_vs_1.39.0/opentelemetry-sdk-logs.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of opentelemetry-sdk-logs-1.40.0.jar against opentelemetry-sdk-logs-1.39.0.jar +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.40.0_vs_1.39.0/opentelemetry-sdk-metrics.txt b/docs/apidiffs/1.40.0_vs_1.39.0/opentelemetry-sdk-metrics.txt new file mode 100644 index 00000000000..b4b81d47fa6 --- /dev/null +++ b/docs/apidiffs/1.40.0_vs_1.39.0/opentelemetry-sdk-metrics.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of opentelemetry-sdk-metrics-1.40.0.jar against opentelemetry-sdk-metrics-1.39.0.jar +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.40.0_vs_1.39.0/opentelemetry-sdk-testing.txt b/docs/apidiffs/1.40.0_vs_1.39.0/opentelemetry-sdk-testing.txt new file mode 100644 index 00000000000..3eba71a9768 --- /dev/null +++ b/docs/apidiffs/1.40.0_vs_1.39.0/opentelemetry-sdk-testing.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of opentelemetry-sdk-testing-1.40.0.jar against opentelemetry-sdk-testing-1.39.0.jar +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.40.0_vs_1.39.0/opentelemetry-sdk-trace.txt b/docs/apidiffs/1.40.0_vs_1.39.0/opentelemetry-sdk-trace.txt new file mode 100644 index 00000000000..38bc5b93520 --- /dev/null +++ b/docs/apidiffs/1.40.0_vs_1.39.0/opentelemetry-sdk-trace.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of opentelemetry-sdk-trace-1.40.0.jar against opentelemetry-sdk-trace-1.39.0.jar +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.40.0_vs_1.39.0/opentelemetry-sdk.txt b/docs/apidiffs/1.40.0_vs_1.39.0/opentelemetry-sdk.txt new file mode 100644 index 00000000000..6eb2fc4ff19 --- /dev/null +++ b/docs/apidiffs/1.40.0_vs_1.39.0/opentelemetry-sdk.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of opentelemetry-sdk-1.40.0.jar against opentelemetry-sdk-1.39.0.jar +No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-api.txt b/docs/apidiffs/current_vs_latest/opentelemetry-api.txt index 308b2296bf9..2f47172d1e2 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-api.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-api.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of opentelemetry-api-1.41.0-SNAPSHOT.jar against opentelemetry-api-1.39.0.jar +Comparing source compatibility of opentelemetry-api-1.41.0-SNAPSHOT.jar against opentelemetry-api-1.40.0.jar No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-context.txt b/docs/apidiffs/current_vs_latest/opentelemetry-context.txt index fb98e2e4d33..99fd10ca51c 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-context.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-context.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of opentelemetry-context-1.41.0-SNAPSHOT.jar against opentelemetry-context-1.39.0.jar +Comparing source compatibility of opentelemetry-context-1.41.0-SNAPSHOT.jar against opentelemetry-context-1.40.0.jar No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-common.txt b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-common.txt index 3744deb0c83..293b0e7753a 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-common.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-common.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of opentelemetry-exporter-common-1.41.0-SNAPSHOT.jar against opentelemetry-exporter-common-1.39.0.jar +Comparing source compatibility of opentelemetry-exporter-common-1.41.0-SNAPSHOT.jar against opentelemetry-exporter-common-1.40.0.jar No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-logging-otlp.txt b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-logging-otlp.txt index 5552c072ca2..b3b31306740 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-logging-otlp.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-logging-otlp.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of opentelemetry-exporter-logging-otlp-1.41.0-SNAPSHOT.jar against opentelemetry-exporter-logging-otlp-1.39.0.jar +Comparing source compatibility of opentelemetry-exporter-logging-otlp-1.41.0-SNAPSHOT.jar against opentelemetry-exporter-logging-otlp-1.40.0.jar No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-logging.txt b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-logging.txt index 8228d777d48..592ea522f93 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-logging.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-logging.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of opentelemetry-exporter-logging-1.41.0-SNAPSHOT.jar against opentelemetry-exporter-logging-1.39.0.jar +Comparing source compatibility of opentelemetry-exporter-logging-1.41.0-SNAPSHOT.jar against opentelemetry-exporter-logging-1.40.0.jar No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-otlp-common.txt b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-otlp-common.txt index e7c4c9aed92..11b791dba91 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-otlp-common.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-otlp-common.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of opentelemetry-exporter-otlp-common-1.41.0-SNAPSHOT.jar against opentelemetry-exporter-otlp-common-1.39.0.jar +Comparing source compatibility of opentelemetry-exporter-otlp-common-1.41.0-SNAPSHOT.jar against opentelemetry-exporter-otlp-common-1.40.0.jar No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-otlp.txt b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-otlp.txt index 41930cf1924..c921ed65a0e 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-otlp.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-otlp.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of opentelemetry-exporter-otlp-1.41.0-SNAPSHOT.jar against opentelemetry-exporter-otlp-1.39.0.jar +Comparing source compatibility of opentelemetry-exporter-otlp-1.41.0-SNAPSHOT.jar against opentelemetry-exporter-otlp-1.40.0.jar No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-sender-grpc-managed-channel.txt b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-sender-grpc-managed-channel.txt index c70533096ba..c34170d151e 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-sender-grpc-managed-channel.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-sender-grpc-managed-channel.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of opentelemetry-exporter-sender-grpc-managed-channel-1.41.0-SNAPSHOT.jar against opentelemetry-exporter-sender-grpc-managed-channel-1.39.0.jar +Comparing source compatibility of opentelemetry-exporter-sender-grpc-managed-channel-1.41.0-SNAPSHOT.jar against opentelemetry-exporter-sender-grpc-managed-channel-1.40.0.jar No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-sender-jdk.txt b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-sender-jdk.txt index 4cf59ce4902..30ec5ef8469 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-sender-jdk.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-sender-jdk.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of opentelemetry-exporter-sender-jdk-1.41.0-SNAPSHOT.jar against opentelemetry-exporter-sender-jdk-1.39.0.jar +Comparing source compatibility of opentelemetry-exporter-sender-jdk-1.41.0-SNAPSHOT.jar against opentelemetry-exporter-sender-jdk-1.40.0.jar No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-sender-okhttp.txt b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-sender-okhttp.txt index 1d952ead0d4..610f416ec20 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-sender-okhttp.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-sender-okhttp.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of opentelemetry-exporter-sender-okhttp-1.41.0-SNAPSHOT.jar against opentelemetry-exporter-sender-okhttp-1.39.0.jar +Comparing source compatibility of opentelemetry-exporter-sender-okhttp-1.41.0-SNAPSHOT.jar against opentelemetry-exporter-sender-okhttp-1.40.0.jar No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-zipkin.txt b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-zipkin.txt index c7f5c981a2f..da02402b76c 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-zipkin.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-zipkin.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of opentelemetry-exporter-zipkin-1.41.0-SNAPSHOT.jar against opentelemetry-exporter-zipkin-1.39.0.jar +Comparing source compatibility of opentelemetry-exporter-zipkin-1.41.0-SNAPSHOT.jar against opentelemetry-exporter-zipkin-1.40.0.jar No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-extension-kotlin.txt b/docs/apidiffs/current_vs_latest/opentelemetry-extension-kotlin.txt index c0c356b5dfc..a853783527d 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-extension-kotlin.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-extension-kotlin.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of opentelemetry-extension-kotlin-1.41.0-SNAPSHOT.jar against opentelemetry-extension-kotlin-1.39.0.jar +Comparing source compatibility of opentelemetry-extension-kotlin-1.41.0-SNAPSHOT.jar against opentelemetry-extension-kotlin-1.40.0.jar No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-extension-trace-propagators.txt b/docs/apidiffs/current_vs_latest/opentelemetry-extension-trace-propagators.txt index a78eead783d..b081205d5c7 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-extension-trace-propagators.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-extension-trace-propagators.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of opentelemetry-extension-trace-propagators-1.41.0-SNAPSHOT.jar against opentelemetry-extension-trace-propagators-1.39.0.jar +Comparing source compatibility of opentelemetry-extension-trace-propagators-1.41.0-SNAPSHOT.jar against opentelemetry-extension-trace-propagators-1.40.0.jar No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-opentracing-shim.txt b/docs/apidiffs/current_vs_latest/opentelemetry-opentracing-shim.txt index bede2d101f0..b5ebebc0df0 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-opentracing-shim.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-opentracing-shim.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of opentelemetry-opentracing-shim-1.41.0-SNAPSHOT.jar against opentelemetry-opentracing-shim-1.39.0.jar +Comparing source compatibility of opentelemetry-opentracing-shim-1.41.0-SNAPSHOT.jar against opentelemetry-opentracing-shim-1.40.0.jar No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-common.txt b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-common.txt index 23807f0f3c7..cc49df57512 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-common.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-common.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of opentelemetry-sdk-common-1.41.0-SNAPSHOT.jar against opentelemetry-sdk-common-1.39.0.jar +Comparing source compatibility of opentelemetry-sdk-common-1.41.0-SNAPSHOT.jar against opentelemetry-sdk-common-1.40.0.jar No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-extension-autoconfigure-spi.txt b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-extension-autoconfigure-spi.txt index dc8461c0dca..2746b5f2db3 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-extension-autoconfigure-spi.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-extension-autoconfigure-spi.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of opentelemetry-sdk-extension-autoconfigure-spi-1.41.0-SNAPSHOT.jar against opentelemetry-sdk-extension-autoconfigure-spi-1.39.0.jar +Comparing source compatibility of opentelemetry-sdk-extension-autoconfigure-spi-1.41.0-SNAPSHOT.jar against opentelemetry-sdk-extension-autoconfigure-spi-1.40.0.jar No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-extension-autoconfigure.txt b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-extension-autoconfigure.txt index 6954fa20b94..c4cab0f5d87 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-extension-autoconfigure.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-extension-autoconfigure.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of opentelemetry-sdk-extension-autoconfigure-1.41.0-SNAPSHOT.jar against opentelemetry-sdk-extension-autoconfigure-1.39.0.jar +Comparing source compatibility of opentelemetry-sdk-extension-autoconfigure-1.41.0-SNAPSHOT.jar against opentelemetry-sdk-extension-autoconfigure-1.40.0.jar No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-extension-jaeger-remote-sampler.txt b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-extension-jaeger-remote-sampler.txt index e3049a3753a..4e9bf403288 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-extension-jaeger-remote-sampler.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-extension-jaeger-remote-sampler.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of opentelemetry-sdk-extension-jaeger-remote-sampler-1.41.0-SNAPSHOT.jar against opentelemetry-sdk-extension-jaeger-remote-sampler-1.39.0.jar +Comparing source compatibility of opentelemetry-sdk-extension-jaeger-remote-sampler-1.41.0-SNAPSHOT.jar against opentelemetry-sdk-extension-jaeger-remote-sampler-1.40.0.jar No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-logs.txt b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-logs.txt index cc067d2fc33..6a9004e48a2 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-logs.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-logs.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of opentelemetry-sdk-logs-1.41.0-SNAPSHOT.jar against opentelemetry-sdk-logs-1.39.0.jar +Comparing source compatibility of opentelemetry-sdk-logs-1.41.0-SNAPSHOT.jar against opentelemetry-sdk-logs-1.40.0.jar No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-metrics.txt b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-metrics.txt index ebf7c920b20..16fcea04710 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-metrics.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-metrics.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of opentelemetry-sdk-metrics-1.41.0-SNAPSHOT.jar against opentelemetry-sdk-metrics-1.39.0.jar +Comparing source compatibility of opentelemetry-sdk-metrics-1.41.0-SNAPSHOT.jar against opentelemetry-sdk-metrics-1.40.0.jar No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-testing.txt b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-testing.txt index 5ccef55017a..e82c60b281d 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-testing.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-testing.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of opentelemetry-sdk-testing-1.41.0-SNAPSHOT.jar against opentelemetry-sdk-testing-1.39.0.jar +Comparing source compatibility of opentelemetry-sdk-testing-1.41.0-SNAPSHOT.jar against opentelemetry-sdk-testing-1.40.0.jar No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-trace.txt b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-trace.txt index a6370d09708..4e569d20a7f 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-trace.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-trace.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of opentelemetry-sdk-trace-1.41.0-SNAPSHOT.jar against opentelemetry-sdk-trace-1.39.0.jar +Comparing source compatibility of opentelemetry-sdk-trace-1.41.0-SNAPSHOT.jar against opentelemetry-sdk-trace-1.40.0.jar No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-sdk.txt b/docs/apidiffs/current_vs_latest/opentelemetry-sdk.txt index d50b1245e64..e94606b0616 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-sdk.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-sdk.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of opentelemetry-sdk-1.41.0-SNAPSHOT.jar against opentelemetry-sdk-1.39.0.jar +Comparing source compatibility of opentelemetry-sdk-1.41.0-SNAPSHOT.jar against opentelemetry-sdk-1.40.0.jar No changes. \ No newline at end of file From 5ebb37ac6f0cdc7c1ea0103740ebe553b54200ad Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 8 Jul 2024 16:23:12 -0500 Subject: [PATCH 467/901] Update dependency org.codehaus.mojo:animal-sniffer-annotations to v1.24 (#6553) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- dependencyManagement/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index 3c7685c98fe..41af5c96a10 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -75,7 +75,7 @@ val DEPENDENCIES = listOf( "nl.jqno.equalsverifier:equalsverifier:3.16.1", "org.awaitility:awaitility:4.2.1", "org.bouncycastle:bcpkix-jdk15on:1.70", - "org.codehaus.mojo:animal-sniffer-annotations:1.23", + "org.codehaus.mojo:animal-sniffer-annotations:1.24", "org.jctools:jctools-core:4.0.5", "org.junit-pioneer:junit-pioneer:1.9.1", "org.mock-server:mockserver-netty:5.15.0:shaded", From 6b1092a89f6fce4d0de5b437be820201631bef8d Mon Sep 17 00:00:00 2001 From: Jonathan Halliday Date: Mon, 8 Jul 2024 22:45:26 +0100 Subject: [PATCH 468/901] Add exporter data model impl for profiling signal type. (#6498) --- exporters/otlp/profiles/build.gradle.kts | 2 + .../data/ImmutableAttributeUnitData.java | 33 ++++++++ .../internal/data/ImmutableFunctionData.java | 34 ++++++++ .../internal/data/ImmutableLabelData.java | 32 ++++++++ .../otlp/internal/data/ImmutableLineData.java | 33 ++++++++ .../otlp/internal/data/ImmutableLinkData.java | 33 ++++++++ .../internal/data/ImmutableLocationData.java | 42 ++++++++++ .../internal/data/ImmutableMappingData.java | 58 ++++++++++++++ .../data/ImmutableProfileContainerData.java | 63 +++++++++++++++ .../internal/data/ImmutableProfileData.java | 80 +++++++++++++++++++ .../internal/data/ImmutableSampleData.java | 48 +++++++++++ .../internal/data/ImmutableValueTypeData.java | 35 ++++++++ .../exporter/otlp/profiles/LocationData.java | 2 +- 13 files changed, 494 insertions(+), 1 deletion(-) create mode 100644 exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/internal/data/ImmutableAttributeUnitData.java create mode 100644 exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/internal/data/ImmutableFunctionData.java create mode 100644 exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/internal/data/ImmutableLabelData.java create mode 100644 exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/internal/data/ImmutableLineData.java create mode 100644 exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/internal/data/ImmutableLinkData.java create mode 100644 exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/internal/data/ImmutableLocationData.java create mode 100644 exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/internal/data/ImmutableMappingData.java create mode 100644 exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/internal/data/ImmutableProfileContainerData.java create mode 100644 exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/internal/data/ImmutableProfileData.java create mode 100644 exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/internal/data/ImmutableSampleData.java create mode 100644 exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/internal/data/ImmutableValueTypeData.java diff --git a/exporters/otlp/profiles/build.gradle.kts b/exporters/otlp/profiles/build.gradle.kts index a24e2a82739..45b80b238a6 100644 --- a/exporters/otlp/profiles/build.gradle.kts +++ b/exporters/otlp/profiles/build.gradle.kts @@ -11,4 +11,6 @@ otelJava.moduleName.set("io.opentelemetry.exporter.otlp.profiles") dependencies { api(project(":sdk:common")) + + annotationProcessor("com.google.auto.value:auto-value") } diff --git a/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/internal/data/ImmutableAttributeUnitData.java b/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/internal/data/ImmutableAttributeUnitData.java new file mode 100644 index 00000000000..60255827102 --- /dev/null +++ b/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/internal/data/ImmutableAttributeUnitData.java @@ -0,0 +1,33 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.exporter.otlp.internal.data; + +import com.google.auto.value.AutoValue; +import io.opentelemetry.exporter.otlp.profiles.AttributeUnitData; +import javax.annotation.concurrent.Immutable; + +/** + * Auto value implementation of {@link AttributeUnitData}, which represents a mapping between + * Attribute Keys and Units. + * + *

      This class is internal and is hence not for public use. Its APIs are unstable and can change + * at any time. + */ +@Immutable +@AutoValue +public abstract class ImmutableAttributeUnitData implements AttributeUnitData { + + /** + * Returns a new AttributeUnitData mapping the given key to the given unit. + * + * @return a new AttributeUnitData mapping the given key to the given unit. + */ + public static AttributeUnitData create(long attributeKey, long unitIndex) { + return new AutoValue_ImmutableAttributeUnitData(attributeKey, unitIndex); + } + + ImmutableAttributeUnitData() {} +} diff --git a/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/internal/data/ImmutableFunctionData.java b/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/internal/data/ImmutableFunctionData.java new file mode 100644 index 00000000000..30de9f2927c --- /dev/null +++ b/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/internal/data/ImmutableFunctionData.java @@ -0,0 +1,34 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.exporter.otlp.internal.data; + +import com.google.auto.value.AutoValue; +import io.opentelemetry.exporter.otlp.profiles.FunctionData; +import javax.annotation.concurrent.Immutable; + +/** + * Auto value implementation of {@link FunctionData}, which describes a code function. + * + *

      This class is internal and is hence not for public use. Its APIs are unstable and can change + * at any time. + */ +@Immutable +@AutoValue +public abstract class ImmutableFunctionData implements FunctionData { + + /** + * Returns a new FunctionData describing the given function characteristics. + * + * @return a new FunctionData describing the given function characteristics. + */ + public static FunctionData create( + long nameIndex, long systemNameIndex, long filenameIndex, long startLine) { + return new AutoValue_ImmutableFunctionData( + nameIndex, systemNameIndex, filenameIndex, startLine); + } + + ImmutableFunctionData() {} +} diff --git a/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/internal/data/ImmutableLabelData.java b/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/internal/data/ImmutableLabelData.java new file mode 100644 index 00000000000..77797fee92c --- /dev/null +++ b/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/internal/data/ImmutableLabelData.java @@ -0,0 +1,32 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.exporter.otlp.internal.data; + +import com.google.auto.value.AutoValue; +import io.opentelemetry.exporter.otlp.profiles.LabelData; +import javax.annotation.concurrent.Immutable; + +/** + * Auto value implementation of {@link LabelData}, which provides additional context for a sample. + * + *

      This class is internal and is hence not for public use. Its APIs are unstable and can change + * at any time. + */ +@Immutable +@AutoValue +public abstract class ImmutableLabelData implements LabelData { + + /** + * Returns a new LabelData describing the given context for a sample. + * + * @return a new LabelData describing the given context for a sample. + */ + public static LabelData create(long keyIndex, long strIndex, long num, long numUnitIndex) { + return new AutoValue_ImmutableLabelData(keyIndex, strIndex, num, numUnitIndex); + } + + ImmutableLabelData() {} +} diff --git a/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/internal/data/ImmutableLineData.java b/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/internal/data/ImmutableLineData.java new file mode 100644 index 00000000000..e5c5d673d23 --- /dev/null +++ b/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/internal/data/ImmutableLineData.java @@ -0,0 +1,33 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.exporter.otlp.internal.data; + +import com.google.auto.value.AutoValue; +import io.opentelemetry.exporter.otlp.profiles.LineData; +import javax.annotation.concurrent.Immutable; + +/** + * Auto value implementation of {@link LineData}, which details a specific line in a source code, + * linked to a function. + * + *

      This class is internal and is hence not for public use. Its APIs are unstable and can change + * at any time. + */ +@Immutable +@AutoValue +public abstract class ImmutableLineData implements LineData { + + /** + * Returns a new LineData describing the given details a specific line in a source code. + * + * @return a new LineData describing the given details a specific line in a source code. + */ + public static LineData create(long functionIndex, long line, long column) { + return new AutoValue_ImmutableLineData(functionIndex, line, column); + } + + ImmutableLineData() {} +} diff --git a/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/internal/data/ImmutableLinkData.java b/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/internal/data/ImmutableLinkData.java new file mode 100644 index 00000000000..1345503b405 --- /dev/null +++ b/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/internal/data/ImmutableLinkData.java @@ -0,0 +1,33 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.exporter.otlp.internal.data; + +import com.google.auto.value.AutoValue; +import io.opentelemetry.exporter.otlp.profiles.LinkData; +import javax.annotation.concurrent.Immutable; + +/** + * Auto value implementation of {@link LinkData}, which represents a connection from a profile + * Sample to a trace Span. + * + *

      This class is internal and is hence not for public use. Its APIs are unstable and can change + * at any time. + */ +@Immutable +@AutoValue +public abstract class ImmutableLinkData implements LinkData { + + /** + * Returns a new LinkData representing an association to the given trace span. + * + * @return a new LinkData representing an association to the given trace span. + */ + public static LinkData create(String traceId, String spanId) { + return new AutoValue_ImmutableLinkData(traceId, spanId); + } + + ImmutableLinkData() {} +} diff --git a/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/internal/data/ImmutableLocationData.java b/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/internal/data/ImmutableLocationData.java new file mode 100644 index 00000000000..13554152dcd --- /dev/null +++ b/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/internal/data/ImmutableLocationData.java @@ -0,0 +1,42 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.exporter.otlp.internal.data; + +import com.google.auto.value.AutoValue; +import io.opentelemetry.exporter.otlp.profiles.LineData; +import io.opentelemetry.exporter.otlp.profiles.LocationData; +import java.util.List; +import javax.annotation.concurrent.Immutable; + +/** + * Auto value implementation of {@link LocationData}, which describes function and line table debug + * information. + * + *

      This class is internal and is hence not for public use. Its APIs are unstable and can change + * at any time. + */ +@Immutable +@AutoValue +public abstract class ImmutableLocationData implements LocationData { + + /** + * Returns a new LocationData describing the given function and line table information. + * + * @return a new LocationData describing the given function and line table information. + */ + public static LocationData create( + long mappingIndex, + long address, + List lines, + boolean folded, + int typeIndex, + List attributes) { + return new AutoValue_ImmutableLocationData( + mappingIndex, address, lines, folded, typeIndex, attributes); + } + + ImmutableLocationData() {} +} diff --git a/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/internal/data/ImmutableMappingData.java b/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/internal/data/ImmutableMappingData.java new file mode 100644 index 00000000000..da020967adb --- /dev/null +++ b/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/internal/data/ImmutableMappingData.java @@ -0,0 +1,58 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.exporter.otlp.internal.data; + +import com.google.auto.value.AutoValue; +import io.opentelemetry.exporter.otlp.profiles.BuildIdKind; +import io.opentelemetry.exporter.otlp.profiles.MappingData; +import java.util.List; +import javax.annotation.concurrent.Immutable; + +/** + * Auto value implementation of {@link MappingData}, which describes the mapping of a binary in + * memory. + * + *

      This class is internal and is hence not for public use. Its APIs are unstable and can change + * at any time. + */ +@Immutable +@AutoValue +public abstract class ImmutableMappingData implements MappingData { + + /** + * Returns a new MappingData describing the given mapping of a binary in memory. + * + * @return a new MappingData describing the given mapping of a binary in memory. + */ + @SuppressWarnings("TooManyParameters") + public static MappingData create( + long memoryStart, + long memoryLimit, + long fileOffset, + long filenameIndex, + long buildIdIndex, + BuildIdKind buildIdKind, + List attributeIndices, + boolean hasFunctions, + boolean hasFilenames, + boolean hasLineNumbers, + boolean hasInlineFrames) { + return new AutoValue_ImmutableMappingData( + memoryStart, + memoryLimit, + fileOffset, + filenameIndex, + buildIdIndex, + buildIdKind, + attributeIndices, + hasFunctions, + hasFilenames, + hasLineNumbers, + hasInlineFrames); + } + + ImmutableMappingData() {} +} diff --git a/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/internal/data/ImmutableProfileContainerData.java b/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/internal/data/ImmutableProfileContainerData.java new file mode 100644 index 00000000000..e6449c88e10 --- /dev/null +++ b/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/internal/data/ImmutableProfileContainerData.java @@ -0,0 +1,63 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.exporter.otlp.internal.data; + +import com.google.auto.value.AutoValue; +import io.opentelemetry.api.common.Attributes; +import io.opentelemetry.exporter.otlp.profiles.ProfileContainerData; +import io.opentelemetry.exporter.otlp.profiles.ProfileData; +import io.opentelemetry.sdk.common.InstrumentationScopeInfo; +import io.opentelemetry.sdk.resources.Resource; +import java.nio.ByteBuffer; +import javax.annotation.Nullable; +import javax.annotation.concurrent.Immutable; + +/** + * Auto value implementation of {@link ProfileContainerData}, which represents a single profile. + * + *

      This class is internal and is hence not for public use. Its APIs are unstable and can change + * at any time. + */ +@Immutable +@AutoValue +public abstract class ImmutableProfileContainerData implements ProfileContainerData { + + /** + * Returns a new ProfileContainerData representing the given profile information. + * + * @return a new ProfileContainerData representing the given profile information. + */ + @SuppressWarnings("TooManyParameters") + public static ProfileContainerData create( + Resource resource, + InstrumentationScopeInfo instrumentationScopeInfo, + String profileId, + long startEpochNanos, + long endEpochNanos, + Attributes attributes, + int totalAttributeCount, + @Nullable String originalPayloadFormat, + ByteBuffer originalPayload, + ProfileData profile) { + return new AutoValue_ImmutableProfileContainerData( + resource, + instrumentationScopeInfo, + profileId, + startEpochNanos, + endEpochNanos, + attributes, + totalAttributeCount, + originalPayloadFormat, + originalPayload, + profile); + } + + ImmutableProfileContainerData() {} + + public ByteBuffer getOriginalPayloadReadOnly() { + return getOriginalPayload().asReadOnlyBuffer(); + } +} diff --git a/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/internal/data/ImmutableProfileData.java b/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/internal/data/ImmutableProfileData.java new file mode 100644 index 00000000000..717084d320a --- /dev/null +++ b/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/internal/data/ImmutableProfileData.java @@ -0,0 +1,80 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.exporter.otlp.internal.data; + +import com.google.auto.value.AutoValue; +import io.opentelemetry.api.common.Attributes; +import io.opentelemetry.exporter.otlp.profiles.AttributeUnitData; +import io.opentelemetry.exporter.otlp.profiles.FunctionData; +import io.opentelemetry.exporter.otlp.profiles.LinkData; +import io.opentelemetry.exporter.otlp.profiles.LocationData; +import io.opentelemetry.exporter.otlp.profiles.MappingData; +import io.opentelemetry.exporter.otlp.profiles.ProfileData; +import io.opentelemetry.exporter.otlp.profiles.SampleData; +import io.opentelemetry.exporter.otlp.profiles.ValueTypeData; +import java.util.List; +import javax.annotation.concurrent.Immutable; + +/** + * Auto value implementation of {@link ProfileData}, which represents a complete profile, including + * sample types, samples, mappings to binaries, locations, functions, string table, and additional + * metadata. + * + *

      This class is internal and is hence not for public use. Its APIs are unstable and can change + * at any time. + */ +@Immutable +@AutoValue +public abstract class ImmutableProfileData implements ProfileData { + + /** + * Returns a new ProfileData representing the given data. + * + * @return a new ProfileData representing the given data. + */ + @SuppressWarnings("TooManyParameters") + public static ProfileData create( + List sampleTypes, + List samples, + List mappings, + List locations, + List locationIndices, + List functions, + Attributes attributes, + List attributeUnits, + List links, + List stringTable, + long dropFrames, + long keepFrames, + long timeNanos, + long durationNanos, + ValueTypeData periodType, + long period, + List comment, + long defaultSampleType) { + return new AutoValue_ImmutableProfileData( + sampleTypes, + samples, + mappings, + locations, + locationIndices, + functions, + attributes, + attributeUnits, + links, + stringTable, + dropFrames, + keepFrames, + timeNanos, + durationNanos, + periodType, + period, + comment, + defaultSampleType); + } + + ImmutableProfileData() {} +} diff --git a/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/internal/data/ImmutableSampleData.java b/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/internal/data/ImmutableSampleData.java new file mode 100644 index 00000000000..6d121146e52 --- /dev/null +++ b/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/internal/data/ImmutableSampleData.java @@ -0,0 +1,48 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.exporter.otlp.internal.data; + +import com.google.auto.value.AutoValue; +import io.opentelemetry.exporter.otlp.profiles.SampleData; +import java.util.List; +import javax.annotation.concurrent.Immutable; + +/** + * Auto value implementation of {@link SampleData}, which records values encountered in some program + * context. + * + *

      This class is internal and is hence not for public use. Its APIs are unstable and can change + * at any time. + */ +@Immutable +@AutoValue +public abstract class ImmutableSampleData implements SampleData { + + /** + * Returns a new SampleData representing the given program context. + * + * @return a new SampleData representing the given program context. + */ + public static SampleData create( + long locationsStartIndex, + long locationsLength, + int stacktraceIdIndex, + List values, + List attributes, + long link, + List timestamps) { + return new AutoValue_ImmutableSampleData( + locationsStartIndex, + locationsLength, + stacktraceIdIndex, + values, + attributes, + link, + timestamps); + } + + ImmutableSampleData() {} +} diff --git a/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/internal/data/ImmutableValueTypeData.java b/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/internal/data/ImmutableValueTypeData.java new file mode 100644 index 00000000000..3d6ff8c4281 --- /dev/null +++ b/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/internal/data/ImmutableValueTypeData.java @@ -0,0 +1,35 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.exporter.otlp.internal.data; + +import com.google.auto.value.AutoValue; +import io.opentelemetry.exporter.otlp.profiles.AggregationTemporality; +import io.opentelemetry.exporter.otlp.profiles.ValueTypeData; +import javax.annotation.concurrent.Immutable; + +/** + * Auto value implementation of {@link ValueTypeData}, which describes the type and units of a + * value. + * + *

      This class is internal and is hence not for public use. Its APIs are unstable and can change + * at any time. + */ +@Immutable +@AutoValue +public abstract class ImmutableValueTypeData implements ValueTypeData { + + /** + * Returns a new ValueTypeData describing the given type and unit characteristics. + * + * @return a new ValueTypeData describing the given type and unit characteristics. + */ + public static ValueTypeData create( + long type, long unit, AggregationTemporality aggregationTemporality) { + return new AutoValue_ImmutableValueTypeData(type, unit, aggregationTemporality); + } + + ImmutableValueTypeData() {} +} diff --git a/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/LocationData.java b/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/LocationData.java index d22ba65c55d..a36280cebd1 100644 --- a/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/LocationData.java +++ b/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/LocationData.java @@ -9,7 +9,7 @@ import javax.annotation.concurrent.Immutable; /** - * Describes a function. + * Describes function and line table debug information. * * @see "pprofextended.proto::Location" */ From 7b85775807a16293f94b38af9740ed555cb553c4 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 8 Jul 2024 16:55:02 -0500 Subject: [PATCH 469/901] Update dependency org.owasp:dependency-check-gradle to v10 (#6547) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- buildSrc/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts index 2006e0b7aeb..5504d89b8d4 100644 --- a/buildSrc/build.gradle.kts +++ b/buildSrc/build.gradle.kts @@ -66,7 +66,7 @@ dependencies { implementation("net.ltgt.gradle:gradle-errorprone-plugin:4.0.1") implementation("net.ltgt.gradle:gradle-nullaway-plugin:2.0.0") implementation("org.jetbrains.kotlin:kotlin-gradle-plugin:2.0.0") - implementation("org.owasp:dependency-check-gradle:9.2.0") + implementation("org.owasp:dependency-check-gradle:10.0.2") implementation("ru.vyarus:gradle-animalsniffer-plugin:1.7.1") } From f1fc3cd17ce5f436c45c5c672ebf602a631a4341 Mon Sep 17 00:00:00 2001 From: "HS.Zhang" <80237674+hongshuai1994@users.noreply.github.com> Date: Tue, 9 Jul 2024 06:12:37 +0800 Subject: [PATCH 470/901] Update the Composing builds section in contributing.md (#6560) Co-authored-by: Jack Berg --- CONTRIBUTING.md | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 0eac89cb75d..c8285b218e7 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -250,13 +250,18 @@ Example usage could be as follows: } ``` + Please confirm whether the local opentelemetry-java version is consistent with the + opentelemetry-java version declared in the project that relies on opentelemetry-java. + If it is inconsistent, `dependencySubstitution` may not take effect. + See [the Gradle documentation](https://docs.gradle.org/current/userguide/composite_builds.html#included_build_declaring_substitutions) for more information. - 4. If you now build your project, it will use the included build to supply the opentelemetry-java artifacts, ignoring any version declarations. Use the prefix `:DIRECTORY:` to refer to tasks/projects within the included build, where DIRECTORY is the name of the directory in the included build (only the part after the last `/`). +5. Here are some issues and solutions ([discussions/6551](https://github.com/open-telemetry/opentelemetry-java/discussions/6551)) + you may encounter that may be helpful to you. ### Updating the OTLP protobufs From 13a11fb8016adc0310e2c3017cd63846626724d2 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 8 Jul 2024 15:14:12 -0700 Subject: [PATCH 471/901] Update dependency io.opentelemetry.semconv:opentelemetry-semconv-incubating to v1.26.0-alpha (#6563) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- dependencyManagement/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index 41af5c96a10..689d185056c 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -66,7 +66,7 @@ val DEPENDENCIES = listOf( "io.github.netmikey.logunit:logunit-jul:2.0.0", "io.jaegertracing:jaeger-client:1.8.1", "io.opentelemetry.contrib:opentelemetry-aws-xray-propagator:1.29.0-alpha", - "io.opentelemetry.semconv:opentelemetry-semconv-incubating:1.25.0-alpha", + "io.opentelemetry.semconv:opentelemetry-semconv-incubating:1.26.0-alpha", "io.opentelemetry.proto:opentelemetry-proto:1.3.2-alpha", "io.opentracing:opentracing-api:0.33.0", "io.opentracing:opentracing-noop:0.33.0", From 09c7c4a992f75cb29289345d772548eb68eb0073 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 8 Jul 2024 15:52:31 -0700 Subject: [PATCH 472/901] Update dependency com.fasterxml.jackson:jackson-bom to v2.17.2 (#6557) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- dependencyManagement/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index 689d185056c..55ae7366108 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -8,7 +8,7 @@ val dependencyVersions = hashMapOf() rootProject.extra["versions"] = dependencyVersions val DEPENDENCY_BOMS = listOf( - "com.fasterxml.jackson:jackson-bom:2.17.1", + "com.fasterxml.jackson:jackson-bom:2.17.2", "com.google.guava:guava-bom:33.2.1-jre", "com.google.protobuf:protobuf-bom:3.25.3", "com.linecorp.armeria:armeria-bom:1.29.1", From 0bc74744cb3c00f5551c3c062bddbfc20390c62d Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 9 Jul 2024 13:04:07 -0700 Subject: [PATCH 473/901] Update dependency org.assertj:assertj-bom to v3.26.3 (#6566) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- dependencyManagement/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index 55ae7366108..c6b38f36e38 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -18,7 +18,7 @@ val DEPENDENCY_BOMS = listOf( "io.netty:netty-bom:4.1.111.Final", "io.zipkin.brave:brave-bom:6.0.3", "io.zipkin.reporter2:zipkin-reporter-bom:3.4.0", - "org.assertj:assertj-bom:3.26.0", + "org.assertj:assertj-bom:3.26.3", "org.junit:junit-bom:5.10.3", "org.testcontainers:testcontainers-bom:1.19.8", "org.snakeyaml:snakeyaml-engine:2.7" From 8ad5cacc165c3b40f16ce1523cf7791890eea182 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 9 Jul 2024 18:06:39 -0700 Subject: [PATCH 474/901] Update dependency com.google.api.grpc:proto-google-common-protos to v2.41.0 (#6538) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- dependencyManagement/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index c6b38f36e38..fa7104ef69d 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -55,7 +55,7 @@ val DEPENDENCIES = listOf( "io.prometheus:simpleclient_httpserver:${prometheusClientVersion}", "javax.annotation:javax.annotation-api:1.3.2", "com.github.stefanbirkner:system-rules:1.19.0", - "com.google.api.grpc:proto-google-common-protos:2.40.0", + "com.google.api.grpc:proto-google-common-protos:2.41.0", "com.google.code.findbugs:jsr305:3.0.2", "com.google.guava:guava-beta-checker:1.0", "com.sun.net.httpserver:http:20070405", From 3aeb410ecc7eb114bb9b26714e351e4694115d10 Mon Sep 17 00:00:00 2001 From: "shalk(xiao kun)" Date: Wed, 10 Jul 2024 09:14:08 +0800 Subject: [PATCH 475/901] rename open-telemetry-docs to opentelemetry-java-examples (#6564) --- CHANGELOG.md | 2 +- CONTRIBUTING.md | 2 +- README.md | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2bb8d74c282..b9d27b1cd0a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1939,7 +1939,7 @@ should not be many. Thanks for bearing with us on this. ### General * Examples moved - to [opentelemetry-java-docs](https://github.com/open-telemetry/opentelemetry-java-docs) + to [opentelemetry-java-examples](https://github.com/open-telemetry/opentelemetry-java-examples) ### SDK diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index c8285b218e7..b2d5d510c9b 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -93,7 +93,7 @@ Other repositories in the OpenTelemetry Java ecosystem include: contains instrumentation. * [opentelemetry-java-contrib](https://github.com/open-telemetry/opentelemetry-java-contrib) contains extensions, prototypes, and instrumentation, including vendor specific components. -* [opentelemetry-java-docs](https://github.com/open-telemetry/opentelemetry-java-docs) contains +* [opentelemetry-java-examples](https://github.com/open-telemetry/opentelemetry-java-examples) contains working code snippets demonstrating various concepts. ## Style guideline diff --git a/README.md b/README.md index 0e9f992ec2d..3920f9ef59e 100644 --- a/README.md +++ b/README.md @@ -15,7 +15,7 @@ javaagent**, see [opentelemetry-java-instrumentation][]. If you are looking for **examples** on how to use the OpenTelemetry API to write your own **manual instrumentation**, or how to set up the OpenTelemetry Java SDK, see [Manual instrumentation][]. Fully-functional examples -are available in [opentelemetry-java-docs][]. +are available in [opentelemetry-java-examples][]. If you are looking for generated classes for the [OpenTelemetry semantic conventions][opentelemetry-semantic-conventions], @@ -338,7 +338,7 @@ Made with [contrib.rocks](https://contrib.rocks). [maven-image]: https://maven-badges.herokuapp.com/maven-central/io.opentelemetry/opentelemetry-api/badge.svg [maven-url]: https://maven-badges.herokuapp.com/maven-central/io.opentelemetry/opentelemetry-api [opentelemetry-java-instrumentation]: https://github.com/open-telemetry/opentelemetry-java-instrumentation -[opentelemetry-java-docs]: https://github.com/open-telemetry/opentelemetry-java-docs +[opentelemetry-java-examples]: https://github.com/open-telemetry/opentelemetry-java-examples [opentelemetry-semantic-conventions]: https://opentelemetry.io/docs/specs/semconv/ [opentelemetry-semantic-conventions-java]: https://github.com/open-telemetry/semantic-conventions-java [opentelemetry.io]: https://opentelemetry.io From 38aeffff145338ae0f65730fd69f94c83219592a Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 10 Jul 2024 20:37:35 -0700 Subject: [PATCH 476/901] Update dependency com.linecorp.armeria:armeria-bom to v1.29.2 (#6567) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- dependencyManagement/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index fa7104ef69d..fd5ab235e77 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -11,7 +11,7 @@ val DEPENDENCY_BOMS = listOf( "com.fasterxml.jackson:jackson-bom:2.17.2", "com.google.guava:guava-bom:33.2.1-jre", "com.google.protobuf:protobuf-bom:3.25.3", - "com.linecorp.armeria:armeria-bom:1.29.1", + "com.linecorp.armeria:armeria-bom:1.29.2", "com.squareup.okhttp3:okhttp-bom:4.12.0", "com.squareup.okio:okio-bom:3.9.0", // applies to transitive dependencies of okhttp "io.grpc:grpc-bom:1.65.0", From 20bcd7546b4009c81feffd83c6e636416656ef6d Mon Sep 17 00:00:00 2001 From: Tyler Benson <734411+tylerbenson@users.noreply.github.com> Date: Thu, 11 Jul 2024 18:03:17 -0400 Subject: [PATCH 477/901] Add links from experimental methods to the helper functions that allow access to them. (#6529) Co-authored-by: Jack Berg --- .../sdk/logs/SdkLoggerProviderBuilder.java | 8 ++++++++ .../sdk/metrics/SdkMeterProviderBuilder.java | 13 ++++++++++++- .../io/opentelemetry/sdk/metrics/ViewBuilder.java | 7 +++++++ .../sdk/trace/SdkTracerProviderBuilder.java | 8 ++++++++ 4 files changed, 35 insertions(+), 1 deletion(-) diff --git a/sdk/logs/src/main/java/io/opentelemetry/sdk/logs/SdkLoggerProviderBuilder.java b/sdk/logs/src/main/java/io/opentelemetry/sdk/logs/SdkLoggerProviderBuilder.java index 87fec0c8d84..94d990c8a4b 100644 --- a/sdk/logs/src/main/java/io/opentelemetry/sdk/logs/SdkLoggerProviderBuilder.java +++ b/sdk/logs/src/main/java/io/opentelemetry/sdk/logs/SdkLoggerProviderBuilder.java @@ -16,6 +16,7 @@ import io.opentelemetry.sdk.internal.ScopeConfiguratorBuilder; import io.opentelemetry.sdk.logs.data.LogRecordData; import io.opentelemetry.sdk.logs.internal.LoggerConfig; +import io.opentelemetry.sdk.logs.internal.SdkLoggerProviderUtil; import io.opentelemetry.sdk.resources.Resource; import java.util.ArrayList; import java.util.List; @@ -111,6 +112,9 @@ public SdkLoggerProviderBuilder setClock(Clock clock) { * Set the logger configurator, which computes {@link LoggerConfig} for each {@link * InstrumentationScopeInfo}. * + *

      This method is experimental so not public. You may reflectively call it using {@link + * SdkLoggerProviderUtil#setLoggerConfigurator(SdkLoggerProviderBuilder, ScopeConfigurator)}. + * *

      Overrides any matchers added via {@link #addLoggerConfiguratorCondition(Predicate, * LoggerConfig)}. * @@ -126,6 +130,10 @@ SdkLoggerProviderBuilder setLoggerConfigurator( * Adds a condition to the logger configurator, which computes {@link LoggerConfig} for each * {@link InstrumentationScopeInfo}. * + *

      This method is experimental so not public. You may reflectively call it using {@link + * SdkLoggerProviderUtil#addLoggerConfiguratorCondition(SdkLoggerProviderBuilder, Predicate, + * LoggerConfig)}. + * *

      Applies after any previously added conditions. * *

      If {@link #setLoggerConfigurator(ScopeConfigurator)} was previously called, this condition diff --git a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkMeterProviderBuilder.java b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkMeterProviderBuilder.java index 9317c26e6c9..57895d45035 100644 --- a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkMeterProviderBuilder.java +++ b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkMeterProviderBuilder.java @@ -83,7 +83,7 @@ public SdkMeterProviderBuilder addResource(Resource resource) { /** * Assign an {@link ExemplarFilter} for all metrics created by Meters. * - *

      Note: not currently stable but available for experimental use via {@link + *

      This method is experimental so not public. You may reflectively call it using {@link * SdkMeterProviderUtil#setExemplarFilter(SdkMeterProviderBuilder, ExemplarFilter)}. */ SdkMeterProviderBuilder setExemplarFilter(ExemplarFilter filter) { @@ -137,6 +137,10 @@ public SdkMeterProviderBuilder registerMetricReader(MetricReader reader) { /** * Registers a {@link MetricReader} with a {@link CardinalityLimitSelector}. * + *

      This method is experimental so not public. You may reflectively call it using {@link + * SdkMeterProviderUtil#registerMetricReaderWithCardinalitySelector(SdkMeterProviderBuilder, + * MetricReader, CardinalityLimitSelector)} + * *

      Note: not currently stable but available for experimental use via {@link * SdkMeterProviderUtil#registerMetricReaderWithCardinalitySelector(SdkMeterProviderBuilder, * MetricReader, CardinalityLimitSelector)}. @@ -161,6 +165,9 @@ public SdkMeterProviderBuilder registerMetricProducer(MetricProducer metricProdu * Set the meter configurator, which computes {@link MeterConfig} for each {@link * InstrumentationScopeInfo}. * + *

      This method is experimental so not public. You may reflectively call it using {@link + * SdkMeterProviderUtil#setMeterConfigurator(SdkMeterProviderBuilder, ScopeConfigurator)}. + * *

      Overrides any matchers added via {@link #addMeterConfiguratorCondition(Predicate, * MeterConfig)}. * @@ -175,6 +182,10 @@ SdkMeterProviderBuilder setMeterConfigurator(ScopeConfigurator mete * Adds a condition to the meter configurator, which computes {@link MeterConfig} for each {@link * InstrumentationScopeInfo}. * + *

      This method is experimental so not public. You may reflectively call it using {@link + * SdkMeterProviderUtil#addMeterConfiguratorCondition(SdkMeterProviderBuilder, Predicate, + * MeterConfig)}. + * *

      Applies after any previously added conditions. * *

      If {@link #setMeterConfigurator(ScopeConfigurator)} was previously called, this condition diff --git a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/ViewBuilder.java b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/ViewBuilder.java index 26996df4bdf..8172abce8ca 100644 --- a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/ViewBuilder.java +++ b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/ViewBuilder.java @@ -94,6 +94,10 @@ public ViewBuilder setAttributeFilter(Predicate keyFilter) { /** * Add an attribute processor. * + *

      This method is experimental so not public. You may reflectively call it using {@link + * SdkMeterProviderUtil#appendFilteredBaggageAttributes(ViewBuilder, Predicate)}, {@link + * SdkMeterProviderUtil#appendAllBaggageAttributes(ViewBuilder)}. + * *

      Note: not currently stable but additional attribute processors can be configured via {@link * SdkMeterProviderUtil#appendAllBaggageAttributes(ViewBuilder)}. */ @@ -106,6 +110,9 @@ ViewBuilder addAttributesProcessor(AttributesProcessor attributesProcessor) { /** * Set the cardinality limit. * + *

      This method is experimental so not public. You may reflectively call it using {@link + * SdkMeterProviderUtil#setCardinalityLimit(ViewBuilder, int)} + * *

      Note: not currently stable but cardinality limit can be configured via * SdkMeterProviderUtil#setCardinalityLimit(ViewBuilder, int). * diff --git a/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/SdkTracerProviderBuilder.java b/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/SdkTracerProviderBuilder.java index f84c7f79855..531cd1a6384 100644 --- a/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/SdkTracerProviderBuilder.java +++ b/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/SdkTracerProviderBuilder.java @@ -12,6 +12,7 @@ import io.opentelemetry.sdk.internal.ScopeConfigurator; import io.opentelemetry.sdk.internal.ScopeConfiguratorBuilder; import io.opentelemetry.sdk.resources.Resource; +import io.opentelemetry.sdk.trace.internal.SdkTracerProviderUtil; import io.opentelemetry.sdk.trace.internal.TracerConfig; import io.opentelemetry.sdk.trace.samplers.Sampler; import java.util.ArrayList; @@ -158,6 +159,9 @@ public SdkTracerProviderBuilder addSpanProcessor(SpanProcessor spanProcessor) { * Set the tracer configurator, which computes {@link TracerConfig} for each {@link * InstrumentationScopeInfo}. * + *

      This method is experimental so not public. You may reflectively call it using {@link + * SdkTracerProviderUtil#setTracerConfigurator(SdkTracerProviderBuilder, ScopeConfigurator)}. + * *

      Overrides any matchers added via {@link #addTracerConfiguratorCondition(Predicate, * TracerConfig)}. * @@ -173,6 +177,10 @@ SdkTracerProviderBuilder setTracerConfigurator( * Adds a condition to the tracer configurator, which computes {@link TracerConfig} for each * {@link InstrumentationScopeInfo}. * + *

      This method is experimental so not public. You may reflectively call it using {@link + * SdkTracerProviderUtil#addTracerConfiguratorCondition(SdkTracerProviderBuilder, Predicate, + * TracerConfig)}. + * *

      Applies after any previously added conditions. * *

      If {@link #setTracerConfigurator(ScopeConfigurator)} was previously called, this condition From fbb5ebb01e5152e54a4c77bd43ba18f347798db5 Mon Sep 17 00:00:00 2001 From: John Watson Date: Fri, 12 Jul 2024 20:09:03 -0700 Subject: [PATCH 478/901] PR 6524 with amendments (#6569) Co-authored-by: junwense <970597653@qq.com> Co-authored-by: SeanJ <44492651+junwense@users.noreply.github.com> --- .../propagation/CaseInsensitiveMap.java | 19 ++++- .../propagation/CaseInsensitiveMapTest.java | 69 +++++++++++++++++++ 2 files changed, 85 insertions(+), 3 deletions(-) create mode 100644 api/incubator/src/test/java/io/opentelemetry/api/incubator/propagation/CaseInsensitiveMapTest.java diff --git a/api/incubator/src/main/java/io/opentelemetry/api/incubator/propagation/CaseInsensitiveMap.java b/api/incubator/src/main/java/io/opentelemetry/api/incubator/propagation/CaseInsensitiveMap.java index def4b6f8b53..64a33350508 100644 --- a/api/incubator/src/main/java/io/opentelemetry/api/incubator/propagation/CaseInsensitiveMap.java +++ b/api/incubator/src/main/java/io/opentelemetry/api/incubator/propagation/CaseInsensitiveMap.java @@ -14,18 +14,31 @@ class CaseInsensitiveMap extends HashMap { private static final long serialVersionUID = -4202518750189126871L; + CaseInsensitiveMap() {} + CaseInsensitiveMap(Map carrier) { - super(carrier); + if (carrier != null) { + this.putAll(carrier); + } } @Override public String put(String key, String value) { - return super.put(key.toLowerCase(Locale.ROOT), value); + return super.put(getKeyLowerCase(key), value); + } + + @Override + public void putAll(Map m) { + m.forEach(this::put); + } + + private static String getKeyLowerCase(String key) { + return key.toLowerCase(Locale.ROOT); } @Override @Nullable public String get(Object key) { - return super.get(((String) key).toLowerCase(Locale.ROOT)); + return super.get(getKeyLowerCase((String) key)); } } diff --git a/api/incubator/src/test/java/io/opentelemetry/api/incubator/propagation/CaseInsensitiveMapTest.java b/api/incubator/src/test/java/io/opentelemetry/api/incubator/propagation/CaseInsensitiveMapTest.java new file mode 100644 index 00000000000..ac9feee91b4 --- /dev/null +++ b/api/incubator/src/test/java/io/opentelemetry/api/incubator/propagation/CaseInsensitiveMapTest.java @@ -0,0 +1,69 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.api.incubator.propagation; + +import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.assertThat; + +import java.util.HashMap; +import java.util.Map; +import org.junit.jupiter.api.Test; + +class CaseInsensitiveMapTest { + + @Test + void createByConstructor() { + Map map = new HashMap<>(); + map.put("Key1", "test"); + map.put("Key2", "test2"); + + CaseInsensitiveMap caseInsensitiveMap = new CaseInsensitiveMap(map); + + Map standardMap = new HashMap<>(); + standardMap.put("key1", "test"); + standardMap.put("key2", "test2"); + + assertThat(caseInsensitiveMap).isEqualTo(standardMap); + } + + @Test + void putAll() { + CaseInsensitiveMap caseInsensitiveMap = new CaseInsensitiveMap(); + Map standardMap = new HashMap<>(); + standardMap.put("key1", "test"); + standardMap.put("key2", "test2"); + caseInsensitiveMap.putAll(standardMap); + assertThat(caseInsensitiveMap).isEqualTo(standardMap); + } + + @Test + void putIfAbsent() { + CaseInsensitiveMap caseInsensitiveMap = new CaseInsensitiveMap(); + caseInsensitiveMap.putIfAbsent("key1", "test"); + assertThat(caseInsensitiveMap.get("KEY1")).isEqualTo("test"); + caseInsensitiveMap.putIfAbsent("key1", "nope"); + assertThat(caseInsensitiveMap.get("KEY1")).isEqualTo("test"); + } + + @Test + void createByConstructorWithNullMap() { + CaseInsensitiveMap caseInsensitiveMap = new CaseInsensitiveMap(null); + assertThat(caseInsensitiveMap).isEmpty(); + } + + @Test + void caseInsensitivity() { + CaseInsensitiveMap caseInsensitiveMap = new CaseInsensitiveMap(null); + + assertThat(caseInsensitiveMap).isEmpty(); + + caseInsensitiveMap.put("KEY1", "test1"); + caseInsensitiveMap.put("KEY2", "test2"); + assertThat(caseInsensitiveMap.get("key1")).isEqualTo("test1"); + assertThat(caseInsensitiveMap.get("key2")).isEqualTo("test2"); + assertThat(caseInsensitiveMap.get("kEy2")).isEqualTo("test2"); + assertThat(caseInsensitiveMap.get("KEY2")).isEqualTo("test2"); + } +} From 82ad786856129ce2639ab716dc8aac214445f16b Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 12 Jul 2024 20:19:47 -0700 Subject: [PATCH 479/901] Update dependency gradle to v8.9 (#6570) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- gradle/wrapper/gradle-wrapper.jar | Bin 43453 -> 43504 bytes gradle/wrapper/gradle-wrapper.properties | 4 ++-- gradlew | 5 ++++- gradlew.bat | 2 ++ 4 files changed, 8 insertions(+), 3 deletions(-) diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index e6441136f3d4ba8a0da8d277868979cfbc8ad796..2c3521197d7c4586c843d1d3e9090525f1898cde 100644 GIT binary patch delta 8703 zcmYLtRag{&)-BQ@Dc#cDDP2Q%r*wBHJ*0FE-92)X$3_b$L+F2Fa28UVeg>}yRjC}^a^+(Cdu_FTlV;w_x7ig{yd(NYi_;SHXEq`|Qa`qPMf1B~v#%<*D zn+KWJfX#=$FMopqZ>Cv7|0WiA^M(L@tZ=_Hi z*{?)#Cn^{TIzYD|H>J3dyXQCNy8f@~OAUfR*Y@C6r=~KMZ{X}q`t@Er8NRiCUcR=?Y+RMv`o0i{krhWT6XgmUt!&X=e_Q2=u@F=PXKpr9-FL@0 zfKigQcGHyPn{3vStLFk=`h@+Lh1XBNC-_nwNU{ytxZF$o}oyVfHMj|ZHWmEmZeNIlO5eLco<=RI&3=fYK*=kmv*75aqE~&GtAp(VJ z`VN#&v2&}|)s~*yQ)-V2@RmCG8lz5Ysu&I_N*G5njY`<@HOc*Bj)ZwC%2|2O<%W;M z+T{{_bHLh~n(rM|8SpGi8Whep9(cURNRVfCBQQ2VG<6*L$CkvquqJ~9WZ~!<6-EZ&L(TN zpSEGXrDiZNz)`CzG>5&_bxzBlXBVs|RTTQi5GX6s5^)a3{6l)Wzpnc|Cc~(5mO)6; z6gVO2Zf)srRQ&BSeg0)P2en#<)X30qXB{sujc3Ppm4*)}zOa)@YZ<%1oV9K%+(VzJ zk(|p>q-$v>lImtsB)`Mm;Z0LaU;4T1BX!wbnu-PSlH1%`)jZZJ(uvbmM^is*r=Y{B zI?(l;2n)Nx!goxrWfUnZ?y5$=*mVU$Lpc_vS2UyW>tD%i&YYXvcr1v7hL2zWkHf42 z_8q$Gvl>%468i#uV`RoLgrO+R1>xP8I^7~&3(=c-Z-#I`VDnL`6stnsRlYL zJNiI`4J_0fppF<(Ot3o2w?UT*8QQrk1{#n;FW@4M7kR}oW-}k6KNQaGPTs=$5{Oz} zUj0qo@;PTg#5moUF`+?5qBZ)<%-$qw(Z?_amW*X}KW4j*FmblWo@SiU16V>;nm`Eg zE0MjvGKN_eA%R0X&RDT!hSVkLbF`BFf;{8Nym#1?#5Fb?bAHY(?me2tww}5K9AV9y+T7YaqaVx8n{d=K`dxS|=))*KJn(~8u@^J% zj;8EM+=Dq^`HL~VPag9poTmeP$E`npJFh^|=}Mxs2El)bOyoimzw8(RQle(f$n#*v zzzG@VOO(xXiG8d?gcsp-Trn-36}+S^w$U(IaP`-5*OrmjB%Ozzd;jfaeRHAzc_#?- z`0&PVZANQIcb1sS_JNA2TFyN$*yFSvmZbqrRhfME3(PJ62u%KDeJ$ZeLYuiQMC2Sc z35+Vxg^@gSR6flp>mS|$p&IS7#fL@n20YbNE9(fH;n%C{w?Y0=N5?3GnQLIJLu{lm zV6h@UDB+23dQoS>>)p`xYe^IvcXD*6nDsR;xo?1aNTCMdbZ{uyF^zMyloFDiS~P7W>WuaH2+`xp0`!d_@>Fn<2GMt z&UTBc5QlWv1)K5CoShN@|0y1M?_^8$Y*U(9VrroVq6NwAJe zxxiTWHnD#cN0kEds(wN8YGEjK&5%|1pjwMH*81r^aXR*$qf~WiD2%J^=PHDUl|=+f zkB=@_7{K$Fo0%-WmFN_pyXBxl^+lLG+m8Bk1OxtFU}$fQU8gTYCK2hOC0sVEPCb5S z4jI07>MWhA%cA{R2M7O_ltorFkJ-BbmPc`{g&Keq!IvDeg8s^PI3a^FcF z@gZ2SB8$BPfenkFc*x#6&Z;7A5#mOR5qtgE}hjZ)b!MkOQ zEqmM3s>cI_v>MzM<2>U*eHoC69t`W`^9QBU^F$ z;nU4%0$)$ILukM6$6U+Xts8FhOFb|>J-*fOLsqVfB=vC0v2U&q8kYy~x@xKXS*b6i zy=HxwsDz%)!*T5Bj3DY1r`#@Tc%LKv`?V|g6Qv~iAnrqS+48TfuhmM)V_$F8#CJ1j4;L}TBZM~PX!88IT+lSza{BY#ER3TpyMqi# z#{nTi!IsLYt9cH?*y^bxWw4djrd!#)YaG3|3>|^1mzTuXW6SV4+X8sA2dUWcjH)a3 z&rXUMHbOO?Vcdf3H<_T-=DB0M4wsB;EL3lx?|T(}@)`*C5m`H%le54I{bfg7GHqYB z9p+30u+QXMt4z&iG%LSOk1uw7KqC2}ogMEFzc{;5x`hU(rh0%SvFCBQe}M#RSWJv;`KM zf7D&z0a)3285{R$ZW%+I@JFa^oZN)vx77y_;@p0(-gz6HEE!w&b}>0b)mqz-(lfh4 zGt}~Hl@{P63b#dc`trFkguB}6Flu!S;w7lp_>yt|3U=c|@>N~mMK_t#LO{n;_wp%E zQUm=z6?JMkuQHJ!1JV$gq)q)zeBg)g7yCrP=3ZA|wt9%_l#yPjsS#C7qngav8etSX+s?JJ1eX-n-%WvP!IH1%o9j!QH zeP<8aW}@S2w|qQ`=YNC}+hN+lxv-Wh1lMh?Y;LbIHDZqVvW^r;^i1O<9e z%)ukq=r=Sd{AKp;kj?YUpRcCr*6)<@Mnp-cx{rPayiJ0!7Jng}27Xl93WgthgVEn2 zQlvj!%Q#V#j#gRWx7((Y>;cC;AVbPoX*mhbqK*QnDQQ?qH+Q*$u6_2QISr!Fn;B-F@!E+`S9?+Jr zt`)cc(ZJ$9q^rFohZJoRbP&X3)sw9CLh#-?;TD}!i>`a;FkY6(1N8U-T;F#dGE&VI zm<*Tn>EGW(TioP@hqBg zn6nEolK5(}I*c;XjG!hcI0R=WPzT)auX-g4Znr;P`GfMa*!!KLiiTqOE*STX4C(PD z&}1K|kY#>~>sx6I0;0mUn8)=lV?o#Bcn3tn|M*AQ$FscYD$0H(UKzC0R588Mi}sFl z@hG4h^*;_;PVW#KW=?>N)4?&PJF&EO(X?BKOT)OCi+Iw)B$^uE)H>KQZ54R8_2z2_ z%d-F7nY_WQiSB5vWd0+>^;G^j{1A%-B359C(Eji{4oLT9wJ~80H`6oKa&{G- z)2n-~d8S0PIkTW_*Cu~nwVlE&Zd{?7QbsGKmwETa=m*RG>g??WkZ|_WH7q@ zfaxzTsOY2B3!Fu;rBIJ~aW^yqn{V;~4LS$xA zGHP@f>X^FPnSOxEbrnEOd*W7{c(c`b;RlOEQ*x!*Ek<^p*C#8L=Ty^S&hg zaV)g8<@!3p6(@zW$n7O8H$Zej+%gf^)WYc$WT{zp<8hmn!PR&#MMOLm^hcL2;$o=Q zXJ=9_0vO)ZpNxPjYs$nukEGK2bbL%kc2|o|zxYMqK8F?$YtXk9Owx&^tf`VvCCgUz zLNmDWtociY`(}KqT~qnVUkflu#9iVqXw7Qi7}YT@{K2Uk(Wx7Q-L}u^h+M(81;I*J ze^vW&-D&=aOQq0lF5nLd)OxY&duq#IdK?-r7En0MnL~W51UXJQFVVTgSl#85=q$+| zHI%I(T3G8ci9Ubq4(snkbQ*L&ksLCnX_I(xa1`&(Bp)|fW$kFot17I)jyIi06dDTTiI%gNR z8i*FpB0y0 zjzWln{UG1qk!{DEE5?0R5jsNkJ(IbGMjgeeNL4I9;cP&>qm%q7cHT}@l0v;TrsuY0 zUg;Z53O-rR*W!{Q*Gp26h`zJ^p&FmF0!EEt@R3aT4YFR0&uI%ko6U0jzEYk_xScP@ zyk%nw`+Ic4)gm4xvCS$)y;^)B9^}O0wYFEPas)!=ijoBCbF0DbVMP z`QI7N8;88x{*g=51AfHx+*hoW3hK(?kr(xVtKE&F-%Tb}Iz1Z8FW>usLnoCwr$iWv ztOVMNMV27l*fFE29x}veeYCJ&TUVuxsd`hV-8*SxX@UD6au5NDhCQ4Qs{{CJQHE#4 z#bg6dIGO2oUZQVY0iL1(Q>%-5)<7rhnenUjOV53*9Qq?aU$exS6>;BJqz2|#{We_| zX;Nsg$KS<+`*5=WA?idE6G~kF9oQPSSAs#Mh-|)@kh#pPCgp&?&=H@Xfnz`5G2(95 z`Gx2RfBV~`&Eyq2S9m1}T~LI6q*#xC^o*EeZ#`}Uw)@RD>~<_Kvgt2?bRbO&H3&h- zjB&3bBuWs|YZSkmcZvX|GJ5u7#PAF$wj0ULv;~$7a?_R%e%ST{al;=nqj-<0pZiEgNznHM;TVjCy5E#4f?hudTr0W8)a6o;H; zhnh6iNyI^F-l_Jz$F`!KZFTG$yWdioL=AhImGr!$AJihd{j(YwqVmqxMKlqFj<_Hlj@~4nmrd~&6#f~9>r2_e-^nca(nucjf z;(VFfBrd0?k--U9L*iey5GTc|Msnn6prtF*!5AW3_BZ9KRO2(q7mmJZ5kz-yms`04e; z=uvr2o^{lVBnAkB_~7b7?1#rDUh4>LI$CH1&QdEFN4J%Bz6I$1lFZjDz?dGjmNYlD zDt}f;+xn-iHYk~V-7Fx!EkS``+w`-f&Ow>**}c5I*^1tpFdJk>vG23PKw}FrW4J#x zBm1zcp^){Bf}M|l+0UjvJXRjP3~!#`I%q*E=>?HLZ>AvB5$;cqwSf_*jzEmxxscH; zcl>V3s>*IpK`Kz1vP#APs#|tV9~#yMnCm&FOllccilcNmAwFdaaY7GKg&(AKG3KFj zk@%9hYvfMO;Vvo#%8&H_OO~XHlwKd()gD36!_;o z*7pl*o>x9fbe?jaGUO25ZZ@#qqn@|$B+q49TvTQnasc$oy`i~*o}Ka*>Wg4csQOZR z|Fs_6-04vj-Dl|B2y{&mf!JlPJBf3qG~lY=a*I7SBno8rLRdid7*Kl@sG|JLCt60# zqMJ^1u^Gsb&pBPXh8m1@4;)}mx}m%P6V8$1oK?|tAk5V6yyd@Ez}AlRPGcz_b!c;; z%(uLm1Cp=NT(4Hcbk;m`oSeW5&c^lybx8+nAn&fT(!HOi@^&l1lDci*?L#*J7-u}} z%`-*V&`F1;4fWsvcHOlZF#SD&j+I-P(Mu$L;|2IjK*aGG3QXmN$e}7IIRko8{`0h9 z7JC2vi2Nm>g`D;QeN@^AhC0hKnvL(>GUqs|X8UD1r3iUc+-R4$=!U!y+?p6rHD@TL zI!&;6+LK_E*REZ2V`IeFP;qyS*&-EOu)3%3Q2Hw19hpM$3>v!!YABs?mG44{L=@rjD%X-%$ajTW7%t_$7to%9d3 z8>lk z?_e}(m&>emlIx3%7{ER?KOVXi>MG_)cDK}v3skwd%Vqn0WaKa1;e=bK$~Jy}p#~`B zGk-XGN9v)YX)K2FM{HNY-{mloSX|a?> z8Om9viiwL|vbVF~j%~hr;|1wlC0`PUGXdK12w;5Wubw}miQZ)nUguh?7asm90n>q= z;+x?3haT5#62bg^_?VozZ-=|h2NbG%+-pJ?CY(wdMiJ6!0ma2x{R{!ys=%in;;5@v z{-rpytg){PNbCGP4Ig>=nJV#^ie|N68J4D;C<1=$6&boh&ol~#A?F-{9sBL*1rlZshXm~6EvG!X9S zD5O{ZC{EEpHvmD5K}ck+3$E~{xrrg*ITiA}@ZCoIm`%kVqaX$|#ddV$bxA{jux^uRHkH)o6#}fT6XE|2BzU zJiNOAqcxdcQdrD=U7OVqer@p>30l|ke$8h;Mny-+PP&OM&AN z9)!bENg5Mr2g+GDIMyzQpS1RHE6ow;O*ye;(Qqej%JC?!D`u;<;Y}1qi5cL&jm6d9 za{plRJ0i|4?Q%(t)l_6f8An9e2<)bL3eULUVdWanGSP9mm?PqFbyOeeSs9{qLEO-) zTeH*<$kRyrHPr*li6p+K!HUCf$OQIqwIw^R#mTN>@bm^E=H=Ger_E=ztfGV9xTgh=}Hep!i97A;IMEC9nb5DBA5J#a8H_Daq~ z6^lZ=VT)7=y}H3=gm5&j!Q79#e%J>w(L?xBcj_RNj44r*6^~nCZZYtCrLG#Njm$$E z7wP?E?@mdLN~xyWosgwkCot8bEY-rUJLDo7gukwm@;TjXeQ>fr(wKP%7LnH4Xsv?o zUh6ta5qPx8a5)WO4 zK37@GE@?tG{!2_CGeq}M8VW(gU6QXSfadNDhZEZ}W2dwm)>Y7V1G^IaRI9ugWCP#sw1tPtU|13R!nwd1;Zw8VMx4hUJECJkocrIMbJI zS9k2|`0$SD%;g_d0cmE7^MXP_;_6`APcj1yOy_NXU22taG9Z;C2=Z1|?|5c^E}dR& zRfK2Eo=Y=sHm@O1`62ciS1iKv9BX=_l7PO9VUkWS7xlqo<@OxlR*tn$_WbrR8F?ha zBQ4Y!is^AIsq-46^uh;=9B`gE#Sh+4m>o@RMZFHHi=qb7QcUrgTos$e z^4-0Z?q<7XfCP~d#*7?hwdj%LyPj2}bsdWL6HctL)@!tU$ftMmV=miEvZ2KCJXP%q zLMG&%rVu8HaaM-tn4abcSE$88EYmK|5%_29B*L9NyO|~j3m>YGXf6fQL$(7>Bm9o zjHfJ+lmYu_`+}xUa^&i81%9UGQ6t|LV45I)^+m@Lz@jEeF;?_*y>-JbK`=ZVsSEWZ z$p^SK_v(0d02AyIv$}*8m)9kjef1-%H*_daPdSXD6mpc>TW`R$h9On=Z9n>+f4swL zBz^(d9uaQ_J&hjDvEP{&6pNz-bg;A===!Ac%}bu^>0}E)wdH1nc}?W*q^J2SX_A*d zBLF@n+=flfH96zs@2RlOz&;vJPiG6In>$&{D+`DNgzPYVu8<(N&0yPt?G|>D6COM# zVd)6v$i-VtYfYi1h)pXvO}8KO#wuF=F^WJXPC+;hqpv>{Z+FZTP1w&KaPl?D)*A=( z8$S{Fh;Ww&GqSvia6|MvKJg-RpNL<6MXTl(>1}XFfziRvPaLDT1y_tjLYSGS$N;8| zZC*Hcp!~u?v~ty3&dBm`1A&kUe6@`q!#>P>ZZZgGRYhNIxFU6B>@f@YL%hOV0=9s# z?@0~aR1|d9LFoSI+li~@?g({Y0_{~~E_MycHTXz`EZmR2$J$3QVoA25j$9pe?Ub)d z`jbm8v&V0JVfY-^1mG=a`70a_tjafgi}z-8$smw7Mc`-!*6y{rB-xN1l`G3PLBGk~ z{o(KCV0HEfj*rMAiluQuIZ1tevmU@m{adQQr3xgS!e_WXw&eE?GjlS+tL0@x%Hm{1 zzUF^qF*2KAxY0$~pzVRpg9dA*)^ z7&wu-V$7+Jgb<5g;U1z*ymus?oZi7&gr!_3zEttV`=5VlLtf!e&~zv~PdspA0JCRz zZi|bO5d)>E;q)?}OADAhGgey#6(>+36XVThP%b#8%|a9B_H^)Nps1md_lVv5~OO@(*IJO@;eqE@@(y}KA- z`zj@%6q#>hIgm9}*-)n(^Xbdp8`>w~3JCC`(H{NUh8Umm{NUntE+eMg^WvSyL+ilV zff54-b59jg&r_*;*#P~ON#I=gAW99hTD;}nh_j;)B6*tMgP_gz4?=2EJZg$8IU;Ly<(TTC?^)& zj@%V!4?DU&tE=8)BX6f~x0K+w$%=M3;Fpq$VhETRlJ8LEEe;aUcG;nBe|2Gw>+h7CuJ-^gYFhQzDg(`e=!2f7t0AXrl zAx`RQ1u1+}?EkEWSb|jQN)~wOg#Ss&1oHoFBvg{Z|4#g$)mNzjKLq+8rLR(jC(QUC Ojj7^59?Sdh$^Qpp*~F>< delta 8662 zcmYM1RaBhK(uL9BL4pT&ch}$qcL*As0R|^HFD`?-26qkaNwC3nu;A|Q0Yd)oJ7=x) z_f6HatE;=#>YLq{FoYf$!na@pfNwSyI%>|UMk5`vO(z@Ao)eZR(~D#FF?U$)+q)1q z9OVG^Ib0v?R8wYfQ*1H;5Oyixqnyt6cXR#u=LM~V7_GUu}N(b}1+x^JUL#_8Xj zB*(FInWvSPGo;K=k3}p&4`*)~)p`nX#}W&EpfKCcOf^7t zPUS81ov(mXS;$9To6q84I!tlP&+Z?lkctuIZ(SHN#^=JGZe^hr^(3d*40pYsjikBWME6IFf!!+kC*TBc!T)^&aJ#z0#4?OCUbNoa}pwh=_SFfMf|x$`-5~ zP%%u%QdWp#zY6PZUR8Mz1n$f44EpTEvKLTL;yiZrPCV=XEL09@qmQV#*Uu*$#-WMN zZ?rc(7}93z4iC~XHcatJev=ey*hnEzajfb|22BpwJ4jDi;m>Av|B?TqzdRm-YT(EV zCgl${%#nvi?ayAFYV7D_s#07}v&FI43BZz@`dRogK!k7Y!y6r=fvm~=F9QP{QTj>x z#Y)*j%`OZ~;rqP0L5@qYhR`qzh^)4JtE;*faTsB;dNHyGMT+fpyz~LDaMOO?c|6FD z{DYA+kzI4`aD;Ms|~h49UAvOfhMEFip&@&Tz>3O+MpC0s>`fl!T(;ZP*;Ux zr<2S-wo(Kq&wfD_Xn7XXQJ0E4u7GcC6pqe`3$fYZ5Eq4`H67T6lex_QP>Ca##n2zx z!tc=_Ukzf{p1%zUUkEO(0r~B=o5IoP1@#0A=uP{g6WnPnX&!1Z$UWjkc^~o^y^Kkn z%zCrr^*BPjcTA58ZR}?%q7A_<=d&<*mXpFSQU%eiOR`=78@}+8*X##KFb)r^zyfOTxvA@cbo65VbwoK0lAj3x8X)U5*w3(}5 z(Qfv5jl{^hk~j-n&J;kaK;fNhy9ZBYxrKQNCY4oevotO-|7X}r{fvYN+{sCFn2(40 zvCF7f_OdX*L`GrSf0U$C+I@>%+|wQv*}n2yT&ky;-`(%#^vF79p1 z>y`59E$f7!vGT}d)g)n}%T#-Wfm-DlGU6CX`>!y8#tm-Nc}uH50tG)dab*IVrt-TTEM8!)gIILu*PG_-fbnFjRA+LLd|_U3yas12Lro%>NEeG%IwN z{FWomsT{DqMjq{7l6ZECb1Hm@GQ`h=dcyApkoJ6CpK3n83o-YJnXxT9b2%TmBfKZ* zi~%`pvZ*;(I%lJEt9Bphs+j#)ws}IaxQYV6 zWBgVu#Kna>sJe;dBQ1?AO#AHecU~3cMCVD&G})JMkbkF80a?(~1HF_wv6X!p z6uXt_8u)`+*%^c@#)K27b&Aa%m>rXOcGQg8o^OB4t0}@-WWy38&)3vXd_4_t%F1|( z{z(S)>S!9eUCFA$fQ^127DonBeq@5FF|IR7(tZ?Nrx0(^{w#a$-(fbjhN$$(fQA(~|$wMG4 z?UjfpyON`6n#lVwcKQ+#CuAQm^nmQ!sSk>=Mdxk9e@SgE(L2&v`gCXv&8ezHHn*@% zi6qeD|I%Q@gb(?CYus&VD3EE#xfELUvni89Opq-6fQmY-9Di3jxF?i#O)R4t66ekw z)OW*IN7#{_qhrb?qlVwmM@)50jEGbjTiDB;nX{}%IC~pw{ev#!1`i6@xr$mgXX>j} zqgxKRY$fi?B7|GHArqvLWu;`?pvPr!m&N=F1<@i-kzAmZ69Sqp;$)kKg7`76GVBo{ zk+r?sgl{1)i6Hg2Hj!ehsDF3tp(@n2+l%ihOc7D~`vzgx=iVU0{tQ&qaV#PgmalfG zPj_JimuEvo^1X)dGYNrTHBXwTe@2XH-bcnfpDh$i?Il9r%l$Ob2!dqEL-To>;3O>` z@8%M*(1#g3_ITfp`z4~Z7G7ZG>~F0W^byMvwzfEf*59oM*g1H)8@2zL&da+$ms$Dp zrPZ&Uq?X)yKm7{YA;mX|rMEK@;W zA-SADGLvgp+)f01=S-d$Z8XfvEZk$amHe}B(gQX-g>(Y?IA6YJfZM(lWrf);5L zEjq1_5qO6U7oPSb>3|&z>OZ13;mVT zWCZ=CeIEK~6PUv_wqjl)pXMy3_46hB?AtR7_74~bUS=I}2O2CjdFDA*{749vOj2hJ z{kYM4fd`;NHTYQ_1Rk2dc;J&F2ex^}^%0kleFbM!yhwO|J^~w*CygBbkvHnzz@a~D z|60RVTr$AEa-5Z->qEMEfau=__2RanCTKQ{XzbhD{c!e5hz&$ZvhBX0(l84W%eW17 zQ!H)JKxP$wTOyq83^qmx1Qs;VuWuxclIp!BegkNYiwyMVBay@XWlTpPCzNn>&4)f* zm&*aS?T?;6?2>T~+!=Gq4fjP1Z!)+S<xiG>XqzY@WKKMzx?0|GTS4{ z+z&e0Uysciw#Hg%)mQ3C#WQkMcm{1yt(*)y|yao2R_FRX$WPvg-*NPoj%(k*{BA8Xx&0HEqT zI0Swyc#QyEeUc)0CC}x{p+J{WN>Z|+VZWDpzW`bZ2d7^Yc4ev~9u-K&nR zl#B0^5%-V4c~)1_xrH=dGbbYf*7)D&yy-}^V|Np|>V@#GOm($1=El5zV?Z`Z__tD5 zcLUi?-0^jKbZrbEny&VD!zA0Nk3L|~Kt4z;B43v@k~ zFwNisc~D*ZROFH;!f{&~&Pof-x8VG8{gSm9-Yg$G(Q@O5!A!{iQH0j z80Rs>Ket|`cbw>z$P@Gfxp#wwu;I6vi5~7GqtE4t7$Hz zPD=W|mg%;0+r~6)dC>MJ&!T$Dxq3 zU@UK_HHc`_nI5;jh!vi9NPx*#{~{$5Azx`_VtJGT49vB_=WN`*i#{^X`xu$9P@m>Z zL|oZ5CT=Zk?SMj{^NA5E)FqA9q88h{@E96;&tVv^+;R$K`kbB_ zZneKrSN+IeIrMq;4EcH>sT2~3B zrZf-vSJfekcY4A%e2nVzK8C5~rAaP%dV2Hwl~?W87Hdo<*EnDcbZqVUb#8lz$HE@y z2DN2AQh%OcqiuWRzRE>cKd)24PCc)#@o&VCo!Rcs;5u9prhK}!->CC)H1Sn-3C7m9 zyUeD#Udh1t_OYkIMAUrGU>ccTJS0tV9tW;^-6h$HtTbon@GL1&OukJvgz>OdY)x4D zg1m6Y@-|p;nB;bZ_O>_j&{BmuW9km4a728vJV5R0nO7wt*h6sy7QOT0ny-~cWTCZ3 z9EYG^5RaAbLwJ&~d(^PAiicJJs&ECAr&C6jQcy#L{JCK&anL)GVLK?L3a zYnsS$+P>UB?(QU7EI^%#9C;R-jqb;XWX2Bx5C;Uu#n9WGE<5U=zhekru(St>|FH2$ zOG*+Tky6R9l-yVPJk7giGulOO$gS_c!DyCog5PT`Sl@P!pHarmf7Y0HRyg$X@fB7F zaQy&vnM1KZe}sHuLY5u7?_;q!>mza}J?&eLLpx2o4q8$qY+G2&Xz6P8*fnLU+g&i2}$F%6R_Vd;k)U{HBg{+uuKUAo^*FRg!#z}BajS)OnqwXd!{u>Y&aH?)z%bwu_NB9zNw+~661!> zD3%1qX2{743H1G8d~`V=W`w7xk?bWgut-gyAl*6{dW=g_lU*m?fJ>h2#0_+J3EMz_ zR9r+0j4V*k>HU`BJaGd~@*G|3Yp?~Ljpth@!_T_?{an>URYtict~N+wb}%n)^GE8eM(=NqLnn*KJnE*v(7Oo)NmKB*qk;0&FbO zkrIQs&-)ln0-j~MIt__0pLdrcBH{C(62`3GvGjR?`dtTdX#tf-2qkGbeV;Ud6Dp0& z|A6-DPgg=v*%2`L4M&p|&*;;I`=Tn1M^&oER=Gp&KHBRxu_OuFGgX;-U8F?*2>PXjb!wwMMh_*N8$?L4(RdvV#O5cUu0F|_zQ#w1zMA4* zJeRk}$V4?zPVMB=^}N7x?(P7!x6BfI%*)yaUoZS0)|$bw07XN{NygpgroPW>?VcO} z@er3&#@R2pLVwkpg$X8HJM@>FT{4^Wi&6fr#DI$5{ERpM@|+60{o2_*a7k__tIvGJ9D|NPoX@$4?i_dQPFkx0^f$=#_)-hphQ93a0|`uaufR!Nlc^AP+hFWe~(j_DCZmv;7CJ4L7tWk{b;IFDvT zchD1qB=cE)Mywg5Nw>`-k#NQhT`_X^c`s$ODVZZ-)T}vgYM3*syn41}I*rz?)`Q<* zs-^C3!9AsV-nX^0wH;GT)Y$yQC*0x3o!Bl<%>h-o$6UEG?{g1ip>njUYQ}DeIw0@qnqJyo0do(`OyE4kqE2stOFNos%!diRfe=M zeU@=V=3$1dGv5ZbX!llJ!TnRQQe6?t5o|Y&qReNOxhkEa{CE6d^UtmF@OXk<_qkc0 zc+ckH8Knc!FTjk&5FEQ}$sxj!(a4223cII&iai-nY~2`|K89YKcrYFAMo^oIh@W^; zsb{KOy?dv_D5%}zPk_7^I!C2YsrfyNBUw_ude7XDc0-+LjC0!X_moHU3wmveS@GRu zX>)G}L_j1I-_5B|b&|{ExH~;Nm!xytCyc}Ed!&Hqg;=qTK7C93f>!m3n!S5Z!m`N} zjIcDWm8ES~V2^dKuv>8@Eu)Zi{A4;qHvTW7hB6B38h%$K76BYwC3DIQ0a;2fSQvo$ z`Q?BEYF1`@I-Nr6z{@>`ty~mFC|XR`HSg(HN>&-#&eoDw-Q1g;x@Bc$@sW{Q5H&R_ z5Aici44Jq-tbGnDsu0WVM(RZ=s;CIcIq?73**v!Y^jvz7ckw*=?0=B!{I?f{68@V( z4dIgOUYbLOiQccu$X4P87wZC^IbGnB5lLfFkBzLC3hRD?q4_^%@O5G*WbD?Wug6{<|N#Fv_Zf3ST>+v_!q5!fSy#{_XVq$;k*?Ar^R&FuFM7 zKYiLaSe>Cw@`=IUMZ*U#v>o5!iZ7S|rUy2(yG+AGnauj{;z=s8KQ(CdwZ>&?Z^&Bt z+74(G;BD!N^Ke>(-wwZN5~K%P#L)59`a;zSnRa>2dCzMEz`?VaHaTC>?&o|(d6e*Z zbD!=Ua-u6T6O!gQnncZ&699BJyAg9mKXd_WO8O`N@}bx%BSq)|jgrySfnFvzOj!44 z9ci@}2V3!ag8@ZbJO;;Q5ivdTWx+TGR`?75Jcje}*ufx@%5MFUsfsi%FoEx)&uzkN zgaGFOV!s@Hw3M%pq5`)M4Nz$)~Sr9$V2rkP?B7kvI7VAcnp6iZl zOd!(TNw+UH49iHWC4!W&9;ZuB+&*@Z$}>0fx8~6J@d)fR)WG1UndfdVEeKW=HAur| z15zG-6mf`wyn&x@&?@g1ibkIMob_`x7nh7yu9M>@x~pln>!_kzsLAY#2ng0QEcj)qKGj8PdWEuYKdM!jd{ zHP6j^`1g}5=C%)LX&^kpe=)X+KR4VRNli?R2KgYlwKCN9lcw8GpWMV+1Ku)~W^jV2 zyiTv-b*?$AhvU7j9~S5+u`Ysw9&5oo0Djp8e(j25Etbx42Qa=4T~}q+PG&XdkWDNF z7bqo#7KW&%dh~ST6hbu8S=0V`{X&`kAy@8jZWZJuYE}_#b4<-^4dNUc-+%6g($yN% z5ny^;ogGh}H5+Gq3jR21rQgy@5#TCgX+(28NZ4w}dzfx-LP%uYk9LPTKABaQh1ah) z@Y(g!cLd!Mcz+e|XI@@IH9z*2=zxJ0uaJ+S(iIsk7=d>A#L<}={n`~O?UTGX{8Pda z_KhI*4jI?b{A!?~-M$xk)w0QBJb7I=EGy&o3AEB_RloU;v~F8ubD@9BbxV1c36CsTX+wzAZlvUm*;Re06D+Bq~LYg-qF4L z5kZZ80PB&4U?|hL9nIZm%jVj0;P_lXar)NSt3u8xx!K6Y0bclZ%<9fwjZ&!^;!>ug zQ}M`>k@S{BR20cyVXtKK%Qa^7?e<%VSAPGmVtGo6zc6BkO5vW5)m8_k{xT3;ocdpH zudHGT06XU@y6U!&kP8i6ubMQl>cm7=(W6P7^24Uzu4Xpwc->ib?RSHL*?!d{c-aE# zp?TrFr{4iDL3dpljl#HHbEn{~eW2Nqfksa(r-}n)lJLI%e#Bu|+1% zN&!n(nv(3^jGx?onfDcyeCC*p6)DuFn_<*62b92Pn$LH(INE{z^8y?mEvvO zZ~2I;A2qXvuj>1kk@WsECq1WbsSC!0m8n=S^t3kxAx~of0vpv{EqmAmDJ3(o;-cvf zu$33Z)C0)Y4(iBhh@)lsS|a%{;*W(@DbID^$ z|FzcJB-RFzpkBLaFLQ;EWMAW#@K(D#oYoOmcctdTV?fzM2@6U&S#+S$&zA4t<^-!V z+&#*xa)cLnfMTVE&I}o#4kxP~JT3-A)L_5O!yA2ebq?zvb0WO1D6$r9p?!L0#)Fc> z+I&?aog~FPBH}BpWfW^pyc{2i8#Io6e)^6wv}MZn&`01oq@$M@5eJ6J^IrXLI) z4C!#kh)89u5*Q@W5(rYDqBKO6&G*kPGFZfu@J}ug^7!sC(Wcv3Fbe{$Sy|{-VXTct znsP+0v}kduRs=S=x0MA$*(7xZPE-%aIt^^JG9s}8$43E~^t4=MxmMts;q2$^sj=k( z#^suR{0Wl3#9KAI<=SC6hifXuA{o02vdyq>iw%(#tv+@ov{QZBI^*^1K?Q_QQqA5n9YLRwO3a7JR+1x3#d3lZL;R1@8Z!2hnWj^_5 z^M{3wg%f15Db5Pd>tS!6Hj~n^l478ljxe@>!C;L$%rKfm#RBw^_K&i~ZyY_$BC%-L z^NdD{thVHFlnwfy(a?{%!m;U_9ic*!OPxf&5$muWz7&4VbW{PP)oE5u$uXUZU>+8R zCsZ~_*HLVnBm*^{seTAV=iN)mB0{<}C!EgE$_1RMj1kGUU?cjSWu*|zFA(ZrNE(CkY7>Mv1C)E1WjsBKAE%w}{~apwNj z0h`k)C1$TwZ<3de9+>;v6A0eZ@xHm#^7|z9`gQ3<`+lpz(1(RsgHAM@Ja+)c?;#j- zC=&5FD)m@9AX}0g9XQ_Yt4YB}aT`XxM-t>7v@BV}2^0gu0zRH%S9}!P(MBAFGyJ8F zEMdB&{eGOd$RqV77Lx>8pX^<@TdL{6^K7p$0uMTLC^n)g*yXRXMy`tqjYIZ|3b#Iv z4<)jtQU5`b{A;r2QCqIy>@!uuj^TBed3OuO1>My{GQe<^9|$4NOHTKFp{GpdFY-kC zi?uHq>lF$}<(JbQatP0*>$Aw_lygfmUyojkE=PnV)zc)7%^5BxpjkU+>ol2}WpB2hlDP(hVA;uLdu`=M_A!%RaRTd6>Mi_ozLYOEh!dfT_h0dSsnQm1bk)%K45)xLw zql&fx?ZOMBLXtUd$PRlqpo2CxNQTBb=!T|_>p&k1F})Hq&xksq>o#4b+KSs2KyxPQ z#{(qj@)9r6u2O~IqHG76@Fb~BZ4Wz_J$p_NU9-b3V$$kzjN24*sdw5spXetOuU1SR z{v}b92c>^PmvPs>BK2Ylp6&1>tnPsBA0jg0RQ{({-?^SBBm>=W>tS?_h^6%Scc)8L zgsKjSU@@6kSFX%_3%Qe{i7Z9Wg7~fM_)v?ExpM@htI{G6Db5ak(B4~4kRghRp_7zr z#Pco0_(bD$IS6l2j>%Iv^Hc)M`n-vIu;-2T+6nhW0JZxZ|NfDEh;ZnAe d|9e8rKfIInFTYPwOD9TMuEcqhmizAn{|ERF)u#Xe diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 8a1f6b97f47..68e8816d71c 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,7 +1,7 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionSha256Sum=a4b4158601f8636cdeeab09bd76afb640030bb5b144aafe261a5e8af027dc612 -distributionUrl=https\://services.gradle.org/distributions/gradle-8.8-bin.zip +distributionSha256Sum=d725d707bfabd4dfdc958c624003b3c80accc03f7037b5122c4b1d0ef15cecab +distributionUrl=https\://services.gradle.org/distributions/gradle-8.9-bin.zip networkTimeout=10000 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME diff --git a/gradlew b/gradlew index b740cf13397..f5feea6d6b1 100755 --- a/gradlew +++ b/gradlew @@ -15,6 +15,8 @@ # See the License for the specific language governing permissions and # limitations under the License. # +# SPDX-License-Identifier: Apache-2.0 +# ############################################################################## # @@ -84,7 +86,8 @@ done # shellcheck disable=SC2034 APP_BASE_NAME=${0##*/} # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) -APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s +' "$PWD" ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum diff --git a/gradlew.bat b/gradlew.bat index 25da30dbdee..9d21a21834d 100644 --- a/gradlew.bat +++ b/gradlew.bat @@ -13,6 +13,8 @@ @rem See the License for the specific language governing permissions and @rem limitations under the License. @rem +@rem SPDX-License-Identifier: Apache-2.0 +@rem @if "%DEBUG%"=="" @echo off @rem ########################################################################## From 3fa57f9280ff73bc74525f0e773eaef9b2ab9489 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 12 Jul 2024 21:35:32 -0700 Subject: [PATCH 480/901] Update dependency io.grpc:grpc-bom to v1.65.1 (#6573) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- dependencyManagement/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index fd5ab235e77..ba5156cc439 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -14,7 +14,7 @@ val DEPENDENCY_BOMS = listOf( "com.linecorp.armeria:armeria-bom:1.29.2", "com.squareup.okhttp3:okhttp-bom:4.12.0", "com.squareup.okio:okio-bom:3.9.0", // applies to transitive dependencies of okhttp - "io.grpc:grpc-bom:1.65.0", + "io.grpc:grpc-bom:1.65.1", "io.netty:netty-bom:4.1.111.Final", "io.zipkin.brave:brave-bom:6.0.3", "io.zipkin.reporter2:zipkin-reporter-bom:3.4.0", From dc1ec9cbedc762f357944595e51f27ee346b93a7 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 16 Jul 2024 19:13:49 -0700 Subject: [PATCH 481/901] Update gradle/actions action to v3.5.0 (#6582) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/gradle-wrapper-validation.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/gradle-wrapper-validation.yml b/.github/workflows/gradle-wrapper-validation.yml index 4eb03862f58..37bde5bf7b9 100644 --- a/.github/workflows/gradle-wrapper-validation.yml +++ b/.github/workflows/gradle-wrapper-validation.yml @@ -13,4 +13,4 @@ jobs: steps: - uses: actions/checkout@v4 - - uses: gradle/actions/wrapper-validation@v3.4.2 + - uses: gradle/actions/wrapper-validation@v3.5.0 From 6dd000be2508ab97323a464129362798b2902951 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 17 Jul 2024 14:26:13 -0500 Subject: [PATCH 482/901] Update dependency org.testcontainers:testcontainers-bom to v1.20.0 (#6590) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- dependencyManagement/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index ba5156cc439..556e10431b1 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -20,7 +20,7 @@ val DEPENDENCY_BOMS = listOf( "io.zipkin.reporter2:zipkin-reporter-bom:3.4.0", "org.assertj:assertj-bom:3.26.3", "org.junit:junit-bom:5.10.3", - "org.testcontainers:testcontainers-bom:1.19.8", + "org.testcontainers:testcontainers-bom:1.20.0", "org.snakeyaml:snakeyaml-engine:2.7" ) From 034c0c2ded420ce162c59ee5fde68839a88de2d2 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 17 Jul 2024 14:26:47 -0500 Subject: [PATCH 483/901] Update dependency org.owasp:dependency-check-gradle to v10.0.3 (#6585) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- buildSrc/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts index 5504d89b8d4..7c9dea46a5e 100644 --- a/buildSrc/build.gradle.kts +++ b/buildSrc/build.gradle.kts @@ -66,7 +66,7 @@ dependencies { implementation("net.ltgt.gradle:gradle-errorprone-plugin:4.0.1") implementation("net.ltgt.gradle:gradle-nullaway-plugin:2.0.0") implementation("org.jetbrains.kotlin:kotlin-gradle-plugin:2.0.0") - implementation("org.owasp:dependency-check-gradle:10.0.2") + implementation("org.owasp:dependency-check-gradle:10.0.3") implementation("ru.vyarus:gradle-animalsniffer-plugin:1.7.1") } From 958b59be4d32c2539e9a301b4bd0119b7c606d25 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 17 Jul 2024 14:38:02 -0500 Subject: [PATCH 484/901] Update dependency com.squareup.wire:wire-bom to v5 (#6580) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Co-authored-by: Jack Berg --- buildSrc/build.gradle.kts | 2 +- .../opentelemetry/gradle/ProtoFieldsWireHandlerFactory.kt | 7 +------ 2 files changed, 2 insertions(+), 7 deletions(-) diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts index 7c9dea46a5e..ebf161f5c93 100644 --- a/buildSrc/build.gradle.kts +++ b/buildSrc/build.gradle.kts @@ -50,7 +50,7 @@ repositories { } dependencies { - implementation(enforcedPlatform("com.squareup.wire:wire-bom:4.9.9")) + implementation(enforcedPlatform("com.squareup.wire:wire-bom:5.0.0")) implementation("com.google.auto.value:auto-value-annotations:1.11.0") // When updating, update above in plugins too implementation("com.diffplug.spotless:spotless-plugin-gradle:6.25.0") diff --git a/buildSrc/src/main/kotlin/io/opentelemetry/gradle/ProtoFieldsWireHandlerFactory.kt b/buildSrc/src/main/kotlin/io/opentelemetry/gradle/ProtoFieldsWireHandlerFactory.kt index 2aca450347f..cd99a69dc44 100644 --- a/buildSrc/src/main/kotlin/io/opentelemetry/gradle/ProtoFieldsWireHandlerFactory.kt +++ b/buildSrc/src/main/kotlin/io/opentelemetry/gradle/ProtoFieldsWireHandlerFactory.kt @@ -3,10 +3,6 @@ package io.opentelemetry.gradle import com.squareup.wire.schema.SchemaHandler class ProtoFieldsWireHandlerFactory : SchemaHandler.Factory{ - @Deprecated("deprecated in parent") - override fun create(): SchemaHandler { - return ProtoFieldsWireHandler() - } override fun create( includes: List, @@ -15,8 +11,7 @@ class ProtoFieldsWireHandlerFactory : SchemaHandler.Factory{ outDirectory: String, options: Map ): SchemaHandler { - @Suppress("DEPRECATION") - return create() + return ProtoFieldsWireHandler() } } From 8f3460ae4317d6ce2761d20fa9d42d2914d23dce Mon Sep 17 00:00:00 2001 From: SylvainJuge <763082+SylvainJuge@users.noreply.github.com> Date: Wed, 17 Jul 2024 21:38:32 +0200 Subject: [PATCH 485/901] suppress instrumentation: move to api + generic context key (#6546) --- .../api/internal/InstrumentationUtil.java | 40 +++++++++++++++++++ .../api/internal/InstrumentationUtilTest.java | 27 +++++++++++++ .../internal/InstrumentationUtil.java | 14 +++---- .../internal/InstrumentationUtilTest.java | 3 ++ .../okhttp/internal/OkHttpGrpcSender.java | 2 +- .../okhttp/internal/OkHttpHttpSender.java | 2 +- .../AbstractOkHttpSuppressionTest.java | 2 +- 7 files changed, 80 insertions(+), 10 deletions(-) create mode 100644 api/all/src/main/java/io/opentelemetry/api/internal/InstrumentationUtil.java create mode 100644 api/all/src/test/java/io/opentelemetry/api/internal/InstrumentationUtilTest.java diff --git a/api/all/src/main/java/io/opentelemetry/api/internal/InstrumentationUtil.java b/api/all/src/main/java/io/opentelemetry/api/internal/InstrumentationUtil.java new file mode 100644 index 00000000000..4f5c1e676bf --- /dev/null +++ b/api/all/src/main/java/io/opentelemetry/api/internal/InstrumentationUtil.java @@ -0,0 +1,40 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.api.internal; + +import io.opentelemetry.context.Context; +import io.opentelemetry.context.ContextKey; +import java.util.Objects; + +/** + * This class is internal and is hence not for public use. Its APIs are unstable and can change at + * any time. + */ +public final class InstrumentationUtil { + private static final ContextKey SUPPRESS_INSTRUMENTATION_KEY = + ContextKey.named("suppress_instrumentation"); + + private InstrumentationUtil() {} + + /** + * Adds a Context boolean key that will allow to identify HTTP calls coming from OTel exporters. + * The key later be checked by an automatic instrumentation to avoid tracing OTel exporter's + * calls. + */ + public static void suppressInstrumentation(Runnable runnable) { + Context.current().with(SUPPRESS_INSTRUMENTATION_KEY, true).wrap(runnable).run(); + } + + /** + * Checks if an automatic instrumentation should be suppressed with the provided Context. + * + * @return TRUE to suppress the automatic instrumentation, FALSE to continue with the + * instrumentation. + */ + public static boolean shouldSuppressInstrumentation(Context context) { + return Objects.equals(context.get(SUPPRESS_INSTRUMENTATION_KEY), true); + } +} diff --git a/api/all/src/test/java/io/opentelemetry/api/internal/InstrumentationUtilTest.java b/api/all/src/test/java/io/opentelemetry/api/internal/InstrumentationUtilTest.java new file mode 100644 index 00000000000..066c906d875 --- /dev/null +++ b/api/all/src/test/java/io/opentelemetry/api/internal/InstrumentationUtilTest.java @@ -0,0 +1,27 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.api.internal; + +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import io.opentelemetry.context.Context; +import org.junit.jupiter.api.Test; + +class InstrumentationUtilTest { + @Test + void verifySuppressInstrumentation() { + // Should be false by default. + assertFalse(InstrumentationUtil.shouldSuppressInstrumentation(Context.current())); + + // Should be true inside the Runnable passed to InstrumentationUtil.suppressInstrumentation. + InstrumentationUtil.suppressInstrumentation( + () -> assertTrue(InstrumentationUtil.shouldSuppressInstrumentation(Context.current()))); + + // Should be false after the runnable finishes. + assertFalse(InstrumentationUtil.shouldSuppressInstrumentation(Context.current())); + } +} diff --git a/exporters/common/src/main/java/io/opentelemetry/exporter/internal/InstrumentationUtil.java b/exporters/common/src/main/java/io/opentelemetry/exporter/internal/InstrumentationUtil.java index 4ce9622fe4c..5eddab53b76 100644 --- a/exporters/common/src/main/java/io/opentelemetry/exporter/internal/InstrumentationUtil.java +++ b/exporters/common/src/main/java/io/opentelemetry/exporter/internal/InstrumentationUtil.java @@ -6,16 +6,16 @@ package io.opentelemetry.exporter.internal; import io.opentelemetry.context.Context; -import io.opentelemetry.context.ContextKey; -import java.util.Objects; /** * This class is internal and is hence not for public use. Its APIs are unstable and can change at - * any time. + * any time + * + * @deprecated use {@link io.opentelemetry.api.internal.InstrumentationUtil} instead. This class + * should be removed once instrumentation does not refer to it anymore. */ +@Deprecated public final class InstrumentationUtil { - private static final ContextKey SUPPRESS_INSTRUMENTATION_KEY = - ContextKey.named("suppress_internal_exporter_instrumentation"); private InstrumentationUtil() {} @@ -25,7 +25,7 @@ private InstrumentationUtil() {} * calls. */ public static void suppressInstrumentation(Runnable runnable) { - Context.current().with(SUPPRESS_INSTRUMENTATION_KEY, true).wrap(runnable).run(); + io.opentelemetry.api.internal.InstrumentationUtil.suppressInstrumentation(runnable); } /** @@ -35,6 +35,6 @@ public static void suppressInstrumentation(Runnable runnable) { * instrumentation. */ public static boolean shouldSuppressInstrumentation(Context context) { - return Objects.equals(context.get(SUPPRESS_INSTRUMENTATION_KEY), true); + return io.opentelemetry.api.internal.InstrumentationUtil.shouldSuppressInstrumentation(context); } } diff --git a/exporters/common/src/test/java/io/opentelemetry/exporter/internal/InstrumentationUtilTest.java b/exporters/common/src/test/java/io/opentelemetry/exporter/internal/InstrumentationUtilTest.java index 2c7e9f540c7..5a6a2cfd5a2 100644 --- a/exporters/common/src/test/java/io/opentelemetry/exporter/internal/InstrumentationUtilTest.java +++ b/exporters/common/src/test/java/io/opentelemetry/exporter/internal/InstrumentationUtilTest.java @@ -12,7 +12,10 @@ import org.junit.jupiter.api.Test; class InstrumentationUtilTest { + + // testing deprecated implementation until it's removed @Test + @SuppressWarnings("deprecation") void verifySuppressInstrumentation() { // Should be false by default. assertFalse(InstrumentationUtil.shouldSuppressInstrumentation(Context.current())); diff --git a/exporters/sender/okhttp/src/main/java/io/opentelemetry/exporter/sender/okhttp/internal/OkHttpGrpcSender.java b/exporters/sender/okhttp/src/main/java/io/opentelemetry/exporter/sender/okhttp/internal/OkHttpGrpcSender.java index d9ceecb77b7..7fb04c4e513 100644 --- a/exporters/sender/okhttp/src/main/java/io/opentelemetry/exporter/sender/okhttp/internal/OkHttpGrpcSender.java +++ b/exporters/sender/okhttp/src/main/java/io/opentelemetry/exporter/sender/okhttp/internal/OkHttpGrpcSender.java @@ -23,7 +23,7 @@ package io.opentelemetry.exporter.sender.okhttp.internal; -import io.opentelemetry.exporter.internal.InstrumentationUtil; +import io.opentelemetry.api.internal.InstrumentationUtil; import io.opentelemetry.exporter.internal.RetryUtil; import io.opentelemetry.exporter.internal.compression.Compressor; import io.opentelemetry.exporter.internal.grpc.GrpcExporterUtil; diff --git a/exporters/sender/okhttp/src/main/java/io/opentelemetry/exporter/sender/okhttp/internal/OkHttpHttpSender.java b/exporters/sender/okhttp/src/main/java/io/opentelemetry/exporter/sender/okhttp/internal/OkHttpHttpSender.java index 8b85396ce08..1a0263a13de 100644 --- a/exporters/sender/okhttp/src/main/java/io/opentelemetry/exporter/sender/okhttp/internal/OkHttpHttpSender.java +++ b/exporters/sender/okhttp/src/main/java/io/opentelemetry/exporter/sender/okhttp/internal/OkHttpHttpSender.java @@ -5,7 +5,7 @@ package io.opentelemetry.exporter.sender.okhttp.internal; -import io.opentelemetry.exporter.internal.InstrumentationUtil; +import io.opentelemetry.api.internal.InstrumentationUtil; import io.opentelemetry.exporter.internal.RetryUtil; import io.opentelemetry.exporter.internal.auth.Authenticator; import io.opentelemetry.exporter.internal.compression.Compressor; diff --git a/exporters/sender/okhttp/src/test/java/io/opentelemetry/exporter/sender/okhttp/internal/AbstractOkHttpSuppressionTest.java b/exporters/sender/okhttp/src/test/java/io/opentelemetry/exporter/sender/okhttp/internal/AbstractOkHttpSuppressionTest.java index d1a84a7491d..4787bb8a610 100644 --- a/exporters/sender/okhttp/src/test/java/io/opentelemetry/exporter/sender/okhttp/internal/AbstractOkHttpSuppressionTest.java +++ b/exporters/sender/okhttp/src/test/java/io/opentelemetry/exporter/sender/okhttp/internal/AbstractOkHttpSuppressionTest.java @@ -7,8 +7,8 @@ import static org.junit.jupiter.api.Assertions.assertTrue; +import io.opentelemetry.api.internal.InstrumentationUtil; import io.opentelemetry.context.Context; -import io.opentelemetry.exporter.internal.InstrumentationUtil; import java.util.concurrent.CountDownLatch; import java.util.concurrent.atomic.AtomicBoolean; import org.junit.jupiter.api.AfterEach; From 0b513ad227fa2011d98509a199406c8118f23aa5 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 17 Jul 2024 18:29:01 -0700 Subject: [PATCH 486/901] Update errorProneVersion to v2.29.1 (#6586) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- dependencyManagement/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index 556e10431b1..e6728e3f66d 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -25,7 +25,7 @@ val DEPENDENCY_BOMS = listOf( ) val autoValueVersion = "1.11.0" -val errorProneVersion = "2.28.0" +val errorProneVersion = "2.29.1" val jmhVersion = "1.37" // Mockito 5.x.x requires Java 11 https://github.com/mockito/mockito/releases/tag/v5.0.0 val mockitoVersion = "4.11.0" From fa215ff24258f4b135766c5c6a819afbd208b0f9 Mon Sep 17 00:00:00 2001 From: jack-berg <34418638+jack-berg@users.noreply.github.com> Date: Fri, 19 Jul 2024 13:56:32 -0500 Subject: [PATCH 487/901] Update stability status of opentelemetry-exporter-sender-jdk in readme (#6592) --- README.md | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/README.md b/README.md index 3920f9ef59e..ba545f08a51 100644 --- a/README.md +++ b/README.md @@ -261,18 +261,18 @@ dependency as follows, replacing `{{artifact-id}}` with the value from the "Arti ### SDK Exporters -| Component | Description | Artifact ID | Version | Javadoc | -|-----------------------------------------------------------------------|------------------------------------------------------------------------------|-------------------------------------------------------------------------|-------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| [OTLP Exporters](./exporters/otlp/all) | OTLP gRPC & HTTP exporters, including traces, metrics, and logs | `opentelemetry-exporter-otlp` | 1.40.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-otlp.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-otlp) | -| [OTLP Logging Exporters](./exporters/logging-otlp) | Logging exporters in OTLP JSON encoding, including traces, metrics, and logs | `opentelemetry-exporter-logging-otlp` | 1.40.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-logging-otlp.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-logging-otlp) | -| [OTLP Common](./exporters/otlp/common) | Shared OTLP components (internal) | `opentelemetry-exporter-otlp-common` | 1.40.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-otlp-common.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-otlp-common) | -| [Logging Exporter](./exporters/logging) | Logging exporters, including metrics, traces, and logs | `opentelemetry-exporter-logging` | 1.40.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-logging.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-logging) | -| [Zipkin Exporter](./exporters/zipkin) | Zipkin trace exporter | `opentelemetry-exporter-zipkin` | 1.40.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-zipkin.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-zipkin) | -| [Prometheus Exporter](./exporters/prometheus) | Prometheus metric exporter | `opentelemetry-exporter-prometheus` | 1.40.0-alpha | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-prometheus.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-prometheus) | -| [Exporter Common](./exporters/common) | Shared exporter components (internal) | `opentelemetry-exporter-common` | 1.40.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-common.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-common) | -| [OkHttp Sender](./exporters/sender/okhttp) | OkHttp implementation of HttpSender (internal) | `opentelemetry-exporter-sender-okhttp` | 1.40.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-sender-okhttp.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-sender-okhttp) | -| [JDK Sender](./exporters/sender/jdk) | Java 11+ native HttpClient implementation of HttpSender (internal) | `opentelemetry-exporter-sender-jdk` TODO: remove `-alpha` after release | 1.40.0-alpha | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-sender-jdk.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-sender-jdk) | | -| [gRPC ManagedChannel Sender](./exporters/sender/grpc-managed-channel) | gRPC ManagedChannel implementation of GrpcSender (internal) | `opentelemetry-exporter-sender-grpc-managed-channel` | 1.40.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-sender-grpc-managed-channel.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-sender-grpc-managed-channel) | | +| Component | Description | Artifact ID | Version | Javadoc | +|-----------------------------------------------------------------------|------------------------------------------------------------------------------|------------------------------------------------------|-------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| [OTLP Exporters](./exporters/otlp/all) | OTLP gRPC & HTTP exporters, including traces, metrics, and logs | `opentelemetry-exporter-otlp` | 1.40.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-otlp.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-otlp) | +| [OTLP Logging Exporters](./exporters/logging-otlp) | Logging exporters in OTLP JSON encoding, including traces, metrics, and logs | `opentelemetry-exporter-logging-otlp` | 1.40.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-logging-otlp.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-logging-otlp) | +| [OTLP Common](./exporters/otlp/common) | Shared OTLP components (internal) | `opentelemetry-exporter-otlp-common` | 1.40.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-otlp-common.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-otlp-common) | +| [Logging Exporter](./exporters/logging) | Logging exporters, including metrics, traces, and logs | `opentelemetry-exporter-logging` | 1.40.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-logging.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-logging) | +| [Zipkin Exporter](./exporters/zipkin) | Zipkin trace exporter | `opentelemetry-exporter-zipkin` | 1.40.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-zipkin.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-zipkin) | +| [Prometheus Exporter](./exporters/prometheus) | Prometheus metric exporter | `opentelemetry-exporter-prometheus` | 1.40.0-alpha | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-prometheus.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-prometheus) | +| [Exporter Common](./exporters/common) | Shared exporter components (internal) | `opentelemetry-exporter-common` | 1.40.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-common.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-common) | +| [OkHttp Sender](./exporters/sender/okhttp) | OkHttp implementation of HttpSender (internal) | `opentelemetry-exporter-sender-okhttp` | 1.40.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-sender-okhttp.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-sender-okhttp) | +| [JDK Sender](./exporters/sender/jdk) | Java 11+ native HttpClient implementation of HttpSender (internal) | `opentelemetry-exporter-sender-jdk` | 1.40.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-sender-jdk.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-sender-jdk) | | +| [gRPC ManagedChannel Sender](./exporters/sender/grpc-managed-channel) | gRPC ManagedChannel implementation of GrpcSender (internal) | `opentelemetry-exporter-sender-grpc-managed-channel` | 1.40.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-sender-grpc-managed-channel.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-sender-grpc-managed-channel) | | ### SDK Extensions From 8fd45a771c85584c9f710767dfe82bc458421358 Mon Sep 17 00:00:00 2001 From: jack-berg <34418638+jack-berg@users.noreply.github.com> Date: Fri, 19 Jul 2024 14:27:57 -0500 Subject: [PATCH 488/901] Enable retry by default for OTLP exporters (#6588) --- .../internal/grpc/GrpcExporterBuilder.java | 4 +- .../internal/http/HttpExporterBuilder.java | 4 +- .../OtlpHttpLogRecordExporterBuilder.java | 7 +- .../OtlpHttpMetricExporterBuilder.java | 7 +- .../trace/OtlpHttpSpanExporterBuilder.java | 7 +- .../otlp/internal/OtlpConfigUtil.java | 14 +- .../OtlpGrpcLogRecordExporterBuilder.java | 7 +- .../OtlpGrpcMetricExporterBuilder.java | 7 +- .../trace/OtlpGrpcSpanExporterBuilder.java | 7 +- .../OtlpLogRecordExporterProviderTest.java | 12 +- .../OtlpMetricExporterProviderTest.java | 12 +- .../OtlpSpanExporterProviderTest.java | 12 +- ...tlpHttpMetricExporterOkHttpSenderTest.java | 1 + .../OtlpHttpSpanExporterOkHttpSenderTest.java | 1 + .../metrics/OtlpGrpcMetricExporterTest.java | 1 + .../otlp/traces/OtlpGrpcSpanExporterTest.java | 1 + .../OtlpHttpMetricExporterJdkSenderTest.java | 1 + .../AbstractGrpcTelemetryExporterTest.java | 275 ++++++++++-------- .../AbstractHttpTelemetryExporterTest.java | 83 ++---- .../GrpcLogRecordExporterBuilderWrapper.java | 3 +- .../GrpcMetricExporterBuilderWrapper.java | 3 +- .../GrpcSpanExporterBuilderWrapper.java | 3 +- .../HttpLogRecordExporterBuilderWrapper.java | 3 +- .../HttpMetricExporterBuilderWrapper.java | 3 +- .../HttpSpanExporterBuilderWrapper.java | 3 +- ...anagedChannelTelemetryExporterBuilder.java | 5 +- .../internal/TelemetryExporterBuilder.java | 3 +- 27 files changed, 256 insertions(+), 233 deletions(-) diff --git a/exporters/common/src/main/java/io/opentelemetry/exporter/internal/grpc/GrpcExporterBuilder.java b/exporters/common/src/main/java/io/opentelemetry/exporter/internal/grpc/GrpcExporterBuilder.java index 52dd51fe552..c5b04fd8db8 100644 --- a/exporters/common/src/main/java/io/opentelemetry/exporter/internal/grpc/GrpcExporterBuilder.java +++ b/exporters/common/src/main/java/io/opentelemetry/exporter/internal/grpc/GrpcExporterBuilder.java @@ -60,7 +60,7 @@ public class GrpcExporterBuilder { private final Map constantHeaders = new HashMap<>(); private Supplier> headerSupplier = Collections::emptyMap; private TlsConfigHelper tlsConfigHelper = new TlsConfigHelper(); - @Nullable private RetryPolicy retryPolicy; + @Nullable private RetryPolicy retryPolicy = RetryPolicy.getDefault(); private Supplier meterProviderSupplier = GlobalOpenTelemetry::getMeterProvider; // Use Object type since gRPC may not be on the classpath. @@ -137,7 +137,7 @@ public GrpcExporterBuilder setHeadersSupplier(Supplier> h return this; } - public GrpcExporterBuilder setRetryPolicy(RetryPolicy retryPolicy) { + public GrpcExporterBuilder setRetryPolicy(@Nullable RetryPolicy retryPolicy) { this.retryPolicy = retryPolicy; return this; } diff --git a/exporters/common/src/main/java/io/opentelemetry/exporter/internal/http/HttpExporterBuilder.java b/exporters/common/src/main/java/io/opentelemetry/exporter/internal/http/HttpExporterBuilder.java index 8f1d441b154..4d23d39ea85 100644 --- a/exporters/common/src/main/java/io/opentelemetry/exporter/internal/http/HttpExporterBuilder.java +++ b/exporters/common/src/main/java/io/opentelemetry/exporter/internal/http/HttpExporterBuilder.java @@ -59,7 +59,7 @@ public final class HttpExporterBuilder { private Supplier> headerSupplier = Collections::emptyMap; private TlsConfigHelper tlsConfigHelper = new TlsConfigHelper(); - @Nullable private RetryPolicy retryPolicy; + @Nullable private RetryPolicy retryPolicy = RetryPolicy.getDefault(); private Supplier meterProviderSupplier = GlobalOpenTelemetry::getMeterProvider; @Nullable private Authenticator authenticator; @@ -128,7 +128,7 @@ public HttpExporterBuilder setMeterProvider(Supplier meterProv return this; } - public HttpExporterBuilder setRetryPolicy(RetryPolicy retryPolicy) { + public HttpExporterBuilder setRetryPolicy(@Nullable RetryPolicy retryPolicy) { this.retryPolicy = retryPolicy; return this; } diff --git a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/logs/OtlpHttpLogRecordExporterBuilder.java b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/logs/OtlpHttpLogRecordExporterBuilder.java index 615f79fabe1..0d2654051f4 100644 --- a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/logs/OtlpHttpLogRecordExporterBuilder.java +++ b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/logs/OtlpHttpLogRecordExporterBuilder.java @@ -23,6 +23,7 @@ import java.util.Map; import java.util.concurrent.TimeUnit; import java.util.function.Supplier; +import javax.annotation.Nullable; import javax.net.ssl.SSLContext; import javax.net.ssl.X509TrustManager; @@ -166,12 +167,12 @@ public OtlpHttpLogRecordExporterBuilder setSslContext( } /** - * Set the retry policy. Retry is disabled by default. + * Set the retry policy, or {@code null} to disable retry. Retry policy is {@link + * RetryPolicy#getDefault()} by default * * @since 1.28.0 */ - public OtlpHttpLogRecordExporterBuilder setRetryPolicy(RetryPolicy retryPolicy) { - requireNonNull(retryPolicy, "retryPolicy"); + public OtlpHttpLogRecordExporterBuilder setRetryPolicy(@Nullable RetryPolicy retryPolicy) { delegate.setRetryPolicy(retryPolicy); return this; } diff --git a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/metrics/OtlpHttpMetricExporterBuilder.java b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/metrics/OtlpHttpMetricExporterBuilder.java index f187d5a0696..49a1c45183d 100644 --- a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/metrics/OtlpHttpMetricExporterBuilder.java +++ b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/metrics/OtlpHttpMetricExporterBuilder.java @@ -28,6 +28,7 @@ import java.util.Map; import java.util.concurrent.TimeUnit; import java.util.function.Supplier; +import javax.annotation.Nullable; import javax.net.ssl.SSLContext; import javax.net.ssl.X509TrustManager; @@ -212,12 +213,12 @@ public OtlpHttpMetricExporterBuilder setDefaultAggregationSelector( } /** - * Set the retry policy. Retry is disabled by default. + * Set the retry policy, or {@code null} to disable retry. Retry policy is {@link + * RetryPolicy#getDefault()} by default * * @since 1.28.0 */ - public OtlpHttpMetricExporterBuilder setRetryPolicy(RetryPolicy retryPolicy) { - requireNonNull(retryPolicy, "retryPolicy"); + public OtlpHttpMetricExporterBuilder setRetryPolicy(@Nullable RetryPolicy retryPolicy) { delegate.setRetryPolicy(retryPolicy); return this; } diff --git a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/trace/OtlpHttpSpanExporterBuilder.java b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/trace/OtlpHttpSpanExporterBuilder.java index 6e5f27a8c5e..fe91ceb6da7 100644 --- a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/trace/OtlpHttpSpanExporterBuilder.java +++ b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/trace/OtlpHttpSpanExporterBuilder.java @@ -23,6 +23,7 @@ import java.util.Map; import java.util.concurrent.TimeUnit; import java.util.function.Supplier; +import javax.annotation.Nullable; import javax.net.ssl.SSLContext; import javax.net.ssl.X509TrustManager; @@ -167,12 +168,12 @@ public OtlpHttpSpanExporterBuilder setSslContext( } /** - * Set the retry policy. Retry is disabled by default. + * Set the retry policy, or {@code null} to disable retry. Retry policy is {@link + * RetryPolicy#getDefault()} by default * * @since 1.28.0 */ - public OtlpHttpSpanExporterBuilder setRetryPolicy(RetryPolicy retryPolicy) { - requireNonNull(retryPolicy, "retryPolicy"); + public OtlpHttpSpanExporterBuilder setRetryPolicy(@Nullable RetryPolicy retryPolicy) { delegate.setRetryPolicy(retryPolicy); return this; } diff --git a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/OtlpConfigUtil.java b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/OtlpConfigUtil.java index 2b387d06367..7f1214bd518 100644 --- a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/OtlpConfigUtil.java +++ b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/OtlpConfigUtil.java @@ -151,10 +151,16 @@ public static void configureOtlpExporterBuilder( setClientTls.accept(clientKeyBytes, clientKeyChainBytes); } - boolean retryEnabled = - config.getBoolean("otel.experimental.exporter.otlp.retry.enabled", false); - if (retryEnabled) { - setRetryPolicy.accept(RetryPolicy.getDefault()); + Boolean retryDisabled = config.getBoolean("otel.java.exporter.otlp.retry.disabled"); + if (retryDisabled == null) { + Boolean experimentalRetryEnabled = + config.getBoolean("otel.experimental.exporter.otlp.retry.enabled"); + if (experimentalRetryEnabled != null) { + retryDisabled = !experimentalRetryEnabled; + } + } + if (retryDisabled != null && retryDisabled) { + setRetryPolicy.accept(null); } ExporterBuilderUtil.configureExporterMemoryMode(config, setMemoryMode); diff --git a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/logs/OtlpGrpcLogRecordExporterBuilder.java b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/logs/OtlpGrpcLogRecordExporterBuilder.java index ade585dbf70..8f082855b75 100644 --- a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/logs/OtlpGrpcLogRecordExporterBuilder.java +++ b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/logs/OtlpGrpcLogRecordExporterBuilder.java @@ -24,6 +24,7 @@ import java.util.Map; import java.util.concurrent.TimeUnit; import java.util.function.Supplier; +import javax.annotation.Nullable; import javax.net.ssl.SSLContext; import javax.net.ssl.X509TrustManager; @@ -210,12 +211,12 @@ public OtlpGrpcLogRecordExporterBuilder setHeaders(Supplier> } /** - * Set the retry policy. Retry is disabled by default. + * Set the retry policy, or {@code null} to disable retry. Retry policy is {@link + * RetryPolicy#getDefault()} by default * * @since 1.28.0 */ - public OtlpGrpcLogRecordExporterBuilder setRetryPolicy(RetryPolicy retryPolicy) { - requireNonNull(retryPolicy, "retryPolicy"); + public OtlpGrpcLogRecordExporterBuilder setRetryPolicy(@Nullable RetryPolicy retryPolicy) { delegate.setRetryPolicy(retryPolicy); return this; } diff --git a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/metrics/OtlpGrpcMetricExporterBuilder.java b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/metrics/OtlpGrpcMetricExporterBuilder.java index 5937d4a1f1a..4a975e257c6 100644 --- a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/metrics/OtlpGrpcMetricExporterBuilder.java +++ b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/metrics/OtlpGrpcMetricExporterBuilder.java @@ -29,6 +29,7 @@ import java.util.Map; import java.util.concurrent.TimeUnit; import java.util.function.Supplier; +import javax.annotation.Nullable; import javax.net.ssl.SSLContext; import javax.net.ssl.X509TrustManager; @@ -256,12 +257,12 @@ public OtlpGrpcMetricExporterBuilder setDefaultAggregationSelector( } /** - * Set the retry policy. Retry is disabled by default. + * Set the retry policy, or {@code null} to disable retry. Retry policy is {@link + * RetryPolicy#getDefault()} by default * * @since 1.28.0 */ - public OtlpGrpcMetricExporterBuilder setRetryPolicy(RetryPolicy retryPolicy) { - requireNonNull(retryPolicy, "retryPolicy"); + public OtlpGrpcMetricExporterBuilder setRetryPolicy(@Nullable RetryPolicy retryPolicy) { delegate.setRetryPolicy(retryPolicy); return this; } diff --git a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/trace/OtlpGrpcSpanExporterBuilder.java b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/trace/OtlpGrpcSpanExporterBuilder.java index b6455d6c5a9..370c3b5bd2c 100644 --- a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/trace/OtlpGrpcSpanExporterBuilder.java +++ b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/trace/OtlpGrpcSpanExporterBuilder.java @@ -24,6 +24,7 @@ import java.util.Map; import java.util.concurrent.TimeUnit; import java.util.function.Supplier; +import javax.annotation.Nullable; import javax.net.ssl.SSLContext; import javax.net.ssl.X509TrustManager; @@ -207,12 +208,12 @@ public OtlpGrpcSpanExporterBuilder setHeaders(Supplier> head } /** - * Set the retry policy. Retry is disabled by default. + * Set the retry policy, or {@code null} to disable retry. Retry policy is {@link + * RetryPolicy#getDefault()} by default * * @since 1.28.0 */ - public OtlpGrpcSpanExporterBuilder setRetryPolicy(RetryPolicy retryPolicy) { - requireNonNull(retryPolicy, "retryPolicy"); + public OtlpGrpcSpanExporterBuilder setRetryPolicy(@Nullable RetryPolicy retryPolicy) { delegate.setRetryPolicy(retryPolicy); return this; } diff --git a/exporters/otlp/all/src/test/java/io/opentelemetry/exporter/otlp/internal/OtlpLogRecordExporterProviderTest.java b/exporters/otlp/all/src/test/java/io/opentelemetry/exporter/otlp/internal/OtlpLogRecordExporterProviderTest.java index 5619ddf5aa4..2f882b3ebfd 100644 --- a/exporters/otlp/all/src/test/java/io/opentelemetry/exporter/otlp/internal/OtlpLogRecordExporterProviderTest.java +++ b/exporters/otlp/all/src/test/java/io/opentelemetry/exporter/otlp/internal/OtlpLogRecordExporterProviderTest.java @@ -127,7 +127,7 @@ void createExporter_GrpcDefaults() { verify(grpcBuilder, never()).setTimeout(any()); verify(grpcBuilder, never()).setTrustedCertificates(any()); verify(grpcBuilder, never()).setClientTls(any(), any()); - assertThat(grpcBuilder).extracting("delegate").extracting("retryPolicy").isNull(); + assertThat(grpcBuilder).extracting("delegate").extracting("retryPolicy").isNotNull(); assertThat(exporter).extracting("memoryMode").isEqualTo(MemoryMode.IMMUTABLE_DATA); } Mockito.verifyNoInteractions(httpBuilder); @@ -143,7 +143,7 @@ void createExporter_GrpcWithGeneralConfiguration() throws CertificateEncodingExc config.put("otel.exporter.otlp.headers", "header-key=header-value"); config.put("otel.exporter.otlp.compression", "gzip"); config.put("otel.exporter.otlp.timeout", "15s"); - config.put("otel.experimental.exporter.otlp.retry.enabled", "true"); + config.put("otel.java.exporter.otlp.retry.disabled", "true"); try (LogRecordExporter exporter = provider.createExporter(DefaultConfigProperties.createFromMap(config))) { @@ -156,7 +156,7 @@ void createExporter_GrpcWithGeneralConfiguration() throws CertificateEncodingExc verify(grpcBuilder).setTrustedCertificates(serverTls.certificate().getEncoded()); verify(grpcBuilder) .setClientTls(clientTls.privateKey().getEncoded(), clientTls.certificate().getEncoded()); - assertThat(grpcBuilder).extracting("delegate").extracting("retryPolicy").isNotNull(); + assertThat(grpcBuilder).extracting("delegate").extracting("retryPolicy").isNull(); } Mockito.verifyNoInteractions(httpBuilder); } @@ -210,7 +210,7 @@ void createExporter_HttpDefaults() { verify(httpBuilder, never()).setTimeout(any()); verify(httpBuilder, never()).setTrustedCertificates(any()); verify(httpBuilder, never()).setClientTls(any(), any()); - assertThat(httpBuilder).extracting("delegate").extracting("retryPolicy").isNull(); + assertThat(httpBuilder).extracting("delegate").extracting("retryPolicy").isNotNull(); assertThat(exporter).extracting("memoryMode").isEqualTo(MemoryMode.IMMUTABLE_DATA); } Mockito.verifyNoInteractions(grpcBuilder); @@ -227,7 +227,7 @@ void createExporter_HttpWithGeneralConfiguration() throws CertificateEncodingExc config.put("otel.exporter.otlp.headers", "header-key=header-value"); config.put("otel.exporter.otlp.compression", "gzip"); config.put("otel.exporter.otlp.timeout", "15s"); - config.put("otel.experimental.exporter.otlp.retry.enabled", "true"); + config.put("otel.java.exporter.otlp.retry.disabled", "true"); try (LogRecordExporter exporter = provider.createExporter(DefaultConfigProperties.createFromMap(config))) { @@ -240,7 +240,7 @@ void createExporter_HttpWithGeneralConfiguration() throws CertificateEncodingExc verify(httpBuilder).setTrustedCertificates(serverTls.certificate().getEncoded()); verify(httpBuilder) .setClientTls(clientTls.privateKey().getEncoded(), clientTls.certificate().getEncoded()); - assertThat(httpBuilder).extracting("delegate").extracting("retryPolicy").isNotNull(); + assertThat(httpBuilder).extracting("delegate").extracting("retryPolicy").isNull(); } Mockito.verifyNoInteractions(grpcBuilder); } diff --git a/exporters/otlp/all/src/test/java/io/opentelemetry/exporter/otlp/internal/OtlpMetricExporterProviderTest.java b/exporters/otlp/all/src/test/java/io/opentelemetry/exporter/otlp/internal/OtlpMetricExporterProviderTest.java index 36e6b88cfa8..3956b4f62d8 100644 --- a/exporters/otlp/all/src/test/java/io/opentelemetry/exporter/otlp/internal/OtlpMetricExporterProviderTest.java +++ b/exporters/otlp/all/src/test/java/io/opentelemetry/exporter/otlp/internal/OtlpMetricExporterProviderTest.java @@ -127,7 +127,7 @@ void createExporter_GrpcDefaults() { verify(grpcBuilder, never()).setTimeout(any()); verify(grpcBuilder, never()).setTrustedCertificates(any()); verify(grpcBuilder, never()).setClientTls(any(), any()); - assertThat(grpcBuilder).extracting("delegate").extracting("retryPolicy").isNull(); + assertThat(grpcBuilder).extracting("delegate").extracting("retryPolicy").isNotNull(); assertThat(exporter.getMemoryMode()).isEqualTo(MemoryMode.IMMUTABLE_DATA); } Mockito.verifyNoInteractions(httpBuilder); @@ -143,7 +143,7 @@ void createExporter_GrpcWithGeneralConfiguration() throws CertificateEncodingExc config.put("otel.exporter.otlp.headers", "header-key=header-value"); config.put("otel.exporter.otlp.compression", "gzip"); config.put("otel.exporter.otlp.timeout", "15s"); - config.put("otel.experimental.exporter.otlp.retry.enabled", "true"); + config.put("otel.java.exporter.otlp.retry.disabled", "true"); try (MetricExporter exporter = provider.createExporter(DefaultConfigProperties.createFromMap(config))) { @@ -156,7 +156,7 @@ void createExporter_GrpcWithGeneralConfiguration() throws CertificateEncodingExc verify(grpcBuilder).setTrustedCertificates(serverTls.certificate().getEncoded()); verify(grpcBuilder) .setClientTls(clientTls.privateKey().getEncoded(), clientTls.certificate().getEncoded()); - assertThat(grpcBuilder).extracting("delegate").extracting("retryPolicy").isNotNull(); + assertThat(grpcBuilder).extracting("delegate").extracting("retryPolicy").isNull(); } Mockito.verifyNoInteractions(httpBuilder); } @@ -211,7 +211,7 @@ void createExporter_HttpDefaults() { verify(httpBuilder, never()).setTimeout(any()); verify(httpBuilder, never()).setTrustedCertificates(any()); verify(httpBuilder, never()).setClientTls(any(), any()); - assertThat(httpBuilder).extracting("delegate").extracting("retryPolicy").isNull(); + assertThat(httpBuilder).extracting("delegate").extracting("retryPolicy").isNotNull(); assertThat(exporter.getMemoryMode()).isEqualTo(MemoryMode.IMMUTABLE_DATA); } Mockito.verifyNoInteractions(grpcBuilder); @@ -228,7 +228,7 @@ void createExporter_HttpWithGeneralConfiguration() throws CertificateEncodingExc config.put("otel.exporter.otlp.headers", "header-key=header-value"); config.put("otel.exporter.otlp.compression", "gzip"); config.put("otel.exporter.otlp.timeout", "15s"); - config.put("otel.experimental.exporter.otlp.retry.enabled", "true"); + config.put("otel.java.exporter.otlp.retry.disabled", "true"); try (MetricExporter exporter = provider.createExporter(DefaultConfigProperties.createFromMap(config))) { @@ -241,7 +241,7 @@ void createExporter_HttpWithGeneralConfiguration() throws CertificateEncodingExc verify(httpBuilder).setTrustedCertificates(serverTls.certificate().getEncoded()); verify(httpBuilder) .setClientTls(clientTls.privateKey().getEncoded(), clientTls.certificate().getEncoded()); - assertThat(httpBuilder).extracting("delegate").extracting("retryPolicy").isNotNull(); + assertThat(httpBuilder).extracting("delegate").extracting("retryPolicy").isNull(); } Mockito.verifyNoInteractions(grpcBuilder); } diff --git a/exporters/otlp/all/src/test/java/io/opentelemetry/exporter/otlp/internal/OtlpSpanExporterProviderTest.java b/exporters/otlp/all/src/test/java/io/opentelemetry/exporter/otlp/internal/OtlpSpanExporterProviderTest.java index b2b67b56b61..06d39054a0f 100644 --- a/exporters/otlp/all/src/test/java/io/opentelemetry/exporter/otlp/internal/OtlpSpanExporterProviderTest.java +++ b/exporters/otlp/all/src/test/java/io/opentelemetry/exporter/otlp/internal/OtlpSpanExporterProviderTest.java @@ -128,7 +128,7 @@ void createExporter_GrpcDefaults() { verify(grpcBuilder, never()).setTimeout(any()); verify(grpcBuilder, never()).setTrustedCertificates(any()); verify(grpcBuilder, never()).setClientTls(any(), any()); - assertThat(grpcBuilder).extracting("delegate").extracting("retryPolicy").isNull(); + assertThat(grpcBuilder).extracting("delegate").extracting("retryPolicy").isNotNull(); assertThat(exporter).extracting("memoryMode").isEqualTo(MemoryMode.IMMUTABLE_DATA); } Mockito.verifyNoInteractions(httpBuilder); @@ -144,7 +144,7 @@ void createExporter_GrpcWithGeneralConfiguration() throws CertificateEncodingExc config.put("otel.exporter.otlp.headers", "header-key=header-value"); config.put("otel.exporter.otlp.compression", "gzip"); config.put("otel.exporter.otlp.timeout", "15s"); - config.put("otel.experimental.exporter.otlp.retry.enabled", "true"); + config.put("otel.java.exporter.otlp.retry.disabled", "true"); try (SpanExporter exporter = provider.createExporter(DefaultConfigProperties.createFromMap(config))) { @@ -157,7 +157,7 @@ void createExporter_GrpcWithGeneralConfiguration() throws CertificateEncodingExc verify(grpcBuilder).setTrustedCertificates(serverTls.certificate().getEncoded()); verify(grpcBuilder) .setClientTls(clientTls.privateKey().getEncoded(), clientTls.certificate().getEncoded()); - assertThat(grpcBuilder).extracting("delegate").extracting("retryPolicy").isNotNull(); + assertThat(grpcBuilder).extracting("delegate").extracting("retryPolicy").isNull(); } Mockito.verifyNoInteractions(httpBuilder); } @@ -211,7 +211,7 @@ void createExporter_HttpDefaults() { verify(httpBuilder, never()).setTimeout(any()); verify(httpBuilder, never()).setTrustedCertificates(any()); verify(httpBuilder, never()).setClientTls(any(), any()); - assertThat(httpBuilder).extracting("delegate").extracting("retryPolicy").isNull(); + assertThat(httpBuilder).extracting("delegate").extracting("retryPolicy").isNotNull(); assertThat(exporter).extracting("memoryMode").isEqualTo(MemoryMode.IMMUTABLE_DATA); } Mockito.verifyNoInteractions(grpcBuilder); @@ -229,7 +229,7 @@ void createExporter_HttpWithGeneralConfiguration() throws CertificateEncodingExc "otel.exporter.otlp.headers", "header-key1=header%20value1,header-key2=header value2"); config.put("otel.exporter.otlp.compression", "gzip"); config.put("otel.exporter.otlp.timeout", "15s"); - config.put("otel.experimental.exporter.otlp.retry.enabled", "true"); + config.put("otel.java.exporter.otlp.retry.disabled", "true"); try (SpanExporter exporter = provider.createExporter(DefaultConfigProperties.createFromMap(config))) { @@ -243,7 +243,7 @@ void createExporter_HttpWithGeneralConfiguration() throws CertificateEncodingExc verify(httpBuilder).setTrustedCertificates(serverTls.certificate().getEncoded()); verify(httpBuilder) .setClientTls(clientTls.privateKey().getEncoded(), clientTls.certificate().getEncoded()); - assertThat(httpBuilder).extracting("delegate").extracting("retryPolicy").isNotNull(); + assertThat(httpBuilder).extracting("delegate").extracting("retryPolicy").isNull(); assertThat(exporter).extracting("memoryMode").isEqualTo(MemoryMode.IMMUTABLE_DATA); } Mockito.verifyNoInteractions(grpcBuilder); diff --git a/exporters/otlp/all/src/testDefaultSender/java/io/opentelemetry/exporter/otlp/http/metrics/OtlpHttpMetricExporterOkHttpSenderTest.java b/exporters/otlp/all/src/testDefaultSender/java/io/opentelemetry/exporter/otlp/http/metrics/OtlpHttpMetricExporterOkHttpSenderTest.java index a6686aa9d5d..eee09f314c5 100644 --- a/exporters/otlp/all/src/testDefaultSender/java/io/opentelemetry/exporter/otlp/http/metrics/OtlpHttpMetricExporterOkHttpSenderTest.java +++ b/exporters/otlp/all/src/testDefaultSender/java/io/opentelemetry/exporter/otlp/http/metrics/OtlpHttpMetricExporterOkHttpSenderTest.java @@ -99,6 +99,7 @@ void stringRepresentation() { + ", " + "exportAsJson=false, " + "headers=Headers\\{User-Agent=OBFUSCATED\\}, " + + "retryPolicy=RetryPolicy\\{.*\\}, " + "aggregationTemporalitySelector=AggregationTemporalitySelector\\{.*\\}, " + "defaultAggregationSelector=DefaultAggregationSelector\\{.*\\}, " + "memoryMode=IMMUTABLE_DATA" diff --git a/exporters/otlp/all/src/testDefaultSender/java/io/opentelemetry/exporter/otlp/http/trace/OtlpHttpSpanExporterOkHttpSenderTest.java b/exporters/otlp/all/src/testDefaultSender/java/io/opentelemetry/exporter/otlp/http/trace/OtlpHttpSpanExporterOkHttpSenderTest.java index dbe9f9a816a..da42bed03d8 100644 --- a/exporters/otlp/all/src/testDefaultSender/java/io/opentelemetry/exporter/otlp/http/trace/OtlpHttpSpanExporterOkHttpSenderTest.java +++ b/exporters/otlp/all/src/testDefaultSender/java/io/opentelemetry/exporter/otlp/http/trace/OtlpHttpSpanExporterOkHttpSenderTest.java @@ -48,6 +48,7 @@ void stringRepresentation() { + ", " + "exportAsJson=false, " + "headers=Headers\\{User-Agent=OBFUSCATED\\}, " + + "retryPolicy=RetryPolicy\\{.*\\}, " + "memoryMode=IMMUTABLE_DATA" + "\\}"); } diff --git a/exporters/otlp/all/src/testDefaultSender/java/io/opentelemetry/exporter/otlp/metrics/OtlpGrpcMetricExporterTest.java b/exporters/otlp/all/src/testDefaultSender/java/io/opentelemetry/exporter/otlp/metrics/OtlpGrpcMetricExporterTest.java index 7a9e52a741c..6e57cabd41c 100644 --- a/exporters/otlp/all/src/testDefaultSender/java/io/opentelemetry/exporter/otlp/metrics/OtlpGrpcMetricExporterTest.java +++ b/exporters/otlp/all/src/testDefaultSender/java/io/opentelemetry/exporter/otlp/metrics/OtlpGrpcMetricExporterTest.java @@ -99,6 +99,7 @@ void stringRepresentation() { + ", " + "compressorEncoding=null, " + "headers=Headers\\{User-Agent=OBFUSCATED\\}, " + + "retryPolicy=RetryPolicy\\{.*\\}, " + "aggregationTemporalitySelector=AggregationTemporalitySelector\\{.*\\}, " + "defaultAggregationSelector=DefaultAggregationSelector\\{.*\\}, " + "memoryMode=IMMUTABLE_DATA" diff --git a/exporters/otlp/all/src/testDefaultSender/java/io/opentelemetry/exporter/otlp/traces/OtlpGrpcSpanExporterTest.java b/exporters/otlp/all/src/testDefaultSender/java/io/opentelemetry/exporter/otlp/traces/OtlpGrpcSpanExporterTest.java index 05b8523ebd4..e54b7279cb5 100644 --- a/exporters/otlp/all/src/testDefaultSender/java/io/opentelemetry/exporter/otlp/traces/OtlpGrpcSpanExporterTest.java +++ b/exporters/otlp/all/src/testDefaultSender/java/io/opentelemetry/exporter/otlp/traces/OtlpGrpcSpanExporterTest.java @@ -48,6 +48,7 @@ void stringRepresentation() { + ", " + "compressorEncoding=null, " + "headers=Headers\\{User-Agent=OBFUSCATED\\}, " + + "retryPolicy=RetryPolicy\\{.*\\}, " + "memoryMode=IMMUTABLE_DATA" + "\\}"); } diff --git a/exporters/otlp/all/src/testJdkHttpSender/java/io/opentelemetry/exporter/otlp/http/metrics/OtlpHttpMetricExporterJdkSenderTest.java b/exporters/otlp/all/src/testJdkHttpSender/java/io/opentelemetry/exporter/otlp/http/metrics/OtlpHttpMetricExporterJdkSenderTest.java index cf08d4dc05f..4c1ad15e856 100644 --- a/exporters/otlp/all/src/testJdkHttpSender/java/io/opentelemetry/exporter/otlp/http/metrics/OtlpHttpMetricExporterJdkSenderTest.java +++ b/exporters/otlp/all/src/testJdkHttpSender/java/io/opentelemetry/exporter/otlp/http/metrics/OtlpHttpMetricExporterJdkSenderTest.java @@ -100,6 +100,7 @@ void stringRepresentation() { + ", " + "exportAsJson=false, " + "headers=Headers\\{User-Agent=OBFUSCATED\\}, " + + "retryPolicy=RetryPolicy\\{.*\\}, " + "aggregationTemporalitySelector=AggregationTemporalitySelector\\{.*\\}, " + "defaultAggregationSelector=DefaultAggregationSelector\\{.*\\}, " + "memoryMode=IMMUTABLE_DATA" diff --git a/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/AbstractGrpcTelemetryExporterTest.java b/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/AbstractGrpcTelemetryExporterTest.java index 7a8384e15e8..a62911a54b0 100644 --- a/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/AbstractGrpcTelemetryExporterTest.java +++ b/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/AbstractGrpcTelemetryExporterTest.java @@ -187,7 +187,17 @@ protected AbstractGrpcTelemetryExporterTest(String type, U resourceTelemetryInst @BeforeAll void setUp() { - exporter = exporterBuilder().setEndpoint(server.httpUri().toString()).build(); + exporter = + exporterBuilder() + .setEndpoint(server.httpUri().toString()) + // We don't validate backoff time itself in these tests, just that retries + // occur. Keep the tests fast by using minimal backoff. + .setRetryPolicy( + RetryPolicy.getDefault().toBuilder() + .setMaxAttempts(2) + .setInitialBackoff(Duration.ofMillis(1)) + .build()) + .build(); // Sanity check that TLS files are in PEM format. assertThat(certificate.certificateFile()) @@ -469,6 +479,7 @@ void connectTimeout() { // Connecting to a non-routable IP address to trigger connection error .setEndpoint("http://10.255.255.1") .setConnectTimeout(Duration.ofMillis(1)) + .setRetryPolicy(null) .build(); try { long startTimeMillis = System.currentTimeMillis(); @@ -530,121 +541,83 @@ void doubleShutdown() { @SuppressLogger(GrpcExporter.class) void error() { addGrpcError(13, null); - assertThat( - exporter - .export(Collections.singletonList(generateFakeTelemetry())) - .join(10, TimeUnit.SECONDS) - .isSuccess()) - .isFalse(); - LoggingEvent log = - logs.assertContains( - "Failed to export " - + type - + "s. Server responded with gRPC status code 13. Error message:"); - assertThat(log.getLevel()).isEqualTo(Level.WARN); + + TelemetryExporter exporter = nonRetryingExporter(); + + try { + assertThat( + exporter + .export(Collections.singletonList(generateFakeTelemetry())) + .join(10, TimeUnit.SECONDS) + .isSuccess()) + .isFalse(); + LoggingEvent log = + logs.assertContains( + "Failed to export " + + type + + "s. Server responded with gRPC status code 13. Error message:"); + assertThat(log.getLevel()).isEqualTo(Level.WARN); + } finally { + exporter.shutdown(); + } } @Test @SuppressLogger(GrpcExporter.class) void errorWithMessage() { addGrpcError(8, "out of quota"); - assertThat( - exporter - .export(Collections.singletonList(generateFakeTelemetry())) - .join(10, TimeUnit.SECONDS) - .isSuccess()) - .isFalse(); - LoggingEvent log = - logs.assertContains( - "Failed to export " - + type - + "s. Server responded with gRPC status code 8. Error message: out of quota"); - assertThat(log.getLevel()).isEqualTo(Level.WARN); + + TelemetryExporter exporter = nonRetryingExporter(); + + try { + assertThat( + exporter + .export(Collections.singletonList(generateFakeTelemetry())) + .join(10, TimeUnit.SECONDS) + .isSuccess()) + .isFalse(); + LoggingEvent log = + logs.assertContains( + "Failed to export " + + type + + "s. Server responded with gRPC status code 8. Error message: out of quota"); + assertThat(log.getLevel()).isEqualTo(Level.WARN); + } finally { + exporter.shutdown(); + } } @Test @SuppressLogger(GrpcExporter.class) void errorWithEscapedMessage() { addGrpcError(5, "クマ🐻"); - assertThat( - exporter - .export(Collections.singletonList(generateFakeTelemetry())) - .join(10, TimeUnit.SECONDS) - .isSuccess()) - .isFalse(); - LoggingEvent log = - logs.assertContains( - "Failed to export " - + type - + "s. Server responded with gRPC status code 5. Error message: クマ🐻"); - assertThat(log.getLevel()).isEqualTo(Level.WARN); - } - @Test - @SuppressLogger(GrpcExporter.class) - void testExport_Unavailable() { - addGrpcError(14, null); - assertThat( - exporter - .export(Collections.singletonList(generateFakeTelemetry())) - .join(10, TimeUnit.SECONDS) - .isSuccess()) - .isFalse(); - LoggingEvent log = - logs.assertContains( - "Failed to export " - + type - + "s. Server is UNAVAILABLE. " - + "Make sure your collector is running and reachable from this network."); - assertThat(log.getLevel()).isEqualTo(Level.ERROR); - } + TelemetryExporter exporter = nonRetryingExporter(); - @Test - @SuppressLogger(GrpcExporter.class) - void testExport_Unimplemented() { - addGrpcError(12, "UNIMPLEMENTED"); - assertThat( - exporter - .export(Collections.singletonList(generateFakeTelemetry())) - .join(10, TimeUnit.SECONDS) - .isSuccess()) - .isFalse(); - String envVar; - switch (type) { - case "span": - envVar = "OTEL_TRACES_EXPORTER"; - break; - case "metric": - envVar = "OTEL_METRICS_EXPORTER"; - break; - case "log": - envVar = "OTEL_LOGS_EXPORTER"; - break; - default: - throw new AssertionError(); + try { + assertThat( + exporter + .export(Collections.singletonList(generateFakeTelemetry())) + .join(10, TimeUnit.SECONDS) + .isSuccess()) + .isFalse(); + LoggingEvent log = + logs.assertContains( + "Failed to export " + + type + + "s. Server responded with gRPC status code 5. Error message: クマ🐻"); + assertThat(log.getLevel()).isEqualTo(Level.WARN); + } finally { + exporter.shutdown(); } - LoggingEvent log = - logs.assertContains( - "Failed to export " - + type - + "s. Server responded with UNIMPLEMENTED. " - + "This usually means that your collector is not configured with an otlp " - + "receiver in the \"pipelines\" section of the configuration. " - + "If export is not desired and you are using OpenTelemetry autoconfiguration or the javaagent, " - + "disable export by setting " - + envVar - + "=none. " - + "Full error message: UNIMPLEMENTED"); - assertThat(log.getLevel()).isEqualTo(Level.ERROR); } - @ParameterizedTest - @ValueSource(ints = {1, 4, 8, 10, 11, 14, 15}) + @Test @SuppressLogger(GrpcExporter.class) - void retryableError(int code) { - addGrpcError(code, null); + void testExport_Unavailable() { + addGrpcError(14, null); - TelemetryExporter exporter = retryingExporter(); + TelemetryExporter exporter = nonRetryingExporter(); try { assertThat( @@ -652,21 +625,25 @@ void retryableError(int code) { .export(Collections.singletonList(generateFakeTelemetry())) .join(10, TimeUnit.SECONDS) .isSuccess()) - .isTrue(); + .isFalse(); + LoggingEvent log = + logs.assertContains( + "Failed to export " + + type + + "s. Server is UNAVAILABLE. " + + "Make sure your collector is running and reachable from this network."); + assertThat(log.getLevel()).isEqualTo(Level.ERROR); } finally { exporter.shutdown(); } - - assertThat(attempts).hasValue(2); } @Test @SuppressLogger(GrpcExporter.class) - void retryableError_tooManyAttempts() { - addGrpcError(1, null); - addGrpcError(1, null); + void testExport_Unimplemented() { + addGrpcError(12, "UNIMPLEMENTED"); - TelemetryExporter exporter = retryingExporter(); + TelemetryExporter exporter = nonRetryingExporter(); try { assertThat( @@ -675,9 +652,66 @@ void retryableError_tooManyAttempts() { .join(10, TimeUnit.SECONDS) .isSuccess()) .isFalse(); + String envVar; + switch (type) { + case "span": + envVar = "OTEL_TRACES_EXPORTER"; + break; + case "metric": + envVar = "OTEL_METRICS_EXPORTER"; + break; + case "log": + envVar = "OTEL_LOGS_EXPORTER"; + break; + default: + throw new AssertionError(); + } + LoggingEvent log = + logs.assertContains( + "Failed to export " + + type + + "s. Server responded with UNIMPLEMENTED. " + + "This usually means that your collector is not configured with an otlp " + + "receiver in the \"pipelines\" section of the configuration. " + + "If export is not desired and you are using OpenTelemetry autoconfiguration or the javaagent, " + + "disable export by setting " + + envVar + + "=none. " + + "Full error message: UNIMPLEMENTED"); + assertThat(log.getLevel()).isEqualTo(Level.ERROR); } finally { exporter.shutdown(); } + } + + @ParameterizedTest + @ValueSource(ints = {1, 4, 8, 10, 11, 14, 15}) + @SuppressLogger(GrpcExporter.class) + void retryableError(int code) { + addGrpcError(code, null); + + assertThat( + exporter + .export(Collections.singletonList(generateFakeTelemetry())) + .join(10, TimeUnit.SECONDS) + .isSuccess()) + .isTrue(); + + assertThat(attempts).hasValue(2); + } + + @Test + @SuppressLogger(GrpcExporter.class) + void retryableError_tooManyAttempts() { + addGrpcError(1, null); + addGrpcError(1, null); + + assertThat( + exporter + .export(Collections.singletonList(generateFakeTelemetry())) + .join(10, TimeUnit.SECONDS) + .isSuccess()) + .isFalse(); assertThat(attempts).hasValue(2); } @@ -688,18 +722,12 @@ void retryableError_tooManyAttempts() { void nonRetryableError(int code) { addGrpcError(code, null); - TelemetryExporter exporter = retryingExporter(); - - try { - assertThat( - exporter - .export(Collections.singletonList(generateFakeTelemetry())) - .join(10, TimeUnit.SECONDS) - .isSuccess()) - .isFalse(); - } finally { - exporter.shutdown(); - } + assertThat( + exporter + .export(Collections.singletonList(generateFakeTelemetry())) + .join(10, TimeUnit.SECONDS) + .isSuccess()) + .isFalse(); assertThat(attempts).hasValue(1); } @@ -951,19 +979,8 @@ private List toProto(List telemetry) { .collect(Collectors.toList()); } - private TelemetryExporter retryingExporter() { - return exporterBuilder() - .setEndpoint(server.httpUri().toString()) - .setRetryPolicy( - RetryPolicy.builder() - .setMaxAttempts(2) - // We don't validate backoff time itself in these tests, just that retries - // occur. Keep the tests fast by using minimal backoff. - .setInitialBackoff(Duration.ofMillis(1)) - .setMaxBackoff(Duration.ofMillis(1)) - .setBackoffMultiplier(1) - .build()) - .build(); + private TelemetryExporter nonRetryingExporter() { + return exporterBuilder().setEndpoint(server.httpUri().toString()).setRetryPolicy(null).build(); } private static void addGrpcError(int code, @Nullable String message) { diff --git a/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/AbstractHttpTelemetryExporterTest.java b/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/AbstractHttpTelemetryExporterTest.java index da31843490c..befa39af5f3 100644 --- a/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/AbstractHttpTelemetryExporterTest.java +++ b/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/AbstractHttpTelemetryExporterTest.java @@ -223,7 +223,18 @@ protected AbstractHttpTelemetryExporterTest( @BeforeAll void setUp() { - exporter = exporterBuilder().setEndpoint(server.httpUri() + path).build(); + // + exporter = + exporterBuilder() + .setEndpoint(server.httpUri() + path) + // We don't validate backoff time itself in these tests, just that retries + // occur. Keep the tests fast by using minimal backoff. + .setRetryPolicy( + RetryPolicy.getDefault().toBuilder() + .setMaxAttempts(2) + .setInitialBackoff(Duration.ofMillis(1)) + .build()) + .build(); // Sanity check that TLS files are in PEM format. assertThat(certificate.certificateFile()) @@ -518,6 +529,7 @@ void connectTimeout() { // Connecting to a non-routable IP address to trigger connection error .setEndpoint("http://10.255.255.1") .setConnectTimeout(Duration.ofMillis(1)) + .setRetryPolicy(null) .build(); try { long startTimeMillis = System.currentTimeMillis(); @@ -598,18 +610,12 @@ void error() { void retryableError(int code) { addHttpError(code); - TelemetryExporter exporter = retryingExporter(); - - try { - assertThat( - exporter - .export(Collections.singletonList(generateFakeTelemetry())) - .join(10, TimeUnit.SECONDS) - .isSuccess()) - .isTrue(); - } finally { - exporter.shutdown(); - } + assertThat( + exporter + .export(Collections.singletonList(generateFakeTelemetry())) + .join(10, TimeUnit.SECONDS) + .isSuccess()) + .isTrue(); assertThat(attempts).hasValue(2); } @@ -620,18 +626,12 @@ void retryableError_tooManyAttempts() { addHttpError(502); addHttpError(502); - TelemetryExporter exporter = retryingExporter(); - - try { - assertThat( - exporter - .export(Collections.singletonList(generateFakeTelemetry())) - .join(10, TimeUnit.SECONDS) - .isSuccess()) - .isFalse(); - } finally { - exporter.shutdown(); - } + assertThat( + exporter + .export(Collections.singletonList(generateFakeTelemetry())) + .join(10, TimeUnit.SECONDS) + .isSuccess()) + .isFalse(); assertThat(attempts).hasValue(2); } @@ -642,18 +642,12 @@ void retryableError_tooManyAttempts() { void nonRetryableError(int code) { addHttpError(code); - TelemetryExporter exporter = retryingExporter(); - - try { - assertThat( - exporter - .export(Collections.singletonList(generateFakeTelemetry())) - .join(10, TimeUnit.SECONDS) - .isSuccess()) - .isFalse(); - } finally { - exporter.shutdown(); - } + assertThat( + exporter + .export(Collections.singletonList(generateFakeTelemetry())) + .join(10, TimeUnit.SECONDS) + .isSuccess()) + .isFalse(); assertThat(attempts).hasValue(1); } @@ -943,21 +937,6 @@ private List toProto(List telemetry) { .collect(Collectors.toList()); } - private TelemetryExporter retryingExporter() { - return exporterBuilder() - .setEndpoint(server.httpUri() + path) - .setRetryPolicy( - RetryPolicy.builder() - .setMaxAttempts(2) - // We don't validate backoff time itself in these tests, just that retries - // occur. Keep the tests fast by using minimal backoff. - .setInitialBackoff(Duration.ofMillis(1)) - .setMaxBackoff(Duration.ofMillis(1)) - .setBackoffMultiplier(1) - .build()) - .build(); - } - private static void addHttpError(int code) { httpErrors.add(HttpResponse.of(code)); } diff --git a/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/GrpcLogRecordExporterBuilderWrapper.java b/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/GrpcLogRecordExporterBuilderWrapper.java index 5753d4c20fb..99fabd1ecb8 100644 --- a/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/GrpcLogRecordExporterBuilderWrapper.java +++ b/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/GrpcLogRecordExporterBuilderWrapper.java @@ -15,6 +15,7 @@ import java.util.Map; import java.util.concurrent.TimeUnit; import java.util.function.Supplier; +import javax.annotation.Nullable; import javax.net.ssl.SSLContext; import javax.net.ssl.X509TrustManager; @@ -100,7 +101,7 @@ public TelemetryExporterBuilder setSslContext( } @Override - public TelemetryExporterBuilder setRetryPolicy(RetryPolicy retryPolicy) { + public TelemetryExporterBuilder setRetryPolicy(@Nullable RetryPolicy retryPolicy) { builder.setRetryPolicy(retryPolicy); return this; } diff --git a/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/GrpcMetricExporterBuilderWrapper.java b/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/GrpcMetricExporterBuilderWrapper.java index e6e44fab1cf..07d5f39dd15 100644 --- a/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/GrpcMetricExporterBuilderWrapper.java +++ b/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/GrpcMetricExporterBuilderWrapper.java @@ -15,6 +15,7 @@ import java.util.Map; import java.util.concurrent.TimeUnit; import java.util.function.Supplier; +import javax.annotation.Nullable; import javax.net.ssl.SSLContext; import javax.net.ssl.X509TrustManager; @@ -100,7 +101,7 @@ public TelemetryExporterBuilder setSslContext( } @Override - public TelemetryExporterBuilder setRetryPolicy(RetryPolicy retryPolicy) { + public TelemetryExporterBuilder setRetryPolicy(@Nullable RetryPolicy retryPolicy) { builder.setRetryPolicy(retryPolicy); return this; } diff --git a/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/GrpcSpanExporterBuilderWrapper.java b/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/GrpcSpanExporterBuilderWrapper.java index caf82b92ecf..4f728111b6b 100644 --- a/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/GrpcSpanExporterBuilderWrapper.java +++ b/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/GrpcSpanExporterBuilderWrapper.java @@ -15,6 +15,7 @@ import java.util.Map; import java.util.concurrent.TimeUnit; import java.util.function.Supplier; +import javax.annotation.Nullable; import javax.net.ssl.SSLContext; import javax.net.ssl.X509TrustManager; @@ -101,7 +102,7 @@ public TelemetryExporterBuilder setSslContext( } @Override - public TelemetryExporterBuilder setRetryPolicy(RetryPolicy retryPolicy) { + public TelemetryExporterBuilder setRetryPolicy(@Nullable RetryPolicy retryPolicy) { builder.setRetryPolicy(retryPolicy); return this; } diff --git a/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/HttpLogRecordExporterBuilderWrapper.java b/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/HttpLogRecordExporterBuilderWrapper.java index c08fc4ae232..0d9997f4644 100644 --- a/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/HttpLogRecordExporterBuilderWrapper.java +++ b/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/HttpLogRecordExporterBuilderWrapper.java @@ -14,6 +14,7 @@ import java.util.Map; import java.util.concurrent.TimeUnit; import java.util.function.Supplier; +import javax.annotation.Nullable; import javax.net.ssl.SSLContext; import javax.net.ssl.X509TrustManager; @@ -102,7 +103,7 @@ public TelemetryExporterBuilder setClientTls( } @Override - public TelemetryExporterBuilder setRetryPolicy(RetryPolicy retryPolicy) { + public TelemetryExporterBuilder setRetryPolicy(@Nullable RetryPolicy retryPolicy) { builder.setRetryPolicy(retryPolicy); return this; } diff --git a/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/HttpMetricExporterBuilderWrapper.java b/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/HttpMetricExporterBuilderWrapper.java index 9382ee247d6..a553acc5f18 100644 --- a/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/HttpMetricExporterBuilderWrapper.java +++ b/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/HttpMetricExporterBuilderWrapper.java @@ -14,6 +14,7 @@ import java.util.Map; import java.util.concurrent.TimeUnit; import java.util.function.Supplier; +import javax.annotation.Nullable; import javax.net.ssl.SSLContext; import javax.net.ssl.X509TrustManager; @@ -101,7 +102,7 @@ public TelemetryExporterBuilder setClientTls( } @Override - public TelemetryExporterBuilder setRetryPolicy(RetryPolicy retryPolicy) { + public TelemetryExporterBuilder setRetryPolicy(@Nullable RetryPolicy retryPolicy) { builder.setRetryPolicy(retryPolicy); return this; } diff --git a/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/HttpSpanExporterBuilderWrapper.java b/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/HttpSpanExporterBuilderWrapper.java index 8652d8a38cb..1efcf301813 100644 --- a/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/HttpSpanExporterBuilderWrapper.java +++ b/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/HttpSpanExporterBuilderWrapper.java @@ -14,6 +14,7 @@ import java.util.Map; import java.util.concurrent.TimeUnit; import java.util.function.Supplier; +import javax.annotation.Nullable; import javax.net.ssl.SSLContext; import javax.net.ssl.X509TrustManager; @@ -101,7 +102,7 @@ public TelemetryExporterBuilder setClientTls( } @Override - public TelemetryExporterBuilder setRetryPolicy(RetryPolicy retryPolicy) { + public TelemetryExporterBuilder setRetryPolicy(@Nullable RetryPolicy retryPolicy) { builder.setRetryPolicy(retryPolicy); return this; } diff --git a/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/ManagedChannelTelemetryExporterBuilder.java b/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/ManagedChannelTelemetryExporterBuilder.java index 4a5a8b885bc..d9fc98d0f8c 100644 --- a/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/ManagedChannelTelemetryExporterBuilder.java +++ b/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/ManagedChannelTelemetryExporterBuilder.java @@ -134,8 +134,11 @@ public TelemetryExporterBuilder setClientTls(byte[] privateKeyPem, byte[] cer } @Override - public TelemetryExporterBuilder setRetryPolicy(RetryPolicy retryPolicy) { + public TelemetryExporterBuilder setRetryPolicy(@Nullable RetryPolicy retryPolicy) { delegate.setRetryPolicy(retryPolicy); + if (retryPolicy == null) { + return this; + } String grpcServiceName; if (delegate instanceof GrpcLogRecordExporterBuilderWrapper) { grpcServiceName = "opentelemetry.proto.collector.logs.v1.LogsService"; diff --git a/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/TelemetryExporterBuilder.java b/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/TelemetryExporterBuilder.java index 4cbcc9f5c52..2b4b8d94d18 100644 --- a/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/TelemetryExporterBuilder.java +++ b/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/TelemetryExporterBuilder.java @@ -18,6 +18,7 @@ import java.util.Map; import java.util.concurrent.TimeUnit; import java.util.function.Supplier; +import javax.annotation.Nullable; import javax.net.ssl.SSLContext; import javax.net.ssl.X509TrustManager; @@ -59,7 +60,7 @@ static TelemetryExporterBuilder wrap(OtlpGrpcLogRecordExporterBui TelemetryExporterBuilder setSslContext(SSLContext sslContext, X509TrustManager trustManager); - TelemetryExporterBuilder setRetryPolicy(RetryPolicy retryPolicy); + TelemetryExporterBuilder setRetryPolicy(@Nullable RetryPolicy retryPolicy); TelemetryExporterBuilder setProxyOptions(ProxyOptions proxyOptions); From 35d1d383f584e3f271fd89d80567da339eaaca83 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 19 Jul 2024 19:14:28 -0700 Subject: [PATCH 489/901] Update dependency io.netty:netty-bom to v4.1.112.Final (#6595) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- dependencyManagement/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index e6728e3f66d..f55338780a3 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -15,7 +15,7 @@ val DEPENDENCY_BOMS = listOf( "com.squareup.okhttp3:okhttp-bom:4.12.0", "com.squareup.okio:okio-bom:3.9.0", // applies to transitive dependencies of okhttp "io.grpc:grpc-bom:1.65.1", - "io.netty:netty-bom:4.1.111.Final", + "io.netty:netty-bom:4.1.112.Final", "io.zipkin.brave:brave-bom:6.0.3", "io.zipkin.reporter2:zipkin-reporter-bom:3.4.0", "org.assertj:assertj-bom:3.26.3", From 685a3784d6e0938c9cc183df9c7cd5d12374993f Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 20 Jul 2024 15:53:43 -0700 Subject: [PATCH 490/901] Update errorProneVersion to v2.29.2 (#6593) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- dependencyManagement/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index f55338780a3..4592aedfa2f 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -25,7 +25,7 @@ val DEPENDENCY_BOMS = listOf( ) val autoValueVersion = "1.11.0" -val errorProneVersion = "2.29.1" +val errorProneVersion = "2.29.2" val jmhVersion = "1.37" // Mockito 5.x.x requires Java 11 https://github.com/mockito/mockito/releases/tag/v5.0.0 val mockitoVersion = "4.11.0" From 468b5289564b45b7a07c5caee3972d2038dbc6ca Mon Sep 17 00:00:00 2001 From: Abhijeet V <31417623+abvaidya@users.noreply.github.com> Date: Mon, 22 Jul 2024 12:11:19 -0700 Subject: [PATCH 491/901] Use generateCertificates() of CertificateFactory to process certificates (#6579) Signed-off-by: Abhijeet V <31417623+abvaidya@users.noreply.github.com> Co-authored-by: ET --- .../exporter/internal/TlsUtil.java | 22 ++++---- .../exporter/internal/TlsUtilTest.java | 50 +++++++++++++++++++ 2 files changed, 61 insertions(+), 11 deletions(-) diff --git a/exporters/common/src/main/java/io/opentelemetry/exporter/internal/TlsUtil.java b/exporters/common/src/main/java/io/opentelemetry/exporter/internal/TlsUtil.java index 785291635f1..17661a06eb1 100644 --- a/exporters/common/src/main/java/io/opentelemetry/exporter/internal/TlsUtil.java +++ b/exporters/common/src/main/java/io/opentelemetry/exporter/internal/TlsUtil.java @@ -20,7 +20,6 @@ import java.security.cert.Certificate; import java.security.cert.CertificateException; import java.security.cert.CertificateFactory; -import java.security.cert.X509Certificate; import java.security.spec.InvalidKeySpecException; import java.security.spec.PKCS8EncodedKeySpec; import java.util.ArrayList; @@ -77,14 +76,11 @@ public static X509KeyManager keyManager(byte[] privateKeyPem, byte[] certificate PrivateKey key = generatePrivateKey(keySpec, SUPPORTED_KEY_FACTORIES); CertificateFactory cf = CertificateFactory.getInstance("X.509"); - - List chain = new ArrayList<>(); - ByteArrayInputStream is = new ByteArrayInputStream(certificatePem); - while (is.available() > 0) { - chain.add(cf.generateCertificate(is)); - } - + // pass the input stream to generateCertificates to get a list of certificates + // generateCertificates can handle multiple certificates in a single input stream + // including PEM files with explanatory text + List chain = (List) cf.generateCertificates(is); ks.setKeyEntry("trusted", key, "".toCharArray(), chain.toArray(new Certificate[] {})); KeyManagerFactory kmf = @@ -126,9 +122,13 @@ public static X509TrustManager trustManager(byte[] trustedCertificatesPem) throw ByteArrayInputStream is = new ByteArrayInputStream(trustedCertificatesPem); CertificateFactory factory = CertificateFactory.getInstance("X.509"); int i = 0; - while (is.available() > 0) { - X509Certificate cert = (X509Certificate) factory.generateCertificate(is); - ks.setCertificateEntry("cert_" + i, cert); + // pass the input stream to generateCertificates to get a list of certificates + // generateCertificates can handle multiple certificates in a single input stream + // including PEM files with explanatory text + List certificates = + (List) factory.generateCertificates(is); + for (Certificate certificate : certificates) { + ks.setCertificateEntry("cert_" + i, certificate); i++; } diff --git a/exporters/common/src/test/java/io/opentelemetry/exporter/internal/TlsUtilTest.java b/exporters/common/src/test/java/io/opentelemetry/exporter/internal/TlsUtilTest.java index caca1dee1ab..0134fd46f2d 100644 --- a/exporters/common/src/test/java/io/opentelemetry/exporter/internal/TlsUtilTest.java +++ b/exporters/common/src/test/java/io/opentelemetry/exporter/internal/TlsUtilTest.java @@ -8,18 +8,36 @@ import static org.assertj.core.api.Assertions.assertThatCode; import com.linecorp.armeria.internal.common.util.SelfSignedCertificate; +import java.io.File; +import java.io.IOException; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.StandardOpenOption; import java.security.KeyFactory; import java.security.cert.CertificateException; import java.security.spec.PKCS8EncodedKeySpec; import java.time.Instant; import java.util.Collections; import java.util.Date; +import java.util.stream.Stream; import javax.net.ssl.SSLException; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.io.TempDir; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; class TlsUtilTest { + @TempDir private Path tempDir; + + private static final String EXPLANATORY_TEXT = + "Subject: CN=Foo\n" + + "Issuer: CN=Foo\n" + + "Validity: from 7/9/2012 3:10:38 AM UTC to 7/9/2013 3:10:37 AM UTC\n"; + private SelfSignedCertificate rsaCertificate; private SelfSignedCertificate ecCertificate; @@ -60,4 +78,36 @@ void generatePrivateKey_Invalid() { .isInstanceOf(SSLException.class) .hasMessage("Unable to generate key from supported algorithms: [EC]"); } + + /** + * Append explanatory text + * prefix and verify {@link TlsUtil#keyManager(byte[], byte[])} succeeds. + */ + @ParameterizedTest + @MethodSource("keyManagerArgs") + void keyManager_CertWithExplanatoryText(SelfSignedCertificate selfSignedCertificate) + throws IOException { + Path certificate = tempDir.resolve("certificate"); + Files.write(certificate, EXPLANATORY_TEXT.getBytes(StandardCharsets.UTF_8)); + Files.write( + certificate, + com.google.common.io.Files.toByteArray(selfSignedCertificate.certificate()), + StandardOpenOption.APPEND); + Files.write(certificate, "\n".getBytes(StandardCharsets.UTF_8), StandardOpenOption.APPEND); + + assertThatCode( + () -> + TlsUtil.keyManager( + com.google.common.io.Files.toByteArray(selfSignedCertificate.privateKey()), + com.google.common.io.Files.toByteArray(new File(certificate.toString())))) + .doesNotThrowAnyException(); + } + + private static Stream keyManagerArgs() throws CertificateException { + Instant now = Instant.now(); + return Stream.of( + Arguments.of( + new SelfSignedCertificate(Date.from(now), Date.from(now), "RSA", 2048), + new SelfSignedCertificate(Date.from(now), Date.from(now), "EC", 256))); + } } From 26b3d41d721e1e6cd054659760f902252247393c Mon Sep 17 00:00:00 2001 From: Jonathan Halliday Date: Tue, 23 Jul 2024 15:28:12 +0100 Subject: [PATCH 492/901] Add Marshalers for profiling signal type (#6565) --- .../internal/marshal/JsonSerializer.java | 5 + .../internal/marshal/MarshalerUtil.java | 68 +++++ .../internal/marshal/ProtoSerializer.java | 6 + .../exporter/internal/marshal/Serializer.java | 47 +++ exporters/otlp/common/build.gradle.kts | 1 + exporters/otlp/profiles/build.gradle.kts | 7 + .../otlp/profiles/AttributeUnitMarshaler.java | 66 +++++ .../otlp/profiles/FunctionMarshaler.java | 78 +++++ .../exporter/otlp/profiles/LineMarshaler.java | 68 +++++ .../exporter/otlp/profiles/LinkMarshaler.java | 72 +++++ .../otlp/profiles/LocationMarshaler.java | 98 +++++++ .../otlp/profiles/MappingMarshaler.java | 156 ++++++++++ .../otlp/profiles/ProfileMarshaler.java | 208 +++++++++++++ .../otlp/profiles/SampleMarshaler.java | 115 ++++++++ .../otlp/profiles/ValueTypeMarshaler.java | 84 ++++++ .../ProfilesRequestMarshalerTest.java | 273 ++++++++++++++++++ 16 files changed, 1352 insertions(+) create mode 100644 exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/AttributeUnitMarshaler.java create mode 100644 exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/FunctionMarshaler.java create mode 100644 exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/LineMarshaler.java create mode 100644 exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/LinkMarshaler.java create mode 100644 exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/LocationMarshaler.java create mode 100644 exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/MappingMarshaler.java create mode 100644 exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/ProfileMarshaler.java create mode 100644 exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/SampleMarshaler.java create mode 100644 exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/ValueTypeMarshaler.java create mode 100644 exporters/otlp/profiles/src/test/java/io/opentelemetry/exporter/otlp/profiles/ProfilesRequestMarshalerTest.java diff --git a/exporters/common/src/main/java/io/opentelemetry/exporter/internal/marshal/JsonSerializer.java b/exporters/common/src/main/java/io/opentelemetry/exporter/internal/marshal/JsonSerializer.java index 37d18598762..7d8ad3aad3f 100644 --- a/exporters/common/src/main/java/io/opentelemetry/exporter/internal/marshal/JsonSerializer.java +++ b/exporters/common/src/main/java/io/opentelemetry/exporter/internal/marshal/JsonSerializer.java @@ -81,6 +81,11 @@ protected void writeUInt64Value(long value) throws IOException { generator.writeString(Long.toString(value)); } + @Override + public void writeUInt64(ProtoFieldInfo field, long value) throws IOException { + generator.writeStringField(field.getJsonName(), Long.toString(value)); + } + @Override protected void writeFixed32(ProtoFieldInfo field, int value) throws IOException { generator.writeNumberField(field.getJsonName(), value); diff --git a/exporters/common/src/main/java/io/opentelemetry/exporter/internal/marshal/MarshalerUtil.java b/exporters/common/src/main/java/io/opentelemetry/exporter/internal/marshal/MarshalerUtil.java index 5abd24925a5..3fff240704f 100644 --- a/exporters/common/src/main/java/io/opentelemetry/exporter/internal/marshal/MarshalerUtil.java +++ b/exporters/common/src/main/java/io/opentelemetry/exporter/internal/marshal/MarshalerUtil.java @@ -129,6 +129,26 @@ public static int sizeRepeatedUInt64(ProtoFieldInfo field, long[] values) { return field.getTagSize() + CodedOutputStream.computeUInt32SizeNoTag(payloadSize) + payloadSize; } + /** + * Returns the size of a repeated uint64 field. + * + *

      Packed repeated fields contain the tag, an integer representing the incoming payload size, + * and an actual payload of repeated varints. + */ + public static int sizeRepeatedUInt64(ProtoFieldInfo field, List values) { + if (values.isEmpty()) { + return 0; + } + + int payloadSize = 0; + for (long v : values) { + payloadSize += CodedOutputStream.computeUInt64SizeNoTag(v); + } + + // tag size + payload indicator size + actual payload size + return field.getTagSize() + CodedOutputStream.computeUInt32SizeNoTag(payloadSize) + payloadSize; + } + /** * Returns the size of a repeated uint64 field. * @@ -154,6 +174,46 @@ public static int sizeRepeatedUInt64(ProtoFieldInfo field, DynamicPrimitiveLongL return field.getTagSize() + CodedOutputStream.computeUInt32SizeNoTag(payloadSize) + payloadSize; } + /** + * Returns the size of a repeated int64 field. + * + *

      Packed repeated fields contain the tag, an integer representing the incoming payload size, + * and an actual payload of repeated varints. + */ + public static int sizeRepeatedInt64(ProtoFieldInfo field, long[] values) { + if (values.length == 0) { + return 0; + } + + int payloadSize = 0; + for (long v : values) { + payloadSize += CodedOutputStream.computeInt64SizeNoTag(v); + } + + // tag size + payload indicator size + actual payload size + return field.getTagSize() + CodedOutputStream.computeUInt32SizeNoTag(payloadSize) + payloadSize; + } + + /** + * Returns the size of a repeated int64 field. + * + *

      Packed repeated fields contain the tag, an integer representing the incoming payload size, + * and an actual payload of repeated varints. + */ + public static int sizeRepeatedInt64(ProtoFieldInfo field, List values) { + if (values.isEmpty()) { + return 0; + } + + int payloadSize = 0; + for (long v : values) { + payloadSize += CodedOutputStream.computeInt64SizeNoTag(v); + } + + // tag size + payload indicator size + actual payload size + return field.getTagSize() + CodedOutputStream.computeUInt32SizeNoTag(payloadSize) + payloadSize; + } + /** Returns the size of a repeated double field. */ public static int sizeRepeatedDouble(ProtoFieldInfo field, List values) { // Same as fixed64. @@ -207,6 +267,14 @@ public static int sizeInt64(ProtoFieldInfo field, long message) { return field.getTagSize() + CodedOutputStream.computeInt64SizeNoTag(message); } + /** Returns the size of a uint64 field. */ + public static int sizeUInt64(ProtoFieldInfo field, long message) { + if (message == 0) { + return 0; + } + return field.getTagSize() + CodedOutputStream.computeUInt64SizeNoTag(message); + } + /** Returns the size of a uint32 field. */ public static int sizeUInt32(ProtoFieldInfo field, int message) { if (message == 0) { diff --git a/exporters/common/src/main/java/io/opentelemetry/exporter/internal/marshal/ProtoSerializer.java b/exporters/common/src/main/java/io/opentelemetry/exporter/internal/marshal/ProtoSerializer.java index 3149de80f6b..b71109912b2 100644 --- a/exporters/common/src/main/java/io/opentelemetry/exporter/internal/marshal/ProtoSerializer.java +++ b/exporters/common/src/main/java/io/opentelemetry/exporter/internal/marshal/ProtoSerializer.java @@ -108,6 +108,12 @@ public void writeInt64(ProtoFieldInfo field, long value) throws IOException { output.writeInt64NoTag(value); } + @Override + public void writeUInt64(ProtoFieldInfo field, long value) throws IOException { + output.writeUInt32NoTag(field.getTag()); + output.writeUInt64NoTag(value); + } + @Override protected void writeFixed64(ProtoFieldInfo field, long value) throws IOException { output.writeUInt32NoTag(field.getTag()); diff --git a/exporters/common/src/main/java/io/opentelemetry/exporter/internal/marshal/Serializer.java b/exporters/common/src/main/java/io/opentelemetry/exporter/internal/marshal/Serializer.java index 45a855ee131..205ec192e35 100644 --- a/exporters/common/src/main/java/io/opentelemetry/exporter/internal/marshal/Serializer.java +++ b/exporters/common/src/main/java/io/opentelemetry/exporter/internal/marshal/Serializer.java @@ -139,9 +139,20 @@ public void serializeInt64(ProtoFieldInfo field, long value) throws IOException writeInt64(field, value); } + /** Serializes a protobuf {@code uint64} field. */ + public void serializeUInt64(ProtoFieldInfo field, long value) throws IOException { + if (value == 0) { + return; + } + writeUInt64(field, value); + } + /** Writes a protobuf {@code int64} field, even if it matches the default value. */ public abstract void writeInt64(ProtoFieldInfo field, long value) throws IOException; + /** Writes a protobuf {@code uint64} field, even if it matches the default value. */ + public abstract void writeUInt64(ProtoFieldInfo field, long value) throws IOException; + /** Serializes a protobuf {@code fixed64} field. */ public void serializeFixed64(ProtoFieldInfo field, long value) throws IOException { if (value == 0) { @@ -340,6 +351,24 @@ public void serializeRepeatedUInt64(ProtoFieldInfo field, long[] values) throws writeEndRepeatedVarint(); } + /** Serializes a {@code repeated uint64} field. */ + public void serializeRepeatedUInt64(ProtoFieldInfo field, List values) throws IOException { + if (values.isEmpty()) { + return; + } + + int payloadSize = 0; + for (long v : values) { + payloadSize += CodedOutputStream.computeUInt64SizeNoTag(v); + } + + writeStartRepeatedVarint(field, payloadSize); + for (long value : values) { + writeUInt64Value(value); + } + writeEndRepeatedVarint(); + } + /** * Serializes a {@code repeated uint64} field. * @@ -366,6 +395,24 @@ public void serializeRepeatedUInt64(ProtoFieldInfo field, DynamicPrimitiveLongLi writeEndRepeatedVarint(); } + /** Serializes a {@code repeated int64} field. */ + public void serializeRepeatedInt64(ProtoFieldInfo field, List values) throws IOException { + if (values.isEmpty()) { + return; + } + + int payloadSize = 0; + for (long v : values) { + payloadSize += CodedOutputStream.computeInt64SizeNoTag(v); + } + + writeStartRepeatedVarint(field, payloadSize); + for (long value : values) { + writeUInt64Value(value); + } + writeEndRepeatedVarint(); + } + /** Serializes a {@code repeated double} field. */ public void serializeRepeatedDouble(ProtoFieldInfo field, List values) throws IOException { diff --git a/exporters/otlp/common/build.gradle.kts b/exporters/otlp/common/build.gradle.kts index def08665e58..67b3f86aa89 100644 --- a/exporters/otlp/common/build.gradle.kts +++ b/exporters/otlp/common/build.gradle.kts @@ -42,6 +42,7 @@ wire { "opentelemetry.proto.collector.trace.v1.ExportTraceServiceRequest", "opentelemetry.proto.collector.metrics.v1.ExportMetricsServiceRequest", "opentelemetry.proto.collector.logs.v1.ExportLogsServiceRequest", + "opentelemetry.proto.collector.profiles.v1experimental.ExportProfilesServiceRequest" ) custom { diff --git a/exporters/otlp/profiles/build.gradle.kts b/exporters/otlp/profiles/build.gradle.kts index 45b80b238a6..069d8b97033 100644 --- a/exporters/otlp/profiles/build.gradle.kts +++ b/exporters/otlp/profiles/build.gradle.kts @@ -9,8 +9,15 @@ plugins { description = "OpenTelemetry - Profiles Exporter" otelJava.moduleName.set("io.opentelemetry.exporter.otlp.profiles") +val versions: Map by project dependencies { api(project(":sdk:common")) + api(project(":exporters:common")) + implementation(project(":exporters:otlp:common")) annotationProcessor("com.google.auto.value:auto-value") + + testImplementation("com.fasterxml.jackson.core:jackson-databind") + testImplementation("com.google.protobuf:protobuf-java-util") + testImplementation("io.opentelemetry.proto:opentelemetry-proto") } diff --git a/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/AttributeUnitMarshaler.java b/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/AttributeUnitMarshaler.java new file mode 100644 index 00000000000..d3831b78ba5 --- /dev/null +++ b/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/AttributeUnitMarshaler.java @@ -0,0 +1,66 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.exporter.otlp.profiles; + +import io.opentelemetry.exporter.internal.marshal.MarshalerUtil; +import io.opentelemetry.exporter.internal.marshal.MarshalerWithSize; +import io.opentelemetry.exporter.internal.marshal.Serializer; +import io.opentelemetry.proto.profiles.v1experimental.internal.AttributeUnit; +import java.io.IOException; +import java.util.List; +import java.util.function.Consumer; + +final class AttributeUnitMarshaler extends MarshalerWithSize { + + private static final AttributeUnitMarshaler[] EMPTY_REPEATED = new AttributeUnitMarshaler[0]; + + private final long attributeKey; + private final long unitIndex; + + static AttributeUnitMarshaler create(AttributeUnitData attributeUnitData) { + return new AttributeUnitMarshaler( + attributeUnitData.getAttributeKey(), attributeUnitData.getUnitIndex()); + } + + static AttributeUnitMarshaler[] createRepeated(List items) { + if (items.isEmpty()) { + return EMPTY_REPEATED; + } + + AttributeUnitMarshaler[] attributeUnitMarshalers = new AttributeUnitMarshaler[items.size()]; + items.forEach( + item -> + new Consumer() { + int index = 0; + + @Override + public void accept(AttributeUnitData attributeUnitData) { + attributeUnitMarshalers[index++] = AttributeUnitMarshaler.create(attributeUnitData); + } + }); + return attributeUnitMarshalers; + } + + private AttributeUnitMarshaler(long attributeKey, long unitIndex) { + super(calculateSize(attributeKey, unitIndex)); + this.attributeKey = attributeKey; + this.unitIndex = unitIndex; + } + + @Override + protected void writeTo(Serializer output) throws IOException { + output.serializeInt64(AttributeUnit.ATTRIBUTE_KEY, attributeKey); + output.serializeInt64(AttributeUnit.UNIT, unitIndex); + } + + private static int calculateSize(long attributeKey, long unitIndex) { + int size; + size = 0; + size += MarshalerUtil.sizeInt64(AttributeUnit.ATTRIBUTE_KEY, attributeKey); + size += MarshalerUtil.sizeInt64(AttributeUnit.UNIT, unitIndex); + return size; + } +} diff --git a/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/FunctionMarshaler.java b/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/FunctionMarshaler.java new file mode 100644 index 00000000000..7f2a522c95f --- /dev/null +++ b/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/FunctionMarshaler.java @@ -0,0 +1,78 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.exporter.otlp.profiles; + +import io.opentelemetry.exporter.internal.marshal.MarshalerUtil; +import io.opentelemetry.exporter.internal.marshal.MarshalerWithSize; +import io.opentelemetry.exporter.internal.marshal.Serializer; +import io.opentelemetry.proto.profiles.v1experimental.internal.Function; +import java.io.IOException; +import java.util.List; +import java.util.function.Consumer; + +final class FunctionMarshaler extends MarshalerWithSize { + + private static final FunctionMarshaler[] EMPTY_REPEATED = new FunctionMarshaler[0]; + + private final long nameIndex; + private final long systemNameIndex; + private final long filenameIndex; + private final long startLine; + + static FunctionMarshaler create(FunctionData functionData) { + return new FunctionMarshaler( + functionData.getNameIndex(), + functionData.getSystemNameIndex(), + functionData.getFilenameIndex(), + functionData.getStartLine()); + } + + static FunctionMarshaler[] createRepeated(List items) { + if (items.isEmpty()) { + return EMPTY_REPEATED; + } + + FunctionMarshaler[] functionMarshalers = new FunctionMarshaler[items.size()]; + items.forEach( + item -> + new Consumer() { + int index = 0; + + @Override + public void accept(FunctionData functionData) { + functionMarshalers[index++] = FunctionMarshaler.create(functionData); + } + }); + return functionMarshalers; + } + + private FunctionMarshaler( + long nameIndex, long systemNameIndex, long filenameIndex, long startLine) { + super(calculateSize(nameIndex, systemNameIndex, filenameIndex, startLine)); + this.nameIndex = nameIndex; + this.systemNameIndex = systemNameIndex; + this.filenameIndex = filenameIndex; + this.startLine = startLine; + } + + @Override + protected void writeTo(Serializer output) throws IOException { + output.serializeInt64(Function.NAME, nameIndex); + output.serializeInt64(Function.SYSTEM_NAME, systemNameIndex); + output.serializeInt64(Function.FILENAME, filenameIndex); + output.serializeInt64(Function.START_LINE, startLine); + } + + private static int calculateSize( + long nameIndex, long systemNameIndex, long filenameIndex, long startLine) { + int size = 0; + size += MarshalerUtil.sizeInt64(Function.NAME, nameIndex); + size += MarshalerUtil.sizeInt64(Function.SYSTEM_NAME, systemNameIndex); + size += MarshalerUtil.sizeInt64(Function.FILENAME, filenameIndex); + size += MarshalerUtil.sizeInt64(Function.START_LINE, startLine); + return size; + } +} diff --git a/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/LineMarshaler.java b/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/LineMarshaler.java new file mode 100644 index 00000000000..d28aedfa5f9 --- /dev/null +++ b/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/LineMarshaler.java @@ -0,0 +1,68 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.exporter.otlp.profiles; + +import io.opentelemetry.exporter.internal.marshal.MarshalerUtil; +import io.opentelemetry.exporter.internal.marshal.MarshalerWithSize; +import io.opentelemetry.exporter.internal.marshal.Serializer; +import io.opentelemetry.proto.profiles.v1experimental.internal.Line; +import java.io.IOException; +import java.util.List; +import java.util.function.Consumer; + +final class LineMarshaler extends MarshalerWithSize { + + private static final LineMarshaler[] EMPTY_REPEATED = new LineMarshaler[0]; + + private final long functionIndex; + private final long line; + private final long column; + + static LineMarshaler create(LineData lineData) { + return new LineMarshaler(lineData.getFunctionIndex(), lineData.getLine(), lineData.getColumn()); + } + + static LineMarshaler[] createRepeated(List items) { + if (items.isEmpty()) { + return EMPTY_REPEATED; + } + + LineMarshaler[] lineMarshalers = new LineMarshaler[items.size()]; + items.forEach( + item -> + new Consumer() { + int index = 0; + + @Override + public void accept(LineData lineData) { + lineMarshalers[index++] = LineMarshaler.create(lineData); + } + }); + return lineMarshalers; + } + + private LineMarshaler(long functionIndex, long line, long column) { + super(calculateSize(functionIndex, line, column)); + this.functionIndex = functionIndex; + this.line = line; + this.column = column; + } + + @Override + protected void writeTo(Serializer output) throws IOException { + output.serializeUInt64(Line.FUNCTION_INDEX, functionIndex); + output.serializeInt64(Line.LINE, line); + output.serializeInt64(Line.COLUMN, column); + } + + private static int calculateSize(long functionIndex, long line, long column) { + int size = 0; + size += MarshalerUtil.sizeUInt64(Line.FUNCTION_INDEX, functionIndex); + size += MarshalerUtil.sizeInt64(Line.LINE, line); + size += MarshalerUtil.sizeInt64(Line.COLUMN, column); + return size; + } +} diff --git a/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/LinkMarshaler.java b/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/LinkMarshaler.java new file mode 100644 index 00000000000..13f489b32d7 --- /dev/null +++ b/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/LinkMarshaler.java @@ -0,0 +1,72 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.exporter.otlp.profiles; + +import io.opentelemetry.api.internal.OtelEncodingUtils; +import io.opentelemetry.api.trace.SpanId; +import io.opentelemetry.api.trace.TraceId; +import io.opentelemetry.exporter.internal.marshal.MarshalerUtil; +import io.opentelemetry.exporter.internal.marshal.MarshalerWithSize; +import io.opentelemetry.exporter.internal.marshal.Serializer; +import io.opentelemetry.proto.profiles.v1experimental.internal.Link; +import java.io.IOException; +import java.util.List; +import java.util.function.Consumer; + +final class LinkMarshaler extends MarshalerWithSize { + + private static final LinkMarshaler[] EMPTY_REPEATED = new LinkMarshaler[0]; + + private final byte[] traceId; + private final byte[] spanId; + + static LinkMarshaler create(LinkData linkData) { + // in tracing this conversion is handled by utility methods on SpanContext, + // but we don't have a SpanContext here... + byte[] traceId = OtelEncodingUtils.bytesFromBase16(linkData.getTraceId(), TraceId.getLength()); + byte[] spanId = OtelEncodingUtils.bytesFromBase16(linkData.getSpanId(), SpanId.getLength()); + + return new LinkMarshaler(traceId, spanId); + } + + static LinkMarshaler[] createRepeated(List items) { + if (items.isEmpty()) { + return EMPTY_REPEATED; + } + + LinkMarshaler[] linkMarshalers = new LinkMarshaler[items.size()]; + items.forEach( + item -> + new Consumer() { + int index = 0; + + @Override + public void accept(LinkData linkData) { + linkMarshalers[index++] = LinkMarshaler.create(linkData); + } + }); + return linkMarshalers; + } + + private LinkMarshaler(byte[] traceId, byte[] spanId) { + super(calculateSize(traceId, spanId)); + this.traceId = traceId; + this.spanId = spanId; + } + + @Override + protected void writeTo(Serializer output) throws IOException { + output.serializeBytes(Link.TRACE_ID, traceId); + output.serializeBytes(Link.SPAN_ID, spanId); + } + + private static int calculateSize(byte[] traceId, byte[] spanId) { + int size = 0; + size += MarshalerUtil.sizeBytes(Link.TRACE_ID, traceId); + size += MarshalerUtil.sizeBytes(Link.SPAN_ID, spanId); + return size; + } +} diff --git a/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/LocationMarshaler.java b/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/LocationMarshaler.java new file mode 100644 index 00000000000..1a62e13fa55 --- /dev/null +++ b/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/LocationMarshaler.java @@ -0,0 +1,98 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.exporter.otlp.profiles; + +import io.opentelemetry.exporter.internal.marshal.MarshalerUtil; +import io.opentelemetry.exporter.internal.marshal.MarshalerWithSize; +import io.opentelemetry.exporter.internal.marshal.Serializer; +import io.opentelemetry.proto.profiles.v1experimental.internal.Location; +import java.io.IOException; +import java.util.List; +import java.util.function.Consumer; + +final class LocationMarshaler extends MarshalerWithSize { + + private static final LocationMarshaler[] EMPTY_REPEATED = new LocationMarshaler[0]; + + private final long mappingIndex; + private final long address; + private final LineMarshaler[] lineMarshalers; + private final boolean isFolded; + private final int typeIndex; + private final List attributes; + + static LocationMarshaler create(LocationData locationData) { + return new LocationMarshaler( + locationData.getMappingIndex(), + locationData.getAddress(), + LineMarshaler.createRepeated(locationData.getLines()), + locationData.isFolded(), + locationData.getTypeIndex(), + locationData.getAttributes()); + } + + static LocationMarshaler[] createRepeated(List items) { + if (items.isEmpty()) { + return EMPTY_REPEATED; + } + + LocationMarshaler[] locationMarshalers = new LocationMarshaler[items.size()]; + items.forEach( + item -> + new Consumer() { + int index = 0; + + @Override + public void accept(LocationData locationData) { + locationMarshalers[index++] = LocationMarshaler.create(locationData); + } + }); + return locationMarshalers; + } + + private LocationMarshaler( + long mappingIndex, + long address, + LineMarshaler[] lineMarshalers, + boolean isFolded, + int typeIndex, + List attributes) { + super(calculateSize(mappingIndex, address, lineMarshalers, isFolded, typeIndex, attributes)); + this.mappingIndex = mappingIndex; + this.address = address; + this.lineMarshalers = lineMarshalers; + this.isFolded = isFolded; + this.typeIndex = typeIndex; + this.attributes = attributes; + } + + @Override + protected void writeTo(Serializer output) throws IOException { + output.serializeUInt64(Location.MAPPING_INDEX, mappingIndex); + output.serializeUInt64(Location.ADDRESS, address); + output.serializeRepeatedMessage(Location.LINE, lineMarshalers); + output.serializeBool(Location.IS_FOLDED, isFolded); + output.serializeUInt32(Location.TYPE_INDEX, typeIndex); + output.serializeRepeatedUInt64(Location.ATTRIBUTES, attributes); + } + + private static int calculateSize( + long mappingIndex, + long address, + LineMarshaler[] lineMarshalers, + boolean isFolded, + int typeIndex, + List attributes) { + int size = 0; + size += MarshalerUtil.sizeUInt64(Location.MAPPING_INDEX, mappingIndex); + size += MarshalerUtil.sizeUInt64(Location.ADDRESS, address); + size += MarshalerUtil.sizeRepeatedMessage(Location.LINE, lineMarshalers); + size += MarshalerUtil.sizeBool(Location.IS_FOLDED, isFolded); + size += MarshalerUtil.sizeUInt32(Location.TYPE_INDEX, typeIndex); + size += MarshalerUtil.sizeRepeatedUInt64(Location.ATTRIBUTES, attributes); + return size; + } +} diff --git a/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/MappingMarshaler.java b/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/MappingMarshaler.java new file mode 100644 index 00000000000..9b1615137e9 --- /dev/null +++ b/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/MappingMarshaler.java @@ -0,0 +1,156 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.exporter.otlp.profiles; + +import io.opentelemetry.exporter.internal.marshal.MarshalerUtil; +import io.opentelemetry.exporter.internal.marshal.MarshalerWithSize; +import io.opentelemetry.exporter.internal.marshal.ProtoEnumInfo; +import io.opentelemetry.exporter.internal.marshal.Serializer; +import io.opentelemetry.proto.profiles.v1experimental.internal.BuildIdKind; +import io.opentelemetry.proto.profiles.v1experimental.internal.Mapping; +import java.io.IOException; +import java.util.List; +import java.util.function.Consumer; + +final class MappingMarshaler extends MarshalerWithSize { + + private static final MappingMarshaler[] EMPTY_REPEATED = new MappingMarshaler[0]; + + private final long memoryStart; + private final long memoryLimit; + private final long fileOffset; + private final long filenameIndex; + private final long buildIdIndex; + private final ProtoEnumInfo buildIdKind; + private final List attributeIndices; + private final boolean hasFunctions; + private final boolean hasFilenames; + private final boolean hasLineNumbers; + private final boolean hasInlineFrames; + + static MappingMarshaler create(MappingData mappingData) { + ProtoEnumInfo buildKind = BuildIdKind.BUILD_ID_LINKER; + switch (mappingData.getBuildIdKind()) { + case LINKER: + buildKind = BuildIdKind.BUILD_ID_LINKER; + break; + case BINARY_HASH: + buildKind = BuildIdKind.BUILD_ID_BINARY_HASH; + break; + } + return new MappingMarshaler( + mappingData.getMemoryStart(), + mappingData.getMemoryLimit(), + mappingData.getFileOffset(), + mappingData.getFilenameIndex(), + mappingData.getBuildIdIndex(), + buildKind, + mappingData.getAttributeIndices(), + mappingData.hasFunctions(), + mappingData.hasFilenames(), + mappingData.hasLineNumbers(), + mappingData.hasInlineFrames()); + } + + static MappingMarshaler[] createRepeated(List items) { + if (items.isEmpty()) { + return EMPTY_REPEATED; + } + + MappingMarshaler[] mappingMarshalers = new MappingMarshaler[items.size()]; + items.forEach( + item -> + new Consumer() { + int index = 0; + + @Override + public void accept(MappingData mappingData) { + mappingMarshalers[index++] = MappingMarshaler.create(mappingData); + } + }); + return mappingMarshalers; + } + + private MappingMarshaler( + long memoryStart, + long memoryLimit, + long fileOffset, + long filenameIndex, + long buildIdIndex, + ProtoEnumInfo buildIdKind, + List attributeIndices, + boolean hasFunctions, + boolean hasFilenames, + boolean hasLineNumbers, + boolean hasInlineFrames) { + super( + calculateSize( + memoryStart, + memoryLimit, + fileOffset, + filenameIndex, + buildIdIndex, + buildIdKind, + attributeIndices, + hasFunctions, + hasFilenames, + hasLineNumbers, + hasInlineFrames)); + this.memoryStart = memoryStart; + this.memoryLimit = memoryLimit; + this.fileOffset = fileOffset; + this.filenameIndex = filenameIndex; + this.buildIdIndex = buildIdIndex; + this.buildIdKind = buildIdKind; + this.attributeIndices = attributeIndices; + this.hasFunctions = hasFunctions; + this.hasFilenames = hasFilenames; + this.hasLineNumbers = hasLineNumbers; + this.hasInlineFrames = hasInlineFrames; + } + + @Override + protected void writeTo(Serializer output) throws IOException { + output.serializeUInt64(Mapping.MEMORY_START, memoryStart); + output.serializeUInt64(Mapping.MEMORY_LIMIT, memoryLimit); + output.serializeUInt64(Mapping.FILE_OFFSET, fileOffset); + output.serializeInt64(Mapping.FILENAME, filenameIndex); + output.serializeInt64(Mapping.BUILD_ID, buildIdIndex); + output.serializeEnum(Mapping.BUILD_ID_KIND, buildIdKind); + output.serializeRepeatedUInt64(Mapping.ATTRIBUTES, attributeIndices); + output.serializeBool(Mapping.HAS_FUNCTIONS, hasFunctions); + output.serializeBool(Mapping.HAS_FILENAMES, hasFilenames); + output.serializeBool(Mapping.HAS_LINE_NUMBERS, hasLineNumbers); + output.serializeBool(Mapping.HAS_INLINE_FRAMES, hasInlineFrames); + } + + private static int calculateSize( + long memoryStart, + long memoryLimit, + long fileOffset, + long filenameIndex, + long buildIdIndex, + ProtoEnumInfo buildIdKind, + List attributeIndices, + boolean hasFunctions, + boolean hasFilenames, + boolean hasLineNumbers, + boolean hasInlineFrames) { + int size = 0; + size += MarshalerUtil.sizeUInt64(Mapping.MEMORY_START, memoryStart); + size += MarshalerUtil.sizeUInt64(Mapping.MEMORY_LIMIT, memoryLimit); + size += MarshalerUtil.sizeUInt64(Mapping.FILE_OFFSET, fileOffset); + size += MarshalerUtil.sizeInt64(Mapping.FILENAME, filenameIndex); + size += MarshalerUtil.sizeInt64(Mapping.BUILD_ID, buildIdIndex); + size += MarshalerUtil.sizeEnum(Mapping.BUILD_ID_KIND, buildIdKind); + size += MarshalerUtil.sizeRepeatedUInt64(Mapping.ATTRIBUTES, attributeIndices); + size += MarshalerUtil.sizeBool(Mapping.HAS_FUNCTIONS, hasFunctions); + size += MarshalerUtil.sizeBool(Mapping.HAS_FILENAMES, hasFilenames); + size += MarshalerUtil.sizeBool(Mapping.HAS_LINE_NUMBERS, hasLineNumbers); + size += MarshalerUtil.sizeBool(Mapping.HAS_INLINE_FRAMES, hasInlineFrames); + return size; + } +} diff --git a/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/ProfileMarshaler.java b/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/ProfileMarshaler.java new file mode 100644 index 00000000000..6553c598c1d --- /dev/null +++ b/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/ProfileMarshaler.java @@ -0,0 +1,208 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.exporter.otlp.profiles; + +import io.opentelemetry.exporter.internal.marshal.MarshalerUtil; +import io.opentelemetry.exporter.internal.marshal.MarshalerWithSize; +import io.opentelemetry.exporter.internal.marshal.Serializer; +import io.opentelemetry.exporter.internal.otlp.KeyValueMarshaler; +import io.opentelemetry.proto.profiles.v1experimental.internal.Profile; +import java.io.IOException; +import java.nio.charset.StandardCharsets; +import java.util.List; + +final class ProfileMarshaler extends MarshalerWithSize { + + private final ValueTypeMarshaler[] sampleTypeMarshalers; + private final SampleMarshaler[] sampleMarshalers; + private final MappingMarshaler[] mappingMarshalers; + private final LocationMarshaler[] locationMarshalers; + private final List locationIndices; + private final FunctionMarshaler[] functionMarshalers; + private final KeyValueMarshaler[] attributeMarshalers; + private final AttributeUnitMarshaler[] attributeUnitMarshalers; + private final LinkMarshaler[] linkMarshalers; + private final byte[][] stringTable; + private final long dropFrames; + private final long keepFrames; + private final long timeNanos; + private final long durationNanos; + private final ValueTypeMarshaler periodTypeMarshaler; + private final long period; + private final List comment; + private final long defaultSampleType; + + static ProfileMarshaler create(ProfileData profileData) { + + ValueTypeMarshaler[] sampleTypeMarshalers = + ValueTypeMarshaler.createRepeated(profileData.getSampleTypes()); + SampleMarshaler[] sampleMarshalers = SampleMarshaler.createRepeated(profileData.getSamples()); + MappingMarshaler[] mappingMarshalers = + MappingMarshaler.createRepeated(profileData.getMappings()); + LocationMarshaler[] locationMarshalers = + LocationMarshaler.createRepeated(profileData.getLocations()); + FunctionMarshaler[] functionMarshalers = + FunctionMarshaler.createRepeated(profileData.getFunctions()); + KeyValueMarshaler[] attributeMarshalers = + KeyValueMarshaler.createForAttributes(profileData.getAttributes()); + AttributeUnitMarshaler[] attributeUnitsMarshalers = + AttributeUnitMarshaler.createRepeated(profileData.getAttributeUnits()); + LinkMarshaler[] linkMarshalers = LinkMarshaler.createRepeated(profileData.getLinks()); + ValueTypeMarshaler periodTypeMarshaler = ValueTypeMarshaler.create(profileData.getPeriodType()); + + byte[][] convertedStrings = new byte[profileData.getStringTable().size()][]; + for (int i = 0; i < profileData.getStringTable().size(); i++) { + convertedStrings[i] = profileData.getStringTable().get(i).getBytes(StandardCharsets.UTF_8); + } + + return new ProfileMarshaler( + sampleTypeMarshalers, + sampleMarshalers, + mappingMarshalers, + locationMarshalers, + profileData.getLocationIndices(), + functionMarshalers, + attributeMarshalers, + attributeUnitsMarshalers, + linkMarshalers, + convertedStrings, + profileData.getDropFrames(), + profileData.getKeepFrames(), + profileData.getTimeNanos(), + profileData.getDurationNanos(), + periodTypeMarshaler, + profileData.getPeriod(), + profileData.getComment(), + profileData.getDefaultSampleType()); + } + + private ProfileMarshaler( + ValueTypeMarshaler[] sampleTypeMarshalers, + SampleMarshaler[] sampleMarshalers, + MappingMarshaler[] mappingMarshalers, + LocationMarshaler[] locationMarshalers, + List locationIndices, + FunctionMarshaler[] functionMarshalers, + KeyValueMarshaler[] attributeMarshalers, + AttributeUnitMarshaler[] attributeUnitMarshalers, + LinkMarshaler[] linkMarshalers, + byte[][] stringTableUtf8, + long dropFrames, + long keepFrames, + long timeNanos, + long durationNanos, + ValueTypeMarshaler periodTypeMarshaler, + long period, + List comment, + long defaultSampleType) { + super( + calculateSize( + sampleTypeMarshalers, + sampleMarshalers, + mappingMarshalers, + locationMarshalers, + locationIndices, + functionMarshalers, + attributeMarshalers, + attributeUnitMarshalers, + linkMarshalers, + stringTableUtf8, + dropFrames, + keepFrames, + timeNanos, + durationNanos, + periodTypeMarshaler, + period, + comment, + defaultSampleType)); + this.sampleTypeMarshalers = sampleTypeMarshalers; + this.sampleMarshalers = sampleMarshalers; + this.mappingMarshalers = mappingMarshalers; + this.locationMarshalers = locationMarshalers; + this.locationIndices = locationIndices; + this.functionMarshalers = functionMarshalers; + this.attributeMarshalers = attributeMarshalers; + this.attributeUnitMarshalers = attributeUnitMarshalers; + this.linkMarshalers = linkMarshalers; + this.stringTable = stringTableUtf8; + this.dropFrames = dropFrames; + this.keepFrames = keepFrames; + this.timeNanos = timeNanos; + this.durationNanos = durationNanos; + this.periodTypeMarshaler = periodTypeMarshaler; + this.period = period; + this.comment = comment; + this.defaultSampleType = defaultSampleType; + } + + @Override + protected void writeTo(Serializer output) throws IOException { + output.serializeRepeatedMessage(Profile.SAMPLE_TYPE, sampleTypeMarshalers); + output.serializeRepeatedMessage(Profile.SAMPLE, sampleMarshalers); + output.serializeRepeatedMessage(Profile.MAPPING, mappingMarshalers); + output.serializeRepeatedMessage(Profile.LOCATION, locationMarshalers); + output.serializeRepeatedInt64(Profile.LOCATION_INDICES, locationIndices); + output.serializeRepeatedMessage(Profile.FUNCTION, functionMarshalers); + output.serializeRepeatedMessage(Profile.ATTRIBUTE_TABLE, attributeMarshalers); + output.serializeRepeatedMessage(Profile.ATTRIBUTE_UNITS, attributeUnitMarshalers); + output.serializeRepeatedMessage(Profile.LINK_TABLE, linkMarshalers); + for (byte[] i : stringTable) { + output.serializeString(Profile.STRING_TABLE, i); + } + output.serializeInt64(Profile.DROP_FRAMES, dropFrames); + output.serializeInt64(Profile.KEEP_FRAMES, keepFrames); + output.serializeInt64(Profile.TIME_NANOS, timeNanos); + output.serializeInt64(Profile.DURATION_NANOS, durationNanos); + output.serializeMessage(Profile.PERIOD_TYPE, periodTypeMarshaler); + output.serializeInt64(Profile.PERIOD, period); + output.serializeRepeatedInt64(Profile.COMMENT, comment); + output.serializeInt64(Profile.DEFAULT_SAMPLE_TYPE, defaultSampleType); + } + + private static int calculateSize( + ValueTypeMarshaler[] sampleTypeMarshalers, + SampleMarshaler[] sampleMarshalers, + MappingMarshaler[] mappingMarshalers, + LocationMarshaler[] locationMarshalers, + List locationIndices, + FunctionMarshaler[] functionMarshalers, + KeyValueMarshaler[] attributeMarshalers, + AttributeUnitMarshaler[] attributeUnitMarshalers, + LinkMarshaler[] linkMarshalers, + byte[][] stringTable, + long dropFrames, + long keepFrames, + long timeNanos, + long durationNanos, + ValueTypeMarshaler periodTypeMarshaler, + long period, + List comment, + long defaultSampleType) { + int size; + size = 0; + size += MarshalerUtil.sizeRepeatedMessage(Profile.SAMPLE_TYPE, sampleTypeMarshalers); + size += MarshalerUtil.sizeRepeatedMessage(Profile.SAMPLE, sampleMarshalers); + size += MarshalerUtil.sizeRepeatedMessage(Profile.MAPPING, mappingMarshalers); + size += MarshalerUtil.sizeRepeatedMessage(Profile.LOCATION, locationMarshalers); + size += MarshalerUtil.sizeRepeatedInt64(Profile.LOCATION_INDICES, locationIndices); + size += MarshalerUtil.sizeRepeatedMessage(Profile.FUNCTION, functionMarshalers); + size += MarshalerUtil.sizeRepeatedMessage(Profile.ATTRIBUTE_TABLE, attributeMarshalers); + size += MarshalerUtil.sizeRepeatedMessage(Profile.ATTRIBUTE_UNITS, attributeUnitMarshalers); + size += MarshalerUtil.sizeRepeatedMessage(Profile.LINK_TABLE, linkMarshalers); + for (byte[] i : stringTable) { + size += MarshalerUtil.sizeBytes(Profile.STRING_TABLE, i); + } + size += MarshalerUtil.sizeInt64(Profile.DROP_FRAMES, dropFrames); + size += MarshalerUtil.sizeInt64(Profile.KEEP_FRAMES, keepFrames); + size += MarshalerUtil.sizeInt64(Profile.TIME_NANOS, timeNanos); + size += MarshalerUtil.sizeInt64(Profile.DURATION_NANOS, durationNanos); + size += MarshalerUtil.sizeMessage(Profile.PERIOD_TYPE, periodTypeMarshaler); + size += MarshalerUtil.sizeInt64(Profile.PERIOD, period); + size += MarshalerUtil.sizeRepeatedInt64(Profile.COMMENT, comment); + size += MarshalerUtil.sizeInt64(Profile.DEFAULT_SAMPLE_TYPE, defaultSampleType); + return size; + } +} diff --git a/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/SampleMarshaler.java b/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/SampleMarshaler.java new file mode 100644 index 00000000000..0c9cd4ae71e --- /dev/null +++ b/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/SampleMarshaler.java @@ -0,0 +1,115 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.exporter.otlp.profiles; + +import io.opentelemetry.exporter.internal.marshal.MarshalerUtil; +import io.opentelemetry.exporter.internal.marshal.MarshalerWithSize; +import io.opentelemetry.exporter.internal.marshal.Serializer; +import io.opentelemetry.proto.profiles.v1experimental.internal.Sample; +import java.io.IOException; +import java.util.List; +import java.util.function.Consumer; + +final class SampleMarshaler extends MarshalerWithSize { + + private static final SampleMarshaler[] EMPTY_REPEATED = new SampleMarshaler[0]; + + private final long locationsStartIndex; + private final long locationsLength; + private final int stacktraceIdIndex; + private final List values; + private final List attributes; + private final long link; + private final List timestamps; + + static SampleMarshaler create(SampleData sampleData) { + + return new SampleMarshaler( + sampleData.getLocationsStartIndex(), + sampleData.getLocationsLength(), + sampleData.getStacktraceIdIndex(), + sampleData.getValues(), + sampleData.getAttributes(), + sampleData.getLink(), + sampleData.getTimestamps()); + } + + static SampleMarshaler[] createRepeated(List items) { + if (items.isEmpty()) { + return EMPTY_REPEATED; + } + + SampleMarshaler[] sampleMarshalers = new SampleMarshaler[items.size()]; + items.forEach( + item -> + new Consumer() { + int index = 0; + + @Override + public void accept(SampleData sampleData) { + sampleMarshalers[index++] = SampleMarshaler.create(sampleData); + } + }); + return sampleMarshalers; + } + + private SampleMarshaler( + long locationsStartIndex, + long locationsLength, + int stacktraceIdIndex, + List values, + List attributes, + long link, + List timestamps) { + super( + calculateSize( + locationsStartIndex, + locationsLength, + stacktraceIdIndex, + values, + attributes, + link, + timestamps)); + this.locationsStartIndex = locationsStartIndex; + this.locationsLength = locationsLength; + this.stacktraceIdIndex = stacktraceIdIndex; + this.values = values; + this.attributes = attributes; + this.link = link; + this.timestamps = timestamps; + } + + @Override + protected void writeTo(Serializer output) throws IOException { + output.serializeUInt64(Sample.LOCATIONS_START_INDEX, locationsStartIndex); + output.serializeUInt64(Sample.LOCATIONS_LENGTH, locationsLength); + output.serializeUInt32(Sample.STACKTRACE_ID_INDEX, stacktraceIdIndex); + output.serializeRepeatedInt64(Sample.VALUE, values); + output.serializeRepeatedUInt64(Sample.ATTRIBUTES, attributes); + output.serializeUInt64(Sample.LINK, link); + output.serializeRepeatedUInt64(Sample.TIMESTAMPS_UNIX_NANO, timestamps); + } + + private static int calculateSize( + long locationsStartIndex, + long locationsLength, + int stacktraceIdIndex, + List values, + List attributes, + long link, + List timestamps) { + int size; + size = 0; + size += MarshalerUtil.sizeUInt64(Sample.LOCATIONS_START_INDEX, locationsStartIndex); + size += MarshalerUtil.sizeUInt64(Sample.LOCATIONS_LENGTH, locationsLength); + size += MarshalerUtil.sizeUInt32(Sample.STACKTRACE_ID_INDEX, stacktraceIdIndex); + size += MarshalerUtil.sizeRepeatedInt64(Sample.VALUE, values); + size += MarshalerUtil.sizeRepeatedUInt64(Sample.ATTRIBUTES, attributes); + size += MarshalerUtil.sizeUInt64(Sample.LINK, link); + size += MarshalerUtil.sizeRepeatedUInt64(Sample.TIMESTAMPS_UNIX_NANO, timestamps); + return size; + } +} diff --git a/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/ValueTypeMarshaler.java b/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/ValueTypeMarshaler.java new file mode 100644 index 00000000000..e880b3dded9 --- /dev/null +++ b/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/ValueTypeMarshaler.java @@ -0,0 +1,84 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.exporter.otlp.profiles; + +import io.opentelemetry.exporter.internal.marshal.MarshalerUtil; +import io.opentelemetry.exporter.internal.marshal.MarshalerWithSize; +import io.opentelemetry.exporter.internal.marshal.ProtoEnumInfo; +import io.opentelemetry.exporter.internal.marshal.Serializer; +import io.opentelemetry.proto.profiles.v1experimental.internal.AggregationTemporality; +import io.opentelemetry.proto.profiles.v1experimental.internal.ValueType; +import java.io.IOException; +import java.util.List; +import java.util.function.Consumer; + +final class ValueTypeMarshaler extends MarshalerWithSize { + + private static final ValueTypeMarshaler[] EMPTY_REPEATED = new ValueTypeMarshaler[0]; + + private final long type; + private final long unit; + private final ProtoEnumInfo aggregationTemporality; + + static ValueTypeMarshaler create(ValueTypeData valueTypeData) { + ProtoEnumInfo aggregationTemporality = + AggregationTemporality.AGGREGATION_TEMPORALITY_UNSPECIFIED; + if (valueTypeData.aggregationTemporality() != null) { + switch (valueTypeData.aggregationTemporality()) { + case DELTA: + aggregationTemporality = AggregationTemporality.AGGREGATION_TEMPORALITY_DELTA; + break; + case CUMULATIVE: + aggregationTemporality = AggregationTemporality.AGGREGATION_TEMPORALITY_CUMULATIVE; + break; + } + } + return new ValueTypeMarshaler( + valueTypeData.type(), valueTypeData.unit(), aggregationTemporality); + } + + static ValueTypeMarshaler[] createRepeated(List items) { + if (items.isEmpty()) { + return EMPTY_REPEATED; + } + + ValueTypeMarshaler[] valueTypeMarshalers = new ValueTypeMarshaler[items.size()]; + items.forEach( + item -> + new Consumer() { + int index = 0; + + @Override + public void accept(ValueTypeData valueTypeData) { + valueTypeMarshalers[index++] = ValueTypeMarshaler.create(valueTypeData); + } + }); + return valueTypeMarshalers; + } + + private ValueTypeMarshaler(long type, long unit, ProtoEnumInfo aggregationTemporality) { + super(calculateSize(type, unit, aggregationTemporality)); + this.type = type; + this.unit = unit; + this.aggregationTemporality = aggregationTemporality; + } + + @Override + protected void writeTo(Serializer output) throws IOException { + output.serializeInt64(ValueType.TYPE, type); + output.serializeInt64(ValueType.UNIT, unit); + output.serializeEnum(ValueType.AGGREGATION_TEMPORALITY, aggregationTemporality); + } + + private static int calculateSize(long type, long unit, ProtoEnumInfo aggregationTemporality) { + int size; + size = 0; + size += MarshalerUtil.sizeInt64(ValueType.TYPE, type); + size += MarshalerUtil.sizeInt64(ValueType.UNIT, unit); + size += MarshalerUtil.sizeEnum(ValueType.AGGREGATION_TEMPORALITY, aggregationTemporality); + return size; + } +} diff --git a/exporters/otlp/profiles/src/test/java/io/opentelemetry/exporter/otlp/profiles/ProfilesRequestMarshalerTest.java b/exporters/otlp/profiles/src/test/java/io/opentelemetry/exporter/otlp/profiles/ProfilesRequestMarshalerTest.java new file mode 100644 index 00000000000..f4d57fe884d --- /dev/null +++ b/exporters/otlp/profiles/src/test/java/io/opentelemetry/exporter/otlp/profiles/ProfilesRequestMarshalerTest.java @@ -0,0 +1,273 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.exporter.otlp.profiles; + +import static org.assertj.core.api.Assertions.assertThat; + +import com.google.protobuf.ByteString; +import com.google.protobuf.InvalidProtocolBufferException; +import com.google.protobuf.Message; +import com.google.protobuf.util.JsonFormat; +import io.opentelemetry.api.common.Attributes; +import io.opentelemetry.exporter.internal.marshal.Marshaler; +import io.opentelemetry.exporter.otlp.internal.data.ImmutableAttributeUnitData; +import io.opentelemetry.exporter.otlp.internal.data.ImmutableFunctionData; +import io.opentelemetry.exporter.otlp.internal.data.ImmutableLineData; +import io.opentelemetry.exporter.otlp.internal.data.ImmutableLinkData; +import io.opentelemetry.exporter.otlp.internal.data.ImmutableLocationData; +import io.opentelemetry.exporter.otlp.internal.data.ImmutableMappingData; +import io.opentelemetry.exporter.otlp.internal.data.ImmutableProfileData; +import io.opentelemetry.exporter.otlp.internal.data.ImmutableSampleData; +import io.opentelemetry.exporter.otlp.internal.data.ImmutableValueTypeData; +import io.opentelemetry.proto.profiles.v1experimental.AttributeUnit; +import io.opentelemetry.proto.profiles.v1experimental.Function; +import io.opentelemetry.proto.profiles.v1experimental.Line; +import io.opentelemetry.proto.profiles.v1experimental.Link; +import io.opentelemetry.proto.profiles.v1experimental.Location; +import io.opentelemetry.proto.profiles.v1experimental.Mapping; +import io.opentelemetry.proto.profiles.v1experimental.Profile; +import io.opentelemetry.proto.profiles.v1experimental.Sample; +import io.opentelemetry.proto.profiles.v1experimental.ValueType; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.UncheckedIOException; +import java.nio.charset.StandardCharsets; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import org.junit.jupiter.api.Test; + +public class ProfilesRequestMarshalerTest { + + @Test + void compareAttributeUnitMarshaling() { + AttributeUnitData input = ImmutableAttributeUnitData.create(1, 2); + AttributeUnit builderResult = AttributeUnit.newBuilder().setAttributeKey(1).setUnit(2).build(); + + AttributeUnit roundTripResult = + parse(AttributeUnit.getDefaultInstance(), AttributeUnitMarshaler.create(input)); + assertThat(roundTripResult).isEqualTo(builderResult); + } + + @Test + void compareFunctionMarshaling() { + FunctionData input = ImmutableFunctionData.create(1, 2, 3, 4); + Function builderResult = + Function.newBuilder().setName(1).setSystemName(2).setFilename(3).setStartLine(4).build(); + + Function roundTripResult = + parse(Function.getDefaultInstance(), FunctionMarshaler.create(input)); + assertThat(roundTripResult).isEqualTo(builderResult); + } + + @Test + void compareLineMarshaling() { + LineData input = ImmutableLineData.create(1, 2, 3); + Line builderResult = Line.newBuilder().setFunctionIndex(1).setLine(2).setColumn(3).build(); + + Line roundTripResult = parse(Line.getDefaultInstance(), LineMarshaler.create(input)); + assertThat(roundTripResult).isEqualTo(builderResult); + } + + @Test + void compareLinkMarshaling() { + String traceId = "0123456789abcdef0123456789abcdef"; + String spanId = "fedcba9876543210"; + LinkData input = ImmutableLinkData.create(traceId, spanId); + Link builderResult = + Link.newBuilder() + .setTraceId(ByteString.fromHex(traceId)) + .setSpanId(ByteString.fromHex(spanId)) + .build(); + + Link roundTripResult = parse(Link.getDefaultInstance(), LinkMarshaler.create(input)); + assertThat(roundTripResult).isEqualTo(builderResult); + } + + @Test + void compareLocationMarshaling() { + LocationData input = + ImmutableLocationData.create(1, 2, Collections.emptyList(), true, 3, listOf(5L, 6L)); + Location builderResult = + Location.newBuilder() + .setMappingIndex(1) + .setAddress(2) + .setIsFolded(true) + .setTypeIndex(3) + .addAllAttributes(listOf(5L, 6L)) + .build(); + + Location roundTripResult = + parse(Location.getDefaultInstance(), LocationMarshaler.create(input)); + assertThat(roundTripResult).isEqualTo(builderResult); + } + + @Test + void compareMappingMarshaling() { + MappingData input = + ImmutableMappingData.create( + 1, 2, 3, 4, 5, BuildIdKind.LINKER, listOf(6L, 7L), true, true, true, true); + Mapping builderResult = + Mapping.newBuilder() + .setMemoryStart(1) + .setMemoryLimit(2) + .setFileOffset(3) + .setFilename(4) + .setBuildId(5) + .setBuildIdKind( + io.opentelemetry.proto.profiles.v1experimental.BuildIdKind.BUILD_ID_LINKER) + .addAllAttributes(listOf(6L, 7L)) + .setHasFunctions(true) + .setHasFilenames(true) + .setHasLineNumbers(true) + .setHasInlineFrames(true) + .build(); + + Mapping roundTripResult = parse(Mapping.getDefaultInstance(), MappingMarshaler.create(input)); + assertThat(roundTripResult).isEqualTo(builderResult); + } + + @Test + void compareProfileMarshaling() { + ProfileData input = + ImmutableProfileData.create( + Collections.emptyList(), + Collections.emptyList(), + Collections.emptyList(), + Collections.emptyList(), + listOf(1L, 2L), + Collections.emptyList(), + Attributes.empty(), + Collections.emptyList(), + Collections.emptyList(), + Collections.emptyList(), + 3, + 4, + 5, + 6, + ImmutableValueTypeData.create(1, 2, AggregationTemporality.CUMULATIVE), + 7, + listOf(8L, 9L), + 10); + Profile builderResult = + Profile.newBuilder() + .addAllLocationIndices(listOf(1L, 2L)) + .setDropFrames(3) + .setKeepFrames(4) + .setTimeNanos(5) + .setDurationNanos(6) + .setPeriod(7) + .setPeriodType( + ValueType.newBuilder() + .setType(1) + .setUnit(2) + .setAggregationTemporality( + io.opentelemetry.proto.profiles.v1experimental.AggregationTemporality + .AGGREGATION_TEMPORALITY_CUMULATIVE) + .build()) + .addAllComment(listOf(8L, 9L)) + .setDefaultSampleType(10) + .build(); + + Profile roundTripResult = parse(Profile.getDefaultInstance(), ProfileMarshaler.create(input)); + assertThat(roundTripResult).isEqualTo(builderResult); + } + + @Test + void compareSampleMarshaling() { + SampleData input = + ImmutableSampleData.create(1, 2, 3, listOf(4L, 5L), listOf(6L, 7L), 8L, listOf(9L, 10L)); + Sample builderResult = + Sample.newBuilder() + .setLocationsStartIndex(1) + .setLocationsLength(2) + .setStacktraceIdIndex(3) + .addAllValue(listOf(4L, 5L)) + .addAllAttributes(listOf(6L, 7L)) + .setLink(8) + .addAllTimestampsUnixNano(listOf(9L, 10L)) + .build(); + + Sample roundTripResult = parse(Sample.getDefaultInstance(), SampleMarshaler.create(input)); + assertThat(roundTripResult).isEqualTo(builderResult); + } + + @Test + void compareValueTypeMarshaling() { + ValueTypeData input = ImmutableValueTypeData.create(1, 2, AggregationTemporality.CUMULATIVE); + ValueType builderResult = + ValueType.newBuilder() + .setType(1) + .setUnit(2) + .setAggregationTemporality( + io.opentelemetry.proto.profiles.v1experimental.AggregationTemporality + .AGGREGATION_TEMPORALITY_CUMULATIVE) + .build(); + + ValueType roundTripResult = + parse(ValueType.getDefaultInstance(), ValueTypeMarshaler.create(input)); + assertThat(roundTripResult).isEqualTo(builderResult); + } + + private static List listOf(T a, T b) { + ArrayList list = new ArrayList<>(); + list.add(a); + list.add(b); + return Collections.unmodifiableList(list); + } + + @SuppressWarnings("unchecked") + private static T parse(T prototype, Marshaler marshaler) { + byte[] serialized = toByteArray(marshaler); + T result; + try { + result = (T) prototype.newBuilderForType().mergeFrom(serialized).build(); + } catch (InvalidProtocolBufferException e) { + throw new UncheckedIOException(e); + } + // Our marshaler should produce the exact same length of serialized output (for example, field + // default values are not outputted), so we check that here. The output itself may have slightly + // different ordering, mostly due to the way we don't output oneof values in field order all the + // tieme. If the lengths are equal and the resulting protos are equal, the marshaling is + // guaranteed to be valid. + assertThat(result.getSerializedSize()).isEqualTo(serialized.length); + + // We don't compare JSON strings due to some differences (particularly serializing enums as + // numbers instead of names). This may improve in the future but what matters is what we produce + // can be parsed. + String json = toJson(marshaler); + Message.Builder builder = prototype.newBuilderForType(); + try { + JsonFormat.parser().merge(json, builder); + } catch (InvalidProtocolBufferException e) { + throw new UncheckedIOException(e); + } + + assertThat(builder.build()).isEqualTo(result); + + return result; + } + + private static byte[] toByteArray(Marshaler marshaler) { + ByteArrayOutputStream bos = new ByteArrayOutputStream(); + try { + marshaler.writeBinaryTo(bos); + } catch (IOException e) { + throw new UncheckedIOException(e); + } + return bos.toByteArray(); + } + + private static String toJson(Marshaler marshaler) { + ByteArrayOutputStream bos = new ByteArrayOutputStream(); + try { + marshaler.writeJsonTo(bos); + } catch (IOException e) { + throw new UncheckedIOException(e); + } + return new String(bos.toByteArray(), StandardCharsets.UTF_8); + } +} From be91b6fac1cebea25b4189b27df2f0b4d80834ee Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 27 Jul 2024 17:24:31 -0700 Subject: [PATCH 493/901] Update plugin com.gradle.develocity to v3.17.6 (#6597) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- settings.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/settings.gradle.kts b/settings.gradle.kts index f6a1bd2c7c2..93b2663ff18 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -1,7 +1,7 @@ pluginManagement { plugins { id("com.github.johnrengelman.shadow") version "8.1.1" - id("com.gradle.develocity") version "3.17.5" + id("com.gradle.develocity") version "3.17.6" id("de.undercouch.download") version "5.6.0" id("org.jsonschema2pojo") version "1.2.1" id("io.github.gradle-nexus.publish-plugin") version "2.0.0" From c43835970c1165a6667808125581397ed27652fc Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sun, 28 Jul 2024 18:11:24 -0700 Subject: [PATCH 494/901] Update dependency com.toasttab.android:gummy-bears-api-21 to v0.9.0 (#6600) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- animal-sniffer-signature/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/animal-sniffer-signature/build.gradle.kts b/animal-sniffer-signature/build.gradle.kts index 45ccf60f0a3..4e927a9b63a 100644 --- a/animal-sniffer-signature/build.gradle.kts +++ b/animal-sniffer-signature/build.gradle.kts @@ -27,7 +27,7 @@ configurations.add(signatureJarClasspath) configurations.add(generatedSignature) dependencies { - signature("com.toasttab.android:gummy-bears-api-21:0.8.0@signature") + signature("com.toasttab.android:gummy-bears-api-21:0.9.0@signature") signatureJar("com.android.tools:desugar_jdk_libs") } From 1b5ce82b0aabf89b4301a29c76a9dec2a28c8603 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 30 Jul 2024 09:34:54 -0500 Subject: [PATCH 495/901] Update dependency com.uber.nullaway:nullaway to v0.11.1 (#6608) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- dependencyManagement/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index 4592aedfa2f..ff5253706c0 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -60,7 +60,7 @@ val DEPENDENCIES = listOf( "com.google.guava:guava-beta-checker:1.0", "com.sun.net.httpserver:http:20070405", "com.tngtech.archunit:archunit-junit5:1.3.0", - "com.uber.nullaway:nullaway:0.11.0", + "com.uber.nullaway:nullaway:0.11.1", "edu.berkeley.cs.jqf:jqf-fuzz:1.7", // jqf-fuzz version 1.8+ requires Java 11+ "eu.rekawek.toxiproxy:toxiproxy-java:2.1.7", "io.github.netmikey.logunit:logunit-jul:2.0.0", From ea14b9282b04a589f4055d76668978d73f535384 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 30 Jul 2024 09:35:14 -0500 Subject: [PATCH 496/901] Update dependency com.google.api.grpc:proto-google-common-protos to v2.42.0 (#6605) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- dependencyManagement/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index ff5253706c0..824b9326c06 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -55,7 +55,7 @@ val DEPENDENCIES = listOf( "io.prometheus:simpleclient_httpserver:${prometheusClientVersion}", "javax.annotation:javax.annotation-api:1.3.2", "com.github.stefanbirkner:system-rules:1.19.0", - "com.google.api.grpc:proto-google-common-protos:2.41.0", + "com.google.api.grpc:proto-google-common-protos:2.42.0", "com.google.code.findbugs:jsr305:3.0.2", "com.google.guava:guava-beta-checker:1.0", "com.sun.net.httpserver:http:20070405", From 3a597446b34d212e55a110d6f288586fed35a7de Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 30 Jul 2024 09:36:45 -0500 Subject: [PATCH 497/901] Update dependency com.google.protobuf:protobuf-bom to v3.25.4 (#6602) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- dependencyManagement/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index 824b9326c06..bb4af9a1f27 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -10,7 +10,7 @@ rootProject.extra["versions"] = dependencyVersions val DEPENDENCY_BOMS = listOf( "com.fasterxml.jackson:jackson-bom:2.17.2", "com.google.guava:guava-bom:33.2.1-jre", - "com.google.protobuf:protobuf-bom:3.25.3", + "com.google.protobuf:protobuf-bom:3.25.4", "com.linecorp.armeria:armeria-bom:1.29.2", "com.squareup.okhttp3:okhttp-bom:4.12.0", "com.squareup.okio:okio-bom:3.9.0", // applies to transitive dependencies of okhttp From 6fc1d216ca0f199670a1cc5b081ad764d4a043fb Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 30 Jul 2024 19:37:41 -0700 Subject: [PATCH 498/901] Update dependency com.linecorp.armeria:armeria-bom to v1.29.4 (#6606) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- dependencyManagement/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index bb4af9a1f27..88344bdb581 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -11,7 +11,7 @@ val DEPENDENCY_BOMS = listOf( "com.fasterxml.jackson:jackson-bom:2.17.2", "com.google.guava:guava-bom:33.2.1-jre", "com.google.protobuf:protobuf-bom:3.25.4", - "com.linecorp.armeria:armeria-bom:1.29.2", + "com.linecorp.armeria:armeria-bom:1.29.4", "com.squareup.okhttp3:okhttp-bom:4.12.0", "com.squareup.okio:okio-bom:3.9.0", // applies to transitive dependencies of okhttp "io.grpc:grpc-bom:1.65.1", From ea6e3ddb7e31cb3013f7fe180e2d670ecc424449 Mon Sep 17 00:00:00 2001 From: jack-berg <34418638+jack-berg@users.noreply.github.com> Date: Mon, 5 Aug 2024 11:06:27 -0500 Subject: [PATCH 499/901] Add file configuration ComponentProvider support for exporters (#6493) --- .../internal/ExporterBuilderUtil.java | 17 +++ ...oleLogRecordExporterComponentProvider.java | 36 +++++ ...onsoleMetricExporterComponentProvider.java | 36 +++++ .../ConsoleSpanExporterComponentProvider.java | 35 +++++ ...toconfigure.spi.internal.ComponentProvider | 3 + .../otlp/internal/OtlpConfigUtil.java | 134 +++++++++++++++++- ...tlpLogRecordExporterComponentProvider.java | 90 ++++++++++++ .../OtlpMetricExporterComponentProvider.java | 97 +++++++++++++ .../OtlpSpanExporterComponentProvider.java | 89 ++++++++++++ ...toconfigure.spi.internal.ComponentProvider | 3 + .../ZipkinSpanExporterComponentProvider.java | 48 +++++++ ...toconfigure.spi.internal.ComponentProvider | 1 + .../spi/internal/ComponentProvider.java | 7 +- .../sdk/autoconfigure/internal/SpiHelper.java | 51 +++++++ .../autoconfigure/FileConfigurationTest.java | 3 +- .../incubator/fileconfig/FileConfigUtil.java | 40 +----- .../fileconfig/LogRecordExporterFactory.java | 88 ++++-------- .../fileconfig/LogRecordProcessorFactory.java | 22 ++- .../fileconfig/MetricExporterFactory.java | 102 +++---------- .../fileconfig/MetricReaderFactory.java | 5 +- .../fileconfig/SpanExporterFactory.java | 117 ++++----------- .../fileconfig/SpanProcessorFactory.java | 23 ++- .../FileConfigurationCreateTest.java | 3 +- .../LogRecordExporterFactoryTest.java | 101 +++++++------ .../LogRecordProcessorFactoryTest.java | 44 +++--- .../fileconfig/MetricExporterFactoryTest.java | 108 +++++++------- .../fileconfig/SpanExporterFactoryTest.java | 127 +++++++++-------- .../fileconfig/SpanProcessorFactoryTest.java | 44 +++--- .../LogRecordExporterComponentProvider.java | 54 +++++++ .../MetricExporterComponentProvider.java | 63 ++++++++ .../SpanExporterComponentProvider.java | 54 +++++++ ...toconfigure.spi.internal.ComponentProvider | 3 + 32 files changed, 1137 insertions(+), 511 deletions(-) create mode 100644 exporters/logging/src/main/java/io/opentelemetry/exporter/logging/internal/ConsoleLogRecordExporterComponentProvider.java create mode 100644 exporters/logging/src/main/java/io/opentelemetry/exporter/logging/internal/ConsoleMetricExporterComponentProvider.java create mode 100644 exporters/logging/src/main/java/io/opentelemetry/exporter/logging/internal/ConsoleSpanExporterComponentProvider.java create mode 100644 exporters/logging/src/main/resources/META-INF/services/io.opentelemetry.sdk.autoconfigure.spi.internal.ComponentProvider create mode 100644 exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/OtlpLogRecordExporterComponentProvider.java create mode 100644 exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/OtlpMetricExporterComponentProvider.java create mode 100644 exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/OtlpSpanExporterComponentProvider.java create mode 100644 exporters/otlp/all/src/main/resources/META-INF/services/io.opentelemetry.sdk.autoconfigure.spi.internal.ComponentProvider create mode 100644 exporters/zipkin/src/main/java/io/opentelemetry/exporter/zipkin/internal/ZipkinSpanExporterComponentProvider.java create mode 100644 exporters/zipkin/src/main/resources/META-INF/services/io.opentelemetry.sdk.autoconfigure.spi.internal.ComponentProvider create mode 100644 sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/component/LogRecordExporterComponentProvider.java create mode 100644 sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/component/MetricExporterComponentProvider.java create mode 100644 sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/component/SpanExporterComponentProvider.java create mode 100644 sdk-extensions/incubator/src/test/resources/META-INF/services/io.opentelemetry.sdk.autoconfigure.spi.internal.ComponentProvider diff --git a/exporters/common/src/main/java/io/opentelemetry/exporter/internal/ExporterBuilderUtil.java b/exporters/common/src/main/java/io/opentelemetry/exporter/internal/ExporterBuilderUtil.java index b19aad8e131..79256cfd788 100644 --- a/exporters/common/src/main/java/io/opentelemetry/exporter/internal/ExporterBuilderUtil.java +++ b/exporters/common/src/main/java/io/opentelemetry/exporter/internal/ExporterBuilderUtil.java @@ -7,6 +7,7 @@ import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties; import io.opentelemetry.sdk.autoconfigure.spi.ConfigurationException; +import io.opentelemetry.sdk.autoconfigure.spi.internal.StructuredConfigProperties; import io.opentelemetry.sdk.common.export.MemoryMode; import java.net.URI; import java.net.URISyntaxException; @@ -54,5 +55,21 @@ public static void configureExporterMemoryMode( memoryModeConsumer.accept(memoryMode); } + /** Invoke the {@code memoryModeConsumer} with the configured {@link MemoryMode}. */ + public static void configureExporterMemoryMode( + StructuredConfigProperties config, Consumer memoryModeConsumer) { + String memoryModeStr = config.getString("memory_mode"); + if (memoryModeStr == null) { + return; + } + MemoryMode memoryMode; + try { + memoryMode = MemoryMode.valueOf(memoryModeStr.toUpperCase(Locale.ROOT)); + } catch (IllegalArgumentException e) { + throw new ConfigurationException("Unrecognized memory_mode: " + memoryModeStr, e); + } + memoryModeConsumer.accept(memoryMode); + } + private ExporterBuilderUtil() {} } diff --git a/exporters/logging/src/main/java/io/opentelemetry/exporter/logging/internal/ConsoleLogRecordExporterComponentProvider.java b/exporters/logging/src/main/java/io/opentelemetry/exporter/logging/internal/ConsoleLogRecordExporterComponentProvider.java new file mode 100644 index 00000000000..4d03480b335 --- /dev/null +++ b/exporters/logging/src/main/java/io/opentelemetry/exporter/logging/internal/ConsoleLogRecordExporterComponentProvider.java @@ -0,0 +1,36 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.exporter.logging.internal; + +import io.opentelemetry.exporter.logging.SystemOutLogRecordExporter; +import io.opentelemetry.sdk.autoconfigure.spi.internal.ComponentProvider; +import io.opentelemetry.sdk.autoconfigure.spi.internal.StructuredConfigProperties; +import io.opentelemetry.sdk.logs.export.LogRecordExporter; + +/** + * File configuration SPI implementation for {@link SystemOutLogRecordExporter}. + * + *

      This class is internal and is hence not for public use. Its APIs are unstable and can change + * at any time. + */ +public final class ConsoleLogRecordExporterComponentProvider + implements ComponentProvider { + + @Override + public Class getType() { + return LogRecordExporter.class; + } + + @Override + public String getName() { + return "console"; + } + + @Override + public LogRecordExporter create(StructuredConfigProperties config) { + return SystemOutLogRecordExporter.create(); + } +} diff --git a/exporters/logging/src/main/java/io/opentelemetry/exporter/logging/internal/ConsoleMetricExporterComponentProvider.java b/exporters/logging/src/main/java/io/opentelemetry/exporter/logging/internal/ConsoleMetricExporterComponentProvider.java new file mode 100644 index 00000000000..48a449ff0f0 --- /dev/null +++ b/exporters/logging/src/main/java/io/opentelemetry/exporter/logging/internal/ConsoleMetricExporterComponentProvider.java @@ -0,0 +1,36 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.exporter.logging.internal; + +import io.opentelemetry.exporter.logging.LoggingMetricExporter; +import io.opentelemetry.sdk.autoconfigure.spi.internal.ComponentProvider; +import io.opentelemetry.sdk.autoconfigure.spi.internal.StructuredConfigProperties; +import io.opentelemetry.sdk.metrics.export.MetricExporter; + +/** + * File configuration SPI implementation for {@link LoggingMetricExporter}. + * + *

      This class is internal and is hence not for public use. Its APIs are unstable and can change + * at any time. + */ +public final class ConsoleMetricExporterComponentProvider + implements ComponentProvider { + + @Override + public Class getType() { + return MetricExporter.class; + } + + @Override + public String getName() { + return "console"; + } + + @Override + public MetricExporter create(StructuredConfigProperties config) { + return LoggingMetricExporter.create(); + } +} diff --git a/exporters/logging/src/main/java/io/opentelemetry/exporter/logging/internal/ConsoleSpanExporterComponentProvider.java b/exporters/logging/src/main/java/io/opentelemetry/exporter/logging/internal/ConsoleSpanExporterComponentProvider.java new file mode 100644 index 00000000000..c212a77d5d4 --- /dev/null +++ b/exporters/logging/src/main/java/io/opentelemetry/exporter/logging/internal/ConsoleSpanExporterComponentProvider.java @@ -0,0 +1,35 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.exporter.logging.internal; + +import io.opentelemetry.exporter.logging.LoggingSpanExporter; +import io.opentelemetry.sdk.autoconfigure.spi.internal.ComponentProvider; +import io.opentelemetry.sdk.autoconfigure.spi.internal.StructuredConfigProperties; +import io.opentelemetry.sdk.trace.export.SpanExporter; + +/** + * File configuration SPI implementation for {@link LoggingSpanExporter}. + * + *

      This class is internal and is hence not for public use. Its APIs are unstable and can change + * at any time. + */ +public final class ConsoleSpanExporterComponentProvider implements ComponentProvider { + + @Override + public Class getType() { + return SpanExporter.class; + } + + @Override + public String getName() { + return "console"; + } + + @Override + public SpanExporter create(StructuredConfigProperties config) { + return LoggingSpanExporter.create(); + } +} diff --git a/exporters/logging/src/main/resources/META-INF/services/io.opentelemetry.sdk.autoconfigure.spi.internal.ComponentProvider b/exporters/logging/src/main/resources/META-INF/services/io.opentelemetry.sdk.autoconfigure.spi.internal.ComponentProvider new file mode 100644 index 00000000000..ed0c3a77f5e --- /dev/null +++ b/exporters/logging/src/main/resources/META-INF/services/io.opentelemetry.sdk.autoconfigure.spi.internal.ComponentProvider @@ -0,0 +1,3 @@ +io.opentelemetry.exporter.logging.internal.ConsoleMetricExporterComponentProvider +io.opentelemetry.exporter.logging.internal.ConsoleSpanExporterComponentProvider +io.opentelemetry.exporter.logging.internal.ConsoleLogRecordExporterComponentProvider diff --git a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/OtlpConfigUtil.java b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/OtlpConfigUtil.java index 7f1214bd518..7012b1db478 100644 --- a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/OtlpConfigUtil.java +++ b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/OtlpConfigUtil.java @@ -10,6 +10,7 @@ import io.opentelemetry.exporter.internal.ExporterBuilderUtil; import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties; import io.opentelemetry.sdk.autoconfigure.spi.ConfigurationException; +import io.opentelemetry.sdk.autoconfigure.spi.internal.StructuredConfigProperties; import io.opentelemetry.sdk.common.export.MemoryMode; import io.opentelemetry.sdk.common.export.RetryPolicy; import io.opentelemetry.sdk.metrics.Aggregation; @@ -54,6 +55,11 @@ public static String getOtlpProtocol(String dataType, ConfigProperties config) { return config.getString("otel.exporter.otlp.protocol", PROTOCOL_GRPC); } + /** Determine the configured OTLP protocol for the {@code dataType}. */ + public static String getStructuredConfigOtlpProtocol(StructuredConfigProperties config) { + return config.getString("protocol", PROTOCOL_GRPC); + } + /** Invoke the setters with the OTLP configuration for the {@code dataType}. */ @SuppressWarnings("TooManyParameters") public static void configureOtlpExporterBuilder( @@ -134,9 +140,11 @@ public static void configureOtlpExporterBuilder( determinePropertyByType(config, "otel.exporter.otlp", dataType, "client.certificate")); if (clientKeyPath != null && clientKeyChainPath == null) { - throw new ConfigurationException("Client key provided but certification chain is missing"); + throw new ConfigurationException( + "client key provided without client certificate - both client key and client certificate must be set"); } else if (clientKeyPath == null && clientKeyChainPath != null) { - throw new ConfigurationException("Client key chain provided but key is missing"); + throw new ConfigurationException( + "client certificate provided without client key - both client key and client_certificate must be set"); } byte[] certificateBytes = readFileBytes(certificatePath); @@ -166,6 +174,81 @@ public static void configureOtlpExporterBuilder( ExporterBuilderUtil.configureExporterMemoryMode(config, setMemoryMode); } + /** Invoke the setters with the OTLP configuration for the {@code dataType}. */ + @SuppressWarnings("TooManyParameters") + public static void configureOtlpExporterBuilder( + String dataType, + StructuredConfigProperties config, + Consumer setEndpoint, + BiConsumer addHeader, + Consumer setCompression, + Consumer setTimeout, + Consumer setTrustedCertificates, + BiConsumer setClientTls, + Consumer setRetryPolicy, + Consumer setMemoryMode) { + String protocol = getStructuredConfigOtlpProtocol(config); + boolean isHttpProtobuf = protocol.equals(PROTOCOL_HTTP_PROTOBUF); + URL endpoint = validateEndpoint(config.getString("endpoint"), isHttpProtobuf); + if (endpoint != null && isHttpProtobuf) { + String path = endpoint.getPath(); + if (!path.endsWith("/")) { + path += "/"; + } + path += signalPath(dataType); + endpoint = createUrl(endpoint, path); + } + if (endpoint != null) { + setEndpoint.accept(endpoint.toString()); + } + + StructuredConfigProperties headers = config.getStructured("headers"); + if (headers != null) { + headers + .getPropertyKeys() + .forEach( + header -> { + String value = headers.getString(header); + if (value != null) { + addHeader.accept(header, value); + } + }); + } + + String compression = config.getString("compression"); + if (compression != null) { + setCompression.accept(compression); + } + + Integer timeoutMs = config.getInt("timeout"); + if (timeoutMs != null) { + setTimeout.accept(Duration.ofMillis(timeoutMs)); + } + + String certificatePath = config.getString("certificate"); + String clientKeyPath = config.getString("client_key"); + String clientKeyChainPath = config.getString("client_certificate"); + + if (clientKeyPath != null && clientKeyChainPath == null) { + throw new ConfigurationException( + "client_key provided without client_certificate - both client_key and client_certificate must be set"); + } else if (clientKeyPath == null && clientKeyChainPath != null) { + throw new ConfigurationException( + "client_certificate provided without client_key - both client_key and client_certificate must be set"); + } + byte[] certificateBytes = readFileBytes(certificatePath); + if (certificateBytes != null) { + setTrustedCertificates.accept(certificateBytes); + } + byte[] clientKeyBytes = readFileBytes(clientKeyPath); + byte[] clientKeyChainBytes = readFileBytes(clientKeyChainPath); + if (clientKeyBytes != null && clientKeyChainBytes != null) { + setClientTls.accept(clientKeyBytes, clientKeyChainBytes); + } + + ExporterBuilderUtil.configureExporterMemoryMode(config, setMemoryMode); + } + /** * Invoke the {@code aggregationTemporalitySelectorConsumer} with the configured {@link * AggregationTemporality}. @@ -194,6 +277,30 @@ public static void configureOtlpAggregationTemporality( aggregationTemporalitySelectorConsumer.accept(temporalitySelector); } + public static void configureOtlpAggregationTemporality( + StructuredConfigProperties config, + Consumer aggregationTemporalitySelectorConsumer) { + String temporalityStr = config.getString("temporality_preference"); + if (temporalityStr == null) { + return; + } + AggregationTemporalitySelector temporalitySelector; + switch (temporalityStr.toLowerCase(Locale.ROOT)) { + case "cumulative": + temporalitySelector = AggregationTemporalitySelector.alwaysCumulative(); + break; + case "delta": + temporalitySelector = AggregationTemporalitySelector.deltaPreferred(); + break; + case "lowmemory": + temporalitySelector = AggregationTemporalitySelector.lowMemory(); + break; + default: + throw new ConfigurationException("Unrecognized temporality_preference: " + temporalityStr); + } + aggregationTemporalitySelectorConsumer.accept(temporalitySelector); + } + /** * Invoke the {@code defaultAggregationSelectorConsumer} with the configured {@link * DefaultAggregationSelector}. @@ -218,6 +325,29 @@ public static void configureOtlpHistogramDefaultAggregation( } } + /** + * Invoke the {@code defaultAggregationSelectorConsumer} with the configured {@link + * DefaultAggregationSelector}. + */ + public static void configureOtlpHistogramDefaultAggregation( + StructuredConfigProperties config, + Consumer defaultAggregationSelectorConsumer) { + String defaultHistogramAggregation = config.getString("default_histogram_aggregation"); + if (defaultHistogramAggregation == null) { + return; + } + if (AggregationUtil.aggregationName(Aggregation.base2ExponentialBucketHistogram()) + .equalsIgnoreCase(defaultHistogramAggregation)) { + defaultAggregationSelectorConsumer.accept( + DefaultAggregationSelector.getDefault() + .with(InstrumentType.HISTOGRAM, Aggregation.base2ExponentialBucketHistogram())); + } else if (!AggregationUtil.aggregationName(explicitBucketHistogram()) + .equalsIgnoreCase(defaultHistogramAggregation)) { + throw new ConfigurationException( + "Unrecognized default_histogram_aggregation: " + defaultHistogramAggregation); + } + } + private static URL createUrl(URL context, String spec) { try { return new URL(context, spec); diff --git a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/OtlpLogRecordExporterComponentProvider.java b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/OtlpLogRecordExporterComponentProvider.java new file mode 100644 index 00000000000..cd7d97a1d46 --- /dev/null +++ b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/OtlpLogRecordExporterComponentProvider.java @@ -0,0 +1,90 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.exporter.otlp.internal; + +import static io.opentelemetry.exporter.otlp.internal.OtlpConfigUtil.DATA_TYPE_LOGS; +import static io.opentelemetry.exporter.otlp.internal.OtlpConfigUtil.PROTOCOL_GRPC; +import static io.opentelemetry.exporter.otlp.internal.OtlpConfigUtil.PROTOCOL_HTTP_PROTOBUF; + +import io.opentelemetry.exporter.otlp.http.logs.OtlpHttpLogRecordExporter; +import io.opentelemetry.exporter.otlp.http.logs.OtlpHttpLogRecordExporterBuilder; +import io.opentelemetry.exporter.otlp.logs.OtlpGrpcLogRecordExporter; +import io.opentelemetry.exporter.otlp.logs.OtlpGrpcLogRecordExporterBuilder; +import io.opentelemetry.sdk.autoconfigure.spi.ConfigurationException; +import io.opentelemetry.sdk.autoconfigure.spi.internal.ComponentProvider; +import io.opentelemetry.sdk.autoconfigure.spi.internal.StructuredConfigProperties; +import io.opentelemetry.sdk.logs.export.LogRecordExporter; + +/** + * File configuration SPI implementation for {@link OtlpHttpLogRecordExporter} and {@link + * OtlpGrpcLogRecordExporter}. + * + *

      This class is internal and is hence not for public use. Its APIs are unstable and can change + * at any time. + */ +public class OtlpLogRecordExporterComponentProvider + implements ComponentProvider { + + @Override + public Class getType() { + return LogRecordExporter.class; + } + + @Override + public String getName() { + return "otlp"; + } + + @Override + public LogRecordExporter create(StructuredConfigProperties config) { + String protocol = OtlpConfigUtil.getStructuredConfigOtlpProtocol(config); + + if (protocol.equals(PROTOCOL_HTTP_PROTOBUF)) { + OtlpHttpLogRecordExporterBuilder builder = httpBuilder(); + + OtlpConfigUtil.configureOtlpExporterBuilder( + DATA_TYPE_LOGS, + config, + builder::setEndpoint, + builder::addHeader, + builder::setCompression, + builder::setTimeout, + builder::setTrustedCertificates, + builder::setClientTls, + builder::setRetryPolicy, + builder::setMemoryMode); + + return builder.build(); + } else if (protocol.equals(PROTOCOL_GRPC)) { + OtlpGrpcLogRecordExporterBuilder builder = grpcBuilder(); + + OtlpConfigUtil.configureOtlpExporterBuilder( + DATA_TYPE_LOGS, + config, + builder::setEndpoint, + builder::addHeader, + builder::setCompression, + builder::setTimeout, + builder::setTrustedCertificates, + builder::setClientTls, + builder::setRetryPolicy, + builder::setMemoryMode); + + return builder.build(); + } + throw new ConfigurationException("Unsupported OTLP metrics protocol: " + protocol); + } + + // Visible for testing + OtlpHttpLogRecordExporterBuilder httpBuilder() { + return OtlpHttpLogRecordExporter.builder(); + } + + // Visible for testing + OtlpGrpcLogRecordExporterBuilder grpcBuilder() { + return OtlpGrpcLogRecordExporter.builder(); + } +} diff --git a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/OtlpMetricExporterComponentProvider.java b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/OtlpMetricExporterComponentProvider.java new file mode 100644 index 00000000000..bac3b205835 --- /dev/null +++ b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/OtlpMetricExporterComponentProvider.java @@ -0,0 +1,97 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.exporter.otlp.internal; + +import static io.opentelemetry.exporter.otlp.internal.OtlpConfigUtil.DATA_TYPE_METRICS; +import static io.opentelemetry.exporter.otlp.internal.OtlpConfigUtil.PROTOCOL_GRPC; +import static io.opentelemetry.exporter.otlp.internal.OtlpConfigUtil.PROTOCOL_HTTP_PROTOBUF; + +import io.opentelemetry.exporter.otlp.http.metrics.OtlpHttpMetricExporter; +import io.opentelemetry.exporter.otlp.http.metrics.OtlpHttpMetricExporterBuilder; +import io.opentelemetry.exporter.otlp.metrics.OtlpGrpcMetricExporter; +import io.opentelemetry.exporter.otlp.metrics.OtlpGrpcMetricExporterBuilder; +import io.opentelemetry.sdk.autoconfigure.spi.ConfigurationException; +import io.opentelemetry.sdk.autoconfigure.spi.internal.ComponentProvider; +import io.opentelemetry.sdk.autoconfigure.spi.internal.StructuredConfigProperties; +import io.opentelemetry.sdk.metrics.export.MetricExporter; + +/** + * File configuration SPI implementation for {@link OtlpHttpMetricExporter} and {@link + * OtlpGrpcMetricExporter}. + * + *

      This class is internal and is hence not for public use. Its APIs are unstable and can change + * at any time. + */ +public class OtlpMetricExporterComponentProvider implements ComponentProvider { + + @Override + public Class getType() { + return MetricExporter.class; + } + + @Override + public String getName() { + return "otlp"; + } + + @Override + public MetricExporter create(StructuredConfigProperties config) { + String protocol = OtlpConfigUtil.getStructuredConfigOtlpProtocol(config); + + if (protocol.equals(PROTOCOL_HTTP_PROTOBUF)) { + OtlpHttpMetricExporterBuilder builder = httpBuilder(); + + OtlpConfigUtil.configureOtlpExporterBuilder( + DATA_TYPE_METRICS, + config, + builder::setEndpoint, + builder::addHeader, + builder::setCompression, + builder::setTimeout, + builder::setTrustedCertificates, + builder::setClientTls, + builder::setRetryPolicy, + builder::setMemoryMode); + OtlpConfigUtil.configureOtlpAggregationTemporality( + config, builder::setAggregationTemporalitySelector); + OtlpConfigUtil.configureOtlpHistogramDefaultAggregation( + config, builder::setDefaultAggregationSelector); + + return builder.build(); + } else if (protocol.equals(PROTOCOL_GRPC)) { + OtlpGrpcMetricExporterBuilder builder = grpcBuilder(); + + OtlpConfigUtil.configureOtlpExporterBuilder( + DATA_TYPE_METRICS, + config, + builder::setEndpoint, + builder::addHeader, + builder::setCompression, + builder::setTimeout, + builder::setTrustedCertificates, + builder::setClientTls, + builder::setRetryPolicy, + builder::setMemoryMode); + OtlpConfigUtil.configureOtlpAggregationTemporality( + config, builder::setAggregationTemporalitySelector); + OtlpConfigUtil.configureOtlpHistogramDefaultAggregation( + config, builder::setDefaultAggregationSelector); + + return builder.build(); + } + throw new ConfigurationException("Unsupported OTLP metrics protocol: " + protocol); + } + + // Visible for testing + OtlpHttpMetricExporterBuilder httpBuilder() { + return OtlpHttpMetricExporter.builder(); + } + + // Visible for testing + OtlpGrpcMetricExporterBuilder grpcBuilder() { + return OtlpGrpcMetricExporter.builder(); + } +} diff --git a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/OtlpSpanExporterComponentProvider.java b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/OtlpSpanExporterComponentProvider.java new file mode 100644 index 00000000000..707ff0c4383 --- /dev/null +++ b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/OtlpSpanExporterComponentProvider.java @@ -0,0 +1,89 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.exporter.otlp.internal; + +import static io.opentelemetry.exporter.otlp.internal.OtlpConfigUtil.DATA_TYPE_TRACES; +import static io.opentelemetry.exporter.otlp.internal.OtlpConfigUtil.PROTOCOL_GRPC; +import static io.opentelemetry.exporter.otlp.internal.OtlpConfigUtil.PROTOCOL_HTTP_PROTOBUF; + +import io.opentelemetry.exporter.otlp.http.trace.OtlpHttpSpanExporter; +import io.opentelemetry.exporter.otlp.http.trace.OtlpHttpSpanExporterBuilder; +import io.opentelemetry.exporter.otlp.trace.OtlpGrpcSpanExporter; +import io.opentelemetry.exporter.otlp.trace.OtlpGrpcSpanExporterBuilder; +import io.opentelemetry.sdk.autoconfigure.spi.ConfigurationException; +import io.opentelemetry.sdk.autoconfigure.spi.internal.ComponentProvider; +import io.opentelemetry.sdk.autoconfigure.spi.internal.StructuredConfigProperties; +import io.opentelemetry.sdk.trace.export.SpanExporter; + +/** + * File configuration SPI implementation for {@link OtlpHttpSpanExporter} and {@link + * OtlpGrpcSpanExporter}. + * + *

      This class is internal and is hence not for public use. Its APIs are unstable and can change + * at any time. + */ +public class OtlpSpanExporterComponentProvider implements ComponentProvider { + + @Override + public Class getType() { + return SpanExporter.class; + } + + @Override + public String getName() { + return "otlp"; + } + + @Override + public SpanExporter create(StructuredConfigProperties config) { + String protocol = OtlpConfigUtil.getStructuredConfigOtlpProtocol(config); + + if (protocol.equals(PROTOCOL_HTTP_PROTOBUF)) { + OtlpHttpSpanExporterBuilder builder = httpBuilder(); + + OtlpConfigUtil.configureOtlpExporterBuilder( + DATA_TYPE_TRACES, + config, + builder::setEndpoint, + builder::addHeader, + builder::setCompression, + builder::setTimeout, + builder::setTrustedCertificates, + builder::setClientTls, + builder::setRetryPolicy, + builder::setMemoryMode); + + return builder.build(); + } else if (protocol.equals(PROTOCOL_GRPC)) { + OtlpGrpcSpanExporterBuilder builder = grpcBuilder(); + + OtlpConfigUtil.configureOtlpExporterBuilder( + DATA_TYPE_TRACES, + config, + builder::setEndpoint, + builder::addHeader, + builder::setCompression, + builder::setTimeout, + builder::setTrustedCertificates, + builder::setClientTls, + builder::setRetryPolicy, + builder::setMemoryMode); + + return builder.build(); + } + throw new ConfigurationException("Unsupported OTLP metrics protocol: " + protocol); + } + + // Visible for testing + OtlpHttpSpanExporterBuilder httpBuilder() { + return OtlpHttpSpanExporter.builder(); + } + + // Visible for testing + OtlpGrpcSpanExporterBuilder grpcBuilder() { + return OtlpGrpcSpanExporter.builder(); + } +} diff --git a/exporters/otlp/all/src/main/resources/META-INF/services/io.opentelemetry.sdk.autoconfigure.spi.internal.ComponentProvider b/exporters/otlp/all/src/main/resources/META-INF/services/io.opentelemetry.sdk.autoconfigure.spi.internal.ComponentProvider new file mode 100644 index 00000000000..239060d1f1e --- /dev/null +++ b/exporters/otlp/all/src/main/resources/META-INF/services/io.opentelemetry.sdk.autoconfigure.spi.internal.ComponentProvider @@ -0,0 +1,3 @@ +io.opentelemetry.exporter.otlp.internal.OtlpMetricExporterComponentProvider +io.opentelemetry.exporter.otlp.internal.OtlpSpanExporterComponentProvider +io.opentelemetry.exporter.otlp.internal.OtlpLogRecordExporterComponentProvider diff --git a/exporters/zipkin/src/main/java/io/opentelemetry/exporter/zipkin/internal/ZipkinSpanExporterComponentProvider.java b/exporters/zipkin/src/main/java/io/opentelemetry/exporter/zipkin/internal/ZipkinSpanExporterComponentProvider.java new file mode 100644 index 00000000000..eafd62479f0 --- /dev/null +++ b/exporters/zipkin/src/main/java/io/opentelemetry/exporter/zipkin/internal/ZipkinSpanExporterComponentProvider.java @@ -0,0 +1,48 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.exporter.zipkin.internal; + +import io.opentelemetry.exporter.zipkin.ZipkinSpanExporter; +import io.opentelemetry.exporter.zipkin.ZipkinSpanExporterBuilder; +import io.opentelemetry.sdk.autoconfigure.spi.internal.ComponentProvider; +import io.opentelemetry.sdk.autoconfigure.spi.internal.StructuredConfigProperties; +import io.opentelemetry.sdk.trace.export.SpanExporter; +import java.time.Duration; + +/** + * File configuration SPI implementation for {@link ZipkinSpanExporter}. + * + *

      This class is internal and is hence not for public use. Its APIs are unstable and can change + * at any time. + */ +public class ZipkinSpanExporterComponentProvider implements ComponentProvider { + @Override + public Class getType() { + return SpanExporter.class; + } + + @Override + public String getName() { + return "zipkin"; + } + + @Override + public SpanExporter create(StructuredConfigProperties config) { + ZipkinSpanExporterBuilder builder = ZipkinSpanExporter.builder(); + + String endpoint = config.getString("endpoint"); + if (endpoint != null) { + builder.setEndpoint(endpoint); + } + + Long timeoutMs = config.getLong("timeout"); + if (timeoutMs != null) { + builder.setReadTimeout(Duration.ofMillis(timeoutMs)); + } + + return builder.build(); + } +} diff --git a/exporters/zipkin/src/main/resources/META-INF/services/io.opentelemetry.sdk.autoconfigure.spi.internal.ComponentProvider b/exporters/zipkin/src/main/resources/META-INF/services/io.opentelemetry.sdk.autoconfigure.spi.internal.ComponentProvider new file mode 100644 index 00000000000..08330b52dad --- /dev/null +++ b/exporters/zipkin/src/main/resources/META-INF/services/io.opentelemetry.sdk.autoconfigure.spi.internal.ComponentProvider @@ -0,0 +1 @@ +io.opentelemetry.exporter.zipkin.internal.ZipkinSpanExporterComponentProvider diff --git a/sdk-extensions/autoconfigure-spi/src/main/java/io/opentelemetry/sdk/autoconfigure/spi/internal/ComponentProvider.java b/sdk-extensions/autoconfigure-spi/src/main/java/io/opentelemetry/sdk/autoconfigure/spi/internal/ComponentProvider.java index 344dc18267c..fe1e310abc9 100644 --- a/sdk-extensions/autoconfigure-spi/src/main/java/io/opentelemetry/sdk/autoconfigure/spi/internal/ComponentProvider.java +++ b/sdk-extensions/autoconfigure-spi/src/main/java/io/opentelemetry/sdk/autoconfigure/spi/internal/ComponentProvider.java @@ -5,6 +5,8 @@ package io.opentelemetry.sdk.autoconfigure.spi.internal; +import io.opentelemetry.sdk.logs.export.LogRecordExporter; +import io.opentelemetry.sdk.metrics.export.MetricExporter; import io.opentelemetry.sdk.trace.export.SpanExporter; /** @@ -12,9 +14,10 @@ * extension components which are not part of the core SDK to be referenced in file based * configuration. * - * @param the type of the SDK extension component. See {@link #getType()}. + * @param the type of the SDK extension component. See {@link #getType()}. Supported values + * include: {@link SpanExporter}, {@link MetricExporter}, {@link LogRecordExporter}. */ -// TODO (jack-berg): list the specific types which are supported in file configuration +// TODO: add support for Sampler, LogRecordProcessor, SpanProcessor, MetricReader public interface ComponentProvider { /** diff --git a/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/internal/SpiHelper.java b/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/internal/SpiHelper.java index d54e526d44a..bd3bfc13f04 100644 --- a/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/internal/SpiHelper.java +++ b/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/internal/SpiHelper.java @@ -6,8 +6,11 @@ package io.opentelemetry.sdk.autoconfigure.internal; import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties; +import io.opentelemetry.sdk.autoconfigure.spi.ConfigurationException; import io.opentelemetry.sdk.autoconfigure.spi.Ordered; import io.opentelemetry.sdk.autoconfigure.spi.internal.AutoConfigureListener; +import io.opentelemetry.sdk.autoconfigure.spi.internal.ComponentProvider; +import io.opentelemetry.sdk.autoconfigure.spi.internal.StructuredConfigProperties; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; @@ -20,6 +23,7 @@ import java.util.function.BiFunction; import java.util.function.Function; import java.util.function.Supplier; +import java.util.stream.Collectors; /** * This class is internal and is hence not for public use. Its APIs are unstable and can change at @@ -76,6 +80,53 @@ public NamedSpiManager loadConfigurable( return NamedSpiManager.create(nameToProvider); } + /** + * Find a registered {@link ComponentProvider} which {@link ComponentProvider#getType()} matching + * {@code type}, {@link ComponentProvider#getName()} matching {@code name}, and call {@link + * ComponentProvider#create(StructuredConfigProperties)} with the given {@code model}. + * + * @throws ConfigurationException if no matching providers are found, or if multiple are found + * (i.e. conflict), or if {@link ComponentProvider#create(StructuredConfigProperties)} throws + */ + @SuppressWarnings({"unchecked", "rawtypes"}) + public T loadComponent(Class type, String name, StructuredConfigProperties config) { + // TODO(jack-berg): cache loaded component providers + List componentProviders = load(ComponentProvider.class); + List> matchedProviders = + componentProviders.stream() + .map( + (Function>) + componentProvider -> componentProvider) + .filter( + componentProvider -> + componentProvider.getType() == type && name.equals(componentProvider.getName())) + .collect(Collectors.toList()); + if (matchedProviders.isEmpty()) { + throw new ConfigurationException( + "No component provider detected for " + type.getName() + " with name \"" + name + "\"."); + } + if (matchedProviders.size() > 1) { + throw new ConfigurationException( + "Component provider conflict. Multiple providers detected for " + + type.getName() + + " with name \"" + + name + + "\": " + + componentProviders.stream() + .map(provider -> provider.getClass().getName()) + .collect(Collectors.joining(",", "[", "]"))); + } + // Exactly one matching component provider + ComponentProvider provider = (ComponentProvider) matchedProviders.get(0); + + try { + return provider.create(config); + } catch (Throwable throwable) { + throw new ConfigurationException( + "Error configuring " + type.getName() + " with name \"" + name + "\"", throwable); + } + } + /** * Load implementations of an ordered SPI (i.e. implements {@link Ordered}). * diff --git a/sdk-extensions/autoconfigure/src/testFullConfig/java/io/opentelemetry/sdk/autoconfigure/FileConfigurationTest.java b/sdk-extensions/autoconfigure/src/testFullConfig/java/io/opentelemetry/sdk/autoconfigure/FileConfigurationTest.java index 639f2955da3..f9234de4c65 100644 --- a/sdk-extensions/autoconfigure/src/testFullConfig/java/io/opentelemetry/sdk/autoconfigure/FileConfigurationTest.java +++ b/sdk-extensions/autoconfigure/src/testFullConfig/java/io/opentelemetry/sdk/autoconfigure/FileConfigurationTest.java @@ -185,7 +185,8 @@ void configFile_Error(@TempDir Path tempDir) throws IOException { assertThatThrownBy(() -> AutoConfiguredOpenTelemetrySdk.builder().setConfig(config).build()) .isInstanceOf(ConfigurationException.class) - .hasMessage("Unrecognized span exporter(s): [foo]"); + .hasMessage( + "No component provider detected for io.opentelemetry.sdk.trace.export.SpanExporter with name \"foo\"."); } @Test diff --git a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/FileConfigUtil.java b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/FileConfigUtil.java index 7b5bcd9ca2d..4dfdcbd5565 100644 --- a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/FileConfigUtil.java +++ b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/FileConfigUtil.java @@ -11,8 +11,6 @@ import io.opentelemetry.sdk.autoconfigure.spi.internal.StructuredConfigProperties; import java.io.Closeable; import java.util.List; -import java.util.function.Function; -import java.util.stream.Collectors; import javax.annotation.Nullable; final class FileConfigUtil { @@ -42,45 +40,9 @@ static T assertNotNull(@Nullable T object, String description) { * @throws ConfigurationException if no matching providers are found, or if multiple are found * (i.e. conflict), or if {@link ComponentProvider#create(StructuredConfigProperties)} throws */ - @SuppressWarnings({"unchecked", "rawtypes"}) static T loadComponent(SpiHelper spiHelper, Class type, String name, Object model) { - // TODO(jack-berg): cache loaded component providers - List componentProviders = spiHelper.load(ComponentProvider.class); - List> matchedProviders = - componentProviders.stream() - .map( - (Function>) - componentProvider -> componentProvider) - .filter( - componentProvider -> - componentProvider.getType() == type && name.equals(componentProvider.getName())) - .collect(Collectors.toList()); - if (matchedProviders.isEmpty()) { - throw new ConfigurationException( - "No component provider detected for " + type.getName() + " with name \"" + name + "\"."); - } - if (matchedProviders.size() > 1) { - throw new ConfigurationException( - "Component provider conflict. Multiple providers detected for " - + type.getName() - + " with name \"" - + name - + "\": " - + componentProviders.stream() - .map(provider -> provider.getClass().getName()) - .collect(Collectors.joining(",", "[", "]"))); - } - // Exactly one matching component provider - ComponentProvider provider = (ComponentProvider) matchedProviders.get(0); - // Map model to generic structured config properties StructuredConfigProperties config = FileConfiguration.toConfigProperties(model); - - try { - return provider.create(config); - } catch (Throwable throwable) { - throw new ConfigurationException( - "Error configuring " + type.getName() + " with name \"" + name + "\"", throwable); - } + return spiHelper.loadComponent(type, name, config); } } diff --git a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/LogRecordExporterFactory.java b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/LogRecordExporterFactory.java index 3469ec61e36..f930c2846ef 100644 --- a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/LogRecordExporterFactory.java +++ b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/LogRecordExporterFactory.java @@ -7,16 +7,11 @@ import static java.util.stream.Collectors.joining; -import io.opentelemetry.sdk.autoconfigure.internal.NamedSpiManager; import io.opentelemetry.sdk.autoconfigure.internal.SpiHelper; -import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties; import io.opentelemetry.sdk.autoconfigure.spi.ConfigurationException; -import io.opentelemetry.sdk.autoconfigure.spi.internal.DefaultConfigProperties; -import io.opentelemetry.sdk.autoconfigure.spi.logs.ConfigurableLogRecordExporterProvider; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.Otlp; import io.opentelemetry.sdk.logs.export.LogRecordExporter; import java.io.Closeable; -import java.util.HashMap; import java.util.List; import java.util.Map; import javax.annotation.Nullable; @@ -34,7 +29,9 @@ static LogRecordExporterFactory getInstance() { return INSTANCE; } + @SuppressWarnings("NullAway") // Override superclass non-null response @Override + @Nullable public LogRecordExporter create( @Nullable io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.LogRecordExporter @@ -42,73 +39,36 @@ public LogRecordExporter create( SpiHelper spiHelper, List closeables) { if (model == null) { - return LogRecordExporter.composite(); + return null; } Otlp otlpModel = model.getOtlp(); if (otlpModel != null) { - return FileConfigUtil.addAndReturn(closeables, createOtlpExporter(otlpModel, spiHelper)); + model.getAdditionalProperties().put("otlp", otlpModel); } - // TODO(jack-berg): add support for generic SPI exporters if (!model.getAdditionalProperties().isEmpty()) { - throw new ConfigurationException( - "Unrecognized log record exporter(s): " - + model.getAdditionalProperties().keySet().stream().collect(joining(",", "[", "]"))); + Map additionalProperties = model.getAdditionalProperties(); + if (additionalProperties.size() > 1) { + throw new ConfigurationException( + "Invalid configuration - multiple log record exporters set: " + + additionalProperties.keySet().stream().collect(joining(",", "[", "]"))); + } + Map.Entry exporterKeyValue = + additionalProperties.entrySet().stream() + .findFirst() + .orElseThrow( + () -> + new IllegalStateException("Missing exporter. This is a programming error.")); + LogRecordExporter logRecordExporter = + FileConfigUtil.loadComponent( + spiHelper, + LogRecordExporter.class, + exporterKeyValue.getKey(), + exporterKeyValue.getValue()); + return FileConfigUtil.addAndReturn(closeables, logRecordExporter); } - return LogRecordExporter.composite(); - } - - private static LogRecordExporter createOtlpExporter(Otlp otlp, SpiHelper spiHelper) { - // Translate from file configuration scheme to environment variable scheme. This is ultimately - // interpreted by Otlp*ExporterProviders, but we want to avoid the dependency on - // opentelemetry-exporter-otlp - Map properties = new HashMap<>(); - if (otlp.getProtocol() != null) { - properties.put("otel.exporter.otlp.logs.protocol", otlp.getProtocol()); - } - if (otlp.getEndpoint() != null) { - // NOTE: Set general otel.exporter.otlp.endpoint instead of signal specific - // otel.exporter.otlp.logs.endpoint to allow signal path (i.e. /v1/logs) to be added if not - // present - properties.put("otel.exporter.otlp.endpoint", otlp.getEndpoint()); - } - if (otlp.getHeaders() != null) { - properties.put( - "otel.exporter.otlp.logs.headers", - otlp.getHeaders().getAdditionalProperties().entrySet().stream() - .map(entry -> entry.getKey() + "=" + entry.getValue()) - .collect(joining(","))); - } - if (otlp.getCompression() != null) { - properties.put("otel.exporter.otlp.logs.compression", otlp.getCompression()); - } - if (otlp.getTimeout() != null) { - properties.put("otel.exporter.otlp.logs.timeout", Integer.toString(otlp.getTimeout())); - } - if (otlp.getCertificate() != null) { - properties.put("otel.exporter.otlp.logs.certificate", otlp.getCertificate()); - } - if (otlp.getClientKey() != null) { - properties.put("otel.exporter.otlp.logs.client.key", otlp.getClientKey()); - } - if (otlp.getClientCertificate() != null) { - properties.put("otel.exporter.otlp.logs.client.certificate", otlp.getClientCertificate()); - } - - ConfigProperties configProperties = DefaultConfigProperties.createFromMap(properties); - return FileConfigUtil.assertNotNull( - logRecordExporterSpiManager(configProperties, spiHelper).getByName("otlp"), - "otlp exporter"); - } - - private static NamedSpiManager logRecordExporterSpiManager( - ConfigProperties config, SpiHelper spiHelper) { - return spiHelper.loadConfigurable( - ConfigurableLogRecordExporterProvider.class, - ConfigurableLogRecordExporterProvider::getName, - ConfigurableLogRecordExporterProvider::createExporter, - config); + return null; } } diff --git a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/LogRecordProcessorFactory.java b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/LogRecordProcessorFactory.java index 5971d8537a9..aaf472beec7 100644 --- a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/LogRecordProcessorFactory.java +++ b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/LogRecordProcessorFactory.java @@ -47,13 +47,12 @@ public LogRecordProcessor create( batchModel = model.getBatch(); if (batchModel != null) { LogRecordExporter exporterModel = batchModel.getExporter(); - if (exporterModel == null) { - return LogRecordProcessor.composite(); + io.opentelemetry.sdk.logs.export.LogRecordExporter logRecordExporter = + LogRecordExporterFactory.getInstance().create(exporterModel, spiHelper, closeables); + if (logRecordExporter == null) { + throw new ConfigurationException("exporter required for batch log record processor"); } - - BatchLogRecordProcessorBuilder builder = - BatchLogRecordProcessor.builder( - LogRecordExporterFactory.getInstance().create(exporterModel, spiHelper, closeables)); + BatchLogRecordProcessorBuilder builder = BatchLogRecordProcessor.builder(logRecordExporter); if (batchModel.getExportTimeout() != null) { builder.setExporterTimeout(Duration.ofMillis(batchModel.getExportTimeout())); } @@ -73,14 +72,13 @@ public LogRecordProcessor create( simpleModel = model.getSimple(); if (simpleModel != null) { LogRecordExporter exporterModel = simpleModel.getExporter(); - if (exporterModel == null) { - return LogRecordProcessor.composite(); + io.opentelemetry.sdk.logs.export.LogRecordExporter logRecordExporter = + LogRecordExporterFactory.getInstance().create(exporterModel, spiHelper, closeables); + if (logRecordExporter == null) { + throw new ConfigurationException("exporter required for simple log record processor"); } - return FileConfigUtil.addAndReturn( - closeables, - SimpleLogRecordProcessor.create( - LogRecordExporterFactory.getInstance().create(exporterModel, spiHelper, closeables))); + closeables, SimpleLogRecordProcessor.create(logRecordExporter)); } // TODO: add support for generic log record processors diff --git a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/MetricExporterFactory.java b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/MetricExporterFactory.java index 7d187f8a057..7bba4b843f0 100644 --- a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/MetricExporterFactory.java +++ b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/MetricExporterFactory.java @@ -7,17 +7,11 @@ import static java.util.stream.Collectors.joining; -import io.opentelemetry.sdk.autoconfigure.internal.NamedSpiManager; import io.opentelemetry.sdk.autoconfigure.internal.SpiHelper; -import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties; import io.opentelemetry.sdk.autoconfigure.spi.ConfigurationException; -import io.opentelemetry.sdk.autoconfigure.spi.internal.DefaultConfigProperties; -import io.opentelemetry.sdk.autoconfigure.spi.metrics.ConfigurableMetricExporterProvider; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.OtlpMetric; import io.opentelemetry.sdk.metrics.export.MetricExporter; import java.io.Closeable; -import java.util.Collections; -import java.util.HashMap; import java.util.List; import java.util.Map; import javax.annotation.Nullable; @@ -49,93 +43,39 @@ public MetricExporter create( OtlpMetric otlpModel = model.getOtlp(); if (otlpModel != null) { - return FileConfigUtil.addAndReturn(closeables, createOtlpExporter(otlpModel, spiHelper)); + model.getAdditionalProperties().put("otlp", otlpModel); } if (model.getConsole() != null) { - return FileConfigUtil.addAndReturn(closeables, createConsoleExporter(spiHelper)); + model.getAdditionalProperties().put("console", model.getConsole()); } if (model.getPrometheus() != null) { throw new ConfigurationException("prometheus exporter not supported in this context"); } - // TODO(jack-berg): add support for generic SPI exporters if (!model.getAdditionalProperties().isEmpty()) { - throw new ConfigurationException( - "Unrecognized metric exporter(s): " - + model.getAdditionalProperties().keySet().stream().collect(joining(",", "[", "]"))); + Map additionalProperties = model.getAdditionalProperties(); + if (additionalProperties.size() > 1) { + throw new ConfigurationException( + "Invalid configuration - multiple metric exporters set: " + + additionalProperties.keySet().stream().collect(joining(",", "[", "]"))); + } + Map.Entry exporterKeyValue = + additionalProperties.entrySet().stream() + .findFirst() + .orElseThrow( + () -> + new IllegalStateException("Missing exporter. This is a programming error.")); + MetricExporter metricExporter = + FileConfigUtil.loadComponent( + spiHelper, + MetricExporter.class, + exporterKeyValue.getKey(), + exporterKeyValue.getValue()); + return FileConfigUtil.addAndReturn(closeables, metricExporter); } return null; } - - private static MetricExporter createOtlpExporter(OtlpMetric model, SpiHelper spiHelper) { - // Translate from file configuration scheme to environment variable scheme. This is ultimately - // interpreted by Otlp*ExporterProviders, but we want to avoid the dependency on - // opentelemetry-exporter-otlp - Map properties = new HashMap<>(); - if (model.getProtocol() != null) { - properties.put("otel.exporter.otlp.metrics.protocol", model.getProtocol()); - } - if (model.getEndpoint() != null) { - // NOTE: Set general otel.exporter.otlp.endpoint instead of signal specific - // otel.exporter.otlp.metrics.endpoint to allow signal path (i.e. /v1/metrics) to be added - // if not - // present - properties.put("otel.exporter.otlp.endpoint", model.getEndpoint()); - } - if (model.getHeaders() != null) { - properties.put( - "otel.exporter.otlp.metrics.headers", - model.getHeaders().getAdditionalProperties().entrySet().stream() - .map(entry -> entry.getKey() + "=" + entry.getValue()) - .collect(joining(","))); - } - if (model.getCompression() != null) { - properties.put("otel.exporter.otlp.metrics.compression", model.getCompression()); - } - if (model.getTimeout() != null) { - properties.put("otel.exporter.otlp.metrics.timeout", Integer.toString(model.getTimeout())); - } - if (model.getCertificate() != null) { - properties.put("otel.exporter.otlp.metrics.certificate", model.getCertificate()); - } - if (model.getClientKey() != null) { - properties.put("otel.exporter.otlp.metrics.client.key", model.getClientKey()); - } - if (model.getClientCertificate() != null) { - properties.put("otel.exporter.otlp.metrics.client.certificate", model.getClientCertificate()); - } - if (model.getDefaultHistogramAggregation() != null) { - properties.put( - "otel.exporter.otlp.metrics.default.histogram.aggregation", - model.getDefaultHistogramAggregation().value()); - } - if (model.getTemporalityPreference() != null) { - properties.put( - "otel.exporter.otlp.metrics.temporality.preference", model.getTemporalityPreference()); - } - - ConfigProperties configProperties = DefaultConfigProperties.createFromMap(properties); - return FileConfigUtil.assertNotNull( - metricExporterSpiManager(configProperties, spiHelper).getByName("otlp"), "otlp exporter"); - } - - private static MetricExporter createConsoleExporter(SpiHelper spiHelper) { - return FileConfigUtil.assertNotNull( - metricExporterSpiManager( - DefaultConfigProperties.createFromMap(Collections.emptyMap()), spiHelper) - .getByName("logging"), - "logging exporter"); - } - - private static NamedSpiManager metricExporterSpiManager( - ConfigProperties config, SpiHelper spiHelper) { - return spiHelper.loadConfigurable( - ConfigurableMetricExporterProvider.class, - ConfigurableMetricExporterProvider::getName, - ConfigurableMetricExporterProvider::createExporter, - config); - } } diff --git a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/MetricReaderFactory.java b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/MetricReaderFactory.java index 77750920cf2..3a049ab2689 100644 --- a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/MetricReaderFactory.java +++ b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/MetricReaderFactory.java @@ -46,13 +46,10 @@ public MetricReader create( PeriodicMetricReader periodicModel = model.getPeriodic(); if (periodicModel != null) { MetricExporter exporterModel = periodicModel.getExporter(); - if (exporterModel == null) { - throw new ConfigurationException("exporter required for periodic reader"); - } io.opentelemetry.sdk.metrics.export.MetricExporter metricExporter = MetricExporterFactory.getInstance().create(exporterModel, spiHelper, closeables); if (metricExporter == null) { - return null; + throw new ConfigurationException("exporter required for periodic reader"); } PeriodicMetricReaderBuilder builder = io.opentelemetry.sdk.metrics.export.PeriodicMetricReader.builder( diff --git a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/SpanExporterFactory.java b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/SpanExporterFactory.java index 8a3b8cc6dce..cf2c866bc3c 100644 --- a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/SpanExporterFactory.java +++ b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/SpanExporterFactory.java @@ -7,18 +7,12 @@ import static java.util.stream.Collectors.joining; -import io.opentelemetry.sdk.autoconfigure.internal.NamedSpiManager; import io.opentelemetry.sdk.autoconfigure.internal.SpiHelper; -import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties; import io.opentelemetry.sdk.autoconfigure.spi.ConfigurationException; -import io.opentelemetry.sdk.autoconfigure.spi.internal.DefaultConfigProperties; -import io.opentelemetry.sdk.autoconfigure.spi.traces.ConfigurableSpanExporterProvider; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.Otlp; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.Zipkin; import io.opentelemetry.sdk.trace.export.SpanExporter; import java.io.Closeable; -import java.util.Collections; -import java.util.HashMap; import java.util.List; import java.util.Map; import javax.annotation.Nullable; @@ -36,113 +30,54 @@ static SpanExporterFactory getInstance() { return INSTANCE; } + @SuppressWarnings("NullAway") // Override superclass non-null response @Override + @Nullable public SpanExporter create( @Nullable io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.SpanExporter model, SpiHelper spiHelper, List closeables) { if (model == null) { - return SpanExporter.composite(); + return null; } Otlp otlpModel = model.getOtlp(); if (otlpModel != null) { - return FileConfigUtil.addAndReturn(closeables, createOtlpExporter(otlpModel, spiHelper)); + model.getAdditionalProperties().put("otlp", otlpModel); } if (model.getConsole() != null) { - return FileConfigUtil.addAndReturn(closeables, createConsoleExporter(spiHelper)); + model.getAdditionalProperties().put("console", model.getConsole()); } Zipkin zipkinModel = model.getZipkin(); if (zipkinModel != null) { - return FileConfigUtil.addAndReturn(closeables, createZipkinExporter(zipkinModel, spiHelper)); + model.getAdditionalProperties().put("zipkin", model.getZipkin()); } - // TODO(jack-berg): add support for generic SPI exporters if (!model.getAdditionalProperties().isEmpty()) { - throw new ConfigurationException( - "Unrecognized span exporter(s): " - + model.getAdditionalProperties().keySet().stream().collect(joining(",", "[", "]"))); + Map additionalProperties = model.getAdditionalProperties(); + if (additionalProperties.size() > 1) { + throw new ConfigurationException( + "Invalid configuration - multiple span exporters set: " + + additionalProperties.keySet().stream().collect(joining(",", "[", "]"))); + } + Map.Entry exporterKeyValue = + additionalProperties.entrySet().stream() + .findFirst() + .orElseThrow( + () -> + new IllegalStateException("Missing exporter. This is a programming error.")); + SpanExporter spanExporter = + FileConfigUtil.loadComponent( + spiHelper, + SpanExporter.class, + exporterKeyValue.getKey(), + exporterKeyValue.getValue()); + return FileConfigUtil.addAndReturn(closeables, spanExporter); } - return SpanExporter.composite(); - } - - private static SpanExporter createOtlpExporter(Otlp model, SpiHelper spiHelper) { - // Translate from file configuration scheme to environment variable scheme. This is ultimately - // interpreted by Otlp*ExporterProviders, but we want to avoid the dependency on - // opentelemetry-exporter-otlp - Map properties = new HashMap<>(); - if (model.getProtocol() != null) { - properties.put("otel.exporter.otlp.traces.protocol", model.getProtocol()); - } - if (model.getEndpoint() != null) { - // NOTE: Set general otel.exporter.otlp.endpoint instead of signal specific - // otel.exporter.otlp.traces.endpoint to allow signal path (i.e. /v1/traces) to be added if - // not present - properties.put("otel.exporter.otlp.endpoint", model.getEndpoint()); - } - if (model.getHeaders() != null) { - properties.put( - "otel.exporter.otlp.traces.headers", - model.getHeaders().getAdditionalProperties().entrySet().stream() - .map(entry -> entry.getKey() + "=" + entry.getValue()) - .collect(joining(","))); - } - if (model.getCompression() != null) { - properties.put("otel.exporter.otlp.traces.compression", model.getCompression()); - } - if (model.getTimeout() != null) { - properties.put("otel.exporter.otlp.traces.timeout", Integer.toString(model.getTimeout())); - } - if (model.getCertificate() != null) { - properties.put("otel.exporter.otlp.traces.certificate", model.getCertificate()); - } - if (model.getClientKey() != null) { - properties.put("otel.exporter.otlp.traces.client.key", model.getClientKey()); - } - if (model.getClientCertificate() != null) { - properties.put("otel.exporter.otlp.traces.client.certificate", model.getClientCertificate()); - } - - ConfigProperties configProperties = DefaultConfigProperties.createFromMap(properties); - return FileConfigUtil.assertNotNull( - spanExporterSpiManager(configProperties, spiHelper).getByName("otlp"), "otlp exporter"); - } - - private static SpanExporter createConsoleExporter(SpiHelper spiHelper) { - return FileConfigUtil.assertNotNull( - spanExporterSpiManager( - DefaultConfigProperties.createFromMap(Collections.emptyMap()), spiHelper) - .getByName("logging"), - "logging exporter"); - } - - private static SpanExporter createZipkinExporter(Zipkin model, SpiHelper spiHelper) { - // Translate from file configuration scheme to environment variable scheme. This is ultimately - // interpreted by ZipkinSpanExporterProvider, but we want to avoid the dependency on - // opentelemetry-exporter-zipkin - Map properties = new HashMap<>(); - if (model.getEndpoint() != null) { - properties.put("otel.exporter.zipkin.endpoint", model.getEndpoint()); - } - if (model.getTimeout() != null) { - properties.put("otel.exporter.zipkin.timeout", Integer.toString(model.getTimeout())); - } - - ConfigProperties configProperties = DefaultConfigProperties.createFromMap(properties); - return FileConfigUtil.assertNotNull( - spanExporterSpiManager(configProperties, spiHelper).getByName("zipkin"), "zipkin exporter"); - } - - private static NamedSpiManager spanExporterSpiManager( - ConfigProperties config, SpiHelper spiHelper) { - return spiHelper.loadConfigurable( - ConfigurableSpanExporterProvider.class, - ConfigurableSpanExporterProvider::getName, - ConfigurableSpanExporterProvider::createExporter, - config); + return null; } } diff --git a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/SpanProcessorFactory.java b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/SpanProcessorFactory.java index 59b78370ae6..6536f0bf3ca 100644 --- a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/SpanProcessorFactory.java +++ b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/SpanProcessorFactory.java @@ -46,13 +46,12 @@ public SpanProcessor create( batchModel = model.getBatch(); if (batchModel != null) { SpanExporter exporterModel = batchModel.getExporter(); - if (exporterModel == null) { - return SpanProcessor.composite(); + io.opentelemetry.sdk.trace.export.SpanExporter spanExporter = + SpanExporterFactory.getInstance().create(exporterModel, spiHelper, closeables); + if (spanExporter == null) { + throw new ConfigurationException("exporter required for batch span processor"); } - - BatchSpanProcessorBuilder builder = - BatchSpanProcessor.builder( - SpanExporterFactory.getInstance().create(exporterModel, spiHelper, closeables)); + BatchSpanProcessorBuilder builder = BatchSpanProcessor.builder(spanExporter); if (batchModel.getExportTimeout() != null) { builder.setExporterTimeout(Duration.ofMillis(batchModel.getExportTimeout())); } @@ -72,14 +71,12 @@ public SpanProcessor create( simpleModel = model.getSimple(); if (simpleModel != null) { SpanExporter exporterModel = simpleModel.getExporter(); - if (exporterModel == null) { - return SpanProcessor.composite(); + io.opentelemetry.sdk.trace.export.SpanExporter spanExporter = + SpanExporterFactory.getInstance().create(exporterModel, spiHelper, closeables); + if (spanExporter == null) { + throw new ConfigurationException("exporter required for simple span processor"); } - - return FileConfigUtil.addAndReturn( - closeables, - SimpleSpanProcessor.create( - SpanExporterFactory.getInstance().create(exporterModel, spiHelper, closeables))); + return FileConfigUtil.addAndReturn(closeables, SimpleSpanProcessor.create(spanExporter)); } // TODO: add support for generic span processors diff --git a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/FileConfigurationCreateTest.java b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/FileConfigurationCreateTest.java index 7699752b109..dcd90cd60c4 100644 --- a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/FileConfigurationCreateTest.java +++ b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/FileConfigurationCreateTest.java @@ -118,7 +118,8 @@ void parseAndCreate_Exception_CleansUpPartials() { FileConfiguration.parseAndCreate( new ByteArrayInputStream(yaml.getBytes(StandardCharsets.UTF_8)))) .isInstanceOf(ConfigurationException.class) - .hasMessage("Unrecognized log record exporter(s): [foo]"); + .hasMessage( + "No component provider detected for io.opentelemetry.sdk.logs.export.LogRecordExporter with name \"foo\"."); logCapturer.assertContains( "Error encountered interpreting configuration model. Closing partially configured components."); logCapturer.assertContains( diff --git a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/LogRecordExporterFactoryTest.java b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/LogRecordExporterFactoryTest.java index 721421c8552..7a8815d57ce 100644 --- a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/LogRecordExporterFactoryTest.java +++ b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/LogRecordExporterFactoryTest.java @@ -8,20 +8,20 @@ import static io.opentelemetry.sdk.extension.incubator.fileconfig.FileConfigTestUtil.createTempFileWithContent; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; -import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.verify; import com.google.common.collect.ImmutableMap; +import com.google.common.collect.ImmutableSet; import com.linecorp.armeria.testing.junit5.server.SelfSignedCertificateExtension; import io.opentelemetry.exporter.otlp.http.logs.OtlpHttpLogRecordExporter; import io.opentelemetry.exporter.otlp.logs.OtlpGrpcLogRecordExporter; import io.opentelemetry.internal.testing.CleanupExtension; import io.opentelemetry.sdk.autoconfigure.internal.SpiHelper; -import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties; import io.opentelemetry.sdk.autoconfigure.spi.ConfigurationException; -import io.opentelemetry.sdk.autoconfigure.spi.logs.ConfigurableLogRecordExporterProvider; +import io.opentelemetry.sdk.autoconfigure.spi.internal.StructuredConfigProperties; +import io.opentelemetry.sdk.extension.incubator.fileconfig.component.LogRecordExporterComponentProvider; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.Headers; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.Otlp; import io.opentelemetry.sdk.logs.export.LogRecordExporter; @@ -58,12 +58,8 @@ class LogRecordExporterFactoryTest { @Test void create_Null() { - LogRecordExporter expectedExporter = LogRecordExporter.composite(); - - LogRecordExporter exporter = - LogRecordExporterFactory.getInstance().create(null, spiHelper, new ArrayList<>()); - - assertThat(exporter.toString()).isEqualTo(expectedExporter.toString()); + assertThat(LogRecordExporterFactory.getInstance().create(null, spiHelper, new ArrayList<>())) + .isNull(); } @Test @@ -86,19 +82,21 @@ void create_OtlpDefaults() { assertThat(exporter.toString()).isEqualTo(expectedExporter.toString()); - ArgumentCaptor configCaptor = ArgumentCaptor.forClass(ConfigProperties.class); + assertThat(exporter.toString()).isEqualTo(expectedExporter.toString()); + + ArgumentCaptor configCaptor = + ArgumentCaptor.forClass(StructuredConfigProperties.class); verify(spiHelper) - .loadConfigurable( - eq(ConfigurableLogRecordExporterProvider.class), any(), any(), configCaptor.capture()); - ConfigProperties configProperties = configCaptor.getValue(); - assertThat(configProperties.getString("otel.exporter.otlp.logs.protocol")).isNull(); - assertThat(configProperties.getString("otel.exporter.otlp.endpoint")).isNull(); - assertThat(configProperties.getMap("otel.exporter.otlp.logs.headers")).isEmpty(); - assertThat(configProperties.getString("otel.exporter.otlp.logs.compression")).isNull(); - assertThat(configProperties.getDuration("otel.exporter.otlp.logs.timeout")).isNull(); - assertThat(configProperties.getString("otel.exporter.otlp.logs.certificate")).isNull(); - assertThat(configProperties.getString("otel.exporter.otlp.logs.client.key")).isNull(); - assertThat(configProperties.getString("otel.exporter.otlp.logs.client.certificate")).isNull(); + .loadComponent(eq(LogRecordExporter.class), eq("otlp"), configCaptor.capture()); + StructuredConfigProperties configProperties = configCaptor.getValue(); + assertThat(configProperties.getString("protocol")).isNull(); + assertThat(configProperties.getString("endpoint")).isNull(); + assertThat(configProperties.getStructured("headers")).isNull(); + assertThat(configProperties.getString("compression")).isNull(); + assertThat(configProperties.getInt("timeout")).isNull(); + assertThat(configProperties.getString("certificate")).isNull(); + assertThat(configProperties.getString("client_key")).isNull(); + assertThat(configProperties.getString("client_certificate")).isNull(); } @Test @@ -151,30 +149,27 @@ void create_OtlpConfigured(@TempDir Path tempDir) assertThat(exporter.toString()).isEqualTo(expectedExporter.toString()); - ArgumentCaptor configCaptor = ArgumentCaptor.forClass(ConfigProperties.class); + ArgumentCaptor configCaptor = + ArgumentCaptor.forClass(StructuredConfigProperties.class); verify(spiHelper) - .loadConfigurable( - eq(ConfigurableLogRecordExporterProvider.class), any(), any(), configCaptor.capture()); - ConfigProperties configProperties = configCaptor.getValue(); - assertThat(configProperties.getString("otel.exporter.otlp.logs.protocol")) - .isEqualTo("http/protobuf"); - assertThat(configProperties.getString("otel.exporter.otlp.endpoint")) - .isEqualTo("http://example:4318"); - assertThat(configProperties.getMap("otel.exporter.otlp.logs.headers")) - .isEqualTo(ImmutableMap.of("key1", "value1", "key2", "value2")); - assertThat(configProperties.getString("otel.exporter.otlp.logs.compression")).isEqualTo("gzip"); - assertThat(configProperties.getDuration("otel.exporter.otlp.logs.timeout")) - .isEqualTo(Duration.ofSeconds(15)); - assertThat(configProperties.getString("otel.exporter.otlp.logs.certificate")) - .isEqualTo(certificatePath); - assertThat(configProperties.getString("otel.exporter.otlp.logs.client.key")) - .isEqualTo(clientKeyPath); - assertThat(configProperties.getString("otel.exporter.otlp.logs.client.certificate")) - .isEqualTo(clientCertificatePath); + .loadComponent(eq(LogRecordExporter.class), eq("otlp"), configCaptor.capture()); + StructuredConfigProperties configProperties = configCaptor.getValue(); + assertThat(configProperties.getString("protocol")).isEqualTo("http/protobuf"); + assertThat(configProperties.getString("endpoint")).isEqualTo("http://example:4318"); + StructuredConfigProperties headers = configProperties.getStructured("headers"); + assertThat(headers).isNotNull(); + assertThat(headers.getPropertyKeys()).isEqualTo(ImmutableSet.of("key1", "key2")); + assertThat(headers.getString("key1")).isEqualTo("value1"); + assertThat(headers.getString("key2")).isEqualTo("value2"); + assertThat(configProperties.getString("compression")).isEqualTo("gzip"); + assertThat(configProperties.getInt("timeout")).isEqualTo(Duration.ofSeconds(15).toMillis()); + assertThat(configProperties.getString("certificate")).isEqualTo(certificatePath); + assertThat(configProperties.getString("client_key")).isEqualTo(clientKeyPath); + assertThat(configProperties.getString("client_certificate")).isEqualTo(clientCertificatePath); } @Test - void create_SpiExporter() { + void create_SpiExporter_Unknown() { List closeables = new ArrayList<>(); assertThatThrownBy( @@ -183,11 +178,31 @@ void create_SpiExporter() { .create( new io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model .LogRecordExporter() - .withAdditionalProperty("test", ImmutableMap.of("key1", "value1")), + .withAdditionalProperty( + "unknown_key", ImmutableMap.of("key1", "value1")), spiHelper, new ArrayList<>())) .isInstanceOf(ConfigurationException.class) - .hasMessage("Unrecognized log record exporter(s): [test]"); + .hasMessage( + "No component provider detected for io.opentelemetry.sdk.logs.export.LogRecordExporter with name \"unknown_key\"."); cleanup.addCloseables(closeables); } + + @Test + void create_SpiExporter_Valid() { + LogRecordExporter logRecordExporter = + LogRecordExporterFactory.getInstance() + .create( + new io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model + .LogRecordExporter() + .withAdditionalProperty("test", ImmutableMap.of("key1", "value1")), + spiHelper, + new ArrayList<>()); + assertThat(logRecordExporter) + .isInstanceOf(LogRecordExporterComponentProvider.TestLogRecordExporter.class); + assertThat( + ((LogRecordExporterComponentProvider.TestLogRecordExporter) logRecordExporter) + .config.getString("key1")) + .isEqualTo("value1"); + } } diff --git a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/LogRecordProcessorFactoryTest.java b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/LogRecordProcessorFactoryTest.java index 043533117b2..7a9e632d2b3 100644 --- a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/LogRecordProcessorFactoryTest.java +++ b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/LogRecordProcessorFactoryTest.java @@ -48,19 +48,15 @@ void create_Null() { @Test void create_BatchNullExporter() { - List closeables = new ArrayList<>(); - - io.opentelemetry.sdk.logs.LogRecordProcessor processor = - LogRecordProcessorFactory.getInstance() - .create( - new LogRecordProcessor().withBatch(new BatchLogRecordProcessor()), - spiHelper, - Collections.emptyList()); - cleanup.addCloseable(processor); - cleanup.addCloseables(closeables); - - assertThat(processor.toString()) - .isEqualTo(io.opentelemetry.sdk.logs.LogRecordProcessor.composite().toString()); + assertThatThrownBy( + () -> + LogRecordProcessorFactory.getInstance() + .create( + new LogRecordProcessor().withBatch(new BatchLogRecordProcessor()), + spiHelper, + Collections.emptyList())) + .isInstanceOf(ConfigurationException.class) + .hasMessage("exporter required for batch log record processor"); } @Test @@ -119,19 +115,15 @@ void create_BatchConfigured() { @Test void create_SimpleNullExporter() { - List closeables = new ArrayList<>(); - - io.opentelemetry.sdk.logs.LogRecordProcessor processor = - LogRecordProcessorFactory.getInstance() - .create( - new LogRecordProcessor().withSimple(new SimpleLogRecordProcessor()), - spiHelper, - Collections.emptyList()); - cleanup.addCloseable(processor); - cleanup.addCloseables(closeables); - - assertThat(processor.toString()) - .isEqualTo(io.opentelemetry.sdk.logs.LogRecordProcessor.composite().toString()); + assertThatThrownBy( + () -> + LogRecordProcessorFactory.getInstance() + .create( + new LogRecordProcessor().withSimple(new SimpleLogRecordProcessor()), + spiHelper, + Collections.emptyList())) + .isInstanceOf(ConfigurationException.class) + .hasMessage("exporter required for simple log record processor"); } @Test diff --git a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/MetricExporterFactoryTest.java b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/MetricExporterFactoryTest.java index 6470239bfdf..dd8cca69107 100644 --- a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/MetricExporterFactoryTest.java +++ b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/MetricExporterFactoryTest.java @@ -8,21 +8,21 @@ import static io.opentelemetry.sdk.extension.incubator.fileconfig.FileConfigTestUtil.createTempFileWithContent; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; -import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.verify; import com.google.common.collect.ImmutableMap; +import com.google.common.collect.ImmutableSet; import com.linecorp.armeria.testing.junit5.server.SelfSignedCertificateExtension; import io.opentelemetry.exporter.logging.LoggingMetricExporter; import io.opentelemetry.exporter.otlp.http.metrics.OtlpHttpMetricExporter; import io.opentelemetry.exporter.otlp.metrics.OtlpGrpcMetricExporter; import io.opentelemetry.internal.testing.CleanupExtension; import io.opentelemetry.sdk.autoconfigure.internal.SpiHelper; -import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties; import io.opentelemetry.sdk.autoconfigure.spi.ConfigurationException; -import io.opentelemetry.sdk.autoconfigure.spi.metrics.ConfigurableMetricExporterProvider; +import io.opentelemetry.sdk.autoconfigure.spi.internal.StructuredConfigProperties; +import io.opentelemetry.sdk.extension.incubator.fileconfig.component.MetricExporterComponentProvider; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.Console; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.Headers; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.OtlpMetric; @@ -89,25 +89,20 @@ void create_OtlpDefaults() { assertThat(exporter.toString()).isEqualTo(expectedExporter.toString()); - ArgumentCaptor configCaptor = ArgumentCaptor.forClass(ConfigProperties.class); - verify(spiHelper) - .loadConfigurable( - eq(ConfigurableMetricExporterProvider.class), any(), any(), configCaptor.capture()); - ConfigProperties configProperties = configCaptor.getValue(); - assertThat(configProperties.getString("otel.exporter.otlp.metrics.protocol")).isNull(); - assertThat(configProperties.getString("otel.exporter.otlp.endpoint")).isNull(); - assertThat(configProperties.getMap("otel.exporter.otlp.metrics.headers")).isEmpty(); - assertThat(configProperties.getString("otel.exporter.otlp.metrics.compression")).isNull(); - assertThat(configProperties.getDuration("otel.exporter.otlp.metrics.timeout")).isNull(); - assertThat(configProperties.getString("otel.exporter.otlp.metrics.certificate")).isNull(); - assertThat(configProperties.getString("otel.exporter.otlp.metrics.client.key")).isNull(); - assertThat(configProperties.getString("otel.exporter.otlp.metrics.client.certificate")) - .isNull(); - assertThat( - configProperties.getString("otel.exporter.otlp.metrics.default.histogram.aggregation")) - .isNull(); - assertThat(configProperties.getString("otel.exporter.otlp.metrics.temporality.preference")) - .isNull(); + ArgumentCaptor configCaptor = + ArgumentCaptor.forClass(StructuredConfigProperties.class); + verify(spiHelper).loadComponent(eq(MetricExporter.class), eq("otlp"), configCaptor.capture()); + StructuredConfigProperties configProperties = configCaptor.getValue(); + assertThat(configProperties.getString("protocol")).isNull(); + assertThat(configProperties.getString("endpoint")).isNull(); + assertThat(configProperties.getStructured("headers")).isNull(); + assertThat(configProperties.getString("compression")).isNull(); + assertThat(configProperties.getInt("timeout")).isNull(); + assertThat(configProperties.getString("certificate")).isNull(); + assertThat(configProperties.getString("client_key")).isNull(); + assertThat(configProperties.getString("client_certificate")).isNull(); + assertThat(configProperties.getString("temporality_preference")).isNull(); + assertThat(configProperties.getString("default_histogram_aggregation")).isNull(); } @Test @@ -167,31 +162,24 @@ void create_OtlpConfigured(@TempDir Path tempDir) assertThat(exporter.toString()).isEqualTo(expectedExporter.toString()); - ArgumentCaptor configCaptor = ArgumentCaptor.forClass(ConfigProperties.class); - verify(spiHelper) - .loadConfigurable( - eq(ConfigurableMetricExporterProvider.class), any(), any(), configCaptor.capture()); - ConfigProperties configProperties = configCaptor.getValue(); - assertThat(configProperties.getString("otel.exporter.otlp.metrics.protocol")) - .isEqualTo("http/protobuf"); - assertThat(configProperties.getString("otel.exporter.otlp.endpoint")) - .isEqualTo("http://example:4318"); - assertThat(configProperties.getMap("otel.exporter.otlp.metrics.headers")) - .isEqualTo(ImmutableMap.of("key1", "value1", "key2", "value2")); - assertThat(configProperties.getString("otel.exporter.otlp.metrics.compression")) - .isEqualTo("gzip"); - assertThat(configProperties.getDuration("otel.exporter.otlp.metrics.timeout")) - .isEqualTo(Duration.ofSeconds(15)); - assertThat(configProperties.getString("otel.exporter.otlp.metrics.certificate")) - .isEqualTo(certificatePath); - assertThat(configProperties.getString("otel.exporter.otlp.metrics.client.key")) - .isEqualTo(clientKeyPath); - assertThat(configProperties.getString("otel.exporter.otlp.metrics.client.certificate")) - .isEqualTo(clientCertificatePath); - assertThat(configProperties.getString("otel.exporter.otlp.metrics.temporality.preference")) - .isEqualTo("delta"); - assertThat( - configProperties.getString("otel.exporter.otlp.metrics.default.histogram.aggregation")) + ArgumentCaptor configCaptor = + ArgumentCaptor.forClass(StructuredConfigProperties.class); + verify(spiHelper).loadComponent(eq(MetricExporter.class), eq("otlp"), configCaptor.capture()); + StructuredConfigProperties configProperties = configCaptor.getValue(); + assertThat(configProperties.getString("protocol")).isEqualTo("http/protobuf"); + assertThat(configProperties.getString("endpoint")).isEqualTo("http://example:4318"); + StructuredConfigProperties headers = configProperties.getStructured("headers"); + assertThat(headers).isNotNull(); + assertThat(headers.getPropertyKeys()).isEqualTo(ImmutableSet.of("key1", "key2")); + assertThat(headers.getString("key1")).isEqualTo("value1"); + assertThat(headers.getString("key2")).isEqualTo("value2"); + assertThat(configProperties.getString("compression")).isEqualTo("gzip"); + assertThat(configProperties.getInt("timeout")).isEqualTo(Duration.ofSeconds(15).toMillis()); + assertThat(configProperties.getString("certificate")).isEqualTo(certificatePath); + assertThat(configProperties.getString("client_key")).isEqualTo(clientKeyPath); + assertThat(configProperties.getString("client_certificate")).isEqualTo(clientCertificatePath); + assertThat(configProperties.getString("temporality_preference")).isEqualTo("delta"); + assertThat(configProperties.getString("default_histogram_aggregation")) .isEqualTo("base2_exponential_bucket_histogram"); } @@ -235,7 +223,7 @@ void create_PrometheusExporter() { } @Test - void create_SpiExporter() { + void create_SpiExporter_Unknown() { List closeables = new ArrayList<>(); assertThatThrownBy( @@ -244,11 +232,31 @@ void create_SpiExporter() { .create( new io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model .MetricExporter() - .withAdditionalProperty("test", ImmutableMap.of("key1", "value1")), + .withAdditionalProperty( + "unknown_key", ImmutableMap.of("key1", "value1")), spiHelper, new ArrayList<>())) .isInstanceOf(ConfigurationException.class) - .hasMessage("Unrecognized metric exporter(s): [test]"); + .hasMessage( + "No component provider detected for io.opentelemetry.sdk.metrics.export.MetricExporter with name \"unknown_key\"."); cleanup.addCloseables(closeables); } + + @Test + void create_SpiExporter_Valid() { + MetricExporter metricExporter = + MetricExporterFactory.getInstance() + .create( + new io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model + .MetricExporter() + .withAdditionalProperty("test", ImmutableMap.of("key1", "value1")), + spiHelper, + new ArrayList<>()); + assertThat(metricExporter) + .isInstanceOf(MetricExporterComponentProvider.TestMetricExporter.class); + assertThat( + ((MetricExporterComponentProvider.TestMetricExporter) metricExporter) + .config.getString("key1")) + .isEqualTo("value1"); + } } diff --git a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/SpanExporterFactoryTest.java b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/SpanExporterFactoryTest.java index 09c47433003..0712e745d91 100644 --- a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/SpanExporterFactoryTest.java +++ b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/SpanExporterFactoryTest.java @@ -8,12 +8,12 @@ import static io.opentelemetry.sdk.extension.incubator.fileconfig.FileConfigTestUtil.createTempFileWithContent; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; -import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.verify; import com.google.common.collect.ImmutableMap; +import com.google.common.collect.ImmutableSet; import com.linecorp.armeria.testing.junit5.server.SelfSignedCertificateExtension; import io.opentelemetry.exporter.logging.LoggingSpanExporter; import io.opentelemetry.exporter.otlp.http.trace.OtlpHttpSpanExporter; @@ -21,9 +21,9 @@ import io.opentelemetry.exporter.zipkin.ZipkinSpanExporter; import io.opentelemetry.internal.testing.CleanupExtension; import io.opentelemetry.sdk.autoconfigure.internal.SpiHelper; -import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties; import io.opentelemetry.sdk.autoconfigure.spi.ConfigurationException; -import io.opentelemetry.sdk.autoconfigure.spi.traces.ConfigurableSpanExporterProvider; +import io.opentelemetry.sdk.autoconfigure.spi.internal.StructuredConfigProperties; +import io.opentelemetry.sdk.extension.incubator.fileconfig.component.SpanExporterComponentProvider; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.Console; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.Headers; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.Otlp; @@ -59,6 +59,12 @@ class SpanExporterFactoryTest { private SpiHelper spiHelper = SpiHelper.create(SpanExporterFactoryTest.class.getClassLoader()); + @Test + void create_Null() { + assertThat(SpanExporterFactory.getInstance().create(null, spiHelper, new ArrayList<>())) + .isNull(); + } + @Test void create_OtlpDefaults() { spiHelper = spy(spiHelper); @@ -79,19 +85,18 @@ void create_OtlpDefaults() { assertThat(exporter.toString()).isEqualTo(expectedExporter.toString()); - ArgumentCaptor configCaptor = ArgumentCaptor.forClass(ConfigProperties.class); - verify(spiHelper) - .loadConfigurable( - eq(ConfigurableSpanExporterProvider.class), any(), any(), configCaptor.capture()); - ConfigProperties configProperties = configCaptor.getValue(); - assertThat(configProperties.getString("otel.exporter.otlp.traces.protocol")).isNull(); - assertThat(configProperties.getString("otel.exporter.otlp.endpoint")).isNull(); - assertThat(configProperties.getMap("otel.exporter.otlp.traces.headers")).isEmpty(); - assertThat(configProperties.getString("otel.exporter.otlp.traces.compression")).isNull(); - assertThat(configProperties.getDuration("otel.exporter.otlp.traces.timeout")).isNull(); - assertThat(configProperties.getString("otel.exporter.otlp.traces.certificate")).isNull(); - assertThat(configProperties.getString("otel.exporter.otlp.traces.client.key")).isNull(); - assertThat(configProperties.getString("otel.exporter.otlp.traces.client.certificate")).isNull(); + ArgumentCaptor configCaptor = + ArgumentCaptor.forClass(StructuredConfigProperties.class); + verify(spiHelper).loadComponent(eq(SpanExporter.class), eq("otlp"), configCaptor.capture()); + StructuredConfigProperties configProperties = configCaptor.getValue(); + assertThat(configProperties.getString("protocol")).isNull(); + assertThat(configProperties.getString("endpoint")).isNull(); + assertThat(configProperties.getStructured("headers")).isNull(); + assertThat(configProperties.getString("compression")).isNull(); + assertThat(configProperties.getInt("timeout")).isNull(); + assertThat(configProperties.getString("certificate")).isNull(); + assertThat(configProperties.getString("client_key")).isNull(); + assertThat(configProperties.getString("client_certificate")).isNull(); } @Test @@ -144,27 +149,22 @@ void create_OtlpConfigured(@TempDir Path tempDir) assertThat(exporter.toString()).isEqualTo(expectedExporter.toString()); - ArgumentCaptor configCaptor = ArgumentCaptor.forClass(ConfigProperties.class); - verify(spiHelper) - .loadConfigurable( - eq(ConfigurableSpanExporterProvider.class), any(), any(), configCaptor.capture()); - ConfigProperties configProperties = configCaptor.getValue(); - assertThat(configProperties.getString("otel.exporter.otlp.traces.protocol")) - .isEqualTo("http/protobuf"); - assertThat(configProperties.getString("otel.exporter.otlp.endpoint")) - .isEqualTo("http://example:4318"); - assertThat(configProperties.getMap("otel.exporter.otlp.traces.headers")) - .isEqualTo(ImmutableMap.of("key1", "value1", "key2", "value2")); - assertThat(configProperties.getString("otel.exporter.otlp.traces.compression")) - .isEqualTo("gzip"); - assertThat(configProperties.getDuration("otel.exporter.otlp.traces.timeout")) - .isEqualTo(Duration.ofSeconds(15)); - assertThat(configProperties.getString("otel.exporter.otlp.traces.certificate")) - .isEqualTo(certificatePath); - assertThat(configProperties.getString("otel.exporter.otlp.traces.client.key")) - .isEqualTo(clientKeyPath); - assertThat(configProperties.getString("otel.exporter.otlp.traces.client.certificate")) - .isEqualTo(clientCertificatePath); + ArgumentCaptor configCaptor = + ArgumentCaptor.forClass(StructuredConfigProperties.class); + verify(spiHelper).loadComponent(eq(SpanExporter.class), eq("otlp"), configCaptor.capture()); + StructuredConfigProperties configProperties = configCaptor.getValue(); + assertThat(configProperties.getString("protocol")).isEqualTo("http/protobuf"); + assertThat(configProperties.getString("endpoint")).isEqualTo("http://example:4318"); + StructuredConfigProperties headers = configProperties.getStructured("headers"); + assertThat(headers).isNotNull(); + assertThat(headers.getPropertyKeys()).isEqualTo(ImmutableSet.of("key1", "key2")); + assertThat(headers.getString("key1")).isEqualTo("value1"); + assertThat(headers.getString("key2")).isEqualTo("value2"); + assertThat(configProperties.getString("compression")).isEqualTo("gzip"); + assertThat(configProperties.getInt("timeout")).isEqualTo(Duration.ofSeconds(15).toMillis()); + assertThat(configProperties.getString("certificate")).isEqualTo(certificatePath); + assertThat(configProperties.getString("client_key")).isEqualTo(clientKeyPath); + assertThat(configProperties.getString("client_certificate")).isEqualTo(clientCertificatePath); } @Test @@ -209,13 +209,12 @@ void create_ZipkinDefaults() { assertThat(exporter.toString()).isEqualTo(expectedExporter.toString()); - ArgumentCaptor configCaptor = ArgumentCaptor.forClass(ConfigProperties.class); - verify(spiHelper) - .loadConfigurable( - eq(ConfigurableSpanExporterProvider.class), any(), any(), configCaptor.capture()); - ConfigProperties configProperties = configCaptor.getValue(); - assertThat(configProperties.getString("otel.exporter.zipkin.endpoint")).isNull(); - assertThat(configProperties.getDuration("otel.exporter.zipkin.timeout")).isNull(); + ArgumentCaptor configCaptor = + ArgumentCaptor.forClass(StructuredConfigProperties.class); + verify(spiHelper).loadComponent(eq(SpanExporter.class), eq("zipkin"), configCaptor.capture()); + StructuredConfigProperties configProperties = configCaptor.getValue(); + assertThat(configProperties.getString("endpoint")).isNull(); + assertThat(configProperties.getLong("timeout")).isNull(); } @Test @@ -245,19 +244,16 @@ void create_ZipkinConfigured() { assertThat(exporter.toString()).isEqualTo(expectedExporter.toString()); - ArgumentCaptor configCaptor = ArgumentCaptor.forClass(ConfigProperties.class); - verify(spiHelper) - .loadConfigurable( - eq(ConfigurableSpanExporterProvider.class), any(), any(), configCaptor.capture()); - ConfigProperties configProperties = configCaptor.getValue(); - assertThat(configProperties.getString("otel.exporter.zipkin.endpoint")) - .isEqualTo("http://zipkin:9411/v1/v2/spans"); - assertThat(configProperties.getDuration("otel.exporter.zipkin.timeout")) - .isEqualTo(Duration.ofSeconds(15)); + ArgumentCaptor configCaptor = + ArgumentCaptor.forClass(StructuredConfigProperties.class); + verify(spiHelper).loadComponent(eq(SpanExporter.class), eq("zipkin"), configCaptor.capture()); + StructuredConfigProperties configProperties = configCaptor.getValue(); + assertThat(configProperties.getString("endpoint")).isEqualTo("http://zipkin:9411/v1/v2/spans"); + assertThat(configProperties.getLong("timeout")).isEqualTo(15_000); } @Test - void create_SpiExporter() { + void create_SpiExporter_Unknown() { List closeables = new ArrayList<>(); assertThatThrownBy( @@ -266,11 +262,30 @@ void create_SpiExporter() { .create( new io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model .SpanExporter() - .withAdditionalProperty("test", ImmutableMap.of("key1", "value1")), + .withAdditionalProperty( + "unknown_key", ImmutableMap.of("key1", "value1")), spiHelper, new ArrayList<>())) .isInstanceOf(ConfigurationException.class) - .hasMessage("Unrecognized span exporter(s): [test]"); + .hasMessage( + "No component provider detected for io.opentelemetry.sdk.trace.export.SpanExporter with name \"unknown_key\"."); cleanup.addCloseables(closeables); } + + @Test + void create_SpiExporter_Valid() { + SpanExporter spanExporter = + SpanExporterFactory.getInstance() + .create( + new io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model + .SpanExporter() + .withAdditionalProperty("test", ImmutableMap.of("key1", "value1")), + spiHelper, + new ArrayList<>()); + assertThat(spanExporter).isInstanceOf(SpanExporterComponentProvider.TestSpanExporter.class); + assertThat( + ((SpanExporterComponentProvider.TestSpanExporter) spanExporter) + .config.getString("key1")) + .isEqualTo("value1"); + } } diff --git a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/SpanProcessorFactoryTest.java b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/SpanProcessorFactoryTest.java index 3c6059cc714..eb1fb1533ce 100644 --- a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/SpanProcessorFactoryTest.java +++ b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/SpanProcessorFactoryTest.java @@ -48,19 +48,15 @@ void create_Null() { @Test void create_BatchNullExporter() { - List closeables = new ArrayList<>(); - - io.opentelemetry.sdk.trace.SpanProcessor processor = - SpanProcessorFactory.getInstance() - .create( - new SpanProcessor().withBatch(new BatchSpanProcessor()), - spiHelper, - Collections.emptyList()); - cleanup.addCloseable(processor); - cleanup.addCloseables(closeables); - - assertThat(processor.toString()) - .isEqualTo(io.opentelemetry.sdk.trace.SpanProcessor.composite().toString()); + assertThatThrownBy( + () -> + SpanProcessorFactory.getInstance() + .create( + new SpanProcessor().withBatch(new BatchSpanProcessor()), + spiHelper, + Collections.emptyList())) + .isInstanceOf(ConfigurationException.class) + .hasMessage("exporter required for batch span processor"); } @Test @@ -119,19 +115,15 @@ void create_BatchConfigured() { @Test void create_SimpleNullExporter() { - List closeables = new ArrayList<>(); - - io.opentelemetry.sdk.trace.SpanProcessor processor = - SpanProcessorFactory.getInstance() - .create( - new SpanProcessor().withSimple(new SimpleSpanProcessor()), - spiHelper, - Collections.emptyList()); - cleanup.addCloseable(processor); - cleanup.addCloseables(closeables); - - assertThat(processor.toString()) - .isEqualTo(io.opentelemetry.sdk.trace.SpanProcessor.composite().toString()); + assertThatThrownBy( + () -> + SpanProcessorFactory.getInstance() + .create( + new SpanProcessor().withSimple(new SimpleSpanProcessor()), + spiHelper, + Collections.emptyList())) + .isInstanceOf(ConfigurationException.class) + .hasMessage("exporter required for simple span processor"); } @Test diff --git a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/component/LogRecordExporterComponentProvider.java b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/component/LogRecordExporterComponentProvider.java new file mode 100644 index 00000000000..2f2d6f56c7c --- /dev/null +++ b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/component/LogRecordExporterComponentProvider.java @@ -0,0 +1,54 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.sdk.extension.incubator.fileconfig.component; + +import io.opentelemetry.sdk.autoconfigure.spi.internal.ComponentProvider; +import io.opentelemetry.sdk.autoconfigure.spi.internal.StructuredConfigProperties; +import io.opentelemetry.sdk.common.CompletableResultCode; +import io.opentelemetry.sdk.logs.data.LogRecordData; +import io.opentelemetry.sdk.logs.export.LogRecordExporter; +import java.util.Collection; + +public class LogRecordExporterComponentProvider implements ComponentProvider { + @Override + public Class getType() { + return LogRecordExporter.class; + } + + @Override + public String getName() { + return "test"; + } + + @Override + public LogRecordExporter create(StructuredConfigProperties config) { + return new TestLogRecordExporter(config); + } + + public static class TestLogRecordExporter implements LogRecordExporter { + + public final StructuredConfigProperties config; + + private TestLogRecordExporter(StructuredConfigProperties config) { + this.config = config; + } + + @Override + public CompletableResultCode export(Collection logs) { + return CompletableResultCode.ofSuccess(); + } + + @Override + public CompletableResultCode flush() { + return CompletableResultCode.ofSuccess(); + } + + @Override + public CompletableResultCode shutdown() { + return CompletableResultCode.ofSuccess(); + } + } +} diff --git a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/component/MetricExporterComponentProvider.java b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/component/MetricExporterComponentProvider.java new file mode 100644 index 00000000000..b0c46a8be92 --- /dev/null +++ b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/component/MetricExporterComponentProvider.java @@ -0,0 +1,63 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.sdk.extension.incubator.fileconfig.component; + +import io.opentelemetry.sdk.autoconfigure.spi.internal.ComponentProvider; +import io.opentelemetry.sdk.autoconfigure.spi.internal.StructuredConfigProperties; +import io.opentelemetry.sdk.common.CompletableResultCode; +import io.opentelemetry.sdk.metrics.InstrumentType; +import io.opentelemetry.sdk.metrics.data.AggregationTemporality; +import io.opentelemetry.sdk.metrics.data.MetricData; +import io.opentelemetry.sdk.metrics.export.AggregationTemporalitySelector; +import io.opentelemetry.sdk.metrics.export.MetricExporter; +import java.util.Collection; + +public class MetricExporterComponentProvider implements ComponentProvider { + @Override + public Class getType() { + return MetricExporter.class; + } + + @Override + public String getName() { + return "test"; + } + + @Override + public MetricExporter create(StructuredConfigProperties config) { + return new TestMetricExporter(config); + } + + public static class TestMetricExporter implements MetricExporter { + + public final StructuredConfigProperties config; + + private TestMetricExporter(StructuredConfigProperties config) { + this.config = config; + } + + @Override + public AggregationTemporality getAggregationTemporality(InstrumentType instrumentType) { + return AggregationTemporalitySelector.alwaysCumulative() + .getAggregationTemporality(instrumentType); + } + + @Override + public CompletableResultCode export(Collection metrics) { + return CompletableResultCode.ofSuccess(); + } + + @Override + public CompletableResultCode flush() { + return CompletableResultCode.ofSuccess(); + } + + @Override + public CompletableResultCode shutdown() { + return CompletableResultCode.ofSuccess(); + } + } +} diff --git a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/component/SpanExporterComponentProvider.java b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/component/SpanExporterComponentProvider.java new file mode 100644 index 00000000000..f387454f0fd --- /dev/null +++ b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/component/SpanExporterComponentProvider.java @@ -0,0 +1,54 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.sdk.extension.incubator.fileconfig.component; + +import io.opentelemetry.sdk.autoconfigure.spi.internal.ComponentProvider; +import io.opentelemetry.sdk.autoconfigure.spi.internal.StructuredConfigProperties; +import io.opentelemetry.sdk.common.CompletableResultCode; +import io.opentelemetry.sdk.trace.data.SpanData; +import io.opentelemetry.sdk.trace.export.SpanExporter; +import java.util.Collection; + +public class SpanExporterComponentProvider implements ComponentProvider { + @Override + public Class getType() { + return SpanExporter.class; + } + + @Override + public String getName() { + return "test"; + } + + @Override + public SpanExporter create(StructuredConfigProperties config) { + return new TestSpanExporter(config); + } + + public static class TestSpanExporter implements SpanExporter { + + public final StructuredConfigProperties config; + + private TestSpanExporter(StructuredConfigProperties config) { + this.config = config; + } + + @Override + public CompletableResultCode export(Collection spans) { + return CompletableResultCode.ofSuccess(); + } + + @Override + public CompletableResultCode flush() { + return CompletableResultCode.ofSuccess(); + } + + @Override + public CompletableResultCode shutdown() { + return CompletableResultCode.ofSuccess(); + } + } +} diff --git a/sdk-extensions/incubator/src/test/resources/META-INF/services/io.opentelemetry.sdk.autoconfigure.spi.internal.ComponentProvider b/sdk-extensions/incubator/src/test/resources/META-INF/services/io.opentelemetry.sdk.autoconfigure.spi.internal.ComponentProvider new file mode 100644 index 00000000000..0dc2d209e1d --- /dev/null +++ b/sdk-extensions/incubator/src/test/resources/META-INF/services/io.opentelemetry.sdk.autoconfigure.spi.internal.ComponentProvider @@ -0,0 +1,3 @@ +io.opentelemetry.sdk.extension.incubator.fileconfig.component.MetricExporterComponentProvider +io.opentelemetry.sdk.extension.incubator.fileconfig.component.SpanExporterComponentProvider +io.opentelemetry.sdk.extension.incubator.fileconfig.component.LogRecordExporterComponentProvider From 0ffe15cf83bac929874286e50d94937b42484c5d Mon Sep 17 00:00:00 2001 From: jack-berg <34418638+jack-berg@users.noreply.github.com> Date: Mon, 5 Aug 2024 21:34:42 -0500 Subject: [PATCH 500/901] Fix broken link to community contributing guide (#6616) --- CONTRIBUTING.md | 2 +- README.md | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index b2d5d510c9b..c6c78a73621 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -3,7 +3,7 @@ Welcome to OpenTelemetry Java repository! Before you start - see OpenTelemetry general -[contributing](https://github.com/open-telemetry/community/blob/main/CONTRIBUTING.md) +[contributing](https://github.com/open-telemetry/community/blob/main/guides/contributor/README.md) requirements and recommendations. If you want to add new features or change behavior, please make sure your changes follow the diff --git a/README.md b/README.md index ba545f08a51..edd51463736 100644 --- a/README.md +++ b/README.md @@ -298,7 +298,7 @@ Triagers: - [Gregor Zeitlinger](https://github.com/zeitlinger), Grafana Labs -*Find more about the triager role in [community repository](https://github.com/open-telemetry/community/blob/main/community-membership.md#triager).* +*Find more about the triager role in [community repository](https://github.com/open-telemetry/community/blob/main/guides/contributor/membership.md#triager).* Approvers ([@open-telemetry/java-approvers](https://github.com/orgs/open-telemetry/teams/java-approvers)): @@ -307,7 +307,7 @@ Approvers ([@open-telemetry/java-approvers](https://github.com/orgs/open-telemet - [Lauri Tulmin](https://github.com/laurit), Splunk - [Trask Stalnaker](https://github.com/trask), Microsoft -*Find more about the approver role in [community repository](https://github.com/open-telemetry/community/blob/master/community-membership.md#approver).* +*Find more about the approver role in [community repository](https://github.com/open-telemetry/community/blob/main/guides/contributor/membership.md#approver).* Maintainers ([@open-telemetry/java-maintainers](https://github.com/orgs/open-telemetry/teams/java-maintainers)): @@ -320,7 +320,7 @@ Emeritus: - Maintainer [Carlos Alberto](https://github.com/carlosalberto) - Approver [Mateusz Rzeszutek](https://github.com/mateuszrzeszutek) -*Find more about the maintainer role in [community repository](https://github.com/open-telemetry/community/blob/master/community-membership.md#maintainer).* +*Find more about the maintainer role in [community repository](https://github.com/open-telemetry/community/blob/main/guides/contributor/membership.md#maintainer).* ### Thanks to all the people who have contributed From 477658a6ec90d90d97642c2dda1341d753bd62a0 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 6 Aug 2024 18:55:02 -0700 Subject: [PATCH 501/901] Update dependency org.testcontainers:testcontainers-bom to v1.20.1 (#6611) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- dependencyManagement/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index 88344bdb581..7a7587e1c91 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -20,7 +20,7 @@ val DEPENDENCY_BOMS = listOf( "io.zipkin.reporter2:zipkin-reporter-bom:3.4.0", "org.assertj:assertj-bom:3.26.3", "org.junit:junit-bom:5.10.3", - "org.testcontainers:testcontainers-bom:1.20.0", + "org.testcontainers:testcontainers-bom:1.20.1", "org.snakeyaml:snakeyaml-engine:2.7" ) From 5be177df559e5a2d79a171d85e664cb061982183 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 6 Aug 2024 19:55:22 -0700 Subject: [PATCH 502/901] Update dependency org.jetbrains.kotlin:kotlin-gradle-plugin to v2.0.10 (#6621) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- buildSrc/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts index ebf161f5c93..cd5bb0c12d5 100644 --- a/buildSrc/build.gradle.kts +++ b/buildSrc/build.gradle.kts @@ -65,7 +65,7 @@ dependencies { implementation("me.champeau.jmh:jmh-gradle-plugin:0.7.2") implementation("net.ltgt.gradle:gradle-errorprone-plugin:4.0.1") implementation("net.ltgt.gradle:gradle-nullaway-plugin:2.0.0") - implementation("org.jetbrains.kotlin:kotlin-gradle-plugin:2.0.0") + implementation("org.jetbrains.kotlin:kotlin-gradle-plugin:2.0.10") implementation("org.owasp:dependency-check-gradle:10.0.3") implementation("ru.vyarus:gradle-animalsniffer-plugin:1.7.1") } From 04a2b0a841fe3ae33219cd9ee0d86d5d4f096e8d Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 7 Aug 2024 20:06:37 -0700 Subject: [PATCH 503/901] Update dependency org.awaitility:awaitility to v4.2.2 (#6627) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- dependencyManagement/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index 7a7587e1c91..47e1241d85a 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -73,7 +73,7 @@ val DEPENDENCIES = listOf( "io.prometheus:prometheus-metrics-exporter-httpserver:1.3.1", "junit:junit:4.13.2", "nl.jqno.equalsverifier:equalsverifier:3.16.1", - "org.awaitility:awaitility:4.2.1", + "org.awaitility:awaitility:4.2.2", "org.bouncycastle:bcpkix-jdk15on:1.70", "org.codehaus.mojo:animal-sniffer-annotations:1.24", "org.jctools:jctools-core:4.0.5", From 56e7ebe669fc4e1ed461102291850e453746b898 Mon Sep 17 00:00:00 2001 From: jack-berg <34418638+jack-berg@users.noreply.github.com> Date: Thu, 8 Aug 2024 15:08:57 -0500 Subject: [PATCH 504/901] Remove nullable from file config Factory contract (#6612) --- .../autoconfigure/FileConfigurationTest.java | 9 ------ .../fileconfig/AggregationFactory.java | 7 +---- .../fileconfig/AttributesFactory.java | 7 +---- .../incubator/fileconfig/Factory.java | 3 +- .../incubator/fileconfig/FileConfigUtil.java | 7 +++++ .../fileconfig/InstrumentSelectorFactory.java | 7 +---- .../fileconfig/LogLimitsFactory.java | 8 +----- .../fileconfig/LogRecordExporterFactory.java | 15 ++-------- .../fileconfig/LogRecordProcessorFactory.java | 28 +++++++------------ .../fileconfig/LoggerProviderFactory.java | 9 ++---- .../fileconfig/MeterProviderFactory.java | 23 +++++++-------- .../fileconfig/MetricExporterFactory.java | 14 ++-------- .../fileconfig/MetricReaderFactory.java | 26 ++++++----------- .../OpenTelemetryConfigurationFactory.java | 19 ++++++------- .../fileconfig/PropagatorFactory.java | 10 +++---- .../incubator/fileconfig/ResourceFactory.java | 7 +---- .../incubator/fileconfig/SamplerFactory.java | 11 ++------ .../fileconfig/SpanExporterFactory.java | 14 ++-------- .../fileconfig/SpanLimitsFactory.java | 9 +----- .../fileconfig/SpanProcessorFactory.java | 25 ++++++----------- .../fileconfig/TextMapPropagatorFactory.java | 5 ++-- .../fileconfig/TracerProviderFactory.java | 18 +++++------- .../incubator/fileconfig/ViewFactory.java | 8 +----- .../fileconfig/AggregationFactoryTest.java | 11 -------- .../fileconfig/AttributesFactoryTest.java | 8 ------ .../InstrumentSelectorFactoryTest.java | 10 ------- .../fileconfig/LogLimitsFactoryTest.java | 1 - .../LogRecordExporterFactoryTest.java | 6 ---- .../LogRecordProcessorFactoryTest.java | 17 ++--------- .../fileconfig/LoggerProviderFactoryTest.java | 1 - .../fileconfig/MeterProviderFactoryTest.java | 14 ---------- .../fileconfig/MetricExporterFactoryTest.java | 6 ---- .../fileconfig/MetricReaderFactoryTest.java | 10 ++----- ...OpenTelemetryConfigurationFactoryTest.java | 23 +-------------- .../fileconfig/PropagatorFactoryTest.java | 5 ---- .../fileconfig/ResourceFactoryTest.java | 8 ------ .../fileconfig/SamplerFactoryTest.java | 4 --- .../fileconfig/SpanExporterFactoryTest.java | 6 ---- .../fileconfig/SpanLimitsFactoryTest.java | 1 - .../fileconfig/SpanProcessorFactoryTest.java | 17 ++--------- .../TextMapPropagatorFactoryTest.java | 4 --- .../fileconfig/TracerProviderFactoryTest.java | 1 - .../incubator/fileconfig/ViewFactoryTest.java | 12 -------- 43 files changed, 96 insertions(+), 358 deletions(-) diff --git a/sdk-extensions/autoconfigure/src/testFullConfig/java/io/opentelemetry/sdk/autoconfigure/FileConfigurationTest.java b/sdk-extensions/autoconfigure/src/testFullConfig/java/io/opentelemetry/sdk/autoconfigure/FileConfigurationTest.java index f9234de4c65..c49208aa917 100644 --- a/sdk-extensions/autoconfigure/src/testFullConfig/java/io/opentelemetry/sdk/autoconfigure/FileConfigurationTest.java +++ b/sdk-extensions/autoconfigure/src/testFullConfig/java/io/opentelemetry/sdk/autoconfigure/FileConfigurationTest.java @@ -17,11 +17,7 @@ import io.github.netmikey.logunit.api.LogCapturer; import io.opentelemetry.api.GlobalOpenTelemetry; import io.opentelemetry.api.OpenTelemetry; -import io.opentelemetry.api.baggage.propagation.W3CBaggagePropagator; import io.opentelemetry.api.incubator.events.GlobalEventLoggerProvider; -import io.opentelemetry.api.trace.propagation.W3CTraceContextPropagator; -import io.opentelemetry.context.propagation.ContextPropagators; -import io.opentelemetry.context.propagation.TextMapPropagator; import io.opentelemetry.exporter.logging.LoggingSpanExporter; import io.opentelemetry.internal.testing.CleanupExtension; import io.opentelemetry.sdk.OpenTelemetrySdk; @@ -91,11 +87,6 @@ void configFile_Valid() { Resource.getDefault().toBuilder().put("service.name", "test").build()) .addSpanProcessor(SimpleSpanProcessor.create(LoggingSpanExporter.create())) .build()) - .setPropagators( - ContextPropagators.create( - TextMapPropagator.composite( - W3CTraceContextPropagator.getInstance(), - W3CBaggagePropagator.getInstance()))) .build(); cleanup.addCloseable(expectedSdk); AutoConfiguredOpenTelemetrySdkBuilder builder = spy(AutoConfiguredOpenTelemetrySdk.builder()); diff --git a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/AggregationFactory.java b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/AggregationFactory.java index 726177d65a6..45feb74c8cc 100644 --- a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/AggregationFactory.java +++ b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/AggregationFactory.java @@ -12,7 +12,6 @@ import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.ExplicitBucketHistogram; import java.io.Closeable; import java.util.List; -import javax.annotation.Nullable; final class AggregationFactory implements Factory { @@ -27,11 +26,7 @@ static AggregationFactory getInstance() { @Override public io.opentelemetry.sdk.metrics.Aggregation create( - @Nullable Aggregation model, SpiHelper spiHelper, List closeables) { - if (model == null) { - return io.opentelemetry.sdk.metrics.Aggregation.defaultAggregation(); - } - + Aggregation model, SpiHelper spiHelper, List closeables) { if (model.getDrop() != null) { return io.opentelemetry.sdk.metrics.Aggregation.drop(); } diff --git a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/AttributesFactory.java b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/AttributesFactory.java index 22a9273cd8f..70cd2e186ae 100644 --- a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/AttributesFactory.java +++ b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/AttributesFactory.java @@ -14,7 +14,6 @@ import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.Attributes; import java.io.Closeable; import java.util.List; -import javax.annotation.Nullable; final class AttributesFactory implements Factory { @@ -29,11 +28,7 @@ static AttributesFactory getInstance() { @Override public io.opentelemetry.api.common.Attributes create( - @Nullable Attributes model, SpiHelper spiHelper, List closeables) { - if (model == null) { - return io.opentelemetry.api.common.Attributes.empty(); - } - + Attributes model, SpiHelper spiHelper, List closeables) { AttributesBuilder builder = io.opentelemetry.api.common.Attributes.builder(); String serviceName = model.getServiceName(); diff --git a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/Factory.java b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/Factory.java index 609fcd4f902..c5f5e7c59d3 100644 --- a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/Factory.java +++ b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/Factory.java @@ -8,7 +8,6 @@ import io.opentelemetry.sdk.autoconfigure.internal.SpiHelper; import java.io.Closeable; import java.util.List; -import javax.annotation.Nullable; interface Factory { @@ -20,5 +19,5 @@ interface Factory { * @param closeables mutable list of closeables created * @return the {@link ResultT} */ - ResultT create(@Nullable ModelT model, SpiHelper spiHelper, List closeables); + ResultT create(ModelT model, SpiHelper spiHelper, List closeables); } diff --git a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/FileConfigUtil.java b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/FileConfigUtil.java index 4dfdcbd5565..75fd08858a7 100644 --- a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/FileConfigUtil.java +++ b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/FileConfigUtil.java @@ -32,6 +32,13 @@ static T assertNotNull(@Nullable T object, String description) { return object; } + static T requireNonNull(@Nullable T object, String description) { + if (object == null) { + throw new ConfigurationException(description + " is required but is null"); + } + return object; + } + /** * Find a registered {@link ComponentProvider} which {@link ComponentProvider#getType()} matching * {@code type}, {@link ComponentProvider#getName()} matching {@code name}, and call {@link diff --git a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/InstrumentSelectorFactory.java b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/InstrumentSelectorFactory.java index ec117228b64..f89a94ea507 100644 --- a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/InstrumentSelectorFactory.java +++ b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/InstrumentSelectorFactory.java @@ -13,7 +13,6 @@ import io.opentelemetry.sdk.metrics.InstrumentType; import java.io.Closeable; import java.util.List; -import javax.annotation.Nullable; final class InstrumentSelectorFactory implements Factory { @@ -27,11 +26,7 @@ static InstrumentSelectorFactory getInstance() { @Override public InstrumentSelector create( - @Nullable Selector model, SpiHelper spiHelper, List closeables) { - if (model == null) { - throw new ConfigurationException("selector must not be null"); - } - + Selector model, SpiHelper spiHelper, List closeables) { InstrumentSelectorBuilder builder = InstrumentSelector.builder(); if (model.getInstrumentName() != null) { builder.setName(model.getInstrumentName()); diff --git a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/LogLimitsFactory.java b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/LogLimitsFactory.java index d4a7dea5c16..765fdd5100e 100644 --- a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/LogLimitsFactory.java +++ b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/LogLimitsFactory.java @@ -12,7 +12,6 @@ import io.opentelemetry.sdk.logs.LogLimitsBuilder; import java.io.Closeable; import java.util.List; -import javax.annotation.Nullable; final class LogLimitsFactory implements Factory { @@ -26,12 +25,7 @@ static LogLimitsFactory getInstance() { @Override public LogLimits create( - @Nullable LogRecordLimitsAndAttributeLimits model, - SpiHelper spiHelper, - List closeables) { - if (model == null) { - return LogLimits.getDefault(); - } + LogRecordLimitsAndAttributeLimits model, SpiHelper spiHelper, List closeables) { LogLimitsBuilder builder = LogLimits.builder(); AttributeLimits attributeLimitsModel = model.getAttributeLimits(); diff --git a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/LogRecordExporterFactory.java b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/LogRecordExporterFactory.java index f930c2846ef..58ce105eddd 100644 --- a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/LogRecordExporterFactory.java +++ b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/LogRecordExporterFactory.java @@ -14,7 +14,6 @@ import java.io.Closeable; import java.util.List; import java.util.Map; -import javax.annotation.Nullable; final class LogRecordExporterFactory implements Factory< @@ -29,19 +28,11 @@ static LogRecordExporterFactory getInstance() { return INSTANCE; } - @SuppressWarnings("NullAway") // Override superclass non-null response @Override - @Nullable public LogRecordExporter create( - @Nullable - io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.LogRecordExporter - model, + io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.LogRecordExporter model, SpiHelper spiHelper, List closeables) { - if (model == null) { - return null; - } - Otlp otlpModel = model.getOtlp(); if (otlpModel != null) { model.getAdditionalProperties().put("otlp", otlpModel); @@ -67,8 +58,8 @@ public LogRecordExporter create( exporterKeyValue.getKey(), exporterKeyValue.getValue()); return FileConfigUtil.addAndReturn(closeables, logRecordExporter); + } else { + throw new ConfigurationException("log exporter must be set"); } - - return null; } } diff --git a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/LogRecordProcessorFactory.java b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/LogRecordProcessorFactory.java index aaf472beec7..78183f19232 100644 --- a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/LogRecordProcessorFactory.java +++ b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/LogRecordProcessorFactory.java @@ -17,7 +17,6 @@ import java.io.Closeable; import java.time.Duration; import java.util.List; -import javax.annotation.Nullable; final class LogRecordProcessorFactory implements Factory< @@ -34,24 +33,18 @@ static LogRecordProcessorFactory getInstance() { @Override public LogRecordProcessor create( - @Nullable - io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.LogRecordProcessor - model, + io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.LogRecordProcessor model, SpiHelper spiHelper, List closeables) { - if (model == null) { - return LogRecordProcessor.composite(); - } - io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.BatchLogRecordProcessor batchModel = model.getBatch(); if (batchModel != null) { - LogRecordExporter exporterModel = batchModel.getExporter(); + LogRecordExporter exporterModel = + FileConfigUtil.requireNonNull( + batchModel.getExporter(), "batch log record processor exporter"); + io.opentelemetry.sdk.logs.export.LogRecordExporter logRecordExporter = LogRecordExporterFactory.getInstance().create(exporterModel, spiHelper, closeables); - if (logRecordExporter == null) { - throw new ConfigurationException("exporter required for batch log record processor"); - } BatchLogRecordProcessorBuilder builder = BatchLogRecordProcessor.builder(logRecordExporter); if (batchModel.getExportTimeout() != null) { builder.setExporterTimeout(Duration.ofMillis(batchModel.getExportTimeout())); @@ -71,12 +64,11 @@ public LogRecordProcessor create( io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.SimpleLogRecordProcessor simpleModel = model.getSimple(); if (simpleModel != null) { - LogRecordExporter exporterModel = simpleModel.getExporter(); + LogRecordExporter exporterModel = + FileConfigUtil.requireNonNull( + simpleModel.getExporter(), "simple log record processor exporter"); io.opentelemetry.sdk.logs.export.LogRecordExporter logRecordExporter = LogRecordExporterFactory.getInstance().create(exporterModel, spiHelper, closeables); - if (logRecordExporter == null) { - throw new ConfigurationException("exporter required for simple log record processor"); - } return FileConfigUtil.addAndReturn( closeables, SimpleLogRecordProcessor.create(logRecordExporter)); } @@ -86,8 +78,8 @@ public LogRecordProcessor create( throw new ConfigurationException( "Unrecognized log record processor(s): " + model.getAdditionalProperties().keySet().stream().collect(joining(",", "[", "]"))); + } else { + throw new ConfigurationException("log processor must be set"); } - - return LogRecordProcessor.composite(); } } diff --git a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/LoggerProviderFactory.java b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/LoggerProviderFactory.java index 36bbce54566..3d46098ae9e 100644 --- a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/LoggerProviderFactory.java +++ b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/LoggerProviderFactory.java @@ -13,7 +13,6 @@ import io.opentelemetry.sdk.logs.SdkLoggerProviderBuilder; import java.io.Closeable; import java.util.List; -import javax.annotation.Nullable; final class LoggerProviderFactory implements Factory { @@ -28,13 +27,9 @@ static LoggerProviderFactory getInstance() { @Override public SdkLoggerProviderBuilder create( - @Nullable LoggerProviderAndAttributeLimits model, - SpiHelper spiHelper, - List closeables) { + LoggerProviderAndAttributeLimits model, SpiHelper spiHelper, List closeables) { SdkLoggerProviderBuilder builder = SdkLoggerProvider.builder(); - if (model == null) { - return builder; - } + LoggerProvider loggerProviderModel = model.getLoggerProvider(); if (loggerProviderModel == null) { return builder; diff --git a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/MeterProviderFactory.java b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/MeterProviderFactory.java index 0acb6c703f0..c675920a797 100644 --- a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/MeterProviderFactory.java +++ b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/MeterProviderFactory.java @@ -5,15 +5,18 @@ package io.opentelemetry.sdk.extension.incubator.fileconfig; +import static io.opentelemetry.sdk.extension.incubator.fileconfig.FileConfigUtil.requireNonNull; + import io.opentelemetry.sdk.autoconfigure.internal.SpiHelper; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.MeterProvider; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.MetricReader; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.Selector; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.Stream; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.View; import io.opentelemetry.sdk.metrics.SdkMeterProvider; import io.opentelemetry.sdk.metrics.SdkMeterProviderBuilder; import java.io.Closeable; import java.util.List; -import javax.annotation.Nullable; final class MeterProviderFactory implements Factory { @@ -27,11 +30,7 @@ static MeterProviderFactory getInstance() { @Override public SdkMeterProviderBuilder create( - @Nullable MeterProvider model, SpiHelper spiHelper, List closeables) { - if (model == null) { - return SdkMeterProvider.builder(); - } - + MeterProvider model, SpiHelper spiHelper, List closeables) { SdkMeterProviderBuilder builder = SdkMeterProvider.builder(); List readerModels = model.getReaders(); @@ -49,11 +48,13 @@ public SdkMeterProviderBuilder create( List viewModels = model.getViews(); if (viewModels != null) { viewModels.forEach( - viewModel -> - builder.registerView( - InstrumentSelectorFactory.getInstance() - .create(viewModel.getSelector(), spiHelper, closeables), - ViewFactory.getInstance().create(viewModel.getStream(), spiHelper, closeables))); + viewModel -> { + Selector selector = requireNonNull(viewModel.getSelector(), "view selector"); + Stream stream = requireNonNull(viewModel.getStream(), "view stream"); + builder.registerView( + InstrumentSelectorFactory.getInstance().create(selector, spiHelper, closeables), + ViewFactory.getInstance().create(stream, spiHelper, closeables)); + }); } return builder; diff --git a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/MetricExporterFactory.java b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/MetricExporterFactory.java index 7bba4b843f0..f614761728a 100644 --- a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/MetricExporterFactory.java +++ b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/MetricExporterFactory.java @@ -14,7 +14,6 @@ import java.io.Closeable; import java.util.List; import java.util.Map; -import javax.annotation.Nullable; final class MetricExporterFactory implements Factory< @@ -29,18 +28,11 @@ static MetricExporterFactory getInstance() { return INSTANCE; } - @SuppressWarnings("NullAway") // Override superclass non-null response @Override - @Nullable public MetricExporter create( - @Nullable - io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.MetricExporter model, + io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.MetricExporter model, SpiHelper spiHelper, List closeables) { - if (model == null) { - return null; - } - OtlpMetric otlpModel = model.getOtlp(); if (otlpModel != null) { model.getAdditionalProperties().put("otlp", otlpModel); @@ -74,8 +66,8 @@ public MetricExporter create( exporterKeyValue.getKey(), exporterKeyValue.getValue()); return FileConfigUtil.addAndReturn(closeables, metricExporter); + } else { + throw new ConfigurationException("metric exporter must be set"); } - - return null; } } diff --git a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/MetricReaderFactory.java b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/MetricReaderFactory.java index 3a049ab2689..00f3dfa17a0 100644 --- a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/MetricReaderFactory.java +++ b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/MetricReaderFactory.java @@ -5,6 +5,8 @@ package io.opentelemetry.sdk.extension.incubator.fileconfig; +import static io.opentelemetry.sdk.extension.incubator.fileconfig.FileConfigUtil.requireNonNull; + import io.opentelemetry.sdk.autoconfigure.internal.SpiHelper; import io.opentelemetry.sdk.autoconfigure.spi.ConfigurationException; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.MetricExporter; @@ -16,7 +18,6 @@ import java.io.Closeable; import java.time.Duration; import java.util.List; -import javax.annotation.Nullable; final class MetricReaderFactory implements Factory< @@ -31,26 +32,17 @@ static MetricReaderFactory getInstance() { return INSTANCE; } - @SuppressWarnings("NullAway") // Override superclass non-null response @Override - @Nullable public MetricReader create( - @Nullable - io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.MetricReader model, + io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.MetricReader model, SpiHelper spiHelper, List closeables) { - if (model == null) { - return null; - } - PeriodicMetricReader periodicModel = model.getPeriodic(); if (periodicModel != null) { - MetricExporter exporterModel = periodicModel.getExporter(); + MetricExporter exporterModel = + requireNonNull(periodicModel.getExporter(), "periodic metric reader exporter"); io.opentelemetry.sdk.metrics.export.MetricExporter metricExporter = MetricExporterFactory.getInstance().create(exporterModel, spiHelper, closeables); - if (metricExporter == null) { - throw new ConfigurationException("exporter required for periodic reader"); - } PeriodicMetricReaderBuilder builder = io.opentelemetry.sdk.metrics.export.PeriodicMetricReader.builder( FileConfigUtil.addAndReturn(closeables, metricExporter)); @@ -62,10 +54,8 @@ public MetricReader create( PullMetricReader pullModel = model.getPull(); if (pullModel != null) { - MetricExporter exporterModel = pullModel.getExporter(); - if (exporterModel == null) { - throw new ConfigurationException("exporter required for pull reader"); - } + MetricExporter exporterModel = + requireNonNull(pullModel.getExporter(), "pull metric reader exporter"); Prometheus prometheusModel = exporterModel.getPrometheus(); if (prometheusModel != null) { MetricReader metricReader = @@ -77,6 +67,6 @@ public MetricReader create( throw new ConfigurationException("prometheus is the only currently supported pull reader"); } - return null; + throw new ConfigurationException("reader must be set"); } } diff --git a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/OpenTelemetryConfigurationFactory.java b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/OpenTelemetryConfigurationFactory.java index cb2b52a8472..1677361d8ae 100644 --- a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/OpenTelemetryConfigurationFactory.java +++ b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/OpenTelemetryConfigurationFactory.java @@ -14,7 +14,6 @@ import java.io.Closeable; import java.util.List; import java.util.Objects; -import javax.annotation.Nullable; final class OpenTelemetryConfigurationFactory implements Factory { @@ -30,12 +29,8 @@ static OpenTelemetryConfigurationFactory getInstance() { @Override public OpenTelemetrySdk create( - @Nullable OpenTelemetryConfiguration model, SpiHelper spiHelper, List closeables) { + OpenTelemetryConfiguration model, SpiHelper spiHelper, List closeables) { OpenTelemetrySdkBuilder builder = OpenTelemetrySdk.builder(); - if (model == null) { - return FileConfigUtil.addAndReturn(closeables, builder.build()); - } - if (!"0.1".equals(model.getFileFormat())) { throw new ConfigurationException("Unsupported file format. Supported formats include: 0.1"); } @@ -44,11 +39,15 @@ public OpenTelemetrySdk create( return builder.build(); } - builder.setPropagators( - PropagatorFactory.getInstance().create(model.getPropagator(), spiHelper, closeables)); + if (model.getPropagator() != null) { + builder.setPropagators( + PropagatorFactory.getInstance().create(model.getPropagator(), spiHelper, closeables)); + } - Resource resource = - ResourceFactory.getInstance().create(model.getResource(), spiHelper, closeables); + Resource resource = Resource.getDefault(); + if (model.getResource() != null) { + resource = ResourceFactory.getInstance().create(model.getResource(), spiHelper, closeables); + } if (model.getLoggerProvider() != null) { builder.setLoggerProvider( diff --git a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/PropagatorFactory.java b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/PropagatorFactory.java index d53c3beda76..d9572fd8406 100644 --- a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/PropagatorFactory.java +++ b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/PropagatorFactory.java @@ -5,13 +5,14 @@ package io.opentelemetry.sdk.extension.incubator.fileconfig; +import static io.opentelemetry.sdk.extension.incubator.fileconfig.FileConfigUtil.requireNonNull; + import io.opentelemetry.context.propagation.ContextPropagators; import io.opentelemetry.context.propagation.TextMapPropagator; import io.opentelemetry.sdk.autoconfigure.internal.SpiHelper; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.Propagator; import java.io.Closeable; import java.util.List; -import javax.annotation.Nullable; final class PropagatorFactory implements Factory { @@ -25,11 +26,8 @@ static PropagatorFactory getInstance() { @Override public ContextPropagators create( - @Nullable Propagator model, SpiHelper spiHelper, List closeables) { - List compositeModel = null; - if (model != null) { - compositeModel = model.getComposite(); - } + Propagator model, SpiHelper spiHelper, List closeables) { + List compositeModel = requireNonNull(model.getComposite(), "composite propagator"); TextMapPropagator textMapPropagator = TextMapPropagatorFactory.getInstance().create(compositeModel, spiHelper, closeables); return ContextPropagators.create(textMapPropagator); diff --git a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/ResourceFactory.java b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/ResourceFactory.java index 47ec3b6606a..04a0de2bcac 100644 --- a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/ResourceFactory.java +++ b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/ResourceFactory.java @@ -11,7 +11,6 @@ import io.opentelemetry.sdk.resources.ResourceBuilder; import java.io.Closeable; import java.util.List; -import javax.annotation.Nullable; final class ResourceFactory implements Factory { @@ -25,11 +24,7 @@ static ResourceFactory getInstance() { @Override public io.opentelemetry.sdk.resources.Resource create( - @Nullable Resource model, SpiHelper spiHelper, List closeables) { - if (model == null) { - return io.opentelemetry.sdk.resources.Resource.getDefault(); - } - + Resource model, SpiHelper spiHelper, List closeables) { ResourceBuilder builder = io.opentelemetry.sdk.resources.Resource.getDefault().toBuilder(); Attributes attributesModel = model.getAttributes(); diff --git a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/SamplerFactory.java b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/SamplerFactory.java index 8d881c2d03e..f900015f8c4 100644 --- a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/SamplerFactory.java +++ b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/SamplerFactory.java @@ -23,7 +23,6 @@ import java.util.HashMap; import java.util.List; import java.util.Map; -import javax.annotation.Nullable; final class SamplerFactory implements Factory< @@ -39,13 +38,9 @@ static SamplerFactory getInstance() { @Override public Sampler create( - @Nullable io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.Sampler model, + io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.Sampler model, SpiHelper spiHelper, List closeables) { - if (model == null) { - return Sampler.parentBased(Sampler.alwaysOn()); - } - if (model.getAlwaysOn() != null) { return Sampler.alwaysOn(); } @@ -121,9 +116,9 @@ public Sampler create( throw new ConfigurationException( "Unrecognized sampler(s): " + model.getAdditionalProperties().keySet().stream().collect(joining(",", "[", "]"))); + } else { + throw new ConfigurationException("sampler must be set"); } - - return Sampler.parentBased(Sampler.alwaysOn()); } private static NamedSpiManager samplerSpiManager( diff --git a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/SpanExporterFactory.java b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/SpanExporterFactory.java index cf2c866bc3c..a48af93fb75 100644 --- a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/SpanExporterFactory.java +++ b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/SpanExporterFactory.java @@ -15,7 +15,6 @@ import java.io.Closeable; import java.util.List; import java.util.Map; -import javax.annotation.Nullable; final class SpanExporterFactory implements Factory< @@ -30,18 +29,11 @@ static SpanExporterFactory getInstance() { return INSTANCE; } - @SuppressWarnings("NullAway") // Override superclass non-null response @Override - @Nullable public SpanExporter create( - @Nullable - io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.SpanExporter model, + io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.SpanExporter model, SpiHelper spiHelper, List closeables) { - if (model == null) { - return null; - } - Otlp otlpModel = model.getOtlp(); if (otlpModel != null) { model.getAdditionalProperties().put("otlp", otlpModel); @@ -76,8 +68,8 @@ public SpanExporter create( exporterKeyValue.getKey(), exporterKeyValue.getValue()); return FileConfigUtil.addAndReturn(closeables, spanExporter); + } else { + throw new ConfigurationException("span exporter must be set"); } - - return null; } } diff --git a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/SpanLimitsFactory.java b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/SpanLimitsFactory.java index ef03ad70ca8..b3e83b7a2ba 100644 --- a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/SpanLimitsFactory.java +++ b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/SpanLimitsFactory.java @@ -11,7 +11,6 @@ import io.opentelemetry.sdk.trace.SpanLimitsBuilder; import java.io.Closeable; import java.util.List; -import javax.annotation.Nullable; final class SpanLimitsFactory implements Factory { @@ -26,13 +25,7 @@ static SpanLimitsFactory getInstance() { @Override public io.opentelemetry.sdk.trace.SpanLimits create( - @Nullable SpanLimitsAndAttributeLimits model, - SpiHelper spiHelper, - List closeables) { - if (model == null) { - return io.opentelemetry.sdk.trace.SpanLimits.getDefault(); - } - + SpanLimitsAndAttributeLimits model, SpiHelper spiHelper, List closeables) { SpanLimitsBuilder builder = io.opentelemetry.sdk.trace.SpanLimits.builder(); AttributeLimits attributeLimitsModel = model.getAttributeLimits(); diff --git a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/SpanProcessorFactory.java b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/SpanProcessorFactory.java index 6536f0bf3ca..d0c50ebaa61 100644 --- a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/SpanProcessorFactory.java +++ b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/SpanProcessorFactory.java @@ -17,7 +17,6 @@ import java.io.Closeable; import java.time.Duration; import java.util.List; -import javax.annotation.Nullable; final class SpanProcessorFactory implements Factory< @@ -34,23 +33,16 @@ static SpanProcessorFactory getInstance() { @Override public SpanProcessor create( - @Nullable - io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.SpanProcessor model, + io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.SpanProcessor model, SpiHelper spiHelper, List closeables) { - if (model == null) { - return SpanProcessor.composite(); - } - io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.BatchSpanProcessor batchModel = model.getBatch(); if (batchModel != null) { - SpanExporter exporterModel = batchModel.getExporter(); + SpanExporter exporterModel = + FileConfigUtil.requireNonNull(batchModel.getExporter(), "batch span processor exporter"); io.opentelemetry.sdk.trace.export.SpanExporter spanExporter = SpanExporterFactory.getInstance().create(exporterModel, spiHelper, closeables); - if (spanExporter == null) { - throw new ConfigurationException("exporter required for batch span processor"); - } BatchSpanProcessorBuilder builder = BatchSpanProcessor.builder(spanExporter); if (batchModel.getExportTimeout() != null) { builder.setExporterTimeout(Duration.ofMillis(batchModel.getExportTimeout())); @@ -70,12 +62,11 @@ public SpanProcessor create( io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.SimpleSpanProcessor simpleModel = model.getSimple(); if (simpleModel != null) { - SpanExporter exporterModel = simpleModel.getExporter(); + SpanExporter exporterModel = + FileConfigUtil.requireNonNull( + simpleModel.getExporter(), "simple span processor exporter"); io.opentelemetry.sdk.trace.export.SpanExporter spanExporter = SpanExporterFactory.getInstance().create(exporterModel, spiHelper, closeables); - if (spanExporter == null) { - throw new ConfigurationException("exporter required for simple span processor"); - } return FileConfigUtil.addAndReturn(closeables, SimpleSpanProcessor.create(spanExporter)); } @@ -84,8 +75,8 @@ public SpanProcessor create( throw new ConfigurationException( "Unrecognized span processor(s): " + model.getAdditionalProperties().keySet().stream().collect(joining(",", "[", "]"))); + } else { + throw new ConfigurationException("span processor must be set"); } - - return SpanProcessor.composite(); } } diff --git a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/TextMapPropagatorFactory.java b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/TextMapPropagatorFactory.java index 4451ac98516..965093d1c6b 100644 --- a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/TextMapPropagatorFactory.java +++ b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/TextMapPropagatorFactory.java @@ -19,7 +19,6 @@ import java.util.LinkedHashSet; import java.util.List; import java.util.Set; -import javax.annotation.Nullable; final class TextMapPropagatorFactory implements Factory, TextMapPropagator> { @@ -33,8 +32,8 @@ static TextMapPropagatorFactory getInstance() { @Override public TextMapPropagator create( - @Nullable List model, SpiHelper spiHelper, List closeables) { - if (model == null || model.isEmpty()) { + List model, SpiHelper spiHelper, List closeables) { + if (model.isEmpty()) { model = Arrays.asList("tracecontext", "baggage"); } diff --git a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/TracerProviderFactory.java b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/TracerProviderFactory.java index e5940749b55..ff8000806c7 100644 --- a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/TracerProviderFactory.java +++ b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/TracerProviderFactory.java @@ -14,7 +14,6 @@ import io.opentelemetry.sdk.trace.samplers.Sampler; import java.io.Closeable; import java.util.List; -import javax.annotation.Nullable; final class TracerProviderFactory implements Factory { @@ -29,13 +28,8 @@ static TracerProviderFactory getInstance() { @Override public SdkTracerProviderBuilder create( - @Nullable TracerProviderAndAttributeLimits model, - SpiHelper spiHelper, - List closeables) { + TracerProviderAndAttributeLimits model, SpiHelper spiHelper, List closeables) { SdkTracerProviderBuilder builder = SdkTracerProvider.builder(); - if (model == null) { - return builder; - } TracerProvider tracerProviderModel = model.getTracerProvider(); if (tracerProviderModel == null) { return builder; @@ -50,10 +44,12 @@ public SdkTracerProviderBuilder create( closeables); builder.setSpanLimits(spanLimits); - Sampler sampler = - SamplerFactory.getInstance() - .create(tracerProviderModel.getSampler(), spiHelper, closeables); - builder.setSampler(sampler); + if (tracerProviderModel.getSampler() != null) { + Sampler sampler = + SamplerFactory.getInstance() + .create(tracerProviderModel.getSampler(), spiHelper, closeables); + builder.setSampler(sampler); + } List processors = tracerProviderModel.getProcessors(); if (processors != null) { diff --git a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/ViewFactory.java b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/ViewFactory.java index 77a66833761..cb23d699ecc 100644 --- a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/ViewFactory.java +++ b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/ViewFactory.java @@ -6,14 +6,12 @@ package io.opentelemetry.sdk.extension.incubator.fileconfig; import io.opentelemetry.sdk.autoconfigure.internal.SpiHelper; -import io.opentelemetry.sdk.autoconfigure.spi.ConfigurationException; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.Stream; import io.opentelemetry.sdk.metrics.View; import io.opentelemetry.sdk.metrics.ViewBuilder; import java.io.Closeable; import java.util.HashSet; import java.util.List; -import javax.annotation.Nullable; final class ViewFactory implements Factory { @@ -26,11 +24,7 @@ static ViewFactory getInstance() { } @Override - public View create(@Nullable Stream model, SpiHelper spiHelper, List closeables) { - if (model == null) { - throw new ConfigurationException("stream must not be null"); - } - + public View create(Stream model, SpiHelper spiHelper, List closeables) { ViewBuilder builder = View.builder(); if (model.getName() != null) { builder.setName(model.getName()); diff --git a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/AggregationFactoryTest.java b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/AggregationFactoryTest.java index 1f0c6faf5ca..8e7dafad412 100644 --- a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/AggregationFactoryTest.java +++ b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/AggregationFactoryTest.java @@ -17,24 +17,13 @@ import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.Sum; import java.util.ArrayList; import java.util.Arrays; -import java.util.Collections; import java.util.stream.Stream; -import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.MethodSource; class AggregationFactoryTest { - @Test - void create_Null() { - assertThat( - AggregationFactory.getInstance() - .create(null, mock(SpiHelper.class), Collections.emptyList()) - .toString()) - .isEqualTo(io.opentelemetry.sdk.metrics.Aggregation.defaultAggregation().toString()); - } - @ParameterizedTest @MethodSource("createTestCases") void create(Aggregation model, io.opentelemetry.sdk.metrics.Aggregation expectedResult) { diff --git a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/AttributesFactoryTest.java b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/AttributesFactoryTest.java index dc32aa6fe28..e50fa61209d 100644 --- a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/AttributesFactoryTest.java +++ b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/AttributesFactoryTest.java @@ -22,14 +22,6 @@ class AttributesFactoryTest { - @Test - void create_Null() { - assertThat( - AttributesFactory.getInstance() - .create(null, mock(SpiHelper.class), Collections.emptyList())) - .isEqualTo(io.opentelemetry.api.common.Attributes.empty()); - } - @ParameterizedTest @MethodSource("invalidAttributes") void create_InvalidAttributes(Attributes model, String expectedMessage) { diff --git a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/InstrumentSelectorFactoryTest.java b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/InstrumentSelectorFactoryTest.java index c10b6394bc4..9b3ada1a6fe 100644 --- a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/InstrumentSelectorFactoryTest.java +++ b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/InstrumentSelectorFactoryTest.java @@ -19,16 +19,6 @@ class InstrumentSelectorFactoryTest { - @Test - void create_Null() { - assertThatThrownBy( - () -> - InstrumentSelectorFactory.getInstance() - .create(null, mock(SpiHelper.class), Collections.emptyList())) - .isInstanceOf(ConfigurationException.class) - .hasMessage("selector must not be null"); - } - @Test void create_Defaults() { assertThatThrownBy( diff --git a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/LogLimitsFactoryTest.java b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/LogLimitsFactoryTest.java index 49a0b337af2..492b8c4b425 100644 --- a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/LogLimitsFactoryTest.java +++ b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/LogLimitsFactoryTest.java @@ -31,7 +31,6 @@ void create(LogRecordLimitsAndAttributeLimits model, LogLimits expectedLogLimits private static Stream createArguments() { return Stream.of( - Arguments.of(null, LogLimits.builder().build()), Arguments.of( LogRecordLimitsAndAttributeLimits.create(null, null), LogLimits.builder().build()), Arguments.of( diff --git a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/LogRecordExporterFactoryTest.java b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/LogRecordExporterFactoryTest.java index 7a8815d57ce..a2a6d057139 100644 --- a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/LogRecordExporterFactoryTest.java +++ b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/LogRecordExporterFactoryTest.java @@ -56,12 +56,6 @@ class LogRecordExporterFactoryTest { private SpiHelper spiHelper = SpiHelper.create(LogRecordExporterFactoryTest.class.getClassLoader()); - @Test - void create_Null() { - assertThat(LogRecordExporterFactory.getInstance().create(null, spiHelper, new ArrayList<>())) - .isNull(); - } - @Test void create_OtlpDefaults() { spiHelper = spy(spiHelper); diff --git a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/LogRecordProcessorFactoryTest.java b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/LogRecordProcessorFactoryTest.java index 7a9e632d2b3..06ad307ee06 100644 --- a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/LogRecordProcessorFactoryTest.java +++ b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/LogRecordProcessorFactoryTest.java @@ -33,19 +33,6 @@ class LogRecordProcessorFactoryTest { private final SpiHelper spiHelper = SpiHelper.create(LogRecordProcessorFactoryTest.class.getClassLoader()); - @Test - void create_Null() { - List closeables = new ArrayList<>(); - - io.opentelemetry.sdk.logs.LogRecordProcessor processor = - LogRecordProcessorFactory.getInstance().create(null, spiHelper, Collections.emptyList()); - cleanup.addCloseable(processor); - cleanup.addCloseables(closeables); - - assertThat(processor.toString()) - .isEqualTo(io.opentelemetry.sdk.logs.LogRecordProcessor.composite().toString()); - } - @Test void create_BatchNullExporter() { assertThatThrownBy( @@ -56,7 +43,7 @@ void create_BatchNullExporter() { spiHelper, Collections.emptyList())) .isInstanceOf(ConfigurationException.class) - .hasMessage("exporter required for batch log record processor"); + .hasMessage("batch log record processor exporter is required but is null"); } @Test @@ -123,7 +110,7 @@ void create_SimpleNullExporter() { spiHelper, Collections.emptyList())) .isInstanceOf(ConfigurationException.class) - .hasMessage("exporter required for simple log record processor"); + .hasMessage("simple log record processor exporter is required but is null"); } @Test diff --git a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/LoggerProviderFactoryTest.java b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/LoggerProviderFactoryTest.java index 4ab9403b425..312c8dc85d4 100644 --- a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/LoggerProviderFactoryTest.java +++ b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/LoggerProviderFactoryTest.java @@ -52,7 +52,6 @@ void create(LoggerProviderAndAttributeLimits model, SdkLoggerProvider expectedPr private static Stream createArguments() { return Stream.of( - Arguments.of(null, SdkLoggerProvider.builder().build()), Arguments.of( LoggerProviderAndAttributeLimits.create(null, null), SdkLoggerProvider.builder().build()), diff --git a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/MeterProviderFactoryTest.java b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/MeterProviderFactoryTest.java index bdcc24626a7..b2ac1d838d0 100644 --- a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/MeterProviderFactoryTest.java +++ b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/MeterProviderFactoryTest.java @@ -34,20 +34,6 @@ class MeterProviderFactoryTest { private final SpiHelper spiHelper = SpiHelper.create(MeterProviderFactoryTest.class.getClassLoader()); - @Test - void create_Null() { - List closeables = new ArrayList<>(); - SdkMeterProvider expectedProvider = SdkMeterProvider.builder().build(); - cleanup.addCloseable(expectedProvider); - - SdkMeterProvider provider = - MeterProviderFactory.getInstance().create(null, spiHelper, closeables).build(); - cleanup.addCloseable(provider); - cleanup.addCloseables(closeables); - - assertThat(provider.toString()).isEqualTo(expectedProvider.toString()); - } - @Test void create_Defaults() { List closeables = new ArrayList<>(); diff --git a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/MetricExporterFactoryTest.java b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/MetricExporterFactoryTest.java index dd8cca69107..8356339e063 100644 --- a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/MetricExporterFactoryTest.java +++ b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/MetricExporterFactoryTest.java @@ -63,12 +63,6 @@ class MetricExporterFactoryTest { private SpiHelper spiHelper = SpiHelper.create(MetricExporterFactoryTest.class.getClassLoader()); - @Test - void create_Null() { - assertThat(MetricExporterFactory.getInstance().create(null, spiHelper, new ArrayList<>())) - .isNull(); - } - @Test void create_OtlpDefaults() { spiHelper = spy(spiHelper); diff --git a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/MetricReaderFactoryTest.java b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/MetricReaderFactoryTest.java index 3bd03e33c8d..22a7d36106d 100644 --- a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/MetricReaderFactoryTest.java +++ b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/MetricReaderFactoryTest.java @@ -43,12 +43,6 @@ class MetricReaderFactoryTest { private SpiHelper spiHelper = SpiHelper.create(MetricReaderFactoryTest.class.getClassLoader()); - @Test - void create_Null() { - assertThat(MetricReaderFactory.getInstance().create(null, spiHelper, Collections.emptyList())) - .isNull(); - } - @Test void create_PeriodicNullExporter() { assertThatThrownBy( @@ -59,7 +53,7 @@ void create_PeriodicNullExporter() { spiHelper, Collections.emptyList())) .isInstanceOf(ConfigurationException.class) - .hasMessage("exporter required for periodic reader"); + .hasMessage("periodic metric reader exporter is required but is null"); } @Test @@ -181,7 +175,7 @@ void create_InvalidPullReader() { spiHelper, Collections.emptyList())) .isInstanceOf(ConfigurationException.class) - .hasMessage("exporter required for pull reader"); + .hasMessage("pull metric reader exporter is required but is null"); assertThatThrownBy( () -> diff --git a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/OpenTelemetryConfigurationFactoryTest.java b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/OpenTelemetryConfigurationFactoryTest.java index ac249c94b9a..da3cc7cd013 100644 --- a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/OpenTelemetryConfigurationFactoryTest.java +++ b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/OpenTelemetryConfigurationFactoryTest.java @@ -69,20 +69,6 @@ class OpenTelemetryConfigurationFactoryTest { private final SpiHelper spiHelper = SpiHelper.create(OpenTelemetryConfigurationFactoryTest.class.getClassLoader()); - @Test - void create_Null() { - List closeables = new ArrayList<>(); - OpenTelemetrySdk expectedSdk = OpenTelemetrySdk.builder().build(); - cleanup.addCloseable(expectedSdk); - - OpenTelemetrySdk sdk = - OpenTelemetryConfigurationFactory.getInstance().create(null, spiHelper, closeables); - cleanup.addCloseable(sdk); - cleanup.addCloseables(closeables); - - assertThat(sdk.toString()).isEqualTo(expectedSdk.toString()); - } - @Test void create_InvalidFileFormat() { List testCases = @@ -104,14 +90,7 @@ void create_InvalidFileFormat() { @Test void create_Defaults() { List closeables = new ArrayList<>(); - OpenTelemetrySdk expectedSdk = - OpenTelemetrySdk.builder() - .setPropagators( - ContextPropagators.create( - TextMapPropagator.composite( - W3CTraceContextPropagator.getInstance(), - W3CBaggagePropagator.getInstance()))) - .build(); + OpenTelemetrySdk expectedSdk = OpenTelemetrySdk.builder().build(); cleanup.addCloseable(expectedSdk); OpenTelemetrySdk sdk = diff --git a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/PropagatorFactoryTest.java b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/PropagatorFactoryTest.java index ba9f6190e95..8eb099cffa5 100644 --- a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/PropagatorFactoryTest.java +++ b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/PropagatorFactoryTest.java @@ -39,11 +39,6 @@ void create(Propagator model, ContextPropagators expectedPropagators) { private static Stream createArguments() { return Stream.of( - Arguments.of( - null, - ContextPropagators.create( - TextMapPropagator.composite( - W3CTraceContextPropagator.getInstance(), W3CBaggagePropagator.getInstance()))), Arguments.of( new Propagator() .withComposite( diff --git a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/ResourceFactoryTest.java b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/ResourceFactoryTest.java index f1329ffcc77..37e494ee28a 100644 --- a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/ResourceFactoryTest.java +++ b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/ResourceFactoryTest.java @@ -16,14 +16,6 @@ class ResourceFactoryTest { - @Test - void create_Null() { - assertThat( - ResourceFactory.getInstance() - .create(null, mock(SpiHelper.class), Collections.emptyList())) - .isEqualTo(Resource.getDefault()); - } - @Test void create() { assertThat( diff --git a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/SamplerFactoryTest.java b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/SamplerFactoryTest.java index c5c45eb1ae6..4df997c3b2a 100644 --- a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/SamplerFactoryTest.java +++ b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/SamplerFactoryTest.java @@ -60,10 +60,6 @@ void create( private static Stream createArguments() { return Stream.of( - Arguments.of( - null, - io.opentelemetry.sdk.trace.samplers.Sampler.parentBased( - io.opentelemetry.sdk.trace.samplers.Sampler.alwaysOn())), Arguments.of( new Sampler().withAlwaysOn(new AlwaysOn()), io.opentelemetry.sdk.trace.samplers.Sampler.alwaysOn()), diff --git a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/SpanExporterFactoryTest.java b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/SpanExporterFactoryTest.java index 0712e745d91..b4192410110 100644 --- a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/SpanExporterFactoryTest.java +++ b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/SpanExporterFactoryTest.java @@ -59,12 +59,6 @@ class SpanExporterFactoryTest { private SpiHelper spiHelper = SpiHelper.create(SpanExporterFactoryTest.class.getClassLoader()); - @Test - void create_Null() { - assertThat(SpanExporterFactory.getInstance().create(null, spiHelper, new ArrayList<>())) - .isNull(); - } - @Test void create_OtlpDefaults() { spiHelper = spy(spiHelper); diff --git a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/SpanLimitsFactoryTest.java b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/SpanLimitsFactoryTest.java index 1fc09f61f45..c6d78c3b777 100644 --- a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/SpanLimitsFactoryTest.java +++ b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/SpanLimitsFactoryTest.java @@ -32,7 +32,6 @@ void create( private static Stream createArguments() { return Stream.of( - Arguments.of(null, io.opentelemetry.sdk.trace.SpanLimits.getDefault()), Arguments.of( SpanLimitsAndAttributeLimits.create(null, null), io.opentelemetry.sdk.trace.SpanLimits.getDefault()), diff --git a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/SpanProcessorFactoryTest.java b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/SpanProcessorFactoryTest.java index eb1fb1533ce..972e0a137f9 100644 --- a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/SpanProcessorFactoryTest.java +++ b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/SpanProcessorFactoryTest.java @@ -33,19 +33,6 @@ class SpanProcessorFactoryTest { private final SpiHelper spiHelper = SpiHelper.create(SpanProcessorFactoryTest.class.getClassLoader()); - @Test - void create_Null() { - List closeables = new ArrayList<>(); - - io.opentelemetry.sdk.trace.SpanProcessor processor = - SpanProcessorFactory.getInstance().create(null, spiHelper, Collections.emptyList()); - cleanup.addCloseable(processor); - cleanup.addCloseables(closeables); - - assertThat(processor.toString()) - .isEqualTo(io.opentelemetry.sdk.trace.SpanProcessor.composite().toString()); - } - @Test void create_BatchNullExporter() { assertThatThrownBy( @@ -56,7 +43,7 @@ void create_BatchNullExporter() { spiHelper, Collections.emptyList())) .isInstanceOf(ConfigurationException.class) - .hasMessage("exporter required for batch span processor"); + .hasMessage("batch span processor exporter is required but is null"); } @Test @@ -123,7 +110,7 @@ void create_SimpleNullExporter() { spiHelper, Collections.emptyList())) .isInstanceOf(ConfigurationException.class) - .hasMessage("exporter required for simple span processor"); + .hasMessage("simple span processor exporter is required but is null"); } @Test diff --git a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/TextMapPropagatorFactoryTest.java b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/TextMapPropagatorFactoryTest.java index a0a0f6de49d..d2355fda46d 100644 --- a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/TextMapPropagatorFactoryTest.java +++ b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/TextMapPropagatorFactoryTest.java @@ -41,10 +41,6 @@ void create(List model, TextMapPropagator expectedPropagator) { private static Stream createArguments() { return Stream.of( - Arguments.of( - null, - TextMapPropagator.composite( - W3CTraceContextPropagator.getInstance(), W3CBaggagePropagator.getInstance())), Arguments.of( Collections.emptyList(), TextMapPropagator.composite( diff --git a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/TracerProviderFactoryTest.java b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/TracerProviderFactoryTest.java index b244acef40a..b3c637e124f 100644 --- a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/TracerProviderFactoryTest.java +++ b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/TracerProviderFactoryTest.java @@ -54,7 +54,6 @@ void create(TracerProviderAndAttributeLimits model, SdkTracerProvider expectedPr private static Stream createArguments() { return Stream.of( - Arguments.of(null, SdkTracerProvider.builder().build()), Arguments.of( TracerProviderAndAttributeLimits.create(null, null), SdkTracerProvider.builder().build()), diff --git a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/ViewFactoryTest.java b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/ViewFactoryTest.java index e04d5460a2d..087e68d5790 100644 --- a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/ViewFactoryTest.java +++ b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/ViewFactoryTest.java @@ -6,11 +6,9 @@ package io.opentelemetry.sdk.extension.incubator.fileconfig; import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.mockito.Mockito.mock; import io.opentelemetry.sdk.autoconfigure.internal.SpiHelper; -import io.opentelemetry.sdk.autoconfigure.spi.ConfigurationException; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.Aggregation; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.ExplicitBucketHistogram; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.Stream; @@ -22,16 +20,6 @@ class ViewFactoryTest { - @Test - void create_Null() { - assertThatThrownBy( - () -> - ViewFactory.getInstance() - .create(null, mock(SpiHelper.class), Collections.emptyList())) - .isInstanceOf(ConfigurationException.class) - .hasMessage("stream must not be null"); - } - @Test void create_Defaults() { View expectedView = View.builder().build(); From 4f9d1c9fc6fe315a971cb0c1de155326d701e4c6 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 8 Aug 2024 15:09:14 -0500 Subject: [PATCH 505/901] Update dependency io.grpc:grpc-bom to v1.66.0 (#6631) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- dependencyManagement/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index 47e1241d85a..1537e7e352b 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -14,7 +14,7 @@ val DEPENDENCY_BOMS = listOf( "com.linecorp.armeria:armeria-bom:1.29.4", "com.squareup.okhttp3:okhttp-bom:4.12.0", "com.squareup.okio:okio-bom:3.9.0", // applies to transitive dependencies of okhttp - "io.grpc:grpc-bom:1.65.1", + "io.grpc:grpc-bom:1.66.0", "io.netty:netty-bom:4.1.112.Final", "io.zipkin.brave:brave-bom:6.0.3", "io.zipkin.reporter2:zipkin-reporter-bom:3.4.0", From e8b50c688738078ab0e801e9d96fed0d4a7aceed Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 8 Aug 2024 15:22:45 -0500 Subject: [PATCH 506/901] Update gradle/actions action to v4 (#6618) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Co-authored-by: Jason Plumb --- .github/workflows/benchmark-tags.yml | 8 ++++---- .github/workflows/benchmark.yml | 8 ++++---- .github/workflows/build.yml | 19 ++++++++++++------- .github/workflows/codeql-daily.yml | 9 +++++---- .../workflows/gradle-wrapper-validation.yml | 2 +- .../owasp-dependency-check-daily.yml | 7 ++++--- .github/workflows/release.yml | 7 ++++--- 7 files changed, 34 insertions(+), 26 deletions(-) diff --git a/.github/workflows/benchmark-tags.yml b/.github/workflows/benchmark-tags.yml index 81335228f2b..9953fef010a 100644 --- a/.github/workflows/benchmark-tags.yml +++ b/.github/workflows/benchmark-tags.yml @@ -50,10 +50,10 @@ jobs: distribution: temurin java-version: 17 - - uses: gradle/actions/setup-gradle@v3 - with: - arguments: | - jmhJar + - name: Set up gradle + uses: gradle/actions/setup-gradle@v4 + - name: Run jmh + run: ./gradlew jmhJar env: GRADLE_ENTERPRISE_ACCESS_KEY: ${{ secrets.GRADLE_ENTERPRISE_ACCESS_KEY }} diff --git a/.github/workflows/benchmark.yml b/.github/workflows/benchmark.yml index 82bb73e5d17..7a8160dbca7 100644 --- a/.github/workflows/benchmark.yml +++ b/.github/workflows/benchmark.yml @@ -20,10 +20,10 @@ jobs: distribution: temurin java-version: 17 - - uses: gradle/actions/setup-gradle@v3 - with: - arguments: | - jmhJar + - name: Set up gradle + uses: gradle/actions/setup-gradle@v4 + - name: Run jmh + run: ./gradlew jmhJar env: GRADLE_ENTERPRISE_ACCESS_KEY: ${{ secrets.GRADLE_ENTERPRISE_ACCESS_KEY }} diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 8b928eee9f1..33d3cfe545b 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -61,10 +61,11 @@ jobs: distribution: temurin java-version: 17 - - uses: gradle/actions/setup-gradle@v3 - with: - arguments: | - build + - name: Set up gradle + uses: gradle/actions/setup-gradle@v4 + - name: Build + run: > + ./gradlew build ${{ matrix.coverage && 'jacocoTestReport' || '' }} -PtestJavaVersion=${{ matrix.test-java-version }} -Porg.gradle.java.installations.paths=${{ steps.setup-java-test.outputs.path }},${{ steps.setup-java.outputs.path }} @@ -134,12 +135,16 @@ jobs: distribution: temurin java-version: 17 - - uses: gradle/actions/setup-gradle@v3 + - name: Set up gradle + uses: gradle/actions/setup-gradle@v4 + # skipping release branches because the versions in those branches are not snapshots + # (also this skips pull requests) + if: ${{ github.ref_name == 'main' && github.repository == 'open-telemetry/opentelemetry-java' }} + - name: Publish to Sonatype + run: ./gradlew assemble publishToSonatype # skipping release branches because the versions in those branches are not snapshots # (also this skips pull requests) if: ${{ github.ref_name == 'main' && github.repository == 'open-telemetry/opentelemetry-java' }} - with: - arguments: assemble publishToSonatype env: SONATYPE_USER: ${{ secrets.SONATYPE_USER }} SONATYPE_KEY: ${{ secrets.SONATYPE_KEY }} diff --git a/.github/workflows/codeql-daily.yml b/.github/workflows/codeql-daily.yml index 903ed11f4b5..3331db67be3 100644 --- a/.github/workflows/codeql-daily.yml +++ b/.github/workflows/codeql-daily.yml @@ -27,10 +27,11 @@ jobs: # see https://github.com/github/codeql-action/issues/1555#issuecomment-1452228433 tools: latest - - uses: gradle/actions/setup-gradle@v3 - with: - # skipping build cache is needed so that all modules will be analyzed - arguments: assemble --no-build-cache + - name: Set up gradle + uses: gradle/actions/setup-gradle@v4 + - name: Assemble + # skipping build cache is needed so that all modules will be analyzed + run: ./gradlew assemble --no-build-cache - name: Perform CodeQL analysis uses: github/codeql-action/analyze@v3 diff --git a/.github/workflows/gradle-wrapper-validation.yml b/.github/workflows/gradle-wrapper-validation.yml index 37bde5bf7b9..e659ca0fa97 100644 --- a/.github/workflows/gradle-wrapper-validation.yml +++ b/.github/workflows/gradle-wrapper-validation.yml @@ -13,4 +13,4 @@ jobs: steps: - uses: actions/checkout@v4 - - uses: gradle/actions/wrapper-validation@v3.5.0 + - uses: gradle/actions/wrapper-validation@v4.0.0 diff --git a/.github/workflows/owasp-dependency-check-daily.yml b/.github/workflows/owasp-dependency-check-daily.yml index b67270f55aa..4f346d2848b 100644 --- a/.github/workflows/owasp-dependency-check-daily.yml +++ b/.github/workflows/owasp-dependency-check-daily.yml @@ -19,9 +19,10 @@ jobs: distribution: temurin java-version: 17 - - uses: gradle/actions/setup-gradle@v3 - with: - arguments: "dependencyCheckAnalyze" + - name: Set up gradle + uses: gradle/actions/setup-gradle@v4 + - name: Check dependencies + run: ./gradlew dependencyCheckAnalyze - name: Upload report if: always() diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 11b02a7df9c..30bc0809b39 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -21,10 +21,11 @@ jobs: distribution: temurin java-version: 17 + - name: Set up gradle + uses: gradle/actions/setup-gradle@v4 + - name: Build and publish artifacts - uses: gradle/actions/setup-gradle@v3 - with: - arguments: assemble publishToSonatype closeAndReleaseSonatypeStagingRepository + run: ./gradlew assemble publishToSonatype closeAndReleaseSonatypeStagingRepository env: SONATYPE_USER: ${{ secrets.SONATYPE_USER }} SONATYPE_KEY: ${{ secrets.SONATYPE_KEY }} From b53c48a769b88e60cd6f0fef6eef1349e9250ef8 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 8 Aug 2024 15:30:31 -0500 Subject: [PATCH 507/901] Update slf4j monorepo to v2.0.15 (#6622) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- dependencyManagement/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index 1537e7e352b..19ed49449b6 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -29,7 +29,7 @@ val errorProneVersion = "2.29.2" val jmhVersion = "1.37" // Mockito 5.x.x requires Java 11 https://github.com/mockito/mockito/releases/tag/v5.0.0 val mockitoVersion = "4.11.0" -val slf4jVersion = "2.0.13" +val slf4jVersion = "2.0.15" val opencensusVersion = "0.31.1" val prometheusClientVersion = "0.16.0" From d16ba00e15b12e41e25859204d042f5f1067b54a Mon Sep 17 00:00:00 2001 From: jack-berg <34418638+jack-berg@users.noreply.github.com> Date: Thu, 8 Aug 2024 15:34:16 -0500 Subject: [PATCH 508/901] Avoid allocations when advice doesn't remove any attributes (#6629) --- .../view/AdviceAttributesProcessor.java | 17 +++++++++++++++++ .../view/AdviceAttributesProcessorTest.java | 13 +++++++++++++ 2 files changed, 30 insertions(+) diff --git a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/view/AdviceAttributesProcessor.java b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/view/AdviceAttributesProcessor.java index 161dcd72832..b0373f25765 100644 --- a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/view/AdviceAttributesProcessor.java +++ b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/view/AdviceAttributesProcessor.java @@ -23,11 +23,28 @@ final class AdviceAttributesProcessor extends AttributesProcessor { @Override public Attributes process(Attributes incoming, Context context) { + // Exit early to avoid allocations if the incoming attributes do not have extra keys to be + // filtered + if (!hasExtraKeys(incoming)) { + return incoming; + } AttributesBuilder builder = incoming.toBuilder(); builder.removeIf(key -> !attributeKeys.contains(key)); return builder.build(); } + /** Returns true if {@code attributes} has keys not contained in {@link #attributeKeys}. */ + private boolean hasExtraKeys(Attributes attributes) { + boolean[] result = {false}; + attributes.forEach( + (key, value) -> { + if (!result[0] && !attributeKeys.contains(key)) { + result[0] = true; + } + }); + return result[0]; + } + @Override public boolean usesContext() { return false; diff --git a/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/internal/view/AdviceAttributesProcessorTest.java b/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/internal/view/AdviceAttributesProcessorTest.java index 294c05ea157..d809c8a3794 100644 --- a/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/internal/view/AdviceAttributesProcessorTest.java +++ b/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/internal/view/AdviceAttributesProcessorTest.java @@ -24,6 +24,19 @@ void doesNotUseContext() { assertThat(new AdviceAttributesProcessor(emptyList()).usesContext()).isFalse(); } + @Test + void noExtraAttributes() { + AttributesProcessor processor = + new AdviceAttributesProcessor(asList(stringKey("abc"), stringKey("def"))); + + Attributes result = + processor.process( + Attributes.builder().put(stringKey("abc"), "abc").put(stringKey("def"), "def").build(), + Context.root()); + + assertThat(result).containsOnly(entry(stringKey("abc"), "abc"), entry(stringKey("def"), "def")); + } + @Test void removeUnwantedAttributes() { AttributesProcessor processor = From fc283ba7636dae7d265f3ed5882d9d26ee8aac00 Mon Sep 17 00:00:00 2001 From: jack-berg <34418638+jack-berg@users.noreply.github.com> Date: Thu, 8 Aug 2024 16:11:47 -0500 Subject: [PATCH 509/901] Completable result code throwable (#6348) --- .../opentelemetry-sdk-common.txt | 7 ++- .../sdk/common/CompletableResultCode.java | 59 +++++++++++++++++-- .../sdk/common/CompletableResultCodeTest.java | 42 ++++++++++++- 3 files changed, 101 insertions(+), 7 deletions(-) diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-common.txt b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-common.txt index cc49df57512..3b29b622a14 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-common.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-common.txt @@ -1,2 +1,7 @@ Comparing source compatibility of opentelemetry-sdk-common-1.41.0-SNAPSHOT.jar against opentelemetry-sdk-common-1.40.0.jar -No changes. \ No newline at end of file +*** MODIFIED CLASS: PUBLIC FINAL io.opentelemetry.sdk.common.CompletableResultCode (not serializable) + === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 + +++ NEW METHOD: PUBLIC(+) io.opentelemetry.sdk.common.CompletableResultCode failExceptionally(java.lang.Throwable) + +++ NEW METHOD: PUBLIC(+) java.lang.Throwable getFailureThrowable() + +++ NEW ANNOTATION: javax.annotation.Nullable + +++ NEW METHOD: PUBLIC(+) STATIC(+) io.opentelemetry.sdk.common.CompletableResultCode ofExceptionalFailure(java.lang.Throwable) diff --git a/sdk/common/src/main/java/io/opentelemetry/sdk/common/CompletableResultCode.java b/sdk/common/src/main/java/io/opentelemetry/sdk/common/CompletableResultCode.java index b7f7fa944fd..a3646343bd5 100644 --- a/sdk/common/src/main/java/io/opentelemetry/sdk/common/CompletableResultCode.java +++ b/sdk/common/src/main/java/io/opentelemetry/sdk/common/CompletableResultCode.java @@ -13,6 +13,7 @@ import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.atomic.AtomicReference; import javax.annotation.Nullable; /** @@ -33,9 +34,19 @@ public static CompletableResultCode ofFailure() { return FAILURE; } + /** + * Returns a {@link CompletableResultCode} that has been {@link #failExceptionally(Throwable) + * failed exceptionally}. + */ + public static CompletableResultCode ofExceptionalFailure(Throwable throwable) { + return new CompletableResultCode().failExceptionally(throwable); + } + /** * Returns a {@link CompletableResultCode} that completes after all the provided {@link - * CompletableResultCode}s complete. If any of the results fail, the result will be failed. + * CompletableResultCode}s complete. If any of the results fail, the result will be failed. If any + * {@link #failExceptionally(Throwable) failed exceptionally}, the result will be failed + * exceptionally with the first {@link Throwable} from {@code codes}. */ public static CompletableResultCode ofAll(Collection codes) { if (codes.isEmpty()) { @@ -44,15 +55,20 @@ public static CompletableResultCode ofAll(Collection code CompletableResultCode result = new CompletableResultCode(); AtomicInteger pending = new AtomicInteger(codes.size()); AtomicBoolean failed = new AtomicBoolean(); + AtomicReference throwableRef = new AtomicReference<>(); for (CompletableResultCode code : codes) { code.whenComplete( () -> { if (!code.isSuccess()) { failed.set(true); + Throwable codeThrowable = code.getFailureThrowable(); + if (codeThrowable != null) { + throwableRef.compareAndSet(null, codeThrowable); + } } if (pending.decrementAndGet() == 0) { if (failed.get()) { - result.fail(); + result.failInternal(throwableRef.get()); } else { result.succeed(); } @@ -71,6 +87,10 @@ public CompletableResultCode() {} @GuardedBy("lock") private Boolean succeeded = null; + @Nullable + @GuardedBy("lock") + private Throwable throwable = null; + @GuardedBy("lock") private final List completionActions = new ArrayList<>(); @@ -89,11 +109,27 @@ public CompletableResultCode succeed() { return this; } - /** Complete this {@link CompletableResultCode} unsuccessfully if it is not already completed. */ + /** + * Complete this {@link CompletableResultCode} unsuccessfully if it is not already completed, + * setting the {@link #getFailureThrowable() failure throwable} to {@code null}. + */ public CompletableResultCode fail() { + return failInternal(null); + } + + /** + * Completes this {@link CompletableResultCode} unsuccessfully if it is not already completed, + * setting the {@link #getFailureThrowable() failure throwable} to {@code throwable}. + */ + public CompletableResultCode failExceptionally(Throwable throwable) { + return failInternal(throwable); + } + + private CompletableResultCode failInternal(@Nullable Throwable throwable) { synchronized (lock) { if (succeeded == null) { succeeded = false; + this.throwable = throwable; for (Runnable action : completionActions) { action.run(); } @@ -104,7 +140,7 @@ public CompletableResultCode fail() { /** * Obtain the current state of completion. Generally call once completion is achieved via the - * thenRun method. + * {@link #whenComplete(Runnable)} method. * * @return the current state of completion */ @@ -114,6 +150,21 @@ public boolean isSuccess() { } } + /** + * Returns {@link Throwable} if this {@link CompletableResultCode} was {@link + * #failExceptionally(Throwable) failed exceptionally}. Generally call once completion is achieved + * via the {@link #whenComplete(Runnable)} method. + * + * @return the throwable if failed exceptionally, or null if: {@link #fail() failed without + * exception}, {@link #succeed() succeeded}, or not complete. + */ + @Nullable + public Throwable getFailureThrowable() { + synchronized (lock) { + return throwable; + } + } + /** * Perform an action on completion. Actions are guaranteed to be called only once. * diff --git a/sdk/common/src/test/java/io/opentelemetry/sdk/common/CompletableResultCodeTest.java b/sdk/common/src/test/java/io/opentelemetry/sdk/common/CompletableResultCodeTest.java index 544777430f5..3964fdd7f73 100644 --- a/sdk/common/src/test/java/io/opentelemetry/sdk/common/CompletableResultCodeTest.java +++ b/sdk/common/src/test/java/io/opentelemetry/sdk/common/CompletableResultCodeTest.java @@ -21,12 +21,32 @@ class CompletableResultCodeTest { @Test void ofSuccess() { - assertThat(CompletableResultCode.ofSuccess().isSuccess()).isTrue(); + assertThat(CompletableResultCode.ofSuccess()) + .satisfies( + code -> { + assertThat(code.isSuccess()).isTrue(); + assertThat(code.getFailureThrowable()).isNull(); + }); } @Test void ofFailure() { - assertThat(CompletableResultCode.ofFailure().isSuccess()).isFalse(); + assertThat(CompletableResultCode.ofFailure()) + .satisfies( + code -> { + assertThat(code.isSuccess()).isFalse(); + assertThat(code.getFailureThrowable()).isNull(); + }); + } + + @Test + void ofExceptionalFailure() { + assertThat(CompletableResultCode.ofExceptionalFailure(new Exception("error"))) + .satisfies( + code -> { + assertThat(code.isSuccess()).isFalse(); + assertThat(code.getFailureThrowable()).hasMessage("error"); + }); } @Test @@ -149,6 +169,24 @@ void ofAllWithFailure() { .isFalse(); } + @Test + void ofAllWithExceptionalFailure() { + assertThat( + CompletableResultCode.ofAll( + Arrays.asList( + CompletableResultCode.ofSuccess(), + CompletableResultCode.ofFailure(), + CompletableResultCode.ofExceptionalFailure(new Exception("error1")), + CompletableResultCode.ofExceptionalFailure(new Exception("error2")), + CompletableResultCode.ofSuccess()))) + .satisfies( + code -> { + assertThat(code.isSuccess()).isFalse(); + // failure throwable is set to first throwable seen in the collection + assertThat(code.getFailureThrowable()).hasMessage("error1"); + }); + } + @Test void join() { CompletableResultCode result = new CompletableResultCode(); From e2936d460903c8e303d1abe639386fc132acf9c4 Mon Sep 17 00:00:00 2001 From: Abhishek Kumar Date: Fri, 9 Aug 2024 03:01:16 +0530 Subject: [PATCH 510/901] Add config to enable Default Exponential Histogram for Prometheus Exporter (#6541) Co-authored-by: Jack Berg --- dependencyManagement/build.gradle.kts | 1 + .../internal/ExporterBuilderUtil.java | 25 ++++++ .../otlp/internal/OtlpConfigUtil.java | 15 +--- exporters/prometheus/build.gradle.kts | 1 + .../prometheus/PrometheusHttpServer.java | 12 ++- .../PrometheusHttpServerBuilder.java | 22 ++++- .../PrometheusMetricReaderProvider.java | 8 ++ .../prometheus/PrometheusHttpServerTest.java | 82 +++++++++++++++++++ .../PrometheusMetricReaderProviderTest.java | 23 ++++++ 9 files changed, 175 insertions(+), 14 deletions(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index 19ed49449b6..0ec77ee1eea 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -50,6 +50,7 @@ val DEPENDENCIES = listOf( "org.mockito:mockito-junit-jupiter:${mockitoVersion}", "org.slf4j:slf4j-simple:${slf4jVersion}", "org.slf4j:jul-to-slf4j:${slf4jVersion}", + "io.prometheus:prometheus-metrics-shaded-protobuf:1.3.1", "io.prometheus:simpleclient:${prometheusClientVersion}", "io.prometheus:simpleclient_common:${prometheusClientVersion}", "io.prometheus:simpleclient_httpserver:${prometheusClientVersion}", diff --git a/exporters/common/src/main/java/io/opentelemetry/exporter/internal/ExporterBuilderUtil.java b/exporters/common/src/main/java/io/opentelemetry/exporter/internal/ExporterBuilderUtil.java index 79256cfd788..81caace0178 100644 --- a/exporters/common/src/main/java/io/opentelemetry/exporter/internal/ExporterBuilderUtil.java +++ b/exporters/common/src/main/java/io/opentelemetry/exporter/internal/ExporterBuilderUtil.java @@ -5,10 +5,16 @@ package io.opentelemetry.exporter.internal; +import static io.opentelemetry.sdk.metrics.Aggregation.explicitBucketHistogram; + import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties; import io.opentelemetry.sdk.autoconfigure.spi.ConfigurationException; import io.opentelemetry.sdk.autoconfigure.spi.internal.StructuredConfigProperties; import io.opentelemetry.sdk.common.export.MemoryMode; +import io.opentelemetry.sdk.metrics.Aggregation; +import io.opentelemetry.sdk.metrics.InstrumentType; +import io.opentelemetry.sdk.metrics.export.DefaultAggregationSelector; +import io.opentelemetry.sdk.metrics.internal.aggregator.AggregationUtil; import java.net.URI; import java.net.URISyntaxException; import java.util.Locale; @@ -71,5 +77,24 @@ public static void configureExporterMemoryMode( memoryModeConsumer.accept(memoryMode); } + /** + * Invoke the {@code defaultAggregationSelectorConsumer} with the configured {@link + * DefaultAggregationSelector}. + */ + public static void configureHistogramDefaultAggregation( + String defaultHistogramAggregation, + Consumer defaultAggregationSelectorConsumer) { + if (AggregationUtil.aggregationName(Aggregation.base2ExponentialBucketHistogram()) + .equalsIgnoreCase(defaultHistogramAggregation)) { + defaultAggregationSelectorConsumer.accept( + DefaultAggregationSelector.getDefault() + .with(InstrumentType.HISTOGRAM, Aggregation.base2ExponentialBucketHistogram())); + } else if (!AggregationUtil.aggregationName(explicitBucketHistogram()) + .equalsIgnoreCase(defaultHistogramAggregation)) { + throw new ConfigurationException( + "Unrecognized default histogram aggregation: " + defaultHistogramAggregation); + } + } + private ExporterBuilderUtil() {} } diff --git a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/OtlpConfigUtil.java b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/OtlpConfigUtil.java index 7012b1db478..7fbc5107fd1 100644 --- a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/OtlpConfigUtil.java +++ b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/OtlpConfigUtil.java @@ -310,18 +310,9 @@ public static void configureOtlpHistogramDefaultAggregation( Consumer defaultAggregationSelectorConsumer) { String defaultHistogramAggregation = config.getString("otel.exporter.otlp.metrics.default.histogram.aggregation"); - if (defaultHistogramAggregation == null) { - return; - } - if (AggregationUtil.aggregationName(Aggregation.base2ExponentialBucketHistogram()) - .equalsIgnoreCase(defaultHistogramAggregation)) { - defaultAggregationSelectorConsumer.accept( - DefaultAggregationSelector.getDefault() - .with(InstrumentType.HISTOGRAM, Aggregation.base2ExponentialBucketHistogram())); - } else if (!AggregationUtil.aggregationName(explicitBucketHistogram()) - .equalsIgnoreCase(defaultHistogramAggregation)) { - throw new ConfigurationException( - "Unrecognized default histogram aggregation: " + defaultHistogramAggregation); + if (defaultHistogramAggregation != null) { + ExporterBuilderUtil.configureHistogramDefaultAggregation( + defaultHistogramAggregation, defaultAggregationSelectorConsumer); } } diff --git a/exporters/prometheus/build.gradle.kts b/exporters/prometheus/build.gradle.kts index b0e9809ebcc..8fe244b3f3d 100644 --- a/exporters/prometheus/build.gradle.kts +++ b/exporters/prometheus/build.gradle.kts @@ -19,6 +19,7 @@ dependencies { testImplementation(project(":sdk:testing")) testImplementation("io.opentelemetry.proto:opentelemetry-proto") + testImplementation("io.prometheus:prometheus-metrics-shaded-protobuf") testImplementation("com.sun.net.httpserver:http") testImplementation("com.google.guava:guava") testImplementation("com.linecorp.armeria:armeria") diff --git a/exporters/prometheus/src/main/java/io/opentelemetry/exporter/prometheus/PrometheusHttpServer.java b/exporters/prometheus/src/main/java/io/opentelemetry/exporter/prometheus/PrometheusHttpServer.java index 0a306fccaa3..78609ee7549 100644 --- a/exporters/prometheus/src/main/java/io/opentelemetry/exporter/prometheus/PrometheusHttpServer.java +++ b/exporters/prometheus/src/main/java/io/opentelemetry/exporter/prometheus/PrometheusHttpServer.java @@ -14,9 +14,11 @@ import io.opentelemetry.sdk.common.CompletableResultCode; import io.opentelemetry.sdk.common.export.MemoryMode; import io.opentelemetry.sdk.internal.DaemonThreadFactory; +import io.opentelemetry.sdk.metrics.Aggregation; import io.opentelemetry.sdk.metrics.InstrumentType; import io.opentelemetry.sdk.metrics.data.AggregationTemporality; import io.opentelemetry.sdk.metrics.export.CollectionRegistration; +import io.opentelemetry.sdk.metrics.export.DefaultAggregationSelector; import io.opentelemetry.sdk.metrics.export.MetricReader; import io.prometheus.metrics.exporter.httpserver.HTTPServer; import io.prometheus.metrics.model.registry.PrometheusRegistry; @@ -41,6 +43,7 @@ public final class PrometheusHttpServer implements MetricReader { private final PrometheusRegistry prometheusRegistry; private final String host; private final MemoryMode memoryMode; + private final DefaultAggregationSelector defaultAggregationSelector; /** * Returns a new {@link PrometheusHttpServer} which can be registered to an {@link @@ -65,7 +68,8 @@ public static PrometheusHttpServerBuilder builder() { boolean otelScopeEnabled, @Nullable Predicate allowedResourceAttributesFilter, MemoryMode memoryMode, - @Nullable HttpHandler defaultHandler) { + @Nullable HttpHandler defaultHandler, + DefaultAggregationSelector defaultAggregationSelector) { this.builder = builder; this.prometheusMetricReader = new PrometheusMetricReader(otelScopeEnabled, allowedResourceAttributesFilter); @@ -92,6 +96,7 @@ public static PrometheusHttpServerBuilder builder() { } catch (IOException e) { throw new UncheckedIOException("Could not create Prometheus HTTP server", e); } + this.defaultAggregationSelector = defaultAggregationSelector; } @Override @@ -99,6 +104,11 @@ public AggregationTemporality getAggregationTemporality(InstrumentType instrumen return prometheusMetricReader.getAggregationTemporality(instrumentType); } + @Override + public Aggregation getDefaultAggregation(InstrumentType instrumentType) { + return defaultAggregationSelector.getDefaultAggregation(instrumentType); + } + @Override public MemoryMode getMemoryMode() { return memoryMode; diff --git a/exporters/prometheus/src/main/java/io/opentelemetry/exporter/prometheus/PrometheusHttpServerBuilder.java b/exporters/prometheus/src/main/java/io/opentelemetry/exporter/prometheus/PrometheusHttpServerBuilder.java index 20f36fdf426..c1138a6ea31 100644 --- a/exporters/prometheus/src/main/java/io/opentelemetry/exporter/prometheus/PrometheusHttpServerBuilder.java +++ b/exporters/prometheus/src/main/java/io/opentelemetry/exporter/prometheus/PrometheusHttpServerBuilder.java @@ -10,6 +10,9 @@ import com.sun.net.httpserver.HttpHandler; import io.opentelemetry.sdk.common.export.MemoryMode; +import io.opentelemetry.sdk.metrics.InstrumentType; +import io.opentelemetry.sdk.metrics.export.DefaultAggregationSelector; +import io.opentelemetry.sdk.metrics.export.MetricExporter; import io.prometheus.metrics.model.registry.PrometheusRegistry; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; @@ -31,6 +34,8 @@ public final class PrometheusHttpServerBuilder { @Nullable private ExecutorService executor; private MemoryMode memoryMode = DEFAULT_MEMORY_MODE; @Nullable private HttpHandler defaultHandler; + private DefaultAggregationSelector defaultAggregationSelector = + DefaultAggregationSelector.getDefault(); PrometheusHttpServerBuilder() {} @@ -41,6 +46,7 @@ public final class PrometheusHttpServerBuilder { this.otelScopeEnabled = builder.otelScopeEnabled; this.allowedResourceAttributesFilter = builder.allowedResourceAttributesFilter; this.executor = builder.executor; + this.defaultAggregationSelector = builder.defaultAggregationSelector; } /** Sets the host to bind to. If unset, defaults to {@value #DEFAULT_HOST}. */ @@ -126,6 +132,19 @@ public PrometheusHttpServerBuilder setDefaultHandler(HttpHandler defaultHandler) return this; } + /** + * Set the {@link DefaultAggregationSelector} used for {@link + * MetricExporter#getDefaultAggregation(InstrumentType)}. + * + *

      If unset, defaults to {@link DefaultAggregationSelector#getDefault()}. + */ + public PrometheusHttpServerBuilder setDefaultAggregationSelector( + DefaultAggregationSelector defaultAggregationSelector) { + requireNonNull(defaultAggregationSelector, "defaultAggregationSelector"); + this.defaultAggregationSelector = defaultAggregationSelector; + return this; + } + /** * Returns a new {@link PrometheusHttpServer} with the configuration of this builder which can be * registered with a {@link io.opentelemetry.sdk.metrics.SdkMeterProvider}. @@ -140,6 +159,7 @@ public PrometheusHttpServer build() { otelScopeEnabled, allowedResourceAttributesFilter, memoryMode, - defaultHandler); + defaultHandler, + defaultAggregationSelector); } } diff --git a/exporters/prometheus/src/main/java/io/opentelemetry/exporter/prometheus/internal/PrometheusMetricReaderProvider.java b/exporters/prometheus/src/main/java/io/opentelemetry/exporter/prometheus/internal/PrometheusMetricReaderProvider.java index 39d6c755e17..4c60d3def19 100644 --- a/exporters/prometheus/src/main/java/io/opentelemetry/exporter/prometheus/internal/PrometheusMetricReaderProvider.java +++ b/exporters/prometheus/src/main/java/io/opentelemetry/exporter/prometheus/internal/PrometheusMetricReaderProvider.java @@ -35,6 +35,14 @@ public MetricReader createMetricReader(ConfigProperties config) { ExporterBuilderUtil.configureExporterMemoryMode(config, prometheusBuilder::setMemoryMode); + String defaultHistogramAggregation = + config.getString( + "otel.java.experimental.exporter.prometheus.metrics.default.histogram.aggregation"); + if (defaultHistogramAggregation != null) { + ExporterBuilderUtil.configureHistogramDefaultAggregation( + defaultHistogramAggregation, prometheusBuilder::setDefaultAggregationSelector); + } + return prometheusBuilder.build(); } diff --git a/exporters/prometheus/src/test/java/io/opentelemetry/exporter/prometheus/PrometheusHttpServerTest.java b/exporters/prometheus/src/test/java/io/opentelemetry/exporter/prometheus/PrometheusHttpServerTest.java index 9b328493c1f..1ee412eff03 100644 --- a/exporters/prometheus/src/test/java/io/opentelemetry/exporter/prometheus/PrometheusHttpServerTest.java +++ b/exporters/prometheus/src/test/java/io/opentelemetry/exporter/prometheus/PrometheusHttpServerTest.java @@ -16,18 +16,24 @@ import com.linecorp.armeria.client.retry.RetryRule; import com.linecorp.armeria.client.retry.RetryingClient; import com.linecorp.armeria.common.AggregatedHttpResponse; +import com.linecorp.armeria.common.HttpData; import com.linecorp.armeria.common.HttpHeaderNames; import com.linecorp.armeria.common.HttpMethod; import com.linecorp.armeria.common.HttpStatus; import com.linecorp.armeria.common.RequestHeaders; import io.github.netmikey.logunit.api.LogCapturer; import io.opentelemetry.api.common.Attributes; +import io.opentelemetry.api.metrics.DoubleHistogram; import io.opentelemetry.internal.testing.slf4j.SuppressLogger; import io.opentelemetry.sdk.common.InstrumentationScopeInfo; import io.opentelemetry.sdk.common.export.MemoryMode; +import io.opentelemetry.sdk.metrics.Aggregation; +import io.opentelemetry.sdk.metrics.InstrumentType; +import io.opentelemetry.sdk.metrics.SdkMeterProvider; import io.opentelemetry.sdk.metrics.data.AggregationTemporality; import io.opentelemetry.sdk.metrics.data.MetricData; import io.opentelemetry.sdk.metrics.export.CollectionRegistration; +import io.opentelemetry.sdk.metrics.export.DefaultAggregationSelector; import io.opentelemetry.sdk.metrics.internal.data.ImmutableDoublePointData; import io.opentelemetry.sdk.metrics.internal.data.ImmutableGaugeData; import io.opentelemetry.sdk.metrics.internal.data.ImmutableLongPointData; @@ -36,7 +42,9 @@ import io.opentelemetry.sdk.resources.Resource; import io.prometheus.metrics.exporter.httpserver.HTTPServer; import io.prometheus.metrics.exporter.httpserver.MetricsHandler; +import io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics; import io.prometheus.metrics.model.registry.PrometheusRegistry; +import io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.TextFormat; import java.io.ByteArrayInputStream; import java.io.IOException; import java.net.ServerSocket; @@ -113,6 +121,9 @@ void invalidConfig() { assertThatThrownBy(() -> PrometheusHttpServer.builder().setHost("")) .isInstanceOf(IllegalArgumentException.class) .hasMessage("host must not be empty"); + assertThatThrownBy(() -> PrometheusHttpServer.builder().setDefaultAggregationSelector(null)) + .isInstanceOf(NullPointerException.class) + .hasMessage("defaultAggregationSelector"); } @Test @@ -526,4 +537,75 @@ void toBuilder() { .hasFieldOrPropertyWithValue("executor", executor) .hasFieldOrPropertyWithValue("prometheusRegistry", prometheusRegistry); } + + /** + * Set the default histogram aggregation to be {@link + * Aggregation#base2ExponentialBucketHistogram()}. In order to validate that exponential + * histograms are produced, we request protobuf encoded metrics when scraping since the prometheus + * text format does not support native histograms. We parse the binary content protobuf payload to + * the protobuf java bindings, and assert against the string representation. + */ + @Test + void histogramDefaultBase2ExponentialHistogram() throws IOException { + PrometheusHttpServer prometheusServer = + PrometheusHttpServer.builder() + .setHost("localhost") + .setPort(0) + .setDefaultAggregationSelector( + DefaultAggregationSelector.getDefault() + .with(InstrumentType.HISTOGRAM, Aggregation.base2ExponentialBucketHistogram())) + .build(); + try (SdkMeterProvider meterProvider = + SdkMeterProvider.builder().registerMetricReader(prometheusServer).build()) { + DoubleHistogram histogram = meterProvider.get("meter").histogramBuilder("histogram").build(); + histogram.record(1.0); + + WebClient client = + WebClient.builder("http://localhost:" + prometheusServer.getAddress().getPort()) + .decorator(RetryingClient.newDecorator(RetryRule.failsafe())) + // Request protobuf binary encoding, which is required for the prometheus native + // histogram format + .addHeader( + "Accept", + "application/vnd.google.protobuf; proto=io.prometheus.client.MetricFamily") + .build(); + AggregatedHttpResponse response = client.get("/metrics").aggregate().join(); + assertThat(response.status()).isEqualTo(HttpStatus.OK); + assertThat(response.headers().get(HttpHeaderNames.CONTENT_TYPE)) + .isEqualTo( + "application/vnd.google.protobuf; proto=io.prometheus.client.MetricFamily; encoding=delimited"); + // Parse the data to Metrics.MetricFamily protobuf java binding and assert against the string + // representation + try (HttpData data = response.content()) { + Metrics.MetricFamily metricFamily = + Metrics.MetricFamily.parseDelimitedFrom(data.toInputStream()); + String s = TextFormat.printer().printToString(metricFamily); + assertThat(s) + .isEqualTo( + "name: \"histogram\"\n" + + "help: \"\"\n" + + "type: HISTOGRAM\n" + + "metric {\n" + + " label {\n" + + " name: \"otel_scope_name\"\n" + + " value: \"meter\"\n" + + " }\n" + + " histogram {\n" + + " sample_count: 1\n" + + " sample_sum: 1.0\n" + + " schema: 8\n" + + " zero_threshold: 0.0\n" + + " zero_count: 0\n" + + " positive_span {\n" + + " offset: 0\n" + + " length: 1\n" + + " }\n" + + " positive_delta: 1\n" + + " }\n" + + "}\n"); + } + } finally { + prometheusServer.shutdown(); + } + } } diff --git a/exporters/prometheus/src/test/java/io/opentelemetry/exporter/prometheus/internal/PrometheusMetricReaderProviderTest.java b/exporters/prometheus/src/test/java/io/opentelemetry/exporter/prometheus/internal/PrometheusMetricReaderProviderTest.java index 5f450ab751f..e1fc42382e5 100644 --- a/exporters/prometheus/src/test/java/io/opentelemetry/exporter/prometheus/internal/PrometheusMetricReaderProviderTest.java +++ b/exporters/prometheus/src/test/java/io/opentelemetry/exporter/prometheus/internal/PrometheusMetricReaderProviderTest.java @@ -7,14 +7,18 @@ import static org.assertj.core.api.Assertions.as; import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.when; import com.sun.net.httpserver.HttpServer; import io.opentelemetry.exporter.prometheus.PrometheusHttpServer; import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties; +import io.opentelemetry.sdk.autoconfigure.spi.ConfigurationException; import io.opentelemetry.sdk.autoconfigure.spi.internal.DefaultConfigProperties; import io.opentelemetry.sdk.common.export.MemoryMode; +import io.opentelemetry.sdk.metrics.Aggregation; +import io.opentelemetry.sdk.metrics.InstrumentType; import io.opentelemetry.sdk.metrics.export.MetricReader; import io.prometheus.metrics.exporter.httpserver.HTTPServer; import java.io.IOException; @@ -59,6 +63,8 @@ void createMetricReader_Default() throws IOException { assertThat(server.getAddress().getPort()).isEqualTo(9464); }); assertThat(metricReader.getMemoryMode()).isEqualTo(MemoryMode.IMMUTABLE_DATA); + assertThat(metricReader.getDefaultAggregation(InstrumentType.HISTOGRAM)) + .isEqualTo(Aggregation.defaultAggregation()); } } @@ -76,6 +82,9 @@ void createMetricReader_WithConfiguration() throws IOException { config.put("otel.exporter.prometheus.host", "localhost"); config.put("otel.exporter.prometheus.port", String.valueOf(port)); config.put("otel.java.experimental.exporter.memory_mode", "reusable_data"); + config.put( + "otel.java.experimental.exporter.prometheus.metrics.default.histogram.aggregation", + "BASE2_EXPONENTIAL_BUCKET_HISTOGRAM"); when(configProperties.getInt(any())).thenReturn(null); when(configProperties.getString(any())).thenReturn(null); @@ -91,6 +100,20 @@ void createMetricReader_WithConfiguration() throws IOException { assertThat(server.getAddress().getPort()).isEqualTo(port); }); assertThat(metricReader.getMemoryMode()).isEqualTo(MemoryMode.REUSABLE_DATA); + assertThat(metricReader.getDefaultAggregation(InstrumentType.HISTOGRAM)) + .isEqualTo(Aggregation.base2ExponentialBucketHistogram()); } } + + @Test + void createMetricReader_WithWrongConfiguration() { + Map config = new HashMap<>(); + config.put( + "otel.java.experimental.exporter.prometheus.metrics.default.histogram.aggregation", "foo"); + + assertThatThrownBy( + () -> provider.createMetricReader(DefaultConfigProperties.createFromMap(config))) + .isInstanceOf(ConfigurationException.class) + .hasMessageContaining("Unrecognized default histogram aggregation:"); + } } From 910c7cc218f2edca8cca24615a353ed168015fbd Mon Sep 17 00:00:00 2001 From: jack-berg <34418638+jack-berg@users.noreply.github.com> Date: Fri, 9 Aug 2024 09:39:37 -0500 Subject: [PATCH 511/901] Retry ConnectException, add retry logging (#6614) --- .../sender/jdk/internal/JdkHttpSender.java | 52 ++++++++++++-- .../jdk/internal/JdkHttpSenderTest.java | 44 +++++++++++- .../okhttp/internal/RetryInterceptor.java | 70 ++++++++++++++++--- .../okhttp/internal/RetryInterceptorTest.java | 30 ++++++++ 4 files changed, 180 insertions(+), 16 deletions(-) diff --git a/exporters/sender/jdk/src/main/java/io/opentelemetry/exporter/sender/jdk/internal/JdkHttpSender.java b/exporters/sender/jdk/src/main/java/io/opentelemetry/exporter/sender/jdk/internal/JdkHttpSender.java index 22c0609e53d..c79aaf6162f 100644 --- a/exporters/sender/jdk/src/main/java/io/opentelemetry/exporter/sender/jdk/internal/JdkHttpSender.java +++ b/exporters/sender/jdk/src/main/java/io/opentelemetry/exporter/sender/jdk/internal/JdkHttpSender.java @@ -5,6 +5,8 @@ package io.opentelemetry.exporter.sender.jdk.internal; +import static java.util.stream.Collectors.joining; + import io.opentelemetry.exporter.internal.compression.Compressor; import io.opentelemetry.exporter.internal.http.HttpSender; import io.opentelemetry.exporter.internal.marshal.Marshaler; @@ -25,6 +27,7 @@ import java.util.List; import java.util.Map; import java.util.Set; +import java.util.StringJoiner; import java.util.concurrent.CompletableFuture; import java.util.concurrent.ConcurrentLinkedQueue; import java.util.concurrent.ExecutorService; @@ -33,6 +36,8 @@ import java.util.concurrent.TimeUnit; import java.util.function.Consumer; import java.util.function.Supplier; +import java.util.logging.Level; +import java.util.logging.Logger; import javax.annotation.Nullable; import javax.net.ssl.SSLContext; import javax.net.ssl.SSLException; @@ -52,6 +57,8 @@ public final class JdkHttpSender implements HttpSender { private static final ThreadLocal threadLocalByteBufPool = ThreadLocal.withInitial(ByteBufferPool::new); + private static final Logger logger = Logger.getLogger(JdkHttpSender.class.getName()); + private final ExecutorService executorService = Executors.newFixedThreadPool(5); private final HttpClient client; private final URI uri; @@ -211,11 +218,37 @@ HttpResponse sendInternal(Marshaler marshaler) throws IOException { exception = e; } - if (httpResponse != null && !retryableStatusCodes.contains(httpResponse.statusCode())) { - return httpResponse; + if (httpResponse != null) { + boolean retryable = retryableStatusCodes.contains(httpResponse.statusCode()); + if (logger.isLoggable(Level.FINER)) { + logger.log( + Level.FINER, + "Attempt " + + attempt + + " returned " + + (retryable ? "retryable" : "non-retryable") + + " response: " + + responseStringRepresentation(httpResponse)); + } + if (!retryable) { + return httpResponse; + } } - if (exception != null && !isRetryableException(exception)) { - throw exception; + if (exception != null) { + boolean retryable = isRetryableException(exception); + if (logger.isLoggable(Level.FINER)) { + logger.log( + Level.FINER, + "Attempt " + + attempt + + " failed with " + + (retryable ? "retryable" : "non-retryable") + + " exception", + exception); + } + if (!retryable) { + throw exception; + } } } while (attempt < retryPolicy.getMaxAttempts()); @@ -225,6 +258,17 @@ HttpResponse sendInternal(Marshaler marshaler) throws IOException { throw exception; } + private static String responseStringRepresentation(HttpResponse response) { + StringJoiner joiner = new StringJoiner(",", "HttpResponse{", "}"); + joiner.add("code=" + response.statusCode()); + joiner.add( + "headers=" + + response.headers().map().entrySet().stream() + .map(entry -> entry.getKey() + "=" + String.join(",", entry.getValue())) + .collect(joining(",", "[", "]"))); + return joiner.toString(); + } + private void write(Marshaler marshaler, OutputStream os) throws IOException { if (exportAsJson) { marshaler.writeJsonTo(os); diff --git a/exporters/sender/jdk/src/test/java/io/opentelemetry/exporter/sender/jdk/internal/JdkHttpSenderTest.java b/exporters/sender/jdk/src/test/java/io/opentelemetry/exporter/sender/jdk/internal/JdkHttpSenderTest.java index 79a06521c5b..5df723b6560 100644 --- a/exporters/sender/jdk/src/test/java/io/opentelemetry/exporter/sender/jdk/internal/JdkHttpSenderTest.java +++ b/exporters/sender/jdk/src/test/java/io/opentelemetry/exporter/sender/jdk/internal/JdkHttpSenderTest.java @@ -18,6 +18,8 @@ import io.opentelemetry.exporter.internal.marshal.Serializer; import io.opentelemetry.sdk.common.export.RetryPolicy; import java.io.IOException; +import java.net.ConnectException; +import java.net.ServerSocket; import java.net.http.HttpClient; import java.net.http.HttpConnectTimeoutException; import java.time.Duration; @@ -53,8 +55,8 @@ void setup() throws IOException, InterruptedException { sender = new JdkHttpSender( mockHttpClient, - "http://10.255.255.1", // Connecting to a non-routable IP address to trigger connection - // timeout + // Connecting to a non-routable IP address to trigger connection timeout + "http://10.255.255.1", null, false, "text/plain", @@ -74,6 +76,44 @@ void sendInternal_RetryableConnectTimeoutException() throws IOException, Interru verify(mockHttpClient, times(2)).send(any(), any()); } + @Test + void sendInternal_RetryableConnectException() throws IOException, InterruptedException { + sender = + new JdkHttpSender( + mockHttpClient, + // Connecting to localhost on an unused port address to trigger + // java.net.ConnectException (or java.net.http.HttpConnectTimeoutException on linux java + // 11+) + "http://localhost:" + freePort(), + null, + false, + "text/plain", + Duration.ofSeconds(10).toNanos(), + Collections::emptyMap, + RetryPolicy.builder() + .setMaxAttempts(2) + .setInitialBackoff(Duration.ofMillis(1)) + .build()); + + assertThatThrownBy(() -> sender.sendInternal(new NoOpMarshaler())) + .satisfies( + e -> + assertThat( + (e instanceof ConnectException) + || (e instanceof HttpConnectTimeoutException)) + .isTrue()); + + verify(mockHttpClient, times(2)).send(any(), any()); + } + + private static int freePort() { + try (ServerSocket socket = new ServerSocket(0)) { + return socket.getLocalPort(); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + @Test void sendInternal_RetryableIoException() throws IOException, InterruptedException { doThrow(new IOException("error!")).when(mockHttpClient).send(any(), any()); diff --git a/exporters/sender/okhttp/src/main/java/io/opentelemetry/exporter/sender/okhttp/internal/RetryInterceptor.java b/exporters/sender/okhttp/src/main/java/io/opentelemetry/exporter/sender/okhttp/internal/RetryInterceptor.java index ee7d5fc9177..405c54f1945 100644 --- a/exporters/sender/okhttp/src/main/java/io/opentelemetry/exporter/sender/okhttp/internal/RetryInterceptor.java +++ b/exporters/sender/okhttp/src/main/java/io/opentelemetry/exporter/sender/okhttp/internal/RetryInterceptor.java @@ -5,13 +5,19 @@ package io.opentelemetry.exporter.sender.okhttp.internal; +import static java.util.stream.Collectors.joining; + import io.opentelemetry.sdk.common.export.RetryPolicy; import java.io.IOException; +import java.net.ConnectException; import java.net.SocketTimeoutException; import java.util.Locale; +import java.util.StringJoiner; import java.util.concurrent.ThreadLocalRandom; import java.util.concurrent.TimeUnit; import java.util.function.Function; +import java.util.logging.Level; +import java.util.logging.Logger; import okhttp3.Interceptor; import okhttp3.Response; @@ -23,6 +29,8 @@ */ public final class RetryInterceptor implements Interceptor { + private static final Logger logger = Logger.getLogger(RetryInterceptor.class.getName()); + private final RetryPolicy retryPolicy; private final Function isRetryable; private final Function isRetryableException; @@ -84,12 +92,39 @@ public Response intercept(Chain chain) throws IOException { } catch (IOException e) { exception = e; } - if (response != null && !Boolean.TRUE.equals(isRetryable.apply(response))) { - return response; + if (response != null) { + boolean retryable = Boolean.TRUE.equals(isRetryable.apply(response)); + if (logger.isLoggable(Level.FINER)) { + logger.log( + Level.FINER, + "Attempt " + + attempt + + " returned " + + (retryable ? "retryable" : "non-retryable") + + " response: " + + responseStringRepresentation(response)); + } + if (!retryable) { + return response; + } } - if (exception != null && !Boolean.TRUE.equals(isRetryableException.apply(exception))) { - throw exception; + if (exception != null) { + boolean retryable = Boolean.TRUE.equals(isRetryableException.apply(exception)); + if (logger.isLoggable(Level.FINER)) { + logger.log( + Level.FINER, + "Attempt " + + attempt + + " failed with " + + (retryable ? "retryable" : "non-retryable") + + " exception", + exception); + } + if (!retryable) { + throw exception; + } } + } while (attempt < retryPolicy.getMaxAttempts()); if (response != null) { @@ -98,15 +133,30 @@ public Response intercept(Chain chain) throws IOException { throw exception; } + private static String responseStringRepresentation(Response response) { + StringJoiner joiner = new StringJoiner(",", "Response{", "}"); + joiner.add("code=" + response.code()); + joiner.add( + "headers=" + + response.headers().toMultimap().entrySet().stream() + .map(entry -> entry.getKey() + "=" + String.join(",", entry.getValue())) + .collect(joining(",", "[", "]"))); + return joiner.toString(); + } + // Visible for testing static boolean isRetryableException(IOException e) { - if (!(e instanceof SocketTimeoutException)) { - return false; + if (e instanceof SocketTimeoutException) { + String message = e.getMessage(); + // Connect timeouts can produce SocketTimeoutExceptions with no message, or with "connect + // timed out" + return message == null || message.toLowerCase(Locale.ROOT).contains("connect timed out"); + } else if (e instanceof ConnectException) { + // Exceptions resemble: java.net.ConnectException: Failed to connect to + // localhost/[0:0:0:0:0:0:0:1]:62611 + return true; } - String message = e.getMessage(); - // Connect timeouts can produce SocketTimeoutExceptions with no message, or with "connect timed - // out" - return message == null || message.toLowerCase(Locale.ROOT).contains("connect timed out"); + return false; } // Visible for testing diff --git a/exporters/sender/okhttp/src/test/java/io/opentelemetry/exporter/sender/okhttp/internal/RetryInterceptorTest.java b/exporters/sender/okhttp/src/test/java/io/opentelemetry/exporter/sender/okhttp/internal/RetryInterceptorTest.java index f4b644a36f3..1a6656c6217 100644 --- a/exporters/sender/okhttp/src/test/java/io/opentelemetry/exporter/sender/okhttp/internal/RetryInterceptorTest.java +++ b/exporters/sender/okhttp/src/test/java/io/opentelemetry/exporter/sender/okhttp/internal/RetryInterceptorTest.java @@ -23,6 +23,8 @@ import com.linecorp.armeria.testing.junit5.server.mock.MockWebServerExtension; import io.opentelemetry.sdk.common.export.RetryPolicy; import java.io.IOException; +import java.net.ConnectException; +import java.net.ServerSocket; import java.net.SocketTimeoutException; import java.time.Duration; import java.util.concurrent.TimeUnit; @@ -157,6 +159,34 @@ void connectTimeout() throws Exception { verify(sleeper, times(4)).sleep(anyLong()); } + @Test + void connectException() throws Exception { + client = connectTimeoutClient(); + when(random.get(anyLong())).thenReturn(1L); + doNothing().when(sleeper).sleep(anyLong()); + + // Connecting to localhost on an unused port address to trigger java.net.ConnectException + int openPort = freePort(); + assertThatThrownBy( + () -> + client + .newCall(new Request.Builder().url("http://localhost:" + openPort).build()) + .execute()) + .isInstanceOf(ConnectException.class); + + verify(isRetryableException, times(5)).apply(any()); + // Should retry maxAttempts, and sleep maxAttempts - 1 times + verify(sleeper, times(4)).sleep(anyLong()); + } + + private static int freePort() { + try (ServerSocket socket = new ServerSocket(0)) { + return socket.getLocalPort(); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + @Test void nonRetryableException() throws InterruptedException { client = connectTimeoutClient(); From f161a1e0396288e1cc9db0a529d65ce0174ef1c6 Mon Sep 17 00:00:00 2001 From: jack-berg <34418638+jack-berg@users.noreply.github.com> Date: Fri, 9 Aug 2024 09:55:32 -0500 Subject: [PATCH 512/901] Prepare 1.41.0 (#6635) --- CHANGELOG.md | 43 +++++++++++++++++++ .../sdk/common/CompletableResultCode.java | 7 ++- 2 files changed, 49 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b9d27b1cd0a..fcc23780a15 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,49 @@ ## Unreleased +### API + +* Move experimental suppress instrumentation context key to api internal package + ([#6546](https://github.com/open-telemetry/opentelemetry-java/pull/6546)) + +#### Incubator + +* Fix bug in `ExtendedContextPropagators` preventing context extraction when case is incorrect. + ([#6569](https://github.com/open-telemetry/opentelemetry-java/pull/6569)) + +### SDK + +* Extend `CompletableResultCode` with `failExceptionally(Throwable)`. + ([#6348](https://github.com/open-telemetry/opentelemetry-java/pull/6348)) + +#### Metrics + +* Avoid allocations when experimental advice doesn't remove any attributes. + ([#6629](https://github.com/open-telemetry/opentelemetry-java/pull/6629)) + +#### Exporter + +* Enable retry by default for OTLP exporters. + ([#6588](https://github.com/open-telemetry/opentelemetry-java/pull/6588)) +* Retry ConnectException, add retry logging. + ([#6614](https://github.com/open-telemetry/opentelemetry-java/pull/6614)) +* Extend `PrometheusHttpServer` with ability to configure default aggregation as function of + instrument kind, including experimental env var support. + ([#6541](https://github.com/open-telemetry/opentelemetry-java/pull/6541)) +* Add exporter data model impl for profiling signal type. + ([#6498](https://github.com/open-telemetry/opentelemetry-java/pull/6498)) +* Add Marshalers for profiling signal type. + ([#6565](https://github.com/open-telemetry/opentelemetry-java/pull/6565)) +* Use generateCertificates() of CertificateFactory to process certificates. + ([#6579](https://github.com/open-telemetry/opentelemetry-java/pull/6579)) + +#### Extensions + +* Add file configuration ComponentProvider support for exporters. + ([#6493](https://github.com/open-telemetry/opentelemetry-java/pull/6493)) +* Remove nullable from file config Factory contract. + ([#6612](https://github.com/open-telemetry/opentelemetry-java/pull/6612)) + ## Version 1.40.0 (2024-07-05) ### API diff --git a/sdk/common/src/main/java/io/opentelemetry/sdk/common/CompletableResultCode.java b/sdk/common/src/main/java/io/opentelemetry/sdk/common/CompletableResultCode.java index a3646343bd5..4a52effcd90 100644 --- a/sdk/common/src/main/java/io/opentelemetry/sdk/common/CompletableResultCode.java +++ b/sdk/common/src/main/java/io/opentelemetry/sdk/common/CompletableResultCode.java @@ -37,6 +37,8 @@ public static CompletableResultCode ofFailure() { /** * Returns a {@link CompletableResultCode} that has been {@link #failExceptionally(Throwable) * failed exceptionally}. + * + * @since 1.41.0 */ public static CompletableResultCode ofExceptionalFailure(Throwable throwable) { return new CompletableResultCode().failExceptionally(throwable); @@ -120,6 +122,8 @@ public CompletableResultCode fail() { /** * Completes this {@link CompletableResultCode} unsuccessfully if it is not already completed, * setting the {@link #getFailureThrowable() failure throwable} to {@code throwable}. + * + * @since 1.41.0 */ public CompletableResultCode failExceptionally(Throwable throwable) { return failInternal(throwable); @@ -156,7 +160,8 @@ public boolean isSuccess() { * via the {@link #whenComplete(Runnable)} method. * * @return the throwable if failed exceptionally, or null if: {@link #fail() failed without - * exception}, {@link #succeed() succeeded}, or not complete. + * exception}, {@link #succeed() succeeded}, or not complete.g + * @since 1.41.0 */ @Nullable public Throwable getFailureThrowable() { From 5ec05db03b19f30102f010e22bbf04f871d02e29 Mon Sep 17 00:00:00 2001 From: OpenTelemetry Bot <107717825+opentelemetrybot@users.noreply.github.com> Date: Fri, 9 Aug 2024 10:50:51 -0500 Subject: [PATCH 513/901] Update version to 1.42.0 (#6639) --- CHANGELOG.md | 2 ++ version.gradle.kts | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index fcc23780a15..eb95a202958 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,8 @@ ## Unreleased +## Version 1.41.0 (2024-08-09) + ### API * Move experimental suppress instrumentation context key to api internal package diff --git a/version.gradle.kts b/version.gradle.kts index 290a72c8024..91c279ce016 100644 --- a/version.gradle.kts +++ b/version.gradle.kts @@ -1,7 +1,7 @@ val snapshot = true allprojects { - var ver = "1.41.0" + var ver = "1.42.0" val release = findProperty("otel.release") if (release != null) { ver += "-" + release From 354e957b3ed65664b16faacd8cd9bcd46ff8c919 Mon Sep 17 00:00:00 2001 From: OpenTelemetry Bot <107717825+opentelemetrybot@users.noreply.github.com> Date: Fri, 9 Aug 2024 12:12:07 -0500 Subject: [PATCH 514/901] Post release for version 1.41.0 (#6640) --- README.md | 70 +++++++++---------- .../1.41.0_vs_1.40.0/opentelemetry-api.txt | 2 + .../opentelemetry-context.txt | 2 + .../opentelemetry-exporter-common.txt | 2 + .../opentelemetry-exporter-logging-otlp.txt | 2 + .../opentelemetry-exporter-logging.txt | 2 + .../opentelemetry-exporter-otlp-common.txt | 2 + .../opentelemetry-exporter-otlp.txt | 2 + ...y-exporter-sender-grpc-managed-channel.txt | 2 + .../opentelemetry-exporter-sender-jdk.txt | 2 + .../opentelemetry-exporter-sender-okhttp.txt | 2 + .../opentelemetry-exporter-zipkin.txt | 2 + .../opentelemetry-extension-kotlin.txt | 2 + ...ntelemetry-extension-trace-propagators.txt | 2 + .../opentelemetry-opentracing-shim.txt | 2 + .../opentelemetry-sdk-common.txt | 7 ++ ...emetry-sdk-extension-autoconfigure-spi.txt | 2 + ...ntelemetry-sdk-extension-autoconfigure.txt | 2 + ...ry-sdk-extension-jaeger-remote-sampler.txt | 2 + .../opentelemetry-sdk-logs.txt | 2 + .../opentelemetry-sdk-metrics.txt | 2 + .../opentelemetry-sdk-testing.txt | 2 + .../opentelemetry-sdk-trace.txt | 2 + .../1.41.0_vs_1.40.0/opentelemetry-sdk.txt | 2 + .../current_vs_latest/opentelemetry-api.txt | 2 +- .../opentelemetry-context.txt | 2 +- .../opentelemetry-exporter-common.txt | 2 +- .../opentelemetry-exporter-logging-otlp.txt | 2 +- .../opentelemetry-exporter-logging.txt | 2 +- .../opentelemetry-exporter-otlp-common.txt | 2 +- .../opentelemetry-exporter-otlp.txt | 2 +- ...y-exporter-sender-grpc-managed-channel.txt | 2 +- .../opentelemetry-exporter-sender-jdk.txt | 2 +- .../opentelemetry-exporter-sender-okhttp.txt | 2 +- .../opentelemetry-exporter-zipkin.txt | 2 +- .../opentelemetry-extension-kotlin.txt | 2 +- ...ntelemetry-extension-trace-propagators.txt | 2 +- .../opentelemetry-opentracing-shim.txt | 2 +- .../opentelemetry-sdk-common.txt | 9 +-- ...emetry-sdk-extension-autoconfigure-spi.txt | 2 +- ...ntelemetry-sdk-extension-autoconfigure.txt | 2 +- ...ry-sdk-extension-jaeger-remote-sampler.txt | 2 +- .../opentelemetry-sdk-logs.txt | 2 +- .../opentelemetry-sdk-metrics.txt | 2 +- .../opentelemetry-sdk-testing.txt | 2 +- .../opentelemetry-sdk-trace.txt | 2 +- .../current_vs_latest/opentelemetry-sdk.txt | 2 +- 47 files changed, 110 insertions(+), 64 deletions(-) create mode 100644 docs/apidiffs/1.41.0_vs_1.40.0/opentelemetry-api.txt create mode 100644 docs/apidiffs/1.41.0_vs_1.40.0/opentelemetry-context.txt create mode 100644 docs/apidiffs/1.41.0_vs_1.40.0/opentelemetry-exporter-common.txt create mode 100644 docs/apidiffs/1.41.0_vs_1.40.0/opentelemetry-exporter-logging-otlp.txt create mode 100644 docs/apidiffs/1.41.0_vs_1.40.0/opentelemetry-exporter-logging.txt create mode 100644 docs/apidiffs/1.41.0_vs_1.40.0/opentelemetry-exporter-otlp-common.txt create mode 100644 docs/apidiffs/1.41.0_vs_1.40.0/opentelemetry-exporter-otlp.txt create mode 100644 docs/apidiffs/1.41.0_vs_1.40.0/opentelemetry-exporter-sender-grpc-managed-channel.txt create mode 100644 docs/apidiffs/1.41.0_vs_1.40.0/opentelemetry-exporter-sender-jdk.txt create mode 100644 docs/apidiffs/1.41.0_vs_1.40.0/opentelemetry-exporter-sender-okhttp.txt create mode 100644 docs/apidiffs/1.41.0_vs_1.40.0/opentelemetry-exporter-zipkin.txt create mode 100644 docs/apidiffs/1.41.0_vs_1.40.0/opentelemetry-extension-kotlin.txt create mode 100644 docs/apidiffs/1.41.0_vs_1.40.0/opentelemetry-extension-trace-propagators.txt create mode 100644 docs/apidiffs/1.41.0_vs_1.40.0/opentelemetry-opentracing-shim.txt create mode 100644 docs/apidiffs/1.41.0_vs_1.40.0/opentelemetry-sdk-common.txt create mode 100644 docs/apidiffs/1.41.0_vs_1.40.0/opentelemetry-sdk-extension-autoconfigure-spi.txt create mode 100644 docs/apidiffs/1.41.0_vs_1.40.0/opentelemetry-sdk-extension-autoconfigure.txt create mode 100644 docs/apidiffs/1.41.0_vs_1.40.0/opentelemetry-sdk-extension-jaeger-remote-sampler.txt create mode 100644 docs/apidiffs/1.41.0_vs_1.40.0/opentelemetry-sdk-logs.txt create mode 100644 docs/apidiffs/1.41.0_vs_1.40.0/opentelemetry-sdk-metrics.txt create mode 100644 docs/apidiffs/1.41.0_vs_1.40.0/opentelemetry-sdk-testing.txt create mode 100644 docs/apidiffs/1.41.0_vs_1.40.0/opentelemetry-sdk-trace.txt create mode 100644 docs/apidiffs/1.41.0_vs_1.40.0/opentelemetry-sdk.txt diff --git a/README.md b/README.md index edd51463736..6fb2b74002f 100644 --- a/README.md +++ b/README.md @@ -104,7 +104,7 @@ dependency versions in sync. io.opentelemetry opentelemetry-bom - 1.40.0 + 1.41.0 pom import @@ -123,7 +123,7 @@ dependency versions in sync. ```groovy dependencies { - implementation platform("io.opentelemetry:opentelemetry-bom:1.40.0") + implementation platform("io.opentelemetry:opentelemetry-bom:1.41.0") implementation('io.opentelemetry:opentelemetry-api') } ``` @@ -132,8 +132,8 @@ Note that if you want to use any artifacts that have not fully stabilized yet (s ```groovy dependencies { - implementation platform("io.opentelemetry:opentelemetry-bom:1.40.0") - implementation platform('io.opentelemetry:opentelemetry-bom-alpha:1.40.0-alpha') + implementation platform("io.opentelemetry:opentelemetry-bom:1.41.0") + implementation platform('io.opentelemetry:opentelemetry-bom-alpha:1.41.0-alpha') implementation('io.opentelemetry:opentelemetry-api') implementation('io.opentelemetry:opentelemetry-exporter-prometheus') @@ -161,7 +161,7 @@ We strongly recommend using our published BOM to keep all dependency versions in io.opentelemetry opentelemetry-bom - 1.41.0-SNAPSHOT + 1.42.0-SNAPSHOT pom import @@ -184,7 +184,7 @@ repositories { } dependencies { - implementation platform("io.opentelemetry:opentelemetry-bom:1.41.0-SNAPSHOT") + implementation platform("io.opentelemetry:opentelemetry-bom:1.42.0-SNAPSHOT") implementation('io.opentelemetry:opentelemetry-api') } ``` @@ -229,66 +229,66 @@ dependency as follows, replacing `{{artifact-id}}` with the value from the "Arti | Component | Description | Artifact ID | Version | Javadoc | |----------------------------------------------|----------------------------------------|---------------------------|-------------------------------------------------------------|---------| -| [Bill of Materials (BOM)](./bom) | Bill of materials for stable artifacts | `opentelemetry-bom` | 1.40.0 | N/A | -| [Alpha Bill of Materials (BOM)](./bom-alpha) | Bill of materials for alpha artifacts | `opentelemetry-bom-alpha` | 1.40.0-alpha | N/A | +| [Bill of Materials (BOM)](./bom) | Bill of materials for stable artifacts | `opentelemetry-bom` | 1.41.0 | N/A | +| [Alpha Bill of Materials (BOM)](./bom-alpha) | Bill of materials for alpha artifacts | `opentelemetry-bom-alpha` | 1.41.0-alpha | N/A | ### API | Component | Description | Artifact ID | Version | Javadoc | |-----------------------------------|--------------------------------------------------------------------------------------|-------------------------------|---------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| [API](./api/all) | OpenTelemetry API, including metrics, traces, baggage, context | `opentelemetry-api` | 1.40.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-api.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-api) | -| [API Incubator](./api/incubator) | API incubator, including pass through propagator, and extended tracer, and Event API | `opentelemetry-api-incubator` | 1.40.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-api-incubator.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-api-incubator) | -| [Context API](./context) | OpenTelemetry context API | `opentelemetry-context` | 1.40.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-context.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-context) | +| [API](./api/all) | OpenTelemetry API, including metrics, traces, baggage, context | `opentelemetry-api` | 1.41.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-api.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-api) | +| [API Incubator](./api/incubator) | API incubator, including pass through propagator, and extended tracer, and Event API | `opentelemetry-api-incubator` | 1.41.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-api-incubator.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-api-incubator) | +| [Context API](./context) | OpenTelemetry context API | `opentelemetry-context` | 1.41.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-context.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-context) | ### API Extensions | Component | Description | Artifact ID | Version | Javadoc | |---------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|---------------------------------------------|-------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| [Kotlin Extension](./extensions/kotlin) | Context extension for coroutines | `opentelemetry-extension-kotlin` | 1.40.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-extension-kotlin.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-extension-kotlin) | -| [Trace Propagators Extension](./extensions/trace-propagators) | Trace propagators, including B3, Jaeger, OT Trace | `opentelemetry-extension-trace-propagators` | 1.40.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-extension-trace-propagators.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-extension-trace-propagators) | +| [Kotlin Extension](./extensions/kotlin) | Context extension for coroutines | `opentelemetry-extension-kotlin` | 1.41.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-extension-kotlin.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-extension-kotlin) | +| [Trace Propagators Extension](./extensions/trace-propagators) | Trace propagators, including B3, Jaeger, OT Trace | `opentelemetry-extension-trace-propagators` | 1.41.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-extension-trace-propagators.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-extension-trace-propagators) | ### SDK | Component | Description | Artifact ID | Version | Javadoc | |------------------------------|--------------------------------------------------------|-----------------------------|---------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| [SDK](./sdk/all) | OpenTelemetry SDK, including metrics, traces, and logs | `opentelemetry-sdk` | 1.40.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk) | -| [Metrics SDK](./sdk/metrics) | OpenTelemetry metrics SDK | `opentelemetry-sdk-metrics` | 1.40.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-metrics.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-metrics) | -| [Trace SDK](./sdk/trace) | OpenTelemetry trace SDK | `opentelemetry-sdk-trace` | 1.40.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-trace.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-trace) | -| [Log SDK](./sdk/logs) | OpenTelemetry log SDK | `opentelemetry-sdk-logs` | 1.40.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-logs.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-logs) | -| [SDK Common](./sdk/common) | Shared SDK components | `opentelemetry-sdk-common` | 1.40.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-common.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-common) | -| [SDK Testing](./sdk/testing) | Components for testing OpenTelemetry instrumentation | `opentelemetry-sdk-testing` | 1.40.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-testing.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-testing) | +| [SDK](./sdk/all) | OpenTelemetry SDK, including metrics, traces, and logs | `opentelemetry-sdk` | 1.41.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk) | +| [Metrics SDK](./sdk/metrics) | OpenTelemetry metrics SDK | `opentelemetry-sdk-metrics` | 1.41.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-metrics.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-metrics) | +| [Trace SDK](./sdk/trace) | OpenTelemetry trace SDK | `opentelemetry-sdk-trace` | 1.41.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-trace.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-trace) | +| [Log SDK](./sdk/logs) | OpenTelemetry log SDK | `opentelemetry-sdk-logs` | 1.41.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-logs.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-logs) | +| [SDK Common](./sdk/common) | Shared SDK components | `opentelemetry-sdk-common` | 1.41.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-common.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-common) | +| [SDK Testing](./sdk/testing) | Components for testing OpenTelemetry instrumentation | `opentelemetry-sdk-testing` | 1.41.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-testing.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-testing) | ### SDK Exporters | Component | Description | Artifact ID | Version | Javadoc | |-----------------------------------------------------------------------|------------------------------------------------------------------------------|------------------------------------------------------|-------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| [OTLP Exporters](./exporters/otlp/all) | OTLP gRPC & HTTP exporters, including traces, metrics, and logs | `opentelemetry-exporter-otlp` | 1.40.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-otlp.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-otlp) | -| [OTLP Logging Exporters](./exporters/logging-otlp) | Logging exporters in OTLP JSON encoding, including traces, metrics, and logs | `opentelemetry-exporter-logging-otlp` | 1.40.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-logging-otlp.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-logging-otlp) | -| [OTLP Common](./exporters/otlp/common) | Shared OTLP components (internal) | `opentelemetry-exporter-otlp-common` | 1.40.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-otlp-common.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-otlp-common) | -| [Logging Exporter](./exporters/logging) | Logging exporters, including metrics, traces, and logs | `opentelemetry-exporter-logging` | 1.40.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-logging.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-logging) | -| [Zipkin Exporter](./exporters/zipkin) | Zipkin trace exporter | `opentelemetry-exporter-zipkin` | 1.40.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-zipkin.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-zipkin) | -| [Prometheus Exporter](./exporters/prometheus) | Prometheus metric exporter | `opentelemetry-exporter-prometheus` | 1.40.0-alpha | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-prometheus.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-prometheus) | -| [Exporter Common](./exporters/common) | Shared exporter components (internal) | `opentelemetry-exporter-common` | 1.40.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-common.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-common) | -| [OkHttp Sender](./exporters/sender/okhttp) | OkHttp implementation of HttpSender (internal) | `opentelemetry-exporter-sender-okhttp` | 1.40.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-sender-okhttp.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-sender-okhttp) | -| [JDK Sender](./exporters/sender/jdk) | Java 11+ native HttpClient implementation of HttpSender (internal) | `opentelemetry-exporter-sender-jdk` | 1.40.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-sender-jdk.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-sender-jdk) | | -| [gRPC ManagedChannel Sender](./exporters/sender/grpc-managed-channel) | gRPC ManagedChannel implementation of GrpcSender (internal) | `opentelemetry-exporter-sender-grpc-managed-channel` | 1.40.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-sender-grpc-managed-channel.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-sender-grpc-managed-channel) | | +| [OTLP Exporters](./exporters/otlp/all) | OTLP gRPC & HTTP exporters, including traces, metrics, and logs | `opentelemetry-exporter-otlp` | 1.41.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-otlp.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-otlp) | +| [OTLP Logging Exporters](./exporters/logging-otlp) | Logging exporters in OTLP JSON encoding, including traces, metrics, and logs | `opentelemetry-exporter-logging-otlp` | 1.41.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-logging-otlp.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-logging-otlp) | +| [OTLP Common](./exporters/otlp/common) | Shared OTLP components (internal) | `opentelemetry-exporter-otlp-common` | 1.41.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-otlp-common.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-otlp-common) | +| [Logging Exporter](./exporters/logging) | Logging exporters, including metrics, traces, and logs | `opentelemetry-exporter-logging` | 1.41.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-logging.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-logging) | +| [Zipkin Exporter](./exporters/zipkin) | Zipkin trace exporter | `opentelemetry-exporter-zipkin` | 1.41.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-zipkin.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-zipkin) | +| [Prometheus Exporter](./exporters/prometheus) | Prometheus metric exporter | `opentelemetry-exporter-prometheus` | 1.41.0-alpha | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-prometheus.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-prometheus) | +| [Exporter Common](./exporters/common) | Shared exporter components (internal) | `opentelemetry-exporter-common` | 1.41.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-common.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-common) | +| [OkHttp Sender](./exporters/sender/okhttp) | OkHttp implementation of HttpSender (internal) | `opentelemetry-exporter-sender-okhttp` | 1.41.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-sender-okhttp.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-sender-okhttp) | +| [JDK Sender](./exporters/sender/jdk) | Java 11+ native HttpClient implementation of HttpSender (internal) | `opentelemetry-exporter-sender-jdk` | 1.41.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-sender-jdk.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-sender-jdk) | | +| [gRPC ManagedChannel Sender](./exporters/sender/grpc-managed-channel) | gRPC ManagedChannel implementation of GrpcSender (internal) | `opentelemetry-exporter-sender-grpc-managed-channel` | 1.41.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-sender-grpc-managed-channel.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-sender-grpc-managed-channel) | | ### SDK Extensions | Component | Description | Artifact ID | Version | Javadoc | |-------------------------------------------------------------------------------|------------------------------------------------------------------------------------|-----------------------------------------------------|-------------------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| [SDK Autoconfigure](./sdk-extensions/autoconfigure) | Autoconfigure OpenTelemetry SDK from env vars, system properties, and SPI | `opentelemetry-sdk-extension-autoconfigure` | 1.40.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-extension-autoconfigure.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-extension-autoconfigure) | -| [SDK Autoconfigure SPI](./sdk-extensions/autoconfigure-spi) | Service Provider Interface (SPI) definitions for autoconfigure | `opentelemetry-sdk-extension-autoconfigure-spi` | 1.40.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-extension-autoconfigure-spi.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-extension-autoconfigure-spi) | -| [SDK Jaeger Remote Sampler Extension](./sdk-extensions/jaeger-remote-sampler) | Sampler which obtains sampling configuration from remote Jaeger server | `opentelemetry-sdk-extension-jaeger-remote-sampler` | 1.40.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-extension-jaeger-remote-sampler.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-extension-jaeger-remote-sampler) | -| [SDK Incubator](./sdk-extensions/incubator) | SDK incubator, including YAML based view configuration, LeakDetectingSpanProcessor | `opentelemetry-sdk-extension-incubator` | 1.40.0-alpha | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-extension-incubator.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-extension-incubator) | +| [SDK Autoconfigure](./sdk-extensions/autoconfigure) | Autoconfigure OpenTelemetry SDK from env vars, system properties, and SPI | `opentelemetry-sdk-extension-autoconfigure` | 1.41.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-extension-autoconfigure.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-extension-autoconfigure) | +| [SDK Autoconfigure SPI](./sdk-extensions/autoconfigure-spi) | Service Provider Interface (SPI) definitions for autoconfigure | `opentelemetry-sdk-extension-autoconfigure-spi` | 1.41.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-extension-autoconfigure-spi.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-extension-autoconfigure-spi) | +| [SDK Jaeger Remote Sampler Extension](./sdk-extensions/jaeger-remote-sampler) | Sampler which obtains sampling configuration from remote Jaeger server | `opentelemetry-sdk-extension-jaeger-remote-sampler` | 1.41.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-extension-jaeger-remote-sampler.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-extension-jaeger-remote-sampler) | +| [SDK Incubator](./sdk-extensions/incubator) | SDK incubator, including YAML based view configuration, LeakDetectingSpanProcessor | `opentelemetry-sdk-extension-incubator` | 1.41.0-alpha | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-extension-incubator.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-extension-incubator) | ### Shims | Component | Description | Artifact ID | Version | Javadoc | |----------------------------------------|--------------------------------------------------------------|----------------------------------|-------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| [OpenCensus Shim](./opencensus-shim) | Bridge opencensus metrics into the OpenTelemetry metrics SDK | `opentelemetry-opencensus-shim` | 1.40.0-alpha | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-opencensus-shim.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-opencensus-shim) | -| [OpenTracing Shim](./opentracing-shim) | Bridge opentracing spans into the OpenTelemetry trace API | `opentelemetry-opentracing-shim` | 1.40.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-opentracing-shim.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-opentracing-shim) | +| [OpenCensus Shim](./opencensus-shim) | Bridge opencensus metrics into the OpenTelemetry metrics SDK | `opentelemetry-opencensus-shim` | 1.41.0-alpha | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-opencensus-shim.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-opencensus-shim) | +| [OpenTracing Shim](./opentracing-shim) | Bridge opentracing spans into the OpenTelemetry trace API | `opentelemetry-opentracing-shim` | 1.41.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-opentracing-shim.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-opentracing-shim) | ## Contributing diff --git a/docs/apidiffs/1.41.0_vs_1.40.0/opentelemetry-api.txt b/docs/apidiffs/1.41.0_vs_1.40.0/opentelemetry-api.txt new file mode 100644 index 00000000000..afe8b67a002 --- /dev/null +++ b/docs/apidiffs/1.41.0_vs_1.40.0/opentelemetry-api.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of opentelemetry-api-1.41.0.jar against opentelemetry-api-1.40.0.jar +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.41.0_vs_1.40.0/opentelemetry-context.txt b/docs/apidiffs/1.41.0_vs_1.40.0/opentelemetry-context.txt new file mode 100644 index 00000000000..02ae6fcdd0d --- /dev/null +++ b/docs/apidiffs/1.41.0_vs_1.40.0/opentelemetry-context.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of opentelemetry-context-1.41.0.jar against opentelemetry-context-1.40.0.jar +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.41.0_vs_1.40.0/opentelemetry-exporter-common.txt b/docs/apidiffs/1.41.0_vs_1.40.0/opentelemetry-exporter-common.txt new file mode 100644 index 00000000000..d7c1e865d7f --- /dev/null +++ b/docs/apidiffs/1.41.0_vs_1.40.0/opentelemetry-exporter-common.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of opentelemetry-exporter-common-1.41.0.jar against opentelemetry-exporter-common-1.40.0.jar +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.41.0_vs_1.40.0/opentelemetry-exporter-logging-otlp.txt b/docs/apidiffs/1.41.0_vs_1.40.0/opentelemetry-exporter-logging-otlp.txt new file mode 100644 index 00000000000..05e56d6ba4e --- /dev/null +++ b/docs/apidiffs/1.41.0_vs_1.40.0/opentelemetry-exporter-logging-otlp.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of opentelemetry-exporter-logging-otlp-1.41.0.jar against opentelemetry-exporter-logging-otlp-1.40.0.jar +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.41.0_vs_1.40.0/opentelemetry-exporter-logging.txt b/docs/apidiffs/1.41.0_vs_1.40.0/opentelemetry-exporter-logging.txt new file mode 100644 index 00000000000..8015b7b7ae0 --- /dev/null +++ b/docs/apidiffs/1.41.0_vs_1.40.0/opentelemetry-exporter-logging.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of opentelemetry-exporter-logging-1.41.0.jar against opentelemetry-exporter-logging-1.40.0.jar +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.41.0_vs_1.40.0/opentelemetry-exporter-otlp-common.txt b/docs/apidiffs/1.41.0_vs_1.40.0/opentelemetry-exporter-otlp-common.txt new file mode 100644 index 00000000000..3c388babdcc --- /dev/null +++ b/docs/apidiffs/1.41.0_vs_1.40.0/opentelemetry-exporter-otlp-common.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of opentelemetry-exporter-otlp-common-1.41.0.jar against opentelemetry-exporter-otlp-common-1.40.0.jar +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.41.0_vs_1.40.0/opentelemetry-exporter-otlp.txt b/docs/apidiffs/1.41.0_vs_1.40.0/opentelemetry-exporter-otlp.txt new file mode 100644 index 00000000000..6858a24a84d --- /dev/null +++ b/docs/apidiffs/1.41.0_vs_1.40.0/opentelemetry-exporter-otlp.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of opentelemetry-exporter-otlp-1.41.0.jar against opentelemetry-exporter-otlp-1.40.0.jar +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.41.0_vs_1.40.0/opentelemetry-exporter-sender-grpc-managed-channel.txt b/docs/apidiffs/1.41.0_vs_1.40.0/opentelemetry-exporter-sender-grpc-managed-channel.txt new file mode 100644 index 00000000000..64d2a51493f --- /dev/null +++ b/docs/apidiffs/1.41.0_vs_1.40.0/opentelemetry-exporter-sender-grpc-managed-channel.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of opentelemetry-exporter-sender-grpc-managed-channel-1.41.0.jar against opentelemetry-exporter-sender-grpc-managed-channel-1.40.0.jar +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.41.0_vs_1.40.0/opentelemetry-exporter-sender-jdk.txt b/docs/apidiffs/1.41.0_vs_1.40.0/opentelemetry-exporter-sender-jdk.txt new file mode 100644 index 00000000000..e84cf24859a --- /dev/null +++ b/docs/apidiffs/1.41.0_vs_1.40.0/opentelemetry-exporter-sender-jdk.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of opentelemetry-exporter-sender-jdk-1.41.0.jar against opentelemetry-exporter-sender-jdk-1.40.0.jar +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.41.0_vs_1.40.0/opentelemetry-exporter-sender-okhttp.txt b/docs/apidiffs/1.41.0_vs_1.40.0/opentelemetry-exporter-sender-okhttp.txt new file mode 100644 index 00000000000..d5e2bdb2a72 --- /dev/null +++ b/docs/apidiffs/1.41.0_vs_1.40.0/opentelemetry-exporter-sender-okhttp.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of opentelemetry-exporter-sender-okhttp-1.41.0.jar against opentelemetry-exporter-sender-okhttp-1.40.0.jar +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.41.0_vs_1.40.0/opentelemetry-exporter-zipkin.txt b/docs/apidiffs/1.41.0_vs_1.40.0/opentelemetry-exporter-zipkin.txt new file mode 100644 index 00000000000..a6290a1aa53 --- /dev/null +++ b/docs/apidiffs/1.41.0_vs_1.40.0/opentelemetry-exporter-zipkin.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of opentelemetry-exporter-zipkin-1.41.0.jar against opentelemetry-exporter-zipkin-1.40.0.jar +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.41.0_vs_1.40.0/opentelemetry-extension-kotlin.txt b/docs/apidiffs/1.41.0_vs_1.40.0/opentelemetry-extension-kotlin.txt new file mode 100644 index 00000000000..8f6c4acd90c --- /dev/null +++ b/docs/apidiffs/1.41.0_vs_1.40.0/opentelemetry-extension-kotlin.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of opentelemetry-extension-kotlin-1.41.0.jar against opentelemetry-extension-kotlin-1.40.0.jar +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.41.0_vs_1.40.0/opentelemetry-extension-trace-propagators.txt b/docs/apidiffs/1.41.0_vs_1.40.0/opentelemetry-extension-trace-propagators.txt new file mode 100644 index 00000000000..0be9d14cee0 --- /dev/null +++ b/docs/apidiffs/1.41.0_vs_1.40.0/opentelemetry-extension-trace-propagators.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of opentelemetry-extension-trace-propagators-1.41.0.jar against opentelemetry-extension-trace-propagators-1.40.0.jar +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.41.0_vs_1.40.0/opentelemetry-opentracing-shim.txt b/docs/apidiffs/1.41.0_vs_1.40.0/opentelemetry-opentracing-shim.txt new file mode 100644 index 00000000000..68d4997cb1b --- /dev/null +++ b/docs/apidiffs/1.41.0_vs_1.40.0/opentelemetry-opentracing-shim.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of opentelemetry-opentracing-shim-1.41.0.jar against opentelemetry-opentracing-shim-1.40.0.jar +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.41.0_vs_1.40.0/opentelemetry-sdk-common.txt b/docs/apidiffs/1.41.0_vs_1.40.0/opentelemetry-sdk-common.txt new file mode 100644 index 00000000000..cf51f2f56ef --- /dev/null +++ b/docs/apidiffs/1.41.0_vs_1.40.0/opentelemetry-sdk-common.txt @@ -0,0 +1,7 @@ +Comparing source compatibility of opentelemetry-sdk-common-1.41.0.jar against opentelemetry-sdk-common-1.40.0.jar +*** MODIFIED CLASS: PUBLIC FINAL io.opentelemetry.sdk.common.CompletableResultCode (not serializable) + === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 + +++ NEW METHOD: PUBLIC(+) io.opentelemetry.sdk.common.CompletableResultCode failExceptionally(java.lang.Throwable) + +++ NEW METHOD: PUBLIC(+) java.lang.Throwable getFailureThrowable() + +++ NEW ANNOTATION: javax.annotation.Nullable + +++ NEW METHOD: PUBLIC(+) STATIC(+) io.opentelemetry.sdk.common.CompletableResultCode ofExceptionalFailure(java.lang.Throwable) diff --git a/docs/apidiffs/1.41.0_vs_1.40.0/opentelemetry-sdk-extension-autoconfigure-spi.txt b/docs/apidiffs/1.41.0_vs_1.40.0/opentelemetry-sdk-extension-autoconfigure-spi.txt new file mode 100644 index 00000000000..55b6f8964c7 --- /dev/null +++ b/docs/apidiffs/1.41.0_vs_1.40.0/opentelemetry-sdk-extension-autoconfigure-spi.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of opentelemetry-sdk-extension-autoconfigure-spi-1.41.0.jar against opentelemetry-sdk-extension-autoconfigure-spi-1.40.0.jar +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.41.0_vs_1.40.0/opentelemetry-sdk-extension-autoconfigure.txt b/docs/apidiffs/1.41.0_vs_1.40.0/opentelemetry-sdk-extension-autoconfigure.txt new file mode 100644 index 00000000000..99b5916941d --- /dev/null +++ b/docs/apidiffs/1.41.0_vs_1.40.0/opentelemetry-sdk-extension-autoconfigure.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of opentelemetry-sdk-extension-autoconfigure-1.41.0.jar against opentelemetry-sdk-extension-autoconfigure-1.40.0.jar +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.41.0_vs_1.40.0/opentelemetry-sdk-extension-jaeger-remote-sampler.txt b/docs/apidiffs/1.41.0_vs_1.40.0/opentelemetry-sdk-extension-jaeger-remote-sampler.txt new file mode 100644 index 00000000000..08fc54d6789 --- /dev/null +++ b/docs/apidiffs/1.41.0_vs_1.40.0/opentelemetry-sdk-extension-jaeger-remote-sampler.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of opentelemetry-sdk-extension-jaeger-remote-sampler-1.41.0.jar against opentelemetry-sdk-extension-jaeger-remote-sampler-1.40.0.jar +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.41.0_vs_1.40.0/opentelemetry-sdk-logs.txt b/docs/apidiffs/1.41.0_vs_1.40.0/opentelemetry-sdk-logs.txt new file mode 100644 index 00000000000..d6449ab8f5f --- /dev/null +++ b/docs/apidiffs/1.41.0_vs_1.40.0/opentelemetry-sdk-logs.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of opentelemetry-sdk-logs-1.41.0.jar against opentelemetry-sdk-logs-1.40.0.jar +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.41.0_vs_1.40.0/opentelemetry-sdk-metrics.txt b/docs/apidiffs/1.41.0_vs_1.40.0/opentelemetry-sdk-metrics.txt new file mode 100644 index 00000000000..714c909d030 --- /dev/null +++ b/docs/apidiffs/1.41.0_vs_1.40.0/opentelemetry-sdk-metrics.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of opentelemetry-sdk-metrics-1.41.0.jar against opentelemetry-sdk-metrics-1.40.0.jar +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.41.0_vs_1.40.0/opentelemetry-sdk-testing.txt b/docs/apidiffs/1.41.0_vs_1.40.0/opentelemetry-sdk-testing.txt new file mode 100644 index 00000000000..7db61bd614f --- /dev/null +++ b/docs/apidiffs/1.41.0_vs_1.40.0/opentelemetry-sdk-testing.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of opentelemetry-sdk-testing-1.41.0.jar against opentelemetry-sdk-testing-1.40.0.jar +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.41.0_vs_1.40.0/opentelemetry-sdk-trace.txt b/docs/apidiffs/1.41.0_vs_1.40.0/opentelemetry-sdk-trace.txt new file mode 100644 index 00000000000..077d6ad7ed2 --- /dev/null +++ b/docs/apidiffs/1.41.0_vs_1.40.0/opentelemetry-sdk-trace.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of opentelemetry-sdk-trace-1.41.0.jar against opentelemetry-sdk-trace-1.40.0.jar +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.41.0_vs_1.40.0/opentelemetry-sdk.txt b/docs/apidiffs/1.41.0_vs_1.40.0/opentelemetry-sdk.txt new file mode 100644 index 00000000000..b2a1b0452f8 --- /dev/null +++ b/docs/apidiffs/1.41.0_vs_1.40.0/opentelemetry-sdk.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of opentelemetry-sdk-1.41.0.jar against opentelemetry-sdk-1.40.0.jar +No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-api.txt b/docs/apidiffs/current_vs_latest/opentelemetry-api.txt index 2f47172d1e2..58efc24b59d 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-api.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-api.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of opentelemetry-api-1.41.0-SNAPSHOT.jar against opentelemetry-api-1.40.0.jar +Comparing source compatibility of opentelemetry-api-1.42.0-SNAPSHOT.jar against opentelemetry-api-1.41.0.jar No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-context.txt b/docs/apidiffs/current_vs_latest/opentelemetry-context.txt index 99fd10ca51c..77ae369aa58 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-context.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-context.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of opentelemetry-context-1.41.0-SNAPSHOT.jar against opentelemetry-context-1.40.0.jar +Comparing source compatibility of opentelemetry-context-1.42.0-SNAPSHOT.jar against opentelemetry-context-1.41.0.jar No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-common.txt b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-common.txt index 293b0e7753a..bf7463bb94d 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-common.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-common.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of opentelemetry-exporter-common-1.41.0-SNAPSHOT.jar against opentelemetry-exporter-common-1.40.0.jar +Comparing source compatibility of opentelemetry-exporter-common-1.42.0-SNAPSHOT.jar against opentelemetry-exporter-common-1.41.0.jar No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-logging-otlp.txt b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-logging-otlp.txt index b3b31306740..f2331f45543 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-logging-otlp.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-logging-otlp.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of opentelemetry-exporter-logging-otlp-1.41.0-SNAPSHOT.jar against opentelemetry-exporter-logging-otlp-1.40.0.jar +Comparing source compatibility of opentelemetry-exporter-logging-otlp-1.42.0-SNAPSHOT.jar against opentelemetry-exporter-logging-otlp-1.41.0.jar No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-logging.txt b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-logging.txt index 592ea522f93..aea459ed4c3 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-logging.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-logging.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of opentelemetry-exporter-logging-1.41.0-SNAPSHOT.jar against opentelemetry-exporter-logging-1.40.0.jar +Comparing source compatibility of opentelemetry-exporter-logging-1.42.0-SNAPSHOT.jar against opentelemetry-exporter-logging-1.41.0.jar No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-otlp-common.txt b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-otlp-common.txt index 11b791dba91..882fe7863b9 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-otlp-common.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-otlp-common.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of opentelemetry-exporter-otlp-common-1.41.0-SNAPSHOT.jar against opentelemetry-exporter-otlp-common-1.40.0.jar +Comparing source compatibility of opentelemetry-exporter-otlp-common-1.42.0-SNAPSHOT.jar against opentelemetry-exporter-otlp-common-1.41.0.jar No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-otlp.txt b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-otlp.txt index c921ed65a0e..4930adb418b 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-otlp.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-otlp.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of opentelemetry-exporter-otlp-1.41.0-SNAPSHOT.jar against opentelemetry-exporter-otlp-1.40.0.jar +Comparing source compatibility of opentelemetry-exporter-otlp-1.42.0-SNAPSHOT.jar against opentelemetry-exporter-otlp-1.41.0.jar No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-sender-grpc-managed-channel.txt b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-sender-grpc-managed-channel.txt index c34170d151e..b7f21f39fd2 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-sender-grpc-managed-channel.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-sender-grpc-managed-channel.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of opentelemetry-exporter-sender-grpc-managed-channel-1.41.0-SNAPSHOT.jar against opentelemetry-exporter-sender-grpc-managed-channel-1.40.0.jar +Comparing source compatibility of opentelemetry-exporter-sender-grpc-managed-channel-1.42.0-SNAPSHOT.jar against opentelemetry-exporter-sender-grpc-managed-channel-1.41.0.jar No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-sender-jdk.txt b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-sender-jdk.txt index 30ec5ef8469..d83558fee87 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-sender-jdk.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-sender-jdk.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of opentelemetry-exporter-sender-jdk-1.41.0-SNAPSHOT.jar against opentelemetry-exporter-sender-jdk-1.40.0.jar +Comparing source compatibility of opentelemetry-exporter-sender-jdk-1.42.0-SNAPSHOT.jar against opentelemetry-exporter-sender-jdk-1.41.0.jar No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-sender-okhttp.txt b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-sender-okhttp.txt index 610f416ec20..5ac059f5f3d 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-sender-okhttp.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-sender-okhttp.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of opentelemetry-exporter-sender-okhttp-1.41.0-SNAPSHOT.jar against opentelemetry-exporter-sender-okhttp-1.40.0.jar +Comparing source compatibility of opentelemetry-exporter-sender-okhttp-1.42.0-SNAPSHOT.jar against opentelemetry-exporter-sender-okhttp-1.41.0.jar No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-zipkin.txt b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-zipkin.txt index da02402b76c..381d35e1b2d 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-zipkin.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-zipkin.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of opentelemetry-exporter-zipkin-1.41.0-SNAPSHOT.jar against opentelemetry-exporter-zipkin-1.40.0.jar +Comparing source compatibility of opentelemetry-exporter-zipkin-1.42.0-SNAPSHOT.jar against opentelemetry-exporter-zipkin-1.41.0.jar No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-extension-kotlin.txt b/docs/apidiffs/current_vs_latest/opentelemetry-extension-kotlin.txt index a853783527d..96b3803228a 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-extension-kotlin.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-extension-kotlin.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of opentelemetry-extension-kotlin-1.41.0-SNAPSHOT.jar against opentelemetry-extension-kotlin-1.40.0.jar +Comparing source compatibility of opentelemetry-extension-kotlin-1.42.0-SNAPSHOT.jar against opentelemetry-extension-kotlin-1.41.0.jar No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-extension-trace-propagators.txt b/docs/apidiffs/current_vs_latest/opentelemetry-extension-trace-propagators.txt index b081205d5c7..526c3eff1fa 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-extension-trace-propagators.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-extension-trace-propagators.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of opentelemetry-extension-trace-propagators-1.41.0-SNAPSHOT.jar against opentelemetry-extension-trace-propagators-1.40.0.jar +Comparing source compatibility of opentelemetry-extension-trace-propagators-1.42.0-SNAPSHOT.jar against opentelemetry-extension-trace-propagators-1.41.0.jar No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-opentracing-shim.txt b/docs/apidiffs/current_vs_latest/opentelemetry-opentracing-shim.txt index b5ebebc0df0..3f380a6ab35 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-opentracing-shim.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-opentracing-shim.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of opentelemetry-opentracing-shim-1.41.0-SNAPSHOT.jar against opentelemetry-opentracing-shim-1.40.0.jar +Comparing source compatibility of opentelemetry-opentracing-shim-1.42.0-SNAPSHOT.jar against opentelemetry-opentracing-shim-1.41.0.jar No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-common.txt b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-common.txt index 3b29b622a14..4a11449c46c 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-common.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-common.txt @@ -1,7 +1,2 @@ -Comparing source compatibility of opentelemetry-sdk-common-1.41.0-SNAPSHOT.jar against opentelemetry-sdk-common-1.40.0.jar -*** MODIFIED CLASS: PUBLIC FINAL io.opentelemetry.sdk.common.CompletableResultCode (not serializable) - === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 - +++ NEW METHOD: PUBLIC(+) io.opentelemetry.sdk.common.CompletableResultCode failExceptionally(java.lang.Throwable) - +++ NEW METHOD: PUBLIC(+) java.lang.Throwable getFailureThrowable() - +++ NEW ANNOTATION: javax.annotation.Nullable - +++ NEW METHOD: PUBLIC(+) STATIC(+) io.opentelemetry.sdk.common.CompletableResultCode ofExceptionalFailure(java.lang.Throwable) +Comparing source compatibility of opentelemetry-sdk-common-1.42.0-SNAPSHOT.jar against opentelemetry-sdk-common-1.41.0.jar +No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-extension-autoconfigure-spi.txt b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-extension-autoconfigure-spi.txt index 2746b5f2db3..4ea59eeeb08 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-extension-autoconfigure-spi.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-extension-autoconfigure-spi.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of opentelemetry-sdk-extension-autoconfigure-spi-1.41.0-SNAPSHOT.jar against opentelemetry-sdk-extension-autoconfigure-spi-1.40.0.jar +Comparing source compatibility of opentelemetry-sdk-extension-autoconfigure-spi-1.42.0-SNAPSHOT.jar against opentelemetry-sdk-extension-autoconfigure-spi-1.41.0.jar No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-extension-autoconfigure.txt b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-extension-autoconfigure.txt index c4cab0f5d87..39ad67087a2 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-extension-autoconfigure.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-extension-autoconfigure.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of opentelemetry-sdk-extension-autoconfigure-1.41.0-SNAPSHOT.jar against opentelemetry-sdk-extension-autoconfigure-1.40.0.jar +Comparing source compatibility of opentelemetry-sdk-extension-autoconfigure-1.42.0-SNAPSHOT.jar against opentelemetry-sdk-extension-autoconfigure-1.41.0.jar No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-extension-jaeger-remote-sampler.txt b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-extension-jaeger-remote-sampler.txt index 4e9bf403288..ee9075dca1c 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-extension-jaeger-remote-sampler.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-extension-jaeger-remote-sampler.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of opentelemetry-sdk-extension-jaeger-remote-sampler-1.41.0-SNAPSHOT.jar against opentelemetry-sdk-extension-jaeger-remote-sampler-1.40.0.jar +Comparing source compatibility of opentelemetry-sdk-extension-jaeger-remote-sampler-1.42.0-SNAPSHOT.jar against opentelemetry-sdk-extension-jaeger-remote-sampler-1.41.0.jar No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-logs.txt b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-logs.txt index 6a9004e48a2..3f689fe94cc 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-logs.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-logs.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of opentelemetry-sdk-logs-1.41.0-SNAPSHOT.jar against opentelemetry-sdk-logs-1.40.0.jar +Comparing source compatibility of opentelemetry-sdk-logs-1.42.0-SNAPSHOT.jar against opentelemetry-sdk-logs-1.41.0.jar No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-metrics.txt b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-metrics.txt index 16fcea04710..b0c177298f5 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-metrics.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-metrics.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of opentelemetry-sdk-metrics-1.41.0-SNAPSHOT.jar against opentelemetry-sdk-metrics-1.40.0.jar +Comparing source compatibility of opentelemetry-sdk-metrics-1.42.0-SNAPSHOT.jar against opentelemetry-sdk-metrics-1.41.0.jar No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-testing.txt b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-testing.txt index e82c60b281d..7c4d542dd50 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-testing.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-testing.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of opentelemetry-sdk-testing-1.41.0-SNAPSHOT.jar against opentelemetry-sdk-testing-1.40.0.jar +Comparing source compatibility of opentelemetry-sdk-testing-1.42.0-SNAPSHOT.jar against opentelemetry-sdk-testing-1.41.0.jar No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-trace.txt b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-trace.txt index 4e569d20a7f..98ead6c6c5b 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-trace.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-trace.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of opentelemetry-sdk-trace-1.41.0-SNAPSHOT.jar against opentelemetry-sdk-trace-1.40.0.jar +Comparing source compatibility of opentelemetry-sdk-trace-1.42.0-SNAPSHOT.jar against opentelemetry-sdk-trace-1.41.0.jar No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-sdk.txt b/docs/apidiffs/current_vs_latest/opentelemetry-sdk.txt index e94606b0616..ac51a9a4d98 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-sdk.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-sdk.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of opentelemetry-sdk-1.41.0-SNAPSHOT.jar against opentelemetry-sdk-1.40.0.jar +Comparing source compatibility of opentelemetry-sdk-1.42.0-SNAPSHOT.jar against opentelemetry-sdk-1.41.0.jar No changes. \ No newline at end of file From 94238acd7167acc6d211ae70c87caa7751b0fb29 Mon Sep 17 00:00:00 2001 From: jack-berg <34418638+jack-berg@users.noreply.github.com> Date: Fri, 9 Aug 2024 17:25:33 -0500 Subject: [PATCH 515/901] New gradle shadow plugin location (#6637) --- integration-tests/tracecontext/build.gradle.kts | 2 +- sdk/trace-shaded-deps/build.gradle.kts | 2 +- settings.gradle.kts | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/integration-tests/tracecontext/build.gradle.kts b/integration-tests/tracecontext/build.gradle.kts index 44cea7d471b..17b01ecddb7 100644 --- a/integration-tests/tracecontext/build.gradle.kts +++ b/integration-tests/tracecontext/build.gradle.kts @@ -1,7 +1,7 @@ plugins { id("otel.java-conventions") - id("com.github.johnrengelman.shadow") + id("com.gradleup.shadow") } description = "OpenTelemetry W3C Context Propagation Integration Tests" diff --git a/sdk/trace-shaded-deps/build.gradle.kts b/sdk/trace-shaded-deps/build.gradle.kts index e4cd9727909..1254aa3b600 100644 --- a/sdk/trace-shaded-deps/build.gradle.kts +++ b/sdk/trace-shaded-deps/build.gradle.kts @@ -1,7 +1,7 @@ plugins { id("otel.java-conventions") - id("com.github.johnrengelman.shadow") + id("com.gradleup.shadow") } // This project is not published, it is bundled into :sdk:trace diff --git a/settings.gradle.kts b/settings.gradle.kts index 93b2663ff18..4c02af73c6f 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -1,6 +1,6 @@ pluginManagement { plugins { - id("com.github.johnrengelman.shadow") version "8.1.1" + id("com.gradleup.shadow") version "8.3.0" id("com.gradle.develocity") version "3.17.6" id("de.undercouch.download") version "5.6.0" id("org.jsonschema2pojo") version "1.2.1" From 5af07a6b9ddc5677a6e4162913f9ce660962a4a7 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 10 Aug 2024 12:12:07 -0700 Subject: [PATCH 516/901] Update slf4j monorepo to v2.0.16 (#6641) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- dependencyManagement/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index 0ec77ee1eea..6c155fc46a1 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -29,7 +29,7 @@ val errorProneVersion = "2.29.2" val jmhVersion = "1.37" // Mockito 5.x.x requires Java 11 https://github.com/mockito/mockito/releases/tag/v5.0.0 val mockitoVersion = "4.11.0" -val slf4jVersion = "2.0.15" +val slf4jVersion = "2.0.16" val opencensusVersion = "0.31.1" val prometheusClientVersion = "0.16.0" From dcdc6727f78638557ccc65742cb7898e306ea227 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 12 Aug 2024 19:22:08 -0700 Subject: [PATCH 517/901] Update dependency com.linecorp.armeria:armeria-bom to v1.30.0 (#6643) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- dependencyManagement/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index 6c155fc46a1..1d022032976 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -11,7 +11,7 @@ val DEPENDENCY_BOMS = listOf( "com.fasterxml.jackson:jackson-bom:2.17.2", "com.google.guava:guava-bom:33.2.1-jre", "com.google.protobuf:protobuf-bom:3.25.4", - "com.linecorp.armeria:armeria-bom:1.29.4", + "com.linecorp.armeria:armeria-bom:1.30.0", "com.squareup.okhttp3:okhttp-bom:4.12.0", "com.squareup.okio:okio-bom:3.9.0", // applies to transitive dependencies of okhttp "io.grpc:grpc-bom:1.66.0", From ad120a5bff0887dffedb9c73af8e8e0aeb63659a Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 14 Aug 2024 19:06:49 -0700 Subject: [PATCH 518/901] Update dependency org.junit:junit-bom to v5.11.0 (#6646) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- dependencyManagement/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index 1d022032976..35343491d23 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -19,7 +19,7 @@ val DEPENDENCY_BOMS = listOf( "io.zipkin.brave:brave-bom:6.0.3", "io.zipkin.reporter2:zipkin-reporter-bom:3.4.0", "org.assertj:assertj-bom:3.26.3", - "org.junit:junit-bom:5.10.3", + "org.junit:junit-bom:5.11.0", "org.testcontainers:testcontainers-bom:1.20.1", "org.snakeyaml:snakeyaml-engine:2.7" ) From 32c8d665808841983f34eda25ac47ce44dfef8b0 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 19 Aug 2024 13:55:08 -0500 Subject: [PATCH 519/901] Update dependency gradle to v8.10 (#6647) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- gradle/wrapper/gradle-wrapper.jar | Bin 43504 -> 43583 bytes gradle/wrapper/gradle-wrapper.properties | 4 ++-- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index 2c3521197d7c4586c843d1d3e9090525f1898cde..a4b76b9530d66f5e68d973ea569d8e19de379189 100644 GIT binary patch delta 3990 zcmV;H4{7l5(*nQL0Kr1kzC=_KMxQY0|W5(lc#i zH*M1^P4B}|{x<+fkObwl)u#`$GxKKV&3pg*-y6R6txw)0qU|Clf9Uds3x{_-**c=7 z&*)~RHPM>Rw#Hi1R({;bX|7?J@w}DMF>dQQU2}9yj%iLjJ*KD6IEB2^n#gK7M~}6R zkH+)bc--JU^pV~7W=3{E*4|ZFpDpBa7;wh4_%;?XM-5ZgZNnVJ=vm!%a2CdQb?oTa z70>8rTb~M$5Tp!Se+4_OKWOB1LF+7gv~$$fGC95ToUM(I>vrd$>9|@h=O?eARj0MH zT4zo(M>`LWoYvE>pXvqG=d96D-4?VySz~=tPVNyD$XMshoTX(1ZLB5OU!I2OI{kb) zS8$B8Qm>wLT6diNnyJZC?yp{Kn67S{TCOt-!OonOK7$K)e-13U9GlnQXPAb&SJ0#3 z+vs~+4Qovv(%i8g$I#FCpCG^C4DdyQw3phJ(f#y*pvNDQCRZ~MvW<}fUs~PL=4??j zmhPyg<*I4RbTz|NHFE-DC7lf2=}-sGkE5e!RM%3ohM7_I^IF=?O{m*uUPH(V?gqyc(Rp?-Qu(3bBIL4Fz(v?=_Sh?LbK{nqZMD>#9D_hNhaV$0ef3@9V90|0u#|PUNTO>$F=qRhg1duaE z0`v~X3G{8RVT@kOa-pU+z8{JWyP6GF*u2e8eKr7a2t1fuqQy)@d|Qn(%YLZ62TWtoX@$nL}9?atE#Yw`rd(>cr0gY;dT9~^oL;u)zgHUvxc2I*b&ZkGM-iq=&(?kyO(3}=P! zRp=rErEyMT5UE9GjPHZ#T<`cnD)jyIL!8P{H@IU#`e8cAG5jMK zVyKw7--dAC;?-qEu*rMr$5@y535qZ6p(R#+fLA_)G~!wnT~~)|s`}&fA(s6xXN`9j zP#Fd3GBa#HeS{5&8p?%DKUyN^X9cYUc6vq}D_3xJ&d@=6j(6BZKPl?!k1?!`f3z&a zR4ZF60Mx7oBxLSxGuzA*Dy5n-d2K=+)6VMZh_0KetK|{e;E{8NJJ!)=_E~1uu=A=r zrn&gh)h*SFhsQJo!f+wKMIE;-EOaMSMB@aXRU(UcnJhZW^B^mgs|M9@5WF@s6B0p& zm#CTz)yiQCgURE{%hjxHcJ6G&>G9i`7MyftL!QQd5 z@RflRs?7)99?X`kHNt>W3l7YqscBpi*R2+fsgABor>KVOu(i(`03aytf2UA!&SC9v z!E}whj#^9~=XHMinFZ;6UOJjo=mmNaWkv~nC=qH9$s-8roGeyaW-E~SzZ3Gg>j zZ8}<320rg4=$`M0nxN!w(PtHUjeeU?MvYgWKZ6kkzABK;vMN0|U;X9abJleJA(xy<}5h5P(5 z{RzAFPvMnX2m0yH0Jn2Uo-p`daE|(O`YQiC#jB8;6bVIUf?SY(k$#C0`d6qT`>Xe0+0}Oj0=F&*D;PVe=Z<=0AGI<6$gYLwa#r` zm449x*fU;_+J>Mz!wa;T-wldoBB%&OEMJgtm#oaI60TSYCy7;+$5?q!zi5K`u66Wq zvg)Fx$s`V3Em{=OEY{3lmh_7|08ykS&U9w!kp@Ctuzqe1JFOGz6%i5}Kmm9>^=gih z?kRxqLA<3@e=}G4R_?phW{4DVr?`tPfyZSN@R=^;P;?!2bh~F1I|fB7P=V=9a6XU5 z<#0f>RS0O&rhc&nTRFOW7&QhevP0#>j0eq<1@D5yAlgMl5n&O9X|Vq}%RX}iNyRFF z7sX&u#6?E~bm~N|z&YikXC=I0E*8Z$v7PtWfjy)$e_Ez25fnR1Q=q1`;U!~U>|&YS zaOS8y!^ORmr2L4ik!IYR8@Dcx8MTC=(b4P6iE5CnrbI~7j7DmM8em$!da&D!6Xu)!vKPdLG z9f#)se|6=5yOCe)N6xDhPI!m81*dNe7u985zi%IVfOfJh69+#ag4ELzGne?o`eA`42K4T)h3S+s)5IT97%O>du- z0U54L8m4}rkRQ?QBfJ%DLssy^+a7Ajw;0&`NOTY4o;0-ivm9 zBz1C%nr_hQ)X)^QM6T1?=yeLkuG9Lf50(eH}`tFye;01&(p?8i+6h};VV-2B~qdxeC#=X z(JLlzy&fHkyi9Ksbcs~&r^%lh^2COldLz^H@X!s~mr9Dr6z!j+4?zkD@Ls7F8(t(f z9`U?P$Lmn*Y{K}aR4N&1N=?xtQ1%jqf1~pJyQ4SgBrEtR`j4lQuh7cqP49Em5cO=I zB(He2`iPN5M=Y0}h(IU$37ANTGx&|b-u1BYA*#dE(L-lptoOpo&th~E)_)y-`6kSH z3vvyVrcBwW^_XYReJ=JYd9OBQrzv;f2AQdZH#$Y{Y+Oa33M70XFI((fs;mB4e`<<{ ze4dv2B0V_?Ytsi>>g%qs*}oDGd5d(RNZ*6?7qNbdp7wP4T72=F&r?Ud#kZr8Ze5tB z_oNb7{G+(o2ajL$!69FW@jjPQ2a5C)m!MKKRirC$_VYIuVQCpf9rIms0GRDf)8AH${I`q^~5rjot@#3$2#zT2f`(N^P7Z;6(@EK$q*Jgif00I6*^ZGV+XB5uw*1R-@23yTw&WKD{s1;HTL;dO)%5i#`dc6b7;5@^{KU%N|A-$zsYw4)7LA{3`Zp>1 z-?K9_IE&z)dayUM)wd8K^29m-l$lFhi$zj0l!u~4;VGR6Y!?MAfBC^?QD53hy6VdD z@eUZIui}~L%#SmajaRq1J|#> z4m=o$vZ*34=ZWK2!QMNEcp2Lbc5N1q!lEDq(bz0b;WI9;e>l=CG9^n#ro`w>_0F$Q zfZ={2QyTkfByC&gy;x!r*NyXXbk=a%~~(#K?< zTke0HuF5{Q+~?@!KDXR|g+43$+;ab`^flS%miup_0OUTm=nIc%d5nLP)i308PIjl_YMF6cpQ__6&$n6it8K- z8PIjl_YMF6cpQ_!r)L8IivW`WdK8mBs6PXdjR2DYdK8nCs73=4j{uVadK8oNjwX|E wpAeHLsTu^*Y>Trk?aBtSQ(D-o$(D8Px^?ZI-PUB? z*1fv!{YdHme3Fc8%cR@*@zc5A_nq&2=R47Hp@$-JF4Fz*;SLw5}K^y>s-s;V!}b2i=5=M- zComP?ju>8Fe@=H@rlwe1l`J*6BTTo`9b$zjQ@HxrAhp0D#u?M~TxGC_!?ccCHCjt| zF*PgJf@kJB`|Ml}cmsyrAjO#Kjr^E5p29w+#>$C`Q|54BoDv$fQ9D?3n32P9LPMIzu?LjNqggOH=1@T{9bMn*u8(GI z!;MLTtFPHal^S>VcJdiYqX0VU|Rn@A}C1xOlxCribxes0~+n2 z6qDaIA2$?e`opx3_KW!rAgbpzU)gFdjAKXh|5w``#F0R|c)Y)Du0_Ihhz^S?k^pk% zP>9|pIDx)xHH^_~+aA=^$M!<8K~Hy(71nJGf6`HnjtS=4X4=Hk^O71oNia2V{HUCC zoN3RSBS?mZCLw;l4W4a+D8qc)XJS`pUJ5X-f^1ytxwr`@si$lAE?{4G|o; zO0l>`rr?;~c;{ZEFJ!!3=7=FdGJ?Q^xfNQh4A?i;IJ4}B+A?4olTK(fN++3CRBP97 ze~lG9h%oegkn)lpW-4F8o2`*WW0mZHwHez`ko@>U1_;EC_6ig|Drn@=DMV9YEUSCa zIf$kHei3(u#zm9I!Jf(4t`Vm1lltJ&lVHy(eIXE8sy9sUpmz%I_gA#8x^Zv8%w?r2 z{GdkX1SkzRIr>prRK@rqn9j2wG|rUvf6PJbbin=yy-TAXrguvzN8jL$hUrIXzr^s5 zVM?H4;eM-QeRFr06@ifV(ocvk?_)~N@1c2ien56UjWXid6W%6ievIh)>dk|rIs##^kY67ib8Kw%#-oVFaXG7$ERyA9(NSJUvWiOA5H(!{uOpcW zg&-?iqPhds%3%tFspHDqqr;A!e@B#iPQjHd=c>N1LoOEGRehVoPOdxJ>b6>yc#o#+ zl8s8!(|NMeqjsy@0x{8^j0d00SqRZjp{Kj)&4UHYGxG+z9b-)72I*&J70?+8e?p_@ z=>-(>l6z5vYlP~<2%DU02b!mA{7mS)NS_eLe=t)sm&+Pmk?asOEKlkPQ)EUvvfC=;4M&*|I!w}(@V_)eUKLA_t^%`o z0PM9LV|UKTLnk|?M3u!|f2S0?UqZsEIH9*NJS-8lzu;A6-rr-ot=dg9SASoluZUkFH$7X; zP=?kYX!K?JL-b~<#7wU;b;eS)O;@?h%sPPk{4xEBxb{!sm0AY|f9cNvx6>$3F!*0c z75H=dy8JvTyO8}g1w{$9T$p~5en}AeSLoCF>_RT9YPMpChUjl310o*$QocjbH& zbnwg#gssR#jDVN{uEi3n(PZ%PFZ|6J2 z5_rBf0-u>e4sFe0*Km49ATi7>Kn0f9!uc|rRMR1Dtt6m1LW8^>qFlo}h$@br=Rmpi z;mI&>OF64Be{dVeHI8utrh)v^wsZ0jii%x8UgZ8TC%K~@I(4E};GFW&(;WVov}3%H zH;IhRkfD^(vt^DjZz(MyHLZxv8}qzPc(%itBkBwf_fC~sDBgh<3XAv5cxxfF3<2U! z03Xe&z`is!JDHbe;mNmfkH+_LFE*I2^mdL@7(@9DfAcP6O04V-ko;Rpgp<%Cj5r8Z zd0`sXoIjV$j)--;jA6Zy^D5&5v$o^>e%>Q?9GLm{i~p^lAn!%ZtF$I~>39XVZxk0b zROh^Bk9cE0AJBLozZIEmy7xG(yHWGztvfnr0(2ro1%>zsGMS^EMu+S$r=_;9 zWwZkgf7Q7`H9sLf2Go^Xy6&h~a&%s2_T@_Csf19MntF$aVFiFkvE3_hUg(B@&Xw@YJ zpL$wNYf78=0c@!QU6_a$>CPiXT7QAGDM}7Z(0z#_ZA=fmLUj{2z7@Ypo71UDy8GHr z-&TLKf6a5WCf@Adle3VglBt4>Z>;xF}}-S~B7<(%B;Y z0QR55{z-buw>8ilNM3u6I+D$S%?)(p>=eBx-HpvZj{7c*_?K=d()*7q?93us}1dq%FAFYLsW8ZTQ_XZLh`P2*6(NgS}qGcfGXVWpwsp#Rs}IuKbk*`2}&) zI^Vsk6S&Q4@oYS?dJ`NwMVBs6f57+RxdqVub#PvMu?$=^OJy5xEl0<5SLsSRy%%a0 zi}Y#1-F3m;Ieh#Y12UgW?-R)|eX>ZuF-2cc!1>~NS|XSF-6In>zBoZg+ml!6%fk7U zw0LHcz8VQk(jOJ+Yu)|^|15ufl$KQd_1eUZZzj`aC%umU6F1&D5XVWce_wAe(qCSZ zpX-QF4e{EmEVN9~6%bR5U*UT{eMHfcUo`jw*u?4r2s_$`}U{?NjvEm(u&<>B|%mq$Q3weshxk z76<``8vh{+nX`@9CB6IE&z)I%IFjR^LH{s1p|eppv=x za(g_jLU|xjWMAn-V7th$f({|LG8zzIE0g?cyW;%Dmtv%C+0@xVxPE^ zyZzi9P%JAD6ynwHptuzP`Kox7*9h7XSMonCalv;Md0i9Vb-c*!f0ubfk?&T&T}AHh z4m8Bz{JllKcdNg?D^%a5MFQ;#1z|*}H^qHLzW)L}wp?2tY7RejtSh8<;Zw)QGJYUm z|MbTxyj*McKlStlT9I5XlSWtQGN&-LTr2XyNU+`490rg?LYLMRnz-@oKqT1hpCGqP zyRXt4=_Woj$%n5ee<3zhLF>5>`?m9a#xQH+Jk_+|RM8Vi;2*XbK- zEL6sCpaGPzP>k8f4Kh|##_imt#zJMB;ir|JrMPGW`rityK1vHXMLy18%qmMQAm4WZ zP)i30KR&5vs15)C+8dM66&$k~i|ZT;KR&5vs15)C+8dJ(sAmGPijyIz6_bsqKLSFH zlOd=TljEpH0>h4zA*dCTK&emy#FCRCs1=i^sZ9bFmXjf<6_X39E(XY)00000#N437 diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 68e8816d71c..2b189974c29 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,7 +1,7 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionSha256Sum=d725d707bfabd4dfdc958c624003b3c80accc03f7037b5122c4b1d0ef15cecab -distributionUrl=https\://services.gradle.org/distributions/gradle-8.9-bin.zip +distributionSha256Sum=5b9c5eb3f9fc2c94abaea57d90bd78747ca117ddbbf96c859d3741181a12bf2a +distributionUrl=https\://services.gradle.org/distributions/gradle-8.10-bin.zip networkTimeout=10000 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME From 581690ecaca5b92979f0ff559a083a63b4b98590 Mon Sep 17 00:00:00 2001 From: Chung Nguyen Date: Mon, 19 Aug 2024 20:57:08 +0200 Subject: [PATCH 520/901] supress zipkin exporters instrumentations (#6552) --- .../exporter/zipkin/ZipkinSpanExporter.java | 24 +++++--- .../zipkin/ZipkinSpanExporterTest.java | 58 +++++++++++++++++++ 2 files changed, 73 insertions(+), 9 deletions(-) diff --git a/exporters/zipkin/src/main/java/io/opentelemetry/exporter/zipkin/ZipkinSpanExporter.java b/exporters/zipkin/src/main/java/io/opentelemetry/exporter/zipkin/ZipkinSpanExporter.java index c92f70db3f5..a76d3177fd4 100644 --- a/exporters/zipkin/src/main/java/io/opentelemetry/exporter/zipkin/ZipkinSpanExporter.java +++ b/exporters/zipkin/src/main/java/io/opentelemetry/exporter/zipkin/ZipkinSpanExporter.java @@ -5,6 +5,7 @@ package io.opentelemetry.exporter.zipkin; +import io.opentelemetry.api.internal.InstrumentationUtil; import io.opentelemetry.api.metrics.MeterProvider; import io.opentelemetry.exporter.internal.ExporterMetrics; import io.opentelemetry.sdk.common.CompletableResultCode; @@ -75,15 +76,20 @@ public CompletableResultCode export(Collection spanDataList) { encodedSpans.add(encoder.encode(zipkinSpan)); } - try { - sender.send(encodedSpans); - exporterMetrics.addSuccess(numItems); - return CompletableResultCode.ofSuccess(); - } catch (IOException | RuntimeException t) { - exporterMetrics.addFailed(numItems); - logger.log(Level.WARNING, "Failed to export spans", t); - return CompletableResultCode.ofFailure(); - } + CompletableResultCode resultCode = new CompletableResultCode(); + InstrumentationUtil.suppressInstrumentation( + () -> { + try { + sender.send(encodedSpans); + exporterMetrics.addSuccess(numItems); + resultCode.succeed(); + } catch (IOException | RuntimeException e) { + exporterMetrics.addFailed(numItems); + logger.log(Level.WARNING, "Failed to export spans", e); + resultCode.fail(); + } + }); + return resultCode; } @Override diff --git a/exporters/zipkin/src/test/java/io/opentelemetry/exporter/zipkin/ZipkinSpanExporterTest.java b/exporters/zipkin/src/test/java/io/opentelemetry/exporter/zipkin/ZipkinSpanExporterTest.java index 673855d4a8c..2c70691744c 100644 --- a/exporters/zipkin/src/test/java/io/opentelemetry/exporter/zipkin/ZipkinSpanExporterTest.java +++ b/exporters/zipkin/src/test/java/io/opentelemetry/exporter/zipkin/ZipkinSpanExporterTest.java @@ -9,12 +9,15 @@ import static io.opentelemetry.exporter.zipkin.ZipkinTestUtil.zipkinSpanBuilder; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.junit.jupiter.api.Assertions.assertTrue; import static org.mockito.Mockito.doThrow; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import io.github.netmikey.logunit.api.LogCapturer; +import io.opentelemetry.api.internal.InstrumentationUtil; import io.opentelemetry.api.metrics.MeterProvider; +import io.opentelemetry.context.Context; import io.opentelemetry.internal.testing.slf4j.SuppressLogger; import io.opentelemetry.sdk.common.CompletableResultCode; import io.opentelemetry.sdk.testing.trace.TestSpanData; @@ -22,7 +25,9 @@ import java.net.InetAddress; import java.time.Duration; import java.util.Collections; +import java.util.List; import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicBoolean; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.junit.jupiter.api.extension.RegisterExtension; @@ -244,4 +249,57 @@ void stringRepresentation() { "ZipkinSpanExporter{endpoint=http://zipkin:9411/api/v2/spans, compressionEnabled=false, readTimeoutMillis=15000}"); } } + + @Test + void suppressInstrumentation() { + TestSpanData testSpanData = spanBuilder().build(); + + SuppressCatchingSender suppressCatchingSender = new SuppressCatchingSender(Encoding.JSON); + ZipkinSpanExporter zipkinSpanExporter = + new ZipkinSpanExporter( + new ZipkinSpanExporterBuilder(), + mockEncoder, + suppressCatchingSender, + MeterProvider::noop, + mockTransformer); + + byte[] someBytes = new byte[0]; + Span zipkinSpan = + zipkinSpanBuilder(Span.Kind.SERVER, localIp) + .putTag(OtelToZipkinSpanTransformer.OTEL_STATUS_CODE, "OK") + .build(); + when(mockTransformer.generateSpan(testSpanData)).thenReturn(zipkinSpan); + when(mockEncoder.encode(zipkinSpan)).thenReturn(someBytes); + + zipkinSpanExporter.export(Collections.singleton(testSpanData)); + + // Instrumentation should be suppressed on send, to avoid incidental spans related to span + // export. + assertTrue(suppressCatchingSender.sent.get()); + assertTrue(suppressCatchingSender.suppressed.get()); + } + + static class SuppressCatchingSender extends BytesMessageSender.Base { + + final AtomicBoolean sent = new AtomicBoolean(); + final AtomicBoolean suppressed = new AtomicBoolean(); + + protected SuppressCatchingSender(Encoding encoding) { + super(encoding); + } + + @Override + public int messageMaxBytes() { + return 1024; + } + + @Override + public void send(List list) throws IOException { + sent.set(true); + suppressed.set(InstrumentationUtil.shouldSuppressInstrumentation(Context.current())); + } + + @Override + public void close() throws IOException {} + } } From 023c8cc291ae4195aacef9cb5c9e0ddceb689bf7 Mon Sep 17 00:00:00 2001 From: SylvainJuge <763082+SylvainJuge@users.noreply.github.com> Date: Mon, 19 Aug 2024 20:58:23 +0200 Subject: [PATCH 521/901] Fix broken markdown links (#6655) --- sdk-extensions/incubator/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sdk-extensions/incubator/README.md b/sdk-extensions/incubator/README.md index cfc76184c31..abdb90cf9a7 100644 --- a/sdk-extensions/incubator/README.md +++ b/sdk-extensions/incubator/README.md @@ -4,7 +4,7 @@ This artifact contains experimental code related to the trace and metric SDKs. ## File Configuration -Allows for YAML based file configuration of `OpenTelemetrySdk` as defined in the [specification](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/configuration/file-configuration.md). +Allows for YAML based file configuration of `OpenTelemetrySdk` as defined in the [specification](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/configuration/data-model.md#file-based-configuration-model). Usage: @@ -18,7 +18,7 @@ try (FileInputStream yamlConfigFileInputStream = new FileInputStream("/path/to/c ``` Notes: -* Environment variable substitution is supported as [defined in the spec](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/configuration/file-configuration.md#environment-variable-substitution) +* Environment variable substitution is supported as [defined in the spec](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/configuration/data-model.md#environment-variable-substitution) * Currently, there is no support for the SPIs defined in [opentelemetry-sdk-extension-autoconfigure-spi](../autoconfigure-spi). Only built in samplers, processors, exporters, etc can be configured. * You can use file configuration with [autoconfigure](https://github.com/open-telemetry/opentelemetry-java/tree/main/sdk-extensions/autoconfigure#file-configuration) to specify a configuration file via environment variable, e.g. `OTEL_EXPERIMENTAL_CONFIG_FILE=/path/to/config.yaml`. From 4751c07a19af68a7df69027da398dc868fa5494f Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 19 Aug 2024 14:32:48 -0500 Subject: [PATCH 522/901] Update dependency com.google.guava:guava-bom to v33.3.0-jre (#6653) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- dependencyManagement/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index 35343491d23..7caf4c60755 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -9,7 +9,7 @@ rootProject.extra["versions"] = dependencyVersions val DEPENDENCY_BOMS = listOf( "com.fasterxml.jackson:jackson-bom:2.17.2", - "com.google.guava:guava-bom:33.2.1-jre", + "com.google.guava:guava-bom:33.3.0-jre", "com.google.protobuf:protobuf-bom:3.25.4", "com.linecorp.armeria:armeria-bom:1.30.0", "com.squareup.okhttp3:okhttp-bom:4.12.0", From e94c0d133b7ec011d35989f89063a3ff5249f367 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 19 Aug 2024 14:33:13 -0500 Subject: [PATCH 523/901] Update dependency com.google.api.grpc:proto-google-common-protos to v2.43.0 (#6651) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- dependencyManagement/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index 7caf4c60755..d3d9bdd13ce 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -56,7 +56,7 @@ val DEPENDENCIES = listOf( "io.prometheus:simpleclient_httpserver:${prometheusClientVersion}", "javax.annotation:javax.annotation-api:1.3.2", "com.github.stefanbirkner:system-rules:1.19.0", - "com.google.api.grpc:proto-google-common-protos:2.42.0", + "com.google.api.grpc:proto-google-common-protos:2.43.0", "com.google.code.findbugs:jsr305:3.0.2", "com.google.guava:guava-beta-checker:1.0", "com.sun.net.httpserver:http:20070405", From df7bda64e66b681fd8d6a5d832c666055d969073 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 19 Aug 2024 14:33:25 -0500 Subject: [PATCH 524/901] Update dependency com.google.guava:guava to v33.3.0-jre (#6652) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- buildSrc/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts index cd5bb0c12d5..d85c65767de 100644 --- a/buildSrc/build.gradle.kts +++ b/buildSrc/build.gradle.kts @@ -55,7 +55,7 @@ dependencies { // When updating, update above in plugins too implementation("com.diffplug.spotless:spotless-plugin-gradle:6.25.0") // Needed for japicmp but not automatically brought in for some reason. - implementation("com.google.guava:guava:33.2.1-jre") + implementation("com.google.guava:guava:33.3.0-jre") implementation("com.squareup:javapoet:1.13.0") implementation("com.squareup.wire:wire-compiler") implementation("com.squareup.wire:wire-gradle-plugin") From d7626e32d422b5c2d931154107cfb844f35e79f0 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 19 Aug 2024 15:59:23 -0500 Subject: [PATCH 525/901] Update dependency com.uber.nullaway:nullaway to v0.11.2 (#6657) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- dependencyManagement/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index d3d9bdd13ce..9eacbb3bbfa 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -61,7 +61,7 @@ val DEPENDENCIES = listOf( "com.google.guava:guava-beta-checker:1.0", "com.sun.net.httpserver:http:20070405", "com.tngtech.archunit:archunit-junit5:1.3.0", - "com.uber.nullaway:nullaway:0.11.1", + "com.uber.nullaway:nullaway:0.11.2", "edu.berkeley.cs.jqf:jqf-fuzz:1.7", // jqf-fuzz version 1.8+ requires Java 11+ "eu.rekawek.toxiproxy:toxiproxy-java:2.1.7", "io.github.netmikey.logunit:logunit-jul:2.0.0", From 3e8092d086967fa24a0559044651781403033313 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 19 Aug 2024 15:59:42 -0500 Subject: [PATCH 526/901] Update plugin com.gradle.develocity to v3.18 (#6656) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- settings.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/settings.gradle.kts b/settings.gradle.kts index 4c02af73c6f..1ad4058a096 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -1,7 +1,7 @@ pluginManagement { plugins { id("com.gradleup.shadow") version "8.3.0" - id("com.gradle.develocity") version "3.17.6" + id("com.gradle.develocity") version "3.18" id("de.undercouch.download") version "5.6.0" id("org.jsonschema2pojo") version "1.2.1" id("io.github.gradle-nexus.publish-plugin") version "2.0.0" From d4b10a89a05e0bb7c017fc51dc5cfd86b7b773ea Mon Sep 17 00:00:00 2001 From: SylvainJuge <763082+SylvainJuge@users.noreply.github.com> Date: Tue, 20 Aug 2024 19:30:20 +0200 Subject: [PATCH 527/901] add ns and us for config duration units (#6654) Co-authored-by: Jack Berg --- .../spi/internal/DefaultConfigProperties.java | 6 +++++- .../spi/internal/ConfigPropertiesTest.java | 16 ++++++++++++++++ 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/sdk-extensions/autoconfigure-spi/src/main/java/io/opentelemetry/sdk/autoconfigure/spi/internal/DefaultConfigProperties.java b/sdk-extensions/autoconfigure-spi/src/main/java/io/opentelemetry/sdk/autoconfigure/spi/internal/DefaultConfigProperties.java index b8673993fe3..af0e4bae2bf 100644 --- a/sdk-extensions/autoconfigure-spi/src/main/java/io/opentelemetry/sdk/autoconfigure/spi/internal/DefaultConfigProperties.java +++ b/sdk-extensions/autoconfigure-spi/src/main/java/io/opentelemetry/sdk/autoconfigure/spi/internal/DefaultConfigProperties.java @@ -159,7 +159,7 @@ public Duration getDuration(String name) { try { long rawNumber = Long.parseLong(numberString.trim()); TimeUnit unit = getDurationUnit(unitString.trim()); - return Duration.ofMillis(TimeUnit.MILLISECONDS.convert(rawNumber, unit)); + return Duration.ofNanos(TimeUnit.NANOSECONDS.convert(rawNumber, unit)); } catch (NumberFormatException ex) { throw new ConfigurationException( "Invalid duration property " @@ -256,6 +256,10 @@ private static List filterBlanksAndNulls(String[] values) { /** Returns the TimeUnit associated with a unit string. Defaults to milliseconds. */ private static TimeUnit getDurationUnit(String unitString) { switch (unitString) { + case "us": + return TimeUnit.MICROSECONDS; + case "ns": + return TimeUnit.NANOSECONDS; case "": // Fallthrough expected case "ms": return TimeUnit.MILLISECONDS; diff --git a/sdk-extensions/autoconfigure-spi/src/test/java/io/opentelemetry/sdk/autoconfigure/spi/internal/ConfigPropertiesTest.java b/sdk-extensions/autoconfigure-spi/src/test/java/io/opentelemetry/sdk/autoconfigure/spi/internal/ConfigPropertiesTest.java index e0fe198dc9e..78cc6806c08 100644 --- a/sdk-extensions/autoconfigure-spi/src/test/java/io/opentelemetry/sdk/autoconfigure/spi/internal/ConfigPropertiesTest.java +++ b/sdk-extensions/autoconfigure-spi/src/test/java/io/opentelemetry/sdk/autoconfigure/spi/internal/ConfigPropertiesTest.java @@ -185,8 +185,24 @@ void invalidDuration() { .hasMessage("Invalid duration property duration=9mm. Invalid duration string, found: mm"); } + @Test + void durationNegativeParsing() { + assertThat( + DefaultConfigProperties.createFromMap(Collections.singletonMap("duration", "-41")) + .getDuration("duration")) + .isEqualTo(Duration.ofMillis(-41)); + } + @Test void durationUnitParsing() { + assertThat( + DefaultConfigProperties.createFromMap(Collections.singletonMap("duration", "3ns")) + .getDuration("duration")) + .isEqualTo(Duration.ofNanos(3)); + assertThat( + DefaultConfigProperties.createFromMap(Collections.singletonMap("duration", "2us")) + .getDuration("duration")) + .isEqualTo(Duration.ofNanos(2000)); assertThat( DefaultConfigProperties.createFromMap(Collections.singletonMap("duration", "1")) .getDuration("duration")) From dc4cc270091a7dae3b0a49a47761da51bb75f29f Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 20 Aug 2024 16:16:11 -0500 Subject: [PATCH 528/901] Update dependency io.opentelemetry.semconv:opentelemetry-semconv-incubating to v1.27.0-alpha (#6660) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- dependencyManagement/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index 9eacbb3bbfa..206bc3af84e 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -67,7 +67,7 @@ val DEPENDENCIES = listOf( "io.github.netmikey.logunit:logunit-jul:2.0.0", "io.jaegertracing:jaeger-client:1.8.1", "io.opentelemetry.contrib:opentelemetry-aws-xray-propagator:1.29.0-alpha", - "io.opentelemetry.semconv:opentelemetry-semconv-incubating:1.26.0-alpha", + "io.opentelemetry.semconv:opentelemetry-semconv-incubating:1.27.0-alpha", "io.opentelemetry.proto:opentelemetry-proto:1.3.2-alpha", "io.opentracing:opentracing-api:0.33.0", "io.opentracing:opentracing-noop:0.33.0", From 97b3fa42f10d43a4f27ecdf2d809bca95fed4de3 Mon Sep 17 00:00:00 2001 From: jack-berg <34418638+jack-berg@users.noreply.github.com> Date: Tue, 20 Aug 2024 22:05:51 -0500 Subject: [PATCH 529/901] Remove outdated ExtendedSpanBuilder javadoc example (#6659) --- .../api/incubator/trace/ExtendedSpanBuilder.java | 7 ------- 1 file changed, 7 deletions(-) diff --git a/api/incubator/src/main/java/io/opentelemetry/api/incubator/trace/ExtendedSpanBuilder.java b/api/incubator/src/main/java/io/opentelemetry/api/incubator/trace/ExtendedSpanBuilder.java index eec32904a4e..8474095f734 100644 --- a/api/incubator/src/main/java/io/opentelemetry/api/incubator/trace/ExtendedSpanBuilder.java +++ b/api/incubator/src/main/java/io/opentelemetry/api/incubator/trace/ExtendedSpanBuilder.java @@ -29,13 +29,6 @@ public interface ExtendedSpanBuilder extends SpanBuilder { *

      The span context will be extracted from the carrier, which you usually get from * HTTP headers of the metadata of a message you're processing. * - *

      A typical usage would be: - * ExtendedTracer.create(tracer) - * .setSpanKind(SpanKind.SERVER) - * .setParentFrom(propagators, carrier) - * .run("my-span", () -> { ... }); - * - * * @param propagators provide the propagators from {@link OpenTelemetry#getPropagators()} * @param carrier the string map where to extract the span context from */ From 97185c6fa09c6133c758bd62f931274e67d63a81 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 23 Aug 2024 18:39:22 -0700 Subject: [PATCH 530/901] Update dependency nl.jqno.equalsverifier:equalsverifier to v3.16.2 (#6667) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- dependencyManagement/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index 206bc3af84e..3144535bf3e 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -73,7 +73,7 @@ val DEPENDENCIES = listOf( "io.opentracing:opentracing-noop:0.33.0", "io.prometheus:prometheus-metrics-exporter-httpserver:1.3.1", "junit:junit:4.13.2", - "nl.jqno.equalsverifier:equalsverifier:3.16.1", + "nl.jqno.equalsverifier:equalsverifier:3.16.2", "org.awaitility:awaitility:4.2.2", "org.bouncycastle:bcpkix-jdk15on:1.70", "org.codehaus.mojo:animal-sniffer-annotations:1.24", From c90175f1ae7d15fef6bac8eb6c95492c981daa61 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 23 Aug 2024 18:44:24 -0700 Subject: [PATCH 531/901] Update dependency org.jetbrains.kotlin:kotlin-gradle-plugin to v2.0.20 (#6663) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- buildSrc/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts index d85c65767de..5c2c974b841 100644 --- a/buildSrc/build.gradle.kts +++ b/buildSrc/build.gradle.kts @@ -65,7 +65,7 @@ dependencies { implementation("me.champeau.jmh:jmh-gradle-plugin:0.7.2") implementation("net.ltgt.gradle:gradle-errorprone-plugin:4.0.1") implementation("net.ltgt.gradle:gradle-nullaway-plugin:2.0.0") - implementation("org.jetbrains.kotlin:kotlin-gradle-plugin:2.0.10") + implementation("org.jetbrains.kotlin:kotlin-gradle-plugin:2.0.20") implementation("org.owasp:dependency-check-gradle:10.0.3") implementation("ru.vyarus:gradle-animalsniffer-plugin:1.7.1") } From 7522bfe141524d52649b5c344c643104b57af608 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sun, 25 Aug 2024 12:57:30 -0700 Subject: [PATCH 532/901] Update dependency checkstyle to v10.18.0 (#6670) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Co-authored-by: John Watson --- .../java/io/opentelemetry/api/baggage/propagation/Parser.java | 4 ++-- buildSrc/src/main/kotlin/otel.java-conventions.gradle.kts | 2 +- .../exporter/zipkin/LocalInetAddressSupplier.java | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/api/all/src/main/java/io/opentelemetry/api/baggage/propagation/Parser.java b/api/all/src/main/java/io/opentelemetry/api/baggage/propagation/Parser.java index d6c26fcef27..c9d619c1bf3 100644 --- a/api/all/src/main/java/io/opentelemetry/api/baggage/propagation/Parser.java +++ b/api/all/src/main/java/io/opentelemetry/api/baggage/propagation/Parser.java @@ -12,11 +12,11 @@ /** * Implements single-pass Baggage parsing in accordance with https://w3c.github.io/baggage/ Key / - * value are restricted in accordance with https://www.ietf.org/rfc/rfc2616.txt + * value are restricted in accordance with https://www.ietf.org/rfc/rfc2616.txt. * *

      Note: following aspects are not specified in RFC: - some invalid elements (key or value) - * parser will include valid ones, disregard invalid - empty "value" is regarded as invalid - meta - - * anything besides element terminator (comma) + * anything besides element terminator (comma). */ class Parser { diff --git a/buildSrc/src/main/kotlin/otel.java-conventions.gradle.kts b/buildSrc/src/main/kotlin/otel.java-conventions.gradle.kts index f651f5c3021..929cbee6046 100644 --- a/buildSrc/src/main/kotlin/otel.java-conventions.gradle.kts +++ b/buildSrc/src/main/kotlin/otel.java-conventions.gradle.kts @@ -42,7 +42,7 @@ java { checkstyle { configDirectory.set(file("$rootDir/buildscripts/")) - toolVersion = "10.17.0" + toolVersion = "10.18.0" isIgnoreFailures = false configProperties["rootDir"] = rootDir } diff --git a/exporters/zipkin/src/main/java/io/opentelemetry/exporter/zipkin/LocalInetAddressSupplier.java b/exporters/zipkin/src/main/java/io/opentelemetry/exporter/zipkin/LocalInetAddressSupplier.java index 1ddb324edb6..a5376eb88a9 100644 --- a/exporters/zipkin/src/main/java/io/opentelemetry/exporter/zipkin/LocalInetAddressSupplier.java +++ b/exporters/zipkin/src/main/java/io/opentelemetry/exporter/zipkin/LocalInetAddressSupplier.java @@ -30,7 +30,7 @@ public InetAddress get() { return inetAddress; } - /** Logic borrowed from brave.internal.Platform.produceLocalEndpoint */ + /** Logic borrowed from brave.internal.Platform.produceLocalEndpoint. */ @Nullable private static InetAddress findLocalIp() { try { From 71124d2c5b0c3ae36500c82b2853f146b63f82cf Mon Sep 17 00:00:00 2001 From: Jarrod Robins Date: Wed, 28 Aug 2024 05:49:11 +1000 Subject: [PATCH 533/901] Return status code exceptions via CompletableResultCode in GrpcExporter and HttpExporter (#6645) --- .../internal/FailedExportException.java | 126 ++++++++++++++++++ .../exporter/internal/grpc/GrpcExporter.java | 70 ++++++---- .../exporter/internal/http/HttpExporter.java | 6 +- .../AbstractGrpcTelemetryExporterTest.java | 61 ++++++++- .../AbstractHttpTelemetryExporterTest.java | 58 ++++++-- .../okhttp/internal/OkHttpGrpcSender.java | 4 +- .../okhttp/internal/OkHttpHttpSender.java | 7 +- 7 files changed, 284 insertions(+), 48 deletions(-) create mode 100644 exporters/common/src/main/java/io/opentelemetry/exporter/internal/FailedExportException.java diff --git a/exporters/common/src/main/java/io/opentelemetry/exporter/internal/FailedExportException.java b/exporters/common/src/main/java/io/opentelemetry/exporter/internal/FailedExportException.java new file mode 100644 index 00000000000..74f66dbfa1f --- /dev/null +++ b/exporters/common/src/main/java/io/opentelemetry/exporter/internal/FailedExportException.java @@ -0,0 +1,126 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.exporter.internal; + +import io.opentelemetry.exporter.internal.grpc.GrpcResponse; +import io.opentelemetry.exporter.internal.http.HttpSender; +import javax.annotation.Nullable; + +/** + * Represents the failure of a gRPC or HTTP exporter. + * + *

      This class is internal and is hence not for public use. Its APIs are unstable and can change + * at any time. + */ +public abstract class FailedExportException extends Exception { + + private static final long serialVersionUID = 6988924855140178789L; + + private FailedExportException(@Nullable Throwable cause) { + super(cause); + } + + /** Indicates an HTTP export failed after receiving a response from the server. */ + public static HttpExportException httpFailedWithResponse(HttpSender.Response response) { + return new HttpExportException(response, null); + } + + /** Indicates an HTTP export failed exceptionally without receiving a response from the server. */ + public static HttpExportException httpFailedExceptionally(Throwable cause) { + return new HttpExportException(null, cause); + } + + /** Indicates a gRPC export failed after receiving a response from the server. */ + public static GrpcExportException grpcFailedWithResponse(GrpcResponse response) { + return new GrpcExportException(response, null); + } + + /** Indicates a gRPC export failed exceptionally without receiving a response from the server. */ + public static GrpcExportException grpcFailedExceptionally(Throwable cause) { + return new GrpcExportException(null, cause); + } + + /** Returns true if the export failed with a response from the server. */ + public abstract boolean failedWithResponse(); + + /** Represents the failure of an HTTP exporter. */ + public static final class HttpExportException extends FailedExportException { + + private static final long serialVersionUID = -6787390183017184775L; + + @Nullable private final HttpSender.Response response; + @Nullable private final Throwable cause; + + private HttpExportException(@Nullable HttpSender.Response response, @Nullable Throwable cause) { + super(cause); + this.response = response; + this.cause = cause; + } + + @Override + public boolean failedWithResponse() { + return response != null; + } + + /** + * Returns the response if the export failed with a response from the server, or null if the + * export failed exceptionally with no response. + */ + @Nullable + public HttpSender.Response getResponse() { + return response; + } + + /** + * Returns the exceptional cause of failure, or null if the export failed with a response from + * the server. + */ + @Nullable + @Override + public Throwable getCause() { + return cause; + } + } + + /** Represents the failure of a gRPC exporter. */ + public static final class GrpcExportException extends FailedExportException { + + private static final long serialVersionUID = -9157548250286695364L; + + @Nullable private final GrpcResponse response; + @Nullable private final Throwable cause; + + private GrpcExportException(@Nullable GrpcResponse response, @Nullable Throwable cause) { + super(cause); + this.response = response; + this.cause = cause; + } + + @Override + public boolean failedWithResponse() { + return response != null; + } + + /** + * Returns the response if the export failed with a response from the server, or null if the + * export failed exceptionally with no response. + */ + @Nullable + public GrpcResponse getResponse() { + return response; + } + + /** + * Returns the exceptional cause of failure, or null if the export failed with a response from + * the server. + */ + @Nullable + @Override + public Throwable getCause() { + return cause; + } + } +} diff --git a/exporters/common/src/main/java/io/opentelemetry/exporter/internal/grpc/GrpcExporter.java b/exporters/common/src/main/java/io/opentelemetry/exporter/internal/grpc/GrpcExporter.java index 6a74ba5df8a..e8101049b9f 100644 --- a/exporters/common/src/main/java/io/opentelemetry/exporter/internal/grpc/GrpcExporter.java +++ b/exporters/common/src/main/java/io/opentelemetry/exporter/internal/grpc/GrpcExporter.java @@ -7,9 +7,11 @@ import static io.opentelemetry.exporter.internal.grpc.GrpcExporterUtil.GRPC_STATUS_UNAVAILABLE; import static io.opentelemetry.exporter.internal.grpc.GrpcExporterUtil.GRPC_STATUS_UNIMPLEMENTED; +import static io.opentelemetry.exporter.internal.grpc.GrpcExporterUtil.GRPC_STATUS_UNKNOWN; import io.opentelemetry.api.metrics.MeterProvider; import io.opentelemetry.exporter.internal.ExporterMetrics; +import io.opentelemetry.exporter.internal.FailedExportException; import io.opentelemetry.exporter.internal.marshal.Marshaler; import io.opentelemetry.sdk.common.CompletableResultCode; import io.opentelemetry.sdk.internal.ThrottlingLogger; @@ -66,39 +68,17 @@ public CompletableResultCode export(T exportRequest, int numItems) { }, (response, throwable) -> { exporterMetrics.addFailed(numItems); + + logFailureMessage(response, throwable); + switch (response.grpcStatusValue()) { - case GRPC_STATUS_UNIMPLEMENTED: - if (loggedUnimplemented.compareAndSet(false, true)) { - GrpcExporterUtil.logUnimplemented( - internalLogger, type, response.grpcStatusDescription()); - } - break; - case GRPC_STATUS_UNAVAILABLE: - logger.log( - Level.SEVERE, - "Failed to export " - + type - + "s. Server is UNAVAILABLE. " - + "Make sure your collector is running and reachable from this network. " - + "Full error message:" - + response.grpcStatusDescription()); + case GRPC_STATUS_UNKNOWN: + result.failExceptionally(FailedExportException.grpcFailedExceptionally(throwable)); break; default: - logger.log( - Level.WARNING, - "Failed to export " - + type - + "s. Server responded with gRPC status code " - + response.grpcStatusValue() - + ". Error message: " - + response.grpcStatusDescription()); + result.failExceptionally(FailedExportException.grpcFailedWithResponse(response)); break; } - if (logger.isLoggable(Level.FINEST)) { - logger.log( - Level.FINEST, "Failed to export " + type + "s. Details follow: " + throwable); - } - result.fail(); }); return result; @@ -111,4 +91,38 @@ public CompletableResultCode shutdown() { } return grpcSender.shutdown(); } + + private void logFailureMessage(GrpcResponse response, Throwable throwable) { + switch (response.grpcStatusValue()) { + case GRPC_STATUS_UNIMPLEMENTED: + if (loggedUnimplemented.compareAndSet(false, true)) { + GrpcExporterUtil.logUnimplemented(internalLogger, type, response.grpcStatusDescription()); + } + break; + case GRPC_STATUS_UNAVAILABLE: + logger.log( + Level.SEVERE, + "Failed to export " + + type + + "s. Server is UNAVAILABLE. " + + "Make sure your collector is running and reachable from this network. " + + "Full error message:" + + response.grpcStatusDescription()); + break; + default: + logger.log( + Level.WARNING, + "Failed to export " + + type + + "s. Server responded with gRPC status code " + + response.grpcStatusValue() + + ". Error message: " + + response.grpcStatusDescription()); + break; + } + + if (logger.isLoggable(Level.FINEST)) { + logger.log(Level.FINEST, "Failed to export " + type + "s. Details follow: " + throwable); + } + } } diff --git a/exporters/common/src/main/java/io/opentelemetry/exporter/internal/http/HttpExporter.java b/exporters/common/src/main/java/io/opentelemetry/exporter/internal/http/HttpExporter.java index befb579d964..d0361eaecca 100644 --- a/exporters/common/src/main/java/io/opentelemetry/exporter/internal/http/HttpExporter.java +++ b/exporters/common/src/main/java/io/opentelemetry/exporter/internal/http/HttpExporter.java @@ -7,6 +7,7 @@ import io.opentelemetry.api.metrics.MeterProvider; import io.opentelemetry.exporter.internal.ExporterMetrics; +import io.opentelemetry.exporter.internal.FailedExportException; import io.opentelemetry.exporter.internal.grpc.GrpcExporterUtil; import io.opentelemetry.exporter.internal.marshal.Marshaler; import io.opentelemetry.sdk.common.CompletableResultCode; @@ -90,7 +91,8 @@ public CompletableResultCode export(T exportRequest, int numItems) { + statusCode + ". Error message: " + status); - result.fail(); + + result.failExceptionally(FailedExportException.httpFailedWithResponse(httpResponse)); }, e -> { exporterMetrics.addFailed(numItems); @@ -101,7 +103,7 @@ public CompletableResultCode export(T exportRequest, int numItems) { + "s. The request could not be executed. Full error message: " + e.getMessage(), e); - result.fail(); + result.failExceptionally(FailedExportException.httpFailedExceptionally(e)); }); return result; diff --git a/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/AbstractGrpcTelemetryExporterTest.java b/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/AbstractGrpcTelemetryExporterTest.java index a62911a54b0..5950d8c00aa 100644 --- a/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/AbstractGrpcTelemetryExporterTest.java +++ b/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/AbstractGrpcTelemetryExporterTest.java @@ -25,9 +25,11 @@ import com.linecorp.armeria.testing.junit5.server.ServerExtension; import io.github.netmikey.logunit.api.LogCapturer; import io.grpc.ManagedChannel; +import io.opentelemetry.exporter.internal.FailedExportException; import io.opentelemetry.exporter.internal.TlsUtil; import io.opentelemetry.exporter.internal.compression.GzipCompressor; import io.opentelemetry.exporter.internal.grpc.GrpcExporter; +import io.opentelemetry.exporter.internal.grpc.GrpcResponse; import io.opentelemetry.exporter.internal.grpc.MarshalerServiceStub; import io.opentelemetry.exporter.internal.marshal.Marshaler; import io.opentelemetry.exporter.otlp.testing.internal.compressor.Base64Compressor; @@ -66,6 +68,7 @@ import javax.net.ssl.TrustManager; import javax.net.ssl.X509KeyManager; import javax.net.ssl.X509TrustManager; +import org.assertj.core.api.Assertions; import org.assertj.core.api.InstanceOfAssertFactories; import org.assertj.core.api.iterable.ThrowingExtractor; import org.junit.jupiter.api.AfterAll; @@ -486,6 +489,7 @@ void connectTimeout() { CompletableResultCode result = exporter.export(Collections.singletonList(generateFakeTelemetry())); assertThat(result.join(10, TimeUnit.SECONDS).isSuccess()).isFalse(); + // Assert that the export request fails well before the default connect timeout of 10s assertThat(System.currentTimeMillis() - startTimeMillis) .isLessThan(TimeUnit.SECONDS.toMillis(1)); @@ -540,17 +544,33 @@ void doubleShutdown() { @Test @SuppressLogger(GrpcExporter.class) void error() { - addGrpcError(13, null); + int statusCode = 13; + addGrpcError(statusCode, null); TelemetryExporter exporter = nonRetryingExporter(); try { - assertThat( - exporter - .export(Collections.singletonList(generateFakeTelemetry())) - .join(10, TimeUnit.SECONDS) - .isSuccess()) - .isFalse(); + CompletableResultCode result = + exporter + .export(Collections.singletonList(generateFakeTelemetry())) + .join(10, TimeUnit.SECONDS); + + assertThat(result.isSuccess()).isFalse(); + + assertThat(result.getFailureThrowable()) + .asInstanceOf( + InstanceOfAssertFactories.throwable(FailedExportException.GrpcExportException.class)) + .returns(true, Assertions.from(FailedExportException::failedWithResponse)) + .satisfies( + ex -> { + assertThat(ex.getResponse()) + .isNotNull() + .extracting(GrpcResponse::grpcStatusValue) + .isEqualTo(statusCode); + + assertThat(ex.getCause()).isNull(); + }); + LoggingEvent log = logs.assertContains( "Failed to export " @@ -562,6 +582,33 @@ void error() { } } + @Test + @SuppressLogger(GrpcExporter.class) + void errorWithUnknownError() { + addGrpcError(2, null); + + TelemetryExporter exporter = nonRetryingExporter(); + + try { + assertThat( + exporter + .export(Collections.singletonList(generateFakeTelemetry())) + .join(10, TimeUnit.SECONDS) + .getFailureThrowable()) + .asInstanceOf( + InstanceOfAssertFactories.throwable(FailedExportException.GrpcExportException.class)) + .returns(false, Assertions.from(FailedExportException::failedWithResponse)) + .satisfies( + ex -> { + assertThat(ex.getResponse()).isNull(); + + assertThat(ex.getCause()).isNotNull(); + }); + } finally { + exporter.shutdown(); + } + } + @Test @SuppressLogger(GrpcExporter.class) void errorWithMessage() { diff --git a/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/AbstractHttpTelemetryExporterTest.java b/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/AbstractHttpTelemetryExporterTest.java index befa39af5f3..7f6bfff04b3 100644 --- a/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/AbstractHttpTelemetryExporterTest.java +++ b/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/AbstractHttpTelemetryExporterTest.java @@ -26,9 +26,11 @@ import com.linecorp.armeria.testing.junit5.server.SelfSignedCertificateExtension; import com.linecorp.armeria.testing.junit5.server.ServerExtension; import io.github.netmikey.logunit.api.LogCapturer; +import io.opentelemetry.exporter.internal.FailedExportException; import io.opentelemetry.exporter.internal.TlsUtil; import io.opentelemetry.exporter.internal.compression.GzipCompressor; import io.opentelemetry.exporter.internal.http.HttpExporter; +import io.opentelemetry.exporter.internal.http.HttpSender; import io.opentelemetry.exporter.internal.marshal.Marshaler; import io.opentelemetry.exporter.otlp.testing.internal.compressor.Base64Compressor; import io.opentelemetry.internal.testing.slf4j.SuppressLogger; @@ -72,6 +74,8 @@ import okio.GzipSource; import okio.Okio; import okio.Source; +import org.assertj.core.api.Assertions; +import org.assertj.core.api.InstanceOfAssertFactories; import org.assertj.core.api.iterable.ThrowingExtractor; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.AfterEach; @@ -534,8 +538,22 @@ void connectTimeout() { try { long startTimeMillis = System.currentTimeMillis(); CompletableResultCode result = - exporter.export(Collections.singletonList(generateFakeTelemetry())); - assertThat(result.join(10, TimeUnit.SECONDS).isSuccess()).isFalse(); + exporter + .export(Collections.singletonList(generateFakeTelemetry())) + .join(10, TimeUnit.SECONDS); + + assertThat(result.isSuccess()).isFalse(); + + assertThat(result.getFailureThrowable()) + .asInstanceOf( + InstanceOfAssertFactories.throwable(FailedExportException.HttpExportException.class)) + .returns(false, Assertions.from(FailedExportException::failedWithResponse)) + .satisfies( + ex -> { + assertThat(ex.getResponse()).isNull(); + assertThat(ex.getCause()).isNotNull(); + }); + // Assert that the export request fails well before the default connect timeout of 10s assertThat(System.currentTimeMillis() - startTimeMillis) .isLessThan(TimeUnit.SECONDS.toMillis(1)); @@ -590,13 +608,35 @@ void doubleShutdown() { @Test @SuppressLogger(HttpExporter.class) void error() { - addHttpError(500); - assertThat( - exporter - .export(Collections.singletonList(generateFakeTelemetry())) - .join(10, TimeUnit.SECONDS) - .isSuccess()) - .isFalse(); + int statusCode = 500; + addHttpError(statusCode); + CompletableResultCode result = + exporter + .export(Collections.singletonList(generateFakeTelemetry())) + .join(10, TimeUnit.SECONDS); + + assertThat(result.isSuccess()).isFalse(); + + assertThat(result.getFailureThrowable()) + .asInstanceOf( + InstanceOfAssertFactories.throwable(FailedExportException.HttpExportException.class)) + .returns(true, Assertions.from(FailedExportException::failedWithResponse)) + .satisfies( + ex -> { + assertThat(ex.getResponse()) + .isNotNull() + .satisfies( + response -> { + assertThat(response) + .extracting(HttpSender.Response::statusCode) + .isEqualTo(statusCode); + + assertThatCode(response::responseBody).doesNotThrowAnyException(); + }); + + assertThat(ex.getCause()).isNull(); + }); + LoggingEvent log = logs.assertContains( "Failed to export " diff --git a/exporters/sender/okhttp/src/main/java/io/opentelemetry/exporter/sender/okhttp/internal/OkHttpGrpcSender.java b/exporters/sender/okhttp/src/main/java/io/opentelemetry/exporter/sender/okhttp/internal/OkHttpGrpcSender.java index 7fb04c4e513..a622d95ac6c 100644 --- a/exporters/sender/okhttp/src/main/java/io/opentelemetry/exporter/sender/okhttp/internal/OkHttpGrpcSender.java +++ b/exporters/sender/okhttp/src/main/java/io/opentelemetry/exporter/sender/okhttp/internal/OkHttpGrpcSender.java @@ -136,7 +136,9 @@ public void onFailure(Call call, IOException e) { if (description == null) { description = ""; } - onError.accept(GrpcResponse.create(2 /* UNKNOWN */, description), e); + onError.accept( + GrpcResponse.create(GrpcExporterUtil.GRPC_STATUS_UNKNOWN, description), + e); } @Override diff --git a/exporters/sender/okhttp/src/main/java/io/opentelemetry/exporter/sender/okhttp/internal/OkHttpHttpSender.java b/exporters/sender/okhttp/src/main/java/io/opentelemetry/exporter/sender/okhttp/internal/OkHttpHttpSender.java index 1a0263a13de..20af7127451 100644 --- a/exporters/sender/okhttp/src/main/java/io/opentelemetry/exporter/sender/okhttp/internal/OkHttpHttpSender.java +++ b/exporters/sender/okhttp/src/main/java/io/opentelemetry/exporter/sender/okhttp/internal/OkHttpHttpSender.java @@ -143,6 +143,8 @@ public void onResponse(Call call, okhttp3.Response response) { try (ResponseBody body = response.body()) { onResponse.accept( new Response() { + @Nullable private byte[] bodyBytes; + @Override public int statusCode() { return response.code(); @@ -155,7 +157,10 @@ public String statusMessage() { @Override public byte[] responseBody() throws IOException { - return body.bytes(); + if (bodyBytes == null) { + bodyBytes = body.bytes(); + } + return bodyBytes; } }); } From 902c46e2a74239bc13e140f8d70a0106c8f10ee1 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 27 Aug 2024 20:25:20 -0700 Subject: [PATCH 534/901] Update gradle/actions action to v4.0.1 (#6673) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/gradle-wrapper-validation.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/gradle-wrapper-validation.yml b/.github/workflows/gradle-wrapper-validation.yml index e659ca0fa97..c55680e34b8 100644 --- a/.github/workflows/gradle-wrapper-validation.yml +++ b/.github/workflows/gradle-wrapper-validation.yml @@ -13,4 +13,4 @@ jobs: steps: - uses: actions/checkout@v4 - - uses: gradle/actions/wrapper-validation@v4.0.0 + - uses: gradle/actions/wrapper-validation@v4.0.1 From 05fe136cb3d90de26bed5f865bb7d519680e5be2 Mon Sep 17 00:00:00 2001 From: jack-berg <34418638+jack-berg@users.noreply.github.com> Date: Wed, 28 Aug 2024 14:42:37 -0500 Subject: [PATCH 535/901] Add file configuration ComponentProvider support for resources (#6625) --- .../sdk/autoconfigure/internal/SpiHelper.java | 4 +- .../incubator/fileconfig/ResourceFactory.java | 95 +++++++++++++++++-- ...OpenTelemetryConfigurationFactoryTest.java | 4 + .../fileconfig/ResourceFactoryTest.java | 17 +++- .../component/ResourceComponentProvider.java | 27 ++++++ ...ResourceOrderedFirstComponentProvider.java | 33 +++++++ ...esourceOrderedSecondComponentProvider.java | 34 +++++++ ...toconfigure.spi.internal.ComponentProvider | 3 + 8 files changed, 203 insertions(+), 14 deletions(-) create mode 100644 sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/component/ResourceComponentProvider.java create mode 100644 sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/component/ResourceOrderedFirstComponentProvider.java create mode 100644 sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/component/ResourceOrderedSecondComponentProvider.java diff --git a/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/internal/SpiHelper.java b/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/internal/SpiHelper.java index bd3bfc13f04..c8c40e63e07 100644 --- a/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/internal/SpiHelper.java +++ b/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/internal/SpiHelper.java @@ -81,9 +81,9 @@ public NamedSpiManager loadConfigurable( } /** - * Find a registered {@link ComponentProvider} which {@link ComponentProvider#getType()} matching + * Find a registered {@link ComponentProvider} with {@link ComponentProvider#getType()} matching * {@code type}, {@link ComponentProvider#getName()} matching {@code name}, and call {@link - * ComponentProvider#create(StructuredConfigProperties)} with the given {@code model}. + * ComponentProvider#create(StructuredConfigProperties)} with the given {@code config}. * * @throws ConfigurationException if no matching providers are found, or if multiple are found * (i.e. conflict), or if {@link ComponentProvider#create(StructuredConfigProperties)} throws diff --git a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/ResourceFactory.java b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/ResourceFactory.java index 04a0de2bcac..eaaf1ae98b3 100644 --- a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/ResourceFactory.java +++ b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/ResourceFactory.java @@ -6,14 +6,25 @@ package io.opentelemetry.sdk.extension.incubator.fileconfig; import io.opentelemetry.sdk.autoconfigure.internal.SpiHelper; +import io.opentelemetry.sdk.autoconfigure.spi.ConfigurationException; +import io.opentelemetry.sdk.autoconfigure.spi.Ordered; +import io.opentelemetry.sdk.autoconfigure.spi.internal.ComponentProvider; +import io.opentelemetry.sdk.autoconfigure.spi.internal.StructuredConfigProperties; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.Attributes; -import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.Resource; -import io.opentelemetry.sdk.resources.ResourceBuilder; +import io.opentelemetry.sdk.resources.Resource; import java.io.Closeable; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; import java.util.List; +import java.util.stream.Collectors; -final class ResourceFactory implements Factory { +final class ResourceFactory + implements Factory< + io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.Resource, Resource> { + private static final StructuredConfigProperties EMPTY_CONFIG = + FileConfiguration.toConfigProperties(Collections.emptyMap()); private static final ResourceFactory INSTANCE = new ResourceFactory(); private ResourceFactory() {} @@ -23,16 +34,82 @@ static ResourceFactory getInstance() { } @Override - public io.opentelemetry.sdk.resources.Resource create( - Resource model, SpiHelper spiHelper, List closeables) { - ResourceBuilder builder = io.opentelemetry.sdk.resources.Resource.getDefault().toBuilder(); + public Resource create( + io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.Resource model, + SpiHelper spiHelper, + List closeables) { + Resource result = Resource.getDefault(); + + List resourceDetectorResources = loadFromResourceDetectors(spiHelper); + for (Resource resourceProviderResource : resourceDetectorResources) { + result = result.merge(resourceProviderResource); + } Attributes attributesModel = model.getAttributes(); if (attributesModel != null) { - builder.putAll( - AttributesFactory.getInstance().create(attributesModel, spiHelper, closeables)); + result = + result.toBuilder() + .putAll( + AttributesFactory.getInstance().create(attributesModel, spiHelper, closeables)) + .build(); } - return builder.build(); + return result; + } + + /** + * Load resources from resource detectors, in order of lowest priority to highest priority. + * + *

      In file configuration, a resource detector is a {@link ComponentProvider} with {@link + * ComponentProvider#getType()} set to {@link Resource}. Unlike other {@link ComponentProvider}s, + * the resource detector version does not use {@link ComponentProvider#getName()} (except for + * debug messages), and {@link ComponentProvider#create(StructuredConfigProperties)} is called + * with an empty instance. Additionally, the {@link Ordered#order()} value is respected for + * resource detectors which implement {@link Ordered}. + */ + @SuppressWarnings("rawtypes") + private static List loadFromResourceDetectors(SpiHelper spiHelper) { + List componentProviders = spiHelper.load(ComponentProvider.class); + List resourceAndOrders = new ArrayList<>(); + for (ComponentProvider componentProvider : componentProviders) { + if (componentProvider.getType() != Resource.class) { + continue; + } + Resource resource; + try { + resource = (Resource) componentProvider.create(EMPTY_CONFIG); + } catch (Throwable throwable) { + throw new ConfigurationException( + "Error configuring " + + Resource.class.getName() + + " with name \"" + + componentProvider.getName() + + "\"", + throwable); + } + int order = + (componentProvider instanceof Ordered) ? ((Ordered) componentProvider).order() : 0; + resourceAndOrders.add(new ResourceAndOrder(resource, order)); + } + resourceAndOrders.sort(Comparator.comparing(ResourceAndOrder::order)); + return resourceAndOrders.stream().map(ResourceAndOrder::resource).collect(Collectors.toList()); + } + + private static final class ResourceAndOrder { + private final Resource resource; + private final int order; + + private ResourceAndOrder(Resource resource, int order) { + this.resource = resource; + this.order = order; + } + + private Resource resource() { + return resource; + } + + private int order() { + return order; + } } } diff --git a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/OpenTelemetryConfigurationFactoryTest.java b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/OpenTelemetryConfigurationFactoryTest.java index da3cc7cd013..7de50047ece 100644 --- a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/OpenTelemetryConfigurationFactoryTest.java +++ b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/OpenTelemetryConfigurationFactoryTest.java @@ -140,6 +140,10 @@ void create_Configured() { io.opentelemetry.sdk.resources.Resource.getDefault().toBuilder() .put("service.name", "my-service") .put("key", "val") + // resource attributes from resource ComponentProviders + .put("color", "red") + .put("shape", "square") + .put("order", "second") .build(); OpenTelemetrySdk expectedSdk = OpenTelemetrySdk.builder() diff --git a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/ResourceFactoryTest.java b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/ResourceFactoryTest.java index 37e494ee28a..584f908431c 100644 --- a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/ResourceFactoryTest.java +++ b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/ResourceFactoryTest.java @@ -6,7 +6,7 @@ package io.opentelemetry.sdk.extension.incubator.fileconfig; import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.assertThat; -import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.spy; import io.opentelemetry.sdk.autoconfigure.internal.SpiHelper; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.Attributes; @@ -16,8 +16,11 @@ class ResourceFactoryTest { + private SpiHelper spiHelper = SpiHelper.create(MetricExporterFactoryTest.class.getClassLoader()); + @Test void create() { + spiHelper = spy(spiHelper); assertThat( ResourceFactory.getInstance() .create( @@ -26,13 +29,21 @@ void create() { .withAttributes( new Attributes() .withServiceName("my-service") - .withAdditionalProperty("key", "val")), - mock(SpiHelper.class), + .withAdditionalProperty("key", "val") + // Should override shape attribute from ResourceComponentProvider + .withAdditionalProperty("shape", "circle")), + spiHelper, Collections.emptyList())) .isEqualTo( Resource.getDefault().toBuilder() .put("service.name", "my-service") .put("key", "val") + .put("shape", "circle") + // From ResourceComponentProvider + .put("color", "red") + // From ResourceOrderedSecondComponentProvider, which takes priority over + // ResourceOrderedFirstComponentProvider + .put("order", "second") .build()); } } diff --git a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/component/ResourceComponentProvider.java b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/component/ResourceComponentProvider.java new file mode 100644 index 00000000000..13b0e86c05a --- /dev/null +++ b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/component/ResourceComponentProvider.java @@ -0,0 +1,27 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.sdk.extension.incubator.fileconfig.component; + +import io.opentelemetry.sdk.autoconfigure.spi.internal.ComponentProvider; +import io.opentelemetry.sdk.autoconfigure.spi.internal.StructuredConfigProperties; +import io.opentelemetry.sdk.resources.Resource; + +public class ResourceComponentProvider implements ComponentProvider { + @Override + public Class getType() { + return Resource.class; + } + + @Override + public String getName() { + return "unused"; + } + + @Override + public Resource create(StructuredConfigProperties config) { + return Resource.builder().put("shape", "square").put("color", "red").build(); + } +} diff --git a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/component/ResourceOrderedFirstComponentProvider.java b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/component/ResourceOrderedFirstComponentProvider.java new file mode 100644 index 00000000000..f2f41e5b955 --- /dev/null +++ b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/component/ResourceOrderedFirstComponentProvider.java @@ -0,0 +1,33 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.sdk.extension.incubator.fileconfig.component; + +import io.opentelemetry.sdk.autoconfigure.spi.Ordered; +import io.opentelemetry.sdk.autoconfigure.spi.internal.ComponentProvider; +import io.opentelemetry.sdk.autoconfigure.spi.internal.StructuredConfigProperties; +import io.opentelemetry.sdk.resources.Resource; + +public class ResourceOrderedFirstComponentProvider implements ComponentProvider, Ordered { + @Override + public Class getType() { + return Resource.class; + } + + @Override + public String getName() { + return "unused"; + } + + @Override + public Resource create(StructuredConfigProperties config) { + return Resource.builder().put("order", "first").build(); + } + + @Override + public int order() { + return 1; + } +} diff --git a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/component/ResourceOrderedSecondComponentProvider.java b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/component/ResourceOrderedSecondComponentProvider.java new file mode 100644 index 00000000000..00017b2b7d4 --- /dev/null +++ b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/component/ResourceOrderedSecondComponentProvider.java @@ -0,0 +1,34 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.sdk.extension.incubator.fileconfig.component; + +import io.opentelemetry.sdk.autoconfigure.spi.Ordered; +import io.opentelemetry.sdk.autoconfigure.spi.internal.ComponentProvider; +import io.opentelemetry.sdk.autoconfigure.spi.internal.StructuredConfigProperties; +import io.opentelemetry.sdk.resources.Resource; + +public class ResourceOrderedSecondComponentProvider + implements ComponentProvider, Ordered { + @Override + public Class getType() { + return Resource.class; + } + + @Override + public String getName() { + return "unused"; + } + + @Override + public Resource create(StructuredConfigProperties config) { + return Resource.builder().put("order", "second").build(); + } + + @Override + public int order() { + return 2; + } +} diff --git a/sdk-extensions/incubator/src/test/resources/META-INF/services/io.opentelemetry.sdk.autoconfigure.spi.internal.ComponentProvider b/sdk-extensions/incubator/src/test/resources/META-INF/services/io.opentelemetry.sdk.autoconfigure.spi.internal.ComponentProvider index 0dc2d209e1d..6ab8ffdecc3 100644 --- a/sdk-extensions/incubator/src/test/resources/META-INF/services/io.opentelemetry.sdk.autoconfigure.spi.internal.ComponentProvider +++ b/sdk-extensions/incubator/src/test/resources/META-INF/services/io.opentelemetry.sdk.autoconfigure.spi.internal.ComponentProvider @@ -1,3 +1,6 @@ io.opentelemetry.sdk.extension.incubator.fileconfig.component.MetricExporterComponentProvider io.opentelemetry.sdk.extension.incubator.fileconfig.component.SpanExporterComponentProvider io.opentelemetry.sdk.extension.incubator.fileconfig.component.LogRecordExporterComponentProvider +io.opentelemetry.sdk.extension.incubator.fileconfig.component.ResourceComponentProvider +io.opentelemetry.sdk.extension.incubator.fileconfig.component.ResourceOrderedFirstComponentProvider +io.opentelemetry.sdk.extension.incubator.fileconfig.component.ResourceOrderedSecondComponentProvider From 8495996d549a969ab2fece1f12a7d6bc0f84f17c Mon Sep 17 00:00:00 2001 From: jack-berg <34418638+jack-berg@users.noreply.github.com> Date: Wed, 28 Aug 2024 14:59:04 -0500 Subject: [PATCH 536/901] Processor component provider (#6623) --- .../fileconfig/LogRecordProcessorFactory.java | 24 ++++++-- .../fileconfig/SpanProcessorFactory.java | 24 ++++++-- .../LogRecordProcessorFactoryTest.java | 32 +++++++--- .../fileconfig/MetricExporterFactoryTest.java | 5 +- .../fileconfig/SpanProcessorFactoryTest.java | 31 +++++++--- .../LogRecordProcessorComponentProvider.java | 47 ++++++++++++++ .../SpanProcessorComponentProvider.java | 61 +++++++++++++++++++ ...toconfigure.spi.internal.ComponentProvider | 2 + 8 files changed, 200 insertions(+), 26 deletions(-) create mode 100644 sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/component/LogRecordProcessorComponentProvider.java create mode 100644 sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/component/SpanProcessorComponentProvider.java diff --git a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/LogRecordProcessorFactory.java b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/LogRecordProcessorFactory.java index 78183f19232..882db7db24f 100644 --- a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/LogRecordProcessorFactory.java +++ b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/LogRecordProcessorFactory.java @@ -17,6 +17,7 @@ import java.io.Closeable; import java.time.Duration; import java.util.List; +import java.util.Map; final class LogRecordProcessorFactory implements Factory< @@ -73,11 +74,26 @@ public LogRecordProcessor create( closeables, SimpleLogRecordProcessor.create(logRecordExporter)); } - // TODO: add support for generic log record processors if (!model.getAdditionalProperties().isEmpty()) { - throw new ConfigurationException( - "Unrecognized log record processor(s): " - + model.getAdditionalProperties().keySet().stream().collect(joining(",", "[", "]"))); + Map additionalProperties = model.getAdditionalProperties(); + if (additionalProperties.size() > 1) { + throw new ConfigurationException( + "Invalid configuration - multiple log record processors set: " + + additionalProperties.keySet().stream().collect(joining(",", "[", "]"))); + } + Map.Entry processorKeyValue = + additionalProperties.entrySet().stream() + .findFirst() + .orElseThrow( + () -> + new IllegalStateException("Missing processor. This is a programming error.")); + LogRecordProcessor logRecordProcessor = + FileConfigUtil.loadComponent( + spiHelper, + LogRecordProcessor.class, + processorKeyValue.getKey(), + processorKeyValue.getValue()); + return FileConfigUtil.addAndReturn(closeables, logRecordProcessor); } else { throw new ConfigurationException("log processor must be set"); } diff --git a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/SpanProcessorFactory.java b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/SpanProcessorFactory.java index d0c50ebaa61..9d2e4362078 100644 --- a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/SpanProcessorFactory.java +++ b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/SpanProcessorFactory.java @@ -17,6 +17,7 @@ import java.io.Closeable; import java.time.Duration; import java.util.List; +import java.util.Map; final class SpanProcessorFactory implements Factory< @@ -70,11 +71,26 @@ public SpanProcessor create( return FileConfigUtil.addAndReturn(closeables, SimpleSpanProcessor.create(spanExporter)); } - // TODO: add support for generic span processors if (!model.getAdditionalProperties().isEmpty()) { - throw new ConfigurationException( - "Unrecognized span processor(s): " - + model.getAdditionalProperties().keySet().stream().collect(joining(",", "[", "]"))); + Map additionalProperties = model.getAdditionalProperties(); + if (additionalProperties.size() > 1) { + throw new ConfigurationException( + "Invalid configuration - multiple span processors set: " + + additionalProperties.keySet().stream().collect(joining(",", "[", "]"))); + } + Map.Entry processorKeyValue = + additionalProperties.entrySet().stream() + .findFirst() + .orElseThrow( + () -> + new IllegalStateException("Missing processor. This is a programming error.")); + SpanProcessor spanProcessor = + FileConfigUtil.loadComponent( + spiHelper, + SpanProcessor.class, + processorKeyValue.getKey(), + processorKeyValue.getValue()); + return FileConfigUtil.addAndReturn(closeables, spanProcessor); } else { throw new ConfigurationException("span processor must be set"); } diff --git a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/LogRecordProcessorFactoryTest.java b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/LogRecordProcessorFactoryTest.java index 06ad307ee06..31038580e82 100644 --- a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/LogRecordProcessorFactoryTest.java +++ b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/LogRecordProcessorFactoryTest.java @@ -13,6 +13,7 @@ import io.opentelemetry.internal.testing.CleanupExtension; import io.opentelemetry.sdk.autoconfigure.internal.SpiHelper; import io.opentelemetry.sdk.autoconfigure.spi.ConfigurationException; +import io.opentelemetry.sdk.extension.incubator.fileconfig.component.LogRecordProcessorComponentProvider; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.BatchLogRecordProcessor; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.LogRecordExporter; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.LogRecordProcessor; @@ -23,6 +24,7 @@ import java.util.ArrayList; import java.util.Collections; import java.util.List; +import org.assertj.core.api.Assertions; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.RegisterExtension; @@ -137,19 +139,35 @@ void create_SimpleConfigured() { } @Test - void create_SpiProcessor() { - List closeables = new ArrayList<>(); - + void create_SpiProcessor_Unknown() { assertThatThrownBy( () -> LogRecordProcessorFactory.getInstance() .create( new LogRecordProcessor() - .withAdditionalProperty("test", ImmutableMap.of("key1", "value1")), + .withAdditionalProperty( + "unknown_key", ImmutableMap.of("key1", "value1")), spiHelper, - closeables)) + new ArrayList<>())) .isInstanceOf(ConfigurationException.class) - .hasMessage("Unrecognized log record processor(s): [test]"); - cleanup.addCloseables(closeables); + .hasMessage( + "No component provider detected for io.opentelemetry.sdk.logs.LogRecordProcessor with name \"unknown_key\"."); + } + + @Test + void create_SpiExporter_Valid() { + io.opentelemetry.sdk.logs.LogRecordProcessor logRecordProcessor = + LogRecordProcessorFactory.getInstance() + .create( + new LogRecordProcessor() + .withAdditionalProperty("test", ImmutableMap.of("key1", "value1")), + spiHelper, + new ArrayList<>()); + assertThat(logRecordProcessor) + .isInstanceOf(LogRecordProcessorComponentProvider.TestLogRecordProcessor.class); + Assertions.assertThat( + ((LogRecordProcessorComponentProvider.TestLogRecordProcessor) logRecordProcessor) + .config.getString("key1")) + .isEqualTo("value1"); } } diff --git a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/MetricExporterFactoryTest.java b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/MetricExporterFactoryTest.java index 8356339e063..64f0db469ec 100644 --- a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/MetricExporterFactoryTest.java +++ b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/MetricExporterFactoryTest.java @@ -210,7 +210,7 @@ void create_PrometheusExporter() { .MetricExporter() .withPrometheus(new Prometheus()), spiHelper, - new ArrayList<>())) + closeables)) .isInstanceOf(ConfigurationException.class) .hasMessage("prometheus exporter not supported in this context"); cleanup.addCloseables(closeables); @@ -218,8 +218,6 @@ void create_PrometheusExporter() { @Test void create_SpiExporter_Unknown() { - List closeables = new ArrayList<>(); - assertThatThrownBy( () -> MetricExporterFactory.getInstance() @@ -233,7 +231,6 @@ void create_SpiExporter_Unknown() { .isInstanceOf(ConfigurationException.class) .hasMessage( "No component provider detected for io.opentelemetry.sdk.metrics.export.MetricExporter with name \"unknown_key\"."); - cleanup.addCloseables(closeables); } @Test diff --git a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/SpanProcessorFactoryTest.java b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/SpanProcessorFactoryTest.java index 972e0a137f9..19426bd1244 100644 --- a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/SpanProcessorFactoryTest.java +++ b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/SpanProcessorFactoryTest.java @@ -13,6 +13,7 @@ import io.opentelemetry.internal.testing.CleanupExtension; import io.opentelemetry.sdk.autoconfigure.internal.SpiHelper; import io.opentelemetry.sdk.autoconfigure.spi.ConfigurationException; +import io.opentelemetry.sdk.extension.incubator.fileconfig.component.SpanProcessorComponentProvider; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.BatchSpanProcessor; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.Otlp; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.SimpleSpanProcessor; @@ -23,6 +24,7 @@ import java.util.ArrayList; import java.util.Collections; import java.util.List; +import org.assertj.core.api.Assertions; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.RegisterExtension; @@ -137,19 +139,34 @@ void create_SimpleConfigured() { } @Test - void create_SpiProcessor() { - List closeables = new ArrayList<>(); - + void create_SpiProcessor_Unknown() { assertThatThrownBy( () -> SpanProcessorFactory.getInstance() .create( new SpanProcessor() - .withAdditionalProperty("test", ImmutableMap.of("key1", "value1")), + .withAdditionalProperty( + "unknown_key", ImmutableMap.of("key1", "value1")), spiHelper, - closeables)) + new ArrayList<>())) .isInstanceOf(ConfigurationException.class) - .hasMessage("Unrecognized span processor(s): [test]"); - cleanup.addCloseables(closeables); + .hasMessage( + "No component provider detected for io.opentelemetry.sdk.trace.SpanProcessor with name \"unknown_key\"."); + } + + @Test + void create_SpiExporter_Valid() { + io.opentelemetry.sdk.trace.SpanProcessor spanProcessor = + SpanProcessorFactory.getInstance() + .create( + new SpanProcessor() + .withAdditionalProperty("test", ImmutableMap.of("key1", "value1")), + spiHelper, + new ArrayList<>()); + assertThat(spanProcessor).isInstanceOf(SpanProcessorComponentProvider.TestSpanProcessor.class); + Assertions.assertThat( + ((SpanProcessorComponentProvider.TestSpanProcessor) spanProcessor) + .config.getString("key1")) + .isEqualTo("value1"); } } diff --git a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/component/LogRecordProcessorComponentProvider.java b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/component/LogRecordProcessorComponentProvider.java new file mode 100644 index 00000000000..581f2726154 --- /dev/null +++ b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/component/LogRecordProcessorComponentProvider.java @@ -0,0 +1,47 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.sdk.extension.incubator.fileconfig.component; + +import io.opentelemetry.context.Context; +import io.opentelemetry.sdk.autoconfigure.spi.internal.ComponentProvider; +import io.opentelemetry.sdk.autoconfigure.spi.internal.StructuredConfigProperties; +import io.opentelemetry.sdk.common.CompletableResultCode; +import io.opentelemetry.sdk.logs.LogRecordProcessor; +import io.opentelemetry.sdk.logs.ReadWriteLogRecord; + +public class LogRecordProcessorComponentProvider implements ComponentProvider { + @Override + public Class getType() { + return LogRecordProcessor.class; + } + + @Override + public String getName() { + return "test"; + } + + @Override + public LogRecordProcessor create(StructuredConfigProperties config) { + return new TestLogRecordProcessor(config); + } + + public static class TestLogRecordProcessor implements LogRecordProcessor { + + public final StructuredConfigProperties config; + + private TestLogRecordProcessor(StructuredConfigProperties config) { + this.config = config; + } + + @Override + public void onEmit(Context context, ReadWriteLogRecord logRecord) {} + + @Override + public CompletableResultCode shutdown() { + return CompletableResultCode.ofSuccess(); + } + } +} diff --git a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/component/SpanProcessorComponentProvider.java b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/component/SpanProcessorComponentProvider.java new file mode 100644 index 00000000000..7bfe0936cd9 --- /dev/null +++ b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/component/SpanProcessorComponentProvider.java @@ -0,0 +1,61 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.sdk.extension.incubator.fileconfig.component; + +import io.opentelemetry.context.Context; +import io.opentelemetry.sdk.autoconfigure.spi.internal.ComponentProvider; +import io.opentelemetry.sdk.autoconfigure.spi.internal.StructuredConfigProperties; +import io.opentelemetry.sdk.common.CompletableResultCode; +import io.opentelemetry.sdk.trace.ReadWriteSpan; +import io.opentelemetry.sdk.trace.ReadableSpan; +import io.opentelemetry.sdk.trace.SpanProcessor; + +public class SpanProcessorComponentProvider implements ComponentProvider { + @Override + public Class getType() { + return SpanProcessor.class; + } + + @Override + public String getName() { + return "test"; + } + + @Override + public SpanProcessor create(StructuredConfigProperties config) { + return new TestSpanProcessor(config); + } + + public static class TestSpanProcessor implements SpanProcessor { + + public final StructuredConfigProperties config; + + private TestSpanProcessor(StructuredConfigProperties config) { + this.config = config; + } + + @Override + public void onStart(Context parentContext, ReadWriteSpan span) {} + + @Override + public boolean isStartRequired() { + return true; + } + + @Override + public void onEnd(ReadableSpan span) {} + + @Override + public boolean isEndRequired() { + return true; + } + + @Override + public CompletableResultCode shutdown() { + return CompletableResultCode.ofSuccess(); + } + } +} diff --git a/sdk-extensions/incubator/src/test/resources/META-INF/services/io.opentelemetry.sdk.autoconfigure.spi.internal.ComponentProvider b/sdk-extensions/incubator/src/test/resources/META-INF/services/io.opentelemetry.sdk.autoconfigure.spi.internal.ComponentProvider index 6ab8ffdecc3..88759776549 100644 --- a/sdk-extensions/incubator/src/test/resources/META-INF/services/io.opentelemetry.sdk.autoconfigure.spi.internal.ComponentProvider +++ b/sdk-extensions/incubator/src/test/resources/META-INF/services/io.opentelemetry.sdk.autoconfigure.spi.internal.ComponentProvider @@ -1,6 +1,8 @@ io.opentelemetry.sdk.extension.incubator.fileconfig.component.MetricExporterComponentProvider io.opentelemetry.sdk.extension.incubator.fileconfig.component.SpanExporterComponentProvider io.opentelemetry.sdk.extension.incubator.fileconfig.component.LogRecordExporterComponentProvider +io.opentelemetry.sdk.extension.incubator.fileconfig.component.SpanProcessorComponentProvider +io.opentelemetry.sdk.extension.incubator.fileconfig.component.LogRecordProcessorComponentProvider io.opentelemetry.sdk.extension.incubator.fileconfig.component.ResourceComponentProvider io.opentelemetry.sdk.extension.incubator.fileconfig.component.ResourceOrderedFirstComponentProvider io.opentelemetry.sdk.extension.incubator.fileconfig.component.ResourceOrderedSecondComponentProvider From 938b03dff65ee752802f9c131f14afff29bd01d0 Mon Sep 17 00:00:00 2001 From: jack-berg <34418638+jack-berg@users.noreply.github.com> Date: Wed, 28 Aug 2024 15:09:36 -0500 Subject: [PATCH 537/901] Add file configuration ComponentProvider support for samplers (#6494) --- .../fileconfig/FileConfiguration.java | 81 +++++++++++++------ .../incubator/fileconfig/SamplerFactory.java | 79 ++++++------------ .../YamlStructuredConfigProperties.java | 31 +++++-- .../FileConfigurationCreateTest.java | 2 +- .../fileconfig/SamplerFactoryTest.java | 27 ++++++- .../component/SamplerComponentProvider.java | 58 +++++++++++++ ...toconfigure.spi.internal.ComponentProvider | 1 + .../jaeger-remote-sampler/build.gradle.kts | 1 + .../JaegerRemoteSamplerComponentProvider.java | 54 +++++++++++++ ...toconfigure.spi.internal.ComponentProvider | 1 + 10 files changed, 245 insertions(+), 90 deletions(-) create mode 100644 sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/component/SamplerComponentProvider.java create mode 100644 sdk-extensions/jaeger-remote-sampler/src/main/java/io/opentelemetry/sdk/extension/trace/jaeger/sampler/internal/JaegerRemoteSamplerComponentProvider.java create mode 100644 sdk-extensions/jaeger-remote-sampler/src/main/resources/META-INF/services/io.opentelemetry.sdk.autoconfigure.spi.internal.ComponentProvider diff --git a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/FileConfiguration.java b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/FileConfiguration.java index 82888ed5735..1a28935086b 100644 --- a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/FileConfiguration.java +++ b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/FileConfiguration.java @@ -12,8 +12,10 @@ import io.opentelemetry.sdk.OpenTelemetrySdk; import io.opentelemetry.sdk.autoconfigure.internal.SpiHelper; import io.opentelemetry.sdk.autoconfigure.spi.ConfigurationException; +import io.opentelemetry.sdk.autoconfigure.spi.internal.ComponentProvider; import io.opentelemetry.sdk.autoconfigure.spi.internal.StructuredConfigProperties; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.OpenTelemetryConfiguration; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.Sampler; import java.io.Closeable; import java.io.IOException; import java.io.InputStream; @@ -84,30 +86,10 @@ public static OpenTelemetrySdk parseAndCreate(InputStream inputStream) { * @throws ConfigurationException if unable to interpret */ public static OpenTelemetrySdk create(OpenTelemetryConfiguration configurationModel) { - List closeables = new ArrayList<>(); - try { - return OpenTelemetryConfigurationFactory.getInstance() - .create( - configurationModel, - SpiHelper.create(FileConfiguration.class.getClassLoader()), - closeables); - } catch (RuntimeException e) { - logger.info( - "Error encountered interpreting configuration model. Closing partially configured components."); - for (Closeable closeable : closeables) { - try { - logger.fine("Closing " + closeable.getClass().getName()); - closeable.close(); - } catch (IOException ex) { - logger.warning( - "Error closing " + closeable.getClass().getName() + ": " + ex.getMessage()); - } - } - if (e instanceof ConfigurationException) { - throw e; - } - throw new ConfigurationException("Unexpected configuration error", e); - } + return createAndMaybeCleanup( + OpenTelemetryConfigurationFactory.getInstance(), + SpiHelper.create(FileConfiguration.class.getClassLoader()), + configurationModel); } /** @@ -157,6 +139,57 @@ static StructuredConfigProperties toConfigProperties(Object model) { return YamlStructuredConfigProperties.create(configurationMap); } + /** + * Create a {@link Sampler} from the {@code samplerModel} representing the sampler config. + * + *

      This is used when samplers are composed, with one sampler accepting one or more additional + * samplers as config properties. The {@link ComponentProvider} implementation can call this to + * configure a delegate {@link Sampler} from the {@link StructuredConfigProperties} corresponding + * to a particular config property. + */ + // TODO(jack-berg): add create methods for all SDK extension components supported by + // ComponentProvider + public static io.opentelemetry.sdk.trace.samplers.Sampler createSampler( + StructuredConfigProperties genericSamplerModel) { + Sampler samplerModel = convertToModel(genericSamplerModel, Sampler.class); + return createAndMaybeCleanup( + SamplerFactory.getInstance(), + SpiHelper.create(FileConfiguration.class.getClassLoader()), + samplerModel); + } + + static T convertToModel( + StructuredConfigProperties structuredConfigProperties, Class modelType) { + if (!(structuredConfigProperties instanceof YamlStructuredConfigProperties)) { + throw new ConfigurationException( + "Only YamlStructuredConfigProperties can be converted to model"); + } + return MAPPER.convertValue( + ((YamlStructuredConfigProperties) structuredConfigProperties).toMap(), modelType); + } + + static R createAndMaybeCleanup(Factory factory, SpiHelper spiHelper, M model) { + List closeables = new ArrayList<>(); + try { + return factory.create(model, spiHelper, closeables); + } catch (RuntimeException e) { + logger.info("Error encountered interpreting model. Closing partially configured components."); + for (Closeable closeable : closeables) { + try { + logger.fine("Closing " + closeable.getClass().getName()); + closeable.close(); + } catch (IOException ex) { + logger.warning( + "Error closing " + closeable.getClass().getName() + ": " + ex.getMessage()); + } + } + if (e instanceof ConfigurationException) { + throw e; + } + throw new ConfigurationException("Unexpected configuration error", e); + } + } + /** * {@link StandardConstructor} which substitutes environment variables. * diff --git a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/SamplerFactory.java b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/SamplerFactory.java index f900015f8c4..2f8c3bc4520 100644 --- a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/SamplerFactory.java +++ b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/SamplerFactory.java @@ -7,20 +7,14 @@ import static java.util.stream.Collectors.joining; -import io.opentelemetry.sdk.autoconfigure.internal.NamedSpiManager; import io.opentelemetry.sdk.autoconfigure.internal.SpiHelper; -import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties; import io.opentelemetry.sdk.autoconfigure.spi.ConfigurationException; -import io.opentelemetry.sdk.autoconfigure.spi.internal.DefaultConfigProperties; -import io.opentelemetry.sdk.autoconfigure.spi.traces.ConfigurableSamplerProvider; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.JaegerRemote; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.ParentBased; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.TraceIdRatioBased; import io.opentelemetry.sdk.trace.samplers.ParentBasedSamplerBuilder; import io.opentelemetry.sdk.trace.samplers.Sampler; import java.io.Closeable; -import java.util.Collections; -import java.util.HashMap; import java.util.List; import java.util.Map; @@ -63,70 +57,49 @@ public Sampler create( : create(parentBasedModel.getRoot(), spiHelper, closeables); ParentBasedSamplerBuilder builder = Sampler.parentBasedBuilder(root); if (parentBasedModel.getRemoteParentSampled() != null) { - builder.setRemoteParentSampled( - create(parentBasedModel.getRemoteParentSampled(), spiHelper, closeables)); + Sampler sampler = create(parentBasedModel.getRemoteParentSampled(), spiHelper, closeables); + builder.setRemoteParentSampled(sampler); } if (parentBasedModel.getRemoteParentNotSampled() != null) { - builder.setRemoteParentNotSampled( - create(parentBasedModel.getRemoteParentNotSampled(), spiHelper, closeables)); + Sampler sampler = + create(parentBasedModel.getRemoteParentNotSampled(), spiHelper, closeables); + builder.setRemoteParentNotSampled(sampler); } if (parentBasedModel.getLocalParentSampled() != null) { - builder.setLocalParentSampled( - create(parentBasedModel.getLocalParentSampled(), spiHelper, closeables)); + Sampler sampler = create(parentBasedModel.getLocalParentSampled(), spiHelper, closeables); + builder.setLocalParentSampled(sampler); } if (parentBasedModel.getLocalParentNotSampled() != null) { - builder.setLocalParentNotSampled( - create(parentBasedModel.getLocalParentNotSampled(), spiHelper, closeables)); + Sampler sampler = + create(parentBasedModel.getLocalParentNotSampled(), spiHelper, closeables); + builder.setLocalParentNotSampled(sampler); } return builder.build(); } JaegerRemote jaegerRemoteModel = model.getJaegerRemote(); if (jaegerRemoteModel != null) { - // Translate from file configuration scheme to environment variable scheme. This is ultimately - // interpreted by JaegerRemoteSamplerProvider, but we want to avoid the dependency on - // opentelemetry-sdk-extension-jaeger-remote-sampler - Map properties = new HashMap<>(); - if (jaegerRemoteModel.getEndpoint() != null) { - properties.put("endpoint", jaegerRemoteModel.getEndpoint()); - } - if (jaegerRemoteModel.getInterval() != null) { - properties.put("pollingInterval", String.valueOf(jaegerRemoteModel.getInterval())); - } - // TODO(jack-berg): determine how to support initial sampler. This is first case where a - // component configured via SPI has property that isn't available in the environment variable - // scheme. - String otelTraceSamplerArg = - properties.entrySet().stream() - .map(entry -> entry.getKey() + "=" + entry.getValue()) - .collect(joining(",")); - - ConfigProperties configProperties = - DefaultConfigProperties.createFromMap( - Collections.singletonMap("otel.traces.sampler.arg", otelTraceSamplerArg)); - return FileConfigUtil.addAndReturn( - closeables, - FileConfigUtil.assertNotNull( - samplerSpiManager(configProperties, spiHelper).getByName("jaeger_remote"), - "jaeger remote sampler")); + model.getAdditionalProperties().put("jaeger_remote", jaegerRemoteModel); } - // TODO(jack-berg): add support for generic SPI samplers if (!model.getAdditionalProperties().isEmpty()) { - throw new ConfigurationException( - "Unrecognized sampler(s): " - + model.getAdditionalProperties().keySet().stream().collect(joining(",", "[", "]"))); + Map additionalProperties = model.getAdditionalProperties(); + if (additionalProperties.size() > 1) { + throw new ConfigurationException( + "Invalid configuration - multiple samplers exporters set: " + + additionalProperties.keySet().stream().collect(joining(",", "[", "]"))); + } + Map.Entry exporterKeyValue = + additionalProperties.entrySet().stream() + .findFirst() + .orElseThrow( + () -> new IllegalStateException("Missing sampler. This is a programming error.")); + Sampler sampler = + FileConfigUtil.loadComponent( + spiHelper, Sampler.class, exporterKeyValue.getKey(), exporterKeyValue.getValue()); + return FileConfigUtil.addAndReturn(closeables, sampler); } else { throw new ConfigurationException("sampler must be set"); } } - - private static NamedSpiManager samplerSpiManager( - ConfigProperties config, SpiHelper spiHelper) { - return spiHelper.loadConfigurable( - ConfigurableSamplerProvider.class, - ConfigurableSamplerProvider::getName, - ConfigurableSamplerProvider::createSampler, - config); - } } diff --git a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/YamlStructuredConfigProperties.java b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/YamlStructuredConfigProperties.java index 6475bbe1698..2e9e20d3f0c 100644 --- a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/YamlStructuredConfigProperties.java +++ b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/YamlStructuredConfigProperties.java @@ -35,13 +35,13 @@ final class YamlStructuredConfigProperties implements StructuredConfigProperties /** Values are {@link #isPrimitive(Object)}, {@link List} of scalars. */ private final Map simpleEntries; - private final Map> listEntries; - private final Map mapEntries; + private final Map> listEntries; + private final Map mapEntries; private YamlStructuredConfigProperties( Map simpleEntries, - Map> listEntries, - Map mapEntries) { + Map> listEntries, + Map mapEntries) { this.simpleEntries = simpleEntries; this.listEntries = listEntries; this.mapEntries = mapEntries; @@ -59,8 +59,8 @@ private YamlStructuredConfigProperties( @SuppressWarnings("unchecked") static YamlStructuredConfigProperties create(Map properties) { Map simpleEntries = new HashMap<>(); - Map> listEntries = new HashMap<>(); - Map mapEntries = new HashMap<>(); + Map> listEntries = new HashMap<>(); + Map mapEntries = new HashMap<>(); for (Map.Entry entry : properties.entrySet()) { String key = entry.getKey(); Object value = entry.getValue(); @@ -73,7 +73,7 @@ static YamlStructuredConfigProperties create(Map properties) { continue; } if (isListOfMaps(value)) { - List list = + List list = ((List>) value) .stream().map(YamlStructuredConfigProperties::create).collect(toList()); listEntries.put(key, list); @@ -257,7 +257,11 @@ public StructuredConfigProperties getStructured(String name) { @Nullable @Override public List getStructuredList(String name) { - return listEntries.get(name); + List value = listEntries.get(name); + if (value != null) { + return Collections.unmodifiableList(value); + } + return null; } @Override @@ -277,4 +281,15 @@ public String toString() { mapEntries.forEach((key, value) -> joiner.add(key + "=" + value)); return joiner.toString(); } + + /** Return a map representation of the data. */ + Map toMap() { + Map result = new HashMap<>(simpleEntries); + listEntries.forEach( + (key, value) -> + result.put( + key, value.stream().map(YamlStructuredConfigProperties::toMap).collect(toList()))); + mapEntries.forEach((key, value) -> result.put(key, value.toMap())); + return Collections.unmodifiableMap(result); + } } diff --git a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/FileConfigurationCreateTest.java b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/FileConfigurationCreateTest.java index dcd90cd60c4..d47ae14eb9a 100644 --- a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/FileConfigurationCreateTest.java +++ b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/FileConfigurationCreateTest.java @@ -121,7 +121,7 @@ void parseAndCreate_Exception_CleansUpPartials() { .hasMessage( "No component provider detected for io.opentelemetry.sdk.logs.export.LogRecordExporter with name \"foo\"."); logCapturer.assertContains( - "Error encountered interpreting configuration model. Closing partially configured components."); + "Error encountered interpreting model. Closing partially configured components."); logCapturer.assertContains( "Closing io.opentelemetry.exporter.otlp.logs.OtlpGrpcLogRecordExporter"); logCapturer.assertContains("Closing io.opentelemetry.sdk.logs.export.BatchLogRecordProcessor"); diff --git a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/SamplerFactoryTest.java b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/SamplerFactoryTest.java index 4df997c3b2a..4413ddb34c7 100644 --- a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/SamplerFactoryTest.java +++ b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/SamplerFactoryTest.java @@ -13,6 +13,7 @@ import io.opentelemetry.internal.testing.slf4j.SuppressLogger; import io.opentelemetry.sdk.autoconfigure.internal.SpiHelper; import io.opentelemetry.sdk.autoconfigure.spi.ConfigurationException; +import io.opentelemetry.sdk.extension.incubator.fileconfig.component.SamplerComponentProvider; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.AlwaysOff; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.AlwaysOn; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.JaegerRemote; @@ -116,23 +117,41 @@ private static Stream createArguments() { JaegerRemoteSampler.builder() .setEndpoint("http://jaeger-remote-endpoint") .setPollingInterval(Duration.ofSeconds(10)) + .setInitialSampler(io.opentelemetry.sdk.trace.samplers.Sampler.alwaysOff()) .build())); } @Test - void create_SpiExporter() { + void create_SpiExporter_Unknown() { List closeables = new ArrayList<>(); assertThatThrownBy( () -> SamplerFactory.getInstance() .create( - new Sampler() - .withAdditionalProperty("test", ImmutableMap.of("key1", "value1")), + new io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model + .Sampler() + .withAdditionalProperty( + "unknown_key", ImmutableMap.of("key1", "value1")), spiHelper, new ArrayList<>())) .isInstanceOf(ConfigurationException.class) - .hasMessage("Unrecognized sampler(s): [test]"); + .hasMessage( + "No component provider detected for io.opentelemetry.sdk.trace.samplers.Sampler with name \"unknown_key\"."); cleanup.addCloseables(closeables); } + + @Test + void create_SpiExporter_Valid() { + io.opentelemetry.sdk.trace.samplers.Sampler sampler = + SamplerFactory.getInstance() + .create( + new io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.Sampler() + .withAdditionalProperty("test", ImmutableMap.of("key1", "value1")), + spiHelper, + new ArrayList<>()); + assertThat(sampler).isInstanceOf(SamplerComponentProvider.TestSampler.class); + assertThat(((SamplerComponentProvider.TestSampler) sampler).config.getString("key1")) + .isEqualTo("value1"); + } } diff --git a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/component/SamplerComponentProvider.java b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/component/SamplerComponentProvider.java new file mode 100644 index 00000000000..2d4c983e4d7 --- /dev/null +++ b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/component/SamplerComponentProvider.java @@ -0,0 +1,58 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.sdk.extension.incubator.fileconfig.component; + +import io.opentelemetry.api.common.Attributes; +import io.opentelemetry.api.trace.SpanKind; +import io.opentelemetry.context.Context; +import io.opentelemetry.sdk.autoconfigure.spi.internal.ComponentProvider; +import io.opentelemetry.sdk.autoconfigure.spi.internal.StructuredConfigProperties; +import io.opentelemetry.sdk.trace.data.LinkData; +import io.opentelemetry.sdk.trace.samplers.Sampler; +import io.opentelemetry.sdk.trace.samplers.SamplingResult; +import java.util.List; + +public class SamplerComponentProvider implements ComponentProvider { + @Override + public Class getType() { + return Sampler.class; + } + + @Override + public String getName() { + return "test"; + } + + @Override + public Sampler create(StructuredConfigProperties config) { + return new TestSampler(config); + } + + public static class TestSampler implements Sampler { + + public final StructuredConfigProperties config; + + private TestSampler(StructuredConfigProperties config) { + this.config = config; + } + + @Override + public SamplingResult shouldSample( + Context parentContext, + String traceId, + String name, + SpanKind spanKind, + Attributes attributes, + List parentLinks) { + return SamplingResult.recordOnly(); + } + + @Override + public String getDescription() { + return "test"; + } + } +} diff --git a/sdk-extensions/incubator/src/test/resources/META-INF/services/io.opentelemetry.sdk.autoconfigure.spi.internal.ComponentProvider b/sdk-extensions/incubator/src/test/resources/META-INF/services/io.opentelemetry.sdk.autoconfigure.spi.internal.ComponentProvider index 88759776549..2bc161f4d9c 100644 --- a/sdk-extensions/incubator/src/test/resources/META-INF/services/io.opentelemetry.sdk.autoconfigure.spi.internal.ComponentProvider +++ b/sdk-extensions/incubator/src/test/resources/META-INF/services/io.opentelemetry.sdk.autoconfigure.spi.internal.ComponentProvider @@ -1,6 +1,7 @@ io.opentelemetry.sdk.extension.incubator.fileconfig.component.MetricExporterComponentProvider io.opentelemetry.sdk.extension.incubator.fileconfig.component.SpanExporterComponentProvider io.opentelemetry.sdk.extension.incubator.fileconfig.component.LogRecordExporterComponentProvider +io.opentelemetry.sdk.extension.incubator.fileconfig.component.SamplerComponentProvider io.opentelemetry.sdk.extension.incubator.fileconfig.component.SpanProcessorComponentProvider io.opentelemetry.sdk.extension.incubator.fileconfig.component.LogRecordProcessorComponentProvider io.opentelemetry.sdk.extension.incubator.fileconfig.component.ResourceComponentProvider diff --git a/sdk-extensions/jaeger-remote-sampler/build.gradle.kts b/sdk-extensions/jaeger-remote-sampler/build.gradle.kts index fca0210b6a1..ac250eef3d1 100644 --- a/sdk-extensions/jaeger-remote-sampler/build.gradle.kts +++ b/sdk-extensions/jaeger-remote-sampler/build.gradle.kts @@ -13,6 +13,7 @@ otelJava.moduleName.set("io.opentelemetry.sdk.extension.trace.jaeger") dependencies { api(project(":sdk:all")) compileOnly(project(":sdk-extensions:autoconfigure")) + compileOnly(project(":sdk-extensions:incubator")) implementation(project(":sdk:all")) implementation(project(":exporters:common")) diff --git a/sdk-extensions/jaeger-remote-sampler/src/main/java/io/opentelemetry/sdk/extension/trace/jaeger/sampler/internal/JaegerRemoteSamplerComponentProvider.java b/sdk-extensions/jaeger-remote-sampler/src/main/java/io/opentelemetry/sdk/extension/trace/jaeger/sampler/internal/JaegerRemoteSamplerComponentProvider.java new file mode 100644 index 00000000000..9ce99c908b2 --- /dev/null +++ b/sdk-extensions/jaeger-remote-sampler/src/main/java/io/opentelemetry/sdk/extension/trace/jaeger/sampler/internal/JaegerRemoteSamplerComponentProvider.java @@ -0,0 +1,54 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.sdk.extension.trace.jaeger.sampler.internal; + +import io.opentelemetry.sdk.autoconfigure.spi.internal.ComponentProvider; +import io.opentelemetry.sdk.autoconfigure.spi.internal.StructuredConfigProperties; +import io.opentelemetry.sdk.extension.incubator.fileconfig.FileConfiguration; +import io.opentelemetry.sdk.extension.trace.jaeger.sampler.JaegerRemoteSampler; +import io.opentelemetry.sdk.extension.trace.jaeger.sampler.JaegerRemoteSamplerBuilder; +import io.opentelemetry.sdk.trace.samplers.Sampler; +import java.time.Duration; + +/** + * File configuration SPI implementation for {@link JaegerRemoteSampler}. + * + *

      This class is internal and is hence not for public use. Its APIs are unstable and can change + * at any time. + */ +public class JaegerRemoteSamplerComponentProvider implements ComponentProvider { + @Override + public Class getType() { + return Sampler.class; + } + + @Override + public String getName() { + return "jaeger_remote"; + } + + @Override + public Sampler create(StructuredConfigProperties config) { + JaegerRemoteSamplerBuilder builder = JaegerRemoteSampler.builder(); + + // Optional configuration + String endpoint = config.getString("endpoint"); + if (endpoint != null) { + builder.setEndpoint(endpoint); + } + Long pollingIntervalMs = config.getLong("internal"); + if (pollingIntervalMs != null) { + builder.setPollingInterval(Duration.ofMillis(pollingIntervalMs)); + } + StructuredConfigProperties initialSamplerModel = config.getStructured("initial_sampler"); + if (initialSamplerModel != null) { + Sampler initialSampler = FileConfiguration.createSampler(initialSamplerModel); + builder.setInitialSampler(initialSampler); + } + + return builder.build(); + } +} diff --git a/sdk-extensions/jaeger-remote-sampler/src/main/resources/META-INF/services/io.opentelemetry.sdk.autoconfigure.spi.internal.ComponentProvider b/sdk-extensions/jaeger-remote-sampler/src/main/resources/META-INF/services/io.opentelemetry.sdk.autoconfigure.spi.internal.ComponentProvider new file mode 100644 index 00000000000..a06efe29e4f --- /dev/null +++ b/sdk-extensions/jaeger-remote-sampler/src/main/resources/META-INF/services/io.opentelemetry.sdk.autoconfigure.spi.internal.ComponentProvider @@ -0,0 +1 @@ +io.opentelemetry.sdk.extension.trace.jaeger.sampler.internal.JaegerRemoteSamplerComponentProvider From d37c1c74e7ec20a990e1a0a07a5daa1a2ecf9f0b Mon Sep 17 00:00:00 2001 From: jack-berg <34418638+jack-berg@users.noreply.github.com> Date: Wed, 28 Aug 2024 15:18:19 -0500 Subject: [PATCH 538/901] Add file configuration ComponentProvider support for propagators (#6624) --- .../internal/B3ComponentProvider.java | 36 ++++++++++++ .../internal/B3MultiComponentProvider.java | 36 ++++++++++++ .../internal/JaegerComponentProvider.java | 35 ++++++++++++ .../internal/OtTraceComponentProvider.java | 36 ++++++++++++ ...toconfigure.spi.internal.ComponentProvider | 4 ++ .../fileconfig/TextMapPropagatorFactory.java | 26 ++------- .../FileConfigurationCreateTest.java | 5 +- .../TextMapPropagatorFactoryTest.java | 22 +++++++- .../TextMapPropagatorComponentProvider.java | 55 +++++++++++++++++++ ...toconfigure.spi.internal.ComponentProvider | 1 + 10 files changed, 233 insertions(+), 23 deletions(-) create mode 100644 extensions/trace-propagators/src/main/java/io/opentelemetry/extension/trace/propagation/internal/B3ComponentProvider.java create mode 100644 extensions/trace-propagators/src/main/java/io/opentelemetry/extension/trace/propagation/internal/B3MultiComponentProvider.java create mode 100644 extensions/trace-propagators/src/main/java/io/opentelemetry/extension/trace/propagation/internal/JaegerComponentProvider.java create mode 100644 extensions/trace-propagators/src/main/java/io/opentelemetry/extension/trace/propagation/internal/OtTraceComponentProvider.java create mode 100644 extensions/trace-propagators/src/main/resources/META-INF/services/io.opentelemetry.sdk.autoconfigure.spi.internal.ComponentProvider create mode 100644 sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/component/TextMapPropagatorComponentProvider.java diff --git a/extensions/trace-propagators/src/main/java/io/opentelemetry/extension/trace/propagation/internal/B3ComponentProvider.java b/extensions/trace-propagators/src/main/java/io/opentelemetry/extension/trace/propagation/internal/B3ComponentProvider.java new file mode 100644 index 00000000000..b97134eda7a --- /dev/null +++ b/extensions/trace-propagators/src/main/java/io/opentelemetry/extension/trace/propagation/internal/B3ComponentProvider.java @@ -0,0 +1,36 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.extension.trace.propagation.internal; + +import io.opentelemetry.context.propagation.TextMapPropagator; +import io.opentelemetry.extension.trace.propagation.B3Propagator; +import io.opentelemetry.sdk.autoconfigure.spi.internal.ComponentProvider; +import io.opentelemetry.sdk.autoconfigure.spi.internal.StructuredConfigProperties; + +/** + * File configuration SPI implementation for {@link B3Propagator} which allows enables the {@link + * B3Propagator#injectingSingleHeader()}. + * + *

      This class is internal and is hence not for public use. Its APIs are unstable and can change + * at any time. + */ +public final class B3ComponentProvider implements ComponentProvider { + + @Override + public Class getType() { + return TextMapPropagator.class; + } + + @Override + public String getName() { + return "b3"; + } + + @Override + public TextMapPropagator create(StructuredConfigProperties config) { + return B3Propagator.injectingSingleHeader(); + } +} diff --git a/extensions/trace-propagators/src/main/java/io/opentelemetry/extension/trace/propagation/internal/B3MultiComponentProvider.java b/extensions/trace-propagators/src/main/java/io/opentelemetry/extension/trace/propagation/internal/B3MultiComponentProvider.java new file mode 100644 index 00000000000..77ac501a2ea --- /dev/null +++ b/extensions/trace-propagators/src/main/java/io/opentelemetry/extension/trace/propagation/internal/B3MultiComponentProvider.java @@ -0,0 +1,36 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.extension.trace.propagation.internal; + +import io.opentelemetry.context.propagation.TextMapPropagator; +import io.opentelemetry.extension.trace.propagation.B3Propagator; +import io.opentelemetry.sdk.autoconfigure.spi.internal.ComponentProvider; +import io.opentelemetry.sdk.autoconfigure.spi.internal.StructuredConfigProperties; + +/** + * File configuration SPI implementation for {@link B3Propagator} which allows enables the {@link + * B3Propagator#injectingMultiHeaders()}. + * + *

      This class is internal and is hence not for public use. Its APIs are unstable and can change + * at any time. + */ +public final class B3MultiComponentProvider implements ComponentProvider { + + @Override + public Class getType() { + return TextMapPropagator.class; + } + + @Override + public String getName() { + return "b3multi"; + } + + @Override + public TextMapPropagator create(StructuredConfigProperties config) { + return B3Propagator.injectingMultiHeaders(); + } +} diff --git a/extensions/trace-propagators/src/main/java/io/opentelemetry/extension/trace/propagation/internal/JaegerComponentProvider.java b/extensions/trace-propagators/src/main/java/io/opentelemetry/extension/trace/propagation/internal/JaegerComponentProvider.java new file mode 100644 index 00000000000..0fb844a40da --- /dev/null +++ b/extensions/trace-propagators/src/main/java/io/opentelemetry/extension/trace/propagation/internal/JaegerComponentProvider.java @@ -0,0 +1,35 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.extension.trace.propagation.internal; + +import io.opentelemetry.context.propagation.TextMapPropagator; +import io.opentelemetry.extension.trace.propagation.JaegerPropagator; +import io.opentelemetry.sdk.autoconfigure.spi.internal.ComponentProvider; +import io.opentelemetry.sdk.autoconfigure.spi.internal.StructuredConfigProperties; + +/** + * File configuration SPI implementation for {@link JaegerPropagator}. + * + *

      This class is internal and is hence not for public use. Its APIs are unstable and can change + * at any time. + */ +public final class JaegerComponentProvider implements ComponentProvider { + + @Override + public Class getType() { + return TextMapPropagator.class; + } + + @Override + public String getName() { + return "jaeger"; + } + + @Override + public TextMapPropagator create(StructuredConfigProperties config) { + return JaegerPropagator.getInstance(); + } +} diff --git a/extensions/trace-propagators/src/main/java/io/opentelemetry/extension/trace/propagation/internal/OtTraceComponentProvider.java b/extensions/trace-propagators/src/main/java/io/opentelemetry/extension/trace/propagation/internal/OtTraceComponentProvider.java new file mode 100644 index 00000000000..97b41aad3af --- /dev/null +++ b/extensions/trace-propagators/src/main/java/io/opentelemetry/extension/trace/propagation/internal/OtTraceComponentProvider.java @@ -0,0 +1,36 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.extension.trace.propagation.internal; + +import io.opentelemetry.context.propagation.TextMapPropagator; +import io.opentelemetry.extension.trace.propagation.B3Propagator; +import io.opentelemetry.extension.trace.propagation.OtTracePropagator; +import io.opentelemetry.sdk.autoconfigure.spi.internal.ComponentProvider; +import io.opentelemetry.sdk.autoconfigure.spi.internal.StructuredConfigProperties; + +/** + * File configuration SPI implementation for {@link B3Propagator}. + * + *

      This class is internal and is hence not for public use. Its APIs are unstable and can change + * at any time. + */ +public final class OtTraceComponentProvider implements ComponentProvider { + + @Override + public Class getType() { + return TextMapPropagator.class; + } + + @Override + public String getName() { + return "ottrace"; + } + + @Override + public TextMapPropagator create(StructuredConfigProperties config) { + return OtTracePropagator.getInstance(); + } +} diff --git a/extensions/trace-propagators/src/main/resources/META-INF/services/io.opentelemetry.sdk.autoconfigure.spi.internal.ComponentProvider b/extensions/trace-propagators/src/main/resources/META-INF/services/io.opentelemetry.sdk.autoconfigure.spi.internal.ComponentProvider new file mode 100644 index 00000000000..d4194f2b014 --- /dev/null +++ b/extensions/trace-propagators/src/main/resources/META-INF/services/io.opentelemetry.sdk.autoconfigure.spi.internal.ComponentProvider @@ -0,0 +1,4 @@ +io.opentelemetry.extension.trace.propagation.internal.B3ComponentProvider +io.opentelemetry.extension.trace.propagation.internal.B3MultiComponentProvider +io.opentelemetry.extension.trace.propagation.internal.JaegerComponentProvider +io.opentelemetry.extension.trace.propagation.internal.OtTraceComponentProvider diff --git a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/TextMapPropagatorFactory.java b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/TextMapPropagatorFactory.java index 965093d1c6b..b2a212aaa57 100644 --- a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/TextMapPropagatorFactory.java +++ b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/TextMapPropagatorFactory.java @@ -8,17 +8,13 @@ import io.opentelemetry.api.baggage.propagation.W3CBaggagePropagator; import io.opentelemetry.api.trace.propagation.W3CTraceContextPropagator; import io.opentelemetry.context.propagation.TextMapPropagator; -import io.opentelemetry.sdk.autoconfigure.internal.NamedSpiManager; import io.opentelemetry.sdk.autoconfigure.internal.SpiHelper; -import io.opentelemetry.sdk.autoconfigure.spi.ConfigurablePropagatorProvider; import io.opentelemetry.sdk.autoconfigure.spi.ConfigurationException; -import io.opentelemetry.sdk.autoconfigure.spi.internal.DefaultConfigProperties; import java.io.Closeable; +import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; -import java.util.LinkedHashSet; import java.util.List; -import java.util.Set; final class TextMapPropagatorFactory implements Factory, TextMapPropagator> { @@ -45,22 +41,15 @@ public TextMapPropagator create( return TextMapPropagator.noop(); } - NamedSpiManager spiPropagatorsManager = - spiHelper.loadConfigurable( - ConfigurablePropagatorProvider.class, - ConfigurablePropagatorProvider::getName, - ConfigurablePropagatorProvider::getPropagator, - DefaultConfigProperties.createFromMap(Collections.emptyMap())); - Set propagators = new LinkedHashSet<>(); + List propagators = new ArrayList<>(); for (String propagator : model) { - propagators.add(getPropagator(propagator, spiPropagatorsManager)); + propagators.add(getPropagator(spiHelper, propagator)); } return TextMapPropagator.composite(propagators); } - private static TextMapPropagator getPropagator( - String name, NamedSpiManager spiPropagatorsManager) { + private static TextMapPropagator getPropagator(SpiHelper spiHelper, String name) { if (name.equals("tracecontext")) { return W3CTraceContextPropagator.getInstance(); } @@ -68,10 +57,7 @@ private static TextMapPropagator getPropagator( return W3CBaggagePropagator.getInstance(); } - TextMapPropagator spiPropagator = spiPropagatorsManager.getByName(name); - if (spiPropagator != null) { - return spiPropagator; - } - throw new ConfigurationException("Unrecognized propagator: " + name); + return FileConfigUtil.loadComponent( + spiHelper, TextMapPropagator.class, name, Collections.emptyMap()); } } diff --git a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/FileConfigurationCreateTest.java b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/FileConfigurationCreateTest.java index d47ae14eb9a..51f70d930ec 100644 --- a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/FileConfigurationCreateTest.java +++ b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/FileConfigurationCreateTest.java @@ -86,7 +86,10 @@ void parseAndCreate_Examples(@TempDir Path tempDir) "client_key: .*\n", "client_key: " + clientKeyPath + System.lineSeparator()) .replaceAll( "client_certificate: .*\n", - "client_certificate: " + clientCertificatePath + System.lineSeparator()); + "client_certificate: " + clientCertificatePath + System.lineSeparator()) + // TODO: remove once ComponentProvider SPI implemented in + // https://github.com/open-telemetry/opentelemetry-java-contrib/tree/main/aws-xray-propagator + .replaceAll("xray,", ""); InputStream is = new ByteArrayInputStream(rewrittenExampleContent.getBytes(StandardCharsets.UTF_8)); diff --git a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/TextMapPropagatorFactoryTest.java b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/TextMapPropagatorFactoryTest.java index d2355fda46d..d2a1d5d242d 100644 --- a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/TextMapPropagatorFactoryTest.java +++ b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/TextMapPropagatorFactoryTest.java @@ -16,6 +16,8 @@ import io.opentelemetry.extension.trace.propagation.OtTracePropagator; import io.opentelemetry.sdk.autoconfigure.internal.SpiHelper; import io.opentelemetry.sdk.autoconfigure.spi.ConfigurationException; +import io.opentelemetry.sdk.extension.incubator.fileconfig.component.TextMapPropagatorComponentProvider; +import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.List; @@ -68,12 +70,28 @@ void create_NoneAndOther() { } @Test - void create_UnknownSpiPropagator() { + void create_SpiPropagator_Unknown() { assertThatThrownBy( () -> TextMapPropagatorFactory.getInstance() .create(Collections.singletonList("foo"), spiHelper, Collections.emptyList())) .isInstanceOf(ConfigurationException.class) - .hasMessage("Unrecognized propagator: foo"); + .hasMessage( + "No component provider detected for io.opentelemetry.context.propagation.TextMapPropagator with name \"foo\"."); + } + + @Test + void create_SpiPropagator_Valid() { + TextMapPropagator textMapPropagator = + TextMapPropagatorFactory.getInstance() + .create(Collections.singletonList("test"), spiHelper, new ArrayList<>()); + assertThat(textMapPropagator) + .isInstanceOfSatisfying( + TextMapPropagatorComponentProvider.TestTextMapPropagator.class, + testTextMapPropagator -> + assertThat(testTextMapPropagator.config) + .isInstanceOfSatisfying( + YamlStructuredConfigProperties.class, + config -> assertThat(config.getPropertyKeys()).isEmpty())); } } diff --git a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/component/TextMapPropagatorComponentProvider.java b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/component/TextMapPropagatorComponentProvider.java new file mode 100644 index 00000000000..a3005beba4b --- /dev/null +++ b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/component/TextMapPropagatorComponentProvider.java @@ -0,0 +1,55 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.sdk.extension.incubator.fileconfig.component; + +import io.opentelemetry.context.Context; +import io.opentelemetry.context.propagation.TextMapGetter; +import io.opentelemetry.context.propagation.TextMapPropagator; +import io.opentelemetry.context.propagation.TextMapSetter; +import io.opentelemetry.sdk.autoconfigure.spi.internal.ComponentProvider; +import io.opentelemetry.sdk.autoconfigure.spi.internal.StructuredConfigProperties; +import java.util.Collection; +import java.util.Collections; +import javax.annotation.Nullable; + +public class TextMapPropagatorComponentProvider implements ComponentProvider { + @Override + public Class getType() { + return TextMapPropagator.class; + } + + @Override + public String getName() { + return "test"; + } + + @Override + public TextMapPropagator create(StructuredConfigProperties config) { + return new TestTextMapPropagator(config); + } + + public static class TestTextMapPropagator implements TextMapPropagator { + + public final StructuredConfigProperties config; + + private TestTextMapPropagator(StructuredConfigProperties config) { + this.config = config; + } + + @Override + public Collection fields() { + return Collections.emptyList(); + } + + @Override + public void inject(Context context, @Nullable C carrier, TextMapSetter setter) {} + + @Override + public Context extract(Context context, @Nullable C carrier, TextMapGetter getter) { + return context; + } + } +} diff --git a/sdk-extensions/incubator/src/test/resources/META-INF/services/io.opentelemetry.sdk.autoconfigure.spi.internal.ComponentProvider b/sdk-extensions/incubator/src/test/resources/META-INF/services/io.opentelemetry.sdk.autoconfigure.spi.internal.ComponentProvider index 2bc161f4d9c..bf04a784ecd 100644 --- a/sdk-extensions/incubator/src/test/resources/META-INF/services/io.opentelemetry.sdk.autoconfigure.spi.internal.ComponentProvider +++ b/sdk-extensions/incubator/src/test/resources/META-INF/services/io.opentelemetry.sdk.autoconfigure.spi.internal.ComponentProvider @@ -1,6 +1,7 @@ io.opentelemetry.sdk.extension.incubator.fileconfig.component.MetricExporterComponentProvider io.opentelemetry.sdk.extension.incubator.fileconfig.component.SpanExporterComponentProvider io.opentelemetry.sdk.extension.incubator.fileconfig.component.LogRecordExporterComponentProvider +io.opentelemetry.sdk.extension.incubator.fileconfig.component.TextMapPropagatorComponentProvider io.opentelemetry.sdk.extension.incubator.fileconfig.component.SamplerComponentProvider io.opentelemetry.sdk.extension.incubator.fileconfig.component.SpanProcessorComponentProvider io.opentelemetry.sdk.extension.incubator.fileconfig.component.LogRecordProcessorComponentProvider From 649f963a1aca37289e3e8e6c19e88a2b1c2b3052 Mon Sep 17 00:00:00 2001 From: jack-berg <34418638+jack-berg@users.noreply.github.com> Date: Fri, 30 Aug 2024 10:22:38 -0500 Subject: [PATCH 539/901] Stabilize log any value (#6591) --- .../io/opentelemetry/api/common/KeyValue.java | 25 ++ .../api/common/KeyValueImpl.java | 18 ++ .../api/common/KeyValueList.java | 75 ++++++ .../io/opentelemetry/api/common/Value.java | 117 +++++++++ .../opentelemetry/api/common/ValueArray.java | 67 ++++++ .../api/common/ValueBoolean.java} | 18 +- .../opentelemetry/api/common/ValueBytes.java} | 18 +- .../api/common/ValueDouble.java} | 18 +- .../opentelemetry/api/common/ValueLong.java} | 18 +- .../api/common/ValueString.java} | 18 +- .../opentelemetry/api/common/ValueType.java} | 4 +- .../opentelemetry/api/logs/DefaultLogger.java | 6 + .../api/logs/LogRecordBuilder.java | 13 +- .../api/logs/DefaultLoggerTest.java | 2 + .../io/opentelemetry/api/logs/ValueTest.java | 215 +++++++++++++++++ api/incubator/README.md | 7 +- .../incubator/events/DefaultEventLogger.java | 4 +- .../api/incubator/events/EventBuilder.java | 51 ++-- .../api/incubator/logs/AnyValue.java | 111 --------- .../api/incubator/logs/AnyValueArray.java | 67 ------ .../logs/ExtendedLogRecordBuilder.java | 4 +- .../api/incubator/logs/KeyAnyValue.java | 25 -- .../api/incubator/logs/KeyAnyValueImpl.java | 18 -- .../api/incubator/logs/KeyAnyValueList.java | 75 ------ .../events/DefaultEventLoggerTest.java | 12 +- .../incubator/events/EventApiUsageTest.java | 25 +- .../api/incubator/logs/AnyValueTest.java | 222 ------------------ .../logs/ExtendedLogsBridgeApiUsageTest.java | 56 ----- .../otel.japicmp-conventions.gradle.kts | 13 +- .../current_vs_latest/opentelemetry-api.txt | 41 +++- .../opentelemetry-sdk-logs.txt | 15 +- .../opentelemetry-sdk-testing.txt | 15 +- .../logging/SystemOutLogRecordExporter.java | 4 +- .../otlp/LogsRequestMarshalerBenchmark.java | 7 +- .../internal/otlp/AnyValueMarshaler.java | 24 +- .../otlp/AnyValueStatelessMarshaler.java | 18 +- .../internal/otlp/ArrayAnyValueMarshaler.java | 4 +- .../otlp/ArrayAnyValueStatelessMarshaler.java | 8 +- .../otlp/KeyValueListAnyValueMarshaler.java | 6 +- ...eyValueListAnyValueStatelessMarshaler.java | 9 +- .../internal/otlp/KeyValueMarshaler.java | 21 +- .../otlp/KeyValueStatelessMarshaler.java | 28 ++- .../internal/otlp/logs/LogMarshaler.java | 37 +-- .../otlp/logs/LogStatelessMarshaler.java | 67 +----- ...halerTest.java => ValueMarshalerTest.java} | 29 ++- .../OtlpExporterIntegrationTest.java | 65 ++--- .../sdk/logs/SdkLogRecordBuilder.java | 13 +- .../sdk/logs/SdkLogRecordData.java | 21 +- .../sdk/logs/SdkReadWriteLogRecord.java | 8 +- .../io/opentelemetry/sdk/logs/data/Body.java | 28 ++- .../sdk/logs/data/EmptyBody.java | 1 + .../sdk/logs/data/LogRecordData.java | 20 +- .../sdk/logs/data/StringBody.java | 1 + .../sdk/logs/internal/AnyValueBody.java | 43 ---- .../sdk/logs/internal/SdkEventBuilder.java | 8 +- .../sdk/logs/AnyValueBodyTest.java | 156 ------------ .../sdk/logs/ReadWriteLogRecordTest.java | 4 +- .../sdk/logs/SdkLogRecordBuilderTest.java | 4 +- .../opentelemetry/sdk/logs/ValueBodyTest.java | 171 ++++++++++++++ .../opentelemetry/sdk/logs/data/BodyTest.java | 1 + .../internal/SdkEventLoggerProviderTest.java | 69 +++--- .../testing/assertj/LogRecordDataAssert.java | 17 +- .../sdk/testing/logs/TestLogRecordData.java | 38 ++- .../testing/junit4/OpenTelemetryRuleTest.java | 9 +- .../junit5/OpenTelemetryExtensionTest.java | 9 +- 65 files changed, 1185 insertions(+), 1156 deletions(-) create mode 100644 api/all/src/main/java/io/opentelemetry/api/common/KeyValue.java create mode 100644 api/all/src/main/java/io/opentelemetry/api/common/KeyValueImpl.java create mode 100644 api/all/src/main/java/io/opentelemetry/api/common/KeyValueList.java create mode 100644 api/all/src/main/java/io/opentelemetry/api/common/Value.java create mode 100644 api/all/src/main/java/io/opentelemetry/api/common/ValueArray.java rename api/{incubator/src/main/java/io/opentelemetry/api/incubator/logs/AnyValueBoolean.java => all/src/main/java/io/opentelemetry/api/common/ValueBoolean.java} (55%) rename api/{incubator/src/main/java/io/opentelemetry/api/incubator/logs/AnyValueBytes.java => all/src/main/java/io/opentelemetry/api/common/ValueBytes.java} (61%) rename api/{incubator/src/main/java/io/opentelemetry/api/incubator/logs/AnyValueDouble.java => all/src/main/java/io/opentelemetry/api/common/ValueDouble.java} (56%) rename api/{incubator/src/main/java/io/opentelemetry/api/incubator/logs/AnyValueLong.java => all/src/main/java/io/opentelemetry/api/common/ValueLong.java} (56%) rename api/{incubator/src/main/java/io/opentelemetry/api/incubator/logs/AnyValueString.java => all/src/main/java/io/opentelemetry/api/common/ValueString.java} (58%) rename api/{incubator/src/main/java/io/opentelemetry/api/incubator/logs/AnyValueType.java => all/src/main/java/io/opentelemetry/api/common/ValueType.java} (84%) create mode 100644 api/all/src/test/java/io/opentelemetry/api/logs/ValueTest.java delete mode 100644 api/incubator/src/main/java/io/opentelemetry/api/incubator/logs/AnyValue.java delete mode 100644 api/incubator/src/main/java/io/opentelemetry/api/incubator/logs/AnyValueArray.java delete mode 100644 api/incubator/src/main/java/io/opentelemetry/api/incubator/logs/KeyAnyValue.java delete mode 100644 api/incubator/src/main/java/io/opentelemetry/api/incubator/logs/KeyAnyValueImpl.java delete mode 100644 api/incubator/src/main/java/io/opentelemetry/api/incubator/logs/KeyAnyValueList.java delete mode 100644 api/incubator/src/test/java/io/opentelemetry/api/incubator/logs/AnyValueTest.java rename exporters/otlp/common/src/test/java/io/opentelemetry/exporter/internal/otlp/{AnyValueMarshalerTest.java => ValueMarshalerTest.java} (89%) delete mode 100644 sdk/logs/src/main/java/io/opentelemetry/sdk/logs/internal/AnyValueBody.java delete mode 100644 sdk/logs/src/test/java/io/opentelemetry/sdk/logs/AnyValueBodyTest.java create mode 100644 sdk/logs/src/test/java/io/opentelemetry/sdk/logs/ValueBodyTest.java diff --git a/api/all/src/main/java/io/opentelemetry/api/common/KeyValue.java b/api/all/src/main/java/io/opentelemetry/api/common/KeyValue.java new file mode 100644 index 00000000000..341b9d1227a --- /dev/null +++ b/api/all/src/main/java/io/opentelemetry/api/common/KeyValue.java @@ -0,0 +1,25 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.api.common; + +/** + * Key-value pair of {@link String} key and {@link Value} value. + * + * @see Value#of(KeyValue...) + */ +public interface KeyValue { + + /** Returns a {@link KeyValue} for the given {@code key} and {@code value}. */ + static KeyValue of(String key, Value value) { + return KeyValueImpl.create(key, value); + } + + /** Returns the key. */ + String getKey(); + + /** Returns the value. */ + Value getValue(); +} diff --git a/api/all/src/main/java/io/opentelemetry/api/common/KeyValueImpl.java b/api/all/src/main/java/io/opentelemetry/api/common/KeyValueImpl.java new file mode 100644 index 00000000000..1525c3f3c69 --- /dev/null +++ b/api/all/src/main/java/io/opentelemetry/api/common/KeyValueImpl.java @@ -0,0 +1,18 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.api.common; + +import com.google.auto.value.AutoValue; + +@AutoValue +abstract class KeyValueImpl implements KeyValue { + + KeyValueImpl() {} + + static KeyValueImpl create(String key, Value value) { + return new AutoValue_KeyValueImpl(key, value); + } +} diff --git a/api/all/src/main/java/io/opentelemetry/api/common/KeyValueList.java b/api/all/src/main/java/io/opentelemetry/api/common/KeyValueList.java new file mode 100644 index 00000000000..42801205564 --- /dev/null +++ b/api/all/src/main/java/io/opentelemetry/api/common/KeyValueList.java @@ -0,0 +1,75 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.api.common; + +import static java.util.stream.Collectors.joining; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.Objects; + +final class KeyValueList implements Value> { + + private final List value; + + private KeyValueList(List value) { + this.value = value; + } + + static Value> create(KeyValue... value) { + Objects.requireNonNull(value, "value must not be null"); + List list = new ArrayList<>(value.length); + list.addAll(Arrays.asList(value)); + return new KeyValueList(Collections.unmodifiableList(list)); + } + + static Value> createFromMap(Map> value) { + Objects.requireNonNull(value, "value must not be null"); + KeyValue[] array = + value.entrySet().stream() + .map(entry -> KeyValue.of(entry.getKey(), entry.getValue())) + .toArray(KeyValue[]::new); + return create(array); + } + + @Override + public ValueType getType() { + return ValueType.KEY_VALUE_LIST; + } + + @Override + public List getValue() { + return value; + } + + @Override + public String asString() { + return value.stream() + .map(item -> item.getKey() + "=" + item.getValue().asString()) + .collect(joining(", ", "[", "]")); + } + + @Override + public String toString() { + return "KeyValueList{" + asString() + "}"; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + return (o instanceof Value) && Objects.equals(this.value, ((Value) o).getValue()); + } + + @Override + public int hashCode() { + return value.hashCode(); + } +} diff --git a/api/all/src/main/java/io/opentelemetry/api/common/Value.java b/api/all/src/main/java/io/opentelemetry/api/common/Value.java new file mode 100644 index 00000000000..68da725010b --- /dev/null +++ b/api/all/src/main/java/io/opentelemetry/api/common/Value.java @@ -0,0 +1,117 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.api.common; + +import java.nio.ByteBuffer; +import java.util.List; +import java.util.Map; + +/** + * Value mirrors the proto AnyValue + * message type, and is used to model any type. + * + *

      It can be used to represent: + * + *

        + *
      • Primitive values via {@link #of(long)}, {@link #of(String)}, {@link #of(boolean)}, {@link + * #of(double)}. + *
      • String-keyed maps (i.e. associative arrays, dictionaries) via {@link #of(KeyValue...)}, + * {@link #of(Map)}. Note, because map values are type {@link Value}, maps can be nested + * within other maps. + *
      • Arrays (heterogeneous or homogenous) via {@link #of(Value[])}. Note, because array values + * are type {@link Value}, arrays can contain primitives, complex types like maps or arrays, + * or any combination. + *
      • Raw bytes via {@link #of(byte[])} + *
      + * + *

      Currently, Value is only used as an argument for {@link + * io.opentelemetry.api.logs.LogRecordBuilder#setBody(Value)}. + * + * @param the type. See {@link #getValue()} for description of types. + */ +public interface Value { + + /** Returns an {@link Value} for the {@link String} value. */ + static Value of(String value) { + return ValueString.create(value); + } + + /** Returns an {@link Value} for the {@code boolean} value. */ + static Value of(boolean value) { + return ValueBoolean.create(value); + } + + /** Returns an {@link Value} for the {@code long} value. */ + static Value of(long value) { + return ValueLong.create(value); + } + + /** Returns an {@link Value} for the {@code double} value. */ + static Value of(double value) { + return ValueDouble.create(value); + } + + /** Returns an {@link Value} for the {@code byte[]} value. */ + static Value of(byte[] value) { + return ValueBytes.create(value); + } + + /** Returns an {@link Value} for the array of {@link Value} values. */ + static Value>> of(Value... value) { + return ValueArray.create(value); + } + + /** Returns an {@link Value} for the list of {@link Value} values. */ + static Value>> of(List> value) { + return ValueArray.create(value); + } + + /** + * Returns an {@link Value} for the array of {@link KeyValue} values. {@link KeyValue#getKey()} + * values should not repeat - duplicates may be dropped. + */ + static Value> of(KeyValue... value) { + return KeyValueList.create(value); + } + + /** Returns an {@link Value} for the {@link Map} of key, {@link Value}. */ + static Value> of(Map> value) { + return KeyValueList.createFromMap(value); + } + + /** Returns the type of this {@link Value}. Useful for building switch statements. */ + ValueType getType(); + + /** + * Returns the value for this {@link Value}. + * + *

      The return type varies by {@link #getType()} as described below: + * + *

        + *
      • {@link ValueType#STRING} returns {@link String} + *
      • {@link ValueType#BOOLEAN} returns {@code boolean} + *
      • {@link ValueType#LONG} returns {@code long} + *
      • {@link ValueType#DOUBLE} returns {@code double} + *
      • {@link ValueType#ARRAY} returns {@link List} of {@link Value} + *
      • {@link ValueType#KEY_VALUE_LIST} returns {@link List} of {@link KeyValue} + *
      • {@link ValueType#BYTES} returns read only {@link ByteBuffer}. See {@link + * ByteBuffer#asReadOnlyBuffer()}. + *
      + */ + T getValue(); + + /** + * Return a string encoding of this {@link Value}. This is intended to be a fallback serialized + * representation in case there is no suitable encoding that can utilize {@link #getType()} / + * {@link #getValue()} to serialize specific types. + * + *

      WARNING: No guarantees are made about the encoding of this string response. It MAY change in + * a future minor release. If you need a reliable string encoding, write your own serializer. + */ + // TODO(jack-berg): Should this be a JSON encoding? + String asString(); +} diff --git a/api/all/src/main/java/io/opentelemetry/api/common/ValueArray.java b/api/all/src/main/java/io/opentelemetry/api/common/ValueArray.java new file mode 100644 index 00000000000..55c9e5f42b7 --- /dev/null +++ b/api/all/src/main/java/io/opentelemetry/api/common/ValueArray.java @@ -0,0 +1,67 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.api.common; + +import static java.util.stream.Collectors.joining; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import java.util.Objects; + +final class ValueArray implements Value>> { + + private final List> value; + + private ValueArray(List> value) { + this.value = value; + } + + static Value>> create(Value... value) { + Objects.requireNonNull(value, "value must not be null"); + List> list = new ArrayList<>(value.length); + list.addAll(Arrays.asList(value)); + return new ValueArray(Collections.unmodifiableList(list)); + } + + static Value>> create(List> value) { + return new ValueArray(Collections.unmodifiableList(value)); + } + + @Override + public ValueType getType() { + return ValueType.ARRAY; + } + + @Override + public List> getValue() { + return value; + } + + @Override + public String asString() { + return value.stream().map(Value::asString).collect(joining(", ", "[", "]")); + } + + @Override + public String toString() { + return "ValueArray{" + asString() + "}"; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + return (o instanceof Value) && Objects.equals(this.value, ((Value) o).getValue()); + } + + @Override + public int hashCode() { + return value.hashCode(); + } +} diff --git a/api/incubator/src/main/java/io/opentelemetry/api/incubator/logs/AnyValueBoolean.java b/api/all/src/main/java/io/opentelemetry/api/common/ValueBoolean.java similarity index 55% rename from api/incubator/src/main/java/io/opentelemetry/api/incubator/logs/AnyValueBoolean.java rename to api/all/src/main/java/io/opentelemetry/api/common/ValueBoolean.java index fcaa7525241..a4364d414df 100644 --- a/api/incubator/src/main/java/io/opentelemetry/api/incubator/logs/AnyValueBoolean.java +++ b/api/all/src/main/java/io/opentelemetry/api/common/ValueBoolean.java @@ -3,25 +3,25 @@ * SPDX-License-Identifier: Apache-2.0 */ -package io.opentelemetry.api.incubator.logs; +package io.opentelemetry.api.common; import java.util.Objects; -final class AnyValueBoolean implements AnyValue { +final class ValueBoolean implements Value { private final boolean value; - private AnyValueBoolean(boolean value) { + private ValueBoolean(boolean value) { this.value = value; } - static AnyValue create(boolean value) { - return new AnyValueBoolean(value); + static Value create(boolean value) { + return new ValueBoolean(value); } @Override - public AnyValueType getType() { - return AnyValueType.BOOLEAN; + public ValueType getType() { + return ValueType.BOOLEAN; } @Override @@ -36,7 +36,7 @@ public String asString() { @Override public String toString() { - return "AnyValueBoolean{" + asString() + "}"; + return "ValueBoolean{" + asString() + "}"; } @Override @@ -44,7 +44,7 @@ public boolean equals(Object o) { if (this == o) { return true; } - return (o instanceof AnyValue) && Objects.equals(this.value, ((AnyValue) o).getValue()); + return (o instanceof Value) && Objects.equals(this.value, ((Value) o).getValue()); } @Override diff --git a/api/incubator/src/main/java/io/opentelemetry/api/incubator/logs/AnyValueBytes.java b/api/all/src/main/java/io/opentelemetry/api/common/ValueBytes.java similarity index 61% rename from api/incubator/src/main/java/io/opentelemetry/api/incubator/logs/AnyValueBytes.java rename to api/all/src/main/java/io/opentelemetry/api/common/ValueBytes.java index 4f572dee172..8d925cd174d 100644 --- a/api/incubator/src/main/java/io/opentelemetry/api/incubator/logs/AnyValueBytes.java +++ b/api/all/src/main/java/io/opentelemetry/api/common/ValueBytes.java @@ -3,29 +3,29 @@ * SPDX-License-Identifier: Apache-2.0 */ -package io.opentelemetry.api.incubator.logs; +package io.opentelemetry.api.common; import java.nio.ByteBuffer; import java.util.Arrays; import java.util.Base64; import java.util.Objects; -final class AnyValueBytes implements AnyValue { +final class ValueBytes implements Value { private final byte[] raw; - private AnyValueBytes(byte[] value) { + private ValueBytes(byte[] value) { this.raw = value; } - static AnyValue create(byte[] value) { + static Value create(byte[] value) { Objects.requireNonNull(value, "value must not be null"); - return new AnyValueBytes(Arrays.copyOf(value, value.length)); + return new ValueBytes(Arrays.copyOf(value, value.length)); } @Override - public AnyValueType getType() { - return AnyValueType.BYTES; + public ValueType getType() { + return ValueType.BYTES; } @Override @@ -40,7 +40,7 @@ public String asString() { @Override public String toString() { - return "AnyValueBytes{" + asString() + "}"; + return "ValueBytes{" + asString() + "}"; } @Override @@ -48,7 +48,7 @@ public boolean equals(Object o) { if (this == o) { return true; } - return (o instanceof AnyValueBytes) && Arrays.equals(this.raw, ((AnyValueBytes) o).raw); + return (o instanceof ValueBytes) && Arrays.equals(this.raw, ((ValueBytes) o).raw); } @Override diff --git a/api/incubator/src/main/java/io/opentelemetry/api/incubator/logs/AnyValueDouble.java b/api/all/src/main/java/io/opentelemetry/api/common/ValueDouble.java similarity index 56% rename from api/incubator/src/main/java/io/opentelemetry/api/incubator/logs/AnyValueDouble.java rename to api/all/src/main/java/io/opentelemetry/api/common/ValueDouble.java index e1ab55f8528..21f13dd7e78 100644 --- a/api/incubator/src/main/java/io/opentelemetry/api/incubator/logs/AnyValueDouble.java +++ b/api/all/src/main/java/io/opentelemetry/api/common/ValueDouble.java @@ -3,25 +3,25 @@ * SPDX-License-Identifier: Apache-2.0 */ -package io.opentelemetry.api.incubator.logs; +package io.opentelemetry.api.common; import java.util.Objects; -final class AnyValueDouble implements AnyValue { +final class ValueDouble implements Value { private final double value; - private AnyValueDouble(double value) { + private ValueDouble(double value) { this.value = value; } - static AnyValue create(double value) { - return new AnyValueDouble(value); + static Value create(double value) { + return new ValueDouble(value); } @Override - public AnyValueType getType() { - return AnyValueType.DOUBLE; + public ValueType getType() { + return ValueType.DOUBLE; } @Override @@ -36,7 +36,7 @@ public String asString() { @Override public String toString() { - return "AnyValueDouble{" + asString() + "}"; + return "ValueDouble{" + asString() + "}"; } @Override @@ -44,7 +44,7 @@ public boolean equals(Object o) { if (this == o) { return true; } - return (o instanceof AnyValue) && Objects.equals(this.value, ((AnyValue) o).getValue()); + return (o instanceof Value) && Objects.equals(this.value, ((Value) o).getValue()); } @Override diff --git a/api/incubator/src/main/java/io/opentelemetry/api/incubator/logs/AnyValueLong.java b/api/all/src/main/java/io/opentelemetry/api/common/ValueLong.java similarity index 56% rename from api/incubator/src/main/java/io/opentelemetry/api/incubator/logs/AnyValueLong.java rename to api/all/src/main/java/io/opentelemetry/api/common/ValueLong.java index 0cc1d3beafa..8cd1bca4bf9 100644 --- a/api/incubator/src/main/java/io/opentelemetry/api/incubator/logs/AnyValueLong.java +++ b/api/all/src/main/java/io/opentelemetry/api/common/ValueLong.java @@ -3,25 +3,25 @@ * SPDX-License-Identifier: Apache-2.0 */ -package io.opentelemetry.api.incubator.logs; +package io.opentelemetry.api.common; import java.util.Objects; -final class AnyValueLong implements AnyValue { +final class ValueLong implements Value { private final long value; - private AnyValueLong(long value) { + private ValueLong(long value) { this.value = value; } - static AnyValue create(long value) { - return new AnyValueLong(value); + static Value create(long value) { + return new ValueLong(value); } @Override - public AnyValueType getType() { - return AnyValueType.LONG; + public ValueType getType() { + return ValueType.LONG; } @Override @@ -36,7 +36,7 @@ public String asString() { @Override public String toString() { - return "AnyValueLong{" + asString() + "}"; + return "ValueLong{" + asString() + "}"; } @Override @@ -44,7 +44,7 @@ public boolean equals(Object o) { if (this == o) { return true; } - return (o instanceof AnyValue) && Objects.equals(this.value, ((AnyValue) o).getValue()); + return (o instanceof Value) && Objects.equals(this.value, ((Value) o).getValue()); } @Override diff --git a/api/incubator/src/main/java/io/opentelemetry/api/incubator/logs/AnyValueString.java b/api/all/src/main/java/io/opentelemetry/api/common/ValueString.java similarity index 58% rename from api/incubator/src/main/java/io/opentelemetry/api/incubator/logs/AnyValueString.java rename to api/all/src/main/java/io/opentelemetry/api/common/ValueString.java index d2b8be2e729..726cb27dee3 100644 --- a/api/incubator/src/main/java/io/opentelemetry/api/incubator/logs/AnyValueString.java +++ b/api/all/src/main/java/io/opentelemetry/api/common/ValueString.java @@ -3,26 +3,26 @@ * SPDX-License-Identifier: Apache-2.0 */ -package io.opentelemetry.api.incubator.logs; +package io.opentelemetry.api.common; import java.util.Objects; -final class AnyValueString implements AnyValue { +final class ValueString implements Value { private final String value; - private AnyValueString(String value) { + private ValueString(String value) { this.value = value; } - static AnyValue create(String value) { + static Value create(String value) { Objects.requireNonNull(value, "value must not be null"); - return new AnyValueString(value); + return new ValueString(value); } @Override - public AnyValueType getType() { - return AnyValueType.STRING; + public ValueType getType() { + return ValueType.STRING; } @Override @@ -37,7 +37,7 @@ public String asString() { @Override public String toString() { - return "AnyValueString{" + value + "}"; + return "ValueString{" + value + "}"; } @Override @@ -45,7 +45,7 @@ public boolean equals(Object o) { if (this == o) { return true; } - return (o instanceof AnyValue) && Objects.equals(this.value, ((AnyValue) o).getValue()); + return (o instanceof Value) && Objects.equals(this.value, ((Value) o).getValue()); } @Override diff --git a/api/incubator/src/main/java/io/opentelemetry/api/incubator/logs/AnyValueType.java b/api/all/src/main/java/io/opentelemetry/api/common/ValueType.java similarity index 84% rename from api/incubator/src/main/java/io/opentelemetry/api/incubator/logs/AnyValueType.java rename to api/all/src/main/java/io/opentelemetry/api/common/ValueType.java index ea41d887094..99980280d2c 100644 --- a/api/incubator/src/main/java/io/opentelemetry/api/incubator/logs/AnyValueType.java +++ b/api/all/src/main/java/io/opentelemetry/api/common/ValueType.java @@ -3,14 +3,14 @@ * SPDX-License-Identifier: Apache-2.0 */ -package io.opentelemetry.api.incubator.logs; +package io.opentelemetry.api.common; /** * AnyValue type options, mirroring AnyValue#value * options. */ -public enum AnyValueType { +public enum ValueType { STRING, BOOLEAN, LONG, diff --git a/api/all/src/main/java/io/opentelemetry/api/logs/DefaultLogger.java b/api/all/src/main/java/io/opentelemetry/api/logs/DefaultLogger.java index 47644104dcb..56284b43cb2 100644 --- a/api/all/src/main/java/io/opentelemetry/api/logs/DefaultLogger.java +++ b/api/all/src/main/java/io/opentelemetry/api/logs/DefaultLogger.java @@ -6,6 +6,7 @@ package io.opentelemetry.api.logs; import io.opentelemetry.api.common.AttributeKey; +import io.opentelemetry.api.common.Value; import io.opentelemetry.context.Context; import java.time.Instant; import java.util.concurrent.TimeUnit; @@ -70,6 +71,11 @@ public LogRecordBuilder setBody(String body) { return this; } + @Override + public LogRecordBuilder setBody(Value body) { + return this; + } + @Override public LogRecordBuilder setAttribute(AttributeKey key, T value) { return this; diff --git a/api/all/src/main/java/io/opentelemetry/api/logs/LogRecordBuilder.java b/api/all/src/main/java/io/opentelemetry/api/logs/LogRecordBuilder.java index 1b7e24d19a9..392796065d9 100644 --- a/api/all/src/main/java/io/opentelemetry/api/logs/LogRecordBuilder.java +++ b/api/all/src/main/java/io/opentelemetry/api/logs/LogRecordBuilder.java @@ -7,6 +7,7 @@ import io.opentelemetry.api.common.AttributeKey; import io.opentelemetry.api.common.Attributes; +import io.opentelemetry.api.common.Value; import io.opentelemetry.context.Context; import java.time.Instant; import java.util.concurrent.TimeUnit; @@ -66,9 +67,19 @@ public interface LogRecordBuilder { /** Set the severity text. */ LogRecordBuilder setSeverityText(String severityText); - /** Set the body string. */ + /** + * Set the body string. + * + *

      Shorthand for calling {@link #setBody(Value)} with {@link Value#of(String)}. + */ LogRecordBuilder setBody(String body); + /** Set the body {@link Value}. */ + default LogRecordBuilder setBody(Value body) { + setBody(body.asString()); + return this; + } + /** * Sets attributes. If the {@link LogRecordBuilder} previously contained a mapping for any of the * keys, the old values are replaced by the specified values. diff --git a/api/all/src/test/java/io/opentelemetry/api/logs/DefaultLoggerTest.java b/api/all/src/test/java/io/opentelemetry/api/logs/DefaultLoggerTest.java index 9f43ab22b87..ffe68f37e95 100644 --- a/api/all/src/test/java/io/opentelemetry/api/logs/DefaultLoggerTest.java +++ b/api/all/src/test/java/io/opentelemetry/api/logs/DefaultLoggerTest.java @@ -9,6 +9,7 @@ import io.opentelemetry.api.common.AttributeKey; import io.opentelemetry.api.common.Attributes; +import io.opentelemetry.api.common.Value; import io.opentelemetry.context.Context; import java.time.Instant; import java.util.concurrent.TimeUnit; @@ -30,6 +31,7 @@ void buildAndEmit() { .setSeverity(Severity.DEBUG) .setSeverityText("debug") .setBody("body") + .setBody(Value.of("body")) .setAttribute(AttributeKey.stringKey("key1"), "value1") .setAllAttributes(Attributes.builder().put("key2", "value2").build()) .emit()) diff --git a/api/all/src/test/java/io/opentelemetry/api/logs/ValueTest.java b/api/all/src/test/java/io/opentelemetry/api/logs/ValueTest.java new file mode 100644 index 00000000000..ae83e0dd44c --- /dev/null +++ b/api/all/src/test/java/io/opentelemetry/api/logs/ValueTest.java @@ -0,0 +1,215 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.api.logs; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.junit.jupiter.params.provider.Arguments.arguments; + +import io.opentelemetry.api.common.KeyValue; +import io.opentelemetry.api.common.Value; +import io.opentelemetry.api.common.ValueType; +import java.nio.ByteBuffer; +import java.nio.ReadOnlyBufferException; +import java.nio.charset.StandardCharsets; +import java.util.Arrays; +import java.util.Base64; +import java.util.Collections; +import java.util.LinkedHashMap; +import java.util.Map; +import java.util.stream.Stream; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; + +class ValueTest { + + @Test + void value_OfString() { + assertThat(Value.of("foo")) + .satisfies( + value -> { + assertThat(value.getType()).isEqualTo(ValueType.STRING); + assertThat(value.getValue()).isEqualTo("foo"); + assertThat(value).hasSameHashCodeAs(Value.of("foo")); + }); + } + + @Test + void value_OfBoolean() { + assertThat(Value.of(true)) + .satisfies( + value -> { + assertThat(value.getType()).isEqualTo(ValueType.BOOLEAN); + assertThat(value.getValue()).isEqualTo(true); + assertThat(value).hasSameHashCodeAs(Value.of(true)); + }); + } + + @Test + void value_OfLong() { + assertThat(Value.of(1L)) + .satisfies( + value -> { + assertThat(value.getType()).isEqualTo(ValueType.LONG); + assertThat(value.getValue()).isEqualTo(1L); + assertThat(value).hasSameHashCodeAs(Value.of(1L)); + }); + } + + @Test + void value_OfDouble() { + assertThat(Value.of(1.1)) + .satisfies( + value -> { + assertThat(value.getType()).isEqualTo(ValueType.DOUBLE); + assertThat(value.getValue()).isEqualTo(1.1); + assertThat(value).hasSameHashCodeAs(Value.of(1.1)); + }); + } + + @Test + void value_OfByteArray() { + assertThat(Value.of(new byte[] {'a', 'b'})) + .satisfies( + value -> { + assertThat(value.getType()).isEqualTo(ValueType.BYTES); + ByteBuffer buf = value.getValue(); + // ValueBytes returns read only view of ByteBuffer + assertThatThrownBy(buf::array).isInstanceOf(ReadOnlyBufferException.class); + byte[] bytes = new byte[buf.remaining()]; + buf.get(bytes); + assertThat(bytes).isEqualTo(new byte[] {'a', 'b'}); + assertThat(value).hasSameHashCodeAs(Value.of(new byte[] {'a', 'b'})); + }); + } + + @Test + void value_OfvalueArray() { + assertThat(Value.of(Value.of(true), Value.of(1L))) + .satisfies( + value -> { + assertThat(value.getType()).isEqualTo(ValueType.ARRAY); + assertThat(value.getValue()).isEqualTo(Arrays.asList(Value.of(true), Value.of(1L))); + assertThat(value).hasSameHashCodeAs(Value.of(Value.of(true), Value.of(1L))); + }); + } + + @Test + @SuppressWarnings("DoubleBraceInitialization") + void value_OfKeyValueList() { + assertThat(Value.of(KeyValue.of("bool", Value.of(true)), KeyValue.of("long", Value.of(1L)))) + .satisfies( + value -> { + assertThat(value.getType()).isEqualTo(ValueType.KEY_VALUE_LIST); + assertThat(value.getValue()) + .isEqualTo( + Arrays.asList( + KeyValue.of("bool", Value.of(true)), KeyValue.of("long", Value.of(1L)))); + assertThat(value) + .hasSameHashCodeAs( + Value.of( + KeyValue.of("bool", Value.of(true)), KeyValue.of("long", Value.of(1L)))); + }); + + assertThat( + Value.of( + new LinkedHashMap>() { + { + put("bool", Value.of(true)); + put("long", Value.of(1L)); + } + })) + .satisfies( + value -> { + assertThat(value.getType()).isEqualTo(ValueType.KEY_VALUE_LIST); + assertThat(value.getValue()) + .isEqualTo( + Arrays.asList( + KeyValue.of("bool", Value.of(true)), KeyValue.of("long", Value.of(1L)))); + assertThat(value) + .hasSameHashCodeAs( + Value.of( + new LinkedHashMap>() { + { + put("bool", Value.of(true)); + put("long", Value.of(1L)); + } + })); + }); + } + + @Test + void value_NullsNotAllowed() { + assertThatThrownBy(() -> Value.of((String) null)) + .isInstanceOf(NullPointerException.class) + .hasMessageContaining("value must not be null"); + assertThatThrownBy(() -> Value.of((byte[]) null)) + .isInstanceOf(NullPointerException.class) + .hasMessageContaining("value must not be null"); + assertThatThrownBy(() -> Value.of((Value[]) null)) + .isInstanceOf(NullPointerException.class) + .hasMessageContaining("value must not be null"); + assertThatThrownBy(() -> Value.of((KeyValue[]) null)) + .isInstanceOf(NullPointerException.class) + .hasMessageContaining("value must not be null"); + assertThatThrownBy(() -> Value.of((Map>) null)) + .isInstanceOf(NullPointerException.class) + .hasMessageContaining("value must not be null"); + } + + @ParameterizedTest + @MethodSource("asStringArgs") + void asString(Value value, String expectedAsString) { + assertThat(value.asString()).isEqualTo(expectedAsString); + } + + @SuppressWarnings("DoubleBraceInitialization") + private static Stream asStringArgs() { + return Stream.of( + // primitives + arguments(Value.of("str"), "str"), + arguments(Value.of(true), "true"), + arguments(Value.of(1), "1"), + arguments(Value.of(1.1), "1.1"), + // heterogeneous array + arguments( + Value.of(Value.of("str"), Value.of(true), Value.of(1), Value.of(1.1)), + "[str, true, 1, 1.1]"), + // key value list from KeyValue array + arguments( + Value.of(KeyValue.of("key1", Value.of("val1")), KeyValue.of("key2", Value.of(2))), + "[key1=val1, key2=2]"), + // key value list from map + arguments( + Value.of( + new LinkedHashMap>() { + { + put("key1", Value.of("val1")); + put("key2", Value.of(2)); + } + }), + "[key1=val1, key2=2]"), + // map of map + arguments( + Value.of( + Collections.singletonMap( + "child", Value.of(Collections.singletonMap("grandchild", Value.of("str"))))), + "[child=[grandchild=str]]"), + // bytes + arguments(Value.of("hello world".getBytes(StandardCharsets.UTF_8)), "aGVsbG8gd29ybGQ=")); + } + + @Test + void valueByteAsString() { + // TODO: add more test cases + String str = "hello world"; + String base64Encoded = Value.of(str.getBytes(StandardCharsets.UTF_8)).asString(); + byte[] decodedBytes = Base64.getDecoder().decode(base64Encoded); + assertThat(new String(decodedBytes, StandardCharsets.UTF_8)).isEqualTo(str); + } +} diff --git a/api/incubator/README.md b/api/incubator/README.md index ccd4678df43..ee29241f9fe 100644 --- a/api/incubator/README.md +++ b/api/incubator/README.md @@ -14,8 +14,7 @@ See [EventApiUsageTest](./src/test/java/io/opentelemetry/api/incubator/events/Ev Features: -* Check if logger is enabled before emitting logs to avoid uneccessary computation -* Set AnyValue log record body with arbitrarily complex data +* Check if logger is enabled before emitting logs to avoid unnecessary computation See [ExtendedLogsBridgeApiUsageTest](./src/test/java/io/opentelemetry/api/incubator/logs/ExtendedLogsBridgeApiUsageTest.java). @@ -31,7 +30,7 @@ See [ExtendedMetricsApiUsageTest](./src/test/java/io/opentelemetry/api/incubator Features: -* Check if instrument is enabled before recording measurements to avoid uneccessary computation +* Check if instrument is enabled before recording measurements to avoid unnecessary computation * Simplified injection / extraction of context See [ExtendedContextPropagatorsUsageTest](./src/test/java/io/opentelemetry/api/incubator/propagation/ExtendedContextPropagatorsUsageTest.java). @@ -40,7 +39,7 @@ See [ExtendedContextPropagatorsUsageTest](./src/test/java/io/opentelemetry/api/i Features: -* Check if tracer is enabled before starting spans to avoid uneccessary computation +* Check if tracer is enabled before starting spans to avoid unnecessary computation * Utility methods to reduce boilerplace using span API, including extracting context, and wrapping runnables / callables with spans See [ExtendedTraceApiUsageTest](./src/test/java/io/opentelemetry/api/incubator/trace/ExtendedTraceApiUsageTest.java). diff --git a/api/incubator/src/main/java/io/opentelemetry/api/incubator/events/DefaultEventLogger.java b/api/incubator/src/main/java/io/opentelemetry/api/incubator/events/DefaultEventLogger.java index 8017965bf00..c0c795c584b 100644 --- a/api/incubator/src/main/java/io/opentelemetry/api/incubator/events/DefaultEventLogger.java +++ b/api/incubator/src/main/java/io/opentelemetry/api/incubator/events/DefaultEventLogger.java @@ -6,7 +6,7 @@ package io.opentelemetry.api.incubator.events; import io.opentelemetry.api.common.Attributes; -import io.opentelemetry.api.incubator.logs.AnyValue; +import io.opentelemetry.api.common.Value; import io.opentelemetry.api.logs.Severity; import io.opentelemetry.context.Context; import java.time.Instant; @@ -32,7 +32,7 @@ private static class NoOpEventBuilder implements EventBuilder { public static final EventBuilder INSTANCE = new NoOpEventBuilder(); @Override - public EventBuilder put(String key, AnyValue value) { + public EventBuilder put(String key, Value value) { return this; } diff --git a/api/incubator/src/main/java/io/opentelemetry/api/incubator/events/EventBuilder.java b/api/incubator/src/main/java/io/opentelemetry/api/incubator/events/EventBuilder.java index 9aca02b3077..a2c43a47a0e 100644 --- a/api/incubator/src/main/java/io/opentelemetry/api/incubator/events/EventBuilder.java +++ b/api/incubator/src/main/java/io/opentelemetry/api/incubator/events/EventBuilder.java @@ -9,7 +9,7 @@ import io.opentelemetry.api.common.AttributeKey; import io.opentelemetry.api.common.Attributes; -import io.opentelemetry.api.incubator.logs.AnyValue; +import io.opentelemetry.api.common.Value; import io.opentelemetry.api.logs.Severity; import io.opentelemetry.context.Context; import java.time.Instant; @@ -22,58 +22,58 @@ public interface EventBuilder { /** Put the given {@code key} and {@code value} in the payload. */ default EventBuilder put(String key, String value) { - return put(key, AnyValue.of(value)); + return put(key, Value.of(value)); } /** Put the given {@code key} and {@code value} in the payload. */ default EventBuilder put(String key, long value) { - return put(key, AnyValue.of(value)); + return put(key, Value.of(value)); } /** Put the given {@code key} and {@code value} in the payload. */ default EventBuilder put(String key, double value) { - return put(key, AnyValue.of(value)); + return put(key, Value.of(value)); } /** Put the given {@code key} and {@code value} in the payload. */ default EventBuilder put(String key, boolean value) { - return put(key, AnyValue.of(value)); + return put(key, Value.of(value)); } /** Put the given {@code key} and {@code value} in the payload. */ default EventBuilder put(String key, String... value) { - List> values = new ArrayList<>(value.length); + List> values = new ArrayList<>(value.length); for (String val : value) { - values.add(AnyValue.of(val)); + values.add(Value.of(val)); } - return put(key, AnyValue.of(values)); + return put(key, Value.of(values)); } /** Put the given {@code key} and {@code value} in the payload. */ default EventBuilder put(String key, long... value) { - List> values = new ArrayList<>(value.length); + List> values = new ArrayList<>(value.length); for (long val : value) { - values.add(AnyValue.of(val)); + values.add(Value.of(val)); } - return put(key, AnyValue.of(values)); + return put(key, Value.of(values)); } /** Put the given {@code key} and {@code value} in the payload. */ default EventBuilder put(String key, double... value) { - List> values = new ArrayList<>(value.length); + List> values = new ArrayList<>(value.length); for (double val : value) { - values.add(AnyValue.of(val)); + values.add(Value.of(val)); } - return put(key, AnyValue.of(values)); + return put(key, Value.of(values)); } /** Put the given {@code key} and {@code value} in the payload. */ default EventBuilder put(String key, boolean... value) { - List> values = new ArrayList<>(value.length); + List> values = new ArrayList<>(value.length); for (boolean val : value) { - values.add(AnyValue.of(val)); + values.add(Value.of(val)); } - return put(key, AnyValue.of(values)); + return put(key, Value.of(values)); } /** @@ -97,25 +97,24 @@ default EventBuilder put(AttributeKey key, T value) { case STRING_ARRAY: return put( key.getKey(), - AnyValue.of(((List) value).stream().map(AnyValue::of).collect(toList()))); + Value.of(((List) value).stream().map(Value::of).collect(toList()))); case BOOLEAN_ARRAY: return put( key.getKey(), - AnyValue.of(((List) value).stream().map(AnyValue::of).collect(toList()))); + Value.of(((List) value).stream().map(Value::of).collect(toList()))); case LONG_ARRAY: return put( - key.getKey(), - AnyValue.of(((List) value).stream().map(AnyValue::of).collect(toList()))); + key.getKey(), Value.of(((List) value).stream().map(Value::of).collect(toList()))); case DOUBLE_ARRAY: return put( key.getKey(), - AnyValue.of(((List) value).stream().map(AnyValue::of).collect(toList()))); + Value.of(((List) value).stream().map(Value::of).collect(toList()))); } return this; } /** Put the given {@code key} and {@code value} in the payload. */ - EventBuilder put(String key, AnyValue value); + EventBuilder put(String key, Value value); /** * Set the epoch {@code timestamp}, using the timestamp and unit. @@ -143,9 +142,9 @@ default EventBuilder put(AttributeKey key, T value) { * Set the attributes. * *

      Event {@link io.opentelemetry.api.common.Attributes} provide additional details about the - * Event which are not part of the well-defined {@link AnyValue} payload. Setting event attributes - * is less common than adding entries to the event payload. Most users will want to call one of - * the {@code #put(String, ?)} methods instead. + * Event which are not part of the well-defined {@link Value} payload. Setting event attributes is + * less common than adding entries to the event payload. Most users will want to call one of the + * {@code #put(String, ?)} methods instead. */ EventBuilder setAttributes(Attributes attributes); diff --git a/api/incubator/src/main/java/io/opentelemetry/api/incubator/logs/AnyValue.java b/api/incubator/src/main/java/io/opentelemetry/api/incubator/logs/AnyValue.java deleted file mode 100644 index 602e9e289b7..00000000000 --- a/api/incubator/src/main/java/io/opentelemetry/api/incubator/logs/AnyValue.java +++ /dev/null @@ -1,111 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package io.opentelemetry.api.incubator.logs; - -import java.nio.ByteBuffer; -import java.util.List; -import java.util.Map; - -/** - * AnyValue mirrors the proto AnyValue - * message type, and is used to model any type. - * - *

      It can be used to represent: - * - *

        - *
      • Primitive values via {@link #of(long)}, {@link #of(String)}, {@link #of(boolean)}, {@link - * #of(double)}. - *
      • String-keyed maps (i.e. associative arrays, dictionaries) via {@link #of(KeyAnyValue...)}, - * {@link #of(Map)}. Note, because map values are type {@link AnyValue}, maps can be nested - * within other maps. - *
      • Arrays (heterogeneous or homogenous) via {@link #of(AnyValue[])}. Note, because array - * values are type {@link AnyValue}, arrays can contain primitives, complex types like maps or - * arrays, or any combination. - *
      • Raw bytes via {@link #of(byte[])} - *
      - * - * @param the type. See {@link #getValue()} for description of types. - */ -public interface AnyValue { - - /** Returns an {@link AnyValue} for the {@link String} value. */ - static AnyValue of(String value) { - return AnyValueString.create(value); - } - - /** Returns an {@link AnyValue} for the {@code boolean} value. */ - static AnyValue of(boolean value) { - return AnyValueBoolean.create(value); - } - - /** Returns an {@link AnyValue} for the {@code long} value. */ - static AnyValue of(long value) { - return AnyValueLong.create(value); - } - - /** Returns an {@link AnyValue} for the {@code double} value. */ - static AnyValue of(double value) { - return AnyValueDouble.create(value); - } - - /** Returns an {@link AnyValue} for the {@code byte[]} value. */ - static AnyValue of(byte[] value) { - return AnyValueBytes.create(value); - } - - /** Returns an {@link AnyValue} for the array of {@link AnyValue} values. */ - static AnyValue>> of(AnyValue... value) { - return AnyValueArray.create(value); - } - - /** Returns an {@link AnyValue} for the list of {@link AnyValue} values. */ - static AnyValue>> of(List> value) { - return AnyValueArray.create(value); - } - - /** - * Returns an {@link AnyValue} for the array of {@link KeyAnyValue} values. {@link - * KeyAnyValue#getKey()} values should not repeat - duplicates may be dropped. - */ - static AnyValue> of(KeyAnyValue... value) { - return KeyAnyValueList.create(value); - } - - /** Returns an {@link AnyValue} for the {@link Map} of key, {@link AnyValue}. */ - static AnyValue> of(Map> value) { - return KeyAnyValueList.createFromMap(value); - } - - /** Returns the type of this {@link AnyValue}. Useful for building switch statements. */ - AnyValueType getType(); - - /** - * Returns the value for this {@link AnyValue}. - * - *

      The return type varies by {@link #getType()} as described below: - * - *

        - *
      • {@link AnyValueType#STRING} returns {@link String} - *
      • {@link AnyValueType#BOOLEAN} returns {@code boolean} - *
      • {@link AnyValueType#LONG} returns {@code long} - *
      • {@link AnyValueType#DOUBLE} returns {@code double} - *
      • {@link AnyValueType#ARRAY} returns {@link List} of {@link AnyValue} - *
      • {@link AnyValueType#KEY_VALUE_LIST} returns {@link List} of {@link KeyAnyValue} - *
      • {@link AnyValueType#BYTES} returns read only {@link ByteBuffer}. See {@link - * ByteBuffer#asReadOnlyBuffer()}. - *
      - */ - T getValue(); - - /** - * Return a string encoding of this {@link AnyValue}. This is intended to be a fallback serialized - * representation in case there is no suitable encoding that can utilize {@link #getType()} / - * {@link #getValue()} to serialize specific types. - */ - // TODO(jack-berg): Should this be a JSON encoding? - String asString(); -} diff --git a/api/incubator/src/main/java/io/opentelemetry/api/incubator/logs/AnyValueArray.java b/api/incubator/src/main/java/io/opentelemetry/api/incubator/logs/AnyValueArray.java deleted file mode 100644 index 2332c253392..00000000000 --- a/api/incubator/src/main/java/io/opentelemetry/api/incubator/logs/AnyValueArray.java +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package io.opentelemetry.api.incubator.logs; - -import static java.util.stream.Collectors.joining; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.List; -import java.util.Objects; - -final class AnyValueArray implements AnyValue>> { - - private final List> value; - - private AnyValueArray(List> value) { - this.value = value; - } - - static AnyValue>> create(AnyValue... value) { - Objects.requireNonNull(value, "value must not be null"); - List> list = new ArrayList<>(value.length); - list.addAll(Arrays.asList(value)); - return new AnyValueArray(Collections.unmodifiableList(list)); - } - - static AnyValue>> create(List> value) { - return new AnyValueArray(Collections.unmodifiableList(value)); - } - - @Override - public AnyValueType getType() { - return AnyValueType.ARRAY; - } - - @Override - public List> getValue() { - return value; - } - - @Override - public String asString() { - return value.stream().map(AnyValue::asString).collect(joining(", ", "[", "]")); - } - - @Override - public String toString() { - return "AnyValueArray{" + asString() + "}"; - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - return (o instanceof AnyValue) && Objects.equals(this.value, ((AnyValue) o).getValue()); - } - - @Override - public int hashCode() { - return value.hashCode(); - } -} diff --git a/api/incubator/src/main/java/io/opentelemetry/api/incubator/logs/ExtendedLogRecordBuilder.java b/api/incubator/src/main/java/io/opentelemetry/api/incubator/logs/ExtendedLogRecordBuilder.java index d0a48afaf56..4e8af8eee70 100644 --- a/api/incubator/src/main/java/io/opentelemetry/api/incubator/logs/ExtendedLogRecordBuilder.java +++ b/api/incubator/src/main/java/io/opentelemetry/api/incubator/logs/ExtendedLogRecordBuilder.java @@ -10,6 +10,6 @@ /** Extended {@link LogRecordBuilder} with experimental APIs. */ public interface ExtendedLogRecordBuilder extends LogRecordBuilder { - /** Set the body {@link AnyValue}. */ - LogRecordBuilder setBody(AnyValue body); + // Nothing at the moment, but experimental methods may be added in the future. + } diff --git a/api/incubator/src/main/java/io/opentelemetry/api/incubator/logs/KeyAnyValue.java b/api/incubator/src/main/java/io/opentelemetry/api/incubator/logs/KeyAnyValue.java deleted file mode 100644 index e6cc24ad250..00000000000 --- a/api/incubator/src/main/java/io/opentelemetry/api/incubator/logs/KeyAnyValue.java +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package io.opentelemetry.api.incubator.logs; - -/** - * Key-value pair of {@link String} key and {@link AnyValue} value. - * - * @see AnyValue#of(KeyAnyValue...) - */ -public interface KeyAnyValue { - - /** Returns a {@link KeyAnyValue} for the given {@code key} and {@code value}. */ - static KeyAnyValue of(String key, AnyValue value) { - return KeyAnyValueImpl.create(key, value); - } - - /** Returns the key. */ - String getKey(); - - /** Returns the value. */ - AnyValue getAnyValue(); -} diff --git a/api/incubator/src/main/java/io/opentelemetry/api/incubator/logs/KeyAnyValueImpl.java b/api/incubator/src/main/java/io/opentelemetry/api/incubator/logs/KeyAnyValueImpl.java deleted file mode 100644 index 3792353e717..00000000000 --- a/api/incubator/src/main/java/io/opentelemetry/api/incubator/logs/KeyAnyValueImpl.java +++ /dev/null @@ -1,18 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package io.opentelemetry.api.incubator.logs; - -import com.google.auto.value.AutoValue; - -@AutoValue -abstract class KeyAnyValueImpl implements KeyAnyValue { - - KeyAnyValueImpl() {} - - static KeyAnyValueImpl create(String key, AnyValue value) { - return new AutoValue_KeyAnyValueImpl(key, value); - } -} diff --git a/api/incubator/src/main/java/io/opentelemetry/api/incubator/logs/KeyAnyValueList.java b/api/incubator/src/main/java/io/opentelemetry/api/incubator/logs/KeyAnyValueList.java deleted file mode 100644 index caddcbe7f46..00000000000 --- a/api/incubator/src/main/java/io/opentelemetry/api/incubator/logs/KeyAnyValueList.java +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package io.opentelemetry.api.incubator.logs; - -import static java.util.stream.Collectors.joining; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.List; -import java.util.Map; -import java.util.Objects; - -final class KeyAnyValueList implements AnyValue> { - - private final List value; - - private KeyAnyValueList(List value) { - this.value = value; - } - - static AnyValue> create(KeyAnyValue... value) { - Objects.requireNonNull(value, "value must not be null"); - List list = new ArrayList<>(value.length); - list.addAll(Arrays.asList(value)); - return new KeyAnyValueList(Collections.unmodifiableList(list)); - } - - static AnyValue> createFromMap(Map> value) { - Objects.requireNonNull(value, "value must not be null"); - KeyAnyValue[] array = - value.entrySet().stream() - .map(entry -> KeyAnyValue.of(entry.getKey(), entry.getValue())) - .toArray(KeyAnyValue[]::new); - return create(array); - } - - @Override - public AnyValueType getType() { - return AnyValueType.KEY_VALUE_LIST; - } - - @Override - public List getValue() { - return value; - } - - @Override - public String asString() { - return value.stream() - .map(item -> item.getKey() + "=" + item.getAnyValue().asString()) - .collect(joining(", ", "[", "]")); - } - - @Override - public String toString() { - return "KeyAnyValueList{" + asString() + "}"; - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - return (o instanceof AnyValue) && Objects.equals(this.value, ((AnyValue) o).getValue()); - } - - @Override - public int hashCode() { - return value.hashCode(); - } -} diff --git a/api/incubator/src/test/java/io/opentelemetry/api/incubator/events/DefaultEventLoggerTest.java b/api/incubator/src/test/java/io/opentelemetry/api/incubator/events/DefaultEventLoggerTest.java index 054e09d2c35..ff525646ef6 100644 --- a/api/incubator/src/test/java/io/opentelemetry/api/incubator/events/DefaultEventLoggerTest.java +++ b/api/incubator/src/test/java/io/opentelemetry/api/incubator/events/DefaultEventLoggerTest.java @@ -9,7 +9,7 @@ import io.opentelemetry.api.common.AttributeKey; import io.opentelemetry.api.common.Attributes; -import io.opentelemetry.api.incubator.logs.AnyValue; +import io.opentelemetry.api.common.Value; import io.opentelemetry.api.logs.Severity; import io.opentelemetry.context.Context; import java.time.Instant; @@ -38,13 +38,13 @@ void builder() { .put("longArrKey", 1L, 2L) .put("doubleArrKey", 1.0, 2.0) .put("boolArrKey", true, false) - // Set AnyValue types to encode complex data + // Set complex data .put( - "anyValueKey", - AnyValue.of( - new HashMap>() { + "valueKey", + Value.of( + new HashMap>() { { - put("key", AnyValue.of("value")); + put("key", Value.of("value")); } })) // Helper methods to set AttributeKey types diff --git a/api/incubator/src/test/java/io/opentelemetry/api/incubator/events/EventApiUsageTest.java b/api/incubator/src/test/java/io/opentelemetry/api/incubator/events/EventApiUsageTest.java index 4b074ae5b13..3194978ed4f 100644 --- a/api/incubator/src/test/java/io/opentelemetry/api/incubator/events/EventApiUsageTest.java +++ b/api/incubator/src/test/java/io/opentelemetry/api/incubator/events/EventApiUsageTest.java @@ -9,10 +9,9 @@ import com.google.common.collect.ImmutableMap; import io.opentelemetry.api.common.Attributes; -import io.opentelemetry.api.incubator.logs.AnyValue; +import io.opentelemetry.api.common.Value; import io.opentelemetry.sdk.logs.SdkLoggerProvider; import io.opentelemetry.sdk.logs.export.SimpleLogRecordProcessor; -import io.opentelemetry.sdk.logs.internal.AnyValueBody; import io.opentelemetry.sdk.logs.internal.SdkEventLoggerProvider; import io.opentelemetry.sdk.resources.Resource; import io.opentelemetry.sdk.testing.exporter.InMemoryLogRecordExporter; @@ -42,21 +41,20 @@ void eventApiUsage() { eventLogger .builder("org.foo.my-event") // Add fields to the payload. The API has helpers for adding field values which are - // primitives or arrays of primitives, but you can also add a field with type AnyValue, + // primitives or arrays of primitives, but you can also add a field with type Value, // allowing for arbitrarily complex payloads. .put("key1", "value1") .put( "key2", - AnyValue.of( - ImmutableMap.of( - "childKey1", AnyValue.of("value2"), "childKey2", AnyValue.of("value3")))) + Value.of( + ImmutableMap.of("childKey1", Value.of("value2"), "childKey2", Value.of("value3")))) // Optionally set other fields, including timestamp, severity, context, and attributes // (attributes provide additional details about the event which are not part of the well // defined payload) .emit(); // Events manifest as log records with an event.name attribute, and with the payload fields in - // the AnyValue log record body + // the Value log record body loggerProvider.forceFlush().join(10, TimeUnit.SECONDS); assertThat(exporter.getFinishedLogRecordItems()) .satisfiesExactly( @@ -64,19 +62,20 @@ void eventApiUsage() { assertThat(logData) .hasAttributes( Attributes.builder().put("event.name", "org.foo.my-event").build()); - assertThat(((AnyValueBody) logData.getBody()).asAnyValue()) + assertThat(logData.getBodyValue()) + .isNotNull() .isEqualTo( - AnyValue.of( + Value.of( ImmutableMap.of( "key1", - AnyValue.of("value1"), + Value.of("value1"), "key2", - AnyValue.of( + Value.of( ImmutableMap.of( "childKey1", - AnyValue.of("value2"), + Value.of("value2"), "childKey2", - AnyValue.of("value3")))))); + Value.of("value3")))))); }); } } diff --git a/api/incubator/src/test/java/io/opentelemetry/api/incubator/logs/AnyValueTest.java b/api/incubator/src/test/java/io/opentelemetry/api/incubator/logs/AnyValueTest.java deleted file mode 100644 index 4f52637f575..00000000000 --- a/api/incubator/src/test/java/io/opentelemetry/api/incubator/logs/AnyValueTest.java +++ /dev/null @@ -1,222 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package io.opentelemetry.api.incubator.logs; - -import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatThrownBy; -import static org.junit.jupiter.params.provider.Arguments.arguments; - -import java.nio.ByteBuffer; -import java.nio.ReadOnlyBufferException; -import java.nio.charset.StandardCharsets; -import java.util.Arrays; -import java.util.Base64; -import java.util.Collections; -import java.util.LinkedHashMap; -import java.util.Map; -import java.util.stream.Stream; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.Arguments; -import org.junit.jupiter.params.provider.MethodSource; - -class AnyValueTest { - - @Test - void anyValue_OfString() { - assertThat(AnyValue.of("foo")) - .satisfies( - anyValue -> { - assertThat(anyValue.getType()).isEqualTo(AnyValueType.STRING); - assertThat(anyValue.getValue()).isEqualTo("foo"); - assertThat(anyValue).hasSameHashCodeAs(AnyValue.of("foo")); - }); - } - - @Test - void anyValue_OfBoolean() { - assertThat(AnyValue.of(true)) - .satisfies( - anyValue -> { - assertThat(anyValue.getType()).isEqualTo(AnyValueType.BOOLEAN); - assertThat(anyValue.getValue()).isEqualTo(true); - assertThat(anyValue).hasSameHashCodeAs(AnyValue.of(true)); - }); - } - - @Test - void anyValue_OfLong() { - assertThat(AnyValue.of(1L)) - .satisfies( - anyValue -> { - assertThat(anyValue.getType()).isEqualTo(AnyValueType.LONG); - assertThat(anyValue.getValue()).isEqualTo(1L); - assertThat(anyValue).hasSameHashCodeAs(AnyValue.of(1L)); - }); - } - - @Test - void anyValue_OfDouble() { - assertThat(AnyValue.of(1.1)) - .satisfies( - anyValue -> { - assertThat(anyValue.getType()).isEqualTo(AnyValueType.DOUBLE); - assertThat(anyValue.getValue()).isEqualTo(1.1); - assertThat(anyValue).hasSameHashCodeAs(AnyValue.of(1.1)); - }); - } - - @Test - void anyValue_OfByteArray() { - assertThat(AnyValue.of(new byte[] {'a', 'b'})) - .satisfies( - anyValue -> { - assertThat(anyValue.getType()).isEqualTo(AnyValueType.BYTES); - ByteBuffer value = anyValue.getValue(); - // AnyValueBytes returns read only view of ByteBuffer - assertThatThrownBy(value::array).isInstanceOf(ReadOnlyBufferException.class); - byte[] bytes = new byte[value.remaining()]; - value.get(bytes); - assertThat(bytes).isEqualTo(new byte[] {'a', 'b'}); - assertThat(anyValue).hasSameHashCodeAs(AnyValue.of(new byte[] {'a', 'b'})); - }); - } - - @Test - void anyValue_OfAnyValueArray() { - assertThat(AnyValue.of(AnyValue.of(true), AnyValue.of(1L))) - .satisfies( - anyValue -> { - assertThat(anyValue.getType()).isEqualTo(AnyValueType.ARRAY); - assertThat(anyValue.getValue()) - .isEqualTo(Arrays.asList(AnyValue.of(true), AnyValue.of(1L))); - assertThat(anyValue) - .hasSameHashCodeAs(AnyValue.of(AnyValue.of(true), AnyValue.of(1L))); - }); - } - - @Test - @SuppressWarnings("DoubleBraceInitialization") - void anyValue_OfKeyValueList() { - assertThat( - AnyValue.of( - KeyAnyValue.of("bool", AnyValue.of(true)), KeyAnyValue.of("long", AnyValue.of(1L)))) - .satisfies( - anyValue -> { - assertThat(anyValue.getType()).isEqualTo(AnyValueType.KEY_VALUE_LIST); - assertThat(anyValue.getValue()) - .isEqualTo( - Arrays.asList( - KeyAnyValue.of("bool", AnyValue.of(true)), - KeyAnyValue.of("long", AnyValue.of(1L)))); - assertThat(anyValue) - .hasSameHashCodeAs( - AnyValue.of( - KeyAnyValue.of("bool", AnyValue.of(true)), - KeyAnyValue.of("long", AnyValue.of(1L)))); - }); - - assertThat( - AnyValue.of( - new LinkedHashMap>() { - { - put("bool", AnyValue.of(true)); - put("long", AnyValue.of(1L)); - } - })) - .satisfies( - anyValue -> { - assertThat(anyValue.getType()).isEqualTo(AnyValueType.KEY_VALUE_LIST); - assertThat(anyValue.getValue()) - .isEqualTo( - Arrays.asList( - KeyAnyValue.of("bool", AnyValue.of(true)), - KeyAnyValue.of("long", AnyValue.of(1L)))); - assertThat(anyValue) - .hasSameHashCodeAs( - AnyValue.of( - new LinkedHashMap>() { - { - put("bool", AnyValue.of(true)); - put("long", AnyValue.of(1L)); - } - })); - }); - } - - @Test - void anyValue_NullsNotAllowed() { - assertThatThrownBy(() -> AnyValue.of((String) null)) - .isInstanceOf(NullPointerException.class) - .hasMessageContaining("value must not be null"); - assertThatThrownBy(() -> AnyValue.of((byte[]) null)) - .isInstanceOf(NullPointerException.class) - .hasMessageContaining("value must not be null"); - assertThatThrownBy(() -> AnyValue.of((AnyValue[]) null)) - .isInstanceOf(NullPointerException.class) - .hasMessageContaining("value must not be null"); - assertThatThrownBy(() -> AnyValue.of((KeyAnyValue[]) null)) - .isInstanceOf(NullPointerException.class) - .hasMessageContaining("value must not be null"); - assertThatThrownBy(() -> AnyValue.of((Map>) null)) - .isInstanceOf(NullPointerException.class) - .hasMessageContaining("value must not be null"); - } - - @ParameterizedTest - @MethodSource("asStringArgs") - void asString(AnyValue value, String expectedAsString) { - assertThat(value.asString()).isEqualTo(expectedAsString); - } - - @SuppressWarnings("DoubleBraceInitialization") - private static Stream asStringArgs() { - return Stream.of( - // primitives - arguments(AnyValue.of("str"), "str"), - arguments(AnyValue.of(true), "true"), - arguments(AnyValue.of(1), "1"), - arguments(AnyValue.of(1.1), "1.1"), - // heterogeneous array - arguments( - AnyValue.of(AnyValue.of("str"), AnyValue.of(true), AnyValue.of(1), AnyValue.of(1.1)), - "[str, true, 1, 1.1]"), - // key value list from KeyAnyValue array - arguments( - AnyValue.of( - KeyAnyValue.of("key1", AnyValue.of("val1")), - KeyAnyValue.of("key2", AnyValue.of(2))), - "[key1=val1, key2=2]"), - // key value list from map - arguments( - AnyValue.of( - new LinkedHashMap>() { - { - put("key1", AnyValue.of("val1")); - put("key2", AnyValue.of(2)); - } - }), - "[key1=val1, key2=2]"), - // map of map - arguments( - AnyValue.of( - Collections.singletonMap( - "child", - AnyValue.of(Collections.singletonMap("grandchild", AnyValue.of("str"))))), - "[child=[grandchild=str]]"), - // bytes - arguments(AnyValue.of("hello world".getBytes(StandardCharsets.UTF_8)), "aGVsbG8gd29ybGQ=")); - } - - @Test - void anyValueByteAsString() { - // TODO: add more test cases - String str = "hello world"; - String base64Encoded = AnyValue.of(str.getBytes(StandardCharsets.UTF_8)).asString(); - byte[] decodedBytes = Base64.getDecoder().decode(base64Encoded); - assertThat(new String(decodedBytes, StandardCharsets.UTF_8)).isEqualTo(str); - } -} diff --git a/api/incubator/src/test/java/io/opentelemetry/api/incubator/logs/ExtendedLogsBridgeApiUsageTest.java b/api/incubator/src/test/java/io/opentelemetry/api/incubator/logs/ExtendedLogsBridgeApiUsageTest.java index 7a3d7c82e17..2d9c494ee3e 100644 --- a/api/incubator/src/test/java/io/opentelemetry/api/incubator/logs/ExtendedLogsBridgeApiUsageTest.java +++ b/api/incubator/src/test/java/io/opentelemetry/api/incubator/logs/ExtendedLogsBridgeApiUsageTest.java @@ -9,18 +9,14 @@ import static io.opentelemetry.sdk.logs.internal.LoggerConfig.disabled; import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.assertThat; -import com.google.common.collect.ImmutableMap; import io.opentelemetry.api.common.Attributes; -import io.opentelemetry.api.logs.Logger; import io.opentelemetry.sdk.logs.SdkLoggerProvider; import io.opentelemetry.sdk.logs.SdkLoggerProviderBuilder; import io.opentelemetry.sdk.logs.export.SimpleLogRecordProcessor; -import io.opentelemetry.sdk.logs.internal.AnyValueBody; import io.opentelemetry.sdk.logs.internal.SdkLoggerProviderUtil; import io.opentelemetry.sdk.resources.Resource; import io.opentelemetry.sdk.testing.exporter.InMemoryLogRecordExporter; import java.util.Random; -import java.util.concurrent.TimeUnit; import org.junit.jupiter.api.Test; /** Demonstrating usage of extended Logs Bridge API. */ @@ -80,56 +76,4 @@ void loggerEnabled() { private static String flipCoin() { return random.nextBoolean() ? "heads" : "tails"; } - - @Test - void extendedLogRecordBuilderUsage() { - // Setup SdkLoggerProvider - InMemoryLogRecordExporter exporter = InMemoryLogRecordExporter.create(); - SdkLoggerProvider loggerProvider = - SdkLoggerProvider.builder() - // Default resource used for demonstration purposes - .setResource(Resource.getDefault()) - // Simple processor w/ in-memory exporter used for demonstration purposes - .addLogRecordProcessor(SimpleLogRecordProcessor.create(exporter)) - .build(); - - // Get a Logger for a scope - Logger logger = loggerProvider.get("org.foo.my-scope"); - - // Cast to ExtendedLogRecordBuilder, and emit a log - ((ExtendedLogRecordBuilder) logger.logRecordBuilder()) - // ...can set AnyValue log record body, allowing for arbitrarily complex data - .setBody( - AnyValue.of( - ImmutableMap.of( - "key1", - AnyValue.of("value1"), - "key2", - AnyValue.of( - ImmutableMap.of( - "childKey1", - AnyValue.of("value2"), - "childKey2", - AnyValue.of("value3")))))) - .emit(); - - // SDK can access AnyValue body by casting to AnyValueBody - loggerProvider.forceFlush().join(10, TimeUnit.SECONDS); - assertThat(exporter.getFinishedLogRecordItems()) - .satisfiesExactly( - logData -> - assertThat(((AnyValueBody) logData.getBody()).asAnyValue()) - .isEqualTo( - AnyValue.of( - ImmutableMap.of( - "key1", - AnyValue.of("value1"), - "key2", - AnyValue.of( - ImmutableMap.of( - "childKey1", - AnyValue.of("value2"), - "childKey2", - AnyValue.of("value3"))))))); - } } diff --git a/buildSrc/src/main/kotlin/otel.japicmp-conventions.gradle.kts b/buildSrc/src/main/kotlin/otel.japicmp-conventions.gradle.kts index 3c420e1719a..6a7a4139d6e 100644 --- a/buildSrc/src/main/kotlin/otel.japicmp-conventions.gradle.kts +++ b/buildSrc/src/main/kotlin/otel.japicmp-conventions.gradle.kts @@ -29,18 +29,21 @@ class AllowNewAbstractMethodOnAutovalueClasses : AbstractRecordingSeenMembers() override fun maybeAddViolation(member: JApiCompatibility): Violation? { val allowableAutovalueChanges = setOf(JApiCompatibilityChange.METHOD_ABSTRACT_ADDED_TO_CLASS, JApiCompatibilityChange.METHOD_ADDED_TO_PUBLIC_CLASS) if (member.compatibilityChanges.filter { !allowableAutovalueChanges.contains(it) }.isEmpty() && - member is JApiMethod && - member.getjApiClass().newClass.get().getAnnotation(AutoValue::class.java) != null - ) { + member is JApiMethod && isAutoValueClass(member.getjApiClass())) + { return Violation.accept(member, "Autovalue will automatically add implementation") } if (member.compatibilityChanges.isEmpty() && - member is JApiClass && - member.newClass.get().getAnnotation(AutoValue::class.java) != null) { + member is JApiClass && isAutoValueClass(member)) { return Violation.accept(member, "Autovalue class modification is allowed") } return null } + + fun isAutoValueClass(japiClass: JApiClass): Boolean { + return japiClass.newClass.get().getAnnotation(AutoValue::class.java) != null || + japiClass.newClass.get().getAnnotation(AutoValue.Builder::class.java) != null + } } class SourceIncompatibleRule : AbstractRecordingSeenMembers() { diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-api.txt b/docs/apidiffs/current_vs_latest/opentelemetry-api.txt index 58efc24b59d..2b8bdd18bad 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-api.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-api.txt @@ -1,2 +1,41 @@ Comparing source compatibility of opentelemetry-api-1.42.0-SNAPSHOT.jar against opentelemetry-api-1.41.0.jar -No changes. \ No newline at end of file ++++ NEW INTERFACE: PUBLIC(+) ABSTRACT(+) io.opentelemetry.api.common.KeyValue (not serializable) + +++ CLASS FILE FORMAT VERSION: 52.0 <- n.a. + +++ NEW SUPERCLASS: java.lang.Object + +++ NEW METHOD: PUBLIC(+) ABSTRACT(+) java.lang.String getKey() + +++ NEW METHOD: PUBLIC(+) ABSTRACT(+) io.opentelemetry.api.common.Value getValue() + +++ NEW METHOD: PUBLIC(+) STATIC(+) io.opentelemetry.api.common.KeyValue of(java.lang.String, io.opentelemetry.api.common.Value) ++++ NEW INTERFACE: PUBLIC(+) ABSTRACT(+) io.opentelemetry.api.common.Value (not serializable) + +++ CLASS FILE FORMAT VERSION: 52.0 <- n.a. + GENERIC TEMPLATES: +++ T:java.lang.Object + +++ NEW SUPERCLASS: java.lang.Object + +++ NEW METHOD: PUBLIC(+) ABSTRACT(+) java.lang.String asString() + +++ NEW METHOD: PUBLIC(+) ABSTRACT(+) io.opentelemetry.api.common.ValueType getType() + +++ NEW METHOD: PUBLIC(+) ABSTRACT(+) java.lang.Object getValue() + +++ NEW METHOD: PUBLIC(+) STATIC(+) io.opentelemetry.api.common.Value of(java.lang.String) + +++ NEW METHOD: PUBLIC(+) STATIC(+) io.opentelemetry.api.common.Value of(boolean) + +++ NEW METHOD: PUBLIC(+) STATIC(+) io.opentelemetry.api.common.Value of(long) + +++ NEW METHOD: PUBLIC(+) STATIC(+) io.opentelemetry.api.common.Value of(double) + +++ NEW METHOD: PUBLIC(+) STATIC(+) io.opentelemetry.api.common.Value of(byte[]) + +++ NEW METHOD: PUBLIC(+) STATIC(+) io.opentelemetry.api.common.Value>> of(io.opentelemetry.api.common.Value[]) + +++ NEW METHOD: PUBLIC(+) STATIC(+) io.opentelemetry.api.common.Value>> of(java.util.List>) + +++ NEW METHOD: PUBLIC(+) STATIC(+) io.opentelemetry.api.common.Value> of(io.opentelemetry.api.common.KeyValue[]) + +++ NEW METHOD: PUBLIC(+) STATIC(+) io.opentelemetry.api.common.Value> of(java.util.Map>) ++++ NEW ENUM: PUBLIC(+) FINAL(+) io.opentelemetry.api.common.ValueType (compatible) + +++ CLASS FILE FORMAT VERSION: 52.0 <- n.a. + +++ NEW INTERFACE: java.lang.constant.Constable + +++ NEW INTERFACE: java.lang.Comparable + +++ NEW INTERFACE: java.io.Serializable + +++ NEW SUPERCLASS: java.lang.Enum + +++ NEW FIELD: PUBLIC(+) STATIC(+) FINAL(+) io.opentelemetry.api.common.ValueType BYTES + +++ NEW FIELD: PUBLIC(+) STATIC(+) FINAL(+) io.opentelemetry.api.common.ValueType ARRAY + +++ NEW FIELD: PUBLIC(+) STATIC(+) FINAL(+) io.opentelemetry.api.common.ValueType KEY_VALUE_LIST + +++ NEW FIELD: PUBLIC(+) STATIC(+) FINAL(+) io.opentelemetry.api.common.ValueType STRING + +++ NEW FIELD: PUBLIC(+) STATIC(+) FINAL(+) io.opentelemetry.api.common.ValueType DOUBLE + +++ NEW FIELD: PUBLIC(+) STATIC(+) FINAL(+) io.opentelemetry.api.common.ValueType BOOLEAN + +++ NEW FIELD: PUBLIC(+) STATIC(+) FINAL(+) io.opentelemetry.api.common.ValueType LONG + +++ NEW METHOD: PUBLIC(+) STATIC(+) io.opentelemetry.api.common.ValueType valueOf(java.lang.String) + +++ NEW METHOD: PUBLIC(+) STATIC(+) io.opentelemetry.api.common.ValueType[] values() +*** MODIFIED INTERFACE: PUBLIC ABSTRACT io.opentelemetry.api.logs.LogRecordBuilder (not serializable) + === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 + +++ NEW METHOD: PUBLIC(+) io.opentelemetry.api.logs.LogRecordBuilder setBody(io.opentelemetry.api.common.Value) diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-logs.txt b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-logs.txt index 3f689fe94cc..b096d42eb98 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-logs.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-logs.txt @@ -1,2 +1,15 @@ Comparing source compatibility of opentelemetry-sdk-logs-1.42.0-SNAPSHOT.jar against opentelemetry-sdk-logs-1.41.0.jar -No changes. \ No newline at end of file +=== UNCHANGED INTERFACE: PUBLIC ABSTRACT io.opentelemetry.sdk.logs.data.Body (not serializable) + === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 + === UNCHANGED METHOD: PUBLIC ABSTRACT io.opentelemetry.sdk.logs.data.Body$Type getType() + +++ NEW ANNOTATION: java.lang.Deprecated + +++ NEW ANNOTATION: java.lang.Deprecated +=== UNCHANGED ENUM: PUBLIC STATIC FINAL io.opentelemetry.sdk.logs.data.Body$Type (compatible) + === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 + +++ NEW ANNOTATION: java.lang.Deprecated +*** MODIFIED INTERFACE: PUBLIC ABSTRACT io.opentelemetry.sdk.logs.data.LogRecordData (not serializable) + === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 + === UNCHANGED METHOD: PUBLIC ABSTRACT io.opentelemetry.sdk.logs.data.Body getBody() + +++ NEW ANNOTATION: java.lang.Deprecated + +++ NEW METHOD: PUBLIC(+) io.opentelemetry.api.common.Value getBodyValue() + +++ NEW ANNOTATION: javax.annotation.Nullable diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-testing.txt b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-testing.txt index 7c4d542dd50..988fe184f0f 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-testing.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-testing.txt @@ -1,2 +1,15 @@ Comparing source compatibility of opentelemetry-sdk-testing-1.42.0-SNAPSHOT.jar against opentelemetry-sdk-testing-1.41.0.jar -No changes. \ No newline at end of file +*** MODIFIED CLASS: PUBLIC FINAL io.opentelemetry.sdk.testing.assertj.LogRecordDataAssert (not serializable) + === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 + +++ NEW METHOD: PUBLIC(+) io.opentelemetry.sdk.testing.assertj.LogRecordDataAssert hasBody(io.opentelemetry.api.common.Value) +**** MODIFIED CLASS: PUBLIC ABSTRACT io.opentelemetry.sdk.testing.logs.TestLogRecordData (not serializable) + === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 + +++ NEW METHOD: PUBLIC(+) io.opentelemetry.sdk.logs.data.Body getBody() + +++ NEW ANNOTATION: java.lang.Deprecated + +++* NEW METHOD: PUBLIC(+) ABSTRACT(+) io.opentelemetry.api.common.Value getBodyValue() + +++ NEW ANNOTATION: javax.annotation.Nullable +**** MODIFIED CLASS: PUBLIC ABSTRACT STATIC io.opentelemetry.sdk.testing.logs.TestLogRecordData$Builder (not serializable) + === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 + *** MODIFIED METHOD: PUBLIC (<- PACKAGE_PROTECTED) NON_ABSTRACT (<- ABSTRACT) io.opentelemetry.sdk.testing.logs.TestLogRecordData$Builder setBody(io.opentelemetry.sdk.logs.data.Body) + +++ NEW ANNOTATION: java.lang.Deprecated + +++* NEW METHOD: PUBLIC(+) ABSTRACT(+) io.opentelemetry.sdk.testing.logs.TestLogRecordData$Builder setBodyValue(io.opentelemetry.api.common.Value) diff --git a/exporters/logging/src/main/java/io/opentelemetry/exporter/logging/SystemOutLogRecordExporter.java b/exporters/logging/src/main/java/io/opentelemetry/exporter/logging/SystemOutLogRecordExporter.java index 6655c12453a..3848bf0225a 100644 --- a/exporters/logging/src/main/java/io/opentelemetry/exporter/logging/SystemOutLogRecordExporter.java +++ b/exporters/logging/src/main/java/io/opentelemetry/exporter/logging/SystemOutLogRecordExporter.java @@ -7,6 +7,7 @@ import static java.util.concurrent.TimeUnit.NANOSECONDS; +import io.opentelemetry.api.common.Value; import io.opentelemetry.sdk.common.CompletableResultCode; import io.opentelemetry.sdk.common.InstrumentationScopeInfo; import io.opentelemetry.sdk.logs.data.LogRecordData; @@ -63,6 +64,7 @@ public CompletableResultCode flush() { // VisibleForTesting static void formatLog(StringBuilder stringBuilder, LogRecordData log) { InstrumentationScopeInfo instrumentationScopeInfo = log.getInstrumentationScopeInfo(); + Value body = log.getBodyValue(); stringBuilder .append( ISO_FORMAT.format( @@ -71,7 +73,7 @@ static void formatLog(StringBuilder stringBuilder, LogRecordData log) { .append(" ") .append(log.getSeverity()) .append(" '") - .append(log.getBody().asString()) + .append(body == null ? "" : body.asString()) .append("' : ") .append(log.getSpanContext().getTraceId()) .append(" ") diff --git a/exporters/otlp/common/src/jmh/java/io/opentelemetry/exporter/internal/otlp/LogsRequestMarshalerBenchmark.java b/exporters/otlp/common/src/jmh/java/io/opentelemetry/exporter/internal/otlp/LogsRequestMarshalerBenchmark.java index 289f6f77845..2d25476f42a 100644 --- a/exporters/otlp/common/src/jmh/java/io/opentelemetry/exporter/internal/otlp/LogsRequestMarshalerBenchmark.java +++ b/exporters/otlp/common/src/jmh/java/io/opentelemetry/exporter/internal/otlp/LogsRequestMarshalerBenchmark.java @@ -7,8 +7,8 @@ import io.opentelemetry.api.common.AttributeKey; import io.opentelemetry.api.common.Attributes; +import io.opentelemetry.api.common.Value; import io.opentelemetry.api.incubator.events.EventLogger; -import io.opentelemetry.api.incubator.logs.AnyValue; import io.opentelemetry.api.logs.Logger; import io.opentelemetry.api.logs.Severity; import io.opentelemetry.exporter.internal.otlp.logs.LogsRequestMarshaler; @@ -98,9 +98,8 @@ public class LogsRequestMarshalerBenchmark { .put("longArrKey", 1L, 2L) .put("doubleArrKey", 1.0, 2.0) .put("boolArrKey", true, false) - // Set AnyValue types to encode complex data - .put( - "anyValueKey", AnyValue.of(Collections.singletonMap("childKey1", AnyValue.of("value")))) + // Set complex data + .put("key", Value.of(Collections.singletonMap("childKey1", Value.of("value")))) .emit(); LOGS = logRecordExporter.getFinishedLogRecordItems(); diff --git a/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/AnyValueMarshaler.java b/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/AnyValueMarshaler.java index 0b39d15df29..327ad471e4e 100644 --- a/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/AnyValueMarshaler.java +++ b/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/AnyValueMarshaler.java @@ -5,8 +5,8 @@ package io.opentelemetry.exporter.internal.otlp; -import io.opentelemetry.api.incubator.logs.AnyValue; -import io.opentelemetry.api.incubator.logs.KeyAnyValue; +import io.opentelemetry.api.common.KeyValue; +import io.opentelemetry.api.common.Value; import io.opentelemetry.exporter.internal.marshal.MarshalerWithSize; import java.nio.ByteBuffer; import java.util.List; @@ -22,23 +22,23 @@ public final class AnyValueMarshaler { private AnyValueMarshaler() {} @SuppressWarnings("unchecked") - public static MarshalerWithSize create(AnyValue anyValue) { - switch (anyValue.getType()) { + public static MarshalerWithSize create(Value value) { + switch (value.getType()) { case STRING: - return StringAnyValueMarshaler.create((String) anyValue.getValue()); + return StringAnyValueMarshaler.create((String) value.getValue()); case BOOLEAN: - return BoolAnyValueMarshaler.create((boolean) anyValue.getValue()); + return BoolAnyValueMarshaler.create((boolean) value.getValue()); case LONG: - return IntAnyValueMarshaler.create((long) anyValue.getValue()); + return IntAnyValueMarshaler.create((long) value.getValue()); case DOUBLE: - return DoubleAnyValueMarshaler.create((double) anyValue.getValue()); + return DoubleAnyValueMarshaler.create((double) value.getValue()); case ARRAY: - return ArrayAnyValueMarshaler.createAnyValue((List>) anyValue.getValue()); + return ArrayAnyValueMarshaler.createAnyValue((List>) value.getValue()); case KEY_VALUE_LIST: - return KeyValueListAnyValueMarshaler.create((List) anyValue.getValue()); + return KeyValueListAnyValueMarshaler.create((List) value.getValue()); case BYTES: - return BytesAnyValueMarshaler.create((ByteBuffer) anyValue.getValue()); + return BytesAnyValueMarshaler.create((ByteBuffer) value.getValue()); } - throw new IllegalArgumentException("Unsupported AnyValue type: " + anyValue.getType()); + throw new IllegalArgumentException("Unsupported Value type: " + value.getType()); } } diff --git a/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/AnyValueStatelessMarshaler.java b/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/AnyValueStatelessMarshaler.java index f9cbb05589f..bad0d9060d5 100644 --- a/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/AnyValueStatelessMarshaler.java +++ b/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/AnyValueStatelessMarshaler.java @@ -5,8 +5,8 @@ package io.opentelemetry.exporter.internal.otlp; -import io.opentelemetry.api.incubator.logs.AnyValue; -import io.opentelemetry.api.incubator.logs.KeyAnyValue; +import io.opentelemetry.api.common.KeyValue; +import io.opentelemetry.api.common.Value; import io.opentelemetry.exporter.internal.marshal.MarshalerContext; import io.opentelemetry.exporter.internal.marshal.Serializer; import io.opentelemetry.exporter.internal.marshal.StatelessMarshaler; @@ -21,7 +21,7 @@ *

      This class is internal and is hence not for public use. Its APIs are unstable and can change * at any time. */ -public final class AnyValueStatelessMarshaler implements StatelessMarshaler> { +public final class AnyValueStatelessMarshaler implements StatelessMarshaler> { public static final AnyValueStatelessMarshaler INSTANCE = new AnyValueStatelessMarshaler(); @@ -29,7 +29,7 @@ private AnyValueStatelessMarshaler() {} @SuppressWarnings("unchecked") @Override - public void writeTo(Serializer output, AnyValue value, MarshalerContext context) + public void writeTo(Serializer output, Value value, MarshalerContext context) throws IOException { switch (value.getType()) { case STRING: @@ -50,14 +50,14 @@ public void writeTo(Serializer output, AnyValue value, MarshalerContext conte case ARRAY: output.serializeMessageWithContext( io.opentelemetry.proto.common.v1.internal.AnyValue.ARRAY_VALUE, - (List>) value.getValue(), + (List>) value.getValue(), ArrayAnyValueStatelessMarshaler.INSTANCE, context); return; case KEY_VALUE_LIST: output.serializeMessageWithContext( io.opentelemetry.proto.common.v1.internal.AnyValue.KVLIST_VALUE, - (List) value.getValue(), + (List) value.getValue(), KeyValueListAnyValueStatelessMarshaler.INSTANCE, context); return; @@ -73,7 +73,7 @@ public void writeTo(Serializer output, AnyValue value, MarshalerContext conte @SuppressWarnings("unchecked") @Override - public int getBinarySerializedSize(AnyValue value, MarshalerContext context) { + public int getBinarySerializedSize(Value value, MarshalerContext context) { switch (value.getType()) { case STRING: return StringAnyValueStatelessMarshaler.INSTANCE.getBinarySerializedSize( @@ -90,13 +90,13 @@ public int getBinarySerializedSize(AnyValue value, MarshalerContext context) case ARRAY: return StatelessMarshalerUtil.sizeMessageWithContext( io.opentelemetry.proto.common.v1.internal.AnyValue.ARRAY_VALUE, - (List>) value.getValue(), + (List>) value.getValue(), ArrayAnyValueStatelessMarshaler.INSTANCE, context); case KEY_VALUE_LIST: return StatelessMarshalerUtil.sizeMessageWithContext( io.opentelemetry.proto.common.v1.internal.AnyValue.KVLIST_VALUE, - (List) value.getValue(), + (List) value.getValue(), KeyValueListAnyValueStatelessMarshaler.INSTANCE, context); case BYTES: diff --git a/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/ArrayAnyValueMarshaler.java b/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/ArrayAnyValueMarshaler.java index aa1c25e9c14..9b9ba2fc26e 100644 --- a/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/ArrayAnyValueMarshaler.java +++ b/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/ArrayAnyValueMarshaler.java @@ -5,6 +5,7 @@ package io.opentelemetry.exporter.internal.otlp; +import io.opentelemetry.api.common.Value; import io.opentelemetry.exporter.internal.marshal.Marshaler; import io.opentelemetry.exporter.internal.marshal.MarshalerUtil; import io.opentelemetry.exporter.internal.marshal.MarshalerWithSize; @@ -23,8 +24,7 @@ private ArrayAnyValueMarshaler(ArrayValueMarshaler value) { this.value = value; } - static MarshalerWithSize createAnyValue( - List> values) { + static MarshalerWithSize createAnyValue(List> values) { return createInternal(values, AnyValueMarshaler::create); } diff --git a/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/ArrayAnyValueStatelessMarshaler.java b/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/ArrayAnyValueStatelessMarshaler.java index a558953514c..2ccc4a4eca3 100644 --- a/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/ArrayAnyValueStatelessMarshaler.java +++ b/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/ArrayAnyValueStatelessMarshaler.java @@ -5,7 +5,7 @@ package io.opentelemetry.exporter.internal.otlp; -import io.opentelemetry.api.incubator.logs.AnyValue; +import io.opentelemetry.api.common.Value; import io.opentelemetry.exporter.internal.marshal.MarshalerContext; import io.opentelemetry.exporter.internal.marshal.Serializer; import io.opentelemetry.exporter.internal.marshal.StatelessMarshaler; @@ -15,21 +15,21 @@ import java.util.List; /** A Marshaler of key value pairs. See {@link ArrayAnyValueMarshaler}. */ -final class ArrayAnyValueStatelessMarshaler implements StatelessMarshaler>> { +final class ArrayAnyValueStatelessMarshaler implements StatelessMarshaler>> { static final ArrayAnyValueStatelessMarshaler INSTANCE = new ArrayAnyValueStatelessMarshaler(); private ArrayAnyValueStatelessMarshaler() {} @Override - public void writeTo(Serializer output, List> value, MarshalerContext context) + public void writeTo(Serializer output, List> value, MarshalerContext context) throws IOException { output.serializeRepeatedMessageWithContext( ArrayValue.VALUES, value, AnyValueStatelessMarshaler.INSTANCE, context); } @Override - public int getBinarySerializedSize(List> value, MarshalerContext context) { + public int getBinarySerializedSize(List> value, MarshalerContext context) { return StatelessMarshalerUtil.sizeRepeatedMessageWithContext( ArrayValue.VALUES, value, AnyValueStatelessMarshaler.INSTANCE, context); } diff --git a/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/KeyValueListAnyValueMarshaler.java b/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/KeyValueListAnyValueMarshaler.java index afb884a2d86..1e5b345acae 100644 --- a/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/KeyValueListAnyValueMarshaler.java +++ b/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/KeyValueListAnyValueMarshaler.java @@ -5,7 +5,7 @@ package io.opentelemetry.exporter.internal.otlp; -import io.opentelemetry.api.incubator.logs.KeyAnyValue; +import io.opentelemetry.api.common.KeyValue; import io.opentelemetry.exporter.internal.marshal.Marshaler; import io.opentelemetry.exporter.internal.marshal.MarshalerUtil; import io.opentelemetry.exporter.internal.marshal.MarshalerWithSize; @@ -24,11 +24,11 @@ private KeyValueListAnyValueMarshaler(KeyValueListMarshaler value) { this.value = value; } - static MarshalerWithSize create(List values) { + static MarshalerWithSize create(List values) { int len = values.size(); KeyValueMarshaler[] marshalers = new KeyValueMarshaler[values.size()]; for (int i = 0; i < len; i++) { - marshalers[i] = KeyValueMarshaler.createForKeyAnyValue(values.get(i)); + marshalers[i] = KeyValueMarshaler.createForKeyValue(values.get(i)); } return new KeyValueListAnyValueMarshaler(new KeyValueListMarshaler(marshalers)); } diff --git a/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/KeyValueListAnyValueStatelessMarshaler.java b/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/KeyValueListAnyValueStatelessMarshaler.java index 854eb2cea6e..6bb7ef8d210 100644 --- a/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/KeyValueListAnyValueStatelessMarshaler.java +++ b/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/KeyValueListAnyValueStatelessMarshaler.java @@ -5,7 +5,7 @@ package io.opentelemetry.exporter.internal.otlp; -import io.opentelemetry.api.incubator.logs.KeyAnyValue; +import io.opentelemetry.api.common.KeyValue; import io.opentelemetry.exporter.internal.marshal.MarshalerContext; import io.opentelemetry.exporter.internal.marshal.Serializer; import io.opentelemetry.exporter.internal.marshal.StatelessMarshaler; @@ -15,8 +15,7 @@ import java.util.List; /** A Marshaler of key value pairs. See {@link KeyValueListAnyValueMarshaler}. */ -final class KeyValueListAnyValueStatelessMarshaler - implements StatelessMarshaler> { +final class KeyValueListAnyValueStatelessMarshaler implements StatelessMarshaler> { static final KeyValueListAnyValueStatelessMarshaler INSTANCE = new KeyValueListAnyValueStatelessMarshaler(); @@ -24,14 +23,14 @@ final class KeyValueListAnyValueStatelessMarshaler private KeyValueListAnyValueStatelessMarshaler() {} @Override - public void writeTo(Serializer output, List value, MarshalerContext context) + public void writeTo(Serializer output, List value, MarshalerContext context) throws IOException { output.serializeRepeatedMessageWithContext( KeyValueList.VALUES, value, KeyValueStatelessMarshaler.INSTANCE, context); } @Override - public int getBinarySerializedSize(List value, MarshalerContext context) { + public int getBinarySerializedSize(List value, MarshalerContext context) { return StatelessMarshalerUtil.sizeRepeatedMessageWithContext( KeyValueList.VALUES, value, KeyValueStatelessMarshaler.INSTANCE, context); } diff --git a/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/KeyValueMarshaler.java b/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/KeyValueMarshaler.java index 56a3fa06461..47a0a32a759 100644 --- a/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/KeyValueMarshaler.java +++ b/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/KeyValueMarshaler.java @@ -7,13 +7,12 @@ import io.opentelemetry.api.common.AttributeKey; import io.opentelemetry.api.common.Attributes; -import io.opentelemetry.api.incubator.logs.KeyAnyValue; +import io.opentelemetry.api.common.KeyValue; import io.opentelemetry.api.internal.InternalAttributeKeyImpl; import io.opentelemetry.exporter.internal.marshal.Marshaler; import io.opentelemetry.exporter.internal.marshal.MarshalerUtil; import io.opentelemetry.exporter.internal.marshal.MarshalerWithSize; import io.opentelemetry.exporter.internal.marshal.Serializer; -import io.opentelemetry.proto.common.v1.internal.KeyValue; import java.io.IOException; import java.nio.charset.StandardCharsets; import java.util.List; @@ -39,11 +38,11 @@ private KeyValueMarshaler(byte[] keyUtf8, Marshaler value) { this.value = value; } - /** Returns Marshaler for the given KeyAnyValue. */ - public static KeyValueMarshaler createForKeyAnyValue(KeyAnyValue keyAnyValue) { + /** Returns Marshaler for the given KeyValue. */ + public static KeyValueMarshaler createForKeyValue(KeyValue keyValue) { return new KeyValueMarshaler( - keyAnyValue.getKey().getBytes(StandardCharsets.UTF_8), - AnyValueMarshaler.create(keyAnyValue.getAnyValue())); + keyValue.getKey().getBytes(StandardCharsets.UTF_8), + AnyValueMarshaler.create(keyValue.getValue())); } /** Returns Marshalers for the given Attributes. */ @@ -104,14 +103,16 @@ private static KeyValueMarshaler create(AttributeKey attributeKey, Object val @Override public void writeTo(Serializer output) throws IOException { - output.serializeString(KeyValue.KEY, keyUtf8); - output.serializeMessage(KeyValue.VALUE, value); + output.serializeString(io.opentelemetry.proto.common.v1.internal.KeyValue.KEY, keyUtf8); + output.serializeMessage(io.opentelemetry.proto.common.v1.internal.KeyValue.VALUE, value); } private static int calculateSize(byte[] keyUtf8, Marshaler value) { int size = 0; - size += MarshalerUtil.sizeBytes(KeyValue.KEY, keyUtf8); - size += MarshalerUtil.sizeMessage(KeyValue.VALUE, value); + size += + MarshalerUtil.sizeBytes(io.opentelemetry.proto.common.v1.internal.KeyValue.KEY, keyUtf8); + size += + MarshalerUtil.sizeMessage(io.opentelemetry.proto.common.v1.internal.KeyValue.VALUE, value); return size; } } diff --git a/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/KeyValueStatelessMarshaler.java b/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/KeyValueStatelessMarshaler.java index 4b095d640d6..cd7defa9aa6 100644 --- a/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/KeyValueStatelessMarshaler.java +++ b/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/KeyValueStatelessMarshaler.java @@ -5,16 +5,15 @@ package io.opentelemetry.exporter.internal.otlp; -import io.opentelemetry.api.incubator.logs.KeyAnyValue; +import io.opentelemetry.api.common.KeyValue; import io.opentelemetry.exporter.internal.marshal.MarshalerContext; import io.opentelemetry.exporter.internal.marshal.Serializer; import io.opentelemetry.exporter.internal.marshal.StatelessMarshaler; import io.opentelemetry.exporter.internal.marshal.StatelessMarshalerUtil; -import io.opentelemetry.proto.common.v1.internal.KeyValue; import java.io.IOException; /** A Marshaler of key value pairs. See {@link AnyValueMarshaler}. */ -public final class KeyValueStatelessMarshaler implements StatelessMarshaler { +public final class KeyValueStatelessMarshaler implements StatelessMarshaler { public static final KeyValueStatelessMarshaler INSTANCE = new KeyValueStatelessMarshaler(); private static final byte[] EMPTY_BYTES = new byte[0]; @@ -22,28 +21,37 @@ public final class KeyValueStatelessMarshaler implements StatelessMarshaler { - - private static final BodyMarshaler INSTANCE = new BodyMarshaler(); - private static final AnyValue EMPTY_BODY = AnyValue.of(""); - - private BodyMarshaler() {} - - @Override - public void writeTo(Serializer output, Body value, MarshalerContext context) - throws IOException { - AnyValue anyValue; - if (value instanceof AnyValueBody) { - anyValue = ((AnyValueBody) value).asAnyValue(); - } else { - switch (value.getType()) { - case STRING: - anyValue = context.getData(AnyValue.class); - break; - case EMPTY: - anyValue = EMPTY_BODY; - break; - default: - throw new IllegalStateException("Unsupported Body type: " + value.getType()); - } - } - AnyValueStatelessMarshaler.INSTANCE.writeTo(output, anyValue, context); - } - - @Override - public int getBinarySerializedSize(Body value, MarshalerContext context) { - AnyValue anyValue; - if (value instanceof AnyValueBody) { - anyValue = ((AnyValueBody) value).asAnyValue(); - } else { - switch (value.getType()) { - case STRING: - anyValue = AnyValue.of(value.asString()); - context.addData(anyValue); - break; - case EMPTY: - anyValue = EMPTY_BODY; - break; - default: - throw new IllegalStateException("Unsupported Body type: " + value.getType()); - } - } - return AnyValueStatelessMarshaler.INSTANCE.getBinarySerializedSize(anyValue, context); - } - } } diff --git a/exporters/otlp/common/src/test/java/io/opentelemetry/exporter/internal/otlp/AnyValueMarshalerTest.java b/exporters/otlp/common/src/test/java/io/opentelemetry/exporter/internal/otlp/ValueMarshalerTest.java similarity index 89% rename from exporters/otlp/common/src/test/java/io/opentelemetry/exporter/internal/otlp/AnyValueMarshalerTest.java rename to exporters/otlp/common/src/test/java/io/opentelemetry/exporter/internal/otlp/ValueMarshalerTest.java index cd56af8fd84..d9e38900b7e 100644 --- a/exporters/otlp/common/src/test/java/io/opentelemetry/exporter/internal/otlp/AnyValueMarshalerTest.java +++ b/exporters/otlp/common/src/test/java/io/opentelemetry/exporter/internal/otlp/ValueMarshalerTest.java @@ -5,7 +5,7 @@ package io.opentelemetry.exporter.internal.otlp; -import static io.opentelemetry.api.incubator.logs.AnyValue.of; +import static io.opentelemetry.api.common.Value.of; import static org.assertj.core.api.Assertions.assertThat; import static org.junit.jupiter.params.provider.Arguments.arguments; @@ -13,7 +13,8 @@ import com.google.protobuf.InvalidProtocolBufferException; import com.google.protobuf.Message; import com.google.protobuf.util.JsonFormat; -import io.opentelemetry.api.incubator.logs.KeyAnyValue; +import io.opentelemetry.api.common.KeyValue; +import io.opentelemetry.api.common.Value; import io.opentelemetry.exporter.internal.marshal.Marshaler; import io.opentelemetry.exporter.internal.marshal.MarshalerContext; import io.opentelemetry.exporter.internal.marshal.MarshalerWithSize; @@ -21,7 +22,6 @@ import io.opentelemetry.exporter.internal.marshal.StatelessMarshaler; import io.opentelemetry.proto.common.v1.AnyValue; import io.opentelemetry.proto.common.v1.ArrayValue; -import io.opentelemetry.proto.common.v1.KeyValue; import io.opentelemetry.proto.common.v1.KeyValueList; import java.io.ByteArrayOutputStream; import java.io.IOException; @@ -34,22 +34,20 @@ import org.junit.jupiter.params.provider.MethodSource; @SuppressWarnings("BadImport") -class AnyValueMarshalerTest { +class ValueMarshalerTest { @ParameterizedTest @MethodSource("serializeAnyValueArgs") - void anyValueString_StatefulMarshaler( - io.opentelemetry.api.incubator.logs.AnyValue anyValue, AnyValue expectedSerializedValue) { - MarshalerWithSize marshaler = AnyValueMarshaler.create(anyValue); + void anyValueString_StatefulMarshaler(Value value, AnyValue expectedSerializedValue) { + MarshalerWithSize marshaler = AnyValueMarshaler.create(value); AnyValue serializedValue = parse(AnyValue.getDefaultInstance(), marshaler); assertThat(serializedValue).isEqualTo(expectedSerializedValue); } @ParameterizedTest @MethodSource("serializeAnyValueArgs") - void anyValueString_StatelessMarshaler( - io.opentelemetry.api.incubator.logs.AnyValue anyValue, AnyValue expectedSerializedValue) { - Marshaler marshaler = createMarshaler(AnyValueStatelessMarshaler.INSTANCE, anyValue); + void anyValueString_StatelessMarshaler(Value value, AnyValue expectedSerializedValue) { + Marshaler marshaler = createMarshaler(AnyValueStatelessMarshaler.INSTANCE, value); AnyValue serializedValue = parse(AnyValue.getDefaultInstance(), marshaler); assertThat(serializedValue).isEqualTo(expectedSerializedValue); } @@ -75,17 +73,17 @@ private static Stream serializeAnyValueArgs() { .build()), // map arguments( - of(KeyAnyValue.of("key1", of("val1")), KeyAnyValue.of("key2", of(2))), + of(KeyValue.of("key1", of("val1")), KeyValue.of("key2", of(2))), AnyValue.newBuilder() .setKvlistValue( KeyValueList.newBuilder() .addValues( - KeyValue.newBuilder() + io.opentelemetry.proto.common.v1.KeyValue.newBuilder() .setKey("key1") .setValue(AnyValue.newBuilder().setStringValue("val1").build()) .build()) .addValues( - KeyValue.newBuilder() + io.opentelemetry.proto.common.v1.KeyValue.newBuilder() .setKey("key2") .setValue(AnyValue.newBuilder().setIntValue(2).build()) .build()) @@ -100,14 +98,15 @@ private static Stream serializeAnyValueArgs() { .setKvlistValue( KeyValueList.newBuilder() .addValues( - KeyValue.newBuilder() + io.opentelemetry.proto.common.v1.KeyValue.newBuilder() .setKey("child") .setValue( AnyValue.newBuilder() .setKvlistValue( KeyValueList.newBuilder() .addValues( - KeyValue.newBuilder() + io.opentelemetry.proto.common.v1.KeyValue + .newBuilder() .setKey("grandchild") .setValue( AnyValue.newBuilder() diff --git a/integration-tests/otlp/src/main/java/io/opentelemetry/integrationtest/OtlpExporterIntegrationTest.java b/integration-tests/otlp/src/main/java/io/opentelemetry/integrationtest/OtlpExporterIntegrationTest.java index e90c9efe28f..9a0ffec76c6 100644 --- a/integration-tests/otlp/src/main/java/io/opentelemetry/integrationtest/OtlpExporterIntegrationTest.java +++ b/integration-tests/otlp/src/main/java/io/opentelemetry/integrationtest/OtlpExporterIntegrationTest.java @@ -5,7 +5,7 @@ package io.opentelemetry.integrationtest; -import static io.opentelemetry.api.incubator.logs.AnyValue.of; +import static io.opentelemetry.api.common.Value.of; import static java.util.concurrent.CompletableFuture.completedFuture; import static org.assertj.core.api.Assertions.assertThat; import static org.awaitility.Awaitility.await; @@ -21,9 +21,9 @@ import io.opentelemetry.api.GlobalOpenTelemetry; import io.opentelemetry.api.common.AttributeKey; import io.opentelemetry.api.common.Attributes; +import io.opentelemetry.api.common.KeyValue; import io.opentelemetry.api.incubator.events.EventLogger; import io.opentelemetry.api.incubator.logs.ExtendedLogRecordBuilder; -import io.opentelemetry.api.incubator.logs.KeyAnyValue; import io.opentelemetry.api.logs.Logger; import io.opentelemetry.api.logs.Severity; import io.opentelemetry.api.metrics.LongCounter; @@ -50,7 +50,6 @@ import io.opentelemetry.proto.collector.trace.v1.ExportTraceServiceResponse; import io.opentelemetry.proto.common.v1.AnyValue; import io.opentelemetry.proto.common.v1.ArrayValue; -import io.opentelemetry.proto.common.v1.KeyValue; import io.opentelemetry.proto.common.v1.KeyValueList; import io.opentelemetry.proto.logs.v1.ResourceLogs; import io.opentelemetry.proto.logs.v1.ScopeLogs; @@ -329,7 +328,7 @@ private static void testTraceExport(SpanExporter spanExporter) { ResourceSpans resourceSpans = request.getResourceSpans(0); assertThat(resourceSpans.getResource().getAttributesList()) .contains( - KeyValue.newBuilder() + io.opentelemetry.proto.common.v1.KeyValue.newBuilder() .setKey(SERVICE_NAME.getKey()) .setValue(AnyValue.newBuilder().setStringValue("integration test").build()) .build()); @@ -348,7 +347,7 @@ private static void testTraceExport(SpanExporter spanExporter) { assertThat(protoSpan.getAttributesList()) .isEqualTo( Collections.singletonList( - KeyValue.newBuilder() + io.opentelemetry.proto.common.v1.KeyValue.newBuilder() .setKey("key") .setValue(AnyValue.newBuilder().setStringValue("value").build()) .build())); @@ -494,7 +493,7 @@ private static void testMetricExport(MetricExporter metricExporter) { ResourceMetrics resourceMetrics = request.getResourceMetrics(0); assertThat(resourceMetrics.getResource().getAttributesList()) .contains( - KeyValue.newBuilder() + io.opentelemetry.proto.common.v1.KeyValue.newBuilder() .setKey(SERVICE_NAME.getKey()) .setValue(AnyValue.newBuilder().setStringValue("integration test").build()) .build()); @@ -519,7 +518,7 @@ private static void testMetricExport(MetricExporter metricExporter) { assertThat(dataPoint.getAttributesList()) .isEqualTo( Collections.singletonList( - KeyValue.newBuilder() + io.opentelemetry.proto.common.v1.KeyValue.newBuilder() .setKey("key") .setValue(AnyValue.newBuilder().setStringValue("value").build()) .build())); @@ -653,19 +652,19 @@ private static void testLogRecordExporter(LogRecordExporter logRecordExporter) { ((ExtendedLogRecordBuilder) logger.logRecordBuilder()) .setBody( of( - KeyAnyValue.of("str_key", of("value")), - KeyAnyValue.of("bool_key", of(true)), - KeyAnyValue.of("int_key", of(1L)), - KeyAnyValue.of("double_key", of(1.1)), - KeyAnyValue.of("bytes_key", of("value".getBytes(StandardCharsets.UTF_8))), - KeyAnyValue.of("arr_key", of(of("value"), of(1L))), - KeyAnyValue.of( + KeyValue.of("str_key", of("value")), + KeyValue.of("bool_key", of(true)), + KeyValue.of("int_key", of(1L)), + KeyValue.of("double_key", of(1.1)), + KeyValue.of("bytes_key", of("value".getBytes(StandardCharsets.UTF_8))), + KeyValue.of("arr_key", of(of("value"), of(1L))), + KeyValue.of( "kv_list", of( - KeyAnyValue.of("child_str_key", of("value")), - KeyAnyValue.of( + KeyValue.of("child_str_key", of("value")), + KeyValue.of( "child_kv_list", - of(KeyAnyValue.of("grandchild_str_key", of("value")))))))) + of(KeyValue.of("grandchild_str_key", of("value")))))))) .setTimestamp(100, TimeUnit.NANOSECONDS) .setAllAttributes(Attributes.builder().put("key", "value").build()) .setSeverity(Severity.DEBUG) @@ -688,7 +687,7 @@ private static void testLogRecordExporter(LogRecordExporter logRecordExporter) { ResourceLogs resourceLogs = request.getResourceLogs(0); assertThat(resourceLogs.getResource().getAttributesList()) .contains( - KeyValue.newBuilder() + io.opentelemetry.proto.common.v1.KeyValue.newBuilder() .setKey(SERVICE_NAME.getKey()) .setValue(AnyValue.newBuilder().setStringValue("integration test").build()) .build()); @@ -706,27 +705,27 @@ private static void testLogRecordExporter(LogRecordExporter logRecordExporter) { .setKvlistValue( KeyValueList.newBuilder() .addValues( - KeyValue.newBuilder() + io.opentelemetry.proto.common.v1.KeyValue.newBuilder() .setKey("str_key") .setValue(AnyValue.newBuilder().setStringValue("value").build()) .build()) .addValues( - KeyValue.newBuilder() + io.opentelemetry.proto.common.v1.KeyValue.newBuilder() .setKey("bool_key") .setValue(AnyValue.newBuilder().setBoolValue(true).build()) .build()) .addValues( - KeyValue.newBuilder() + io.opentelemetry.proto.common.v1.KeyValue.newBuilder() .setKey("int_key") .setValue(AnyValue.newBuilder().setIntValue(1).build()) .build()) .addValues( - KeyValue.newBuilder() + io.opentelemetry.proto.common.v1.KeyValue.newBuilder() .setKey("double_key") .setValue(AnyValue.newBuilder().setDoubleValue(1.1).build()) .build()) .addValues( - KeyValue.newBuilder() + io.opentelemetry.proto.common.v1.KeyValue.newBuilder() .setKey("bytes_key") .setValue( AnyValue.newBuilder() @@ -736,7 +735,7 @@ private static void testLogRecordExporter(LogRecordExporter logRecordExporter) { .build()) .build()) .addValues( - KeyValue.newBuilder() + io.opentelemetry.proto.common.v1.KeyValue.newBuilder() .setKey("arr_key") .setValue( AnyValue.newBuilder() @@ -752,14 +751,15 @@ private static void testLogRecordExporter(LogRecordExporter logRecordExporter) { .build()) .build()) .addValues( - KeyValue.newBuilder() + io.opentelemetry.proto.common.v1.KeyValue.newBuilder() .setKey("kv_list") .setValue( AnyValue.newBuilder() .setKvlistValue( KeyValueList.newBuilder() .addValues( - KeyValue.newBuilder() + io.opentelemetry.proto.common.v1.KeyValue + .newBuilder() .setKey("child_str_key") .setValue( AnyValue.newBuilder() @@ -767,14 +767,17 @@ private static void testLogRecordExporter(LogRecordExporter logRecordExporter) { .build()) .build()) .addValues( - KeyValue.newBuilder() + io.opentelemetry.proto.common.v1.KeyValue + .newBuilder() .setKey("child_kv_list") .setValue( AnyValue.newBuilder() .setKvlistValue( KeyValueList.newBuilder() .addValues( - KeyValue.newBuilder() + io.opentelemetry.proto + .common.v1.KeyValue + .newBuilder() .setKey( "grandchild_str_key") .setValue( @@ -795,7 +798,7 @@ private static void testLogRecordExporter(LogRecordExporter logRecordExporter) { assertThat(protoLog1.getAttributesList()) .isEqualTo( Collections.singletonList( - KeyValue.newBuilder() + io.opentelemetry.proto.common.v1.KeyValue.newBuilder() .setKey("key") .setValue(AnyValue.newBuilder().setStringValue("value").build()) .build())); @@ -814,13 +817,13 @@ private static void testLogRecordExporter(LogRecordExporter logRecordExporter) { io.opentelemetry.proto.logs.v1.LogRecord protoLog2 = ilLogs.getLogRecords(1); assertThat(protoLog2.getBody().getKvlistValue().getValuesList()) .containsExactlyInAnyOrder( - KeyValue.newBuilder() + io.opentelemetry.proto.common.v1.KeyValue.newBuilder() .setKey("key") .setValue(AnyValue.newBuilder().setStringValue("value").build()) .build()); assertThat(protoLog2.getAttributesList()) .containsExactlyInAnyOrder( - KeyValue.newBuilder() + io.opentelemetry.proto.common.v1.KeyValue.newBuilder() .setKey("event.name") .setValue(AnyValue.newBuilder().setStringValue("namespace.event-name").build()) .build()); diff --git a/sdk/logs/src/main/java/io/opentelemetry/sdk/logs/SdkLogRecordBuilder.java b/sdk/logs/src/main/java/io/opentelemetry/sdk/logs/SdkLogRecordBuilder.java index 6ab1cafe648..ce77d076730 100644 --- a/sdk/logs/src/main/java/io/opentelemetry/sdk/logs/SdkLogRecordBuilder.java +++ b/sdk/logs/src/main/java/io/opentelemetry/sdk/logs/SdkLogRecordBuilder.java @@ -6,7 +6,7 @@ package io.opentelemetry.sdk.logs; import io.opentelemetry.api.common.AttributeKey; -import io.opentelemetry.api.incubator.logs.AnyValue; +import io.opentelemetry.api.common.Value; import io.opentelemetry.api.incubator.logs.ExtendedLogRecordBuilder; import io.opentelemetry.api.logs.LogRecordBuilder; import io.opentelemetry.api.logs.Severity; @@ -14,8 +14,6 @@ import io.opentelemetry.context.Context; import io.opentelemetry.sdk.common.InstrumentationScopeInfo; import io.opentelemetry.sdk.internal.AttributesMap; -import io.opentelemetry.sdk.logs.data.Body; -import io.opentelemetry.sdk.logs.internal.AnyValueBody; import java.time.Instant; import java.util.concurrent.TimeUnit; import javax.annotation.Nullable; @@ -32,7 +30,7 @@ final class SdkLogRecordBuilder implements ExtendedLogRecordBuilder { @Nullable private Context context; private Severity severity = Severity.UNDEFINED_SEVERITY_NUMBER; @Nullable private String severityText; - private Body body = Body.empty(); + @Nullable private Value body; @Nullable private AttributesMap attributes; SdkLogRecordBuilder( @@ -88,13 +86,12 @@ public SdkLogRecordBuilder setSeverityText(String severityText) { @Override public SdkLogRecordBuilder setBody(String body) { - this.body = AnyValueBody.create(AnyValue.of(body)); - return this; + return setBody(Value.of(body)); } @Override - public LogRecordBuilder setBody(AnyValue value) { - this.body = AnyValueBody.create(value); + public SdkLogRecordBuilder setBody(Value value) { + this.body = value; return this; } diff --git a/sdk/logs/src/main/java/io/opentelemetry/sdk/logs/SdkLogRecordData.java b/sdk/logs/src/main/java/io/opentelemetry/sdk/logs/SdkLogRecordData.java index dd77c488f89..1927a0ec572 100644 --- a/sdk/logs/src/main/java/io/opentelemetry/sdk/logs/SdkLogRecordData.java +++ b/sdk/logs/src/main/java/io/opentelemetry/sdk/logs/SdkLogRecordData.java @@ -7,10 +7,10 @@ import com.google.auto.value.AutoValue; import io.opentelemetry.api.common.Attributes; +import io.opentelemetry.api.common.Value; import io.opentelemetry.api.logs.Severity; import io.opentelemetry.api.trace.SpanContext; import io.opentelemetry.sdk.common.InstrumentationScopeInfo; -import io.opentelemetry.sdk.logs.data.Body; import io.opentelemetry.sdk.logs.data.LogRecordData; import io.opentelemetry.sdk.resources.Resource; import javax.annotation.Nullable; @@ -31,7 +31,7 @@ static SdkLogRecordData create( SpanContext spanContext, Severity severity, @Nullable String severityText, - Body body, + @Nullable Value body, Attributes attributes, int totalAttributeCount) { return new AutoValue_SdkLogRecordData( @@ -42,8 +42,21 @@ static SdkLogRecordData create( spanContext, severity, severityText, - body, attributes, - totalAttributeCount); + totalAttributeCount, + body); + } + + @Override + @Nullable + public abstract Value getBodyValue(); + + @Override + @SuppressWarnings("deprecation") // Implementation of deprecated method + public io.opentelemetry.sdk.logs.data.Body getBody() { + Value valueBody = getBodyValue(); + return valueBody == null + ? io.opentelemetry.sdk.logs.data.Body.empty() + : io.opentelemetry.sdk.logs.data.Body.string(valueBody.asString()); } } diff --git a/sdk/logs/src/main/java/io/opentelemetry/sdk/logs/SdkReadWriteLogRecord.java b/sdk/logs/src/main/java/io/opentelemetry/sdk/logs/SdkReadWriteLogRecord.java index c237edff511..881f1d124ee 100644 --- a/sdk/logs/src/main/java/io/opentelemetry/sdk/logs/SdkReadWriteLogRecord.java +++ b/sdk/logs/src/main/java/io/opentelemetry/sdk/logs/SdkReadWriteLogRecord.java @@ -7,12 +7,12 @@ import io.opentelemetry.api.common.AttributeKey; import io.opentelemetry.api.common.Attributes; +import io.opentelemetry.api.common.Value; import io.opentelemetry.api.internal.GuardedBy; import io.opentelemetry.api.logs.Severity; import io.opentelemetry.api.trace.SpanContext; import io.opentelemetry.sdk.common.InstrumentationScopeInfo; import io.opentelemetry.sdk.internal.AttributesMap; -import io.opentelemetry.sdk.logs.data.Body; import io.opentelemetry.sdk.logs.data.LogRecordData; import io.opentelemetry.sdk.resources.Resource; import javax.annotation.Nullable; @@ -29,7 +29,7 @@ class SdkReadWriteLogRecord implements ReadWriteLogRecord { private final SpanContext spanContext; private final Severity severity; @Nullable private final String severityText; - private final Body body; + @Nullable private final Value body; private final Object lock = new Object(); @GuardedBy("lock") @@ -45,7 +45,7 @@ private SdkReadWriteLogRecord( SpanContext spanContext, Severity severity, @Nullable String severityText, - Body body, + @Nullable Value body, @Nullable AttributesMap attributes) { this.logLimits = logLimits; this.resource = resource; @@ -69,7 +69,7 @@ static SdkReadWriteLogRecord create( SpanContext spanContext, Severity severity, @Nullable String severityText, - Body body, + @Nullable Value body, @Nullable AttributesMap attributes) { return new SdkReadWriteLogRecord( logLimits, diff --git a/sdk/logs/src/main/java/io/opentelemetry/sdk/logs/data/Body.java b/sdk/logs/src/main/java/io/opentelemetry/sdk/logs/data/Body.java index 2dc7957de91..fda485f5eaf 100644 --- a/sdk/logs/src/main/java/io/opentelemetry/sdk/logs/data/Body.java +++ b/sdk/logs/src/main/java/io/opentelemetry/sdk/logs/data/Body.java @@ -5,6 +5,8 @@ package io.opentelemetry.sdk.logs.data; +import io.opentelemetry.api.common.Value; +import io.opentelemetry.api.common.ValueType; import javax.annotation.concurrent.Immutable; /** @@ -14,16 +16,21 @@ * log data model. * * @since 1.27.0 + * @deprecated Use {@link LogRecordData#getBodyValue()} and {@link Value}. */ @Immutable +@Deprecated public interface Body { - /** An enum that represents all the possible value types for an {@code Body}. */ + /** + * An enum that represents all the possible value types for an {@code Body}. + * + * @deprecated Use {@link Value#getType()}. + */ + @Deprecated enum Type { EMPTY, STRING - // TODO (jack-berg): Add ANY_VALUE type when API for setting body to AnyValue is stable - // ANY_VALUE } /** @@ -45,9 +52,20 @@ static Body empty() { return EmptyBody.INSTANCE; } - /** Returns the String value of this {@code Body}. */ + /** + * Returns the String value of this {@code Body}. + * + *

      If the log record body is some {@link ValueType} other than {@link ValueType#STRING}, this + * returns {@link Value#asString()}. Consumers should use {@link LogRecordData#getBodyValue()} + * instead. + */ String asString(); - /** Returns the type of the {@code Body}. */ + /** + * Returns the type of the {@code Body}. + * + * @deprecated Use {@link Value#getType()}. + */ + @Deprecated Type getType(); } diff --git a/sdk/logs/src/main/java/io/opentelemetry/sdk/logs/data/EmptyBody.java b/sdk/logs/src/main/java/io/opentelemetry/sdk/logs/data/EmptyBody.java index c70e866ee78..921895e6125 100644 --- a/sdk/logs/src/main/java/io/opentelemetry/sdk/logs/data/EmptyBody.java +++ b/sdk/logs/src/main/java/io/opentelemetry/sdk/logs/data/EmptyBody.java @@ -5,6 +5,7 @@ package io.opentelemetry.sdk.logs.data; +@SuppressWarnings("deprecation") // Implementation of deprecated Body enum EmptyBody implements Body { INSTANCE; diff --git a/sdk/logs/src/main/java/io/opentelemetry/sdk/logs/data/LogRecordData.java b/sdk/logs/src/main/java/io/opentelemetry/sdk/logs/data/LogRecordData.java index eb2f8dcde81..6a896e48530 100644 --- a/sdk/logs/src/main/java/io/opentelemetry/sdk/logs/data/LogRecordData.java +++ b/sdk/logs/src/main/java/io/opentelemetry/sdk/logs/data/LogRecordData.java @@ -6,6 +6,8 @@ package io.opentelemetry.sdk.logs.data; import io.opentelemetry.api.common.Attributes; +import io.opentelemetry.api.common.Value; +import io.opentelemetry.api.common.ValueType; import io.opentelemetry.api.logs.Severity; import io.opentelemetry.api.trace.SpanContext; import io.opentelemetry.sdk.common.InstrumentationScopeInfo; @@ -46,9 +48,25 @@ public interface LogRecordData { @Nullable String getSeverityText(); - /** Returns the body for this log, or {@link Body#empty()} if unset. */ + /** + * Returns the body for this log, or {@link Body#empty()} if unset. + * + *

      If the body has been set to some {@link ValueType} other than {@link ValueType#STRING}, this + * will return a {@link Body} with a string representation of the {@link Value}. + * + * @deprecated Use {@link #getBodyValue()} instead. + */ + @Deprecated Body getBody(); + /** Returns the {@link Value} representation of the log body, of null if unset. */ + @Nullable + @SuppressWarnings("deprecation") // Default impl uses deprecated code for backwards compatibility + default Value getBodyValue() { + Body body = getBody(); + return body.getType() == Body.Type.EMPTY ? null : Value.of(body.asString()); + } + /** Returns the attributes for this log, or {@link Attributes#empty()} if unset. */ Attributes getAttributes(); diff --git a/sdk/logs/src/main/java/io/opentelemetry/sdk/logs/data/StringBody.java b/sdk/logs/src/main/java/io/opentelemetry/sdk/logs/data/StringBody.java index 4496528f7f0..a08dcab55fa 100644 --- a/sdk/logs/src/main/java/io/opentelemetry/sdk/logs/data/StringBody.java +++ b/sdk/logs/src/main/java/io/opentelemetry/sdk/logs/data/StringBody.java @@ -10,6 +10,7 @@ @Immutable @AutoValue +@SuppressWarnings("deprecation") // Implementation of deprecated Body abstract class StringBody implements Body { StringBody() {} diff --git a/sdk/logs/src/main/java/io/opentelemetry/sdk/logs/internal/AnyValueBody.java b/sdk/logs/src/main/java/io/opentelemetry/sdk/logs/internal/AnyValueBody.java deleted file mode 100644 index fdf2b936cd1..00000000000 --- a/sdk/logs/src/main/java/io/opentelemetry/sdk/logs/internal/AnyValueBody.java +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package io.opentelemetry.sdk.logs.internal; - -import io.opentelemetry.api.incubator.logs.AnyValue; -import io.opentelemetry.sdk.logs.data.Body; -import javax.annotation.concurrent.Immutable; - -@Immutable -public final class AnyValueBody implements Body { - - private final AnyValue value; - - private AnyValueBody(AnyValue value) { - this.value = value; - } - - public static Body create(AnyValue value) { - return new AnyValueBody(value); - } - - @Override - public Type getType() { - return Type.STRING; - } - - @Override - public String asString() { - return value.asString(); - } - - public AnyValue asAnyValue() { - return value; - } - - @Override - public String toString() { - return "AnyValueBody{" + asString() + "}"; - } -} diff --git a/sdk/logs/src/main/java/io/opentelemetry/sdk/logs/internal/SdkEventBuilder.java b/sdk/logs/src/main/java/io/opentelemetry/sdk/logs/internal/SdkEventBuilder.java index 5daa5ae56f4..2378d9e6dad 100644 --- a/sdk/logs/src/main/java/io/opentelemetry/sdk/logs/internal/SdkEventBuilder.java +++ b/sdk/logs/src/main/java/io/opentelemetry/sdk/logs/internal/SdkEventBuilder.java @@ -7,8 +7,8 @@ import io.opentelemetry.api.common.AttributeKey; import io.opentelemetry.api.common.Attributes; +import io.opentelemetry.api.common.Value; import io.opentelemetry.api.incubator.events.EventBuilder; -import io.opentelemetry.api.incubator.logs.AnyValue; import io.opentelemetry.api.incubator.logs.ExtendedLogRecordBuilder; import io.opentelemetry.api.logs.LogRecordBuilder; import io.opentelemetry.api.logs.Severity; @@ -23,7 +23,7 @@ class SdkEventBuilder implements EventBuilder { private static final AttributeKey EVENT_NAME = AttributeKey.stringKey("event.name"); - private final Map> payload = new HashMap<>(); + private final Map> payload = new HashMap<>(); private final Clock clock; private final LogRecordBuilder logRecordBuilder; private final String eventName; @@ -36,7 +36,7 @@ class SdkEventBuilder implements EventBuilder { } @Override - public EventBuilder put(String key, AnyValue value) { + public EventBuilder put(String key, Value value) { payload.put(key, value); return this; } @@ -76,7 +76,7 @@ public EventBuilder setAttributes(Attributes attributes) { @Override public void emit() { if (!payload.isEmpty()) { - ((ExtendedLogRecordBuilder) logRecordBuilder).setBody(AnyValue.of(payload)); + ((ExtendedLogRecordBuilder) logRecordBuilder).setBody(Value.of(payload)); } if (!hasTimestamp) { logRecordBuilder.setTimestamp(clock.now(), TimeUnit.NANOSECONDS); diff --git a/sdk/logs/src/test/java/io/opentelemetry/sdk/logs/AnyValueBodyTest.java b/sdk/logs/src/test/java/io/opentelemetry/sdk/logs/AnyValueBodyTest.java deleted file mode 100644 index 8ac803c5c7e..00000000000 --- a/sdk/logs/src/test/java/io/opentelemetry/sdk/logs/AnyValueBodyTest.java +++ /dev/null @@ -1,156 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package io.opentelemetry.sdk.logs; - -import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.assertThat; - -import io.opentelemetry.api.incubator.logs.AnyValue; -import io.opentelemetry.api.incubator.logs.ExtendedLogRecordBuilder; -import io.opentelemetry.api.incubator.logs.KeyAnyValue; -import io.opentelemetry.api.logs.Logger; -import io.opentelemetry.sdk.logs.export.SimpleLogRecordProcessor; -import io.opentelemetry.sdk.logs.internal.AnyValueBody; -import io.opentelemetry.sdk.testing.exporter.InMemoryLogRecordExporter; -import java.nio.charset.StandardCharsets; -import java.util.LinkedHashMap; -import org.junit.jupiter.api.Test; - -class AnyValueBodyTest { - - @Test - @SuppressWarnings("DoubleBraceInitialization") - void anyValueBody() { - InMemoryLogRecordExporter exporter = InMemoryLogRecordExporter.create(); - SdkLoggerProvider provider = - SdkLoggerProvider.builder() - .addLogRecordProcessor(SimpleLogRecordProcessor.create(exporter)) - .build(); - Logger logger = provider.get(AnyValueBodyTest.class.getName()); - - // AnyValue can be a primitive type, like a string, long, double, boolean - extendedLogRecordBuilder(logger).setBody(AnyValue.of(1)).emit(); - assertThat(exporter.getFinishedLogRecordItems()) - .hasSize(1) - .satisfiesExactly( - logRecordData -> { - // TODO (jack-berg): add assertion when ANY_VALUE is added to Body.Type - // assertThat(logRecordData.getBody().getType()).isEqualTo(Body.Type.ANY_VALUE); - assertThat(logRecordData.getBody().asString()).isEqualTo("1"); - assertThat(((AnyValueBody) logRecordData.getBody()).asAnyValue()) - .isEqualTo(AnyValue.of(1)); - }); - exporter.reset(); - - // ...or a byte array of raw data - extendedLogRecordBuilder(logger) - .setBody(AnyValue.of("hello world".getBytes(StandardCharsets.UTF_8))) - .emit(); - assertThat(exporter.getFinishedLogRecordItems()) - .hasSize(1) - .satisfiesExactly( - logRecordData -> { - // TODO (jack-berg): add assertion when ANY_VALUE is added to Body.Type - // assertThat(logRecordData.getBody().getType()).isEqualTo(Body.Type.ANY_VALUE); - assertThat(logRecordData.getBody().asString()).isEqualTo("aGVsbG8gd29ybGQ="); - assertThat(((AnyValueBody) logRecordData.getBody()).asAnyValue()) - .isEqualTo(AnyValue.of("hello world".getBytes(StandardCharsets.UTF_8))); - }); - exporter.reset(); - - // But most commonly it will be used to represent complex structured like a map - extendedLogRecordBuilder(logger) - .setBody( - // The protocol data structure uses a repeated KeyValue to represent a map: - // https://github.com/open-telemetry/opentelemetry-proto/blob/ac3242b03157295e4ee9e616af53b81517b06559/opentelemetry/proto/common/v1/common.proto#L59 - // The comment says that keys aren't allowed to repeat themselves, and because its - // represented as a repeated KeyValue, we need to at least offer the ability to preserve - // order. - // Accepting a Map> makes for a cleaner API, but ordering of the - // entries is lost. To accommodate use cases where ordering should be preserved we - // accept an array of key value pairs, but also a map based alternative (see the - // key_value_list_key entry). - AnyValue.of( - KeyAnyValue.of("str_key", AnyValue.of("value")), - KeyAnyValue.of("bool_key", AnyValue.of(true)), - KeyAnyValue.of("long_key", AnyValue.of(1L)), - KeyAnyValue.of("double_key", AnyValue.of(1.1)), - KeyAnyValue.of("bytes_key", AnyValue.of("bytes".getBytes(StandardCharsets.UTF_8))), - KeyAnyValue.of( - "arr_key", - AnyValue.of(AnyValue.of("entry1"), AnyValue.of(2), AnyValue.of(3.3))), - KeyAnyValue.of( - "key_value_list_key", - AnyValue.of( - new LinkedHashMap>() { - { - put("child_str_key1", AnyValue.of("child_value1")); - put("child_str_key2", AnyValue.of("child_value2")); - } - })))) - .emit(); - assertThat(exporter.getFinishedLogRecordItems()) - .hasSize(1) - .satisfiesExactly( - logRecordData -> { - // TODO (jack-berg): add assertion when ANY_VALUE is added to Body.Type - // assertThat(logRecordData.getBody().getType()).isEqualTo(Body.Type.ANY_VALUE); - assertThat(logRecordData.getBody().asString()) - .isEqualTo( - "[" - + "str_key=value, " - + "bool_key=true, " - + "long_key=1, " - + "double_key=1.1, " - + "bytes_key=Ynl0ZXM=, " - + "arr_key=[entry1, 2, 3.3], " - + "key_value_list_key=[child_str_key1=child_value1, child_str_key2=child_value2]" - + "]"); - assertThat(((AnyValueBody) logRecordData.getBody()).asAnyValue()) - .isEqualTo( - AnyValue.of( - KeyAnyValue.of("str_key", AnyValue.of("value")), - KeyAnyValue.of("bool_key", AnyValue.of(true)), - KeyAnyValue.of("long_key", AnyValue.of(1L)), - KeyAnyValue.of("double_key", AnyValue.of(1.1)), - KeyAnyValue.of( - "bytes_key", AnyValue.of("bytes".getBytes(StandardCharsets.UTF_8))), - KeyAnyValue.of( - "arr_key", - AnyValue.of(AnyValue.of("entry1"), AnyValue.of(2), AnyValue.of(3.3))), - KeyAnyValue.of( - "key_value_list_key", - AnyValue.of( - new LinkedHashMap>() { - { - put("child_str_key1", AnyValue.of("child_value1")); - put("child_str_key2", AnyValue.of("child_value2")); - } - })))); - }); - exporter.reset(); - - // ..or an array (optionally with heterogeneous types) - extendedLogRecordBuilder(logger) - .setBody(AnyValue.of(AnyValue.of("entry1"), AnyValue.of("entry2"), AnyValue.of(3))) - .emit(); - assertThat(exporter.getFinishedLogRecordItems()) - .hasSize(1) - .satisfiesExactly( - logRecordData -> { - // TODO (jack-berg): add assertion when ANY_VALUE is added to Body.Type - // assertThat(logRecordData.getBody().getType()).isEqualTo(Body.Type.ANY_VALUE); - assertThat(logRecordData.getBody().asString()).isEqualTo("[entry1, entry2, 3]"); - assertThat(((AnyValueBody) logRecordData.getBody()).asAnyValue()) - .isEqualTo( - AnyValue.of(AnyValue.of("entry1"), AnyValue.of("entry2"), AnyValue.of(3))); - }); - exporter.reset(); - } - - ExtendedLogRecordBuilder extendedLogRecordBuilder(Logger logger) { - return (ExtendedLogRecordBuilder) logger.logRecordBuilder(); - } -} diff --git a/sdk/logs/src/test/java/io/opentelemetry/sdk/logs/ReadWriteLogRecordTest.java b/sdk/logs/src/test/java/io/opentelemetry/sdk/logs/ReadWriteLogRecordTest.java index ccb6c56ebbc..e671372c515 100644 --- a/sdk/logs/src/test/java/io/opentelemetry/sdk/logs/ReadWriteLogRecordTest.java +++ b/sdk/logs/src/test/java/io/opentelemetry/sdk/logs/ReadWriteLogRecordTest.java @@ -9,11 +9,11 @@ import static org.assertj.core.api.Assertions.assertThat; import io.opentelemetry.api.common.Attributes; +import io.opentelemetry.api.common.Value; import io.opentelemetry.api.logs.Severity; import io.opentelemetry.api.trace.SpanContext; import io.opentelemetry.sdk.common.InstrumentationScopeInfo; import io.opentelemetry.sdk.internal.AttributesMap; -import io.opentelemetry.sdk.logs.data.Body; import io.opentelemetry.sdk.resources.Resource; import org.junit.jupiter.api.Test; @@ -49,7 +49,7 @@ void allHandlesEmpty() { } SdkReadWriteLogRecord buildLogRecord() { - Body body = Body.string("bod"); + Value body = Value.of("bod"); AttributesMap initialAttributes = AttributesMap.create(100, 200); initialAttributes.put(stringKey("foo"), "aaiosjfjioasdiojfjioasojifja"); initialAttributes.put(stringKey("untouched"), "yes"); diff --git a/sdk/logs/src/test/java/io/opentelemetry/sdk/logs/SdkLogRecordBuilderTest.java b/sdk/logs/src/test/java/io/opentelemetry/sdk/logs/SdkLogRecordBuilderTest.java index ff191032265..3c5743e673d 100644 --- a/sdk/logs/src/test/java/io/opentelemetry/sdk/logs/SdkLogRecordBuilderTest.java +++ b/sdk/logs/src/test/java/io/opentelemetry/sdk/logs/SdkLogRecordBuilderTest.java @@ -10,6 +10,7 @@ import io.opentelemetry.api.common.AttributeKey; import io.opentelemetry.api.common.Attributes; +import io.opentelemetry.api.common.Value; import io.opentelemetry.api.logs.Severity; import io.opentelemetry.api.trace.Span; import io.opentelemetry.api.trace.SpanContext; @@ -18,7 +19,6 @@ import io.opentelemetry.context.Context; import io.opentelemetry.sdk.common.Clock; import io.opentelemetry.sdk.common.InstrumentationScopeInfo; -import io.opentelemetry.sdk.logs.data.Body; import io.opentelemetry.sdk.resources.Resource; import java.time.Instant; import java.util.concurrent.TimeUnit; @@ -105,7 +105,7 @@ void emit_NoFields() { assertThat(emittedLog.get().toLogRecordData()) .hasResource(RESOURCE) .hasInstrumentationScope(SCOPE_INFO) - .hasBody(Body.empty().asString()) + .hasBody((Value) null) .hasTimestamp(0L) .hasObservedTimestamp(10L) .hasAttributes(Attributes.empty()) diff --git a/sdk/logs/src/test/java/io/opentelemetry/sdk/logs/ValueBodyTest.java b/sdk/logs/src/test/java/io/opentelemetry/sdk/logs/ValueBodyTest.java new file mode 100644 index 00000000000..cd5820bb974 --- /dev/null +++ b/sdk/logs/src/test/java/io/opentelemetry/sdk/logs/ValueBodyTest.java @@ -0,0 +1,171 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.sdk.logs; + +import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.assertThat; + +import io.opentelemetry.api.common.KeyValue; +import io.opentelemetry.api.common.Value; +import io.opentelemetry.api.common.ValueType; +import io.opentelemetry.api.incubator.logs.ExtendedLogRecordBuilder; +import io.opentelemetry.api.logs.Logger; +import io.opentelemetry.sdk.logs.export.SimpleLogRecordProcessor; +import io.opentelemetry.sdk.testing.exporter.InMemoryLogRecordExporter; +import java.nio.ByteBuffer; +import java.nio.charset.StandardCharsets; +import java.util.LinkedHashMap; +import org.junit.jupiter.api.Test; + +class ValueBodyTest { + + @Test + @SuppressWarnings("DoubleBraceInitialization") + void valueBody() { + InMemoryLogRecordExporter exporter = InMemoryLogRecordExporter.create(); + SdkLoggerProvider provider = + SdkLoggerProvider.builder() + .addLogRecordProcessor(SimpleLogRecordProcessor.create(exporter)) + .build(); + Logger logger = provider.get(ValueBodyTest.class.getName()); + + // Value can be a primitive type, like a string, long, double, boolean + extendedLogRecordBuilder(logger).setBody(Value.of(1)).emit(); + assertThat(exporter.getFinishedLogRecordItems()) + .hasSize(1) + .satisfiesExactly( + logRecordData -> { + assertThat(logRecordData.getBodyValue()) + .isNotNull() + .satisfies( + body -> { + assertThat(body.getType()).isEqualTo(ValueType.LONG); + assertThat((Long) body.getValue()).isEqualTo(1L); + }); + }); + exporter.reset(); + + // ...or a byte array of raw data + extendedLogRecordBuilder(logger) + .setBody(Value.of("hello world".getBytes(StandardCharsets.UTF_8))) + .emit(); + assertThat(exporter.getFinishedLogRecordItems()) + .hasSize(1) + .satisfiesExactly( + logRecordData -> { + assertThat(logRecordData.getBodyValue()) + .isNotNull() + .satisfies( + body -> { + assertThat(body.getType()).isEqualTo(ValueType.BYTES); + assertThat((ByteBuffer) body.getValue()) + .isEqualTo( + ByteBuffer.wrap("hello world".getBytes(StandardCharsets.UTF_8))); + }); + }); + exporter.reset(); + + // But most commonly it will be used to represent complex structured like a map + extendedLogRecordBuilder(logger) + .setBody( + // The protocol data structure uses a repeated KeyValue to represent a map: + // https://github.com/open-telemetry/opentelemetry-proto/blob/ac3242b03157295e4ee9e616af53b81517b06559/opentelemetry/proto/common/v1/common.proto#L59 + // The comment says that keys aren't allowed to repeat themselves, and because its + // represented as a repeated KeyValue, we need to at least offer the ability to preserve + // order. + // Accepting a Map> makes for a cleaner API, but ordering of the + // entries is lost. To accommodate use cases where ordering should be preserved we + // accept an array of key value pairs, but also a map based alternative (see the + // key_value_list_key entry). + Value.of( + KeyValue.of("str_key", Value.of("value")), + KeyValue.of("bool_key", Value.of(true)), + KeyValue.of("long_key", Value.of(1L)), + KeyValue.of("double_key", Value.of(1.1)), + KeyValue.of("bytes_key", Value.of("bytes".getBytes(StandardCharsets.UTF_8))), + KeyValue.of("arr_key", Value.of(Value.of("entry1"), Value.of(2), Value.of(3.3))), + KeyValue.of( + "key_value_list_key", + Value.of( + new LinkedHashMap>() { + { + put("child_str_key1", Value.of("child_value1")); + put("child_str_key2", Value.of("child_value2")); + } + })))) + .emit(); + assertThat(exporter.getFinishedLogRecordItems()) + .hasSize(1) + .satisfiesExactly( + logRecordData -> { + assertThat(logRecordData.getBodyValue()) + .isNotNull() + // TODO: use fluent asserts when available. See + // https://github.com/open-telemetry/opentelemetry-java/pull/6509 + .satisfies( + body -> { + assertThat(body.getType()).isEqualTo(ValueType.KEY_VALUE_LIST); + assertThat(body) + .isEqualTo( + Value.of( + KeyValue.of("str_key", Value.of("value")), + KeyValue.of("bool_key", Value.of(true)), + KeyValue.of("long_key", Value.of(1L)), + KeyValue.of("double_key", Value.of(1.1)), + KeyValue.of( + "bytes_key", + Value.of("bytes".getBytes(StandardCharsets.UTF_8))), + KeyValue.of( + "arr_key", + Value.of(Value.of("entry1"), Value.of(2), Value.of(3.3))), + KeyValue.of( + "key_value_list_key", + Value.of( + new LinkedHashMap>() { + { + put("child_str_key1", Value.of("child_value1")); + put("child_str_key2", Value.of("child_value2")); + } + })))); + assertThat(body.asString()) + .isEqualTo( + "[" + + "str_key=value, " + + "bool_key=true, " + + "long_key=1, " + + "double_key=1.1, " + + "bytes_key=Ynl0ZXM=, " + + "arr_key=[entry1, 2, 3.3], " + + "key_value_list_key=[child_str_key1=child_value1, child_str_key2=child_value2]" + + "]"); + }); + }); + exporter.reset(); + + // ..or an array (optionally with heterogeneous types) + extendedLogRecordBuilder(logger) + .setBody(Value.of(Value.of("entry1"), Value.of("entry2"), Value.of(3))) + .emit(); + assertThat(exporter.getFinishedLogRecordItems()) + .hasSize(1) + .satisfiesExactly( + logRecordData -> { + assertThat(logRecordData.getBodyValue()) + .isNotNull() + .satisfies( + body -> { + assertThat(body.getType()).isEqualTo(ValueType.ARRAY); + assertThat(body) + .isEqualTo( + Value.of(Value.of("entry1"), Value.of("entry2"), Value.of(3))); + }); + }); + exporter.reset(); + } + + ExtendedLogRecordBuilder extendedLogRecordBuilder(Logger logger) { + return (ExtendedLogRecordBuilder) logger.logRecordBuilder(); + } +} diff --git a/sdk/logs/src/test/java/io/opentelemetry/sdk/logs/data/BodyTest.java b/sdk/logs/src/test/java/io/opentelemetry/sdk/logs/data/BodyTest.java index d57fb085fb0..57143d4f49f 100644 --- a/sdk/logs/src/test/java/io/opentelemetry/sdk/logs/data/BodyTest.java +++ b/sdk/logs/src/test/java/io/opentelemetry/sdk/logs/data/BodyTest.java @@ -9,6 +9,7 @@ import org.junit.jupiter.api.Test; +@SuppressWarnings("deprecation") // Testing deprecated code class BodyTest { @Test diff --git a/sdk/logs/src/test/java/io/opentelemetry/sdk/logs/internal/SdkEventLoggerProviderTest.java b/sdk/logs/src/test/java/io/opentelemetry/sdk/logs/internal/SdkEventLoggerProviderTest.java index 71f48757207..d033ba9bc15 100644 --- a/sdk/logs/src/test/java/io/opentelemetry/sdk/logs/internal/SdkEventLoggerProviderTest.java +++ b/sdk/logs/src/test/java/io/opentelemetry/sdk/logs/internal/SdkEventLoggerProviderTest.java @@ -12,8 +12,8 @@ import com.google.common.collect.ImmutableMap; import io.opentelemetry.api.common.AttributeKey; import io.opentelemetry.api.common.Attributes; +import io.opentelemetry.api.common.Value; import io.opentelemetry.api.incubator.events.EventLogger; -import io.opentelemetry.api.incubator.logs.AnyValue; import io.opentelemetry.api.logs.Severity; import io.opentelemetry.sdk.common.Clock; import io.opentelemetry.sdk.common.InstrumentationScopeInfo; @@ -69,10 +69,8 @@ void builder() { .put("extra-attribute", "value") .build()); assertThat(seenLog.get().toLogRecordData().getObservedTimestampEpochNanos()).isPositive(); - AnyValue expectedPayload = - AnyValue.of(Collections.singletonMap("key1", AnyValue.of("value1"))); - assertThat(((AnyValueBody) seenLog.get().toLogRecordData().getBody()).asAnyValue()) - .isEqualTo(expectedPayload); + Value expectedPayload = Value.of(Collections.singletonMap("key1", Value.of("value1"))); + assertThat(seenLog.get().toLogRecordData().getBodyValue()).isEqualTo(expectedPayload); } @Test @@ -91,13 +89,13 @@ void eventBuilder_FullPayload() { .put("longArrKey", 1L, 2L) .put("doubleArrKey", 1.0, 2.0) .put("boolArrKey", true, false) - // Set AnyValue types to encode complex data + // Set complex data .put( - "anyValueKey", - AnyValue.of( + "valueKey", + Value.of( ImmutableMap.of( - "childKey1", AnyValue.of("value"), - "childKey2", AnyValue.of("value")))) + "childKey1", Value.of("value"), + "childKey2", Value.of("value")))) // Helper methods to set AttributeKey types .put(AttributeKey.stringKey("attrStringKey"), "value") .put(AttributeKey.longKey("attrLongKey"), 1L) @@ -109,38 +107,31 @@ void eventBuilder_FullPayload() { .put(AttributeKey.booleanArrayKey("attrBoolArrKey"), Arrays.asList(true, false)) .emit(); - Map> expectedPayload = new HashMap<>(); - expectedPayload.put("stringKey", AnyValue.of("value")); - expectedPayload.put("longKey", AnyValue.of(1L)); - expectedPayload.put("doubleKey", AnyValue.of(1.0)); - expectedPayload.put("boolKey", AnyValue.of(true)); + Map> expectedPayload = new HashMap<>(); + expectedPayload.put("stringKey", Value.of("value")); + expectedPayload.put("longKey", Value.of(1L)); + expectedPayload.put("doubleKey", Value.of(1.0)); + expectedPayload.put("boolKey", Value.of(true)); expectedPayload.put( - "stringArrKey", AnyValue.of(Arrays.asList(AnyValue.of("value1"), AnyValue.of("value2")))); - expectedPayload.put("longArrKey", AnyValue.of(Arrays.asList(AnyValue.of(1L), AnyValue.of(2L)))); + "stringArrKey", Value.of(Arrays.asList(Value.of("value1"), Value.of("value2")))); + expectedPayload.put("longArrKey", Value.of(Arrays.asList(Value.of(1L), Value.of(2L)))); + expectedPayload.put("doubleArrKey", Value.of(Arrays.asList(Value.of(1.0), Value.of(2.0)))); + expectedPayload.put("boolArrKey", Value.of(Arrays.asList(Value.of(true), Value.of(false)))); expectedPayload.put( - "doubleArrKey", AnyValue.of(Arrays.asList(AnyValue.of(1.0), AnyValue.of(2.0)))); - expectedPayload.put( - "boolArrKey", AnyValue.of(Arrays.asList(AnyValue.of(true), AnyValue.of(false)))); - expectedPayload.put( - "anyValueKey", - AnyValue.of( + "valueKey", + Value.of( ImmutableMap.of( - "childKey1", AnyValue.of("value"), - "childKey2", AnyValue.of("value")))); - expectedPayload.put("attrStringKey", AnyValue.of("value")); - expectedPayload.put("attrLongKey", AnyValue.of(1L)); - expectedPayload.put("attrDoubleKey", AnyValue.of(1.0)); - expectedPayload.put("attrBoolKey", AnyValue.of(true)); - expectedPayload.put( - "attrStringArrKey", - AnyValue.of(Arrays.asList(AnyValue.of("value1"), AnyValue.of("value2")))); - expectedPayload.put( - "attrLongArrKey", AnyValue.of(Arrays.asList(AnyValue.of(1L), AnyValue.of(2L)))); - expectedPayload.put( - "attrDoubleArrKey", AnyValue.of(Arrays.asList(AnyValue.of(1.0), AnyValue.of(2.0)))); + "childKey1", Value.of("value"), + "childKey2", Value.of("value")))); + expectedPayload.put("attrStringKey", Value.of("value")); + expectedPayload.put("attrLongKey", Value.of(1L)); + expectedPayload.put("attrDoubleKey", Value.of(1.0)); + expectedPayload.put("attrBoolKey", Value.of(true)); expectedPayload.put( - "attrBoolArrKey", AnyValue.of(Arrays.asList(AnyValue.of(true), AnyValue.of(false)))); - assertThat(((AnyValueBody) seenLog.get().toLogRecordData().getBody()).asAnyValue()) - .isEqualTo(AnyValue.of(expectedPayload)); + "attrStringArrKey", Value.of(Arrays.asList(Value.of("value1"), Value.of("value2")))); + expectedPayload.put("attrLongArrKey", Value.of(Arrays.asList(Value.of(1L), Value.of(2L)))); + expectedPayload.put("attrDoubleArrKey", Value.of(Arrays.asList(Value.of(1.0), Value.of(2.0)))); + expectedPayload.put("attrBoolArrKey", Value.of(Arrays.asList(Value.of(true), Value.of(false)))); + assertThat(seenLog.get().toLogRecordData().getBodyValue()).isEqualTo(Value.of(expectedPayload)); } } diff --git a/sdk/testing/src/main/java/io/opentelemetry/sdk/testing/assertj/LogRecordDataAssert.java b/sdk/testing/src/main/java/io/opentelemetry/sdk/testing/assertj/LogRecordDataAssert.java index 7489cb135b5..11031aa9ef4 100644 --- a/sdk/testing/src/main/java/io/opentelemetry/sdk/testing/assertj/LogRecordDataAssert.java +++ b/sdk/testing/src/main/java/io/opentelemetry/sdk/testing/assertj/LogRecordDataAssert.java @@ -10,6 +10,7 @@ import io.opentelemetry.api.common.AttributeKey; import io.opentelemetry.api.common.Attributes; import io.opentelemetry.api.common.AttributesBuilder; +import io.opentelemetry.api.common.Value; import io.opentelemetry.api.logs.Severity; import io.opentelemetry.api.trace.SpanContext; import io.opentelemetry.sdk.common.InstrumentationScopeInfo; @@ -17,6 +18,7 @@ import io.opentelemetry.sdk.resources.Resource; import java.util.Arrays; import java.util.Map; +import java.util.Objects; import java.util.function.Consumer; import javax.annotation.Nullable; import org.assertj.core.api.AbstractAssert; @@ -54,8 +56,7 @@ public LogRecordDataAssert hasResource(Resource resource) { public LogRecordDataAssert hasResourceSatisfying(Consumer resource) { isNotNull(); resource.accept( - new ResourceAssert( - actual.getResource(), String.format("log [%s]", actual.getBody().asString()))); + new ResourceAssert(actual.getResource(), String.format("log [%s]", actual.getBodyValue()))); return this; } @@ -149,13 +150,19 @@ public LogRecordDataAssert hasSeverityText(String severityText) { /** Asserts the log has the given body. */ public LogRecordDataAssert hasBody(String body) { isNotNull(); - if (!actual.getBody().asString().equals(body)) { + return hasBody(Value.of(body)); + } + + /** Asserts the log has the given body. */ + public LogRecordDataAssert hasBody(@Nullable Value body) { + isNotNull(); + if (!Objects.equals(actual.getBodyValue(), body)) { failWithActualExpectedAndMessage( - actual.getBody(), + actual.getBodyValue(), body, "Expected log to have body <%s> but was <%s>", body, - actual.getBody().asString()); + actual.getBodyValue()); } return this; } diff --git a/sdk/testing/src/main/java/io/opentelemetry/sdk/testing/logs/TestLogRecordData.java b/sdk/testing/src/main/java/io/opentelemetry/sdk/testing/logs/TestLogRecordData.java index 7de560fac49..efb2fee37ca 100644 --- a/sdk/testing/src/main/java/io/opentelemetry/sdk/testing/logs/TestLogRecordData.java +++ b/sdk/testing/src/main/java/io/opentelemetry/sdk/testing/logs/TestLogRecordData.java @@ -7,14 +7,15 @@ import com.google.auto.value.AutoValue; import io.opentelemetry.api.common.Attributes; +import io.opentelemetry.api.common.Value; import io.opentelemetry.api.logs.Severity; import io.opentelemetry.api.trace.SpanContext; import io.opentelemetry.sdk.common.InstrumentationScopeInfo; -import io.opentelemetry.sdk.logs.data.Body; import io.opentelemetry.sdk.logs.data.LogRecordData; import io.opentelemetry.sdk.resources.Resource; import java.time.Instant; import java.util.concurrent.TimeUnit; +import javax.annotation.Nullable; import javax.annotation.concurrent.Immutable; /** @@ -24,6 +25,9 @@ */ @Immutable @AutoValue +@AutoValue.CopyAnnotations +// Carry suppression for Body to AutoValue implementation via @AutoValue.CopyAnnotations +@SuppressWarnings("deprecation") public abstract class TestLogRecordData implements LogRecordData { /** Creates a new Builder for creating an {@link LogRecordData} instance. */ @@ -35,11 +39,22 @@ public static Builder builder() { .setObservedTimestamp(0, TimeUnit.NANOSECONDS) .setSpanContext(SpanContext.getInvalid()) .setSeverity(Severity.UNDEFINED_SEVERITY_NUMBER) - .setBody("") .setAttributes(Attributes.empty()) .setTotalAttributeCount(0); } + @Deprecated + public io.opentelemetry.sdk.logs.data.Body getBody() { + Value valueBody = getBodyValue(); + return valueBody == null + ? io.opentelemetry.sdk.logs.data.Body.empty() + : io.opentelemetry.sdk.logs.data.Body.string(valueBody.asString()); + } + + @Override + @Nullable + public abstract Value getBodyValue(); + TestLogRecordData() {} /** A {@code Builder} class for {@link TestLogRecordData}. */ @@ -123,11 +138,26 @@ public Builder setObservedTimestamp(long timestamp, TimeUnit unit) { /** Set the body string. */ public Builder setBody(String body) { - return setBody(Body.string(body)); + return setBodyValue(Value.of(body)); + } + + /** + * Set the body. + * + * @deprecated Use {@link #setBodyValue(Value)}. + */ + @Deprecated + public Builder setBody(io.opentelemetry.sdk.logs.data.Body body) { + if (body.getType() == io.opentelemetry.sdk.logs.data.Body.Type.STRING) { + setBodyValue(Value.of(body.asString())); + } else if (body.getType() == io.opentelemetry.sdk.logs.data.Body.Type.EMPTY) { + setBodyValue(null); + } + return this; } /** Set the body. */ - abstract Builder setBody(Body body); + public abstract Builder setBodyValue(@Nullable Value body); /** Set the attributes. */ public abstract Builder setAttributes(Attributes attributes); diff --git a/sdk/testing/src/test/java/io/opentelemetry/sdk/testing/junit4/OpenTelemetryRuleTest.java b/sdk/testing/src/test/java/io/opentelemetry/sdk/testing/junit4/OpenTelemetryRuleTest.java index b8a14c5975d..a068d40bd0e 100644 --- a/sdk/testing/src/test/java/io/opentelemetry/sdk/testing/junit4/OpenTelemetryRuleTest.java +++ b/sdk/testing/src/test/java/io/opentelemetry/sdk/testing/junit4/OpenTelemetryRuleTest.java @@ -7,6 +7,7 @@ import static org.assertj.core.api.Assertions.assertThat; +import io.opentelemetry.api.common.Value; import io.opentelemetry.api.logs.Logger; import io.opentelemetry.api.metrics.LongCounter; import io.opentelemetry.api.metrics.Meter; @@ -94,12 +95,12 @@ public void getLogRecords() { assertThat(otelTesting.getLogRecords()) .singleElement() .satisfies( - logRecordData -> assertThat(logRecordData.getBody().asString()).isEqualTo("body")); + logRecordData -> assertThat(logRecordData.getBodyValue()).isEqualTo(Value.of("body"))); // Logs cleared between tests, not when retrieving assertThat(otelTesting.getLogRecords()) .singleElement() .satisfies( - logRecordData -> assertThat(logRecordData.getBody().asString()).isEqualTo("body")); + logRecordData -> assertThat(logRecordData.getBodyValue()).isEqualTo(Value.of("body"))); } // We have two tests to verify logs get cleared up between tests. @@ -110,11 +111,11 @@ public void getLogRecordsAgain() { assertThat(otelTesting.getLogRecords()) .singleElement() .satisfies( - logRecordData -> assertThat(logRecordData.getBody().asString()).isEqualTo("body")); + logRecordData -> assertThat(logRecordData.getBodyValue()).isEqualTo(Value.of("body"))); // Logs cleared between tests, not when retrieving assertThat(otelTesting.getLogRecords()) .singleElement() .satisfies( - logRecordData -> assertThat(logRecordData.getBody().asString()).isEqualTo("body")); + logRecordData -> assertThat(logRecordData.getBodyValue()).isEqualTo(Value.of("body"))); } } diff --git a/sdk/testing/src/test/java/io/opentelemetry/sdk/testing/junit5/OpenTelemetryExtensionTest.java b/sdk/testing/src/test/java/io/opentelemetry/sdk/testing/junit5/OpenTelemetryExtensionTest.java index f2e7257b2bd..e91d3f036ea 100644 --- a/sdk/testing/src/test/java/io/opentelemetry/sdk/testing/junit5/OpenTelemetryExtensionTest.java +++ b/sdk/testing/src/test/java/io/opentelemetry/sdk/testing/junit5/OpenTelemetryExtensionTest.java @@ -10,6 +10,7 @@ import io.opentelemetry.api.GlobalOpenTelemetry; import io.opentelemetry.api.OpenTelemetry; +import io.opentelemetry.api.common.Value; import io.opentelemetry.api.logs.Logger; import io.opentelemetry.api.metrics.LongCounter; import io.opentelemetry.api.metrics.Meter; @@ -184,12 +185,12 @@ public void getLogRecords() { assertThat(otelTesting.getLogRecords()) .singleElement() .satisfies( - logRecordData -> assertThat(logRecordData.getBody().asString()).isEqualTo("body")); + logRecordData -> assertThat(logRecordData.getBodyValue()).isEqualTo(Value.of("body"))); // Logs cleared between tests, not when retrieving assertThat(otelTesting.getLogRecords()) .singleElement() .satisfies( - logRecordData -> assertThat(logRecordData.getBody().asString()).isEqualTo("body")); + logRecordData -> assertThat(logRecordData.getBodyValue()).isEqualTo(Value.of("body"))); } // We have two tests to verify spans get cleared up between tests. @@ -200,12 +201,12 @@ public void getLogRecordsAgain() { assertThat(otelTesting.getLogRecords()) .singleElement() .satisfies( - logRecordData -> assertThat(logRecordData.getBody().asString()).isEqualTo("body")); + logRecordData -> assertThat(logRecordData.getBodyValue()).isEqualTo(Value.of("body"))); // Logs cleared between tests, not when retrieving assertThat(otelTesting.getLogRecords()) .singleElement() .satisfies( - logRecordData -> assertThat(logRecordData.getBody().asString()).isEqualTo("body")); + logRecordData -> assertThat(logRecordData.getBodyValue()).isEqualTo(Value.of("body"))); } @Test From 365fe8a4435aacd3574cb9527b6a29da2bfa3af6 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 30 Aug 2024 10:55:33 -0500 Subject: [PATCH 540/901] Update dependency checkstyle to v10.18.1 (#6678) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- buildSrc/src/main/kotlin/otel.java-conventions.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/buildSrc/src/main/kotlin/otel.java-conventions.gradle.kts b/buildSrc/src/main/kotlin/otel.java-conventions.gradle.kts index 929cbee6046..9eb42f21444 100644 --- a/buildSrc/src/main/kotlin/otel.java-conventions.gradle.kts +++ b/buildSrc/src/main/kotlin/otel.java-conventions.gradle.kts @@ -42,7 +42,7 @@ java { checkstyle { configDirectory.set(file("$rootDir/buildscripts/")) - toolVersion = "10.18.0" + toolVersion = "10.18.1" isIgnoreFailures = false configProperties["rootDir"] = rootDir } From 37e35b239b7debb47ee3f3285ac577ad832d3ce0 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 30 Aug 2024 14:53:57 -0500 Subject: [PATCH 541/901] Update errorProneVersion to v2.31.0 (#6642) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Co-authored-by: Jack Berg --- dependencyManagement/build.gradle.kts | 2 +- .../extension/trace/jaeger/sampler/RateLimitingSampler.java | 3 ++- .../sdk/metrics/internal/debug/StackTraceSourceInfo.java | 4 +++- .../sdk/trace/samplers/TraceIdRatioBasedSampler.java | 3 ++- 4 files changed, 8 insertions(+), 4 deletions(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index 3144535bf3e..5e4ac7e5a87 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -25,7 +25,7 @@ val DEPENDENCY_BOMS = listOf( ) val autoValueVersion = "1.11.0" -val errorProneVersion = "2.29.2" +val errorProneVersion = "2.31.0" val jmhVersion = "1.37" // Mockito 5.x.x requires Java 11 https://github.com/mockito/mockito/releases/tag/v5.0.0 val mockitoVersion = "4.11.0" diff --git a/sdk-extensions/jaeger-remote-sampler/src/main/java/io/opentelemetry/sdk/extension/trace/jaeger/sampler/RateLimitingSampler.java b/sdk-extensions/jaeger-remote-sampler/src/main/java/io/opentelemetry/sdk/extension/trace/jaeger/sampler/RateLimitingSampler.java index 6a6caa171e6..462f87672c4 100644 --- a/sdk-extensions/jaeger-remote-sampler/src/main/java/io/opentelemetry/sdk/extension/trace/jaeger/sampler/RateLimitingSampler.java +++ b/sdk-extensions/jaeger-remote-sampler/src/main/java/io/opentelemetry/sdk/extension/trace/jaeger/sampler/RateLimitingSampler.java @@ -21,6 +21,7 @@ import java.text.DecimalFormat; import java.text.DecimalFormatSymbols; import java.util.List; +import java.util.Locale; /** * {@link RateLimitingSampler} sampler uses a leaky bucket rate limiter to ensure that traces are @@ -73,7 +74,7 @@ public String toString() { } private static String decimalFormat(double value) { - DecimalFormatSymbols decimalFormatSymbols = DecimalFormatSymbols.getInstance(); + DecimalFormatSymbols decimalFormatSymbols = DecimalFormatSymbols.getInstance(Locale.ROOT); decimalFormatSymbols.setDecimalSeparator('.'); DecimalFormat decimalFormat = new DecimalFormat("0.00", decimalFormatSymbols); diff --git a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/debug/StackTraceSourceInfo.java b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/debug/StackTraceSourceInfo.java index a8b43be5fd2..64a18ad6736 100644 --- a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/debug/StackTraceSourceInfo.java +++ b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/debug/StackTraceSourceInfo.java @@ -5,6 +5,8 @@ package io.opentelemetry.sdk.metrics.internal.debug; +import java.util.Locale; + /** Diagnostic information derived from stack traces. */ final class StackTraceSourceInfo implements SourceInfo { @@ -19,7 +21,7 @@ public String shortDebugString() { if (stackTraceElements.length > 0) { for (StackTraceElement e : stackTraceElements) { if (isInterestingStackTrace(e)) { - return String.format("%s:%d", e.getFileName(), e.getLineNumber()); + return String.format(Locale.ROOT, "%s:%d", e.getFileName(), e.getLineNumber()); } } } diff --git a/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/samplers/TraceIdRatioBasedSampler.java b/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/samplers/TraceIdRatioBasedSampler.java index 59a63856318..9a7490931af 100644 --- a/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/samplers/TraceIdRatioBasedSampler.java +++ b/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/samplers/TraceIdRatioBasedSampler.java @@ -13,6 +13,7 @@ import java.text.DecimalFormat; import java.text.DecimalFormatSymbols; import java.util.List; +import java.util.Locale; import javax.annotation.Nullable; import javax.annotation.concurrent.Immutable; @@ -112,7 +113,7 @@ private static long getTraceIdRandomPart(String traceId) { } private static String decimalFormat(double value) { - DecimalFormatSymbols decimalFormatSymbols = DecimalFormatSymbols.getInstance(); + DecimalFormatSymbols decimalFormatSymbols = DecimalFormatSymbols.getInstance(Locale.ROOT); decimalFormatSymbols.setDecimalSeparator('.'); DecimalFormat decimalFormat = new DecimalFormat("0.000000", decimalFormatSymbols); From ee7fd2744949ae0c060d28c73edfca56633dc170 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sun, 1 Sep 2024 10:07:15 -0700 Subject: [PATCH 542/901] Update dependency com.android.tools:desugar_jdk_libs to v2.1.1 (#6671) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- dependencyManagement/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index 5e4ac7e5a87..19c8a1634b4 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -81,7 +81,7 @@ val DEPENDENCIES = listOf( "org.junit-pioneer:junit-pioneer:1.9.1", "org.mock-server:mockserver-netty:5.15.0:shaded", "org.skyscreamer:jsonassert:1.5.3", - "com.android.tools:desugar_jdk_libs:2.0.4", + "com.android.tools:desugar_jdk_libs:2.1.1", ) javaPlatform { From bc2fad4cf3ad9397610a4bcadccf58806647662d Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 4 Sep 2024 09:43:03 -0700 Subject: [PATCH 543/901] Update dependency com.android.tools:desugar_jdk_libs to v2.1.2 (#6684) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- dependencyManagement/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index 19c8a1634b4..3bc673ed1da 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -81,7 +81,7 @@ val DEPENDENCIES = listOf( "org.junit-pioneer:junit-pioneer:1.9.1", "org.mock-server:mockserver-netty:5.15.0:shaded", "org.skyscreamer:jsonassert:1.5.3", - "com.android.tools:desugar_jdk_libs:2.1.1", + "com.android.tools:desugar_jdk_libs:2.1.2", ) javaPlatform { From 09de4bd1059185f20b2ec2da5c2f34d960e06b0f Mon Sep 17 00:00:00 2001 From: Jonas Kunz Date: Wed, 4 Sep 2024 20:52:09 +0200 Subject: [PATCH 544/901] Added SpanProcessor OnEnding callback (#6367) Co-authored-by: jack-berg <34418638+jack-berg@users.noreply.github.com> --- .../sdk/trace/MultiSpanProcessor.java | 25 ++++- .../io/opentelemetry/sdk/trace/SdkSpan.java | 66 +++++++++---- .../trace/internal/ExtendedSpanProcessor.java | 41 ++++++++ .../sdk/trace/MultiSpanProcessorTest.java | 27 ++++-- .../opentelemetry/sdk/trace/SdkSpanTest.java | 94 ++++++++++++++++++- .../ExtendedSpanProcessorUsageTest.java | 85 +++++++++++++++++ 6 files changed, 313 insertions(+), 25 deletions(-) create mode 100644 sdk/trace/src/main/java/io/opentelemetry/sdk/trace/internal/ExtendedSpanProcessor.java create mode 100644 sdk/trace/src/test/java/io/opentelemetry/sdk/trace/internal/ExtendedSpanProcessorUsageTest.java diff --git a/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/MultiSpanProcessor.java b/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/MultiSpanProcessor.java index a06b4b69579..65b37096568 100644 --- a/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/MultiSpanProcessor.java +++ b/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/MultiSpanProcessor.java @@ -7,6 +7,7 @@ import io.opentelemetry.context.Context; import io.opentelemetry.sdk.common.CompletableResultCode; +import io.opentelemetry.sdk.trace.internal.ExtendedSpanProcessor; import java.util.ArrayList; import java.util.List; import java.util.Objects; @@ -16,8 +17,9 @@ * Implementation of the {@code SpanProcessor} that simply forwards all received events to a list of * {@code SpanProcessor}s. */ -final class MultiSpanProcessor implements SpanProcessor { +final class MultiSpanProcessor implements ExtendedSpanProcessor { private final List spanProcessorsStart; + private final List spanProcessorsEnding; private final List spanProcessorsEnd; private final List spanProcessorsAll; private final AtomicBoolean isShutdown = new AtomicBoolean(false); @@ -58,6 +60,18 @@ public boolean isEndRequired() { return !spanProcessorsEnd.isEmpty(); } + @Override + public void onEnding(ReadWriteSpan span) { + for (ExtendedSpanProcessor spanProcessor : spanProcessorsEnding) { + spanProcessor.onEnding(span); + } + } + + @Override + public boolean isOnEndingRequired() { + return !spanProcessorsEnding.isEmpty(); + } + @Override public CompletableResultCode shutdown() { if (isShutdown.getAndSet(true)) { @@ -83,10 +97,17 @@ private MultiSpanProcessor(List spanProcessors) { this.spanProcessorsAll = spanProcessors; this.spanProcessorsStart = new ArrayList<>(spanProcessorsAll.size()); this.spanProcessorsEnd = new ArrayList<>(spanProcessorsAll.size()); + this.spanProcessorsEnding = new ArrayList<>(spanProcessorsAll.size()); for (SpanProcessor spanProcessor : spanProcessorsAll) { if (spanProcessor.isStartRequired()) { spanProcessorsStart.add(spanProcessor); } + if (spanProcessor instanceof ExtendedSpanProcessor) { + ExtendedSpanProcessor extendedSpanProcessor = (ExtendedSpanProcessor) spanProcessor; + if (extendedSpanProcessor.isOnEndingRequired()) { + spanProcessorsEnding.add(extendedSpanProcessor); + } + } if (spanProcessor.isEndRequired()) { spanProcessorsEnd.add(spanProcessor); } @@ -98,6 +119,8 @@ public String toString() { return "MultiSpanProcessor{" + "spanProcessorsStart=" + spanProcessorsStart + + ", spanProcessorsEnding=" + + spanProcessorsEnding + ", spanProcessorsEnd=" + spanProcessorsEnd + ", spanProcessorsAll=" diff --git a/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/SdkSpan.java b/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/SdkSpan.java index 5011b5a3d7d..1580b05c465 100644 --- a/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/SdkSpan.java +++ b/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/SdkSpan.java @@ -23,6 +23,7 @@ import io.opentelemetry.sdk.trace.data.LinkData; import io.opentelemetry.sdk.trace.data.SpanData; import io.opentelemetry.sdk.trace.data.StatusData; +import io.opentelemetry.sdk.trace.internal.ExtendedSpanProcessor; import io.opentelemetry.sdk.trace.internal.data.ExceptionEventData; import java.util.ArrayList; import java.util.Collections; @@ -95,9 +96,24 @@ final class SdkSpan implements ReadWriteSpan { @GuardedBy("lock") private long endEpochNanos; - // True if the span is ended. + private enum EndState { + NOT_ENDED, + ENDING, + ENDED + } + @GuardedBy("lock") - private boolean hasEnded; + private EndState hasEnded; + + /** + * The thread on which {@link #end()} is called and which will be invoking the {@link + * SpanProcessor}s. This field is used to ensure that only this thread may modify the span while + * it is in state {@link EndState#ENDING} to prevent concurrent updates outside of {@link + * ExtendedSpanProcessor#onEnding(ReadWriteSpan)}. + */ + @GuardedBy("lock") + @Nullable + private Thread spanEndingThread; private SdkSpan( SpanContext context, @@ -122,7 +138,7 @@ private SdkSpan( this.kind = kind; this.spanProcessor = spanProcessor; this.resource = resource; - this.hasEnded = false; + this.hasEnded = EndState.NOT_ENDED; this.clock = clock; this.startEpochNanos = startEpochNanos; this.attributes = attributes; @@ -220,7 +236,7 @@ public SpanData toSpanData() { status, name, endEpochNanos, - hasEnded); + hasEnded == EndState.ENDED); } } @@ -242,7 +258,7 @@ public Attributes getAttributes() { @Override public boolean hasEnded() { synchronized (lock) { - return hasEnded; + return hasEnded == EndState.ENDED; } } @@ -288,7 +304,7 @@ public InstrumentationScopeInfo getInstrumentationScopeInfo() { @Override public long getLatencyNanos() { synchronized (lock) { - return (hasEnded ? endEpochNanos : clock.now()) - startEpochNanos; + return (hasEnded == EndState.NOT_ENDED ? clock.now() : endEpochNanos) - startEpochNanos; } } @@ -303,7 +319,7 @@ public ReadWriteSpan setAttribute(AttributeKey key, T value) { return this; } synchronized (lock) { - if (hasEnded) { + if (!isModifiableByCurrentThread()) { logger.log(Level.FINE, "Calling setAttribute() on an ended Span."); return this; } @@ -318,6 +334,12 @@ public ReadWriteSpan setAttribute(AttributeKey key, T value) { return this; } + @GuardedBy("lock") + private boolean isModifiableByCurrentThread() { + return hasEnded == EndState.NOT_ENDED + || (hasEnded == EndState.ENDING && Thread.currentThread() == spanEndingThread); + } + @Override public ReadWriteSpan addEvent(String name) { if (name == null) { @@ -380,7 +402,7 @@ public ReadWriteSpan addEvent(String name, Attributes attributes, long timestamp private void addTimedEvent(EventData timedEvent) { synchronized (lock) { - if (hasEnded) { + if (!isModifiableByCurrentThread()) { logger.log(Level.FINE, "Calling addEvent() on an ended Span."); return; } @@ -400,7 +422,7 @@ public ReadWriteSpan setStatus(StatusCode statusCode, @Nullable String descripti return this; } synchronized (lock) { - if (hasEnded) { + if (!isModifiableByCurrentThread()) { logger.log(Level.FINE, "Calling setStatus() on an ended Span."); return this; } else if (this.status.getStatusCode() == StatusCode.OK) { @@ -438,7 +460,7 @@ public ReadWriteSpan updateName(String name) { return this; } synchronized (lock) { - if (hasEnded) { + if (!isModifiableByCurrentThread()) { logger.log(Level.FINE, "Calling updateName() on an ended Span."); return this; } @@ -463,7 +485,7 @@ public Span addLink(SpanContext spanContext, Attributes attributes) { spanLimits.getMaxNumberOfAttributesPerLink(), spanLimits.getMaxAttributeValueLength())); synchronized (lock) { - if (hasEnded) { + if (!isModifiableByCurrentThread()) { logger.log(Level.FINE, "Calling addLink() on an ended Span."); return this; } @@ -493,12 +515,22 @@ public void end(long timestamp, TimeUnit unit) { private void endInternal(long endEpochNanos) { synchronized (lock) { - if (hasEnded) { - logger.log(Level.FINE, "Calling end() on an ended Span."); + if (hasEnded != EndState.NOT_ENDED) { + logger.log(Level.FINE, "Calling end() on an ended or ending Span."); return; } this.endEpochNanos = endEpochNanos; - hasEnded = true; + spanEndingThread = Thread.currentThread(); + hasEnded = EndState.ENDING; + } + if (spanProcessor instanceof ExtendedSpanProcessor) { + ExtendedSpanProcessor extendedSpanProcessor = (ExtendedSpanProcessor) spanProcessor; + if (extendedSpanProcessor.isOnEndingRequired()) { + extendedSpanProcessor.onEnding(this); + } + } + synchronized (lock) { + hasEnded = EndState.ENDED; } if (spanProcessor.isEndRequired()) { spanProcessor.onEnd(this); @@ -508,7 +540,7 @@ private void endInternal(long endEpochNanos) { @Override public boolean isRecording() { synchronized (lock) { - return !hasEnded; + return hasEnded != EndState.ENDED; } } @@ -533,7 +565,7 @@ private List getImmutableTimedEvents() { // if the span has ended, then the events are unmodifiable // so we can return them directly and save copying all the data. - if (hasEnded) { + if (hasEnded == EndState.ENDED) { return Collections.unmodifiableList(events); } @@ -547,7 +579,7 @@ private Attributes getImmutableAttributes() { } // if the span has ended, then the attributes are unmodifiable, // so we can return them directly and save copying all the data. - if (hasEnded) { + if (hasEnded == EndState.ENDED) { return attributes; } // otherwise, make a copy of the data into an immutable container. diff --git a/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/internal/ExtendedSpanProcessor.java b/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/internal/ExtendedSpanProcessor.java new file mode 100644 index 00000000000..5c608bf8275 --- /dev/null +++ b/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/internal/ExtendedSpanProcessor.java @@ -0,0 +1,41 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.sdk.trace.internal; + +import io.opentelemetry.api.trace.Span; +import io.opentelemetry.sdk.trace.ReadWriteSpan; +import io.opentelemetry.sdk.trace.ReadableSpan; +import io.opentelemetry.sdk.trace.SpanProcessor; + +/** + * Extended {@link SpanProcessor} with experimental APIs. + * + *

      This class is internal and is hence not for public use. Its APIs are unstable and can change + * at any time. + */ +public interface ExtendedSpanProcessor extends SpanProcessor { + + /** + * Called when a {@link io.opentelemetry.api.trace.Span} is ended, but before {@link + * SpanProcessor#onEnd(ReadableSpan)} is invoked with an immutable variant of this span. This + * means that the span will still be mutable. Note that the span will only be modifiable + * synchronously from this callback, concurrent modifications from other threads will be + * prevented. Only called if {@link Span#isRecording()} returns true. + * + *

      This method is called synchronously on the execution thread, should not throw or block the + * execution thread. + * + * @param span the {@code Span} that is just about to be ended. + */ + void onEnding(ReadWriteSpan span); + + /** + * Returns {@code true} if this {@link SpanProcessor} requires onEnding events. + * + * @return {@code true} if this {@link SpanProcessor} requires onEnding events. + */ + boolean isOnEndingRequired(); +} diff --git a/sdk/trace/src/test/java/io/opentelemetry/sdk/trace/MultiSpanProcessorTest.java b/sdk/trace/src/test/java/io/opentelemetry/sdk/trace/MultiSpanProcessorTest.java index c51fe61c954..34ac6e1c03d 100644 --- a/sdk/trace/src/test/java/io/opentelemetry/sdk/trace/MultiSpanProcessorTest.java +++ b/sdk/trace/src/test/java/io/opentelemetry/sdk/trace/MultiSpanProcessorTest.java @@ -14,6 +14,7 @@ import io.opentelemetry.context.Context; import io.opentelemetry.sdk.common.CompletableResultCode; +import io.opentelemetry.sdk.trace.internal.ExtendedSpanProcessor; import java.util.Arrays; import java.util.Collections; import org.junit.jupiter.api.BeforeEach; @@ -27,18 +28,20 @@ @ExtendWith(MockitoExtension.class) @MockitoSettings(strictness = Strictness.LENIENT) class MultiSpanProcessorTest { - @Mock private SpanProcessor spanProcessor1; - @Mock private SpanProcessor spanProcessor2; + @Mock private ExtendedSpanProcessor spanProcessor1; + @Mock private ExtendedSpanProcessor spanProcessor2; @Mock private ReadableSpan readableSpan; @Mock private ReadWriteSpan readWriteSpan; @BeforeEach void setUp() { when(spanProcessor1.isStartRequired()).thenReturn(true); + when(spanProcessor1.isOnEndingRequired()).thenReturn(true); when(spanProcessor1.isEndRequired()).thenReturn(true); when(spanProcessor1.forceFlush()).thenReturn(CompletableResultCode.ofSuccess()); when(spanProcessor1.shutdown()).thenReturn(CompletableResultCode.ofSuccess()); when(spanProcessor2.isStartRequired()).thenReturn(true); + when(spanProcessor2.isOnEndingRequired()).thenReturn(true); when(spanProcessor2.isEndRequired()).thenReturn(true); when(spanProcessor2.forceFlush()).thenReturn(CompletableResultCode.ofSuccess()); when(spanProcessor2.shutdown()).thenReturn(CompletableResultCode.ofSuccess()); @@ -61,12 +64,17 @@ void oneSpanProcessor() { @Test void twoSpanProcessor() { - SpanProcessor multiSpanProcessor = - SpanProcessor.composite(Arrays.asList(spanProcessor1, spanProcessor2)); + ExtendedSpanProcessor multiSpanProcessor = + (ExtendedSpanProcessor) + SpanProcessor.composite(Arrays.asList(spanProcessor1, spanProcessor2)); multiSpanProcessor.onStart(Context.root(), readWriteSpan); verify(spanProcessor1).onStart(same(Context.root()), same(readWriteSpan)); verify(spanProcessor2).onStart(same(Context.root()), same(readWriteSpan)); + multiSpanProcessor.onEnding(readWriteSpan); + verify(spanProcessor1).onEnding(same(readWriteSpan)); + verify(spanProcessor2).onEnding(same(readWriteSpan)); + multiSpanProcessor.onEnd(readableSpan); verify(spanProcessor1).onEnd(same(readableSpan)); verify(spanProcessor2).onEnd(same(readableSpan)); @@ -83,9 +91,11 @@ void twoSpanProcessor() { @Test void twoSpanProcessor_DifferentRequirements() { when(spanProcessor1.isEndRequired()).thenReturn(false); + when(spanProcessor2.isOnEndingRequired()).thenReturn(false); when(spanProcessor2.isStartRequired()).thenReturn(false); - SpanProcessor multiSpanProcessor = - SpanProcessor.composite(Arrays.asList(spanProcessor1, spanProcessor2)); + ExtendedSpanProcessor multiSpanProcessor = + (ExtendedSpanProcessor) + SpanProcessor.composite(Arrays.asList(spanProcessor1, spanProcessor2)); assertThat(multiSpanProcessor.isStartRequired()).isTrue(); assertThat(multiSpanProcessor.isEndRequired()).isTrue(); @@ -94,6 +104,10 @@ void twoSpanProcessor_DifferentRequirements() { verify(spanProcessor1).onStart(same(Context.root()), same(readWriteSpan)); verify(spanProcessor2, times(0)).onStart(any(Context.class), any(ReadWriteSpan.class)); + multiSpanProcessor.onEnding(readWriteSpan); + verify(spanProcessor1).onEnding(same(readWriteSpan)); + verify(spanProcessor2, times(0)).onEnding(any(ReadWriteSpan.class)); + multiSpanProcessor.onEnd(readableSpan); verify(spanProcessor1, times(0)).onEnd(any(ReadableSpan.class)); verify(spanProcessor2).onEnd(same(readableSpan)); @@ -117,6 +131,7 @@ void stringRepresentation() { .hasToString( "MultiSpanProcessor{" + "spanProcessorsStart=[spanProcessor1, spanProcessor1], " + + "spanProcessorsEnding=[spanProcessor1, spanProcessor1], " + "spanProcessorsEnd=[spanProcessor1, spanProcessor1], " + "spanProcessorsAll=[spanProcessor1, spanProcessor1]}"); } diff --git a/sdk/trace/src/test/java/io/opentelemetry/sdk/trace/SdkSpanTest.java b/sdk/trace/src/test/java/io/opentelemetry/sdk/trace/SdkSpanTest.java index df56d05a07e..7814074269b 100644 --- a/sdk/trace/src/test/java/io/opentelemetry/sdk/trace/SdkSpanTest.java +++ b/sdk/trace/src/test/java/io/opentelemetry/sdk/trace/SdkSpanTest.java @@ -18,6 +18,8 @@ import static org.assertj.core.api.Assertions.assertThatCode; import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.same; +import static org.mockito.Mockito.doAnswer; import static org.mockito.Mockito.never; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @@ -42,6 +44,7 @@ import io.opentelemetry.sdk.trace.data.LinkData; import io.opentelemetry.sdk.trace.data.SpanData; import io.opentelemetry.sdk.trace.data.StatusData; +import io.opentelemetry.sdk.trace.internal.ExtendedSpanProcessor; import io.opentelemetry.sdk.trace.internal.data.ExceptionEventData; import java.io.PrintWriter; import java.io.StringWriter; @@ -58,6 +61,8 @@ import java.util.concurrent.Executors; import java.util.concurrent.Future; import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.concurrent.atomic.AtomicLong; import java.util.stream.IntStream; import javax.annotation.Nullable; import org.junit.jupiter.api.BeforeEach; @@ -90,7 +95,7 @@ class SdkSpanTest { private final Map attributes = new HashMap<>(); private Attributes expectedAttributes; private final LinkData link = LinkData.create(spanContext); - @Mock private SpanProcessor spanProcessor; + @Mock private ExtendedSpanProcessor spanProcessor; private TestClock testClock; @@ -107,6 +112,7 @@ void setUp() { expectedAttributes = builder.build(); testClock = TestClock.create(Instant.ofEpochSecond(0, START_EPOCH_NANOS)); when(spanProcessor.isStartRequired()).thenReturn(true); + when(spanProcessor.isOnEndingRequired()).thenReturn(true); when(spanProcessor.isEndRequired()).thenReturn(true); } @@ -140,6 +146,92 @@ void endSpanTwice_DoNotCrash() { assertThat(span.hasEnded()).isTrue(); } + @Test + void onEnding_spanStillMutable() { + SdkSpan span = createTestSpan(SpanKind.INTERNAL); + + AttributeKey dummyAttrib = AttributeKey.stringKey("processor_foo"); + + AtomicBoolean endedStateInProcessor = new AtomicBoolean(); + doAnswer( + invocation -> { + ReadWriteSpan sp = invocation.getArgument(0, ReadWriteSpan.class); + assertThat(sp.hasEnded()).isFalse(); + sp.end(); // should have no effect, nested end should be detected + endedStateInProcessor.set(sp.hasEnded()); + sp.setAttribute(dummyAttrib, "bar"); + return null; + }) + .when(spanProcessor) + .onEnding(any()); + + span.end(); + verify(spanProcessor).onEnding(same(span)); + assertThat(span.hasEnded()).isTrue(); + assertThat(endedStateInProcessor.get()).isFalse(); + assertThat(span.getAttribute(dummyAttrib)).isEqualTo("bar"); + } + + @Test + void onEnding_concurrentModificationsPrevented() { + SdkSpan span = createTestSpan(SpanKind.INTERNAL); + + AttributeKey syncAttrib = AttributeKey.stringKey("sync_foo"); + AttributeKey concurrentAttrib = AttributeKey.stringKey("concurrent_foo"); + + doAnswer( + invocation -> { + ReadWriteSpan sp = invocation.getArgument(0, ReadWriteSpan.class); + + Thread concurrent = + new Thread( + () -> { + sp.setAttribute(concurrentAttrib, "concurrent_bar"); + }); + concurrent.start(); + concurrent.join(); + + sp.setAttribute(syncAttrib, "sync_bar"); + + return null; + }) + .when(spanProcessor) + .onEnding(any()); + + span.end(); + verify(spanProcessor).onEnding(same(span)); + assertThat(span.getAttribute(concurrentAttrib)).isNull(); + assertThat(span.getAttribute(syncAttrib)).isEqualTo("sync_bar"); + } + + @Test + void onEnding_latencyPinned() { + SdkSpan span = createTestSpan(SpanKind.INTERNAL); + + AtomicLong spanLatencyInProcessor = new AtomicLong(); + doAnswer( + invocation -> { + ReadWriteSpan sp = invocation.getArgument(0, ReadWriteSpan.class); + + testClock.advance(Duration.ofSeconds(100)); + spanLatencyInProcessor.set(sp.getLatencyNanos()); + return null; + }) + .when(spanProcessor) + .onEnding(any()); + + testClock.advance(Duration.ofSeconds(1)); + long expectedDuration = testClock.now() - START_EPOCH_NANOS; + + assertThat(span.getLatencyNanos()).isEqualTo(expectedDuration); + + span.end(); + verify(spanProcessor).onEnding(same(span)); + assertThat(span.hasEnded()).isTrue(); + assertThat(span.getLatencyNanos()).isEqualTo(expectedDuration); + assertThat(spanLatencyInProcessor.get()).isEqualTo(expectedDuration); + } + @Test void toSpanData_ActiveSpan() { SdkSpan span = createTestSpan(SpanKind.INTERNAL); diff --git a/sdk/trace/src/test/java/io/opentelemetry/sdk/trace/internal/ExtendedSpanProcessorUsageTest.java b/sdk/trace/src/test/java/io/opentelemetry/sdk/trace/internal/ExtendedSpanProcessorUsageTest.java new file mode 100644 index 00000000000..3185aa9a1df --- /dev/null +++ b/sdk/trace/src/test/java/io/opentelemetry/sdk/trace/internal/ExtendedSpanProcessorUsageTest.java @@ -0,0 +1,85 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.sdk.trace.internal; + +import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.assertThat; + +import io.opentelemetry.api.common.AttributeKey; +import io.opentelemetry.api.trace.Span; +import io.opentelemetry.api.trace.Tracer; +import io.opentelemetry.context.Context; +import io.opentelemetry.sdk.testing.exporter.InMemorySpanExporter; +import io.opentelemetry.sdk.trace.ReadWriteSpan; +import io.opentelemetry.sdk.trace.ReadableSpan; +import io.opentelemetry.sdk.trace.SdkTracerProvider; +import io.opentelemetry.sdk.trace.export.SimpleSpanProcessor; +import org.junit.jupiter.api.Test; + +/** Demonstrating usage of {@link ExtendedSpanProcessor}. */ +class ExtendedSpanProcessorUsageTest { + + private static final AttributeKey FOO_KEY = AttributeKey.stringKey("foo"); + private static final AttributeKey BAR_KEY = AttributeKey.stringKey("bar"); + + private static class CopyFooToBarProcessor implements ExtendedSpanProcessor { + + @Override + public void onStart(Context parentContext, ReadWriteSpan span) {} + + @Override + public boolean isStartRequired() { + return false; + } + + @Override + public void onEnd(ReadableSpan span) {} + + @Override + public boolean isEndRequired() { + return false; + } + + @Override + public void onEnding(ReadWriteSpan span) { + String val = span.getAttribute(FOO_KEY); + span.setAttribute(BAR_KEY, val); + } + + @Override + public boolean isOnEndingRequired() { + return true; + } + } + + @Test + void extendedSpanProcessorUsage() { + InMemorySpanExporter exporter = InMemorySpanExporter.create(); + + try (SdkTracerProvider tracerProvider = + SdkTracerProvider.builder() + .addSpanProcessor(SimpleSpanProcessor.create(exporter)) + .addSpanProcessor(new CopyFooToBarProcessor()) + .build()) { + + Tracer tracer = tracerProvider.get("dummy-tracer"); + Span span = tracer.spanBuilder("my-span").startSpan(); + + span.setAttribute(FOO_KEY, "Hello!"); + + span.end(); + + assertThat(exporter.getFinishedSpanItems()) + .hasSize(1) + .first() + .satisfies( + spanData -> { + assertThat(spanData.getAttributes()) + .containsEntry(FOO_KEY, "Hello!") + .containsEntry(BAR_KEY, "Hello!"); + }); + } + } +} From 43be1e7f9d3e326bc9ab34ab54f3c2f24385cf46 Mon Sep 17 00:00:00 2001 From: Drew Hammond <2405390+drewhammond@users.noreply.github.com> Date: Wed, 4 Sep 2024 15:03:19 -0400 Subject: [PATCH 545/901] change polling interval property name to match spec (#6672) Co-authored-by: Jack Berg --- .../sampler/JaegerRemoteSamplerProvider.java | 21 ++++++++++++++++++- .../JaegerRemoteSamplerProviderTest.java | 2 +- 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/sdk-extensions/jaeger-remote-sampler/src/main/java/io/opentelemetry/sdk/extension/trace/jaeger/sampler/JaegerRemoteSamplerProvider.java b/sdk-extensions/jaeger-remote-sampler/src/main/java/io/opentelemetry/sdk/extension/trace/jaeger/sampler/JaegerRemoteSamplerProvider.java index d099f3b33f8..422a3b3f4e4 100644 --- a/sdk-extensions/jaeger-remote-sampler/src/main/java/io/opentelemetry/sdk/extension/trace/jaeger/sampler/JaegerRemoteSamplerProvider.java +++ b/sdk-extensions/jaeger-remote-sampler/src/main/java/io/opentelemetry/sdk/extension/trace/jaeger/sampler/JaegerRemoteSamplerProvider.java @@ -10,16 +10,21 @@ import io.opentelemetry.sdk.trace.samplers.Sampler; import java.util.Map; import java.util.concurrent.TimeUnit; +import java.util.logging.Level; +import java.util.logging.Logger; public class JaegerRemoteSamplerProvider implements ConfigurableSamplerProvider { + private static final Logger LOGGER = + Logger.getLogger(JaegerRemoteSamplerProvider.class.getName()); + // visible for testing static final String ATTRIBUTE_PROPERTY = "otel.resource.attributes"; static final String SERVICE_NAME_PROPERTY = "otel.service.name"; static final String SAMPLER_ARG_PROPERTY = "otel.traces.sampler.arg"; static final String RESOURCE_ATTRIBUTE_SERVICE_NAME_PROPERTY = "service.name"; private static final String ENDPOINT_KEY = "endpoint"; - private static final String POLLING_INTERVAL = "pollingInterval"; + private static final String POLLING_INTERVAL = "pollingIntervalMs"; private static final String INITIAL_SAMPLING_RATE = "initialSamplingRate"; @Override @@ -43,9 +48,23 @@ public Sampler createSampler(ConfigProperties config) { builder.setEndpoint(endpoint); } String pollingInterval = params.get(POLLING_INTERVAL); + // Previously, we mistakenly read from pollingInterval. For backwards compatibility, check + // pollingInterval and log warning if set. + if (pollingInterval == null) { + pollingInterval = params.get("pollingInterval"); + if (pollingInterval != null) { + LOGGER.log( + Level.WARNING, + SAMPLER_ARG_PROPERTY + + " contains deprecated \"pollingInterval\" property. Please use \"" + + POLLING_INTERVAL + + "\" instead."); + } + } if (pollingInterval != null) { builder.setPollingInterval(Integer.valueOf(pollingInterval), TimeUnit.MILLISECONDS); } + String initialSamplingRate = params.get(INITIAL_SAMPLING_RATE); if (initialSamplingRate != null) { builder.setInitialSampler( diff --git a/sdk-extensions/jaeger-remote-sampler/src/test/java/io/opentelemetry/sdk/extension/trace/jaeger/sampler/JaegerRemoteSamplerProviderTest.java b/sdk-extensions/jaeger-remote-sampler/src/test/java/io/opentelemetry/sdk/extension/trace/jaeger/sampler/JaegerRemoteSamplerProviderTest.java index 8fa43a7f759..e691b576f18 100644 --- a/sdk-extensions/jaeger-remote-sampler/src/test/java/io/opentelemetry/sdk/extension/trace/jaeger/sampler/JaegerRemoteSamplerProviderTest.java +++ b/sdk-extensions/jaeger-remote-sampler/src/test/java/io/opentelemetry/sdk/extension/trace/jaeger/sampler/JaegerRemoteSamplerProviderTest.java @@ -34,7 +34,7 @@ void serviceProvider() { .thenReturn("test_service"); HashMap samplerArgs = new HashMap<>(); samplerArgs.put("endpoint", "http://localhost:9999"); - samplerArgs.put("pollingInterval", "99"); + samplerArgs.put("pollingIntervalMs", "99"); double samplingRate = 0.33; samplerArgs.put("initialSamplingRate", String.valueOf(samplingRate)); when(mockConfig.getMap(JaegerRemoteSamplerProvider.SAMPLER_ARG_PROPERTY)) From 5ca6177fcf18de8e11b1f4ea7bdee0f820b6337c Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 4 Sep 2024 14:29:36 -0500 Subject: [PATCH 546/901] Update dependency org.owasp:dependency-check-gradle to v10.0.4 (#6679) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- buildSrc/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts index 5c2c974b841..54dcfc1fb5e 100644 --- a/buildSrc/build.gradle.kts +++ b/buildSrc/build.gradle.kts @@ -66,7 +66,7 @@ dependencies { implementation("net.ltgt.gradle:gradle-errorprone-plugin:4.0.1") implementation("net.ltgt.gradle:gradle-nullaway-plugin:2.0.0") implementation("org.jetbrains.kotlin:kotlin-gradle-plugin:2.0.20") - implementation("org.owasp:dependency-check-gradle:10.0.3") + implementation("org.owasp:dependency-check-gradle:10.0.4") implementation("ru.vyarus:gradle-animalsniffer-plugin:1.7.1") } From e063b34a2ad1865b8e8bc0e8758e6c375efbf473 Mon Sep 17 00:00:00 2001 From: jason plumb <75337021+breedx-splk@users.noreply.github.com> Date: Thu, 5 Sep 2024 09:55:02 -0700 Subject: [PATCH 547/901] Add asserts for event body fields (#6509) --- .../opentelemetry-sdk-testing.txt | 11 ++ sdk/testing/build.gradle.kts | 1 + .../testing/assertj/LogRecordDataAssert.java | 139 ++++++++++++++++++ .../testing/assertj/LogAssertionsTest.java | 99 ++++++++++--- 4 files changed, 231 insertions(+), 19 deletions(-) diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-testing.txt b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-testing.txt index 988fe184f0f..4d359472772 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-testing.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-testing.txt @@ -2,6 +2,17 @@ Comparing source compatibility of opentelemetry-sdk-testing-1.42.0-SNAPSHOT.jar *** MODIFIED CLASS: PUBLIC FINAL io.opentelemetry.sdk.testing.assertj.LogRecordDataAssert (not serializable) === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 +++ NEW METHOD: PUBLIC(+) io.opentelemetry.sdk.testing.assertj.LogRecordDataAssert hasBody(io.opentelemetry.api.common.Value) + +++ NEW METHOD: PUBLIC(+) io.opentelemetry.sdk.testing.assertj.LogRecordDataAssert hasBodyField(java.lang.String, java.lang.String) + +++ NEW METHOD: PUBLIC(+) io.opentelemetry.sdk.testing.assertj.LogRecordDataAssert hasBodyField(java.lang.String, long) + +++ NEW METHOD: PUBLIC(+) io.opentelemetry.sdk.testing.assertj.LogRecordDataAssert hasBodyField(java.lang.String, double) + +++ NEW METHOD: PUBLIC(+) io.opentelemetry.sdk.testing.assertj.LogRecordDataAssert hasBodyField(java.lang.String, boolean) + +++ NEW METHOD: PUBLIC(+) io.opentelemetry.sdk.testing.assertj.LogRecordDataAssert hasBodyField(java.lang.String, java.lang.String[]) + +++ NEW METHOD: PUBLIC(+) io.opentelemetry.sdk.testing.assertj.LogRecordDataAssert hasBodyField(java.lang.String, long[]) + +++ NEW METHOD: PUBLIC(+) io.opentelemetry.sdk.testing.assertj.LogRecordDataAssert hasBodyField(java.lang.String, double[]) + +++ NEW METHOD: PUBLIC(+) io.opentelemetry.sdk.testing.assertj.LogRecordDataAssert hasBodyField(java.lang.String, boolean[]) + +++ NEW METHOD: PUBLIC(+) io.opentelemetry.sdk.testing.assertj.LogRecordDataAssert hasBodyField(java.lang.String, io.opentelemetry.api.common.Value) + +++ NEW METHOD: PUBLIC(+) io.opentelemetry.sdk.testing.assertj.LogRecordDataAssert hasBodyField(io.opentelemetry.api.common.AttributeKey, java.lang.Object) + GENERIC TEMPLATES: +++ T:java.lang.Object **** MODIFIED CLASS: PUBLIC ABSTRACT io.opentelemetry.sdk.testing.logs.TestLogRecordData (not serializable) === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 +++ NEW METHOD: PUBLIC(+) io.opentelemetry.sdk.logs.data.Body getBody() diff --git a/sdk/testing/build.gradle.kts b/sdk/testing/build.gradle.kts index a9f2534aafd..4d3f3aa4ec8 100644 --- a/sdk/testing/build.gradle.kts +++ b/sdk/testing/build.gradle.kts @@ -8,6 +8,7 @@ otelJava.moduleName.set("io.opentelemetry.sdk.testing") dependencies { api(project(":api:all")) + api(project(":api:incubator")) api(project(":sdk:all")) compileOnly("org.assertj:assertj-core") diff --git a/sdk/testing/src/main/java/io/opentelemetry/sdk/testing/assertj/LogRecordDataAssert.java b/sdk/testing/src/main/java/io/opentelemetry/sdk/testing/assertj/LogRecordDataAssert.java index 11031aa9ef4..b717ecedad9 100644 --- a/sdk/testing/src/main/java/io/opentelemetry/sdk/testing/assertj/LogRecordDataAssert.java +++ b/sdk/testing/src/main/java/io/opentelemetry/sdk/testing/assertj/LogRecordDataAssert.java @@ -5,18 +5,25 @@ package io.opentelemetry.sdk.testing.assertj; +import static io.opentelemetry.api.common.ValueType.KEY_VALUE_LIST; import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.assertThat; +import static java.util.stream.Collectors.toList; +import static org.junit.Assert.assertNotNull; import io.opentelemetry.api.common.AttributeKey; import io.opentelemetry.api.common.Attributes; import io.opentelemetry.api.common.AttributesBuilder; +import io.opentelemetry.api.common.KeyValue; import io.opentelemetry.api.common.Value; +import io.opentelemetry.api.common.ValueType; import io.opentelemetry.api.logs.Severity; import io.opentelemetry.api.trace.SpanContext; import io.opentelemetry.sdk.common.InstrumentationScopeInfo; import io.opentelemetry.sdk.logs.data.LogRecordData; import io.opentelemetry.sdk.resources.Resource; +import java.util.ArrayList; import java.util.Arrays; +import java.util.List; import java.util.Map; import java.util.Objects; import java.util.function.Consumer; @@ -167,6 +174,138 @@ public LogRecordDataAssert hasBody(@Nullable Value body) { return this; } + /** + * Asserts the log has a body of type {@link ValueType#KEY_VALUE_LIST}, containing a field with + * the given {@code key} and String {@code value}. + */ + public LogRecordDataAssert hasBodyField(String key, String value) { + return hasBodyField(key, Value.of(value)); + } + + /** + * Asserts the log has a body of type {@link ValueType#KEY_VALUE_LIST}, containing a field with + * the given {@code key} and long {@code value}. + */ + public LogRecordDataAssert hasBodyField(String key, long value) { + return hasBodyField(key, Value.of(value)); + } + + /** + * Asserts the log has a body of type {@link ValueType#KEY_VALUE_LIST}, containing a field with + * the given {@code key} and double {@code value}. + */ + public LogRecordDataAssert hasBodyField(String key, double value) { + return hasBodyField(key, Value.of(value)); + } + + /** + * Asserts the log has a body of type {@link ValueType#KEY_VALUE_LIST}, containing a field with + * the given {@code key} and boolean {@code value}. + */ + public LogRecordDataAssert hasBodyField(String key, boolean value) { + return hasBodyField(key, Value.of(value)); + } + + /** + * Asserts the log has a body of type {@link ValueType#KEY_VALUE_LIST}, containing a field with + * the given {@code key} and list of String {@code value}s. + */ + public LogRecordDataAssert hasBodyField(String key, String... value) { + List> values = new ArrayList<>(value.length); + for (String val : value) { + values.add(Value.of(val)); + } + return hasBodyField(key, Value.of(values)); + } + + /** + * Asserts the log has a body of type {@link ValueType#KEY_VALUE_LIST}, containing a field with + * the given {@code key} and list of long {@code value}s. + */ + public LogRecordDataAssert hasBodyField(String key, long... value) { + List> values = new ArrayList<>(value.length); + for (long val : value) { + values.add(Value.of(val)); + } + return hasBodyField(key, Value.of(values)); + } + + /** + * Asserts the log has a body of type {@link ValueType#KEY_VALUE_LIST}, containing a field with + * the given {@code key} and list of double {@code value}s. + */ + public LogRecordDataAssert hasBodyField(String key, double... value) { + List> values = new ArrayList<>(value.length); + for (double val : value) { + values.add(Value.of(val)); + } + return hasBodyField(key, Value.of(values)); + } + + /** + * Asserts the log has a body of type {@link ValueType#KEY_VALUE_LIST}, containing a field with + * the given {@code key} and list of boolean {@code value}s. + */ + public LogRecordDataAssert hasBodyField(String key, boolean... value) { + List> values = new ArrayList<>(value.length); + for (boolean val : value) { + values.add(Value.of(val)); + } + return hasBodyField(key, Value.of(values)); + } + + /** + * Asserts the log has a body of type {@link ValueType#KEY_VALUE_LIST}, containing a field with + * the given {@code key} and {@code value}. + */ + @SuppressWarnings({"unchecked"}) + public LogRecordDataAssert hasBodyField(String key, Value value) { + isNotNull(); + Value bodyValue = actual.getBodyValue(); + assertNotNull( + "Body was not expected to be null.", bodyValue); // Can't use assertj or nullaway complains + assertThat(bodyValue.getType()).isEqualTo(KEY_VALUE_LIST); + Value> body = (Value>) bodyValue; + List payload = body.getValue(); + KeyValue expected = KeyValue.of(key, value); + assertThat(payload).contains(expected); + return this; + } + + /** + * Asserts the log has a body of type {@link ValueType#KEY_VALUE_LIST}, containing a field with + * the given attribute {@code key} and {@code value}. + */ + @SuppressWarnings({"unchecked"}) + public LogRecordDataAssert hasBodyField(AttributeKey key, T value) { + switch (key.getType()) { + case STRING: + return hasBodyField(key.getKey(), (String) value); + case BOOLEAN: + return hasBodyField(key.getKey(), (boolean) value); + case LONG: + return hasBodyField(key.getKey(), (long) value); + case DOUBLE: + return hasBodyField(key.getKey(), (double) value); + case STRING_ARRAY: + return hasBodyField( + key.getKey(), + Value.of(((List) value).stream().map(Value::of).collect(toList()))); + case BOOLEAN_ARRAY: + return hasBodyField( + key.getKey(), + Value.of(((List) value).stream().map(Value::of).collect(toList()))); + case LONG_ARRAY: + return hasBodyField( + key.getKey(), Value.of(((List) value).stream().map(Value::of).collect(toList()))); + case DOUBLE_ARRAY: + return hasBodyField( + key.getKey(), + Value.of(((List) value).stream().map(Value::of).collect(toList()))); + } + return this; + } + /** Asserts the log has the given attributes. */ public LogRecordDataAssert hasAttributes(Attributes attributes) { isNotNull(); diff --git a/sdk/testing/src/test/java/io/opentelemetry/sdk/testing/assertj/LogAssertionsTest.java b/sdk/testing/src/test/java/io/opentelemetry/sdk/testing/assertj/LogAssertionsTest.java index 15da07a5214..849ba25b90f 100644 --- a/sdk/testing/src/test/java/io/opentelemetry/sdk/testing/assertj/LogAssertionsTest.java +++ b/sdk/testing/src/test/java/io/opentelemetry/sdk/testing/assertj/LogAssertionsTest.java @@ -5,6 +5,14 @@ package io.opentelemetry.sdk.testing.assertj; +import static io.opentelemetry.api.common.AttributeKey.booleanArrayKey; +import static io.opentelemetry.api.common.AttributeKey.booleanKey; +import static io.opentelemetry.api.common.AttributeKey.doubleArrayKey; +import static io.opentelemetry.api.common.AttributeKey.doubleKey; +import static io.opentelemetry.api.common.AttributeKey.longArrayKey; +import static io.opentelemetry.api.common.AttributeKey.longKey; +import static io.opentelemetry.api.common.AttributeKey.stringArrayKey; +import static io.opentelemetry.api.common.AttributeKey.stringKey; import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.assertThat; import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.attributeEntry; import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.equalTo; @@ -13,15 +21,22 @@ import io.opentelemetry.api.common.AttributeKey; import io.opentelemetry.api.common.Attributes; +import io.opentelemetry.api.common.Value; +import io.opentelemetry.api.incubator.events.EventLogger; import io.opentelemetry.api.logs.Severity; import io.opentelemetry.api.trace.SpanContext; import io.opentelemetry.api.trace.TraceFlags; import io.opentelemetry.api.trace.TraceState; import io.opentelemetry.sdk.common.InstrumentationScopeInfo; +import io.opentelemetry.sdk.logs.SdkLoggerProvider; import io.opentelemetry.sdk.logs.data.LogRecordData; +import io.opentelemetry.sdk.logs.export.SimpleLogRecordProcessor; +import io.opentelemetry.sdk.logs.internal.SdkEventLoggerProvider; import io.opentelemetry.sdk.resources.Resource; +import io.opentelemetry.sdk.testing.exporter.InMemoryLogRecordExporter; import io.opentelemetry.sdk.testing.logs.TestLogRecordData; import java.util.Arrays; +import java.util.List; import java.util.concurrent.TimeUnit; import org.junit.jupiter.api.Test; @@ -33,7 +48,7 @@ public class LogAssertionsTest { private static final String TRACE_ID = "00000000000000010000000000000002"; private static final String SPAN_ID = "0000000000000003"; - private static final AttributeKey DOG = AttributeKey.stringKey("dog"); + private static final AttributeKey DOG = stringKey("dog"); private static final Attributes ATTRIBUTES = Attributes.builder() .put("bear", "mya") @@ -79,7 +94,7 @@ void passing() { attributes -> assertThat(attributes) .hasSize(2) - .containsEntry(AttributeKey.stringKey("dog"), "bark") + .containsEntry(stringKey("dog"), "bark") .hasEntrySatisfying(DOG, value -> assertThat(value).hasSize(4)) .hasEntrySatisfying( AttributeKey.booleanKey("dog is cute"), @@ -118,14 +133,13 @@ void passing() { attributes -> OpenTelemetryAssertions.assertThat(attributes) .hasSize(8) - .containsEntry(AttributeKey.stringKey("bear"), "mya") - .hasEntrySatisfying( - AttributeKey.stringKey("bear"), value -> assertThat(value).hasSize(3)) + .containsEntry(stringKey("bear"), "mya") + .hasEntrySatisfying(stringKey("bear"), value -> assertThat(value).hasSize(3)) .containsEntry("bear", "mya") .containsEntry("warm", true) .containsEntry("temperature", 30) - .containsEntry(AttributeKey.longKey("temperature"), 30L) - .containsEntry(AttributeKey.longKey("temperature"), 30) + .containsEntry(longKey("temperature"), 30L) + .containsEntry(longKey("temperature"), 30) .containsEntry("length", 1.2) .containsEntry("colors", "red", "blue") .containsEntryWithStringValuesOf("colors", Arrays.asList("red", "blue")) @@ -135,7 +149,7 @@ void passing() { .containsEntryWithLongValuesOf("scores", Arrays.asList(0L, 1L)) .containsEntry("coins", 0.01, 0.05, 0.1) .containsEntryWithDoubleValuesOf("coins", Arrays.asList(0.01, 0.05, 0.1)) - .containsKey(AttributeKey.stringKey("bear")) + .containsKey(stringKey("bear")) .containsKey("bear") .containsOnly( attributeEntry("bear", "mya"), @@ -147,12 +161,12 @@ void passing() { attributeEntry("scores", 0L, 1L), attributeEntry("coins", 0.01, 0.05, 0.1))) .hasAttributesSatisfying( - equalTo(AttributeKey.stringKey("bear"), "mya"), + equalTo(stringKey("bear"), "mya"), equalTo(AttributeKey.booleanArrayKey("conditions"), Arrays.asList(false, true))) .hasAttributesSatisfyingExactly( - equalTo(AttributeKey.stringKey("bear"), "mya"), + equalTo(stringKey("bear"), "mya"), equalTo(AttributeKey.booleanKey("warm"), true), - equalTo(AttributeKey.longKey("temperature"), 30L), + equalTo(longKey("temperature"), 30L), equalTo(AttributeKey.doubleKey("length"), 1.2), equalTo(AttributeKey.stringArrayKey("colors"), Arrays.asList("red", "blue")), equalTo(AttributeKey.booleanArrayKey("conditions"), Arrays.asList(false, true)), @@ -228,7 +242,7 @@ void failure() { .hasAttributesSatisfying( attributes -> OpenTelemetryAssertions.assertThat(attributes) - .containsKey(AttributeKey.stringKey("cat")))) + .containsKey(stringKey("cat")))) .isInstanceOf(AssertionError.class); assertThatThrownBy( () -> @@ -256,24 +270,71 @@ void failure() { attributes -> OpenTelemetryAssertions.assertThat(attributes) .hasEntrySatisfying( - AttributeKey.stringKey("bear"), - value -> assertThat(value).hasSize(2)))) + stringKey("bear"), value -> assertThat(value).hasSize(2)))) .isInstanceOf(AssertionError.class); assertThatThrownBy( - () -> - assertThat(LOG_DATA) - .hasAttributesSatisfying(equalTo(AttributeKey.stringKey("bear"), "moo"))) + () -> assertThat(LOG_DATA).hasAttributesSatisfying(equalTo(stringKey("bear"), "moo"))) .isInstanceOf(AssertionError.class); assertThatThrownBy( () -> assertThat(LOG_DATA) .hasAttributesSatisfyingExactly( - equalTo(AttributeKey.stringKey("bear"), "mya"), + equalTo(stringKey("bear"), "mya"), equalTo(AttributeKey.booleanKey("warm"), true), - equalTo(AttributeKey.longKey("temperature"), 30L), + equalTo(longKey("temperature"), 30L), equalTo(AttributeKey.doubleKey("length"), 1.2))) .isInstanceOf(AssertionError.class); assertThatThrownBy(() -> assertThat(LOG_DATA).hasTotalAttributeCount(11)) .isInstanceOf(AssertionError.class); } + + @Test + void eventBodyAssertions() { + InMemoryLogRecordExporter exporter = InMemoryLogRecordExporter.create(); + SdkLoggerProvider loggerProvider = + SdkLoggerProvider.builder() + .addLogRecordProcessor(SimpleLogRecordProcessor.create(exporter)) + .build(); + EventLogger eventLogger = SdkEventLoggerProvider.create(loggerProvider).get("test.test"); + eventLogger + .builder("foo") + .put("foostr", "bar") + .put("foobool", true) + .put("foolong", 12L) + .put("foodbl", 12.0) + .put("foostra", "bar", "baz", "buzz") + .put("foolonga", 9, 0, 2, 1, 0) + .put("foodbla", 9.1, 0.2, 2.3, 1.4, 0.5) + .put("fooboola", true, true, true, false) + .put("fooany", Value.of("grim")) + .put(stringKey("ak_str"), "bar") + .put(booleanKey("ak_bool"), true) + .put(longKey("ak_long"), 12L) + .put(doubleKey("ak_dbl"), 12.0) + .put(stringArrayKey("ak_stra"), Arrays.asList("bar", "baz", "buzz")) + .put(longArrayKey("ak_longa"), Arrays.asList(9L, 0L, 2L, 1L, 0L)) + .put(doubleArrayKey("ak_dbla"), Arrays.asList(9.1, 0.2, 2.3, 1.4, 0.5)) + .put(booleanArrayKey("ak_boola"), Arrays.asList(true, true, true, false)) + .emit(); + List logs = exporter.getFinishedLogRecordItems(); + assertThat(logs).hasSize(1); + assertThat(logs.get(0)) + .hasBodyField("foostr", "bar") + .hasBodyField("foobool", true) + .hasBodyField("foolong", 12L) + .hasBodyField("foodbl", 12.0) + .hasBodyField("foostra", "bar", "baz", "buzz") + .hasBodyField("foolonga", 9, 0, 2, 1, 0) + .hasBodyField("foodbla", 9.1, 0.2, 2.3, 1.4, 0.5) + .hasBodyField("fooboola", true, true, true, false) + .hasBodyField("fooany", Value.of("grim")) + .hasBodyField(stringKey("ak_str"), "bar") + .hasBodyField(booleanKey("ak_bool"), true) + .hasBodyField(longKey("ak_long"), 12L) + .hasBodyField(doubleKey("ak_dbl"), 12.0) + .hasBodyField(stringArrayKey("ak_stra"), Arrays.asList("bar", "baz", "buzz")) + .hasBodyField(longArrayKey("ak_longa"), Arrays.asList(9L, 0L, 2L, 1L, 0L)) + .hasBodyField(doubleArrayKey("ak_dbla"), Arrays.asList(9.1, 0.2, 2.3, 1.4, 0.5)) + .hasBodyField(booleanArrayKey("ak_boola"), Arrays.asList(true, true, true, false)); + } } From aef4ca5b1e0739eb7e2282e7efe863330f1eb205 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 5 Sep 2024 13:50:06 -0500 Subject: [PATCH 548/901] Update dependency io.netty:netty-bom to v4.1.113.Final (#6685) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- dependencyManagement/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index 3bc673ed1da..777cd1ea2b7 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -15,7 +15,7 @@ val DEPENDENCY_BOMS = listOf( "com.squareup.okhttp3:okhttp-bom:4.12.0", "com.squareup.okio:okio-bom:3.9.0", // applies to transitive dependencies of okhttp "io.grpc:grpc-bom:1.66.0", - "io.netty:netty-bom:4.1.112.Final", + "io.netty:netty-bom:4.1.113.Final", "io.zipkin.brave:brave-bom:6.0.3", "io.zipkin.reporter2:zipkin-reporter-bom:3.4.0", "org.assertj:assertj-bom:3.26.3", From 61a4b466765d25acfcc808b813712743cc51bddd Mon Sep 17 00:00:00 2001 From: jackshirazi Date: Thu, 5 Sep 2024 21:07:33 +0100 Subject: [PATCH 549/901] make SdkTracer.tracerEnabled mutable (#6687) Co-authored-by: jack-berg <34418638+jack-berg@users.noreply.github.com> --- .../src/main/java/io/opentelemetry/sdk/trace/SdkTracer.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/SdkTracer.java b/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/SdkTracer.java index cd8c7ca2471..7b74c035e82 100644 --- a/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/SdkTracer.java +++ b/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/SdkTracer.java @@ -19,7 +19,10 @@ final class SdkTracer implements ExtendedTracer { private final TracerSharedState sharedState; private final InstrumentationScopeInfo instrumentationScopeInfo; - private final boolean tracerEnabled; + + // TODO: add dedicated API for updating scope config. + @SuppressWarnings("FieldCanBeFinal") // For now, allow updating reflectively. + private boolean tracerEnabled; SdkTracer( TracerSharedState sharedState, From 00b0e9f87c7009db6c40f384d02595c4662056c1 Mon Sep 17 00:00:00 2001 From: jack-berg <34418638+jack-berg@users.noreply.github.com> Date: Thu, 5 Sep 2024 15:08:18 -0500 Subject: [PATCH 550/901] Declarative configuration missing pieces (#6677) --- .../spi/internal/ComponentProvider.java | 17 ++++++++++++++--- sdk-extensions/incubator/build.gradle.kts | 1 + .../incubator/fileconfig/FileConfiguration.java | 14 ++++++++++++-- .../YamlStructuredConfigProperties.java | 4 ++-- .../YamlStructuredConfigPropertiesTest.java | 7 ++++++- 5 files changed, 35 insertions(+), 8 deletions(-) diff --git a/sdk-extensions/autoconfigure-spi/src/main/java/io/opentelemetry/sdk/autoconfigure/spi/internal/ComponentProvider.java b/sdk-extensions/autoconfigure-spi/src/main/java/io/opentelemetry/sdk/autoconfigure/spi/internal/ComponentProvider.java index fe1e310abc9..335c9a7c0ab 100644 --- a/sdk-extensions/autoconfigure-spi/src/main/java/io/opentelemetry/sdk/autoconfigure/spi/internal/ComponentProvider.java +++ b/sdk-extensions/autoconfigure-spi/src/main/java/io/opentelemetry/sdk/autoconfigure/spi/internal/ComponentProvider.java @@ -5,19 +5,29 @@ package io.opentelemetry.sdk.autoconfigure.spi.internal; +import io.opentelemetry.context.propagation.TextMapPropagator; +import io.opentelemetry.sdk.logs.LogRecordProcessor; import io.opentelemetry.sdk.logs.export.LogRecordExporter; import io.opentelemetry.sdk.metrics.export.MetricExporter; +import io.opentelemetry.sdk.resources.Resource; +import io.opentelemetry.sdk.trace.SpanProcessor; import io.opentelemetry.sdk.trace.export.SpanExporter; +import io.opentelemetry.sdk.trace.samplers.Sampler; /** * Provides configured instances of SDK extension components. {@link ComponentProvider} allows SDK * extension components which are not part of the core SDK to be referenced in file based * configuration. * + *

      NOTE: when {@link #getType()} is {@link Resource}, the {@link #getName()} is not (currently) + * used, and {@link #create(StructuredConfigProperties)} is (currently) called with an empty {@link + * StructuredConfigProperties}. + * * @param the type of the SDK extension component. See {@link #getType()}. Supported values - * include: {@link SpanExporter}, {@link MetricExporter}, {@link LogRecordExporter}. + * include: {@link SpanExporter}, {@link MetricExporter}, {@link LogRecordExporter}, {@link + * SpanProcessor}, {@link LogRecordProcessor}, {@link TextMapPropagator}, {@link Sampler}, + * {@link Resource}. */ -// TODO: add support for Sampler, LogRecordProcessor, SpanProcessor, MetricReader public interface ComponentProvider { /** @@ -31,7 +41,8 @@ public interface ComponentProvider { * instances of a custom span exporter for the "acme" protocol, the name might be "acme". * *

      This name MUST not be the same as any other component provider name which returns components - * of the same {@link #getType() type}. + * of the same {@link #getType() type}. In other words, {@link #getType()} and name form a + * composite key uniquely identifying the provider. */ String getName(); diff --git a/sdk-extensions/incubator/build.gradle.kts b/sdk-extensions/incubator/build.gradle.kts index 847a3b039e6..f562360655e 100644 --- a/sdk-extensions/incubator/build.gradle.kts +++ b/sdk-extensions/incubator/build.gradle.kts @@ -26,6 +26,7 @@ dependencies { // io.opentelemetry.sdk.extension.incubator.fileconfig implementation("com.fasterxml.jackson.core:jackson-databind") + api("com.fasterxml.jackson.core:jackson-annotations") implementation("com.fasterxml.jackson.dataformat:jackson-dataformat-yaml") implementation(project(":sdk-extensions:autoconfigure")) diff --git a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/FileConfiguration.java b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/FileConfiguration.java index 1a28935086b..ec7fe6407ac 100644 --- a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/FileConfiguration.java +++ b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/FileConfiguration.java @@ -123,8 +123,7 @@ static Object loadYaml(InputStream inputStream, Map environmentV } /** - * Convert the {@code model} to a generic {@link StructuredConfigProperties}, which can be used to - * read configuration not part of the model. + * Convert the {@code model} to a generic {@link StructuredConfigProperties}. * * @param model the configuration model * @return a generic {@link StructuredConfigProperties} representation of the model @@ -133,6 +132,17 @@ public static StructuredConfigProperties toConfigProperties(OpenTelemetryConfigu return toConfigProperties((Object) model); } + /** + * Convert the {@code configuration} YAML to a generic {@link StructuredConfigProperties}. + * + * @param configuration configuration YAML + * @return a generic {@link StructuredConfigProperties} representation of the model + */ + public static StructuredConfigProperties toConfigProperties(InputStream configuration) { + Object yamlObj = loadYaml(configuration, System.getenv()); + return toConfigProperties(yamlObj); + } + static StructuredConfigProperties toConfigProperties(Object model) { Map configurationMap = MAPPER.convertValue(model, new TypeReference>() {}); diff --git a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/YamlStructuredConfigProperties.java b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/YamlStructuredConfigProperties.java index 2e9e20d3f0c..bc74b333cd4 100644 --- a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/YamlStructuredConfigProperties.java +++ b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/YamlStructuredConfigProperties.java @@ -64,7 +64,7 @@ static YamlStructuredConfigProperties create(Map properties) { for (Map.Entry entry : properties.entrySet()) { String key = entry.getKey(); Object value = entry.getValue(); - if (isPrimitive(value)) { + if (isPrimitive(value) || value == null) { simpleEntries.put(key, value); continue; } @@ -283,7 +283,7 @@ public String toString() { } /** Return a map representation of the data. */ - Map toMap() { + public Map toMap() { Map result = new HashMap<>(simpleEntries); listEntries.forEach( (key, value) -> diff --git a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/YamlStructuredConfigPropertiesTest.java b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/YamlStructuredConfigPropertiesTest.java index 5c4f3d71333..b29e4c97162 100644 --- a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/YamlStructuredConfigPropertiesTest.java +++ b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/YamlStructuredConfigPropertiesTest.java @@ -33,6 +33,7 @@ class YamlStructuredConfigPropertiesTest { + " int_key: 1\n" + " float_key: 1.1\n" + " bool_key: true\n" + + " null_key:\n" + " str_list_key: [val1, val2]\n" + " int_list_key: [1, 2]\n" + " float_list_key: [1.1, 2.2]\n" @@ -90,6 +91,7 @@ void additionalProperties() { "int_key", "float_key", "bool_key", + "null_key", "str_list_key", "int_list_key", "float_list_key", @@ -101,7 +103,10 @@ void additionalProperties() { assertThat(otherProps.getInt("int_key")).isEqualTo(1); assertThat(otherProps.getLong("int_key")).isEqualTo(1); assertThat(otherProps.getDouble("float_key")).isEqualTo(1.1); - assertThat(otherProps.getBoolean("bool_key")).isTrue(); + assertThat(otherProps.getString("null_key")).isNull(); + assertThat(otherProps.getInt("null_key")).isNull(); + assertThat(otherProps.getLong("null_key")).isNull(); + assertThat(otherProps.getBoolean("null_key")).isNull(); assertThat(otherProps.getScalarList("str_list_key", String.class)) .isEqualTo(Arrays.asList("val1", "val2")); assertThat(otherProps.getScalarList("int_list_key", Long.class)) From 1f6de3590d284e3ced20c5ac9c8217dda6336732 Mon Sep 17 00:00:00 2001 From: jack-berg <34418638+jack-berg@users.noreply.github.com> Date: Thu, 5 Sep 2024 15:22:56 -0500 Subject: [PATCH 551/901] Align GrpcSender contract with HttpSender (#6658) --- .../exporter/internal/grpc/GrpcExporter.java | 69 +++++++------- .../exporter/internal/grpc/GrpcResponse.java | 2 + .../exporter/internal/grpc/GrpcSender.java | 4 +- .../exporter/internal/http/HttpExporter.java | 89 ++++++++++--------- .../AbstractGrpcTelemetryExporterTest.java | 17 +++- .../internal/UpstreamGrpcSender.java | 38 ++++++-- .../okhttp/internal/OkHttpGrpcSender.java | 27 ++---- .../internal/OkHttpGrpcSuppressionTest.java | 2 +- 8 files changed, 140 insertions(+), 108 deletions(-) diff --git a/exporters/common/src/main/java/io/opentelemetry/exporter/internal/grpc/GrpcExporter.java b/exporters/common/src/main/java/io/opentelemetry/exporter/internal/grpc/GrpcExporter.java index e8101049b9f..128ddc436d5 100644 --- a/exporters/common/src/main/java/io/opentelemetry/exporter/internal/grpc/GrpcExporter.java +++ b/exporters/common/src/main/java/io/opentelemetry/exporter/internal/grpc/GrpcExporter.java @@ -7,7 +7,6 @@ import static io.opentelemetry.exporter.internal.grpc.GrpcExporterUtil.GRPC_STATUS_UNAVAILABLE; import static io.opentelemetry.exporter.internal.grpc.GrpcExporterUtil.GRPC_STATUS_UNIMPLEMENTED; -import static io.opentelemetry.exporter.internal.grpc.GrpcExporterUtil.GRPC_STATUS_UNKNOWN; import io.opentelemetry.api.metrics.MeterProvider; import io.opentelemetry.exporter.internal.ExporterMetrics; @@ -62,41 +61,27 @@ public CompletableResultCode export(T exportRequest, int numItems) { grpcSender.send( exportRequest, - () -> { - exporterMetrics.addSuccess(numItems); - result.succeed(); - }, - (response, throwable) -> { - exporterMetrics.addFailed(numItems); - - logFailureMessage(response, throwable); - - switch (response.grpcStatusValue()) { - case GRPC_STATUS_UNKNOWN: - result.failExceptionally(FailedExportException.grpcFailedExceptionally(throwable)); - break; - default: - result.failExceptionally(FailedExportException.grpcFailedWithResponse(response)); - break; - } - }); + grpcResponse -> onResponse(result, numItems, grpcResponse), + throwable -> onError(result, numItems, throwable)); return result; } - public CompletableResultCode shutdown() { - if (!isShutdown.compareAndSet(false, true)) { - logger.log(Level.INFO, "Calling shutdown() multiple times."); - return CompletableResultCode.ofSuccess(); + private void onResponse(CompletableResultCode result, int numItems, GrpcResponse grpcResponse) { + int statusCode = grpcResponse.grpcStatusValue(); + + if (statusCode == 0) { + exporterMetrics.addSuccess(numItems); + result.succeed(); + return; } - return grpcSender.shutdown(); - } - private void logFailureMessage(GrpcResponse response, Throwable throwable) { - switch (response.grpcStatusValue()) { + exporterMetrics.addFailed(numItems); + switch (statusCode) { case GRPC_STATUS_UNIMPLEMENTED: if (loggedUnimplemented.compareAndSet(false, true)) { - GrpcExporterUtil.logUnimplemented(internalLogger, type, response.grpcStatusDescription()); + GrpcExporterUtil.logUnimplemented( + internalLogger, type, grpcResponse.grpcStatusDescription()); } break; case GRPC_STATUS_UNAVAILABLE: @@ -107,7 +92,7 @@ private void logFailureMessage(GrpcResponse response, Throwable throwable) { + "s. Server is UNAVAILABLE. " + "Make sure your collector is running and reachable from this network. " + "Full error message:" - + response.grpcStatusDescription()); + + grpcResponse.grpcStatusDescription()); break; default: logger.log( @@ -115,14 +100,34 @@ private void logFailureMessage(GrpcResponse response, Throwable throwable) { "Failed to export " + type + "s. Server responded with gRPC status code " - + response.grpcStatusValue() + + statusCode + ". Error message: " - + response.grpcStatusDescription()); + + grpcResponse.grpcStatusDescription()); break; } + result.failExceptionally(FailedExportException.grpcFailedWithResponse(grpcResponse)); + } + private void onError(CompletableResultCode result, int numItems, Throwable e) { + exporterMetrics.addFailed(numItems); + logger.log( + Level.SEVERE, + "Failed to export " + + type + + "s. The request could not be executed. Error message: " + + e.getMessage(), + e); if (logger.isLoggable(Level.FINEST)) { - logger.log(Level.FINEST, "Failed to export " + type + "s. Details follow: " + throwable); + logger.log(Level.FINEST, "Failed to export " + type + "s. Details follow: " + e); } + result.failExceptionally(FailedExportException.grpcFailedExceptionally(e)); + } + + public CompletableResultCode shutdown() { + if (!isShutdown.compareAndSet(false, true)) { + logger.log(Level.INFO, "Calling shutdown() multiple times."); + return CompletableResultCode.ofSuccess(); + } + return grpcSender.shutdown(); } } diff --git a/exporters/common/src/main/java/io/opentelemetry/exporter/internal/grpc/GrpcResponse.java b/exporters/common/src/main/java/io/opentelemetry/exporter/internal/grpc/GrpcResponse.java index 01ac2f53e6f..4602cbc0ba7 100644 --- a/exporters/common/src/main/java/io/opentelemetry/exporter/internal/grpc/GrpcResponse.java +++ b/exporters/common/src/main/java/io/opentelemetry/exporter/internal/grpc/GrpcResponse.java @@ -25,4 +25,6 @@ public static GrpcResponse create(int grpcStatusValue, @Nullable String grpcStat @Nullable public abstract String grpcStatusDescription(); + + // TODO(jack-berg): add byte[] responseBody() throws IOException; } diff --git a/exporters/common/src/main/java/io/opentelemetry/exporter/internal/grpc/GrpcSender.java b/exporters/common/src/main/java/io/opentelemetry/exporter/internal/grpc/GrpcSender.java index d2dc05b16fd..ed85d630e42 100644 --- a/exporters/common/src/main/java/io/opentelemetry/exporter/internal/grpc/GrpcSender.java +++ b/exporters/common/src/main/java/io/opentelemetry/exporter/internal/grpc/GrpcSender.java @@ -7,7 +7,7 @@ import io.opentelemetry.exporter.internal.marshal.Marshaler; import io.opentelemetry.sdk.common.CompletableResultCode; -import java.util.function.BiConsumer; +import java.util.function.Consumer; /** * An exporter of a messages encoded by {@link Marshaler} using the gRPC wire format. @@ -17,7 +17,7 @@ */ public interface GrpcSender { - void send(T request, Runnable onSuccess, BiConsumer onError); + void send(T request, Consumer onResponse, Consumer onError); /** Shutdown the sender. */ CompletableResultCode shutdown(); diff --git a/exporters/common/src/main/java/io/opentelemetry/exporter/internal/http/HttpExporter.java b/exporters/common/src/main/java/io/opentelemetry/exporter/internal/http/HttpExporter.java index d0361eaecca..5ab37416b97 100644 --- a/exporters/common/src/main/java/io/opentelemetry/exporter/internal/http/HttpExporter.java +++ b/exporters/common/src/main/java/io/opentelemetry/exporter/internal/http/HttpExporter.java @@ -63,52 +63,57 @@ public CompletableResultCode export(T exportRequest, int numItems) { httpSender.send( exportRequest, exportRequest.getBinarySerializedSize(), - httpResponse -> { - int statusCode = httpResponse.statusCode(); - - if (statusCode >= 200 && statusCode < 300) { - exporterMetrics.addSuccess(numItems); - result.succeed(); - return; - } - - exporterMetrics.addFailed(numItems); - - byte[] body = null; - try { - body = httpResponse.responseBody(); - } catch (IOException ex) { - logger.log(Level.FINE, "Unable to obtain response body", ex); - } - - String status = extractErrorStatus(httpResponse.statusMessage(), body); - - logger.log( - Level.WARNING, - "Failed to export " - + type - + "s. Server responded with HTTP status code " - + statusCode - + ". Error message: " - + status); - - result.failExceptionally(FailedExportException.httpFailedWithResponse(httpResponse)); - }, - e -> { - exporterMetrics.addFailed(numItems); - logger.log( - Level.SEVERE, - "Failed to export " - + type - + "s. The request could not be executed. Full error message: " - + e.getMessage(), - e); - result.failExceptionally(FailedExportException.httpFailedExceptionally(e)); - }); + httpResponse -> onResponse(result, numItems, httpResponse), + throwable -> onError(result, numItems, throwable)); return result; } + private void onResponse( + CompletableResultCode result, int numItems, HttpSender.Response httpResponse) { + int statusCode = httpResponse.statusCode(); + + if (statusCode >= 200 && statusCode < 300) { + exporterMetrics.addSuccess(numItems); + result.succeed(); + return; + } + + exporterMetrics.addFailed(numItems); + + byte[] body = null; + try { + body = httpResponse.responseBody(); + } catch (IOException ex) { + logger.log(Level.FINE, "Unable to obtain response body", ex); + } + + String status = extractErrorStatus(httpResponse.statusMessage(), body); + + logger.log( + Level.WARNING, + "Failed to export " + + type + + "s. Server responded with HTTP status code " + + statusCode + + ". Error message: " + + status); + + result.failExceptionally(FailedExportException.httpFailedWithResponse(httpResponse)); + } + + private void onError(CompletableResultCode result, int numItems, Throwable e) { + exporterMetrics.addFailed(numItems); + logger.log( + Level.SEVERE, + "Failed to export " + + type + + "s. The request could not be executed. Full error message: " + + e.getMessage(), + e); + result.failExceptionally(FailedExportException.httpFailedExceptionally(e)); + } + public CompletableResultCode shutdown() { if (!isShutdown.compareAndSet(false, true)) { logger.log(Level.INFO, "Calling shutdown() multiple times."); diff --git a/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/AbstractGrpcTelemetryExporterTest.java b/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/AbstractGrpcTelemetryExporterTest.java index 5950d8c00aa..4dcacfb329b 100644 --- a/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/AbstractGrpcTelemetryExporterTest.java +++ b/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/AbstractGrpcTelemetryExporterTest.java @@ -488,8 +488,19 @@ void connectTimeout() { long startTimeMillis = System.currentTimeMillis(); CompletableResultCode result = exporter.export(Collections.singletonList(generateFakeTelemetry())); + assertThat(result.join(10, TimeUnit.SECONDS).isSuccess()).isFalse(); + assertThat(result.getFailureThrowable()) + .asInstanceOf( + InstanceOfAssertFactories.throwable(FailedExportException.GrpcExportException.class)) + .returns(false, Assertions.from(FailedExportException::failedWithResponse)) + .satisfies( + ex -> { + assertThat(ex.getResponse()).isNull(); + assertThat(ex.getCause()).isNotNull(); + }); + // Assert that the export request fails well before the default connect timeout of 10s assertThat(System.currentTimeMillis() - startTimeMillis) .isLessThan(TimeUnit.SECONDS.toMillis(1)); @@ -597,12 +608,12 @@ void errorWithUnknownError() { .getFailureThrowable()) .asInstanceOf( InstanceOfAssertFactories.throwable(FailedExportException.GrpcExportException.class)) - .returns(false, Assertions.from(FailedExportException::failedWithResponse)) + .returns(true, Assertions.from(FailedExportException::failedWithResponse)) .satisfies( ex -> { - assertThat(ex.getResponse()).isNull(); + assertThat(ex.getResponse()).isNotNull(); - assertThat(ex.getCause()).isNotNull(); + assertThat(ex.getCause()).isNull(); }); } finally { exporter.shutdown(); diff --git a/exporters/sender/grpc-managed-channel/src/main/java/io/opentelemetry/exporter/sender/grpc/managedchannel/internal/UpstreamGrpcSender.java b/exporters/sender/grpc-managed-channel/src/main/java/io/opentelemetry/exporter/sender/grpc/managedchannel/internal/UpstreamGrpcSender.java index f8fa234e4e6..2c250399bb1 100644 --- a/exporters/sender/grpc-managed-channel/src/main/java/io/opentelemetry/exporter/sender/grpc/managedchannel/internal/UpstreamGrpcSender.java +++ b/exporters/sender/grpc-managed-channel/src/main/java/io/opentelemetry/exporter/sender/grpc/managedchannel/internal/UpstreamGrpcSender.java @@ -11,6 +11,8 @@ import io.grpc.ManagedChannel; import io.grpc.Metadata; import io.grpc.Status; +import io.grpc.StatusException; +import io.grpc.StatusRuntimeException; import io.grpc.stub.MetadataUtils; import io.opentelemetry.exporter.internal.grpc.GrpcResponse; import io.opentelemetry.exporter.internal.grpc.GrpcSender; @@ -20,9 +22,9 @@ import java.util.List; import java.util.Map; import java.util.concurrent.TimeUnit; -import java.util.function.BiConsumer; +import java.util.function.Consumer; import java.util.function.Supplier; -import org.checkerframework.checker.nullness.qual.Nullable; +import javax.annotation.Nullable; /** * A {@link GrpcSender} which uses the upstream grpc-java library. @@ -50,7 +52,7 @@ public UpstreamGrpcSender( } @Override - public void send(T request, Runnable onSuccess, BiConsumer onError) { + public void send(T request, Consumer onResponse, Consumer onError) { MarshalerServiceStub stub = this.stub; if (timeoutNanos > 0) { stub = stub.withDeadlineAfter(timeoutNanos, TimeUnit.NANOSECONDS); @@ -71,19 +73,41 @@ public void send(T request, Runnable onSuccess, BiConsumer() { @Override public void onSuccess(@Nullable Object unused) { - onSuccess.run(); + onResponse.accept( + GrpcResponse.create(Status.OK.getCode().value(), Status.OK.getDescription())); } @Override public void onFailure(Throwable t) { - Status status = Status.fromThrowable(t); - onError.accept( - GrpcResponse.create(status.getCode().value(), status.getDescription()), t); + Status status = fromThrowable(t); + if (status == null) { + onError.accept(t); + } else { + onResponse.accept( + GrpcResponse.create(status.getCode().value(), status.getDescription())); + } } }, MoreExecutors.directExecutor()); } + /** + * Copy of {@link Status#fromThrowable(Throwable)} which returns null instead of {@link + * Status#UNKNOWN} when no status can be found. + */ + @Nullable + private static Status fromThrowable(Throwable cause) { + while (cause != null) { + if (cause instanceof StatusException) { + return ((StatusException) cause).getStatus(); + } else if (cause instanceof StatusRuntimeException) { + return ((StatusRuntimeException) cause).getStatus(); + } + cause = cause.getCause(); + } + return null; + } + @Override public CompletableResultCode shutdown() { if (shutdownChannel) { diff --git a/exporters/sender/okhttp/src/main/java/io/opentelemetry/exporter/sender/okhttp/internal/OkHttpGrpcSender.java b/exporters/sender/okhttp/src/main/java/io/opentelemetry/exporter/sender/okhttp/internal/OkHttpGrpcSender.java index a622d95ac6c..8776762b62b 100644 --- a/exporters/sender/okhttp/src/main/java/io/opentelemetry/exporter/sender/okhttp/internal/OkHttpGrpcSender.java +++ b/exporters/sender/okhttp/src/main/java/io/opentelemetry/exporter/sender/okhttp/internal/OkHttpGrpcSender.java @@ -40,7 +40,7 @@ import java.util.Collections; import java.util.List; import java.util.Map; -import java.util.function.BiConsumer; +import java.util.function.Consumer; import java.util.function.Supplier; import javax.annotation.Nullable; import javax.net.ssl.SSLContext; @@ -109,7 +109,7 @@ public OkHttpGrpcSender( } @Override - public void send(T request, Runnable onSuccess, BiConsumer onError) { + public void send(T request, Consumer onResponse, Consumer onError) { Request.Builder requestBuilder = new Request.Builder().url(url); Map> headers = headersSupplier.get(); @@ -132,13 +132,7 @@ public void send(T request, Runnable onSuccess, BiConsumer sender, Runnable onSuccess, Runnable onFailure) { - sender.send(new DummyMarshaler(), onSuccess, (grpcResponse, throwable) -> onFailure.run()); + sender.send(new DummyMarshaler(), grpcResponse -> {}, throwable -> onFailure.run()); } @Override From f85a57b5b6bdff9c6292d1ad6aa9d13b914df6f8 Mon Sep 17 00:00:00 2001 From: Gregor Zeitlinger Date: Thu, 5 Sep 2024 23:02:27 +0200 Subject: [PATCH 552/901] don't throw class cast exception when we have a noop tracer, meter, logger (#6617) Co-authored-by: Jack Berg --- api/all/build.gradle.kts | 5 + .../api/internal/IncubatingUtil.java | 29 ++ .../api/logs/LoggerProvider.java | 5 +- .../api/metrics/DefaultMeterProvider.java | 7 +- .../api/trace/DefaultTracerProvider.java | 6 +- .../opentelemetry/api/OpenTelemetryTest.java | 96 +--- .../api/logs/DefaultLoggerProviderTest.java | 33 -- .../api/logs/DefaultLoggerTest.java | 37 +- .../api/metrics/DefaultMeterProviderTest.java | 29 -- .../api/metrics/DefaultMeterTest.java | 198 +------- .../api/trace/DefaultTracerProviderTest.java | 19 - .../api/trace/DefaultTracerTest.java | 88 +--- .../api/trace/SpanBuilderTest.java | 65 --- .../api/AbstractOpenTelemetryTest.java | 114 +++++ .../api/logs/AbstractDefaultLoggerTest.java | 65 +++ .../api/metrics/AbstractDefaultMeterTest.java | 251 ++++++++++ .../api/trace/AbstractDefaultTracerTest.java | 153 ++++++ api/incubator/build.gradle.kts | 1 + .../incubator/logs/ExtendedDefaultLogger.java | 90 ++++ .../logs/ExtendedDefaultLoggerProvider.java | 45 ++ .../metrics/ExtendedDefaultMeter.java | 454 ++++++++++++++++++ .../metrics/ExtendedDefaultMeterProvider.java | 45 ++ .../trace/ExtendedDefaultTracer.java | 156 ++++++ .../trace/ExtendedDefaultTracerBuilder.java | 32 ++ .../trace/ExtendedDefaultTracerProvider.java | 38 ++ .../opentelemetry-api/reflect-config.json | 38 ++ .../incubator/ExtendedOpenTelemetryTest.java | 53 ++ .../logs/ExtendedDefaultLoggerTest.java | 37 ++ .../metrics/ExtendedDefaultMeterTest.java | 70 +++ .../trace/ExtendedDefaultTracerTest.java | 65 +++ .../graal-incubating/build.gradle.kts | 48 ++ .../graal/IncubatingApiTests.java | 26 + .../graal/IncubatingNotFoundApiTests.java | 26 + settings.gradle.kts | 1 + 34 files changed, 1889 insertions(+), 536 deletions(-) create mode 100644 api/all/src/main/java/io/opentelemetry/api/internal/IncubatingUtil.java delete mode 100644 api/all/src/test/java/io/opentelemetry/api/logs/DefaultLoggerProviderTest.java delete mode 100644 api/all/src/test/java/io/opentelemetry/api/metrics/DefaultMeterProviderTest.java delete mode 100644 api/all/src/test/java/io/opentelemetry/api/trace/DefaultTracerProviderTest.java delete mode 100644 api/all/src/test/java/io/opentelemetry/api/trace/SpanBuilderTest.java create mode 100644 api/all/src/testFixtures/java/io/opentelemetry/api/AbstractOpenTelemetryTest.java create mode 100644 api/all/src/testFixtures/java/io/opentelemetry/api/logs/AbstractDefaultLoggerTest.java create mode 100644 api/all/src/testFixtures/java/io/opentelemetry/api/metrics/AbstractDefaultMeterTest.java create mode 100644 api/all/src/testFixtures/java/io/opentelemetry/api/trace/AbstractDefaultTracerTest.java create mode 100644 api/incubator/src/main/java/io/opentelemetry/api/incubator/logs/ExtendedDefaultLogger.java create mode 100644 api/incubator/src/main/java/io/opentelemetry/api/incubator/logs/ExtendedDefaultLoggerProvider.java create mode 100644 api/incubator/src/main/java/io/opentelemetry/api/incubator/metrics/ExtendedDefaultMeter.java create mode 100644 api/incubator/src/main/java/io/opentelemetry/api/incubator/metrics/ExtendedDefaultMeterProvider.java create mode 100644 api/incubator/src/main/java/io/opentelemetry/api/incubator/trace/ExtendedDefaultTracer.java create mode 100644 api/incubator/src/main/java/io/opentelemetry/api/incubator/trace/ExtendedDefaultTracerBuilder.java create mode 100644 api/incubator/src/main/java/io/opentelemetry/api/incubator/trace/ExtendedDefaultTracerProvider.java create mode 100644 api/incubator/src/main/resources/META-INF/native-image/io.opentelemetry/opentelemetry-api/reflect-config.json create mode 100644 api/incubator/src/test/java/io/opentelemetry/api/incubator/ExtendedOpenTelemetryTest.java create mode 100644 api/incubator/src/test/java/io/opentelemetry/api/incubator/logs/ExtendedDefaultLoggerTest.java create mode 100644 api/incubator/src/test/java/io/opentelemetry/api/incubator/metrics/ExtendedDefaultMeterTest.java create mode 100644 api/incubator/src/test/java/io/opentelemetry/api/incubator/trace/ExtendedDefaultTracerTest.java create mode 100644 integration-tests/graal-incubating/build.gradle.kts create mode 100644 integration-tests/graal-incubating/src/test/java/io/opentelemetry/integrationtests/graal/IncubatingApiTests.java create mode 100644 integration-tests/graal/src/test/java/io/opentelemetry/integrationtests/graal/IncubatingNotFoundApiTests.java diff --git a/api/all/build.gradle.kts b/api/all/build.gradle.kts index 4998fd9ddd3..6ade72dfd88 100644 --- a/api/all/build.gradle.kts +++ b/api/all/build.gradle.kts @@ -1,6 +1,7 @@ plugins { id("otel.java-conventions") id("otel.publish-conventions") + id("java-test-fixtures") id("otel.jmh-conventions") id("otel.animalsniffer-conventions") @@ -17,6 +18,10 @@ dependencies { testImplementation("edu.berkeley.cs.jqf:jqf-fuzz") testImplementation("com.google.guava:guava-testlib") + testFixturesApi(project(":testing-internal")) + testFixturesApi("junit:junit") + testFixturesApi("org.assertj:assertj-core") + testFixturesApi("org.mockito:mockito-core") } tasks.test { diff --git a/api/all/src/main/java/io/opentelemetry/api/internal/IncubatingUtil.java b/api/all/src/main/java/io/opentelemetry/api/internal/IncubatingUtil.java new file mode 100644 index 00000000000..1ef82d373f2 --- /dev/null +++ b/api/all/src/main/java/io/opentelemetry/api/internal/IncubatingUtil.java @@ -0,0 +1,29 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.api.internal; + +import java.lang.reflect.Method; + +/** + * Incubating utilities. + * + *

      This class is internal and is hence not for public use. Its APIs are unstable and can change + * at any time. + */ +public class IncubatingUtil { + private IncubatingUtil() {} + + @SuppressWarnings("unchecked") + public static T incubatingApiIfAvailable(T stableApi, String incubatingClassName) { + try { + Class incubatingClass = Class.forName(incubatingClassName); + Method getInstance = incubatingClass.getDeclaredMethod("getNoop"); + return (T) getInstance.invoke(null); + } catch (Exception e) { + return stableApi; + } + } +} diff --git a/api/all/src/main/java/io/opentelemetry/api/logs/LoggerProvider.java b/api/all/src/main/java/io/opentelemetry/api/logs/LoggerProvider.java index d00cb310ffc..5bad7eeee51 100644 --- a/api/all/src/main/java/io/opentelemetry/api/logs/LoggerProvider.java +++ b/api/all/src/main/java/io/opentelemetry/api/logs/LoggerProvider.java @@ -5,6 +5,7 @@ package io.opentelemetry.api.logs; +import io.opentelemetry.api.internal.IncubatingUtil; import javax.annotation.concurrent.ThreadSafe; /** @@ -43,6 +44,8 @@ default Logger get(String instrumentationScopeName) { /** Returns a no-op {@link LoggerProvider} which provides Loggers which do not record or emit. */ static LoggerProvider noop() { - return DefaultLoggerProvider.getInstance(); + return IncubatingUtil.incubatingApiIfAvailable( + DefaultLoggerProvider.getInstance(), + "io.opentelemetry.api.incubator.logs.ExtendedDefaultLoggerProvider"); } } diff --git a/api/all/src/main/java/io/opentelemetry/api/metrics/DefaultMeterProvider.java b/api/all/src/main/java/io/opentelemetry/api/metrics/DefaultMeterProvider.java index 6d1a6de3d48..3ea78ec2d34 100644 --- a/api/all/src/main/java/io/opentelemetry/api/metrics/DefaultMeterProvider.java +++ b/api/all/src/main/java/io/opentelemetry/api/metrics/DefaultMeterProvider.java @@ -5,6 +5,8 @@ package io.opentelemetry.api.metrics; +import io.opentelemetry.api.internal.IncubatingUtil; + /** A {@link MeterProvider} that does nothing. */ class DefaultMeterProvider implements MeterProvider { @Override @@ -12,7 +14,10 @@ public MeterBuilder meterBuilder(String instrumentationScopeName) { return BUILDER_INSTANCE; } - private static final DefaultMeterProvider INSTANCE = new DefaultMeterProvider(); + private static final MeterProvider INSTANCE = + IncubatingUtil.incubatingApiIfAvailable( + new DefaultMeterProvider(), + "io.opentelemetry.api.incubator.metrics.ExtendedDefaultMeterProvider"); private static final MeterBuilder BUILDER_INSTANCE = new NoopMeterBuilder(); static MeterProvider getInstance() { diff --git a/api/all/src/main/java/io/opentelemetry/api/trace/DefaultTracerProvider.java b/api/all/src/main/java/io/opentelemetry/api/trace/DefaultTracerProvider.java index 97ddbe0c7b8..9bef6cf9928 100644 --- a/api/all/src/main/java/io/opentelemetry/api/trace/DefaultTracerProvider.java +++ b/api/all/src/main/java/io/opentelemetry/api/trace/DefaultTracerProvider.java @@ -5,12 +5,16 @@ package io.opentelemetry.api.trace; +import io.opentelemetry.api.internal.IncubatingUtil; import javax.annotation.concurrent.ThreadSafe; @ThreadSafe class DefaultTracerProvider implements TracerProvider { - private static final TracerProvider INSTANCE = new DefaultTracerProvider(); + private static final TracerProvider INSTANCE = + IncubatingUtil.incubatingApiIfAvailable( + new DefaultTracerProvider(), + "io.opentelemetry.api.incubator.trace.ExtendedDefaultTracerProvider"); static TracerProvider getInstance() { return INSTANCE; diff --git a/api/all/src/test/java/io/opentelemetry/api/OpenTelemetryTest.java b/api/all/src/test/java/io/opentelemetry/api/OpenTelemetryTest.java index 42a4cd31476..c3754a6df3b 100644 --- a/api/all/src/test/java/io/opentelemetry/api/OpenTelemetryTest.java +++ b/api/all/src/test/java/io/opentelemetry/api/OpenTelemetryTest.java @@ -5,100 +5,24 @@ package io.opentelemetry.api; -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatThrownBy; -import static org.mockito.Mockito.mock; - import io.opentelemetry.api.logs.LoggerProvider; import io.opentelemetry.api.metrics.MeterProvider; import io.opentelemetry.api.trace.TracerProvider; -import io.opentelemetry.context.propagation.ContextPropagators; -import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.Test; - -class OpenTelemetryTest { - - @BeforeAll - static void beforeClass() { - GlobalOpenTelemetry.resetForTest(); - } - - @AfterEach - void after() { - GlobalOpenTelemetry.resetForTest(); - } - - @Test - void testDefault() { - assertThat(OpenTelemetry.noop().getTracerProvider()).isSameAs(TracerProvider.noop()); - assertThat(OpenTelemetry.noop().getPropagators()).isSameAs(ContextPropagators.noop()); - assertThat(OpenTelemetry.noop().getMeterProvider()).isSameAs(MeterProvider.noop()); - assertThat(OpenTelemetry.noop().getLogsBridge()).isSameAs(LoggerProvider.noop()); - } - @Test - void propagating() { - ContextPropagators contextPropagators = mock(ContextPropagators.class); - OpenTelemetry openTelemetry = OpenTelemetry.propagating(contextPropagators); - - assertThat(openTelemetry.getTracerProvider()).isSameAs(TracerProvider.noop()); - assertThat(openTelemetry.getMeterProvider()).isSameAs(MeterProvider.noop()); - assertThat(openTelemetry.getLogsBridge()).isSameAs(LoggerProvider.noop()); - assertThat(openTelemetry.getPropagators()).isSameAs(contextPropagators); - } - - @Test - void testGlobalBeforeSet() { - assertThat(GlobalOpenTelemetry.getTracerProvider()).isSameAs(TracerProvider.noop()); - assertThat(GlobalOpenTelemetry.getTracerProvider()) - .isSameAs(GlobalOpenTelemetry.getTracerProvider()); - assertThat(GlobalOpenTelemetry.getPropagators()).isSameAs(GlobalOpenTelemetry.getPropagators()); - } - - @Test - void independentNonGlobalPropagators() { - ContextPropagators propagators1 = mock(ContextPropagators.class); - OpenTelemetry otel1 = OpenTelemetry.propagating(propagators1); - ContextPropagators propagators2 = mock(ContextPropagators.class); - OpenTelemetry otel2 = OpenTelemetry.propagating(propagators2); - - assertThat(otel1.getPropagators()).isSameAs(propagators1); - assertThat(otel2.getPropagators()).isSameAs(propagators2); - } - - @Test - void setThenSet() { - setOpenTelemetry(); - assertThatThrownBy(() -> GlobalOpenTelemetry.set(OpenTelemetry.noop())) - .isInstanceOf(IllegalStateException.class) - .hasMessageContaining("GlobalOpenTelemetry.set has already been called") - .hasStackTraceContaining("setOpenTelemetry"); - } - - @Test - void getThenSet() { - assertThat(getOpenTelemetry()).isInstanceOf(DefaultOpenTelemetry.class); - assertThatThrownBy(() -> GlobalOpenTelemetry.set(OpenTelemetry.noop())) - .isInstanceOf(IllegalStateException.class) - .hasMessageContaining("GlobalOpenTelemetry.set has already been called") - .hasStackTraceContaining("getOpenTelemetry"); - } +class OpenTelemetryTest extends AbstractOpenTelemetryTest { - @Test - void toString_noop_Valid() { - assertThat(OpenTelemetry.noop().toString()) - .isEqualTo( - "DefaultOpenTelemetry{" - + "propagators=DefaultContextPropagators{textMapPropagator=NoopTextMapPropagator}" - + "}"); + @Override + protected TracerProvider getTracerProvider() { + return TracerProvider.noop(); } - private static void setOpenTelemetry() { - GlobalOpenTelemetry.set(OpenTelemetry.noop()); + @Override + protected MeterProvider getMeterProvider() { + return MeterProvider.noop(); } - private static OpenTelemetry getOpenTelemetry() { - return GlobalOpenTelemetry.get(); + @Override + protected LoggerProvider getLoggerProvider() { + return LoggerProvider.noop(); } } diff --git a/api/all/src/test/java/io/opentelemetry/api/logs/DefaultLoggerProviderTest.java b/api/all/src/test/java/io/opentelemetry/api/logs/DefaultLoggerProviderTest.java deleted file mode 100644 index 81a8bec1f84..00000000000 --- a/api/all/src/test/java/io/opentelemetry/api/logs/DefaultLoggerProviderTest.java +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package io.opentelemetry.api.logs; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatCode; - -import org.junit.jupiter.api.Test; - -class DefaultLoggerProviderTest { - - @Test - void noopLoggerProvider_doesNotThrow() { - LoggerProvider provider = LoggerProvider.noop(); - - assertThat(provider).isSameAs(DefaultLoggerProvider.getInstance()); - assertThatCode(() -> provider.get("scope-name")).doesNotThrowAnyException(); - assertThatCode( - () -> - provider - .loggerBuilder("scope-name") - .setInstrumentationVersion("1.0") - .setSchemaUrl("http://schema.com") - .build()) - .doesNotThrowAnyException(); - - assertThatCode(() -> provider.loggerBuilder("scope-name").build().logRecordBuilder()) - .doesNotThrowAnyException(); - } -} diff --git a/api/all/src/test/java/io/opentelemetry/api/logs/DefaultLoggerTest.java b/api/all/src/test/java/io/opentelemetry/api/logs/DefaultLoggerTest.java index ffe68f37e95..436baee524c 100644 --- a/api/all/src/test/java/io/opentelemetry/api/logs/DefaultLoggerTest.java +++ b/api/all/src/test/java/io/opentelemetry/api/logs/DefaultLoggerTest.java @@ -5,36 +5,15 @@ package io.opentelemetry.api.logs; -import static org.assertj.core.api.Assertions.assertThatCode; +class DefaultLoggerTest extends AbstractDefaultLoggerTest { -import io.opentelemetry.api.common.AttributeKey; -import io.opentelemetry.api.common.Attributes; -import io.opentelemetry.api.common.Value; -import io.opentelemetry.context.Context; -import java.time.Instant; -import java.util.concurrent.TimeUnit; -import org.junit.jupiter.api.Test; - -class DefaultLoggerTest { + @Override + protected LoggerProvider getLoggerProvider() { + return DefaultLoggerProvider.getInstance(); + } - @Test - void buildAndEmit() { - assertThatCode( - () -> - DefaultLogger.getInstance() - .logRecordBuilder() - .setTimestamp(100, TimeUnit.SECONDS) - .setTimestamp(Instant.now()) - .setObservedTimestamp(100, TimeUnit.SECONDS) - .setObservedTimestamp(Instant.now()) - .setContext(Context.root()) - .setSeverity(Severity.DEBUG) - .setSeverityText("debug") - .setBody("body") - .setBody(Value.of("body")) - .setAttribute(AttributeKey.stringKey("key1"), "value1") - .setAllAttributes(Attributes.builder().put("key2", "value2").build()) - .emit()) - .doesNotThrowAnyException(); + @Override + protected Logger getLogger() { + return DefaultLogger.getInstance(); } } diff --git a/api/all/src/test/java/io/opentelemetry/api/metrics/DefaultMeterProviderTest.java b/api/all/src/test/java/io/opentelemetry/api/metrics/DefaultMeterProviderTest.java deleted file mode 100644 index 786d0a68a6e..00000000000 --- a/api/all/src/test/java/io/opentelemetry/api/metrics/DefaultMeterProviderTest.java +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package io.opentelemetry.api.metrics; - -import org.junit.jupiter.api.Test; - -public class DefaultMeterProviderTest { - @Test - void noopMeterProvider_getDoesNotThrow() { - MeterProvider provider = MeterProvider.noop(); - provider.get("user-instrumentation"); - } - - @Test - void noopMeterProvider_builderDoesNotThrow() { - MeterProvider provider = MeterProvider.noop(); - provider.meterBuilder("user-instrumentation").build(); - provider.meterBuilder("advanced-instrumetnation").setInstrumentationVersion("1.0").build(); - provider.meterBuilder("schema-instrumentation").setSchemaUrl("myschema://url").build(); - provider - .meterBuilder("schema-instrumentation") - .setInstrumentationVersion("1.0") - .setSchemaUrl("myschema://url") - .build(); - } -} diff --git a/api/all/src/test/java/io/opentelemetry/api/metrics/DefaultMeterTest.java b/api/all/src/test/java/io/opentelemetry/api/metrics/DefaultMeterTest.java index fd9884bdad7..1b012be1d55 100644 --- a/api/all/src/test/java/io/opentelemetry/api/metrics/DefaultMeterTest.java +++ b/api/all/src/test/java/io/opentelemetry/api/metrics/DefaultMeterTest.java @@ -5,199 +5,15 @@ package io.opentelemetry.api.metrics; -import static io.opentelemetry.api.common.AttributeKey.stringKey; +public class DefaultMeterTest extends AbstractDefaultMeterTest { -import io.opentelemetry.api.common.Attributes; -import io.opentelemetry.context.Context; -import io.opentelemetry.internal.testing.slf4j.SuppressLogger; -import org.junit.jupiter.api.Test; - -@SuppressLogger() -public class DefaultMeterTest { - private static final Meter METER = DefaultMeter.getInstance(); - - @Test - void noopLongCounter_doesNotThrow() { - LongCounter counter = - METER.counterBuilder("size").setDescription("The size I'm measuring").setUnit("1").build(); - counter.add(1); - counter.add(1, Attributes.of(stringKey("thing"), "car")); - counter.add(1, Attributes.of(stringKey("thing"), "car"), Context.current()); - } - - @Test - void noopDoubleCounter_doesNotThrow() { - DoubleCounter counter = - METER - .counterBuilder("size") - .ofDoubles() - .setDescription("The size I'm measuring") - .setUnit("1") - .build(); - counter.add(1.2); - counter.add(2.5, Attributes.of(stringKey("thing"), "car")); - counter.add(2.5, Attributes.of(stringKey("thing"), "car"), Context.current()); - } - - @Test - void noopLongUpDownCounter_doesNotThrow() { - LongUpDownCounter counter = - METER - .upDownCounterBuilder("size") - .setDescription("The size I'm measuring") - .setUnit("1") - .build(); - counter.add(-1); - counter.add(1, Attributes.of(stringKey("thing"), "car")); - counter.add(1, Attributes.of(stringKey("thing"), "car"), Context.current()); - } - - @Test - void noopDoubleUpDownCounter_doesNotThrow() { - DoubleUpDownCounter counter = - METER - .upDownCounterBuilder("size") - .ofDoubles() - .setDescription("The size I'm measuring") - .setUnit("1") - .build(); - counter.add(-2e4); - counter.add(1.0e-1, Attributes.of(stringKey("thing"), "car")); - counter.add(1.0e-1, Attributes.of(stringKey("thing"), "car"), Context.current()); - } - - @Test - void noopLongHistogram_doesNotThrow() { - LongHistogram histogram = - METER - .histogramBuilder("size") - .ofLongs() - .setDescription("The size I'm measuring") - .setUnit("1") - .build(); - histogram.record(-1); - histogram.record(1, Attributes.of(stringKey("thing"), "car")); - histogram.record(1, Attributes.of(stringKey("thing"), "car"), Context.current()); - } - - @Test - void noopDoubleHistogram_doesNotThrow() { - DoubleHistogram histogram = - METER - .histogramBuilder("size") - .setDescription("The size I'm measuring") - .setUnit("1") - .build(); - histogram.record(-2e4); - histogram.record(1.0e-1, Attributes.of(stringKey("thing"), "car")); - histogram.record(1.0e-1, Attributes.of(stringKey("thing"), "car"), Context.current()); - } - - @Test - void noopLongGauage_doesNotThrow() { - LongGauge gauge = - METER - .gaugeBuilder("temperature") - .ofLongs() - .setDescription("The current temperature") - .setUnit("C") - .build(); - gauge.set(1); - gauge.set(2, Attributes.of(stringKey("thing"), "engine")); - gauge.set(2, Attributes.of(stringKey("thing"), "engine"), Context.current()); - } - - @Test - void noopObservableLongGauage_doesNotThrow() { - METER - .gaugeBuilder("temperature") - .ofLongs() - .setDescription("The current temperature") - .setUnit("C") - .buildWithCallback( - m -> { - m.record(1); - m.record(2, Attributes.of(stringKey("thing"), "engine")); - }); - } - - @Test - void noopDoubleGauage_doesNotThrow() { - DoubleGauge gauge = - METER - .gaugeBuilder("temperature") - .setDescription("The current temperature") - .setUnit("C") - .build(); - gauge.set(1); - gauge.set(2, Attributes.of(stringKey("thing"), "engine")); - gauge.set(2, Attributes.of(stringKey("thing"), "engine"), Context.current()); - } - - @Test - void noopObservableDoubleGauage_doesNotThrow() { - METER - .gaugeBuilder("temperature") - .setDescription("The current temperature") - .setUnit("C") - .buildWithCallback( - m -> { - m.record(1.0e1); - m.record(-27.4, Attributes.of(stringKey("thing"), "engine")); - }); - } - - @Test - void noopObservableLongCounter_doesNotThrow() { - METER - .counterBuilder("temperature") - .setDescription("The current temperature") - .setUnit("C") - .buildWithCallback( - m -> { - m.record(1); - m.record(2, Attributes.of(stringKey("thing"), "engine")); - }); - } - - @Test - void noopObservableDoubleCounter_doesNotThrow() { - METER - .counterBuilder("temperature") - .ofDoubles() - .setDescription("The current temperature") - .setUnit("C") - .buildWithCallback( - m -> { - m.record(1.0e1); - m.record(-27.4, Attributes.of(stringKey("thing"), "engine")); - }); - } - - @Test - void noopObservableLongUpDownCounter_doesNotThrow() { - METER - .upDownCounterBuilder("temperature") - .setDescription("The current temperature") - .setUnit("C") - .buildWithCallback( - m -> { - m.record(1); - m.record(2, Attributes.of(stringKey("thing"), "engine")); - }); + @Override + protected Meter getMeter() { + return DefaultMeter.getInstance(); } - @Test - void noopObservableDoubleUpDownCounter_doesNotThrow() { - METER - .upDownCounterBuilder("temperature") - .ofDoubles() - .setDescription("The current temperature") - .setUnit("C") - .buildWithCallback( - m -> { - m.record(1.0e1); - m.record(-27.4, Attributes.of(stringKey("thing"), "engine")); - }); + @Override + protected MeterProvider getMeterProvider() { + return DefaultMeterProvider.getInstance(); } } diff --git a/api/all/src/test/java/io/opentelemetry/api/trace/DefaultTracerProviderTest.java b/api/all/src/test/java/io/opentelemetry/api/trace/DefaultTracerProviderTest.java deleted file mode 100644 index 72a98f29f59..00000000000 --- a/api/all/src/test/java/io/opentelemetry/api/trace/DefaultTracerProviderTest.java +++ /dev/null @@ -1,19 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package io.opentelemetry.api.trace; - -import static org.assertj.core.api.Assertions.assertThat; - -import org.junit.jupiter.api.Test; - -class DefaultTracerProviderTest { - - @Test - void returnsDefaultTracer() { - assertThat(TracerProvider.noop().get("test")).isInstanceOf(DefaultTracer.class); - assertThat(TracerProvider.noop().get("test", "1.0")).isInstanceOf(DefaultTracer.class); - } -} diff --git a/api/all/src/test/java/io/opentelemetry/api/trace/DefaultTracerTest.java b/api/all/src/test/java/io/opentelemetry/api/trace/DefaultTracerTest.java index dc364e96457..f0f577d9946 100644 --- a/api/all/src/test/java/io/opentelemetry/api/trace/DefaultTracerTest.java +++ b/api/all/src/test/java/io/opentelemetry/api/trace/DefaultTracerTest.java @@ -5,89 +5,15 @@ package io.opentelemetry.api.trace; -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatCode; +class DefaultTracerTest extends AbstractDefaultTracerTest { -import io.opentelemetry.api.common.Attributes; -import io.opentelemetry.context.Context; -import org.junit.jupiter.api.Test; - -/** Unit tests for {@link DefaultTracer}. */ -// Need to suppress warnings for MustBeClosed because Android 14 does not support -// try-with-resources. -@SuppressWarnings("MustBeClosedChecker") -class DefaultTracerTest { - private static final Tracer defaultTracer = DefaultTracer.getInstance(); - private static final String SPAN_NAME = "MySpanName"; - private static final SpanContext spanContext = - SpanContext.create( - "00000000000000000000000000000061", - "0000000000000061", - TraceFlags.getDefault(), - TraceState.getDefault()); - - @Test - void defaultSpanBuilderWithName() { - assertThat(defaultTracer.spanBuilder(SPAN_NAME).startSpan().getSpanContext().isValid()) - .isFalse(); - } - - @Test - void testSpanContextPropagationExplicitParent() { - Span span = - defaultTracer - .spanBuilder(SPAN_NAME) - .setParent(Context.root().with(Span.wrap(spanContext))) - .startSpan(); - assertThat(span.getSpanContext()).isSameAs(spanContext); - } - - @Test - void testSpanContextPropagation() { - Span parent = Span.wrap(spanContext); - - Span span = - defaultTracer.spanBuilder(SPAN_NAME).setParent(Context.root().with(parent)).startSpan(); - assertThat(span.getSpanContext()).isSameAs(spanContext); - } - - @Test - void noSpanContextMakesInvalidSpans() { - Span span = defaultTracer.spanBuilder(SPAN_NAME).startSpan(); - assertThat(span.getSpanContext()).isSameAs(SpanContext.getInvalid()); - } - - @Test - void testSpanContextPropagation_fromContext() { - Context context = Context.current().with(Span.wrap(spanContext)); - - Span span = defaultTracer.spanBuilder(SPAN_NAME).setParent(context).startSpan(); - assertThat(span.getSpanContext()).isSameAs(spanContext); - } - - @Test - void testSpanContextPropagation_fromContextAfterNoParent() { - Context context = Context.current().with(Span.wrap(spanContext)); - - Span span = defaultTracer.spanBuilder(SPAN_NAME).setNoParent().setParent(context).startSpan(); - assertThat(span.getSpanContext()).isSameAs(spanContext); - } - - @Test - void testSpanContextPropagation_fromContextThenNoParent() { - Context context = Context.current().with(Span.wrap(spanContext)); - - Span span = defaultTracer.spanBuilder(SPAN_NAME).setParent(context).setNoParent().startSpan(); - assertThat(span.getSpanContext()).isEqualTo(SpanContext.getInvalid()); + @Override + public Tracer getTracer() { + return DefaultTracer.getInstance(); } - @Test - void addLink() { - Span span = Span.fromContext(Context.root()); - assertThatCode(() -> span.addLink(null)).doesNotThrowAnyException(); - assertThatCode(() -> span.addLink(SpanContext.getInvalid())).doesNotThrowAnyException(); - assertThatCode(() -> span.addLink(null, null)).doesNotThrowAnyException(); - assertThatCode(() -> span.addLink(SpanContext.getInvalid(), Attributes.empty())) - .doesNotThrowAnyException(); + @Override + public TracerProvider getTracerProvider() { + return DefaultTracerProvider.getInstance(); } } diff --git a/api/all/src/test/java/io/opentelemetry/api/trace/SpanBuilderTest.java b/api/all/src/test/java/io/opentelemetry/api/trace/SpanBuilderTest.java deleted file mode 100644 index a7ed2dc27cb..00000000000 --- a/api/all/src/test/java/io/opentelemetry/api/trace/SpanBuilderTest.java +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package io.opentelemetry.api.trace; - -import static io.opentelemetry.api.common.AttributeKey.stringKey; -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatCode; - -import io.opentelemetry.api.common.AttributeKey; -import io.opentelemetry.api.common.Attributes; -import io.opentelemetry.context.Context; -import java.time.Instant; -import java.util.concurrent.TimeUnit; -import org.junit.jupiter.api.Test; - -/** Unit tests for {@link SpanBuilder}. */ -class SpanBuilderTest { - private final Tracer tracer = DefaultTracer.getInstance(); - - @Test - void doNotCrash_NoopImplementation() { - assertThatCode( - () -> { - SpanBuilder spanBuilder = tracer.spanBuilder(null); - spanBuilder.setSpanKind(null); - spanBuilder.setParent(null); - spanBuilder.setNoParent(); - spanBuilder.addLink(null); - spanBuilder.addLink(null, Attributes.empty()); - spanBuilder.addLink(SpanContext.getInvalid(), null); - spanBuilder.setAttribute((String) null, "foo"); - spanBuilder.setAttribute("foo", null); - spanBuilder.setAttribute(null, 0L); - spanBuilder.setAttribute(null, 0.0); - spanBuilder.setAttribute(null, false); - spanBuilder.setAttribute((AttributeKey) null, "foo"); - spanBuilder.setAttribute(stringKey(null), "foo"); - spanBuilder.setAttribute(stringKey(""), "foo"); - spanBuilder.setAttribute(stringKey("foo"), null); - spanBuilder.setStartTimestamp(-1, TimeUnit.MILLISECONDS); - spanBuilder.setStartTimestamp(1, null); - spanBuilder.setParent(Context.root().with(Span.wrap(null))); - spanBuilder.setParent(Context.root()); - spanBuilder.setNoParent(); - spanBuilder.addLink(Span.getInvalid().getSpanContext()); - spanBuilder.addLink(Span.getInvalid().getSpanContext(), Attributes.empty()); - spanBuilder.setAttribute("key", "value"); - spanBuilder.setAttribute("key", 12345L); - spanBuilder.setAttribute("key", .12345); - spanBuilder.setAttribute("key", true); - spanBuilder.setAttribute(stringKey("key"), "value"); - spanBuilder.setAllAttributes(Attributes.of(stringKey("key"), "value")); - spanBuilder.setAllAttributes(Attributes.empty()); - spanBuilder.setAllAttributes(null); - spanBuilder.setStartTimestamp(12345L, TimeUnit.NANOSECONDS); - spanBuilder.setStartTimestamp(Instant.EPOCH); - spanBuilder.setStartTimestamp(null); - assertThat(spanBuilder.startSpan().getSpanContext().isValid()).isFalse(); - }) - .doesNotThrowAnyException(); - } -} diff --git a/api/all/src/testFixtures/java/io/opentelemetry/api/AbstractOpenTelemetryTest.java b/api/all/src/testFixtures/java/io/opentelemetry/api/AbstractOpenTelemetryTest.java new file mode 100644 index 00000000000..6ba27d89760 --- /dev/null +++ b/api/all/src/testFixtures/java/io/opentelemetry/api/AbstractOpenTelemetryTest.java @@ -0,0 +1,114 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.api; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; + +import io.opentelemetry.api.logs.LoggerProvider; +import io.opentelemetry.api.metrics.MeterProvider; +import io.opentelemetry.api.trace.TracerProvider; +import io.opentelemetry.context.propagation.ContextPropagators; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; +import org.mockito.Mockito; + +/** Unit tests for {@link OpenTelemetry}. */ +public abstract class AbstractOpenTelemetryTest { + @BeforeAll + public static void beforeClass() { + GlobalOpenTelemetry.resetForTest(); + } + + private void setOpenTelemetry() { + GlobalOpenTelemetry.set(getOpenTelemetry()); + } + + private static OpenTelemetry getGlobalOpenTelemetry() { + return GlobalOpenTelemetry.get(); + } + + @AfterEach + public void after() { + GlobalOpenTelemetry.resetForTest(); + } + + @Test + void testDefault() { + assertThat(getOpenTelemetry().getTracerProvider()).isSameAs(getTracerProvider()); + assertThat(getOpenTelemetry().getPropagators()).isSameAs(ContextPropagators.noop()); + assertThat(getOpenTelemetry().getMeterProvider()).isSameAs(getMeterProvider()); + assertThat(getOpenTelemetry().getLogsBridge()).isSameAs(getLoggerProvider()); + } + + protected abstract TracerProvider getTracerProvider(); + + protected OpenTelemetry getOpenTelemetry() { + return OpenTelemetry.noop(); + } + + protected abstract MeterProvider getMeterProvider(); + + protected abstract LoggerProvider getLoggerProvider(); + + @Test + void propagating() { + ContextPropagators contextPropagators = Mockito.mock(ContextPropagators.class); + OpenTelemetry openTelemetry = OpenTelemetry.propagating(contextPropagators); + + assertThat(openTelemetry.getTracerProvider()).isSameAs(getTracerProvider()); + assertThat(openTelemetry.getMeterProvider()).isSameAs(getMeterProvider()); + assertThat(openTelemetry.getLogsBridge()).isSameAs(getLoggerProvider()); + assertThat(openTelemetry.getPropagators()).isSameAs(contextPropagators); + } + + @Test + void testGlobalBeforeSet() { + assertThat(GlobalOpenTelemetry.getTracerProvider()).isSameAs(getTracerProvider()); + assertThat(GlobalOpenTelemetry.getTracerProvider()) + .isSameAs(GlobalOpenTelemetry.getTracerProvider()); + assertThat(GlobalOpenTelemetry.getPropagators()).isSameAs(GlobalOpenTelemetry.getPropagators()); + } + + @Test + void independentNonGlobalPropagators() { + ContextPropagators propagators1 = Mockito.mock(ContextPropagators.class); + OpenTelemetry otel1 = OpenTelemetry.propagating(propagators1); + ContextPropagators propagators2 = Mockito.mock(ContextPropagators.class); + OpenTelemetry otel2 = OpenTelemetry.propagating(propagators2); + + assertThat(otel1.getPropagators()).isSameAs(propagators1); + assertThat(otel2.getPropagators()).isSameAs(propagators2); + } + + @Test + void setThenSet() { + setOpenTelemetry(); + assertThatThrownBy(() -> GlobalOpenTelemetry.set(getOpenTelemetry())) + .isInstanceOf(IllegalStateException.class) + .hasMessageContaining("GlobalOpenTelemetry.set has already been called") + .hasStackTraceContaining("setOpenTelemetry"); + } + + @Test + void getThenSet() { + assertThat(getGlobalOpenTelemetry()).isInstanceOf(DefaultOpenTelemetry.class); + assertThatThrownBy(() -> GlobalOpenTelemetry.set(getOpenTelemetry())) + .isInstanceOf(IllegalStateException.class) + .hasMessageContaining("GlobalOpenTelemetry.set has already been called") + .hasStackTraceContaining("getGlobalOpenTelemetry"); + } + + @Test + void toString_noop_Valid() { + assertThat(getOpenTelemetry().toString()) + .isEqualTo( + "DefaultOpenTelemetry{" + + "propagators=DefaultContextPropagators{textMapPropagator=NoopTextMapPropagator}" + + "}"); + } +} diff --git a/api/all/src/testFixtures/java/io/opentelemetry/api/logs/AbstractDefaultLoggerTest.java b/api/all/src/testFixtures/java/io/opentelemetry/api/logs/AbstractDefaultLoggerTest.java new file mode 100644 index 00000000000..88ecb74809a --- /dev/null +++ b/api/all/src/testFixtures/java/io/opentelemetry/api/logs/AbstractDefaultLoggerTest.java @@ -0,0 +1,65 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.api.logs; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatCode; + +import io.opentelemetry.api.common.AttributeKey; +import io.opentelemetry.api.common.Attributes; +import io.opentelemetry.api.common.Value; +import io.opentelemetry.context.Context; +import java.time.Instant; +import java.util.concurrent.TimeUnit; +import org.junit.jupiter.api.Test; + +/** Unit tests for {@link DefaultLogger}. */ +public abstract class AbstractDefaultLoggerTest { + + protected abstract LoggerProvider getLoggerProvider(); + + protected abstract Logger getLogger(); + + @Test + void noopLoggerProvider_doesNotThrow() { + LoggerProvider provider = LoggerProvider.noop(); + + assertThat(provider).isSameAs(getLoggerProvider()); + assertThatCode(() -> provider.get("scope-name")).doesNotThrowAnyException(); + assertThatCode( + () -> + provider + .loggerBuilder("scope-name") + .setInstrumentationVersion("1.0") + .setSchemaUrl("http://schema.com") + .build()) + .doesNotThrowAnyException(); + + assertThatCode(() -> provider.loggerBuilder("scope-name").build().logRecordBuilder()) + .doesNotThrowAnyException(); + } + + @Test + void buildAndEmit() { + assertThatCode( + () -> + getLogger() + .logRecordBuilder() + .setTimestamp(100, TimeUnit.SECONDS) + .setTimestamp(Instant.now()) + .setObservedTimestamp(100, TimeUnit.SECONDS) + .setObservedTimestamp(Instant.now()) + .setContext(Context.root()) + .setSeverity(Severity.DEBUG) + .setSeverityText("debug") + .setBody("body") + .setBody(Value.of("body")) + .setAttribute(AttributeKey.stringKey("key1"), "value1") + .setAllAttributes(Attributes.builder().put("key2", "value2").build()) + .emit()) + .doesNotThrowAnyException(); + } +} diff --git a/api/all/src/testFixtures/java/io/opentelemetry/api/metrics/AbstractDefaultMeterTest.java b/api/all/src/testFixtures/java/io/opentelemetry/api/metrics/AbstractDefaultMeterTest.java new file mode 100644 index 00000000000..b64c0929803 --- /dev/null +++ b/api/all/src/testFixtures/java/io/opentelemetry/api/metrics/AbstractDefaultMeterTest.java @@ -0,0 +1,251 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.api.metrics; + +import static io.opentelemetry.api.common.AttributeKey.stringKey; + +import io.opentelemetry.api.common.Attributes; +import io.opentelemetry.context.Context; +import io.opentelemetry.internal.testing.slf4j.SuppressLogger; +import org.junit.jupiter.api.Test; + +/** Unit tests for {@link DefaultMeter}. */ +@SuppressLogger() +public abstract class AbstractDefaultMeterTest { + private final Meter meter = getMeter(); + + protected abstract Meter getMeter(); + + protected abstract MeterProvider getMeterProvider(); + + @Test + void noopMeterProvider_getDoesNotThrow() { + MeterProvider provider = getMeterProvider(); + provider.get("user-instrumentation"); + } + + @Test + void noopMeterProvider_builderDoesNotThrow() { + MeterProvider provider = getMeterProvider(); + provider.meterBuilder("user-instrumentation").build(); + provider.meterBuilder("advanced-instrumetnation").setInstrumentationVersion("1.0").build(); + provider.meterBuilder("schema-instrumentation").setSchemaUrl("myschema://url").build(); + provider + .meterBuilder("schema-instrumentation") + .setInstrumentationVersion("1.0") + .setSchemaUrl("myschema://url") + .build(); + } + + @Test + void noopLongCounter_doesNotThrow() { + LongCounter counter = + meter.counterBuilder("size").setDescription("The size I'm measuring").setUnit("1").build(); + counter.add(1); + counter.add(1, Attributes.of(stringKey("thing"), "car")); + counter.add(1, Attributes.of(stringKey("thing"), "car"), Context.current()); + } + + @Test + void noopDoubleCounter_doesNotThrow() { + DoubleCounter counter = + meter + .counterBuilder("size") + .ofDoubles() + .setDescription("The size I'm measuring") + .setUnit("1") + .build(); + counter.add(1.2); + counter.add(2.5, Attributes.of(stringKey("thing"), "car")); + counter.add(2.5, Attributes.of(stringKey("thing"), "car"), Context.current()); + } + + @Test + void noopLongUpDownCounter_doesNotThrow() { + LongUpDownCounter counter = + meter + .upDownCounterBuilder("size") + .setDescription("The size I'm measuring") + .setUnit("1") + .build(); + counter.add(-1); + counter.add(1, Attributes.of(stringKey("thing"), "car")); + counter.add(1, Attributes.of(stringKey("thing"), "car"), Context.current()); + } + + @Test + void noopDoubleUpDownCounter_doesNotThrow() { + DoubleUpDownCounter counter = + meter + .upDownCounterBuilder("size") + .ofDoubles() + .setDescription("The size I'm measuring") + .setUnit("1") + .build(); + counter.add(-2e4); + counter.add(1.0e-1, Attributes.of(stringKey("thing"), "car")); + counter.add(1.0e-1, Attributes.of(stringKey("thing"), "car"), Context.current()); + } + + @Test + void noopLongHistogram_doesNotThrow() { + LongHistogram histogram = + meter + .histogramBuilder("size") + .ofLongs() + .setDescription("The size I'm measuring") + .setUnit("1") + .build(); + histogram.record(-1); + histogram.record(1, Attributes.of(stringKey("thing"), "car")); + histogram.record(1, Attributes.of(stringKey("thing"), "car"), Context.current()); + } + + @Test + void noopDoubleHistogram_doesNotThrow() { + DoubleHistogram histogram = + meter + .histogramBuilder("size") + .setDescription("The size I'm measuring") + .setUnit("1") + .build(); + histogram.record(-2e4); + histogram.record(1.0e-1, Attributes.of(stringKey("thing"), "car")); + histogram.record(1.0e-1, Attributes.of(stringKey("thing"), "car"), Context.current()); + } + + @Test + void noopLongGauage_doesNotThrow() { + LongGauge gauge = + meter + .gaugeBuilder("temperature") + .ofLongs() + .setDescription("The current temperature") + .setUnit("C") + .build(); + gauge.set(1); + gauge.set(2, Attributes.of(stringKey("thing"), "engine")); + gauge.set(2, Attributes.of(stringKey("thing"), "engine"), Context.current()); + + ObservableLongMeasurement measurement = + meter + .gaugeBuilder("temperature") + .ofLongs() + .setDescription("The current temperature") + .setUnit("C") + .buildObserver(); + measurement.record(1); + measurement.record(1, Attributes.of(stringKey("thing"), "engine")); + } + + @Test + void noopObservableLongGauage_doesNotThrow() { + meter + .gaugeBuilder("temperature") + .ofLongs() + .setDescription("The current temperature") + .setUnit("C") + .buildWithCallback( + m -> { + m.record(1); + m.record(2, Attributes.of(stringKey("thing"), "engine")); + }); + } + + @Test + void noopDoubleGauage_doesNotThrow() { + DoubleGauge gauge = + meter + .gaugeBuilder("temperature") + .setDescription("The current temperature") + .setUnit("C") + .build(); + gauge.set(1); + gauge.set(2, Attributes.of(stringKey("thing"), "engine")); + gauge.set(2, Attributes.of(stringKey("thing"), "engine"), Context.current()); + + ObservableDoubleMeasurement measurement = + meter + .gaugeBuilder("temperature") + .setDescription("The current temperature") + .setUnit("C") + .buildObserver(); + measurement.record(1.0); + measurement.record(1.0, Attributes.of(stringKey("thing"), "engine")); + } + + @Test + void noopObservableDoubleGauage_doesNotThrow() { + meter + .gaugeBuilder("temperature") + .setDescription("The current temperature") + .setUnit("C") + .buildWithCallback( + m -> { + m.record(1.0e1); + m.record(-27.4, Attributes.of(stringKey("thing"), "engine")); + }); + } + + @Test + void noopObservableLongCounter_doesNotThrow() { + meter + .counterBuilder("temperature") + .setDescription("The current temperature") + .setUnit("C") + .buildWithCallback( + m -> { + m.record(1); + m.record(2, Attributes.of(stringKey("thing"), "engine")); + }); + } + + @Test + void noopObservableDoubleCounter_doesNotThrow() { + meter + .counterBuilder("temperature") + .ofDoubles() + .setDescription("The current temperature") + .setUnit("C") + .buildWithCallback( + m -> { + m.record(1.0e1); + m.record(-27.4, Attributes.of(stringKey("thing"), "engine")); + }); + } + + @Test + void noopObservableLongUpDownCounter_doesNotThrow() { + meter + .upDownCounterBuilder("temperature") + .setDescription("The current temperature") + .setUnit("C") + .buildWithCallback( + m -> { + m.record(1); + m.record(2, Attributes.of(stringKey("thing"), "engine")); + }); + } + + @Test + void noopObservableDoubleUpDownCounter_doesNotThrow() { + meter + .upDownCounterBuilder("temperature") + .ofDoubles() + .setDescription("The current temperature") + .setUnit("C") + .buildWithCallback( + m -> { + m.record(1.0e1); + m.record(-27.4, Attributes.of(stringKey("thing"), "engine")); + }); + } + + @Test + void noopBatchCallback_doesNotThrow() { + meter.batchCallback(() -> {}, null); + } +} diff --git a/api/all/src/testFixtures/java/io/opentelemetry/api/trace/AbstractDefaultTracerTest.java b/api/all/src/testFixtures/java/io/opentelemetry/api/trace/AbstractDefaultTracerTest.java new file mode 100644 index 00000000000..1933e289d5b --- /dev/null +++ b/api/all/src/testFixtures/java/io/opentelemetry/api/trace/AbstractDefaultTracerTest.java @@ -0,0 +1,153 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.api.trace; + +import static io.opentelemetry.api.common.AttributeKey.stringKey; +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatCode; + +import io.opentelemetry.api.common.AttributeKey; +import io.opentelemetry.api.common.Attributes; +import io.opentelemetry.context.Context; +import java.time.Instant; +import java.util.concurrent.TimeUnit; +import org.junit.jupiter.api.Test; + +/** Unit tests for {@link DefaultTracer}. */ +// Need to suppress warnings for MustBeClosed because Android 14 does not support +// try-with-resources. +@SuppressWarnings("MustBeClosedChecker") +public abstract class AbstractDefaultTracerTest { + private final Tracer defaultTracer = getTracer(); + private static final String SPAN_NAME = "MySpanName"; + private static final SpanContext spanContext = + SpanContext.create( + "00000000000000000000000000000061", + "0000000000000061", + TraceFlags.getDefault(), + TraceState.getDefault()); + + public abstract Tracer getTracer(); + + public abstract TracerProvider getTracerProvider(); + + @Test + void returnsDefaultTracer() { + TracerProvider tracerProvider = getTracerProvider(); + Class want = defaultTracer.getClass(); + assertThat( + tracerProvider + .tracerBuilder("test") + .setSchemaUrl("schema") + .setInstrumentationVersion("1") + .build()) + .isInstanceOf(want); + assertThat(tracerProvider.get("test")).isInstanceOf(want); + assertThat(tracerProvider.get("test", "1.0")).isInstanceOf(want); + } + + @Test + void defaultSpanBuilderWithName() { + assertThat(defaultTracer.spanBuilder(SPAN_NAME).startSpan().getSpanContext().isValid()) + .isFalse(); + } + + @Test + void spanContextPropagationExplicitParent() { + assertThat( + defaultTracer + .spanBuilder(SPAN_NAME) + .setParent(Context.root().with(Span.wrap(spanContext))) + .startSpan() + .getSpanContext()) + .isSameAs(spanContext); + + SpanBuilder builder = defaultTracer.spanBuilder(SPAN_NAME); + assertThat(builder.setParent(null)).isSameAs(builder); + } + + @Test + void spanContextPropagation() { + Span parent = Span.wrap(spanContext); + + Span span = + defaultTracer.spanBuilder(SPAN_NAME).setParent(Context.root().with(parent)).startSpan(); + assertThat(span.getSpanContext()).isSameAs(spanContext); + } + + @Test + void noSpanContextMakesInvalidSpans() { + Span span = defaultTracer.spanBuilder(SPAN_NAME).startSpan(); + assertThat(span.getSpanContext()).isSameAs(SpanContext.getInvalid()); + } + + @Test + void spanContextPropagation_fromContext() { + Context context = Context.current().with(Span.wrap(spanContext)); + + Span span = defaultTracer.spanBuilder(SPAN_NAME).setParent(context).startSpan(); + assertThat(span.getSpanContext()).isSameAs(spanContext); + } + + @Test + void spanContextPropagation_fromContextAfterNoParent() { + Context context = Context.current().with(Span.wrap(spanContext)); + + Span span = defaultTracer.spanBuilder(SPAN_NAME).setNoParent().setParent(context).startSpan(); + assertThat(span.getSpanContext()).isSameAs(spanContext); + } + + @Test + void spanContextPropagation_fromContextThenNoParent() { + Context context = Context.current().with(Span.wrap(spanContext)); + + Span span = defaultTracer.spanBuilder(SPAN_NAME).setParent(context).setNoParent().startSpan(); + assertThat(span.getSpanContext()).isEqualTo(SpanContext.getInvalid()); + } + + @Test + void doNotCrash_NoopImplementation() { + assertThatCode( + () -> { + SpanBuilder spanBuilder = defaultTracer.spanBuilder(null); + spanBuilder.setSpanKind(null); + spanBuilder.setParent(null); + spanBuilder.setNoParent(); + spanBuilder.addLink(null); + spanBuilder.addLink(null, Attributes.empty()); + spanBuilder.addLink(SpanContext.getInvalid(), null); + spanBuilder.setAttribute((String) null, "foo"); + spanBuilder.setAttribute("foo", null); + spanBuilder.setAttribute(null, 0L); + spanBuilder.setAttribute(null, 0.0); + spanBuilder.setAttribute(null, false); + spanBuilder.setAttribute((AttributeKey) null, "foo"); + spanBuilder.setAttribute(stringKey(null), "foo"); + spanBuilder.setAttribute(stringKey(""), "foo"); + spanBuilder.setAttribute(stringKey("foo"), null); + spanBuilder.setStartTimestamp(-1, TimeUnit.MILLISECONDS); + spanBuilder.setStartTimestamp(1, null); + spanBuilder.setParent(Context.root().with(Span.wrap(null))); + spanBuilder.setParent(Context.root()); + spanBuilder.setNoParent(); + spanBuilder.addLink(Span.getInvalid().getSpanContext()); + spanBuilder.addLink(Span.getInvalid().getSpanContext(), Attributes.empty()); + spanBuilder.setAttribute("key", "value"); + spanBuilder.setAttribute("key", 12345L); + spanBuilder.setAttribute("key", .12345); + spanBuilder.setAttribute("key", true); + spanBuilder.setAttribute(stringKey("key"), "value"); + spanBuilder.setAllAttributes(Attributes.of(stringKey("key"), "value")); + spanBuilder.setAllAttributes(Attributes.empty()); + spanBuilder.setAllAttributes(null); + spanBuilder.setStartTimestamp(12345L, TimeUnit.NANOSECONDS); + spanBuilder.setStartTimestamp(Instant.EPOCH); + spanBuilder.setStartTimestamp(null); + assertThat(spanBuilder.startSpan().getSpanContext().isValid()).isFalse(); + }) + .doesNotThrowAnyException(); + } +} diff --git a/api/incubator/build.gradle.kts b/api/incubator/build.gradle.kts index 3dfa0e79a3c..b28295de6d0 100644 --- a/api/incubator/build.gradle.kts +++ b/api/incubator/build.gradle.kts @@ -15,6 +15,7 @@ dependencies { annotationProcessor("com.google.auto.value:auto-value") testImplementation(project(":sdk:testing")) + testImplementation(testFixtures(project(":api:all"))) testImplementation("io.opentelemetry.semconv:opentelemetry-semconv-incubating") diff --git a/api/incubator/src/main/java/io/opentelemetry/api/incubator/logs/ExtendedDefaultLogger.java b/api/incubator/src/main/java/io/opentelemetry/api/incubator/logs/ExtendedDefaultLogger.java new file mode 100644 index 00000000000..3e8dce08e74 --- /dev/null +++ b/api/incubator/src/main/java/io/opentelemetry/api/incubator/logs/ExtendedDefaultLogger.java @@ -0,0 +1,90 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.api.incubator.logs; + +import io.opentelemetry.api.common.AttributeKey; +import io.opentelemetry.api.common.Value; +import io.opentelemetry.api.logs.LogRecordBuilder; +import io.opentelemetry.api.logs.Logger; +import io.opentelemetry.api.logs.Severity; +import io.opentelemetry.context.Context; +import java.time.Instant; +import java.util.concurrent.TimeUnit; + +class ExtendedDefaultLogger implements ExtendedLogger { + + private static final Logger INSTANCE = new ExtendedDefaultLogger(); + private static final LogRecordBuilder NOOP_LOG_RECORD_BUILDER = new NoopLogRecordBuilder(); + + private ExtendedDefaultLogger() {} + + static Logger getNoop() { + return INSTANCE; + } + + @Override + public LogRecordBuilder logRecordBuilder() { + return NOOP_LOG_RECORD_BUILDER; + } + + private static final class NoopLogRecordBuilder implements ExtendedLogRecordBuilder { + + private NoopLogRecordBuilder() {} + + @Override + public LogRecordBuilder setTimestamp(long timestamp, TimeUnit unit) { + return this; + } + + @Override + public LogRecordBuilder setTimestamp(Instant instant) { + return this; + } + + @Override + public LogRecordBuilder setObservedTimestamp(long timestamp, TimeUnit unit) { + return this; + } + + @Override + public LogRecordBuilder setObservedTimestamp(Instant instant) { + return this; + } + + @Override + public LogRecordBuilder setContext(Context context) { + return this; + } + + @Override + public LogRecordBuilder setSeverity(Severity severity) { + return this; + } + + @Override + public LogRecordBuilder setSeverityText(String severityText) { + return this; + } + + @Override + public LogRecordBuilder setBody(String body) { + return this; + } + + @Override + public LogRecordBuilder setBody(Value body) { + return this; + } + + @Override + public LogRecordBuilder setAttribute(AttributeKey key, T value) { + return this; + } + + @Override + public void emit() {} + } +} diff --git a/api/incubator/src/main/java/io/opentelemetry/api/incubator/logs/ExtendedDefaultLoggerProvider.java b/api/incubator/src/main/java/io/opentelemetry/api/incubator/logs/ExtendedDefaultLoggerProvider.java new file mode 100644 index 00000000000..6cf93296689 --- /dev/null +++ b/api/incubator/src/main/java/io/opentelemetry/api/incubator/logs/ExtendedDefaultLoggerProvider.java @@ -0,0 +1,45 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.api.incubator.logs; + +import io.opentelemetry.api.logs.Logger; +import io.opentelemetry.api.logs.LoggerBuilder; +import io.opentelemetry.api.logs.LoggerProvider; + +public class ExtendedDefaultLoggerProvider implements LoggerProvider { + + private static final LoggerProvider INSTANCE = new ExtendedDefaultLoggerProvider(); + private static final LoggerBuilder NOOP_BUILDER = new NoopLoggerBuilder(); + + private ExtendedDefaultLoggerProvider() {} + + public static LoggerProvider getNoop() { + return INSTANCE; + } + + @Override + public LoggerBuilder loggerBuilder(String instrumentationScopeName) { + return NOOP_BUILDER; + } + + private static class NoopLoggerBuilder implements LoggerBuilder { + + @Override + public LoggerBuilder setSchemaUrl(String schemaUrl) { + return this; + } + + @Override + public LoggerBuilder setInstrumentationVersion(String instrumentationVersion) { + return this; + } + + @Override + public Logger build() { + return ExtendedDefaultLogger.getNoop(); + } + } +} diff --git a/api/incubator/src/main/java/io/opentelemetry/api/incubator/metrics/ExtendedDefaultMeter.java b/api/incubator/src/main/java/io/opentelemetry/api/incubator/metrics/ExtendedDefaultMeter.java new file mode 100644 index 00000000000..de1ec1fdefc --- /dev/null +++ b/api/incubator/src/main/java/io/opentelemetry/api/incubator/metrics/ExtendedDefaultMeter.java @@ -0,0 +1,454 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.api.incubator.metrics; + +import io.opentelemetry.api.common.Attributes; +import io.opentelemetry.api.metrics.BatchCallback; +import io.opentelemetry.api.metrics.DoubleCounter; +import io.opentelemetry.api.metrics.DoubleCounterBuilder; +import io.opentelemetry.api.metrics.DoubleGauge; +import io.opentelemetry.api.metrics.DoubleGaugeBuilder; +import io.opentelemetry.api.metrics.DoubleHistogram; +import io.opentelemetry.api.metrics.DoubleHistogramBuilder; +import io.opentelemetry.api.metrics.DoubleUpDownCounter; +import io.opentelemetry.api.metrics.DoubleUpDownCounterBuilder; +import io.opentelemetry.api.metrics.LongCounter; +import io.opentelemetry.api.metrics.LongCounterBuilder; +import io.opentelemetry.api.metrics.LongGauge; +import io.opentelemetry.api.metrics.LongGaugeBuilder; +import io.opentelemetry.api.metrics.LongHistogram; +import io.opentelemetry.api.metrics.LongHistogramBuilder; +import io.opentelemetry.api.metrics.LongUpDownCounter; +import io.opentelemetry.api.metrics.LongUpDownCounterBuilder; +import io.opentelemetry.api.metrics.Meter; +import io.opentelemetry.api.metrics.ObservableDoubleCounter; +import io.opentelemetry.api.metrics.ObservableDoubleGauge; +import io.opentelemetry.api.metrics.ObservableDoubleMeasurement; +import io.opentelemetry.api.metrics.ObservableDoubleUpDownCounter; +import io.opentelemetry.api.metrics.ObservableLongCounter; +import io.opentelemetry.api.metrics.ObservableLongGauge; +import io.opentelemetry.api.metrics.ObservableLongMeasurement; +import io.opentelemetry.api.metrics.ObservableLongUpDownCounter; +import io.opentelemetry.api.metrics.ObservableMeasurement; +import io.opentelemetry.context.Context; +import java.util.function.Consumer; +import javax.annotation.concurrent.ThreadSafe; + +/** + * No-op implementation of {@link Meter}. + * + *

      This implementation should induce as close to zero overhead as possible. + */ +@ThreadSafe +class ExtendedDefaultMeter implements Meter { + + private static final Meter INSTANCE = new ExtendedDefaultMeter(); + + private static final LongCounterBuilder NOOP_LONG_COUNTER_BUILDER = new NoopLongCounterBuilder(); + private static final LongUpDownCounterBuilder NOOP_LONG_UP_DOWN_COUNTER_BUILDER = + new NoopLongUpDownCounterBuilder(); + private static final DoubleHistogramBuilder NOOP_DOUBLE_HISTOGRAM_BUILDER = + new NoopDoubleHistogramBuilder(); + private static final DoubleGaugeBuilder NOOP_DOUBLE_GAUGE_BUILDER = new NoopDoubleGaugeBuilder(); + private static final BatchCallback NOOP_BATCH_CALLBACK = new BatchCallback() {}; + private static final ObservableDoubleMeasurement NOOP_OBSERVABLE_DOUBLE_MEASUREMENT = + new NoopObservableDoubleMeasurement(); + private static final ObservableLongMeasurement NOOP_OBSERVABLE_LONG_MEASUREMENT = + new NoopObservableLongMeasurement(); + + static Meter getNoop() { + return INSTANCE; + } + + @Override + public LongCounterBuilder counterBuilder(String name) { + return NOOP_LONG_COUNTER_BUILDER; + } + + @Override + public LongUpDownCounterBuilder upDownCounterBuilder(String name) { + return NOOP_LONG_UP_DOWN_COUNTER_BUILDER; + } + + @Override + public DoubleHistogramBuilder histogramBuilder(String name) { + return NOOP_DOUBLE_HISTOGRAM_BUILDER; + } + + @Override + public DoubleGaugeBuilder gaugeBuilder(String name) { + return NOOP_DOUBLE_GAUGE_BUILDER; + } + + @Override + public BatchCallback batchCallback( + Runnable callback, + ObservableMeasurement observableMeasurement, + ObservableMeasurement... additionalMeasurements) { + return NOOP_BATCH_CALLBACK; + } + + private ExtendedDefaultMeter() {} + + private static class NoopLongCounter implements ExtendedLongCounter { + @Override + public void add(long value, Attributes attributes, Context context) {} + + @Override + public void add(long value, Attributes attributes) {} + + @Override + public void add(long value) {} + } + + private static class NoopDoubleCounter implements ExtendedDoubleCounter { + @Override + public void add(double value, Attributes attributes, Context context) {} + + @Override + public void add(double value, Attributes attributes) {} + + @Override + public void add(double value) {} + } + + private static class NoopLongCounterBuilder implements ExtendedLongCounterBuilder { + private static final LongCounter NOOP_COUNTER = new NoopLongCounter(); + private static final ObservableLongCounter NOOP_OBSERVABLE_COUNTER = + new ObservableLongCounter() {}; + private static final DoubleCounterBuilder NOOP_DOUBLE_COUNTER_BUILDER = + new NoopDoubleCounterBuilder(); + + @Override + public LongCounterBuilder setDescription(String description) { + return this; + } + + @Override + public LongCounterBuilder setUnit(String unit) { + return this; + } + + @Override + public DoubleCounterBuilder ofDoubles() { + return NOOP_DOUBLE_COUNTER_BUILDER; + } + + @Override + public LongCounter build() { + return NOOP_COUNTER; + } + + @Override + public ObservableLongCounter buildWithCallback(Consumer callback) { + return NOOP_OBSERVABLE_COUNTER; + } + + @Override + public ObservableLongMeasurement buildObserver() { + return NOOP_OBSERVABLE_LONG_MEASUREMENT; + } + } + + private static class NoopDoubleCounterBuilder implements ExtendedDoubleCounterBuilder { + private static final DoubleCounter NOOP_COUNTER = new NoopDoubleCounter(); + private static final ObservableDoubleCounter NOOP_OBSERVABLE_COUNTER = + new ObservableDoubleCounter() {}; + + @Override + public DoubleCounterBuilder setDescription(String description) { + return this; + } + + @Override + public DoubleCounterBuilder setUnit(String unit) { + return this; + } + + @Override + public DoubleCounter build() { + return NOOP_COUNTER; + } + + @Override + public ObservableDoubleCounter buildWithCallback( + Consumer callback) { + return NOOP_OBSERVABLE_COUNTER; + } + + @Override + public ObservableDoubleMeasurement buildObserver() { + return NOOP_OBSERVABLE_DOUBLE_MEASUREMENT; + } + } + + private static class NoopLongUpDownCounter implements ExtendedLongUpDownCounter { + @Override + public void add(long value, Attributes attributes, Context context) {} + + @Override + public void add(long value, Attributes attributes) {} + + @Override + public void add(long value) {} + } + + private static class NoopDoubleUpDownCounter implements ExtendedDoubleUpDownCounter { + @Override + public void add(double value, Attributes attributes, Context context) {} + + @Override + public void add(double value, Attributes attributes) {} + + @Override + public void add(double value) {} + } + + private static class NoopLongUpDownCounterBuilder implements ExtendedLongUpDownCounterBuilder { + private static final LongUpDownCounter NOOP_UP_DOWN_COUNTER = new NoopLongUpDownCounter() {}; + private static final ObservableLongUpDownCounter NOOP_OBSERVABLE_UP_DOWN_COUNTER = + new ObservableLongUpDownCounter() {}; + private static final DoubleUpDownCounterBuilder NOOP_DOUBLE_UP_DOWN_COUNTER_BUILDER = + new NoopDoubleUpDownCounterBuilder(); + + @Override + public LongUpDownCounterBuilder setDescription(String description) { + return this; + } + + @Override + public LongUpDownCounterBuilder setUnit(String unit) { + return this; + } + + @Override + public DoubleUpDownCounterBuilder ofDoubles() { + return NOOP_DOUBLE_UP_DOWN_COUNTER_BUILDER; + } + + @Override + public LongUpDownCounter build() { + return NOOP_UP_DOWN_COUNTER; + } + + @Override + public ObservableLongUpDownCounter buildWithCallback( + Consumer callback) { + return NOOP_OBSERVABLE_UP_DOWN_COUNTER; + } + + @Override + public ObservableLongMeasurement buildObserver() { + return NOOP_OBSERVABLE_LONG_MEASUREMENT; + } + } + + private static class NoopDoubleUpDownCounterBuilder + implements ExtendedDoubleUpDownCounterBuilder { + private static final DoubleUpDownCounter NOOP_UP_DOWN_COUNTER = + new NoopDoubleUpDownCounter() {}; + private static final ObservableDoubleUpDownCounter NOOP_OBSERVABLE_UP_DOWN_COUNTER = + new ObservableDoubleUpDownCounter() {}; + + @Override + public DoubleUpDownCounterBuilder setDescription(String description) { + return this; + } + + @Override + public DoubleUpDownCounterBuilder setUnit(String unit) { + return this; + } + + @Override + public DoubleUpDownCounter build() { + return NOOP_UP_DOWN_COUNTER; + } + + @Override + public ObservableDoubleUpDownCounter buildWithCallback( + Consumer callback) { + return NOOP_OBSERVABLE_UP_DOWN_COUNTER; + } + + @Override + public ObservableDoubleMeasurement buildObserver() { + return NOOP_OBSERVABLE_DOUBLE_MEASUREMENT; + } + } + + private static class NoopDoubleHistogram implements ExtendedDoubleHistogram { + @Override + public void record(double value, Attributes attributes, Context context) {} + + @Override + public void record(double value, Attributes attributes) {} + + @Override + public void record(double value) {} + } + + private static class NoopLongHistogram implements ExtendedLongHistogram { + @Override + public void record(long value, Attributes attributes, Context context) {} + + @Override + public void record(long value, Attributes attributes) {} + + @Override + public void record(long value) {} + } + + private static class NoopDoubleHistogramBuilder implements ExtendedDoubleHistogramBuilder { + private static final DoubleHistogram NOOP = new NoopDoubleHistogram(); + private static final LongHistogramBuilder NOOP_LONG_HISTOGRAM_BUILDER = + new NoopLongHistogramBuilder(); + + @Override + public DoubleHistogramBuilder setDescription(String description) { + return this; + } + + @Override + public DoubleHistogramBuilder setUnit(String unit) { + return this; + } + + @Override + public LongHistogramBuilder ofLongs() { + return NOOP_LONG_HISTOGRAM_BUILDER; + } + + @Override + public DoubleHistogram build() { + return NOOP; + } + } + + private static class NoopLongHistogramBuilder implements ExtendedLongHistogramBuilder { + private static final LongHistogram NOOP = new NoopLongHistogram(); + + @Override + public LongHistogramBuilder setDescription(String description) { + return this; + } + + @Override + public LongHistogramBuilder setUnit(String unit) { + return this; + } + + @Override + public LongHistogram build() { + return NOOP; + } + } + + private static class NoopDoubleGaugeBuilder implements ExtendedDoubleGaugeBuilder { + private static final ObservableDoubleGauge NOOP_OBSERVABLE_GAUGE = + new ObservableDoubleGauge() {}; + private static final LongGaugeBuilder NOOP_LONG_GAUGE_BUILDER = new NoopLongGaugeBuilder(); + private static final NoopDoubleGauge NOOP_GAUGE = new NoopDoubleGauge(); + + @Override + public DoubleGaugeBuilder setDescription(String description) { + return this; + } + + @Override + public DoubleGaugeBuilder setUnit(String unit) { + return this; + } + + @Override + public LongGaugeBuilder ofLongs() { + return NOOP_LONG_GAUGE_BUILDER; + } + + @Override + public ObservableDoubleGauge buildWithCallback(Consumer callback) { + return NOOP_OBSERVABLE_GAUGE; + } + + @Override + public ObservableDoubleMeasurement buildObserver() { + return NOOP_OBSERVABLE_DOUBLE_MEASUREMENT; + } + + @Override + public DoubleGauge build() { + return NOOP_GAUGE; + } + } + + private static class NoopDoubleGauge implements ExtendedDoubleGauge { + @Override + public void set(double value) {} + + @Override + public void set(double value, Attributes attributes) {} + + @Override + public void set(double value, Attributes attributes, Context context) {} + } + + private static class NoopLongGaugeBuilder implements ExtendedLongGaugeBuilder { + private static final ObservableLongGauge NOOP_OBSERVABLE_GAUGE = new ObservableLongGauge() {}; + private static final NoopLongGauge NOOP_GAUGE = new NoopLongGauge(); + + @Override + public LongGaugeBuilder setDescription(String description) { + return this; + } + + @Override + public LongGaugeBuilder setUnit(String unit) { + return this; + } + + @Override + public ObservableLongGauge buildWithCallback(Consumer callback) { + return NOOP_OBSERVABLE_GAUGE; + } + + @Override + public ObservableLongMeasurement buildObserver() { + return NOOP_OBSERVABLE_LONG_MEASUREMENT; + } + + @Override + public LongGauge build() { + return NOOP_GAUGE; + } + } + + private static class NoopLongGauge implements ExtendedLongGauge { + @Override + public void set(long value) {} + + @Override + public void set(long value, Attributes attributes) {} + + @Override + public void set(long value, Attributes attributes, Context context) {} + } + + private static class NoopObservableDoubleMeasurement implements ObservableDoubleMeasurement { + @Override + public void record(double value) {} + + @Override + public void record(double value, Attributes attributes) {} + } + + private static class NoopObservableLongMeasurement implements ObservableLongMeasurement { + @Override + public void record(long value) {} + + @Override + public void record(long value, Attributes attributes) {} + } +} diff --git a/api/incubator/src/main/java/io/opentelemetry/api/incubator/metrics/ExtendedDefaultMeterProvider.java b/api/incubator/src/main/java/io/opentelemetry/api/incubator/metrics/ExtendedDefaultMeterProvider.java new file mode 100644 index 00000000000..3eeca2081f8 --- /dev/null +++ b/api/incubator/src/main/java/io/opentelemetry/api/incubator/metrics/ExtendedDefaultMeterProvider.java @@ -0,0 +1,45 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.api.incubator.metrics; + +import io.opentelemetry.api.metrics.Meter; +import io.opentelemetry.api.metrics.MeterBuilder; +import io.opentelemetry.api.metrics.MeterProvider; + +/** A {@link MeterProvider} that does nothing. */ +public class ExtendedDefaultMeterProvider implements MeterProvider { + @Override + public MeterBuilder meterBuilder(String instrumentationScopeName) { + return BUILDER_INSTANCE; + } + + private static final ExtendedDefaultMeterProvider INSTANCE = new ExtendedDefaultMeterProvider(); + private static final MeterBuilder BUILDER_INSTANCE = new NoopMeterBuilder(); + + public static MeterProvider getNoop() { + return INSTANCE; + } + + private ExtendedDefaultMeterProvider() {} + + private static class NoopMeterBuilder implements MeterBuilder { + + @Override + public MeterBuilder setSchemaUrl(String schemaUrl) { + return this; + } + + @Override + public MeterBuilder setInstrumentationVersion(String instrumentationScopeVersion) { + return this; + } + + @Override + public Meter build() { + return ExtendedDefaultMeter.getNoop(); + } + } +} diff --git a/api/incubator/src/main/java/io/opentelemetry/api/incubator/trace/ExtendedDefaultTracer.java b/api/incubator/src/main/java/io/opentelemetry/api/incubator/trace/ExtendedDefaultTracer.java new file mode 100644 index 00000000000..948f17e9996 --- /dev/null +++ b/api/incubator/src/main/java/io/opentelemetry/api/incubator/trace/ExtendedDefaultTracer.java @@ -0,0 +1,156 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.api.incubator.trace; + +import io.opentelemetry.api.common.AttributeKey; +import io.opentelemetry.api.common.Attributes; +import io.opentelemetry.api.incubator.propagation.ExtendedContextPropagators; +import io.opentelemetry.api.internal.ApiUsageLogger; +import io.opentelemetry.api.trace.Span; +import io.opentelemetry.api.trace.SpanBuilder; +import io.opentelemetry.api.trace.SpanContext; +import io.opentelemetry.api.trace.SpanKind; +import io.opentelemetry.api.trace.Tracer; +import io.opentelemetry.context.Context; +import io.opentelemetry.context.propagation.ContextPropagators; +import java.util.Map; +import java.util.concurrent.TimeUnit; +import java.util.function.BiConsumer; +import javax.annotation.Nullable; +import javax.annotation.concurrent.ThreadSafe; + +/** No-op implementation of {@link ExtendedTracer}. */ +@ThreadSafe +final class ExtendedDefaultTracer implements ExtendedTracer { + + private static final Tracer INSTANCE = new ExtendedDefaultTracer(); + + static Tracer getNoop() { + return INSTANCE; + } + + @Override + public SpanBuilder spanBuilder(String spanName) { + return NoopSpanBuilder.create(); + } + + private ExtendedDefaultTracer() {} + + // Noop implementation of Span.Builder. + private static final class NoopSpanBuilder implements ExtendedSpanBuilder { + static NoopSpanBuilder create() { + return new NoopSpanBuilder(); + } + + @Nullable private SpanContext spanContext; + + @Override + public Span startSpan() { + if (spanContext == null) { + spanContext = Span.current().getSpanContext(); + } + + return Span.wrap(spanContext); + } + + @Override + public NoopSpanBuilder setParent(Context context) { + if (context == null) { + ApiUsageLogger.log("context is null"); + return this; + } + spanContext = Span.fromContext(context).getSpanContext(); + return this; + } + + @Override + public NoopSpanBuilder setParentFrom( + ContextPropagators propagators, Map carrier) { + setParent(ExtendedContextPropagators.extractTextMapPropagationContext(carrier, propagators)); + return this; + } + + @Override + public NoopSpanBuilder setNoParent() { + spanContext = SpanContext.getInvalid(); + return this; + } + + @Override + public NoopSpanBuilder addLink(SpanContext spanContext) { + return this; + } + + @Override + public NoopSpanBuilder addLink(SpanContext spanContext, Attributes attributes) { + return this; + } + + @Override + public NoopSpanBuilder setAttribute(String key, String value) { + return this; + } + + @Override + public NoopSpanBuilder setAttribute(String key, long value) { + return this; + } + + @Override + public NoopSpanBuilder setAttribute(String key, double value) { + return this; + } + + @Override + public NoopSpanBuilder setAttribute(String key, boolean value) { + return this; + } + + @Override + public NoopSpanBuilder setAttribute(AttributeKey key, T value) { + return this; + } + + @Override + public NoopSpanBuilder setAllAttributes(Attributes attributes) { + return this; + } + + @Override + public NoopSpanBuilder setSpanKind(SpanKind spanKind) { + return this; + } + + @Override + public NoopSpanBuilder setStartTimestamp(long startTimestamp, TimeUnit unit) { + return this; + } + + @Override + public T startAndCall(SpanCallable spanCallable) throws E { + return spanCallable.callInSpan(); + } + + @Override + public T startAndCall( + SpanCallable spanCallable, BiConsumer handleException) throws E { + return spanCallable.callInSpan(); + } + + @Override + public void startAndRun(SpanRunnable runnable) throws E { + runnable.runInSpan(); + } + + @Override + public void startAndRun( + SpanRunnable runnable, BiConsumer handleException) throws E { + runnable.runInSpan(); + } + + private NoopSpanBuilder() {} + } +} diff --git a/api/incubator/src/main/java/io/opentelemetry/api/incubator/trace/ExtendedDefaultTracerBuilder.java b/api/incubator/src/main/java/io/opentelemetry/api/incubator/trace/ExtendedDefaultTracerBuilder.java new file mode 100644 index 00000000000..20469674ae5 --- /dev/null +++ b/api/incubator/src/main/java/io/opentelemetry/api/incubator/trace/ExtendedDefaultTracerBuilder.java @@ -0,0 +1,32 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.api.incubator.trace; + +import io.opentelemetry.api.trace.Tracer; +import io.opentelemetry.api.trace.TracerBuilder; + +final class ExtendedDefaultTracerBuilder implements TracerBuilder { + private static final ExtendedDefaultTracerBuilder INSTANCE = new ExtendedDefaultTracerBuilder(); + + static TracerBuilder getInstance() { + return INSTANCE; + } + + @Override + public TracerBuilder setSchemaUrl(String schemaUrl) { + return this; + } + + @Override + public TracerBuilder setInstrumentationVersion(String instrumentationScopeVersion) { + return this; + } + + @Override + public Tracer build() { + return ExtendedDefaultTracer.getNoop(); + } +} diff --git a/api/incubator/src/main/java/io/opentelemetry/api/incubator/trace/ExtendedDefaultTracerProvider.java b/api/incubator/src/main/java/io/opentelemetry/api/incubator/trace/ExtendedDefaultTracerProvider.java new file mode 100644 index 00000000000..b7bd2133ad7 --- /dev/null +++ b/api/incubator/src/main/java/io/opentelemetry/api/incubator/trace/ExtendedDefaultTracerProvider.java @@ -0,0 +1,38 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.api.incubator.trace; + +import io.opentelemetry.api.trace.Tracer; +import io.opentelemetry.api.trace.TracerBuilder; +import io.opentelemetry.api.trace.TracerProvider; +import javax.annotation.concurrent.ThreadSafe; + +@ThreadSafe +public class ExtendedDefaultTracerProvider implements TracerProvider { + + private static final TracerProvider INSTANCE = new ExtendedDefaultTracerProvider(); + + public static TracerProvider getNoop() { + return INSTANCE; + } + + @Override + public Tracer get(String instrumentationScopeName) { + return ExtendedDefaultTracer.getNoop(); + } + + @Override + public Tracer get(String instrumentationScopeName, String instrumentationScopeVersion) { + return ExtendedDefaultTracer.getNoop(); + } + + @Override + public TracerBuilder tracerBuilder(String instrumentationScopeName) { + return ExtendedDefaultTracerBuilder.getInstance(); + } + + private ExtendedDefaultTracerProvider() {} +} diff --git a/api/incubator/src/main/resources/META-INF/native-image/io.opentelemetry/opentelemetry-api/reflect-config.json b/api/incubator/src/main/resources/META-INF/native-image/io.opentelemetry/opentelemetry-api/reflect-config.json new file mode 100644 index 00000000000..d9abd56c422 --- /dev/null +++ b/api/incubator/src/main/resources/META-INF/native-image/io.opentelemetry/opentelemetry-api/reflect-config.json @@ -0,0 +1,38 @@ +[ + { + "methods": [ + { + "name": "getNoop", + "parameterTypes": [] + } + ], + "name": "io.opentelemetry.api.incubator.logs.ExtendedDefaultLoggerProvider" + }, + { + "methods": [ + { + "name": "getNoop", + "parameterTypes": [] + } + ], + "name": "io.opentelemetry.api.incubator.metrics.ExtendedDefaultMeterProvider" + }, + { + "methods": [ + { + "name": "getNoop", + "parameterTypes": [] + } + ], + "name": "io.opentelemetry.api.incubator.trace.ExtendedDefaultTracerProvider" + }, + { + "methods": [ + { + "name": "getNoop", + "parameterTypes": [] + } + ], + "name": "io.opentelemetry.api.incubator.ExtendedDefaultOpenTelemetry" + } +] diff --git a/api/incubator/src/test/java/io/opentelemetry/api/incubator/ExtendedOpenTelemetryTest.java b/api/incubator/src/test/java/io/opentelemetry/api/incubator/ExtendedOpenTelemetryTest.java new file mode 100644 index 00000000000..b33c29c8194 --- /dev/null +++ b/api/incubator/src/test/java/io/opentelemetry/api/incubator/ExtendedOpenTelemetryTest.java @@ -0,0 +1,53 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.api.incubator; + +import static org.assertj.core.api.Assertions.assertThat; + +import io.opentelemetry.api.AbstractOpenTelemetryTest; +import io.opentelemetry.api.OpenTelemetry; +import io.opentelemetry.api.incubator.logs.ExtendedDefaultLoggerProvider; +import io.opentelemetry.api.incubator.logs.ExtendedLogger; +import io.opentelemetry.api.incubator.metrics.ExtendedDefaultMeterProvider; +import io.opentelemetry.api.incubator.metrics.ExtendedLongCounterBuilder; +import io.opentelemetry.api.incubator.trace.ExtendedDefaultTracerProvider; +import io.opentelemetry.api.incubator.trace.ExtendedTracer; +import io.opentelemetry.api.logs.LoggerProvider; +import io.opentelemetry.api.metrics.MeterProvider; +import io.opentelemetry.api.trace.TracerProvider; +import io.opentelemetry.context.propagation.ContextPropagators; +import org.junit.jupiter.api.Test; + +class ExtendedOpenTelemetryTest extends AbstractOpenTelemetryTest { + + @Override + protected TracerProvider getTracerProvider() { + return ExtendedDefaultTracerProvider.getNoop(); + } + + @Override + protected MeterProvider getMeterProvider() { + return ExtendedDefaultMeterProvider.getNoop(); + } + + @Override + protected LoggerProvider getLoggerProvider() { + return ExtendedDefaultLoggerProvider.getNoop(); + } + + @Test + void incubatingApiIsLoaded() { + assertIsExtended(OpenTelemetry.noop()); + assertIsExtended(OpenTelemetry.propagating(ContextPropagators.noop())); + } + + private static void assertIsExtended(OpenTelemetry openTelemetry) { + assertThat(openTelemetry.getMeter("test").counterBuilder("test")) + .isInstanceOf(ExtendedLongCounterBuilder.class); + assertThat(openTelemetry.getLogsBridge().get("test")).isInstanceOf(ExtendedLogger.class); + assertThat(openTelemetry.getTracer("test")).isInstanceOf(ExtendedTracer.class); + } +} diff --git a/api/incubator/src/test/java/io/opentelemetry/api/incubator/logs/ExtendedDefaultLoggerTest.java b/api/incubator/src/test/java/io/opentelemetry/api/incubator/logs/ExtendedDefaultLoggerTest.java new file mode 100644 index 00000000000..e558b53fcf1 --- /dev/null +++ b/api/incubator/src/test/java/io/opentelemetry/api/incubator/logs/ExtendedDefaultLoggerTest.java @@ -0,0 +1,37 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.api.incubator.logs; + +import static org.assertj.core.api.Assertions.assertThat; + +import io.opentelemetry.api.common.Value; +import io.opentelemetry.api.logs.AbstractDefaultLoggerTest; +import io.opentelemetry.api.logs.Logger; +import io.opentelemetry.api.logs.LoggerProvider; +import org.junit.jupiter.api.Test; + +class ExtendedDefaultLoggerTest extends AbstractDefaultLoggerTest { + + @Override + protected LoggerProvider getLoggerProvider() { + return ExtendedDefaultLoggerProvider.getNoop(); + } + + @Override + protected Logger getLogger() { + return ExtendedDefaultLogger.getNoop(); + } + + @Test + void incubatingApiIsLoaded() { + Logger logger = LoggerProvider.noop().get("test"); + + assertThat(logger).isInstanceOf(ExtendedLogger.class); + ExtendedLogRecordBuilder builder = (ExtendedLogRecordBuilder) logger.logRecordBuilder(); + assertThat(builder).isInstanceOf(ExtendedLogRecordBuilder.class); + assertThat(builder.setBody(Value.of(0))).isSameAs(builder); + } +} diff --git a/api/incubator/src/test/java/io/opentelemetry/api/incubator/metrics/ExtendedDefaultMeterTest.java b/api/incubator/src/test/java/io/opentelemetry/api/incubator/metrics/ExtendedDefaultMeterTest.java new file mode 100644 index 00000000000..3d342a33661 --- /dev/null +++ b/api/incubator/src/test/java/io/opentelemetry/api/incubator/metrics/ExtendedDefaultMeterTest.java @@ -0,0 +1,70 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.api.incubator.metrics; + +import static org.assertj.core.api.Assertions.assertThat; + +import io.opentelemetry.api.OpenTelemetry; +import io.opentelemetry.api.metrics.AbstractDefaultMeterTest; +import io.opentelemetry.api.metrics.Meter; +import io.opentelemetry.api.metrics.MeterProvider; +import org.assertj.core.api.Assertions; +import org.junit.jupiter.api.Test; + +class ExtendedDefaultMeterTest extends AbstractDefaultMeterTest { + + @Override + protected Meter getMeter() { + return ExtendedDefaultMeter.getNoop(); + } + + @Override + protected MeterProvider getMeterProvider() { + return ExtendedDefaultMeterProvider.getNoop(); + } + + @Test + public void incubatingApiIsLoaded() { + Meter meter = MeterProvider.noop().get("test"); + assertThat(meter).isSameAs(OpenTelemetry.noop().getMeter("test")); + + Assertions.assertThat(meter.gaugeBuilder("test").ofLongs()) + .isInstanceOf(ExtendedLongGaugeBuilder.class); + Assertions.assertThat(meter.gaugeBuilder("test").ofLongs().build()) + .isInstanceOf(ExtendedLongGauge.class); + Assertions.assertThat(meter.gaugeBuilder("test")) + .isInstanceOf(ExtendedDoubleGaugeBuilder.class); + Assertions.assertThat(meter.gaugeBuilder("test").build()) + .isInstanceOf(ExtendedDoubleGauge.class); + + Assertions.assertThat(meter.histogramBuilder("test").ofLongs()) + .isInstanceOf(ExtendedLongHistogramBuilder.class); + Assertions.assertThat(meter.histogramBuilder("test").ofLongs().build()) + .isInstanceOf(ExtendedLongHistogram.class); + Assertions.assertThat(meter.histogramBuilder("test")) + .isInstanceOf(ExtendedDoubleHistogramBuilder.class); + Assertions.assertThat(meter.histogramBuilder("test").build()) + .isInstanceOf(ExtendedDoubleHistogram.class); + + Assertions.assertThat(meter.counterBuilder("test")) + .isInstanceOf(ExtendedLongCounterBuilder.class); + Assertions.assertThat(meter.counterBuilder("test").build()) + .isInstanceOf(ExtendedLongCounter.class); + Assertions.assertThat(meter.counterBuilder("test").ofDoubles()) + .isInstanceOf(ExtendedDoubleCounterBuilder.class); + Assertions.assertThat(meter.counterBuilder("test").ofDoubles().build()) + .isInstanceOf(ExtendedDoubleCounter.class); + + Assertions.assertThat(meter.upDownCounterBuilder("test")) + .isInstanceOf(ExtendedLongUpDownCounterBuilder.class); + Assertions.assertThat(meter.upDownCounterBuilder("test").build()) + .isInstanceOf(ExtendedLongUpDownCounter.class); + Assertions.assertThat(meter.upDownCounterBuilder("test").ofDoubles()) + .isInstanceOf(ExtendedDoubleUpDownCounterBuilder.class); + Assertions.assertThat(meter.upDownCounterBuilder("test").ofDoubles().build()) + .isInstanceOf(ExtendedDoubleUpDownCounter.class); + } +} diff --git a/api/incubator/src/test/java/io/opentelemetry/api/incubator/trace/ExtendedDefaultTracerTest.java b/api/incubator/src/test/java/io/opentelemetry/api/incubator/trace/ExtendedDefaultTracerTest.java new file mode 100644 index 00000000000..1550796d42d --- /dev/null +++ b/api/incubator/src/test/java/io/opentelemetry/api/incubator/trace/ExtendedDefaultTracerTest.java @@ -0,0 +1,65 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.api.incubator.trace; + +import static org.assertj.core.api.Assertions.assertThat; + +import io.opentelemetry.api.OpenTelemetry; +import io.opentelemetry.api.trace.AbstractDefaultTracerTest; +import io.opentelemetry.api.trace.Tracer; +import io.opentelemetry.api.trace.TracerProvider; +import org.junit.jupiter.api.Test; +import org.mockito.Mockito; + +class ExtendedDefaultTracerTest extends AbstractDefaultTracerTest { + + @Override + public Tracer getTracer() { + return ExtendedDefaultTracer.getNoop(); + } + + @Override + public TracerProvider getTracerProvider() { + return ExtendedDefaultTracerProvider.getNoop(); + } + + @Test + public void incubatingApiIsLoaded() { + Tracer tracer = TracerProvider.noop().get("test"); + assertThat(tracer).isSameAs(OpenTelemetry.noop().getTracer("test")); + + assertThat(tracer).isInstanceOf(ExtendedTracer.class); + assertThat(tracer.spanBuilder("test")).isInstanceOf(ExtendedSpanBuilder.class); + } + + @SuppressWarnings("unchecked") + @Test + public void incubatingApi() { + ExtendedSpanBuilder spanBuilder = + (ExtendedSpanBuilder) ExtendedDefaultTracer.getNoop().spanBuilder("test"); + assertThat(spanBuilder.setParentFrom(null, null)).isSameAs(spanBuilder); + + SpanRunnable spanRunnable = Mockito.mock(SpanRunnable.class); + + spanBuilder.startAndRun(spanRunnable); + Mockito.verify(spanRunnable).runInSpan(); + Mockito.reset(spanRunnable); + + spanBuilder.startAndRun(spanRunnable, null); + Mockito.verify(spanRunnable).runInSpan(); + Mockito.reset(spanRunnable); + + SpanCallable spanCallable = Mockito.mock(SpanCallable.class); + + spanBuilder.startAndCall(spanCallable); + Mockito.verify(spanCallable).callInSpan(); + Mockito.reset(spanCallable); + + spanBuilder.startAndCall(spanCallable, null); + Mockito.verify(spanCallable).callInSpan(); + Mockito.reset(spanCallable); + } +} diff --git a/integration-tests/graal-incubating/build.gradle.kts b/integration-tests/graal-incubating/build.gradle.kts new file mode 100644 index 00000000000..d050e01dee8 --- /dev/null +++ b/integration-tests/graal-incubating/build.gradle.kts @@ -0,0 +1,48 @@ +plugins { + id("otel.java-conventions") + id("org.graalvm.buildtools.native") +} + +description = "OpenTelemetry Graal Integration Tests (Incubating)" +otelJava.moduleName.set("io.opentelemetry.graal.integration.tests.incubating") + +sourceSets { + main { + // We need to ensure that we have the shadowed classes on the classpath, without this + // we will get the <:sdk:trace-shaded-deps> classes only, without the shadowed ones + val traceShadedDeps = project(":sdk:trace-shaded-deps") + output.dir(traceShadedDeps.file("build/extracted/shadow"), "builtBy" to ":sdk:trace-shaded-deps:extractShadowJar") + } +} + +dependencies { + implementation(project(":sdk:all")) + implementation(project(":sdk:trace-shaded-deps")) + implementation(project(":exporters:otlp:all")) + implementation(project(":api:incubator")) +} + +// org.graalvm.buildtools.native pluging requires java 11+ as of version 0.9.26 +// https://github.com/graalvm/native-build-tools/blob/master/docs/src/docs/asciidoc/index.adoc +tasks { + withType().configureEach { + sourceCompatibility = "11" + targetCompatibility = "11" + options.release.set(11) + } + withType().configureEach { + val testJavaVersion: String? by project + enabled = !testJavaVersion.equals("8") + } +} + +graalvmNative { + binaries { + named("test") { + // Required as of junit 5.10.0: https://junit.org/junit5/docs/5.10.0/release-notes/#deprecations-and-breaking-changes + buildArgs.add("--initialize-at-build-time=org.junit.platform.launcher.core.LauncherConfig") + buildArgs.add("--initialize-at-build-time=org.junit.jupiter.engine.config.InstantiatingConfigurationParameterConverter") + } + } + toolchainDetection.set(false) +} diff --git a/integration-tests/graal-incubating/src/test/java/io/opentelemetry/integrationtests/graal/IncubatingApiTests.java b/integration-tests/graal-incubating/src/test/java/io/opentelemetry/integrationtests/graal/IncubatingApiTests.java new file mode 100644 index 00000000000..8d705419452 --- /dev/null +++ b/integration-tests/graal-incubating/src/test/java/io/opentelemetry/integrationtests/graal/IncubatingApiTests.java @@ -0,0 +1,26 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.integrationtests.graal; + +import static org.assertj.core.api.Assertions.assertThat; + +import io.opentelemetry.api.incubator.logs.ExtendedLogger; +import io.opentelemetry.api.incubator.metrics.ExtendedLongCounterBuilder; +import io.opentelemetry.api.incubator.trace.ExtendedTracer; +import io.opentelemetry.api.logs.LoggerProvider; +import io.opentelemetry.api.metrics.MeterProvider; +import io.opentelemetry.api.trace.TracerProvider; +import org.junit.jupiter.api.Test; + +class IncubatingApiTests { + @Test + void incubatingApiIsLoadedViaReflection() { + assertThat(LoggerProvider.noop().get("test")).isInstanceOf(ExtendedLogger.class); + assertThat(TracerProvider.noop().get("test")).isInstanceOf(ExtendedTracer.class); + assertThat(MeterProvider.noop().get("test").counterBuilder("test")) + .isInstanceOf(ExtendedLongCounterBuilder.class); + } +} diff --git a/integration-tests/graal/src/test/java/io/opentelemetry/integrationtests/graal/IncubatingNotFoundApiTests.java b/integration-tests/graal/src/test/java/io/opentelemetry/integrationtests/graal/IncubatingNotFoundApiTests.java new file mode 100644 index 00000000000..ba2ba02a2c3 --- /dev/null +++ b/integration-tests/graal/src/test/java/io/opentelemetry/integrationtests/graal/IncubatingNotFoundApiTests.java @@ -0,0 +1,26 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.integrationtests.graal; + +import static org.assertj.core.api.Assertions.assertThat; + +import io.opentelemetry.api.logs.Logger; +import io.opentelemetry.api.logs.LoggerProvider; +import io.opentelemetry.api.metrics.LongCounterBuilder; +import io.opentelemetry.api.metrics.MeterProvider; +import io.opentelemetry.api.trace.Tracer; +import io.opentelemetry.api.trace.TracerProvider; +import org.junit.jupiter.api.Test; + +class IncubatingNotFoundApiTests { + @Test + void incubatingApiIsNotFoundViaReflection() { + assertThat(LoggerProvider.noop().get("test")).isInstanceOf(Logger.class); + assertThat(TracerProvider.noop().get("test")).isInstanceOf(Tracer.class); + assertThat(MeterProvider.noop().get("test").counterBuilder("test")) + .isInstanceOf(LongCounterBuilder.class); + } +} diff --git a/settings.gradle.kts b/settings.gradle.kts index 1ad4058a096..4bf7ca86538 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -48,6 +48,7 @@ include(":integration-tests") include(":integration-tests:otlp") include(":integration-tests:tracecontext") include(":integration-tests:graal") +include(":integration-tests:graal-incubating") include(":opencensus-shim") include(":opentracing-shim") include(":perf-harness") From fbdb90621bb145da3535d5de571f4a4ad265606f Mon Sep 17 00:00:00 2001 From: jack-berg <34418638+jack-berg@users.noreply.github.com> Date: Fri, 6 Sep 2024 10:04:55 -0500 Subject: [PATCH 553/901] Prepare 1.42.0 (#6688) --- CHANGELOG.md | 52 +++++++++++++++++++ .../io/opentelemetry/api/common/KeyValue.java | 1 + .../io/opentelemetry/api/common/Value.java | 1 + .../opentelemetry/api/common/ValueType.java | 2 + .../api/logs/LogRecordBuilder.java | 6 ++- .../sdk/logs/data/LogRecordData.java | 6 ++- .../testing/assertj/LogRecordDataAssert.java | 26 +++++++++- .../sdk/testing/logs/TestLogRecordData.java | 11 +++- 8 files changed, 101 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index eb95a202958..52e7a80906d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,58 @@ ## Unreleased +### API + +* BREAKING: Stabilize log support for AnyValue bodies. Rename `AnyValue` to `Value`, promote + from `opentelemetry-api-incubator` to `opentelemetry-api`, change package + from `io.opentelemetry.api.incubator.logs` to `io.opentelemetry.api.common`. + ([#6591](https://github.com/open-telemetry/opentelemetry-java/pull/6591)) +* Noop implementations detect when `opentelemetry-api-incubator` is present and return extended noop + implementations. + ([#6617](https://github.com/open-telemetry/opentelemetry-java/pull/6617))% + +### SDK + +#### Traces + +* Added experimental support for SpanProcessor OnEnding callback + ([#6367](https://github.com/open-telemetry/opentelemetry-java/pull/6367)) +* Remove final modifier from SdkTracer.tracerEnabled + ([#6687](https://github.com/open-telemetry/opentelemetry-java/pull/6687)) + +#### Exporters + +* Suppress zipkin exporter instrumentation + ([#6552](https://github.com/open-telemetry/opentelemetry-java/pull/6552)) +* OTLP exporters return status code exceptions via CompletableResultCode in GrpcExporter and + HttpExporter. + ([#6645](https://github.com/open-telemetry/opentelemetry-java/pull/6645)) +* Align GrpcSender contract with HttpSender + ([#6658](https://github.com/open-telemetry/opentelemetry-java/pull/6658)) + +#### Extensions + +* Add autoconfigure support for ns and us durations + ([#6654](https://github.com/open-telemetry/opentelemetry-java/pull/6654)) +* Add declarative configuration ComponentProvider support for resources + ([#6625](https://github.com/open-telemetry/opentelemetry-java/pull/6625)) +* Add declarative configuration ComponentProvider support for processors + ([#6623](https://github.com/open-telemetry/opentelemetry-java/pull/6623)) +* Add declarative configuration ComponentProvider support for samplers + ([#6494](https://github.com/open-telemetry/opentelemetry-java/pull/6494)) +* Add declarative configuration ComponentProvider support for propagators + ([#6624](https://github.com/open-telemetry/opentelemetry-java/pull/6624)) +* Add declarative configuration missing pieces + ([#6677](https://github.com/open-telemetry/opentelemetry-java/pull/6677)) +* Change jaeger remote sampler autoconfigure property from `pollingInterval` to `pollingIntervalMs` + to match spec. + ([#6672](https://github.com/open-telemetry/opentelemetry-java/pull/6672)) + +#### Testing + +* Add asserts for log record body fields + ([#6509](https://github.com/open-telemetry/opentelemetry-java/pull/6509)) + ## Version 1.41.0 (2024-08-09) ### API diff --git a/api/all/src/main/java/io/opentelemetry/api/common/KeyValue.java b/api/all/src/main/java/io/opentelemetry/api/common/KeyValue.java index 341b9d1227a..e5286015e91 100644 --- a/api/all/src/main/java/io/opentelemetry/api/common/KeyValue.java +++ b/api/all/src/main/java/io/opentelemetry/api/common/KeyValue.java @@ -9,6 +9,7 @@ * Key-value pair of {@link String} key and {@link Value} value. * * @see Value#of(KeyValue...) + * @since 1.42.0 */ public interface KeyValue { diff --git a/api/all/src/main/java/io/opentelemetry/api/common/Value.java b/api/all/src/main/java/io/opentelemetry/api/common/Value.java index 68da725010b..a29be801e27 100644 --- a/api/all/src/main/java/io/opentelemetry/api/common/Value.java +++ b/api/all/src/main/java/io/opentelemetry/api/common/Value.java @@ -32,6 +32,7 @@ * io.opentelemetry.api.logs.LogRecordBuilder#setBody(Value)}. * * @param the type. See {@link #getValue()} for description of types. + * @since 1.42.0 */ public interface Value { diff --git a/api/all/src/main/java/io/opentelemetry/api/common/ValueType.java b/api/all/src/main/java/io/opentelemetry/api/common/ValueType.java index 99980280d2c..d7a60722a55 100644 --- a/api/all/src/main/java/io/opentelemetry/api/common/ValueType.java +++ b/api/all/src/main/java/io/opentelemetry/api/common/ValueType.java @@ -9,6 +9,8 @@ * AnyValue type options, mirroring AnyValue#value * options. + * + * @since 1.42.0 */ public enum ValueType { STRING, diff --git a/api/all/src/main/java/io/opentelemetry/api/logs/LogRecordBuilder.java b/api/all/src/main/java/io/opentelemetry/api/logs/LogRecordBuilder.java index 392796065d9..2166ab2b6b8 100644 --- a/api/all/src/main/java/io/opentelemetry/api/logs/LogRecordBuilder.java +++ b/api/all/src/main/java/io/opentelemetry/api/logs/LogRecordBuilder.java @@ -74,7 +74,11 @@ public interface LogRecordBuilder { */ LogRecordBuilder setBody(String body); - /** Set the body {@link Value}. */ + /** + * Set the body {@link Value}. + * + * @since 1.42.0 + */ default LogRecordBuilder setBody(Value body) { setBody(body.asString()); return this; diff --git a/sdk/logs/src/main/java/io/opentelemetry/sdk/logs/data/LogRecordData.java b/sdk/logs/src/main/java/io/opentelemetry/sdk/logs/data/LogRecordData.java index 6a896e48530..f21b175f52f 100644 --- a/sdk/logs/src/main/java/io/opentelemetry/sdk/logs/data/LogRecordData.java +++ b/sdk/logs/src/main/java/io/opentelemetry/sdk/logs/data/LogRecordData.java @@ -59,7 +59,11 @@ public interface LogRecordData { @Deprecated Body getBody(); - /** Returns the {@link Value} representation of the log body, of null if unset. */ + /** + * Returns the {@link Value} representation of the log body, of null if unset. + * + * @since 1.42.0 + */ @Nullable @SuppressWarnings("deprecation") // Default impl uses deprecated code for backwards compatibility default Value getBodyValue() { diff --git a/sdk/testing/src/main/java/io/opentelemetry/sdk/testing/assertj/LogRecordDataAssert.java b/sdk/testing/src/main/java/io/opentelemetry/sdk/testing/assertj/LogRecordDataAssert.java index b717ecedad9..e2256dcbbef 100644 --- a/sdk/testing/src/main/java/io/opentelemetry/sdk/testing/assertj/LogRecordDataAssert.java +++ b/sdk/testing/src/main/java/io/opentelemetry/sdk/testing/assertj/LogRecordDataAssert.java @@ -160,7 +160,11 @@ public LogRecordDataAssert hasBody(String body) { return hasBody(Value.of(body)); } - /** Asserts the log has the given body. */ + /** + * Asserts the log has the given body. + * + * @since 1.42.0 + */ public LogRecordDataAssert hasBody(@Nullable Value body) { isNotNull(); if (!Objects.equals(actual.getBodyValue(), body)) { @@ -177,6 +181,8 @@ public LogRecordDataAssert hasBody(@Nullable Value body) { /** * Asserts the log has a body of type {@link ValueType#KEY_VALUE_LIST}, containing a field with * the given {@code key} and String {@code value}. + * + * @since 1.42.0 */ public LogRecordDataAssert hasBodyField(String key, String value) { return hasBodyField(key, Value.of(value)); @@ -185,6 +191,8 @@ public LogRecordDataAssert hasBodyField(String key, String value) { /** * Asserts the log has a body of type {@link ValueType#KEY_VALUE_LIST}, containing a field with * the given {@code key} and long {@code value}. + * + * @since 1.42.0 */ public LogRecordDataAssert hasBodyField(String key, long value) { return hasBodyField(key, Value.of(value)); @@ -193,6 +201,8 @@ public LogRecordDataAssert hasBodyField(String key, long value) { /** * Asserts the log has a body of type {@link ValueType#KEY_VALUE_LIST}, containing a field with * the given {@code key} and double {@code value}. + * + * @since 1.42.0 */ public LogRecordDataAssert hasBodyField(String key, double value) { return hasBodyField(key, Value.of(value)); @@ -201,6 +211,8 @@ public LogRecordDataAssert hasBodyField(String key, double value) { /** * Asserts the log has a body of type {@link ValueType#KEY_VALUE_LIST}, containing a field with * the given {@code key} and boolean {@code value}. + * + * @since 1.42.0 */ public LogRecordDataAssert hasBodyField(String key, boolean value) { return hasBodyField(key, Value.of(value)); @@ -209,6 +221,8 @@ public LogRecordDataAssert hasBodyField(String key, boolean value) { /** * Asserts the log has a body of type {@link ValueType#KEY_VALUE_LIST}, containing a field with * the given {@code key} and list of String {@code value}s. + * + * @since 1.42.0 */ public LogRecordDataAssert hasBodyField(String key, String... value) { List> values = new ArrayList<>(value.length); @@ -221,6 +235,8 @@ public LogRecordDataAssert hasBodyField(String key, String... value) { /** * Asserts the log has a body of type {@link ValueType#KEY_VALUE_LIST}, containing a field with * the given {@code key} and list of long {@code value}s. + * + * @since 1.42.0 */ public LogRecordDataAssert hasBodyField(String key, long... value) { List> values = new ArrayList<>(value.length); @@ -233,6 +249,8 @@ public LogRecordDataAssert hasBodyField(String key, long... value) { /** * Asserts the log has a body of type {@link ValueType#KEY_VALUE_LIST}, containing a field with * the given {@code key} and list of double {@code value}s. + * + * @since 1.42.0 */ public LogRecordDataAssert hasBodyField(String key, double... value) { List> values = new ArrayList<>(value.length); @@ -245,6 +263,8 @@ public LogRecordDataAssert hasBodyField(String key, double... value) { /** * Asserts the log has a body of type {@link ValueType#KEY_VALUE_LIST}, containing a field with * the given {@code key} and list of boolean {@code value}s. + * + * @since 1.42.0 */ public LogRecordDataAssert hasBodyField(String key, boolean... value) { List> values = new ArrayList<>(value.length); @@ -257,6 +277,8 @@ public LogRecordDataAssert hasBodyField(String key, boolean... value) { /** * Asserts the log has a body of type {@link ValueType#KEY_VALUE_LIST}, containing a field with * the given {@code key} and {@code value}. + * + * @since 1.42.0 */ @SuppressWarnings({"unchecked"}) public LogRecordDataAssert hasBodyField(String key, Value value) { @@ -275,6 +297,8 @@ public LogRecordDataAssert hasBodyField(String key, Value value) { /** * Asserts the log has a body of type {@link ValueType#KEY_VALUE_LIST}, containing a field with * the given attribute {@code key} and {@code value}. + * + * @since 1.42.0 */ @SuppressWarnings({"unchecked"}) public LogRecordDataAssert hasBodyField(AttributeKey key, T value) { diff --git a/sdk/testing/src/main/java/io/opentelemetry/sdk/testing/logs/TestLogRecordData.java b/sdk/testing/src/main/java/io/opentelemetry/sdk/testing/logs/TestLogRecordData.java index efb2fee37ca..ec2e37294f4 100644 --- a/sdk/testing/src/main/java/io/opentelemetry/sdk/testing/logs/TestLogRecordData.java +++ b/sdk/testing/src/main/java/io/opentelemetry/sdk/testing/logs/TestLogRecordData.java @@ -51,6 +51,11 @@ public io.opentelemetry.sdk.logs.data.Body getBody() { : io.opentelemetry.sdk.logs.data.Body.string(valueBody.asString()); } + /** + * {@inheritDoc} + * + * @since 1.42.0 + */ @Override @Nullable public abstract Value getBodyValue(); @@ -156,7 +161,11 @@ public Builder setBody(io.opentelemetry.sdk.logs.data.Body body) { return this; } - /** Set the body. */ + /** + * Set the body. + * + * @since 1.42.0 + */ public abstract Builder setBodyValue(@Nullable Value body); /** Set the attributes. */ From 0a47581b2ef4bcd7e486a2660af953c507a29b42 Mon Sep 17 00:00:00 2001 From: OpenTelemetry Bot <107717825+opentelemetrybot@users.noreply.github.com> Date: Fri, 6 Sep 2024 10:40:39 -0500 Subject: [PATCH 554/901] Update version to 1.43.0 (#6689) --- CHANGELOG.md | 2 ++ version.gradle.kts | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 52e7a80906d..1ee1f4922a0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,8 @@ ## Unreleased +## Version 1.42.0 (2024-09-06) + ### API * BREAKING: Stabilize log support for AnyValue bodies. Rename `AnyValue` to `Value`, promote diff --git a/version.gradle.kts b/version.gradle.kts index 91c279ce016..84022c4cb09 100644 --- a/version.gradle.kts +++ b/version.gradle.kts @@ -1,7 +1,7 @@ val snapshot = true allprojects { - var ver = "1.42.0" + var ver = "1.43.0" val release = findProperty("otel.release") if (release != null) { ver += "-" + release From b0643fef389d26702c10b67fd04ffc2fc5aedaad Mon Sep 17 00:00:00 2001 From: OpenTelemetry Bot <107717825+opentelemetrybot@users.noreply.github.com> Date: Fri, 6 Sep 2024 11:57:22 -0500 Subject: [PATCH 555/901] Post release for version 1.42.0 (#6691) --- README.md | 70 +++++++++---------- .../1.42.0_vs_1.41.0/opentelemetry-api.txt | 41 +++++++++++ .../opentelemetry-context.txt | 2 + .../opentelemetry-exporter-common.txt | 2 + .../opentelemetry-exporter-logging-otlp.txt | 2 + .../opentelemetry-exporter-logging.txt | 2 + .../opentelemetry-exporter-otlp-common.txt | 2 + .../opentelemetry-exporter-otlp.txt | 2 + ...y-exporter-sender-grpc-managed-channel.txt | 2 + .../opentelemetry-exporter-sender-jdk.txt | 2 + .../opentelemetry-exporter-sender-okhttp.txt | 2 + .../opentelemetry-exporter-zipkin.txt | 2 + .../opentelemetry-extension-kotlin.txt | 2 + ...ntelemetry-extension-trace-propagators.txt | 2 + .../opentelemetry-opentracing-shim.txt | 2 + .../opentelemetry-sdk-common.txt | 2 + ...emetry-sdk-extension-autoconfigure-spi.txt | 2 + ...ntelemetry-sdk-extension-autoconfigure.txt | 2 + ...ry-sdk-extension-jaeger-remote-sampler.txt | 2 + .../opentelemetry-sdk-logs.txt | 15 ++++ .../opentelemetry-sdk-metrics.txt | 2 + .../opentelemetry-sdk-testing.txt | 26 +++++++ .../opentelemetry-sdk-trace.txt | 2 + .../1.42.0_vs_1.41.0/opentelemetry-sdk.txt | 2 + .../current_vs_latest/opentelemetry-api.txt | 43 +----------- .../opentelemetry-context.txt | 2 +- .../opentelemetry-exporter-common.txt | 2 +- .../opentelemetry-exporter-logging-otlp.txt | 2 +- .../opentelemetry-exporter-logging.txt | 2 +- .../opentelemetry-exporter-otlp-common.txt | 2 +- .../opentelemetry-exporter-otlp.txt | 2 +- ...y-exporter-sender-grpc-managed-channel.txt | 2 +- .../opentelemetry-exporter-sender-jdk.txt | 2 +- .../opentelemetry-exporter-sender-okhttp.txt | 2 +- .../opentelemetry-exporter-zipkin.txt | 2 +- .../opentelemetry-extension-kotlin.txt | 2 +- ...ntelemetry-extension-trace-propagators.txt | 2 +- .../opentelemetry-opentracing-shim.txt | 2 +- .../opentelemetry-sdk-common.txt | 2 +- ...emetry-sdk-extension-autoconfigure-spi.txt | 2 +- ...ntelemetry-sdk-extension-autoconfigure.txt | 2 +- ...ry-sdk-extension-jaeger-remote-sampler.txt | 2 +- .../opentelemetry-sdk-logs.txt | 17 +---- .../opentelemetry-sdk-metrics.txt | 2 +- .../opentelemetry-sdk-testing.txt | 28 +------- .../opentelemetry-sdk-trace.txt | 2 +- .../current_vs_latest/opentelemetry-sdk.txt | 2 +- 47 files changed, 183 insertions(+), 137 deletions(-) create mode 100644 docs/apidiffs/1.42.0_vs_1.41.0/opentelemetry-api.txt create mode 100644 docs/apidiffs/1.42.0_vs_1.41.0/opentelemetry-context.txt create mode 100644 docs/apidiffs/1.42.0_vs_1.41.0/opentelemetry-exporter-common.txt create mode 100644 docs/apidiffs/1.42.0_vs_1.41.0/opentelemetry-exporter-logging-otlp.txt create mode 100644 docs/apidiffs/1.42.0_vs_1.41.0/opentelemetry-exporter-logging.txt create mode 100644 docs/apidiffs/1.42.0_vs_1.41.0/opentelemetry-exporter-otlp-common.txt create mode 100644 docs/apidiffs/1.42.0_vs_1.41.0/opentelemetry-exporter-otlp.txt create mode 100644 docs/apidiffs/1.42.0_vs_1.41.0/opentelemetry-exporter-sender-grpc-managed-channel.txt create mode 100644 docs/apidiffs/1.42.0_vs_1.41.0/opentelemetry-exporter-sender-jdk.txt create mode 100644 docs/apidiffs/1.42.0_vs_1.41.0/opentelemetry-exporter-sender-okhttp.txt create mode 100644 docs/apidiffs/1.42.0_vs_1.41.0/opentelemetry-exporter-zipkin.txt create mode 100644 docs/apidiffs/1.42.0_vs_1.41.0/opentelemetry-extension-kotlin.txt create mode 100644 docs/apidiffs/1.42.0_vs_1.41.0/opentelemetry-extension-trace-propagators.txt create mode 100644 docs/apidiffs/1.42.0_vs_1.41.0/opentelemetry-opentracing-shim.txt create mode 100644 docs/apidiffs/1.42.0_vs_1.41.0/opentelemetry-sdk-common.txt create mode 100644 docs/apidiffs/1.42.0_vs_1.41.0/opentelemetry-sdk-extension-autoconfigure-spi.txt create mode 100644 docs/apidiffs/1.42.0_vs_1.41.0/opentelemetry-sdk-extension-autoconfigure.txt create mode 100644 docs/apidiffs/1.42.0_vs_1.41.0/opentelemetry-sdk-extension-jaeger-remote-sampler.txt create mode 100644 docs/apidiffs/1.42.0_vs_1.41.0/opentelemetry-sdk-logs.txt create mode 100644 docs/apidiffs/1.42.0_vs_1.41.0/opentelemetry-sdk-metrics.txt create mode 100644 docs/apidiffs/1.42.0_vs_1.41.0/opentelemetry-sdk-testing.txt create mode 100644 docs/apidiffs/1.42.0_vs_1.41.0/opentelemetry-sdk-trace.txt create mode 100644 docs/apidiffs/1.42.0_vs_1.41.0/opentelemetry-sdk.txt diff --git a/README.md b/README.md index 6fb2b74002f..27c83571802 100644 --- a/README.md +++ b/README.md @@ -104,7 +104,7 @@ dependency versions in sync. io.opentelemetry opentelemetry-bom - 1.41.0 + 1.42.0 pom import @@ -123,7 +123,7 @@ dependency versions in sync. ```groovy dependencies { - implementation platform("io.opentelemetry:opentelemetry-bom:1.41.0") + implementation platform("io.opentelemetry:opentelemetry-bom:1.42.0") implementation('io.opentelemetry:opentelemetry-api') } ``` @@ -132,8 +132,8 @@ Note that if you want to use any artifacts that have not fully stabilized yet (s ```groovy dependencies { - implementation platform("io.opentelemetry:opentelemetry-bom:1.41.0") - implementation platform('io.opentelemetry:opentelemetry-bom-alpha:1.41.0-alpha') + implementation platform("io.opentelemetry:opentelemetry-bom:1.42.0") + implementation platform('io.opentelemetry:opentelemetry-bom-alpha:1.42.0-alpha') implementation('io.opentelemetry:opentelemetry-api') implementation('io.opentelemetry:opentelemetry-exporter-prometheus') @@ -161,7 +161,7 @@ We strongly recommend using our published BOM to keep all dependency versions in io.opentelemetry opentelemetry-bom - 1.42.0-SNAPSHOT + 1.43.0-SNAPSHOT pom import @@ -184,7 +184,7 @@ repositories { } dependencies { - implementation platform("io.opentelemetry:opentelemetry-bom:1.42.0-SNAPSHOT") + implementation platform("io.opentelemetry:opentelemetry-bom:1.43.0-SNAPSHOT") implementation('io.opentelemetry:opentelemetry-api') } ``` @@ -229,66 +229,66 @@ dependency as follows, replacing `{{artifact-id}}` with the value from the "Arti | Component | Description | Artifact ID | Version | Javadoc | |----------------------------------------------|----------------------------------------|---------------------------|-------------------------------------------------------------|---------| -| [Bill of Materials (BOM)](./bom) | Bill of materials for stable artifacts | `opentelemetry-bom` | 1.41.0 | N/A | -| [Alpha Bill of Materials (BOM)](./bom-alpha) | Bill of materials for alpha artifacts | `opentelemetry-bom-alpha` | 1.41.0-alpha | N/A | +| [Bill of Materials (BOM)](./bom) | Bill of materials for stable artifacts | `opentelemetry-bom` | 1.42.0 | N/A | +| [Alpha Bill of Materials (BOM)](./bom-alpha) | Bill of materials for alpha artifacts | `opentelemetry-bom-alpha` | 1.42.0-alpha | N/A | ### API | Component | Description | Artifact ID | Version | Javadoc | |-----------------------------------|--------------------------------------------------------------------------------------|-------------------------------|---------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| [API](./api/all) | OpenTelemetry API, including metrics, traces, baggage, context | `opentelemetry-api` | 1.41.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-api.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-api) | -| [API Incubator](./api/incubator) | API incubator, including pass through propagator, and extended tracer, and Event API | `opentelemetry-api-incubator` | 1.41.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-api-incubator.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-api-incubator) | -| [Context API](./context) | OpenTelemetry context API | `opentelemetry-context` | 1.41.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-context.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-context) | +| [API](./api/all) | OpenTelemetry API, including metrics, traces, baggage, context | `opentelemetry-api` | 1.42.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-api.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-api) | +| [API Incubator](./api/incubator) | API incubator, including pass through propagator, and extended tracer, and Event API | `opentelemetry-api-incubator` | 1.42.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-api-incubator.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-api-incubator) | +| [Context API](./context) | OpenTelemetry context API | `opentelemetry-context` | 1.42.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-context.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-context) | ### API Extensions | Component | Description | Artifact ID | Version | Javadoc | |---------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|---------------------------------------------|-------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| [Kotlin Extension](./extensions/kotlin) | Context extension for coroutines | `opentelemetry-extension-kotlin` | 1.41.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-extension-kotlin.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-extension-kotlin) | -| [Trace Propagators Extension](./extensions/trace-propagators) | Trace propagators, including B3, Jaeger, OT Trace | `opentelemetry-extension-trace-propagators` | 1.41.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-extension-trace-propagators.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-extension-trace-propagators) | +| [Kotlin Extension](./extensions/kotlin) | Context extension for coroutines | `opentelemetry-extension-kotlin` | 1.42.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-extension-kotlin.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-extension-kotlin) | +| [Trace Propagators Extension](./extensions/trace-propagators) | Trace propagators, including B3, Jaeger, OT Trace | `opentelemetry-extension-trace-propagators` | 1.42.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-extension-trace-propagators.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-extension-trace-propagators) | ### SDK | Component | Description | Artifact ID | Version | Javadoc | |------------------------------|--------------------------------------------------------|-----------------------------|---------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| [SDK](./sdk/all) | OpenTelemetry SDK, including metrics, traces, and logs | `opentelemetry-sdk` | 1.41.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk) | -| [Metrics SDK](./sdk/metrics) | OpenTelemetry metrics SDK | `opentelemetry-sdk-metrics` | 1.41.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-metrics.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-metrics) | -| [Trace SDK](./sdk/trace) | OpenTelemetry trace SDK | `opentelemetry-sdk-trace` | 1.41.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-trace.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-trace) | -| [Log SDK](./sdk/logs) | OpenTelemetry log SDK | `opentelemetry-sdk-logs` | 1.41.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-logs.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-logs) | -| [SDK Common](./sdk/common) | Shared SDK components | `opentelemetry-sdk-common` | 1.41.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-common.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-common) | -| [SDK Testing](./sdk/testing) | Components for testing OpenTelemetry instrumentation | `opentelemetry-sdk-testing` | 1.41.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-testing.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-testing) | +| [SDK](./sdk/all) | OpenTelemetry SDK, including metrics, traces, and logs | `opentelemetry-sdk` | 1.42.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk) | +| [Metrics SDK](./sdk/metrics) | OpenTelemetry metrics SDK | `opentelemetry-sdk-metrics` | 1.42.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-metrics.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-metrics) | +| [Trace SDK](./sdk/trace) | OpenTelemetry trace SDK | `opentelemetry-sdk-trace` | 1.42.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-trace.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-trace) | +| [Log SDK](./sdk/logs) | OpenTelemetry log SDK | `opentelemetry-sdk-logs` | 1.42.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-logs.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-logs) | +| [SDK Common](./sdk/common) | Shared SDK components | `opentelemetry-sdk-common` | 1.42.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-common.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-common) | +| [SDK Testing](./sdk/testing) | Components for testing OpenTelemetry instrumentation | `opentelemetry-sdk-testing` | 1.42.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-testing.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-testing) | ### SDK Exporters | Component | Description | Artifact ID | Version | Javadoc | |-----------------------------------------------------------------------|------------------------------------------------------------------------------|------------------------------------------------------|-------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| [OTLP Exporters](./exporters/otlp/all) | OTLP gRPC & HTTP exporters, including traces, metrics, and logs | `opentelemetry-exporter-otlp` | 1.41.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-otlp.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-otlp) | -| [OTLP Logging Exporters](./exporters/logging-otlp) | Logging exporters in OTLP JSON encoding, including traces, metrics, and logs | `opentelemetry-exporter-logging-otlp` | 1.41.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-logging-otlp.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-logging-otlp) | -| [OTLP Common](./exporters/otlp/common) | Shared OTLP components (internal) | `opentelemetry-exporter-otlp-common` | 1.41.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-otlp-common.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-otlp-common) | -| [Logging Exporter](./exporters/logging) | Logging exporters, including metrics, traces, and logs | `opentelemetry-exporter-logging` | 1.41.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-logging.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-logging) | -| [Zipkin Exporter](./exporters/zipkin) | Zipkin trace exporter | `opentelemetry-exporter-zipkin` | 1.41.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-zipkin.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-zipkin) | -| [Prometheus Exporter](./exporters/prometheus) | Prometheus metric exporter | `opentelemetry-exporter-prometheus` | 1.41.0-alpha | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-prometheus.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-prometheus) | -| [Exporter Common](./exporters/common) | Shared exporter components (internal) | `opentelemetry-exporter-common` | 1.41.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-common.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-common) | -| [OkHttp Sender](./exporters/sender/okhttp) | OkHttp implementation of HttpSender (internal) | `opentelemetry-exporter-sender-okhttp` | 1.41.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-sender-okhttp.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-sender-okhttp) | -| [JDK Sender](./exporters/sender/jdk) | Java 11+ native HttpClient implementation of HttpSender (internal) | `opentelemetry-exporter-sender-jdk` | 1.41.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-sender-jdk.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-sender-jdk) | | -| [gRPC ManagedChannel Sender](./exporters/sender/grpc-managed-channel) | gRPC ManagedChannel implementation of GrpcSender (internal) | `opentelemetry-exporter-sender-grpc-managed-channel` | 1.41.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-sender-grpc-managed-channel.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-sender-grpc-managed-channel) | | +| [OTLP Exporters](./exporters/otlp/all) | OTLP gRPC & HTTP exporters, including traces, metrics, and logs | `opentelemetry-exporter-otlp` | 1.42.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-otlp.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-otlp) | +| [OTLP Logging Exporters](./exporters/logging-otlp) | Logging exporters in OTLP JSON encoding, including traces, metrics, and logs | `opentelemetry-exporter-logging-otlp` | 1.42.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-logging-otlp.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-logging-otlp) | +| [OTLP Common](./exporters/otlp/common) | Shared OTLP components (internal) | `opentelemetry-exporter-otlp-common` | 1.42.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-otlp-common.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-otlp-common) | +| [Logging Exporter](./exporters/logging) | Logging exporters, including metrics, traces, and logs | `opentelemetry-exporter-logging` | 1.42.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-logging.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-logging) | +| [Zipkin Exporter](./exporters/zipkin) | Zipkin trace exporter | `opentelemetry-exporter-zipkin` | 1.42.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-zipkin.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-zipkin) | +| [Prometheus Exporter](./exporters/prometheus) | Prometheus metric exporter | `opentelemetry-exporter-prometheus` | 1.42.0-alpha | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-prometheus.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-prometheus) | +| [Exporter Common](./exporters/common) | Shared exporter components (internal) | `opentelemetry-exporter-common` | 1.42.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-common.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-common) | +| [OkHttp Sender](./exporters/sender/okhttp) | OkHttp implementation of HttpSender (internal) | `opentelemetry-exporter-sender-okhttp` | 1.42.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-sender-okhttp.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-sender-okhttp) | +| [JDK Sender](./exporters/sender/jdk) | Java 11+ native HttpClient implementation of HttpSender (internal) | `opentelemetry-exporter-sender-jdk` | 1.42.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-sender-jdk.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-sender-jdk) | | +| [gRPC ManagedChannel Sender](./exporters/sender/grpc-managed-channel) | gRPC ManagedChannel implementation of GrpcSender (internal) | `opentelemetry-exporter-sender-grpc-managed-channel` | 1.42.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-sender-grpc-managed-channel.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-sender-grpc-managed-channel) | | ### SDK Extensions | Component | Description | Artifact ID | Version | Javadoc | |-------------------------------------------------------------------------------|------------------------------------------------------------------------------------|-----------------------------------------------------|-------------------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| [SDK Autoconfigure](./sdk-extensions/autoconfigure) | Autoconfigure OpenTelemetry SDK from env vars, system properties, and SPI | `opentelemetry-sdk-extension-autoconfigure` | 1.41.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-extension-autoconfigure.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-extension-autoconfigure) | -| [SDK Autoconfigure SPI](./sdk-extensions/autoconfigure-spi) | Service Provider Interface (SPI) definitions for autoconfigure | `opentelemetry-sdk-extension-autoconfigure-spi` | 1.41.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-extension-autoconfigure-spi.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-extension-autoconfigure-spi) | -| [SDK Jaeger Remote Sampler Extension](./sdk-extensions/jaeger-remote-sampler) | Sampler which obtains sampling configuration from remote Jaeger server | `opentelemetry-sdk-extension-jaeger-remote-sampler` | 1.41.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-extension-jaeger-remote-sampler.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-extension-jaeger-remote-sampler) | -| [SDK Incubator](./sdk-extensions/incubator) | SDK incubator, including YAML based view configuration, LeakDetectingSpanProcessor | `opentelemetry-sdk-extension-incubator` | 1.41.0-alpha | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-extension-incubator.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-extension-incubator) | +| [SDK Autoconfigure](./sdk-extensions/autoconfigure) | Autoconfigure OpenTelemetry SDK from env vars, system properties, and SPI | `opentelemetry-sdk-extension-autoconfigure` | 1.42.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-extension-autoconfigure.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-extension-autoconfigure) | +| [SDK Autoconfigure SPI](./sdk-extensions/autoconfigure-spi) | Service Provider Interface (SPI) definitions for autoconfigure | `opentelemetry-sdk-extension-autoconfigure-spi` | 1.42.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-extension-autoconfigure-spi.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-extension-autoconfigure-spi) | +| [SDK Jaeger Remote Sampler Extension](./sdk-extensions/jaeger-remote-sampler) | Sampler which obtains sampling configuration from remote Jaeger server | `opentelemetry-sdk-extension-jaeger-remote-sampler` | 1.42.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-extension-jaeger-remote-sampler.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-extension-jaeger-remote-sampler) | +| [SDK Incubator](./sdk-extensions/incubator) | SDK incubator, including YAML based view configuration, LeakDetectingSpanProcessor | `opentelemetry-sdk-extension-incubator` | 1.42.0-alpha | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-extension-incubator.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-extension-incubator) | ### Shims | Component | Description | Artifact ID | Version | Javadoc | |----------------------------------------|--------------------------------------------------------------|----------------------------------|-------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| [OpenCensus Shim](./opencensus-shim) | Bridge opencensus metrics into the OpenTelemetry metrics SDK | `opentelemetry-opencensus-shim` | 1.41.0-alpha | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-opencensus-shim.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-opencensus-shim) | -| [OpenTracing Shim](./opentracing-shim) | Bridge opentracing spans into the OpenTelemetry trace API | `opentelemetry-opentracing-shim` | 1.41.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-opentracing-shim.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-opentracing-shim) | +| [OpenCensus Shim](./opencensus-shim) | Bridge opencensus metrics into the OpenTelemetry metrics SDK | `opentelemetry-opencensus-shim` | 1.42.0-alpha | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-opencensus-shim.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-opencensus-shim) | +| [OpenTracing Shim](./opentracing-shim) | Bridge opentracing spans into the OpenTelemetry trace API | `opentelemetry-opentracing-shim` | 1.42.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-opentracing-shim.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-opentracing-shim) | ## Contributing diff --git a/docs/apidiffs/1.42.0_vs_1.41.0/opentelemetry-api.txt b/docs/apidiffs/1.42.0_vs_1.41.0/opentelemetry-api.txt new file mode 100644 index 00000000000..3a96056c4f1 --- /dev/null +++ b/docs/apidiffs/1.42.0_vs_1.41.0/opentelemetry-api.txt @@ -0,0 +1,41 @@ +Comparing source compatibility of opentelemetry-api-1.42.0.jar against opentelemetry-api-1.41.0.jar ++++ NEW INTERFACE: PUBLIC(+) ABSTRACT(+) io.opentelemetry.api.common.KeyValue (not serializable) + +++ CLASS FILE FORMAT VERSION: 52.0 <- n.a. + +++ NEW SUPERCLASS: java.lang.Object + +++ NEW METHOD: PUBLIC(+) ABSTRACT(+) java.lang.String getKey() + +++ NEW METHOD: PUBLIC(+) ABSTRACT(+) io.opentelemetry.api.common.Value getValue() + +++ NEW METHOD: PUBLIC(+) STATIC(+) io.opentelemetry.api.common.KeyValue of(java.lang.String, io.opentelemetry.api.common.Value) ++++ NEW INTERFACE: PUBLIC(+) ABSTRACT(+) io.opentelemetry.api.common.Value (not serializable) + +++ CLASS FILE FORMAT VERSION: 52.0 <- n.a. + GENERIC TEMPLATES: +++ T:java.lang.Object + +++ NEW SUPERCLASS: java.lang.Object + +++ NEW METHOD: PUBLIC(+) ABSTRACT(+) java.lang.String asString() + +++ NEW METHOD: PUBLIC(+) ABSTRACT(+) io.opentelemetry.api.common.ValueType getType() + +++ NEW METHOD: PUBLIC(+) ABSTRACT(+) java.lang.Object getValue() + +++ NEW METHOD: PUBLIC(+) STATIC(+) io.opentelemetry.api.common.Value of(java.lang.String) + +++ NEW METHOD: PUBLIC(+) STATIC(+) io.opentelemetry.api.common.Value of(boolean) + +++ NEW METHOD: PUBLIC(+) STATIC(+) io.opentelemetry.api.common.Value of(long) + +++ NEW METHOD: PUBLIC(+) STATIC(+) io.opentelemetry.api.common.Value of(double) + +++ NEW METHOD: PUBLIC(+) STATIC(+) io.opentelemetry.api.common.Value of(byte[]) + +++ NEW METHOD: PUBLIC(+) STATIC(+) io.opentelemetry.api.common.Value>> of(io.opentelemetry.api.common.Value[]) + +++ NEW METHOD: PUBLIC(+) STATIC(+) io.opentelemetry.api.common.Value>> of(java.util.List>) + +++ NEW METHOD: PUBLIC(+) STATIC(+) io.opentelemetry.api.common.Value> of(io.opentelemetry.api.common.KeyValue[]) + +++ NEW METHOD: PUBLIC(+) STATIC(+) io.opentelemetry.api.common.Value> of(java.util.Map>) ++++ NEW ENUM: PUBLIC(+) FINAL(+) io.opentelemetry.api.common.ValueType (compatible) + +++ CLASS FILE FORMAT VERSION: 52.0 <- n.a. + +++ NEW INTERFACE: java.lang.constant.Constable + +++ NEW INTERFACE: java.lang.Comparable + +++ NEW INTERFACE: java.io.Serializable + +++ NEW SUPERCLASS: java.lang.Enum + +++ NEW FIELD: PUBLIC(+) STATIC(+) FINAL(+) io.opentelemetry.api.common.ValueType BYTES + +++ NEW FIELD: PUBLIC(+) STATIC(+) FINAL(+) io.opentelemetry.api.common.ValueType ARRAY + +++ NEW FIELD: PUBLIC(+) STATIC(+) FINAL(+) io.opentelemetry.api.common.ValueType KEY_VALUE_LIST + +++ NEW FIELD: PUBLIC(+) STATIC(+) FINAL(+) io.opentelemetry.api.common.ValueType STRING + +++ NEW FIELD: PUBLIC(+) STATIC(+) FINAL(+) io.opentelemetry.api.common.ValueType DOUBLE + +++ NEW FIELD: PUBLIC(+) STATIC(+) FINAL(+) io.opentelemetry.api.common.ValueType BOOLEAN + +++ NEW FIELD: PUBLIC(+) STATIC(+) FINAL(+) io.opentelemetry.api.common.ValueType LONG + +++ NEW METHOD: PUBLIC(+) STATIC(+) io.opentelemetry.api.common.ValueType valueOf(java.lang.String) + +++ NEW METHOD: PUBLIC(+) STATIC(+) io.opentelemetry.api.common.ValueType[] values() +*** MODIFIED INTERFACE: PUBLIC ABSTRACT io.opentelemetry.api.logs.LogRecordBuilder (not serializable) + === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 + +++ NEW METHOD: PUBLIC(+) io.opentelemetry.api.logs.LogRecordBuilder setBody(io.opentelemetry.api.common.Value) diff --git a/docs/apidiffs/1.42.0_vs_1.41.0/opentelemetry-context.txt b/docs/apidiffs/1.42.0_vs_1.41.0/opentelemetry-context.txt new file mode 100644 index 00000000000..4235de83b07 --- /dev/null +++ b/docs/apidiffs/1.42.0_vs_1.41.0/opentelemetry-context.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of opentelemetry-context-1.42.0.jar against opentelemetry-context-1.41.0.jar +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.42.0_vs_1.41.0/opentelemetry-exporter-common.txt b/docs/apidiffs/1.42.0_vs_1.41.0/opentelemetry-exporter-common.txt new file mode 100644 index 00000000000..b9516eeee56 --- /dev/null +++ b/docs/apidiffs/1.42.0_vs_1.41.0/opentelemetry-exporter-common.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of opentelemetry-exporter-common-1.42.0.jar against opentelemetry-exporter-common-1.41.0.jar +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.42.0_vs_1.41.0/opentelemetry-exporter-logging-otlp.txt b/docs/apidiffs/1.42.0_vs_1.41.0/opentelemetry-exporter-logging-otlp.txt new file mode 100644 index 00000000000..c20575d8213 --- /dev/null +++ b/docs/apidiffs/1.42.0_vs_1.41.0/opentelemetry-exporter-logging-otlp.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of opentelemetry-exporter-logging-otlp-1.42.0.jar against opentelemetry-exporter-logging-otlp-1.41.0.jar +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.42.0_vs_1.41.0/opentelemetry-exporter-logging.txt b/docs/apidiffs/1.42.0_vs_1.41.0/opentelemetry-exporter-logging.txt new file mode 100644 index 00000000000..742accf915d --- /dev/null +++ b/docs/apidiffs/1.42.0_vs_1.41.0/opentelemetry-exporter-logging.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of opentelemetry-exporter-logging-1.42.0.jar against opentelemetry-exporter-logging-1.41.0.jar +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.42.0_vs_1.41.0/opentelemetry-exporter-otlp-common.txt b/docs/apidiffs/1.42.0_vs_1.41.0/opentelemetry-exporter-otlp-common.txt new file mode 100644 index 00000000000..65d41b6ec4e --- /dev/null +++ b/docs/apidiffs/1.42.0_vs_1.41.0/opentelemetry-exporter-otlp-common.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of opentelemetry-exporter-otlp-common-1.42.0.jar against opentelemetry-exporter-otlp-common-1.41.0.jar +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.42.0_vs_1.41.0/opentelemetry-exporter-otlp.txt b/docs/apidiffs/1.42.0_vs_1.41.0/opentelemetry-exporter-otlp.txt new file mode 100644 index 00000000000..217a061f337 --- /dev/null +++ b/docs/apidiffs/1.42.0_vs_1.41.0/opentelemetry-exporter-otlp.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of opentelemetry-exporter-otlp-1.42.0.jar against opentelemetry-exporter-otlp-1.41.0.jar +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.42.0_vs_1.41.0/opentelemetry-exporter-sender-grpc-managed-channel.txt b/docs/apidiffs/1.42.0_vs_1.41.0/opentelemetry-exporter-sender-grpc-managed-channel.txt new file mode 100644 index 00000000000..761405711f8 --- /dev/null +++ b/docs/apidiffs/1.42.0_vs_1.41.0/opentelemetry-exporter-sender-grpc-managed-channel.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of opentelemetry-exporter-sender-grpc-managed-channel-1.42.0.jar against opentelemetry-exporter-sender-grpc-managed-channel-1.41.0.jar +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.42.0_vs_1.41.0/opentelemetry-exporter-sender-jdk.txt b/docs/apidiffs/1.42.0_vs_1.41.0/opentelemetry-exporter-sender-jdk.txt new file mode 100644 index 00000000000..c1b86871894 --- /dev/null +++ b/docs/apidiffs/1.42.0_vs_1.41.0/opentelemetry-exporter-sender-jdk.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of opentelemetry-exporter-sender-jdk-1.42.0.jar against opentelemetry-exporter-sender-jdk-1.41.0.jar +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.42.0_vs_1.41.0/opentelemetry-exporter-sender-okhttp.txt b/docs/apidiffs/1.42.0_vs_1.41.0/opentelemetry-exporter-sender-okhttp.txt new file mode 100644 index 00000000000..8fee739b86d --- /dev/null +++ b/docs/apidiffs/1.42.0_vs_1.41.0/opentelemetry-exporter-sender-okhttp.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of opentelemetry-exporter-sender-okhttp-1.42.0.jar against opentelemetry-exporter-sender-okhttp-1.41.0.jar +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.42.0_vs_1.41.0/opentelemetry-exporter-zipkin.txt b/docs/apidiffs/1.42.0_vs_1.41.0/opentelemetry-exporter-zipkin.txt new file mode 100644 index 00000000000..29c5e24ef73 --- /dev/null +++ b/docs/apidiffs/1.42.0_vs_1.41.0/opentelemetry-exporter-zipkin.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of opentelemetry-exporter-zipkin-1.42.0.jar against opentelemetry-exporter-zipkin-1.41.0.jar +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.42.0_vs_1.41.0/opentelemetry-extension-kotlin.txt b/docs/apidiffs/1.42.0_vs_1.41.0/opentelemetry-extension-kotlin.txt new file mode 100644 index 00000000000..74011673f81 --- /dev/null +++ b/docs/apidiffs/1.42.0_vs_1.41.0/opentelemetry-extension-kotlin.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of opentelemetry-extension-kotlin-1.42.0.jar against opentelemetry-extension-kotlin-1.41.0.jar +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.42.0_vs_1.41.0/opentelemetry-extension-trace-propagators.txt b/docs/apidiffs/1.42.0_vs_1.41.0/opentelemetry-extension-trace-propagators.txt new file mode 100644 index 00000000000..5a5b46fc554 --- /dev/null +++ b/docs/apidiffs/1.42.0_vs_1.41.0/opentelemetry-extension-trace-propagators.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of opentelemetry-extension-trace-propagators-1.42.0.jar against opentelemetry-extension-trace-propagators-1.41.0.jar +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.42.0_vs_1.41.0/opentelemetry-opentracing-shim.txt b/docs/apidiffs/1.42.0_vs_1.41.0/opentelemetry-opentracing-shim.txt new file mode 100644 index 00000000000..459a5cbb037 --- /dev/null +++ b/docs/apidiffs/1.42.0_vs_1.41.0/opentelemetry-opentracing-shim.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of opentelemetry-opentracing-shim-1.42.0.jar against opentelemetry-opentracing-shim-1.41.0.jar +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.42.0_vs_1.41.0/opentelemetry-sdk-common.txt b/docs/apidiffs/1.42.0_vs_1.41.0/opentelemetry-sdk-common.txt new file mode 100644 index 00000000000..15d384cb970 --- /dev/null +++ b/docs/apidiffs/1.42.0_vs_1.41.0/opentelemetry-sdk-common.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of opentelemetry-sdk-common-1.42.0.jar against opentelemetry-sdk-common-1.41.0.jar +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.42.0_vs_1.41.0/opentelemetry-sdk-extension-autoconfigure-spi.txt b/docs/apidiffs/1.42.0_vs_1.41.0/opentelemetry-sdk-extension-autoconfigure-spi.txt new file mode 100644 index 00000000000..507709301e4 --- /dev/null +++ b/docs/apidiffs/1.42.0_vs_1.41.0/opentelemetry-sdk-extension-autoconfigure-spi.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of opentelemetry-sdk-extension-autoconfigure-spi-1.42.0.jar against opentelemetry-sdk-extension-autoconfigure-spi-1.41.0.jar +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.42.0_vs_1.41.0/opentelemetry-sdk-extension-autoconfigure.txt b/docs/apidiffs/1.42.0_vs_1.41.0/opentelemetry-sdk-extension-autoconfigure.txt new file mode 100644 index 00000000000..bc405d103f5 --- /dev/null +++ b/docs/apidiffs/1.42.0_vs_1.41.0/opentelemetry-sdk-extension-autoconfigure.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of opentelemetry-sdk-extension-autoconfigure-1.42.0.jar against opentelemetry-sdk-extension-autoconfigure-1.41.0.jar +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.42.0_vs_1.41.0/opentelemetry-sdk-extension-jaeger-remote-sampler.txt b/docs/apidiffs/1.42.0_vs_1.41.0/opentelemetry-sdk-extension-jaeger-remote-sampler.txt new file mode 100644 index 00000000000..debfbaf6acc --- /dev/null +++ b/docs/apidiffs/1.42.0_vs_1.41.0/opentelemetry-sdk-extension-jaeger-remote-sampler.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of opentelemetry-sdk-extension-jaeger-remote-sampler-1.42.0.jar against opentelemetry-sdk-extension-jaeger-remote-sampler-1.41.0.jar +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.42.0_vs_1.41.0/opentelemetry-sdk-logs.txt b/docs/apidiffs/1.42.0_vs_1.41.0/opentelemetry-sdk-logs.txt new file mode 100644 index 00000000000..44d010071ed --- /dev/null +++ b/docs/apidiffs/1.42.0_vs_1.41.0/opentelemetry-sdk-logs.txt @@ -0,0 +1,15 @@ +Comparing source compatibility of opentelemetry-sdk-logs-1.42.0.jar against opentelemetry-sdk-logs-1.41.0.jar +=== UNCHANGED INTERFACE: PUBLIC ABSTRACT io.opentelemetry.sdk.logs.data.Body (not serializable) + === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 + === UNCHANGED METHOD: PUBLIC ABSTRACT io.opentelemetry.sdk.logs.data.Body$Type getType() + +++ NEW ANNOTATION: java.lang.Deprecated + +++ NEW ANNOTATION: java.lang.Deprecated +=== UNCHANGED ENUM: PUBLIC STATIC FINAL io.opentelemetry.sdk.logs.data.Body$Type (compatible) + === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 + +++ NEW ANNOTATION: java.lang.Deprecated +*** MODIFIED INTERFACE: PUBLIC ABSTRACT io.opentelemetry.sdk.logs.data.LogRecordData (not serializable) + === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 + === UNCHANGED METHOD: PUBLIC ABSTRACT io.opentelemetry.sdk.logs.data.Body getBody() + +++ NEW ANNOTATION: java.lang.Deprecated + +++ NEW METHOD: PUBLIC(+) io.opentelemetry.api.common.Value getBodyValue() + +++ NEW ANNOTATION: javax.annotation.Nullable diff --git a/docs/apidiffs/1.42.0_vs_1.41.0/opentelemetry-sdk-metrics.txt b/docs/apidiffs/1.42.0_vs_1.41.0/opentelemetry-sdk-metrics.txt new file mode 100644 index 00000000000..2d8dc8fe717 --- /dev/null +++ b/docs/apidiffs/1.42.0_vs_1.41.0/opentelemetry-sdk-metrics.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of opentelemetry-sdk-metrics-1.42.0.jar against opentelemetry-sdk-metrics-1.41.0.jar +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.42.0_vs_1.41.0/opentelemetry-sdk-testing.txt b/docs/apidiffs/1.42.0_vs_1.41.0/opentelemetry-sdk-testing.txt new file mode 100644 index 00000000000..be9647f8b89 --- /dev/null +++ b/docs/apidiffs/1.42.0_vs_1.41.0/opentelemetry-sdk-testing.txt @@ -0,0 +1,26 @@ +Comparing source compatibility of opentelemetry-sdk-testing-1.42.0.jar against opentelemetry-sdk-testing-1.41.0.jar +*** MODIFIED CLASS: PUBLIC FINAL io.opentelemetry.sdk.testing.assertj.LogRecordDataAssert (not serializable) + === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 + +++ NEW METHOD: PUBLIC(+) io.opentelemetry.sdk.testing.assertj.LogRecordDataAssert hasBody(io.opentelemetry.api.common.Value) + +++ NEW METHOD: PUBLIC(+) io.opentelemetry.sdk.testing.assertj.LogRecordDataAssert hasBodyField(java.lang.String, java.lang.String) + +++ NEW METHOD: PUBLIC(+) io.opentelemetry.sdk.testing.assertj.LogRecordDataAssert hasBodyField(java.lang.String, long) + +++ NEW METHOD: PUBLIC(+) io.opentelemetry.sdk.testing.assertj.LogRecordDataAssert hasBodyField(java.lang.String, double) + +++ NEW METHOD: PUBLIC(+) io.opentelemetry.sdk.testing.assertj.LogRecordDataAssert hasBodyField(java.lang.String, boolean) + +++ NEW METHOD: PUBLIC(+) io.opentelemetry.sdk.testing.assertj.LogRecordDataAssert hasBodyField(java.lang.String, java.lang.String[]) + +++ NEW METHOD: PUBLIC(+) io.opentelemetry.sdk.testing.assertj.LogRecordDataAssert hasBodyField(java.lang.String, long[]) + +++ NEW METHOD: PUBLIC(+) io.opentelemetry.sdk.testing.assertj.LogRecordDataAssert hasBodyField(java.lang.String, double[]) + +++ NEW METHOD: PUBLIC(+) io.opentelemetry.sdk.testing.assertj.LogRecordDataAssert hasBodyField(java.lang.String, boolean[]) + +++ NEW METHOD: PUBLIC(+) io.opentelemetry.sdk.testing.assertj.LogRecordDataAssert hasBodyField(java.lang.String, io.opentelemetry.api.common.Value) + +++ NEW METHOD: PUBLIC(+) io.opentelemetry.sdk.testing.assertj.LogRecordDataAssert hasBodyField(io.opentelemetry.api.common.AttributeKey, java.lang.Object) + GENERIC TEMPLATES: +++ T:java.lang.Object +**** MODIFIED CLASS: PUBLIC ABSTRACT io.opentelemetry.sdk.testing.logs.TestLogRecordData (not serializable) + === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 + +++ NEW METHOD: PUBLIC(+) io.opentelemetry.sdk.logs.data.Body getBody() + +++ NEW ANNOTATION: java.lang.Deprecated + +++* NEW METHOD: PUBLIC(+) ABSTRACT(+) io.opentelemetry.api.common.Value getBodyValue() + +++ NEW ANNOTATION: javax.annotation.Nullable +**** MODIFIED CLASS: PUBLIC ABSTRACT STATIC io.opentelemetry.sdk.testing.logs.TestLogRecordData$Builder (not serializable) + === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 + *** MODIFIED METHOD: PUBLIC (<- PACKAGE_PROTECTED) NON_ABSTRACT (<- ABSTRACT) io.opentelemetry.sdk.testing.logs.TestLogRecordData$Builder setBody(io.opentelemetry.sdk.logs.data.Body) + +++ NEW ANNOTATION: java.lang.Deprecated + +++* NEW METHOD: PUBLIC(+) ABSTRACT(+) io.opentelemetry.sdk.testing.logs.TestLogRecordData$Builder setBodyValue(io.opentelemetry.api.common.Value) diff --git a/docs/apidiffs/1.42.0_vs_1.41.0/opentelemetry-sdk-trace.txt b/docs/apidiffs/1.42.0_vs_1.41.0/opentelemetry-sdk-trace.txt new file mode 100644 index 00000000000..6812c3e1cd1 --- /dev/null +++ b/docs/apidiffs/1.42.0_vs_1.41.0/opentelemetry-sdk-trace.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of opentelemetry-sdk-trace-1.42.0.jar against opentelemetry-sdk-trace-1.41.0.jar +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.42.0_vs_1.41.0/opentelemetry-sdk.txt b/docs/apidiffs/1.42.0_vs_1.41.0/opentelemetry-sdk.txt new file mode 100644 index 00000000000..78c1aa54f96 --- /dev/null +++ b/docs/apidiffs/1.42.0_vs_1.41.0/opentelemetry-sdk.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of opentelemetry-sdk-1.42.0.jar against opentelemetry-sdk-1.41.0.jar +No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-api.txt b/docs/apidiffs/current_vs_latest/opentelemetry-api.txt index 2b8bdd18bad..d9de410b484 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-api.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-api.txt @@ -1,41 +1,2 @@ -Comparing source compatibility of opentelemetry-api-1.42.0-SNAPSHOT.jar against opentelemetry-api-1.41.0.jar -+++ NEW INTERFACE: PUBLIC(+) ABSTRACT(+) io.opentelemetry.api.common.KeyValue (not serializable) - +++ CLASS FILE FORMAT VERSION: 52.0 <- n.a. - +++ NEW SUPERCLASS: java.lang.Object - +++ NEW METHOD: PUBLIC(+) ABSTRACT(+) java.lang.String getKey() - +++ NEW METHOD: PUBLIC(+) ABSTRACT(+) io.opentelemetry.api.common.Value getValue() - +++ NEW METHOD: PUBLIC(+) STATIC(+) io.opentelemetry.api.common.KeyValue of(java.lang.String, io.opentelemetry.api.common.Value) -+++ NEW INTERFACE: PUBLIC(+) ABSTRACT(+) io.opentelemetry.api.common.Value (not serializable) - +++ CLASS FILE FORMAT VERSION: 52.0 <- n.a. - GENERIC TEMPLATES: +++ T:java.lang.Object - +++ NEW SUPERCLASS: java.lang.Object - +++ NEW METHOD: PUBLIC(+) ABSTRACT(+) java.lang.String asString() - +++ NEW METHOD: PUBLIC(+) ABSTRACT(+) io.opentelemetry.api.common.ValueType getType() - +++ NEW METHOD: PUBLIC(+) ABSTRACT(+) java.lang.Object getValue() - +++ NEW METHOD: PUBLIC(+) STATIC(+) io.opentelemetry.api.common.Value of(java.lang.String) - +++ NEW METHOD: PUBLIC(+) STATIC(+) io.opentelemetry.api.common.Value of(boolean) - +++ NEW METHOD: PUBLIC(+) STATIC(+) io.opentelemetry.api.common.Value of(long) - +++ NEW METHOD: PUBLIC(+) STATIC(+) io.opentelemetry.api.common.Value of(double) - +++ NEW METHOD: PUBLIC(+) STATIC(+) io.opentelemetry.api.common.Value of(byte[]) - +++ NEW METHOD: PUBLIC(+) STATIC(+) io.opentelemetry.api.common.Value>> of(io.opentelemetry.api.common.Value[]) - +++ NEW METHOD: PUBLIC(+) STATIC(+) io.opentelemetry.api.common.Value>> of(java.util.List>) - +++ NEW METHOD: PUBLIC(+) STATIC(+) io.opentelemetry.api.common.Value> of(io.opentelemetry.api.common.KeyValue[]) - +++ NEW METHOD: PUBLIC(+) STATIC(+) io.opentelemetry.api.common.Value> of(java.util.Map>) -+++ NEW ENUM: PUBLIC(+) FINAL(+) io.opentelemetry.api.common.ValueType (compatible) - +++ CLASS FILE FORMAT VERSION: 52.0 <- n.a. - +++ NEW INTERFACE: java.lang.constant.Constable - +++ NEW INTERFACE: java.lang.Comparable - +++ NEW INTERFACE: java.io.Serializable - +++ NEW SUPERCLASS: java.lang.Enum - +++ NEW FIELD: PUBLIC(+) STATIC(+) FINAL(+) io.opentelemetry.api.common.ValueType BYTES - +++ NEW FIELD: PUBLIC(+) STATIC(+) FINAL(+) io.opentelemetry.api.common.ValueType ARRAY - +++ NEW FIELD: PUBLIC(+) STATIC(+) FINAL(+) io.opentelemetry.api.common.ValueType KEY_VALUE_LIST - +++ NEW FIELD: PUBLIC(+) STATIC(+) FINAL(+) io.opentelemetry.api.common.ValueType STRING - +++ NEW FIELD: PUBLIC(+) STATIC(+) FINAL(+) io.opentelemetry.api.common.ValueType DOUBLE - +++ NEW FIELD: PUBLIC(+) STATIC(+) FINAL(+) io.opentelemetry.api.common.ValueType BOOLEAN - +++ NEW FIELD: PUBLIC(+) STATIC(+) FINAL(+) io.opentelemetry.api.common.ValueType LONG - +++ NEW METHOD: PUBLIC(+) STATIC(+) io.opentelemetry.api.common.ValueType valueOf(java.lang.String) - +++ NEW METHOD: PUBLIC(+) STATIC(+) io.opentelemetry.api.common.ValueType[] values() -*** MODIFIED INTERFACE: PUBLIC ABSTRACT io.opentelemetry.api.logs.LogRecordBuilder (not serializable) - === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 - +++ NEW METHOD: PUBLIC(+) io.opentelemetry.api.logs.LogRecordBuilder setBody(io.opentelemetry.api.common.Value) +Comparing source compatibility of opentelemetry-api-1.43.0-SNAPSHOT.jar against opentelemetry-api-1.42.0.jar +No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-context.txt b/docs/apidiffs/current_vs_latest/opentelemetry-context.txt index 77ae369aa58..5fa60369247 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-context.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-context.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of opentelemetry-context-1.42.0-SNAPSHOT.jar against opentelemetry-context-1.41.0.jar +Comparing source compatibility of opentelemetry-context-1.43.0-SNAPSHOT.jar against opentelemetry-context-1.42.0.jar No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-common.txt b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-common.txt index bf7463bb94d..fb3e7390845 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-common.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-common.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of opentelemetry-exporter-common-1.42.0-SNAPSHOT.jar against opentelemetry-exporter-common-1.41.0.jar +Comparing source compatibility of opentelemetry-exporter-common-1.43.0-SNAPSHOT.jar against opentelemetry-exporter-common-1.42.0.jar No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-logging-otlp.txt b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-logging-otlp.txt index f2331f45543..dc7855fea00 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-logging-otlp.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-logging-otlp.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of opentelemetry-exporter-logging-otlp-1.42.0-SNAPSHOT.jar against opentelemetry-exporter-logging-otlp-1.41.0.jar +Comparing source compatibility of opentelemetry-exporter-logging-otlp-1.43.0-SNAPSHOT.jar against opentelemetry-exporter-logging-otlp-1.42.0.jar No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-logging.txt b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-logging.txt index aea459ed4c3..d7abe413fb7 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-logging.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-logging.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of opentelemetry-exporter-logging-1.42.0-SNAPSHOT.jar against opentelemetry-exporter-logging-1.41.0.jar +Comparing source compatibility of opentelemetry-exporter-logging-1.43.0-SNAPSHOT.jar against opentelemetry-exporter-logging-1.42.0.jar No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-otlp-common.txt b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-otlp-common.txt index 882fe7863b9..98e13c3968b 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-otlp-common.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-otlp-common.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of opentelemetry-exporter-otlp-common-1.42.0-SNAPSHOT.jar against opentelemetry-exporter-otlp-common-1.41.0.jar +Comparing source compatibility of opentelemetry-exporter-otlp-common-1.43.0-SNAPSHOT.jar against opentelemetry-exporter-otlp-common-1.42.0.jar No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-otlp.txt b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-otlp.txt index 4930adb418b..16843ef0141 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-otlp.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-otlp.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of opentelemetry-exporter-otlp-1.42.0-SNAPSHOT.jar against opentelemetry-exporter-otlp-1.41.0.jar +Comparing source compatibility of opentelemetry-exporter-otlp-1.43.0-SNAPSHOT.jar against opentelemetry-exporter-otlp-1.42.0.jar No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-sender-grpc-managed-channel.txt b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-sender-grpc-managed-channel.txt index b7f21f39fd2..21de48895ee 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-sender-grpc-managed-channel.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-sender-grpc-managed-channel.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of opentelemetry-exporter-sender-grpc-managed-channel-1.42.0-SNAPSHOT.jar against opentelemetry-exporter-sender-grpc-managed-channel-1.41.0.jar +Comparing source compatibility of opentelemetry-exporter-sender-grpc-managed-channel-1.43.0-SNAPSHOT.jar against opentelemetry-exporter-sender-grpc-managed-channel-1.42.0.jar No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-sender-jdk.txt b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-sender-jdk.txt index d83558fee87..203ebc9b40c 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-sender-jdk.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-sender-jdk.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of opentelemetry-exporter-sender-jdk-1.42.0-SNAPSHOT.jar against opentelemetry-exporter-sender-jdk-1.41.0.jar +Comparing source compatibility of opentelemetry-exporter-sender-jdk-1.43.0-SNAPSHOT.jar against opentelemetry-exporter-sender-jdk-1.42.0.jar No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-sender-okhttp.txt b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-sender-okhttp.txt index 5ac059f5f3d..275c68642af 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-sender-okhttp.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-sender-okhttp.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of opentelemetry-exporter-sender-okhttp-1.42.0-SNAPSHOT.jar against opentelemetry-exporter-sender-okhttp-1.41.0.jar +Comparing source compatibility of opentelemetry-exporter-sender-okhttp-1.43.0-SNAPSHOT.jar against opentelemetry-exporter-sender-okhttp-1.42.0.jar No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-zipkin.txt b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-zipkin.txt index 381d35e1b2d..f44eb5c177b 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-zipkin.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-zipkin.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of opentelemetry-exporter-zipkin-1.42.0-SNAPSHOT.jar against opentelemetry-exporter-zipkin-1.41.0.jar +Comparing source compatibility of opentelemetry-exporter-zipkin-1.43.0-SNAPSHOT.jar against opentelemetry-exporter-zipkin-1.42.0.jar No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-extension-kotlin.txt b/docs/apidiffs/current_vs_latest/opentelemetry-extension-kotlin.txt index 96b3803228a..9d2147d32d1 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-extension-kotlin.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-extension-kotlin.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of opentelemetry-extension-kotlin-1.42.0-SNAPSHOT.jar against opentelemetry-extension-kotlin-1.41.0.jar +Comparing source compatibility of opentelemetry-extension-kotlin-1.43.0-SNAPSHOT.jar against opentelemetry-extension-kotlin-1.42.0.jar No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-extension-trace-propagators.txt b/docs/apidiffs/current_vs_latest/opentelemetry-extension-trace-propagators.txt index 526c3eff1fa..9d47b0f73c3 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-extension-trace-propagators.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-extension-trace-propagators.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of opentelemetry-extension-trace-propagators-1.42.0-SNAPSHOT.jar against opentelemetry-extension-trace-propagators-1.41.0.jar +Comparing source compatibility of opentelemetry-extension-trace-propagators-1.43.0-SNAPSHOT.jar against opentelemetry-extension-trace-propagators-1.42.0.jar No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-opentracing-shim.txt b/docs/apidiffs/current_vs_latest/opentelemetry-opentracing-shim.txt index 3f380a6ab35..d543d84783c 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-opentracing-shim.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-opentracing-shim.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of opentelemetry-opentracing-shim-1.42.0-SNAPSHOT.jar against opentelemetry-opentracing-shim-1.41.0.jar +Comparing source compatibility of opentelemetry-opentracing-shim-1.43.0-SNAPSHOT.jar against opentelemetry-opentracing-shim-1.42.0.jar No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-common.txt b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-common.txt index 4a11449c46c..f7f5e800cad 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-common.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-common.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of opentelemetry-sdk-common-1.42.0-SNAPSHOT.jar against opentelemetry-sdk-common-1.41.0.jar +Comparing source compatibility of opentelemetry-sdk-common-1.43.0-SNAPSHOT.jar against opentelemetry-sdk-common-1.42.0.jar No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-extension-autoconfigure-spi.txt b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-extension-autoconfigure-spi.txt index 4ea59eeeb08..2af1a4c5b30 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-extension-autoconfigure-spi.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-extension-autoconfigure-spi.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of opentelemetry-sdk-extension-autoconfigure-spi-1.42.0-SNAPSHOT.jar against opentelemetry-sdk-extension-autoconfigure-spi-1.41.0.jar +Comparing source compatibility of opentelemetry-sdk-extension-autoconfigure-spi-1.43.0-SNAPSHOT.jar against opentelemetry-sdk-extension-autoconfigure-spi-1.42.0.jar No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-extension-autoconfigure.txt b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-extension-autoconfigure.txt index 39ad67087a2..8d051c5e8c1 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-extension-autoconfigure.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-extension-autoconfigure.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of opentelemetry-sdk-extension-autoconfigure-1.42.0-SNAPSHOT.jar against opentelemetry-sdk-extension-autoconfigure-1.41.0.jar +Comparing source compatibility of opentelemetry-sdk-extension-autoconfigure-1.43.0-SNAPSHOT.jar against opentelemetry-sdk-extension-autoconfigure-1.42.0.jar No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-extension-jaeger-remote-sampler.txt b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-extension-jaeger-remote-sampler.txt index ee9075dca1c..c9fc3ad2546 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-extension-jaeger-remote-sampler.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-extension-jaeger-remote-sampler.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of opentelemetry-sdk-extension-jaeger-remote-sampler-1.42.0-SNAPSHOT.jar against opentelemetry-sdk-extension-jaeger-remote-sampler-1.41.0.jar +Comparing source compatibility of opentelemetry-sdk-extension-jaeger-remote-sampler-1.43.0-SNAPSHOT.jar against opentelemetry-sdk-extension-jaeger-remote-sampler-1.42.0.jar No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-logs.txt b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-logs.txt index b096d42eb98..fa9c85da1d4 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-logs.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-logs.txt @@ -1,15 +1,2 @@ -Comparing source compatibility of opentelemetry-sdk-logs-1.42.0-SNAPSHOT.jar against opentelemetry-sdk-logs-1.41.0.jar -=== UNCHANGED INTERFACE: PUBLIC ABSTRACT io.opentelemetry.sdk.logs.data.Body (not serializable) - === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 - === UNCHANGED METHOD: PUBLIC ABSTRACT io.opentelemetry.sdk.logs.data.Body$Type getType() - +++ NEW ANNOTATION: java.lang.Deprecated - +++ NEW ANNOTATION: java.lang.Deprecated -=== UNCHANGED ENUM: PUBLIC STATIC FINAL io.opentelemetry.sdk.logs.data.Body$Type (compatible) - === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 - +++ NEW ANNOTATION: java.lang.Deprecated -*** MODIFIED INTERFACE: PUBLIC ABSTRACT io.opentelemetry.sdk.logs.data.LogRecordData (not serializable) - === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 - === UNCHANGED METHOD: PUBLIC ABSTRACT io.opentelemetry.sdk.logs.data.Body getBody() - +++ NEW ANNOTATION: java.lang.Deprecated - +++ NEW METHOD: PUBLIC(+) io.opentelemetry.api.common.Value getBodyValue() - +++ NEW ANNOTATION: javax.annotation.Nullable +Comparing source compatibility of opentelemetry-sdk-logs-1.43.0-SNAPSHOT.jar against opentelemetry-sdk-logs-1.42.0.jar +No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-metrics.txt b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-metrics.txt index b0c177298f5..8979de6e159 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-metrics.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-metrics.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of opentelemetry-sdk-metrics-1.42.0-SNAPSHOT.jar against opentelemetry-sdk-metrics-1.41.0.jar +Comparing source compatibility of opentelemetry-sdk-metrics-1.43.0-SNAPSHOT.jar against opentelemetry-sdk-metrics-1.42.0.jar No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-testing.txt b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-testing.txt index 4d359472772..a7ccc6eabb7 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-testing.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-testing.txt @@ -1,26 +1,2 @@ -Comparing source compatibility of opentelemetry-sdk-testing-1.42.0-SNAPSHOT.jar against opentelemetry-sdk-testing-1.41.0.jar -*** MODIFIED CLASS: PUBLIC FINAL io.opentelemetry.sdk.testing.assertj.LogRecordDataAssert (not serializable) - === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 - +++ NEW METHOD: PUBLIC(+) io.opentelemetry.sdk.testing.assertj.LogRecordDataAssert hasBody(io.opentelemetry.api.common.Value) - +++ NEW METHOD: PUBLIC(+) io.opentelemetry.sdk.testing.assertj.LogRecordDataAssert hasBodyField(java.lang.String, java.lang.String) - +++ NEW METHOD: PUBLIC(+) io.opentelemetry.sdk.testing.assertj.LogRecordDataAssert hasBodyField(java.lang.String, long) - +++ NEW METHOD: PUBLIC(+) io.opentelemetry.sdk.testing.assertj.LogRecordDataAssert hasBodyField(java.lang.String, double) - +++ NEW METHOD: PUBLIC(+) io.opentelemetry.sdk.testing.assertj.LogRecordDataAssert hasBodyField(java.lang.String, boolean) - +++ NEW METHOD: PUBLIC(+) io.opentelemetry.sdk.testing.assertj.LogRecordDataAssert hasBodyField(java.lang.String, java.lang.String[]) - +++ NEW METHOD: PUBLIC(+) io.opentelemetry.sdk.testing.assertj.LogRecordDataAssert hasBodyField(java.lang.String, long[]) - +++ NEW METHOD: PUBLIC(+) io.opentelemetry.sdk.testing.assertj.LogRecordDataAssert hasBodyField(java.lang.String, double[]) - +++ NEW METHOD: PUBLIC(+) io.opentelemetry.sdk.testing.assertj.LogRecordDataAssert hasBodyField(java.lang.String, boolean[]) - +++ NEW METHOD: PUBLIC(+) io.opentelemetry.sdk.testing.assertj.LogRecordDataAssert hasBodyField(java.lang.String, io.opentelemetry.api.common.Value) - +++ NEW METHOD: PUBLIC(+) io.opentelemetry.sdk.testing.assertj.LogRecordDataAssert hasBodyField(io.opentelemetry.api.common.AttributeKey, java.lang.Object) - GENERIC TEMPLATES: +++ T:java.lang.Object -**** MODIFIED CLASS: PUBLIC ABSTRACT io.opentelemetry.sdk.testing.logs.TestLogRecordData (not serializable) - === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 - +++ NEW METHOD: PUBLIC(+) io.opentelemetry.sdk.logs.data.Body getBody() - +++ NEW ANNOTATION: java.lang.Deprecated - +++* NEW METHOD: PUBLIC(+) ABSTRACT(+) io.opentelemetry.api.common.Value getBodyValue() - +++ NEW ANNOTATION: javax.annotation.Nullable -**** MODIFIED CLASS: PUBLIC ABSTRACT STATIC io.opentelemetry.sdk.testing.logs.TestLogRecordData$Builder (not serializable) - === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 - *** MODIFIED METHOD: PUBLIC (<- PACKAGE_PROTECTED) NON_ABSTRACT (<- ABSTRACT) io.opentelemetry.sdk.testing.logs.TestLogRecordData$Builder setBody(io.opentelemetry.sdk.logs.data.Body) - +++ NEW ANNOTATION: java.lang.Deprecated - +++* NEW METHOD: PUBLIC(+) ABSTRACT(+) io.opentelemetry.sdk.testing.logs.TestLogRecordData$Builder setBodyValue(io.opentelemetry.api.common.Value) +Comparing source compatibility of opentelemetry-sdk-testing-1.43.0-SNAPSHOT.jar against opentelemetry-sdk-testing-1.42.0.jar +No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-trace.txt b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-trace.txt index 98ead6c6c5b..266b05b06f1 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-trace.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-trace.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of opentelemetry-sdk-trace-1.42.0-SNAPSHOT.jar against opentelemetry-sdk-trace-1.41.0.jar +Comparing source compatibility of opentelemetry-sdk-trace-1.43.0-SNAPSHOT.jar against opentelemetry-sdk-trace-1.42.0.jar No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-sdk.txt b/docs/apidiffs/current_vs_latest/opentelemetry-sdk.txt index ac51a9a4d98..dcbd3ecaa3f 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-sdk.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-sdk.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of opentelemetry-sdk-1.42.0-SNAPSHOT.jar against opentelemetry-sdk-1.41.0.jar +Comparing source compatibility of opentelemetry-sdk-1.43.0-SNAPSHOT.jar against opentelemetry-sdk-1.42.0.jar No changes. \ No newline at end of file From 9ddccada89ff974e8e2c765ce15367b352a2c059 Mon Sep 17 00:00:00 2001 From: jack-berg <34418638+jack-berg@users.noreply.github.com> Date: Mon, 9 Sep 2024 21:02:28 -0500 Subject: [PATCH 556/901] Stop publishing test fixtures with opentelemetry-api (#6695) --- api/all/build.gradle.kts | 7 ++----- .../opentelemetry/api/OpenTelemetryTest.java | 1 + .../api/logs/DefaultLoggerTest.java | 2 ++ .../api/metrics/DefaultMeterTest.java | 2 ++ .../api/trace/DefaultTracerTest.java | 2 ++ api/incubator/build.gradle.kts | 2 +- .../incubator/ExtendedOpenTelemetryTest.java | 2 +- .../logs/ExtendedDefaultLoggerTest.java | 2 +- .../metrics/ExtendedDefaultMeterTest.java | 2 +- .../trace/ExtendedDefaultTracerTest.java | 2 +- api/testing-internal/build.gradle.kts | 21 +++++++++++++++++++ .../internal}/AbstractDefaultLoggerTest.java | 7 +++++-- .../internal}/AbstractDefaultMeterTest.java | 17 +++++++++++++-- .../internal}/AbstractDefaultTracerTest.java | 13 ++++++++++-- .../internal}/AbstractOpenTelemetryTest.java | 10 ++++++--- settings.gradle.kts | 1 + 16 files changed, 74 insertions(+), 19 deletions(-) create mode 100644 api/testing-internal/build.gradle.kts rename api/{all/src/testFixtures/java/io/opentelemetry/api/logs => testing-internal/src/main/java/io/opentelemetry/api/testing/internal}/AbstractDefaultLoggerTest.java (90%) rename api/{all/src/testFixtures/java/io/opentelemetry/api/metrics => testing-internal/src/main/java/io/opentelemetry/api/testing/internal}/AbstractDefaultMeterTest.java (90%) rename api/{all/src/testFixtures/java/io/opentelemetry/api/trace => testing-internal/src/main/java/io/opentelemetry/api/testing/internal}/AbstractDefaultTracerTest.java (92%) rename api/{all/src/testFixtures/java/io/opentelemetry/api => testing-internal/src/main/java/io/opentelemetry/api/testing/internal}/AbstractOpenTelemetryTest.java (92%) diff --git a/api/all/build.gradle.kts b/api/all/build.gradle.kts index 6ade72dfd88..ad6896387d8 100644 --- a/api/all/build.gradle.kts +++ b/api/all/build.gradle.kts @@ -1,7 +1,6 @@ plugins { id("otel.java-conventions") id("otel.publish-conventions") - id("java-test-fixtures") id("otel.jmh-conventions") id("otel.animalsniffer-conventions") @@ -16,12 +15,10 @@ dependencies { annotationProcessor("com.google.auto.value:auto-value") + testImplementation(project(":api:testing-internal")) + testImplementation("edu.berkeley.cs.jqf:jqf-fuzz") testImplementation("com.google.guava:guava-testlib") - testFixturesApi(project(":testing-internal")) - testFixturesApi("junit:junit") - testFixturesApi("org.assertj:assertj-core") - testFixturesApi("org.mockito:mockito-core") } tasks.test { diff --git a/api/all/src/test/java/io/opentelemetry/api/OpenTelemetryTest.java b/api/all/src/test/java/io/opentelemetry/api/OpenTelemetryTest.java index c3754a6df3b..f985cffe2ed 100644 --- a/api/all/src/test/java/io/opentelemetry/api/OpenTelemetryTest.java +++ b/api/all/src/test/java/io/opentelemetry/api/OpenTelemetryTest.java @@ -7,6 +7,7 @@ import io.opentelemetry.api.logs.LoggerProvider; import io.opentelemetry.api.metrics.MeterProvider; +import io.opentelemetry.api.testing.internal.AbstractOpenTelemetryTest; import io.opentelemetry.api.trace.TracerProvider; class OpenTelemetryTest extends AbstractOpenTelemetryTest { diff --git a/api/all/src/test/java/io/opentelemetry/api/logs/DefaultLoggerTest.java b/api/all/src/test/java/io/opentelemetry/api/logs/DefaultLoggerTest.java index 436baee524c..10b43897a3e 100644 --- a/api/all/src/test/java/io/opentelemetry/api/logs/DefaultLoggerTest.java +++ b/api/all/src/test/java/io/opentelemetry/api/logs/DefaultLoggerTest.java @@ -5,6 +5,8 @@ package io.opentelemetry.api.logs; +import io.opentelemetry.api.testing.internal.AbstractDefaultLoggerTest; + class DefaultLoggerTest extends AbstractDefaultLoggerTest { @Override diff --git a/api/all/src/test/java/io/opentelemetry/api/metrics/DefaultMeterTest.java b/api/all/src/test/java/io/opentelemetry/api/metrics/DefaultMeterTest.java index 1b012be1d55..69b32d5ecc0 100644 --- a/api/all/src/test/java/io/opentelemetry/api/metrics/DefaultMeterTest.java +++ b/api/all/src/test/java/io/opentelemetry/api/metrics/DefaultMeterTest.java @@ -5,6 +5,8 @@ package io.opentelemetry.api.metrics; +import io.opentelemetry.api.testing.internal.AbstractDefaultMeterTest; + public class DefaultMeterTest extends AbstractDefaultMeterTest { @Override diff --git a/api/all/src/test/java/io/opentelemetry/api/trace/DefaultTracerTest.java b/api/all/src/test/java/io/opentelemetry/api/trace/DefaultTracerTest.java index f0f577d9946..b6736fa3843 100644 --- a/api/all/src/test/java/io/opentelemetry/api/trace/DefaultTracerTest.java +++ b/api/all/src/test/java/io/opentelemetry/api/trace/DefaultTracerTest.java @@ -5,6 +5,8 @@ package io.opentelemetry.api.trace; +import io.opentelemetry.api.testing.internal.AbstractDefaultTracerTest; + class DefaultTracerTest extends AbstractDefaultTracerTest { @Override diff --git a/api/incubator/build.gradle.kts b/api/incubator/build.gradle.kts index b28295de6d0..bdf12950acf 100644 --- a/api/incubator/build.gradle.kts +++ b/api/incubator/build.gradle.kts @@ -15,7 +15,7 @@ dependencies { annotationProcessor("com.google.auto.value:auto-value") testImplementation(project(":sdk:testing")) - testImplementation(testFixtures(project(":api:all"))) + testImplementation(project(":api:testing-internal")) testImplementation("io.opentelemetry.semconv:opentelemetry-semconv-incubating") diff --git a/api/incubator/src/test/java/io/opentelemetry/api/incubator/ExtendedOpenTelemetryTest.java b/api/incubator/src/test/java/io/opentelemetry/api/incubator/ExtendedOpenTelemetryTest.java index b33c29c8194..4903d00c2e6 100644 --- a/api/incubator/src/test/java/io/opentelemetry/api/incubator/ExtendedOpenTelemetryTest.java +++ b/api/incubator/src/test/java/io/opentelemetry/api/incubator/ExtendedOpenTelemetryTest.java @@ -7,7 +7,6 @@ import static org.assertj.core.api.Assertions.assertThat; -import io.opentelemetry.api.AbstractOpenTelemetryTest; import io.opentelemetry.api.OpenTelemetry; import io.opentelemetry.api.incubator.logs.ExtendedDefaultLoggerProvider; import io.opentelemetry.api.incubator.logs.ExtendedLogger; @@ -17,6 +16,7 @@ import io.opentelemetry.api.incubator.trace.ExtendedTracer; import io.opentelemetry.api.logs.LoggerProvider; import io.opentelemetry.api.metrics.MeterProvider; +import io.opentelemetry.api.testing.internal.AbstractOpenTelemetryTest; import io.opentelemetry.api.trace.TracerProvider; import io.opentelemetry.context.propagation.ContextPropagators; import org.junit.jupiter.api.Test; diff --git a/api/incubator/src/test/java/io/opentelemetry/api/incubator/logs/ExtendedDefaultLoggerTest.java b/api/incubator/src/test/java/io/opentelemetry/api/incubator/logs/ExtendedDefaultLoggerTest.java index e558b53fcf1..e92a3c160a6 100644 --- a/api/incubator/src/test/java/io/opentelemetry/api/incubator/logs/ExtendedDefaultLoggerTest.java +++ b/api/incubator/src/test/java/io/opentelemetry/api/incubator/logs/ExtendedDefaultLoggerTest.java @@ -8,9 +8,9 @@ import static org.assertj.core.api.Assertions.assertThat; import io.opentelemetry.api.common.Value; -import io.opentelemetry.api.logs.AbstractDefaultLoggerTest; import io.opentelemetry.api.logs.Logger; import io.opentelemetry.api.logs.LoggerProvider; +import io.opentelemetry.api.testing.internal.AbstractDefaultLoggerTest; import org.junit.jupiter.api.Test; class ExtendedDefaultLoggerTest extends AbstractDefaultLoggerTest { diff --git a/api/incubator/src/test/java/io/opentelemetry/api/incubator/metrics/ExtendedDefaultMeterTest.java b/api/incubator/src/test/java/io/opentelemetry/api/incubator/metrics/ExtendedDefaultMeterTest.java index 3d342a33661..a56a8740b04 100644 --- a/api/incubator/src/test/java/io/opentelemetry/api/incubator/metrics/ExtendedDefaultMeterTest.java +++ b/api/incubator/src/test/java/io/opentelemetry/api/incubator/metrics/ExtendedDefaultMeterTest.java @@ -8,9 +8,9 @@ import static org.assertj.core.api.Assertions.assertThat; import io.opentelemetry.api.OpenTelemetry; -import io.opentelemetry.api.metrics.AbstractDefaultMeterTest; import io.opentelemetry.api.metrics.Meter; import io.opentelemetry.api.metrics.MeterProvider; +import io.opentelemetry.api.testing.internal.AbstractDefaultMeterTest; import org.assertj.core.api.Assertions; import org.junit.jupiter.api.Test; diff --git a/api/incubator/src/test/java/io/opentelemetry/api/incubator/trace/ExtendedDefaultTracerTest.java b/api/incubator/src/test/java/io/opentelemetry/api/incubator/trace/ExtendedDefaultTracerTest.java index 1550796d42d..791c6b7d47c 100644 --- a/api/incubator/src/test/java/io/opentelemetry/api/incubator/trace/ExtendedDefaultTracerTest.java +++ b/api/incubator/src/test/java/io/opentelemetry/api/incubator/trace/ExtendedDefaultTracerTest.java @@ -8,7 +8,7 @@ import static org.assertj.core.api.Assertions.assertThat; import io.opentelemetry.api.OpenTelemetry; -import io.opentelemetry.api.trace.AbstractDefaultTracerTest; +import io.opentelemetry.api.testing.internal.AbstractDefaultTracerTest; import io.opentelemetry.api.trace.Tracer; import io.opentelemetry.api.trace.TracerProvider; import org.junit.jupiter.api.Test; diff --git a/api/testing-internal/build.gradle.kts b/api/testing-internal/build.gradle.kts new file mode 100644 index 00000000000..b3e79cf0cfe --- /dev/null +++ b/api/testing-internal/build.gradle.kts @@ -0,0 +1,21 @@ +plugins { + id("otel.java-conventions") +} + +description = "OpenTelemetry API Testing (Internal)" +otelJava.moduleName.set("io.opentelemetry.api.testing.internal") + +dependencies { + api(project(":api:all")) + + implementation(project(":testing-internal")) + + implementation("com.linecorp.armeria:armeria-junit5") + implementation("org.assertj:assertj-core") + implementation("org.mockito:mockito-core") +} + +// Skip OWASP dependencyCheck task on test module +dependencyCheck { + skip = true +} diff --git a/api/all/src/testFixtures/java/io/opentelemetry/api/logs/AbstractDefaultLoggerTest.java b/api/testing-internal/src/main/java/io/opentelemetry/api/testing/internal/AbstractDefaultLoggerTest.java similarity index 90% rename from api/all/src/testFixtures/java/io/opentelemetry/api/logs/AbstractDefaultLoggerTest.java rename to api/testing-internal/src/main/java/io/opentelemetry/api/testing/internal/AbstractDefaultLoggerTest.java index 88ecb74809a..82d9f0b1f67 100644 --- a/api/all/src/testFixtures/java/io/opentelemetry/api/logs/AbstractDefaultLoggerTest.java +++ b/api/testing-internal/src/main/java/io/opentelemetry/api/testing/internal/AbstractDefaultLoggerTest.java @@ -3,7 +3,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -package io.opentelemetry.api.logs; +package io.opentelemetry.api.testing.internal; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatCode; @@ -11,12 +11,15 @@ import io.opentelemetry.api.common.AttributeKey; import io.opentelemetry.api.common.Attributes; import io.opentelemetry.api.common.Value; +import io.opentelemetry.api.logs.Logger; +import io.opentelemetry.api.logs.LoggerProvider; +import io.opentelemetry.api.logs.Severity; import io.opentelemetry.context.Context; import java.time.Instant; import java.util.concurrent.TimeUnit; import org.junit.jupiter.api.Test; -/** Unit tests for {@link DefaultLogger}. */ +/** Unit tests for No-op {@link Logger}. */ public abstract class AbstractDefaultLoggerTest { protected abstract LoggerProvider getLoggerProvider(); diff --git a/api/all/src/testFixtures/java/io/opentelemetry/api/metrics/AbstractDefaultMeterTest.java b/api/testing-internal/src/main/java/io/opentelemetry/api/testing/internal/AbstractDefaultMeterTest.java similarity index 90% rename from api/all/src/testFixtures/java/io/opentelemetry/api/metrics/AbstractDefaultMeterTest.java rename to api/testing-internal/src/main/java/io/opentelemetry/api/testing/internal/AbstractDefaultMeterTest.java index b64c0929803..b96de557c42 100644 --- a/api/all/src/testFixtures/java/io/opentelemetry/api/metrics/AbstractDefaultMeterTest.java +++ b/api/testing-internal/src/main/java/io/opentelemetry/api/testing/internal/AbstractDefaultMeterTest.java @@ -3,16 +3,28 @@ * SPDX-License-Identifier: Apache-2.0 */ -package io.opentelemetry.api.metrics; +package io.opentelemetry.api.testing.internal; import static io.opentelemetry.api.common.AttributeKey.stringKey; import io.opentelemetry.api.common.Attributes; +import io.opentelemetry.api.metrics.DoubleCounter; +import io.opentelemetry.api.metrics.DoubleGauge; +import io.opentelemetry.api.metrics.DoubleHistogram; +import io.opentelemetry.api.metrics.DoubleUpDownCounter; +import io.opentelemetry.api.metrics.LongCounter; +import io.opentelemetry.api.metrics.LongGauge; +import io.opentelemetry.api.metrics.LongHistogram; +import io.opentelemetry.api.metrics.LongUpDownCounter; +import io.opentelemetry.api.metrics.Meter; +import io.opentelemetry.api.metrics.MeterProvider; +import io.opentelemetry.api.metrics.ObservableDoubleMeasurement; +import io.opentelemetry.api.metrics.ObservableLongMeasurement; import io.opentelemetry.context.Context; import io.opentelemetry.internal.testing.slf4j.SuppressLogger; import org.junit.jupiter.api.Test; -/** Unit tests for {@link DefaultMeter}. */ +/** Unit tests for No-op {@link Meter}. */ @SuppressLogger() public abstract class AbstractDefaultMeterTest { private final Meter meter = getMeter(); @@ -245,6 +257,7 @@ void noopObservableDoubleUpDownCounter_doesNotThrow() { } @Test + @SuppressWarnings("NullAway") void noopBatchCallback_doesNotThrow() { meter.batchCallback(() -> {}, null); } diff --git a/api/all/src/testFixtures/java/io/opentelemetry/api/trace/AbstractDefaultTracerTest.java b/api/testing-internal/src/main/java/io/opentelemetry/api/testing/internal/AbstractDefaultTracerTest.java similarity index 92% rename from api/all/src/testFixtures/java/io/opentelemetry/api/trace/AbstractDefaultTracerTest.java rename to api/testing-internal/src/main/java/io/opentelemetry/api/testing/internal/AbstractDefaultTracerTest.java index 1933e289d5b..c90b7da21d9 100644 --- a/api/all/src/testFixtures/java/io/opentelemetry/api/trace/AbstractDefaultTracerTest.java +++ b/api/testing-internal/src/main/java/io/opentelemetry/api/testing/internal/AbstractDefaultTracerTest.java @@ -3,7 +3,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -package io.opentelemetry.api.trace; +package io.opentelemetry.api.testing.internal; import static io.opentelemetry.api.common.AttributeKey.stringKey; import static org.assertj.core.api.Assertions.assertThat; @@ -11,12 +11,19 @@ import io.opentelemetry.api.common.AttributeKey; import io.opentelemetry.api.common.Attributes; +import io.opentelemetry.api.trace.Span; +import io.opentelemetry.api.trace.SpanBuilder; +import io.opentelemetry.api.trace.SpanContext; +import io.opentelemetry.api.trace.TraceFlags; +import io.opentelemetry.api.trace.TraceState; +import io.opentelemetry.api.trace.Tracer; +import io.opentelemetry.api.trace.TracerProvider; import io.opentelemetry.context.Context; import java.time.Instant; import java.util.concurrent.TimeUnit; import org.junit.jupiter.api.Test; -/** Unit tests for {@link DefaultTracer}. */ +/** Unit tests for No-op {@link Tracer}. */ // Need to suppress warnings for MustBeClosed because Android 14 does not support // try-with-resources. @SuppressWarnings("MustBeClosedChecker") @@ -56,6 +63,7 @@ void defaultSpanBuilderWithName() { } @Test + @SuppressWarnings("NullAway") void spanContextPropagationExplicitParent() { assertThat( defaultTracer @@ -109,6 +117,7 @@ void spanContextPropagation_fromContextThenNoParent() { } @Test + @SuppressWarnings("NullAway") void doNotCrash_NoopImplementation() { assertThatCode( () -> { diff --git a/api/all/src/testFixtures/java/io/opentelemetry/api/AbstractOpenTelemetryTest.java b/api/testing-internal/src/main/java/io/opentelemetry/api/testing/internal/AbstractOpenTelemetryTest.java similarity index 92% rename from api/all/src/testFixtures/java/io/opentelemetry/api/AbstractOpenTelemetryTest.java rename to api/testing-internal/src/main/java/io/opentelemetry/api/testing/internal/AbstractOpenTelemetryTest.java index 6ba27d89760..4223d853661 100644 --- a/api/all/src/testFixtures/java/io/opentelemetry/api/AbstractOpenTelemetryTest.java +++ b/api/testing-internal/src/main/java/io/opentelemetry/api/testing/internal/AbstractOpenTelemetryTest.java @@ -3,11 +3,13 @@ * SPDX-License-Identifier: Apache-2.0 */ -package io.opentelemetry.api; +package io.opentelemetry.api.testing.internal; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; +import io.opentelemetry.api.GlobalOpenTelemetry; +import io.opentelemetry.api.OpenTelemetry; import io.opentelemetry.api.logs.LoggerProvider; import io.opentelemetry.api.metrics.MeterProvider; import io.opentelemetry.api.trace.TracerProvider; @@ -17,8 +19,9 @@ import org.junit.jupiter.api.Test; import org.mockito.Mockito; -/** Unit tests for {@link OpenTelemetry}. */ +/** Unit tests for No-op {@link OpenTelemetry}. */ public abstract class AbstractOpenTelemetryTest { + @BeforeAll public static void beforeClass() { GlobalOpenTelemetry.resetForTest(); @@ -96,7 +99,8 @@ void setThenSet() { @Test void getThenSet() { - assertThat(getGlobalOpenTelemetry()).isInstanceOf(DefaultOpenTelemetry.class); + assertThat(getGlobalOpenTelemetry().getClass().getName()) + .isEqualTo("io.opentelemetry.api.DefaultOpenTelemetry"); assertThatThrownBy(() -> GlobalOpenTelemetry.set(getOpenTelemetry())) .isInstanceOf(IllegalStateException.class) .hasMessageContaining("GlobalOpenTelemetry.set has already been called") diff --git a/settings.gradle.kts b/settings.gradle.kts index 4bf7ca86538..12121e5094a 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -25,6 +25,7 @@ rootProject.name = "opentelemetry-java" include(":all") include(":api:all") include(":api:incubator") +include(":api:testing-internal") include(":bom") include(":bom-alpha") include(":context") From a55e9b6440057fb50db9908ec072086a7a4b3c95 Mon Sep 17 00:00:00 2001 From: OpenTelemetry Bot <107717825+opentelemetrybot@users.noreply.github.com> Date: Tue, 10 Sep 2024 10:25:06 -0500 Subject: [PATCH 557/901] Merge change log updates from release/v1.42.x (#6707) --- CHANGELOG.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1ee1f4922a0..74beb601dd6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,13 @@ ## Unreleased +## Version 1.42.1 (2024-09-10) + +### API + +* Revert `java-test-fixtures` plugin to remove test dependencies from `pom.xml`. + ([#6695](https://github.com/open-telemetry/opentelemetry-java/pull/6695)) + ## Version 1.42.0 (2024-09-06) ### API From 0feca55ee2fb7e7c894c587511ca0bbaed177d38 Mon Sep 17 00:00:00 2001 From: OpenTelemetry Bot <107717825+opentelemetrybot@users.noreply.github.com> Date: Wed, 11 Sep 2024 09:16:39 -0500 Subject: [PATCH 558/901] Post release for version 1.42.0 (#6711) --- docs/apidiffs/current_vs_latest/opentelemetry-api.txt | 2 +- docs/apidiffs/current_vs_latest/opentelemetry-context.txt | 2 +- .../current_vs_latest/opentelemetry-exporter-common.txt | 2 +- .../current_vs_latest/opentelemetry-exporter-logging-otlp.txt | 2 +- .../current_vs_latest/opentelemetry-exporter-logging.txt | 2 +- .../current_vs_latest/opentelemetry-exporter-otlp-common.txt | 2 +- docs/apidiffs/current_vs_latest/opentelemetry-exporter-otlp.txt | 2 +- .../opentelemetry-exporter-sender-grpc-managed-channel.txt | 2 +- .../current_vs_latest/opentelemetry-exporter-sender-jdk.txt | 2 +- .../current_vs_latest/opentelemetry-exporter-sender-okhttp.txt | 2 +- .../current_vs_latest/opentelemetry-exporter-zipkin.txt | 2 +- .../current_vs_latest/opentelemetry-extension-kotlin.txt | 2 +- .../opentelemetry-extension-trace-propagators.txt | 2 +- .../current_vs_latest/opentelemetry-opentracing-shim.txt | 2 +- docs/apidiffs/current_vs_latest/opentelemetry-sdk-common.txt | 2 +- .../opentelemetry-sdk-extension-autoconfigure-spi.txt | 2 +- .../opentelemetry-sdk-extension-autoconfigure.txt | 2 +- .../opentelemetry-sdk-extension-jaeger-remote-sampler.txt | 2 +- docs/apidiffs/current_vs_latest/opentelemetry-sdk-logs.txt | 2 +- docs/apidiffs/current_vs_latest/opentelemetry-sdk-metrics.txt | 2 +- docs/apidiffs/current_vs_latest/opentelemetry-sdk-testing.txt | 2 +- docs/apidiffs/current_vs_latest/opentelemetry-sdk-trace.txt | 2 +- docs/apidiffs/current_vs_latest/opentelemetry-sdk.txt | 2 +- 23 files changed, 23 insertions(+), 23 deletions(-) diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-api.txt b/docs/apidiffs/current_vs_latest/opentelemetry-api.txt index d9de410b484..547ea83e519 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-api.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-api.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of opentelemetry-api-1.43.0-SNAPSHOT.jar against opentelemetry-api-1.42.0.jar +Comparing source compatibility of opentelemetry-api-1.43.0-SNAPSHOT.jar against opentelemetry-api-1.42.1.jar No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-context.txt b/docs/apidiffs/current_vs_latest/opentelemetry-context.txt index 5fa60369247..c861601babb 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-context.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-context.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of opentelemetry-context-1.43.0-SNAPSHOT.jar against opentelemetry-context-1.42.0.jar +Comparing source compatibility of opentelemetry-context-1.43.0-SNAPSHOT.jar against opentelemetry-context-1.42.1.jar No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-common.txt b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-common.txt index fb3e7390845..9e03ebcd3c3 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-common.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-common.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of opentelemetry-exporter-common-1.43.0-SNAPSHOT.jar against opentelemetry-exporter-common-1.42.0.jar +Comparing source compatibility of opentelemetry-exporter-common-1.43.0-SNAPSHOT.jar against opentelemetry-exporter-common-1.42.1.jar No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-logging-otlp.txt b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-logging-otlp.txt index dc7855fea00..58fedf2a521 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-logging-otlp.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-logging-otlp.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of opentelemetry-exporter-logging-otlp-1.43.0-SNAPSHOT.jar against opentelemetry-exporter-logging-otlp-1.42.0.jar +Comparing source compatibility of opentelemetry-exporter-logging-otlp-1.43.0-SNAPSHOT.jar against opentelemetry-exporter-logging-otlp-1.42.1.jar No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-logging.txt b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-logging.txt index d7abe413fb7..c893f199396 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-logging.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-logging.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of opentelemetry-exporter-logging-1.43.0-SNAPSHOT.jar against opentelemetry-exporter-logging-1.42.0.jar +Comparing source compatibility of opentelemetry-exporter-logging-1.43.0-SNAPSHOT.jar against opentelemetry-exporter-logging-1.42.1.jar No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-otlp-common.txt b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-otlp-common.txt index 98e13c3968b..4e744fdd9ac 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-otlp-common.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-otlp-common.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of opentelemetry-exporter-otlp-common-1.43.0-SNAPSHOT.jar against opentelemetry-exporter-otlp-common-1.42.0.jar +Comparing source compatibility of opentelemetry-exporter-otlp-common-1.43.0-SNAPSHOT.jar against opentelemetry-exporter-otlp-common-1.42.1.jar No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-otlp.txt b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-otlp.txt index 16843ef0141..7b0edf4faa9 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-otlp.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-otlp.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of opentelemetry-exporter-otlp-1.43.0-SNAPSHOT.jar against opentelemetry-exporter-otlp-1.42.0.jar +Comparing source compatibility of opentelemetry-exporter-otlp-1.43.0-SNAPSHOT.jar against opentelemetry-exporter-otlp-1.42.1.jar No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-sender-grpc-managed-channel.txt b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-sender-grpc-managed-channel.txt index 21de48895ee..b7a41b5c2d0 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-sender-grpc-managed-channel.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-sender-grpc-managed-channel.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of opentelemetry-exporter-sender-grpc-managed-channel-1.43.0-SNAPSHOT.jar against opentelemetry-exporter-sender-grpc-managed-channel-1.42.0.jar +Comparing source compatibility of opentelemetry-exporter-sender-grpc-managed-channel-1.43.0-SNAPSHOT.jar against opentelemetry-exporter-sender-grpc-managed-channel-1.42.1.jar No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-sender-jdk.txt b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-sender-jdk.txt index 203ebc9b40c..2440c50dc8a 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-sender-jdk.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-sender-jdk.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of opentelemetry-exporter-sender-jdk-1.43.0-SNAPSHOT.jar against opentelemetry-exporter-sender-jdk-1.42.0.jar +Comparing source compatibility of opentelemetry-exporter-sender-jdk-1.43.0-SNAPSHOT.jar against opentelemetry-exporter-sender-jdk-1.42.1.jar No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-sender-okhttp.txt b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-sender-okhttp.txt index 275c68642af..dfa3073e783 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-sender-okhttp.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-sender-okhttp.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of opentelemetry-exporter-sender-okhttp-1.43.0-SNAPSHOT.jar against opentelemetry-exporter-sender-okhttp-1.42.0.jar +Comparing source compatibility of opentelemetry-exporter-sender-okhttp-1.43.0-SNAPSHOT.jar against opentelemetry-exporter-sender-okhttp-1.42.1.jar No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-zipkin.txt b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-zipkin.txt index f44eb5c177b..537e948dcc2 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-zipkin.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-zipkin.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of opentelemetry-exporter-zipkin-1.43.0-SNAPSHOT.jar against opentelemetry-exporter-zipkin-1.42.0.jar +Comparing source compatibility of opentelemetry-exporter-zipkin-1.43.0-SNAPSHOT.jar against opentelemetry-exporter-zipkin-1.42.1.jar No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-extension-kotlin.txt b/docs/apidiffs/current_vs_latest/opentelemetry-extension-kotlin.txt index 9d2147d32d1..7c65c448a0b 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-extension-kotlin.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-extension-kotlin.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of opentelemetry-extension-kotlin-1.43.0-SNAPSHOT.jar against opentelemetry-extension-kotlin-1.42.0.jar +Comparing source compatibility of opentelemetry-extension-kotlin-1.43.0-SNAPSHOT.jar against opentelemetry-extension-kotlin-1.42.1.jar No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-extension-trace-propagators.txt b/docs/apidiffs/current_vs_latest/opentelemetry-extension-trace-propagators.txt index 9d47b0f73c3..98a141a6aeb 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-extension-trace-propagators.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-extension-trace-propagators.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of opentelemetry-extension-trace-propagators-1.43.0-SNAPSHOT.jar against opentelemetry-extension-trace-propagators-1.42.0.jar +Comparing source compatibility of opentelemetry-extension-trace-propagators-1.43.0-SNAPSHOT.jar against opentelemetry-extension-trace-propagators-1.42.1.jar No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-opentracing-shim.txt b/docs/apidiffs/current_vs_latest/opentelemetry-opentracing-shim.txt index d543d84783c..05003fc7f80 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-opentracing-shim.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-opentracing-shim.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of opentelemetry-opentracing-shim-1.43.0-SNAPSHOT.jar against opentelemetry-opentracing-shim-1.42.0.jar +Comparing source compatibility of opentelemetry-opentracing-shim-1.43.0-SNAPSHOT.jar against opentelemetry-opentracing-shim-1.42.1.jar No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-common.txt b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-common.txt index f7f5e800cad..86896440efc 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-common.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-common.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of opentelemetry-sdk-common-1.43.0-SNAPSHOT.jar against opentelemetry-sdk-common-1.42.0.jar +Comparing source compatibility of opentelemetry-sdk-common-1.43.0-SNAPSHOT.jar against opentelemetry-sdk-common-1.42.1.jar No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-extension-autoconfigure-spi.txt b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-extension-autoconfigure-spi.txt index 2af1a4c5b30..b2d9f314311 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-extension-autoconfigure-spi.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-extension-autoconfigure-spi.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of opentelemetry-sdk-extension-autoconfigure-spi-1.43.0-SNAPSHOT.jar against opentelemetry-sdk-extension-autoconfigure-spi-1.42.0.jar +Comparing source compatibility of opentelemetry-sdk-extension-autoconfigure-spi-1.43.0-SNAPSHOT.jar against opentelemetry-sdk-extension-autoconfigure-spi-1.42.1.jar No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-extension-autoconfigure.txt b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-extension-autoconfigure.txt index 8d051c5e8c1..71e51b48273 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-extension-autoconfigure.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-extension-autoconfigure.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of opentelemetry-sdk-extension-autoconfigure-1.43.0-SNAPSHOT.jar against opentelemetry-sdk-extension-autoconfigure-1.42.0.jar +Comparing source compatibility of opentelemetry-sdk-extension-autoconfigure-1.43.0-SNAPSHOT.jar against opentelemetry-sdk-extension-autoconfigure-1.42.1.jar No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-extension-jaeger-remote-sampler.txt b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-extension-jaeger-remote-sampler.txt index c9fc3ad2546..908a8c453d1 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-extension-jaeger-remote-sampler.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-extension-jaeger-remote-sampler.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of opentelemetry-sdk-extension-jaeger-remote-sampler-1.43.0-SNAPSHOT.jar against opentelemetry-sdk-extension-jaeger-remote-sampler-1.42.0.jar +Comparing source compatibility of opentelemetry-sdk-extension-jaeger-remote-sampler-1.43.0-SNAPSHOT.jar against opentelemetry-sdk-extension-jaeger-remote-sampler-1.42.1.jar No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-logs.txt b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-logs.txt index fa9c85da1d4..2b74b883472 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-logs.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-logs.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of opentelemetry-sdk-logs-1.43.0-SNAPSHOT.jar against opentelemetry-sdk-logs-1.42.0.jar +Comparing source compatibility of opentelemetry-sdk-logs-1.43.0-SNAPSHOT.jar against opentelemetry-sdk-logs-1.42.1.jar No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-metrics.txt b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-metrics.txt index 8979de6e159..d72c3db4aa0 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-metrics.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-metrics.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of opentelemetry-sdk-metrics-1.43.0-SNAPSHOT.jar against opentelemetry-sdk-metrics-1.42.0.jar +Comparing source compatibility of opentelemetry-sdk-metrics-1.43.0-SNAPSHOT.jar against opentelemetry-sdk-metrics-1.42.1.jar No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-testing.txt b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-testing.txt index a7ccc6eabb7..dce15125b1c 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-testing.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-testing.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of opentelemetry-sdk-testing-1.43.0-SNAPSHOT.jar against opentelemetry-sdk-testing-1.42.0.jar +Comparing source compatibility of opentelemetry-sdk-testing-1.43.0-SNAPSHOT.jar against opentelemetry-sdk-testing-1.42.1.jar No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-trace.txt b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-trace.txt index 266b05b06f1..d9256c134de 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-trace.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-trace.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of opentelemetry-sdk-trace-1.43.0-SNAPSHOT.jar against opentelemetry-sdk-trace-1.42.0.jar +Comparing source compatibility of opentelemetry-sdk-trace-1.43.0-SNAPSHOT.jar against opentelemetry-sdk-trace-1.42.1.jar No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-sdk.txt b/docs/apidiffs/current_vs_latest/opentelemetry-sdk.txt index dcbd3ecaa3f..b44828c2284 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-sdk.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-sdk.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of opentelemetry-sdk-1.43.0-SNAPSHOT.jar against opentelemetry-sdk-1.42.0.jar +Comparing source compatibility of opentelemetry-sdk-1.43.0-SNAPSHOT.jar against opentelemetry-sdk-1.42.1.jar No changes. \ No newline at end of file From 8fb169e934634d98161963c4d0980ea19b9e06a1 Mon Sep 17 00:00:00 2001 From: jack-berg <34418638+jack-berg@users.noreply.github.com> Date: Wed, 11 Sep 2024 09:16:58 -0500 Subject: [PATCH 559/901] Codify stance against using java-test-fixtures plugin (#6696) --- CONTRIBUTING.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index c6c78a73621..5c02e405c0d 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -146,6 +146,13 @@ uses [google-java-format](https://github.com/google/google-java-format) library: synchronized (lock) { ... } } ``` +* Don't + use [gradle test fixtures](https://docs.gradle.org/current/userguide/java_testing.html#sec:java_test_fixtures) ( + i.e. `java-test-fixtures` plugin) to reuse code for internal testing. The test fixtures plugin has + side effects where test dependencies are added to the `pom.xml` and publishes an + extra `*-test-fixtures.jar` artifact which is unnecessary for internal testing. Instead, create a + new `*:testing-internal` module and omit the `otel.java-conventions`. For example, + see [/exporters/otlp/testing-internal](./exporters/otlp/testing-internal). If you notice any practice being applied in the project consistently that isn't listed here, please consider a pull request to add it. From 57f94cf92a28e4dd0ee3ad39f601d5f39febeb33 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 11 Sep 2024 20:34:15 -0700 Subject: [PATCH 560/901] Update dependency gradle to v8.10.1 (#6694) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- gradle/wrapper/gradle-wrapper.properties | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 2b189974c29..8e876e1c557 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,7 +1,7 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionSha256Sum=5b9c5eb3f9fc2c94abaea57d90bd78747ca117ddbbf96c859d3741181a12bf2a -distributionUrl=https\://services.gradle.org/distributions/gradle-8.10-bin.zip +distributionSha256Sum=1541fa36599e12857140465f3c91a97409b4512501c26f9631fb113e392c5bd1 +distributionUrl=https\://services.gradle.org/distributions/gradle-8.10.1-bin.zip networkTimeout=10000 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME From 18d192d1fadc6f6dd4dfbff01c0c139eaf93c604 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 12 Sep 2024 18:16:33 -0700 Subject: [PATCH 561/901] Update dependency com.google.api.grpc:proto-google-common-protos to v2.44.0 (#6697) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- dependencyManagement/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index 777cd1ea2b7..2877c451d02 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -56,7 +56,7 @@ val DEPENDENCIES = listOf( "io.prometheus:simpleclient_httpserver:${prometheusClientVersion}", "javax.annotation:javax.annotation-api:1.3.2", "com.github.stefanbirkner:system-rules:1.19.0", - "com.google.api.grpc:proto-google-common-protos:2.43.0", + "com.google.api.grpc:proto-google-common-protos:2.44.0", "com.google.code.findbugs:jsr305:3.0.2", "com.google.guava:guava-beta-checker:1.0", "com.sun.net.httpserver:http:20070405", From 983800cc56f9dee5362cbdca7a40e274c0825906 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 16 Sep 2024 20:43:42 -0700 Subject: [PATCH 562/901] Update plugin org.graalvm.buildtools.native to v0.10.3 (#6702) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- settings.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/settings.gradle.kts b/settings.gradle.kts index 12121e5094a..83cd78db302 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -5,7 +5,7 @@ pluginManagement { id("de.undercouch.download") version "5.6.0" id("org.jsonschema2pojo") version "1.2.1" id("io.github.gradle-nexus.publish-plugin") version "2.0.0" - id("org.graalvm.buildtools.native") version "0.10.2" + id("org.graalvm.buildtools.native") version "0.10.3" } } From 0132d5d98b21cd4cbc2a0354a4d5bcc2867a2969 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 17 Sep 2024 18:22:23 -0700 Subject: [PATCH 563/901] Update dependency com.linecorp.armeria:armeria-bom to v1.30.1 (#6701) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- dependencyManagement/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index 2877c451d02..3a445c38436 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -11,7 +11,7 @@ val DEPENDENCY_BOMS = listOf( "com.fasterxml.jackson:jackson-bom:2.17.2", "com.google.guava:guava-bom:33.3.0-jre", "com.google.protobuf:protobuf-bom:3.25.4", - "com.linecorp.armeria:armeria-bom:1.30.0", + "com.linecorp.armeria:armeria-bom:1.30.1", "com.squareup.okhttp3:okhttp-bom:4.12.0", "com.squareup.okio:okio-bom:3.9.0", // applies to transitive dependencies of okhttp "io.grpc:grpc-bom:1.66.0", From 82b9e9b64d3c0f1674ed03228f371696223fc594 Mon Sep 17 00:00:00 2001 From: jack-berg <34418638+jack-berg@users.noreply.github.com> Date: Wed, 18 Sep 2024 15:07:31 -0500 Subject: [PATCH 564/901] Optimize advice with FilteredAttributes (#6633) --- .../api/internal/ImmutableKeyValuePairs.java | 9 + sdk/metrics/build.gradle.kts | 1 + .../sdk/metrics/MetricAdviceBenchmark.java | 273 +++++++++++++++++ .../view/AdviceAttributesProcessor.java | 22 +- .../internal/view/FilteredAttributes.java | 284 ++++++++++++++++++ .../internal/view/FilteredAttributesTest.java | 192 ++++++++++++ 6 files changed, 760 insertions(+), 21 deletions(-) create mode 100644 sdk/metrics/src/jmh/java/io/opentelemetry/sdk/metrics/MetricAdviceBenchmark.java create mode 100644 sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/view/FilteredAttributes.java create mode 100644 sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/internal/view/FilteredAttributesTest.java diff --git a/api/all/src/main/java/io/opentelemetry/api/internal/ImmutableKeyValuePairs.java b/api/all/src/main/java/io/opentelemetry/api/internal/ImmutableKeyValuePairs.java index a2590633b83..4e6b19cee36 100644 --- a/api/all/src/main/java/io/opentelemetry/api/internal/ImmutableKeyValuePairs.java +++ b/api/all/src/main/java/io/opentelemetry/api/internal/ImmutableKeyValuePairs.java @@ -274,4 +274,13 @@ public String toString() { sb.append("}"); return sb.toString(); } + + /** + * Return the backing data array for these attributes. This is only exposed for internal use by + * opentelemetry authors. The contents of the array MUST NOT be modified. + */ + @SuppressWarnings("AvoidObjectArrays") + public Object[] getData() { + return data; + } } diff --git a/sdk/metrics/build.gradle.kts b/sdk/metrics/build.gradle.kts index ef2dd8244a5..0fffd03457e 100644 --- a/sdk/metrics/build.gradle.kts +++ b/sdk/metrics/build.gradle.kts @@ -25,6 +25,7 @@ dependencies { testImplementation(project(":sdk:testing")) testImplementation("com.google.guava:guava") + testImplementation("com.google.guava:guava-testlib") jmh(project(":sdk:trace")) jmh(project(":sdk:testing")) diff --git a/sdk/metrics/src/jmh/java/io/opentelemetry/sdk/metrics/MetricAdviceBenchmark.java b/sdk/metrics/src/jmh/java/io/opentelemetry/sdk/metrics/MetricAdviceBenchmark.java new file mode 100644 index 00000000000..66c1a830607 --- /dev/null +++ b/sdk/metrics/src/jmh/java/io/opentelemetry/sdk/metrics/MetricAdviceBenchmark.java @@ -0,0 +1,273 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.sdk.metrics; + +import io.opentelemetry.api.common.AttributeKey; +import io.opentelemetry.api.common.Attributes; +import io.opentelemetry.api.incubator.metrics.ExtendedLongCounterBuilder; +import io.opentelemetry.api.metrics.LongCounter; +import io.opentelemetry.api.metrics.Meter; +import io.opentelemetry.sdk.testing.exporter.InMemoryMetricReader; +import java.util.Arrays; +import java.util.List; +import java.util.concurrent.TimeUnit; +import org.openjdk.jmh.annotations.Benchmark; +import org.openjdk.jmh.annotations.BenchmarkMode; +import org.openjdk.jmh.annotations.Fork; +import org.openjdk.jmh.annotations.Level; +import org.openjdk.jmh.annotations.Measurement; +import org.openjdk.jmh.annotations.Mode; +import org.openjdk.jmh.annotations.OutputTimeUnit; +import org.openjdk.jmh.annotations.Param; +import org.openjdk.jmh.annotations.Scope; +import org.openjdk.jmh.annotations.Setup; +import org.openjdk.jmh.annotations.State; +import org.openjdk.jmh.annotations.TearDown; +import org.openjdk.jmh.annotations.Threads; +import org.openjdk.jmh.annotations.Warmup; + +@BenchmarkMode({Mode.AverageTime}) +@OutputTimeUnit(TimeUnit.NANOSECONDS) +@Warmup(iterations = 5, time = 1) +@Measurement(iterations = 10, time = 1) +@Fork(1) +public class MetricAdviceBenchmark { + + static final AttributeKey HTTP_REQUEST_METHOD = + AttributeKey.stringKey("http.request.method"); + static final AttributeKey URL_PATH = AttributeKey.stringKey("url.path"); + static final AttributeKey URL_SCHEME = AttributeKey.stringKey("url.scheme"); + static final AttributeKey HTTP_RESPONSE_STATUS_CODE = + AttributeKey.longKey("http.response.status_code"); + static final AttributeKey HTTP_ROUTE = AttributeKey.stringKey("http.route"); + static final AttributeKey NETWORK_PROTOCOL_NAME = + AttributeKey.stringKey("network.protocol.name"); + static final AttributeKey SERVER_PORT = AttributeKey.longKey("server.port"); + static final AttributeKey URL_QUERY = AttributeKey.stringKey("url.query"); + static final AttributeKey CLIENT_ADDRESS = AttributeKey.stringKey("client.address"); + static final AttributeKey NETWORK_PEER_ADDRESS = + AttributeKey.stringKey("network.peer.address"); + static final AttributeKey NETWORK_PEER_PORT = AttributeKey.longKey("network.peer.port"); + static final AttributeKey NETWORK_PROTOCOL_VERSION = + AttributeKey.stringKey("network.protocol.version"); + static final AttributeKey SERVER_ADDRESS = AttributeKey.stringKey("server.address"); + static final AttributeKey USER_AGENT_ORIGINAL = + AttributeKey.stringKey("user_agent.original"); + + static final List> httpServerMetricAttributeKeys = + Arrays.asList( + HTTP_REQUEST_METHOD, + URL_SCHEME, + HTTP_RESPONSE_STATUS_CODE, + HTTP_ROUTE, + NETWORK_PROTOCOL_NAME, + SERVER_PORT, + NETWORK_PROTOCOL_VERSION, + SERVER_ADDRESS); + + static Attributes httpServerMetricAttributes() { + return Attributes.builder() + .put(HTTP_REQUEST_METHOD, "GET") + .put(URL_SCHEME, "http") + .put(HTTP_RESPONSE_STATUS_CODE, 200) + .put(HTTP_ROUTE, "/v1/users/{id}") + .put(NETWORK_PROTOCOL_NAME, "http") + .put(SERVER_PORT, 8080) + .put(NETWORK_PROTOCOL_VERSION, "1.1") + .put(SERVER_ADDRESS, "localhost") + .build(); + } + + static Attributes httpServerSpanAttributes() { + return Attributes.builder() + .put(HTTP_REQUEST_METHOD, "GET") + .put(URL_PATH, "/v1/users/123") + .put(URL_SCHEME, "http") + .put(HTTP_RESPONSE_STATUS_CODE, 200) + .put(HTTP_ROUTE, "/v1/users/{id}") + .put(NETWORK_PROTOCOL_NAME, "http") + .put(SERVER_PORT, 8080) + .put(URL_QUERY, "with=email") + .put(CLIENT_ADDRESS, "192.168.0.17") + .put(NETWORK_PEER_ADDRESS, "192.168.0.17") + .put(NETWORK_PEER_PORT, 11265) + .put(NETWORK_PROTOCOL_VERSION, "1.1") + .put(SERVER_ADDRESS, "localhost") + .put(USER_AGENT_ORIGINAL, "okhttp/1.27.2") + .build(); + } + + static final Attributes CACHED_HTTP_SERVER_SPAN_ATTRIBUTES = httpServerSpanAttributes(); + + @State(Scope.Benchmark) + public static class ThreadState { + + @Param InstrumentParam instrumentParam; + + SdkMeterProvider meterProvider; + + @Setup(Level.Iteration) + public void setup() { + meterProvider = + SdkMeterProvider.builder() + .registerMetricReader(InMemoryMetricReader.createDelta()) + .build(); + Meter meter = meterProvider.get("meter"); + instrumentParam.instrument().setup(meter); + } + + @TearDown + public void tearDown() { + meterProvider.shutdown().join(10, TimeUnit.SECONDS); + } + } + + @Benchmark + @Threads(1) + public void record(ThreadState threadState) { + threadState.instrumentParam.instrument().record(1); + } + + @SuppressWarnings("ImmutableEnumChecker") + public enum InstrumentParam { + /** + * Record HTTP span attributes without advice. This baseline shows the CPU and memory allocation + * independent of advice. + */ + NO_ADVICE_ALL_ATTRIBUTES( + new Instrument() { + private LongCounter counter; + + @Override + void setup(Meter meter) { + counter = ((ExtendedLongCounterBuilder) meter.counterBuilder("counter")).build(); + } + + @Override + void record(long value) { + counter.add(value, httpServerSpanAttributes()); + } + }), + /** + * Record HTTP metric attributes without advice. This baseline shows the lower bound if + * attribute filtering was done in instrumentation instead of the metrics SDK with advice. It's + * not quite fair though because instrumentation would have to separately allocate attributes + * for spans and metrics, whereas with advice, we can manage to only allocate span attributes + * and a lightweight metrics attributes view derived from span attributes. + */ + NO_ADVICE_FILTERED_ATTRIBUTES( + new Instrument() { + private LongCounter counter; + + @Override + void setup(Meter meter) { + counter = ((ExtendedLongCounterBuilder) meter.counterBuilder("counter")).build(); + } + + @Override + void record(long value) { + counter.add(value, httpServerMetricAttributes()); + } + }), + /** + * Record cached HTTP span attributes without advice. This baseline helps isolate the CPU and + * memory allocation for recording vs. creating attributes. + */ + NO_ADVICE_ALL_ATTRIBUTES_CACHED( + new Instrument() { + private LongCounter counter; + + @Override + void setup(Meter meter) { + counter = ((ExtendedLongCounterBuilder) meter.counterBuilder("counter")).build(); + } + + @Override + void record(long value) { + counter.add(value, CACHED_HTTP_SERVER_SPAN_ATTRIBUTES); + } + }), + /** + * Record HTTP span attributes with advice filtering to HTTP metric attributes. This is meant to + * realistically demonstrate a typical HTTP server instrumentation scenario. + */ + ADVICE_ALL_ATTRIBUTES( + new Instrument() { + private LongCounter counter; + + @Override + void setup(Meter meter) { + counter = + ((ExtendedLongCounterBuilder) meter.counterBuilder("counter")) + .setAttributesAdvice(httpServerMetricAttributeKeys) + .build(); + } + + @Override + void record(long value) { + counter.add(value, httpServerSpanAttributes()); + } + }), + /** + * Record HTTP metric attributes with advice filtering to HTTP metric attributes. This + * demonstrates the overhead of advice when no attributes are filtered. + */ + ADVICE_FILTERED_ATTRIBUTES( + new Instrument() { + private LongCounter counter; + + @Override + void setup(Meter meter) { + counter = + ((ExtendedLongCounterBuilder) meter.counterBuilder("counter")) + .setAttributesAdvice(httpServerMetricAttributeKeys) + .build(); + } + + @Override + void record(long value) { + counter.add(value, httpServerMetricAttributes()); + } + }), + /** + * Record cached HTTP span attributes with advice filtering to HTTP metric attributes. This + * isolates the CPU and memory allocation for applying advice vs. creating attributes. + */ + ADVICE_ALL_ATTRIBUTES_CACHED( + new Instrument() { + private LongCounter counter; + + @Override + void setup(Meter meter) { + counter = + ((ExtendedLongCounterBuilder) meter.counterBuilder("counter")) + .setAttributesAdvice(httpServerMetricAttributeKeys) + .build(); + } + + @Override + void record(long value) { + counter.add(value, CACHED_HTTP_SERVER_SPAN_ATTRIBUTES); + } + }); + + private final Instrument instrument; + + InstrumentParam(Instrument instrument) { + this.instrument = instrument; + } + + Instrument instrument() { + return instrument; + } + } + + private abstract static class Instrument { + abstract void setup(Meter meter); + + abstract void record(long value); + } +} diff --git a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/view/AdviceAttributesProcessor.java b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/view/AdviceAttributesProcessor.java index b0373f25765..8b77b48e631 100644 --- a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/view/AdviceAttributesProcessor.java +++ b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/view/AdviceAttributesProcessor.java @@ -7,7 +7,6 @@ import io.opentelemetry.api.common.AttributeKey; import io.opentelemetry.api.common.Attributes; -import io.opentelemetry.api.common.AttributesBuilder; import io.opentelemetry.context.Context; import java.util.HashSet; import java.util.List; @@ -23,26 +22,7 @@ final class AdviceAttributesProcessor extends AttributesProcessor { @Override public Attributes process(Attributes incoming, Context context) { - // Exit early to avoid allocations if the incoming attributes do not have extra keys to be - // filtered - if (!hasExtraKeys(incoming)) { - return incoming; - } - AttributesBuilder builder = incoming.toBuilder(); - builder.removeIf(key -> !attributeKeys.contains(key)); - return builder.build(); - } - - /** Returns true if {@code attributes} has keys not contained in {@link #attributeKeys}. */ - private boolean hasExtraKeys(Attributes attributes) { - boolean[] result = {false}; - attributes.forEach( - (key, value) -> { - if (!result[0] && !attributeKeys.contains(key)) { - result[0] = true; - } - }); - return result[0]; + return FilteredAttributes.create(incoming, attributeKeys); } @Override diff --git a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/view/FilteredAttributes.java b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/view/FilteredAttributes.java new file mode 100644 index 00000000000..d71616c20e8 --- /dev/null +++ b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/view/FilteredAttributes.java @@ -0,0 +1,284 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.sdk.metrics.internal.view; + +import io.opentelemetry.api.common.AttributeKey; +import io.opentelemetry.api.common.Attributes; +import io.opentelemetry.api.common.AttributesBuilder; +import io.opentelemetry.api.internal.ImmutableKeyValuePairs; +import java.util.BitSet; +import java.util.Collections; +import java.util.LinkedHashMap; +import java.util.Map; +import java.util.Objects; +import java.util.Set; +import java.util.StringJoiner; +import java.util.function.BiConsumer; +import javax.annotation.Nullable; + +/** + * Filtered attributes is a filtered view of a {@link ImmutableKeyValuePairs} backed {@link + * Attributes} instance. Rather than creating an entirely new attributes instance, it keeps track of + * which source attributes are excluded while implementing the {@link Attributes} interface. + * + *

      Notably, the {@link FilteredAttributes#equals(Object)} and {@link + * FilteredAttributes#hashCode()} depend on comparison against other {@link FilteredAttributes} + * instances. This means that where {@link FilteredAttributes} is used for things like map keys, it + * must be used for all keys in that map. You cannot mix {@link Attributes} implementations. This is + * also true for the default attributes implementation. + */ +@SuppressWarnings("unchecked") +abstract class FilteredAttributes implements Attributes { + + // Backing source data from ImmutableKeyValuePairs.data. This array MUST NOT be mutated. + private final Object[] sourceData; + private final int hashcode; + private final int size; + + private FilteredAttributes(Object[] sourceData, int hashcode, int size) { + this.sourceData = sourceData; + this.hashcode = hashcode; + this.size = size; + } + + /** + * Create a {@link FilteredAttributes} instance. + * + * @param source the source attributes, which SHOULD be based on the standard {@link + * ImmutableKeyValuePairs}. If not, the source will first be converted to the standard + * implementation. + * @param includedKeys the set of attribute keys to include in the output. + */ + @SuppressWarnings("NullAway") + static Attributes create(Attributes source, Set> includedKeys) { + // Convert alternative implementations of Attributes to standard implementation. + // This is required for proper functioning of equals and hashcode. + if (!(source instanceof ImmutableKeyValuePairs)) { + source = convertToStandardImplementation(source); + } + if (!(source instanceof ImmutableKeyValuePairs)) { + throw new IllegalStateException( + "Expected ImmutableKeyValuePairs based implementation of Attributes. This is a programming error."); + } + // Compute filteredIndices (and filteredIndicesBitSet if needed) during initialization. Compute + // hashcode at the same time to avoid iteration later. + Object[] sourceData = ((ImmutableKeyValuePairs) source).getData(); + int filteredIndices = 0; + BitSet filteredIndicesBitSet = + source.size() > SmallFilteredAttributes.BITS_PER_INTEGER ? new BitSet(source.size()) : null; + int hashcode = 1; + int size = 0; + for (int i = 0; i < sourceData.length; i += 2) { + int filterIndex = i / 2; + // If the sourceData key isn't present in includedKeys, record the exclusion in + // filteredIndices or filteredIndicesBitSet (depending on size) + if (!includedKeys.contains(sourceData[i])) { + // Record + if (filteredIndicesBitSet != null) { + filteredIndicesBitSet.set(filterIndex); + } else { + filteredIndices = filteredIndices | (1 << filterIndex); + } + } else { // The key-value is included in the output, record in the hashcode and size. + hashcode = 31 * hashcode + sourceData[i].hashCode(); + hashcode = 31 * hashcode + sourceData[i + 1].hashCode(); + size++; + } + } + // If size is 0, short circuit and return Attributes.empty() + if (size == 0) { + return Attributes.empty(); + } + return filteredIndicesBitSet != null + ? new RegularFilteredAttributes(sourceData, hashcode, size, filteredIndicesBitSet) + : new SmallFilteredAttributes(sourceData, hashcode, size, filteredIndices); + } + + /** + * Implementation that relies on the source having less than {@link #BITS_PER_INTEGER} attributes, + * and storing entry filter status in the bits of an integer. + */ + private static class SmallFilteredAttributes extends FilteredAttributes { + + private static final int BITS_PER_INTEGER = 32; + + private final int filteredIndices; + + private SmallFilteredAttributes( + Object[] sourceData, int hashcode, int size, int filteredIndices) { + super(sourceData, hashcode, size); + this.filteredIndices = filteredIndices; + } + + @Override + boolean includeIndexInOutput(int sourceIndex) { + return (filteredIndices & (1 << (sourceIndex / 2))) == 0; + } + } + + /** + * Implementation that can handle attributes of arbitrary size by storing filter status in a + * {@link BitSet}. + */ + private static class RegularFilteredAttributes extends FilteredAttributes { + + private final BitSet bitSet; + + private RegularFilteredAttributes(Object[] sourceData, int hashcode, int size, BitSet bitSet) { + super(sourceData, hashcode, size); + this.bitSet = bitSet; + } + + @Override + boolean includeIndexInOutput(int sourceIndex) { + return !bitSet.get(sourceIndex / 2); + } + } + + private static Attributes convertToStandardImplementation(Attributes source) { + AttributesBuilder builder = Attributes.builder(); + source.forEach( + (key, value) -> putInBuilder(builder, (AttributeKey) key, value)); + return builder.build(); + } + + @Nullable + @Override + public T get(AttributeKey key) { + if (key == null) { + return null; + } + for (int i = 0; i < sourceData.length; i += 2) { + if (key.equals(sourceData[i]) && includeIndexInOutput(i)) { + return (T) sourceData[i + 1]; + } + } + return null; + } + + @Override + public void forEach(BiConsumer, ? super Object> consumer) { + for (int i = 0; i < sourceData.length; i += 2) { + if (includeIndexInOutput(i)) { + consumer.accept((AttributeKey) sourceData[i], sourceData[i + 1]); + } + } + } + + @Override + public int size() { + return size; + } + + @Override + public boolean isEmpty() { + // #create short circuits and returns Attributes.empty() if empty, so FilteredAttributes is + // never empty + return false; + } + + @Override + public Map, Object> asMap() { + Map, Object> result = new LinkedHashMap<>(size); + for (int i = 0; i < sourceData.length; i += 2) { + if (includeIndexInOutput(i)) { + result.put((AttributeKey) sourceData[i], sourceData[i + 1]); + } + } + return Collections.unmodifiableMap(result); + } + + @Override + public AttributesBuilder toBuilder() { + AttributesBuilder builder = Attributes.builder(); + for (int i = 0; i < sourceData.length; i += 2) { + if (includeIndexInOutput(i)) { + putInBuilder(builder, (AttributeKey) sourceData[i], sourceData[i + 1]); + } + } + return builder; + } + + private static void putInBuilder(AttributesBuilder builder, AttributeKey key, T value) { + builder.put(key, value); + } + + @Override + public boolean equals(Object object) { + if (this == object) { + return true; + } + // We require other object to also be instances of FilteredAttributes. In other words, where one + // FilteredAttributes is used for a key in a map, it must be used for all the keys. Note, this + // same requirement exists for the default Attributes implementation - you can not mix + // implementations. + if (object == null || !(object instanceof FilteredAttributes)) { + return false; + } + + FilteredAttributes that = (FilteredAttributes) object; + // exit early if sizes are not equal + if (size() != that.size()) { + return false; + } + // Compare each non-filtered key / value pair from this to that. + // Depends on the entries from the backing ImmutableKeyValuePairs being sorted. + int thisIndex = 0; + int thatIndex = 0; + boolean thisDone; + boolean thatDone; + do { + thisDone = thisIndex >= this.sourceData.length; + thatDone = thatIndex >= that.sourceData.length; + // advance to next unfiltered key value pair for this and that + if (!thisDone && !this.includeIndexInOutput(thisIndex)) { + thisIndex += 2; + continue; + } + if (!thatDone && !that.includeIndexInOutput(thatIndex)) { + thatIndex += 2; + continue; + } + // if we're done iterating both this and that, we exit and return true since these are equal + if (thisDone && thatDone) { + break; + } + // if either this or that is done iterating, but not both, these are not equal + if (thisDone != thatDone) { + return false; + } + // if we make it here, both thisIndex and thatIndex within bounds and are included in the + // output. the current + // key and value and this and that must be equal for this and that to be equal. + if (!Objects.equals(this.sourceData[thisIndex], that.sourceData[thatIndex]) + || !Objects.equals(this.sourceData[thisIndex + 1], that.sourceData[thatIndex + 1])) { + return false; + } + thisIndex += 2; + thatIndex += 2; + } while (true); + // if we make it here without exiting early, all elements of this and that are equal + return true; + } + + @Override + public int hashCode() { + return hashcode; + } + + @Override + public String toString() { + StringJoiner joiner = new StringJoiner(",", "FilteredAttributes{", "}"); + for (int i = 0; i < sourceData.length; i += 2) { + if (includeIndexInOutput(i)) { + joiner.add(((AttributeKey) sourceData[i]).getKey() + "=" + sourceData[i + 1]); + } + } + return joiner.toString(); + } + + abstract boolean includeIndexInOutput(int sourceIndex); +} diff --git a/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/internal/view/FilteredAttributesTest.java b/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/internal/view/FilteredAttributesTest.java new file mode 100644 index 00000000000..b8bc0d10932 --- /dev/null +++ b/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/internal/view/FilteredAttributesTest.java @@ -0,0 +1,192 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.sdk.metrics.internal.view; + +import static io.opentelemetry.api.common.AttributeKey.longKey; +import static io.opentelemetry.api.common.AttributeKey.stringKey; +import static org.assertj.core.api.Assertions.assertThat; + +import com.google.common.collect.ImmutableMap; +import com.google.common.collect.ImmutableSet; +import com.google.common.testing.EqualsTester; +import io.opentelemetry.api.common.AttributeKey; +import io.opentelemetry.api.common.Attributes; +import io.opentelemetry.api.common.AttributesBuilder; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; +import java.util.stream.Collectors; +import java.util.stream.IntStream; +import java.util.stream.Stream; +import org.junit.jupiter.api.RepeatedTest; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; + +/** Unit tests for {@link FilteredAttributes}s. */ +@SuppressWarnings("rawtypes") +class FilteredAttributesTest { + + private static final AttributeKey KEY1 = stringKey("key1"); + private static final AttributeKey KEY2 = stringKey("key2"); + private static final AttributeKey KEY3 = stringKey("key3"); + private static final AttributeKey KEY4 = stringKey("key4"); + private static final AttributeKey KEY2_LONG = longKey("key2"); + private static final Set> ALL_KEYS = + ImmutableSet.of(KEY1, KEY2, KEY3, KEY4, KEY2_LONG); + private static final Attributes ALL_ATTRIBUTES = + Attributes.of(KEY1, "value1", KEY2, "value2", KEY2_LONG, 222L, KEY3, "value3"); + private static final Attributes FILTERED_ATTRIBUTES_ONE = + FilteredAttributes.create(ALL_ATTRIBUTES, ImmutableSet.of(KEY1)); + private static final Attributes FILTERED_ATTRIBUTES_TWO = + FilteredAttributes.create(ALL_ATTRIBUTES, ImmutableSet.of(KEY1, KEY2_LONG)); + private static final Attributes FILTERED_ATTRIBUTES_THREE = + FilteredAttributes.create(ALL_ATTRIBUTES, ImmutableSet.of(KEY1, KEY2_LONG, KEY3)); + private static final Attributes FILTERED_ATTRIBUTES_FOUR = + FilteredAttributes.create(ALL_ATTRIBUTES, ImmutableSet.of(KEY1, KEY2_LONG, KEY3, KEY4)); + private static final Attributes FILTERED_ATTRIBUTES_EMPTY_SOURCE = + FilteredAttributes.create(Attributes.empty(), ImmutableSet.of(KEY1)); + private static final Attributes FILTERED_ATTRIBUTES_EMPTY = + FilteredAttributes.create(ALL_ATTRIBUTES, Collections.emptySet()); + + @ParameterizedTest + @MethodSource("mapArgs") + void forEach(Attributes filteredAttributes, Map, Object> expectedMapEntries) { + Map entriesSeen = new HashMap<>(); + filteredAttributes.forEach(entriesSeen::put); + assertThat(entriesSeen).isEqualTo(expectedMapEntries); + } + + @ParameterizedTest + @MethodSource("mapArgs") + void asMap(Attributes filteredAttributes, Map, Object> expectedMapEntries) { + assertThat(filteredAttributes.asMap()).isEqualTo(expectedMapEntries); + } + + @ParameterizedTest + @MethodSource("mapArgs") + void size(Attributes filteredAttributes, Map, Object> expectedMapEntries) { + assertThat(filteredAttributes.size()).isEqualTo(expectedMapEntries.size()); + } + + @ParameterizedTest + @MethodSource("mapArgs") + void isEmpty(Attributes filteredAttributes, Map, Object> expectedMapEntries) { + assertThat(filteredAttributes.isEmpty()).isEqualTo(expectedMapEntries.isEmpty()); + } + + @ParameterizedTest + @MethodSource("mapArgs") + void get(Attributes filteredAttributes, Map, Object> expectedMapEntries) { + for (AttributeKey key : ALL_KEYS) { + Object expectedValue = expectedMapEntries.get(key); + assertThat(filteredAttributes.get(key)).isEqualTo(expectedValue); + } + } + + @ParameterizedTest + @MethodSource("mapArgs") + void toBuilder(Attributes filteredAttributes, Map, Object> expectedMapEntries) { + Attributes attributes = filteredAttributes.toBuilder().build(); + assertThat(attributes.asMap()).isEqualTo(expectedMapEntries); + } + + private static Stream mapArgs() { + return Stream.of( + Arguments.of(FILTERED_ATTRIBUTES_ONE, ImmutableMap.of(KEY1, "value1")), + Arguments.of(FILTERED_ATTRIBUTES_TWO, ImmutableMap.of(KEY1, "value1", KEY2_LONG, 222L)), + Arguments.of( + FILTERED_ATTRIBUTES_THREE, + ImmutableMap.of(KEY1, "value1", KEY2_LONG, 222L, KEY3, "value3")), + Arguments.of( + FILTERED_ATTRIBUTES_FOUR, + ImmutableMap.of(KEY1, "value1", KEY2_LONG, 222L, KEY3, "value3")), + Arguments.of(FILTERED_ATTRIBUTES_EMPTY_SOURCE, Collections.emptyMap()), + Arguments.of(FILTERED_ATTRIBUTES_EMPTY, Collections.emptyMap())); + } + + @Test + void stringRepresentation() { + assertThat(FILTERED_ATTRIBUTES_ONE.toString()).isEqualTo("FilteredAttributes{key1=value1}"); + assertThat(FILTERED_ATTRIBUTES_TWO.toString()) + .isEqualTo("FilteredAttributes{key1=value1,key2=222}"); + assertThat(FILTERED_ATTRIBUTES_THREE.toString()) + .isEqualTo("FilteredAttributes{key1=value1,key2=222,key3=value3}"); + assertThat(FILTERED_ATTRIBUTES_FOUR.toString()) + .isEqualTo("FilteredAttributes{key1=value1,key2=222,key3=value3}"); + assertThat(FILTERED_ATTRIBUTES_EMPTY_SOURCE.toString()).isEqualTo("{}"); + assertThat(FILTERED_ATTRIBUTES_EMPTY.toString()).isEqualTo("{}"); + } + + /** + * Test behavior of attributes with more than the 32 limit of FilteredAttributes.filteredIndices. + */ + @RepeatedTest(10) + void largeAttributes() { + Set> allKeys = new HashSet<>(); + AttributesBuilder allAttributesBuilder = Attributes.builder(); + IntStream.range(0, 100) + .forEach( + i -> { + AttributeKey key = stringKey("key" + i); + allKeys.add(key); + allAttributesBuilder.put(key, "value" + i); + }); + Attributes allAttributes = allAttributesBuilder.build(); + + Attributes empty = FilteredAttributes.create(allAttributes, Collections.emptySet()); + assertThat(empty.size()).isEqualTo(0); + assertThat(empty.isEmpty()).isTrue(); + + Set> oneKey = allKeys.stream().limit(1).collect(Collectors.toSet()); + Attributes one = FilteredAttributes.create(allAttributes, oneKey); + assertThat(one.size()).isEqualTo(1); + assertThat(one.isEmpty()).isFalse(); + allKeys.stream() + .forEach( + key -> { + if (oneKey.contains(key)) { + assertThat(one.get(key)).isNotNull(); + } else { + assertThat(one.get(key)).isNull(); + } + }); + + Set> tenKeys = allKeys.stream().limit(10).collect(Collectors.toSet()); + Attributes ten = FilteredAttributes.create(allAttributes, tenKeys); + assertThat(ten.size()).isEqualTo(10); + assertThat(ten.isEmpty()).isFalse(); + allKeys.stream() + .forEach( + key -> { + if (tenKeys.contains(key)) { + assertThat(ten.get(key)).isNotNull(); + } else { + assertThat(ten.get(key)).isNull(); + } + }); + } + + @Test + void equalsAndHashCode() { + new EqualsTester() + .addEqualityGroup( + FILTERED_ATTRIBUTES_ONE, + FilteredAttributes.create(Attributes.of(KEY1, "value1"), Collections.singleton(KEY1)), + FilteredAttributes.create(Attributes.of(KEY1, "value1"), ImmutableSet.of(KEY1, KEY2)), + FilteredAttributes.create( + Attributes.of(KEY1, "value1", KEY2, "value2"), Collections.singleton(KEY1)), + FilteredAttributes.create( + Attributes.of(KEY1, "value1", KEY2_LONG, 222L), Collections.singleton(KEY1))) + .addEqualityGroup(FILTERED_ATTRIBUTES_TWO) + .addEqualityGroup(FILTERED_ATTRIBUTES_THREE, FILTERED_ATTRIBUTES_FOUR) + .addEqualityGroup(FILTERED_ATTRIBUTES_EMPTY, FILTERED_ATTRIBUTES_EMPTY_SOURCE) + .testEquals(); + } +} From d899702eabacdc9edf0cd326b9f214f3819d8f8c Mon Sep 17 00:00:00 2001 From: Gregor Zeitlinger Date: Wed, 18 Sep 2024 23:00:44 +0200 Subject: [PATCH 565/901] add stdout log record exporter (#6675) Co-authored-by: Jack Berg Co-authored-by: jack-berg <34418638+jack-berg@users.noreply.github.com> --- .../kotlin/otel.java-conventions.gradle.kts | 1 - exporters/logging-otlp/build.gradle.kts | 1 + .../OtlpJsonLoggingLogRecordExporter.java | 48 +-- .../otlp/OtlpJsonLoggingMetricExporter.java | 3 +- .../otlp/OtlpJsonLoggingSpanExporter.java | 6 +- .../LoggingLogRecordExporterProvider.java | 3 +- .../logs/OtlpStdoutLogRecordExporter.java | 92 ++++++ .../OtlpStdoutLogRecordExporterBuilder.java | 76 +++++ ...outLogRecordExporterComponentProvider.java | 36 +++ .../OtlpStdoutLogRecordExporterProvider.java | 29 ++ .../otlp/{ => internal/writer}/JsonUtil.java | 12 +- .../otlp/internal/writer/JsonWriter.java | 21 ++ .../internal/writer/LoggerJsonWriter.java | 65 ++++ .../internal/writer/StreamJsonWriter.java | 94 ++++++ ...toconfigure.spi.internal.ComponentProvider | 1 + ...logs.ConfigurableLogRecordExporterProvider | 3 +- .../OtlpJsonLoggingLogRecordExporterTest.java | 135 +------- .../otlp/OtlpStdoutLogRecordExporterTest.java | 287 ++++++++++++++++++ .../logging/otlp/TestDataExporter.java | 112 +++++++ .../internal/LoggingExporterProviderTest.java | 45 --- .../internal/writer/LoggerJsonWriterTest.java | 44 +++ .../internal/writer/StreamJsonWriterTest.java | 72 +++++ .../test/resources/expected-logs-wrapper.json | 89 ++++++ .../src/test/resources/expected-logs.json | 86 ++++++ .../LogRecordExporterConfiguration.java | 2 + .../LogRecordExporterConfigurationTest.java | 5 + .../LogRecordExporterConfigurationTest.java | 5 + 27 files changed, 1152 insertions(+), 221 deletions(-) rename exporters/logging-otlp/src/main/java/io/opentelemetry/exporter/logging/otlp/internal/{ => logs}/LoggingLogRecordExporterProvider.java (93%) create mode 100644 exporters/logging-otlp/src/main/java/io/opentelemetry/exporter/logging/otlp/internal/logs/OtlpStdoutLogRecordExporter.java create mode 100644 exporters/logging-otlp/src/main/java/io/opentelemetry/exporter/logging/otlp/internal/logs/OtlpStdoutLogRecordExporterBuilder.java create mode 100644 exporters/logging-otlp/src/main/java/io/opentelemetry/exporter/logging/otlp/internal/logs/OtlpStdoutLogRecordExporterComponentProvider.java create mode 100644 exporters/logging-otlp/src/main/java/io/opentelemetry/exporter/logging/otlp/internal/logs/OtlpStdoutLogRecordExporterProvider.java rename exporters/logging-otlp/src/main/java/io/opentelemetry/exporter/logging/otlp/{ => internal/writer}/JsonUtil.java (58%) create mode 100644 exporters/logging-otlp/src/main/java/io/opentelemetry/exporter/logging/otlp/internal/writer/JsonWriter.java create mode 100644 exporters/logging-otlp/src/main/java/io/opentelemetry/exporter/logging/otlp/internal/writer/LoggerJsonWriter.java create mode 100644 exporters/logging-otlp/src/main/java/io/opentelemetry/exporter/logging/otlp/internal/writer/StreamJsonWriter.java create mode 100644 exporters/logging-otlp/src/main/resources/META-INF/services/io.opentelemetry.sdk.autoconfigure.spi.internal.ComponentProvider create mode 100644 exporters/logging-otlp/src/test/java/io/opentelemetry/exporter/logging/otlp/OtlpStdoutLogRecordExporterTest.java create mode 100644 exporters/logging-otlp/src/test/java/io/opentelemetry/exporter/logging/otlp/TestDataExporter.java delete mode 100644 exporters/logging-otlp/src/test/java/io/opentelemetry/exporter/logging/otlp/internal/LoggingExporterProviderTest.java create mode 100644 exporters/logging-otlp/src/test/java/io/opentelemetry/exporter/logging/otlp/internal/writer/LoggerJsonWriterTest.java create mode 100644 exporters/logging-otlp/src/test/java/io/opentelemetry/exporter/logging/otlp/internal/writer/StreamJsonWriterTest.java create mode 100644 exporters/logging-otlp/src/test/resources/expected-logs-wrapper.json create mode 100644 exporters/logging-otlp/src/test/resources/expected-logs.json diff --git a/buildSrc/src/main/kotlin/otel.java-conventions.gradle.kts b/buildSrc/src/main/kotlin/otel.java-conventions.gradle.kts index 9eb42f21444..c357dddc847 100644 --- a/buildSrc/src/main/kotlin/otel.java-conventions.gradle.kts +++ b/buildSrc/src/main/kotlin/otel.java-conventions.gradle.kts @@ -87,7 +87,6 @@ tasks { "-Xlint:-processing", // We suppress the "options" warning because it prevents compilation on modern JDKs "-Xlint:-options", - // Fail build on any warning "-Werror", ), diff --git a/exporters/logging-otlp/build.gradle.kts b/exporters/logging-otlp/build.gradle.kts index 07a2044b5f3..a65f52f8522 100644 --- a/exporters/logging-otlp/build.gradle.kts +++ b/exporters/logging-otlp/build.gradle.kts @@ -20,5 +20,6 @@ dependencies { testImplementation(project(":sdk:testing")) + testImplementation("com.google.guava:guava") testImplementation("org.skyscreamer:jsonassert") } diff --git a/exporters/logging-otlp/src/main/java/io/opentelemetry/exporter/logging/otlp/OtlpJsonLoggingLogRecordExporter.java b/exporters/logging-otlp/src/main/java/io/opentelemetry/exporter/logging/otlp/OtlpJsonLoggingLogRecordExporter.java index c5b7d75cbe5..0c00cca908e 100644 --- a/exporters/logging-otlp/src/main/java/io/opentelemetry/exporter/logging/otlp/OtlpJsonLoggingLogRecordExporter.java +++ b/exporters/logging-otlp/src/main/java/io/opentelemetry/exporter/logging/otlp/OtlpJsonLoggingLogRecordExporter.java @@ -5,18 +5,12 @@ package io.opentelemetry.exporter.logging.otlp; -import static io.opentelemetry.exporter.logging.otlp.JsonUtil.JSON_FACTORY; - -import com.fasterxml.jackson.core.JsonGenerator; -import com.fasterxml.jackson.core.io.SegmentedStringWriter; -import io.opentelemetry.exporter.internal.otlp.logs.ResourceLogsMarshaler; +import io.opentelemetry.exporter.logging.otlp.internal.logs.OtlpStdoutLogRecordExporter; +import io.opentelemetry.exporter.logging.otlp.internal.logs.OtlpStdoutLogRecordExporterBuilder; import io.opentelemetry.sdk.common.CompletableResultCode; import io.opentelemetry.sdk.logs.data.LogRecordData; import io.opentelemetry.sdk.logs.export.LogRecordExporter; -import java.io.IOException; import java.util.Collection; -import java.util.concurrent.atomic.AtomicBoolean; -import java.util.logging.Level; import java.util.logging.Logger; /** @@ -30,49 +24,31 @@ public final class OtlpJsonLoggingLogRecordExporter implements LogRecordExporter private static final Logger logger = Logger.getLogger(OtlpJsonLoggingLogRecordExporter.class.getName()); - private final AtomicBoolean isShutdown = new AtomicBoolean(); + private final OtlpStdoutLogRecordExporter delegate; /** Returns a new {@link OtlpJsonLoggingLogRecordExporter}. */ public static LogRecordExporter create() { - return new OtlpJsonLoggingLogRecordExporter(); + OtlpStdoutLogRecordExporter delegate = + new OtlpStdoutLogRecordExporterBuilder(logger).setWrapperJsonObject(false).build(); + return new OtlpJsonLoggingLogRecordExporter(delegate); } - private OtlpJsonLoggingLogRecordExporter() {} + OtlpJsonLoggingLogRecordExporter(OtlpStdoutLogRecordExporter delegate) { + this.delegate = delegate; + } @Override public CompletableResultCode export(Collection logs) { - if (isShutdown.get()) { - return CompletableResultCode.ofFailure(); - } - - ResourceLogsMarshaler[] allResourceLogs = ResourceLogsMarshaler.create(logs); - for (ResourceLogsMarshaler resourceLogs : allResourceLogs) { - SegmentedStringWriter sw = new SegmentedStringWriter(JSON_FACTORY._getBufferRecycler()); - try (JsonGenerator gen = JsonUtil.create(sw)) { - resourceLogs.writeJsonTo(gen); - } catch (IOException e) { - // Shouldn't happen in practice, just skip it. - continue; - } - try { - logger.log(Level.INFO, sw.getAndClear()); - } catch (IOException e) { - logger.log(Level.WARNING, "Unable to read OTLP JSON log records", e); - } - } - return CompletableResultCode.ofSuccess(); + return delegate.export(logs); } @Override public CompletableResultCode flush() { - return CompletableResultCode.ofSuccess(); + return delegate.flush(); } @Override public CompletableResultCode shutdown() { - if (!isShutdown.compareAndSet(false, true)) { - logger.log(Level.INFO, "Calling shutdown() multiple times."); - } - return CompletableResultCode.ofSuccess(); + return delegate.shutdown(); } } diff --git a/exporters/logging-otlp/src/main/java/io/opentelemetry/exporter/logging/otlp/OtlpJsonLoggingMetricExporter.java b/exporters/logging-otlp/src/main/java/io/opentelemetry/exporter/logging/otlp/OtlpJsonLoggingMetricExporter.java index caacea6e7eb..0f66cc57c95 100644 --- a/exporters/logging-otlp/src/main/java/io/opentelemetry/exporter/logging/otlp/OtlpJsonLoggingMetricExporter.java +++ b/exporters/logging-otlp/src/main/java/io/opentelemetry/exporter/logging/otlp/OtlpJsonLoggingMetricExporter.java @@ -5,11 +5,12 @@ package io.opentelemetry.exporter.logging.otlp; -import static io.opentelemetry.exporter.logging.otlp.JsonUtil.JSON_FACTORY; +import static io.opentelemetry.exporter.logging.otlp.internal.writer.JsonUtil.JSON_FACTORY; import com.fasterxml.jackson.core.JsonGenerator; import com.fasterxml.jackson.core.io.SegmentedStringWriter; import io.opentelemetry.exporter.internal.otlp.metrics.ResourceMetricsMarshaler; +import io.opentelemetry.exporter.logging.otlp.internal.writer.JsonUtil; import io.opentelemetry.sdk.common.CompletableResultCode; import io.opentelemetry.sdk.metrics.InstrumentType; import io.opentelemetry.sdk.metrics.data.AggregationTemporality; diff --git a/exporters/logging-otlp/src/main/java/io/opentelemetry/exporter/logging/otlp/OtlpJsonLoggingSpanExporter.java b/exporters/logging-otlp/src/main/java/io/opentelemetry/exporter/logging/otlp/OtlpJsonLoggingSpanExporter.java index c57c9004d56..cc944e9bab6 100644 --- a/exporters/logging-otlp/src/main/java/io/opentelemetry/exporter/logging/otlp/OtlpJsonLoggingSpanExporter.java +++ b/exporters/logging-otlp/src/main/java/io/opentelemetry/exporter/logging/otlp/OtlpJsonLoggingSpanExporter.java @@ -5,9 +5,12 @@ package io.opentelemetry.exporter.logging.otlp; +import static io.opentelemetry.exporter.logging.otlp.internal.writer.JsonUtil.JSON_FACTORY; + import com.fasterxml.jackson.core.JsonGenerator; import com.fasterxml.jackson.core.io.SegmentedStringWriter; import io.opentelemetry.exporter.internal.otlp.traces.ResourceSpansMarshaler; +import io.opentelemetry.exporter.logging.otlp.internal.writer.JsonUtil; import io.opentelemetry.sdk.common.CompletableResultCode; import io.opentelemetry.sdk.trace.data.SpanData; import io.opentelemetry.sdk.trace.export.SpanExporter; @@ -43,8 +46,7 @@ public CompletableResultCode export(Collection spans) { ResourceSpansMarshaler[] allResourceSpans = ResourceSpansMarshaler.create(spans); for (ResourceSpansMarshaler resourceSpans : allResourceSpans) { - SegmentedStringWriter sw = - new SegmentedStringWriter(JsonUtil.JSON_FACTORY._getBufferRecycler()); + SegmentedStringWriter sw = new SegmentedStringWriter(JSON_FACTORY._getBufferRecycler()); try (JsonGenerator gen = JsonUtil.create(sw)) { resourceSpans.writeJsonTo(gen); } catch (IOException e) { diff --git a/exporters/logging-otlp/src/main/java/io/opentelemetry/exporter/logging/otlp/internal/LoggingLogRecordExporterProvider.java b/exporters/logging-otlp/src/main/java/io/opentelemetry/exporter/logging/otlp/internal/logs/LoggingLogRecordExporterProvider.java similarity index 93% rename from exporters/logging-otlp/src/main/java/io/opentelemetry/exporter/logging/otlp/internal/LoggingLogRecordExporterProvider.java rename to exporters/logging-otlp/src/main/java/io/opentelemetry/exporter/logging/otlp/internal/logs/LoggingLogRecordExporterProvider.java index ebb0d2d0865..a08aafee355 100644 --- a/exporters/logging-otlp/src/main/java/io/opentelemetry/exporter/logging/otlp/internal/LoggingLogRecordExporterProvider.java +++ b/exporters/logging-otlp/src/main/java/io/opentelemetry/exporter/logging/otlp/internal/logs/LoggingLogRecordExporterProvider.java @@ -3,7 +3,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -package io.opentelemetry.exporter.logging.otlp.internal; +package io.opentelemetry.exporter.logging.otlp.internal.logs; import io.opentelemetry.exporter.logging.otlp.OtlpJsonLoggingLogRecordExporter; import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties; @@ -17,6 +17,7 @@ * at any time. */ public class LoggingLogRecordExporterProvider implements ConfigurableLogRecordExporterProvider { + @Override public LogRecordExporter createExporter(ConfigProperties config) { return OtlpJsonLoggingLogRecordExporter.create(); diff --git a/exporters/logging-otlp/src/main/java/io/opentelemetry/exporter/logging/otlp/internal/logs/OtlpStdoutLogRecordExporter.java b/exporters/logging-otlp/src/main/java/io/opentelemetry/exporter/logging/otlp/internal/logs/OtlpStdoutLogRecordExporter.java new file mode 100644 index 00000000000..6a7adb6f742 --- /dev/null +++ b/exporters/logging-otlp/src/main/java/io/opentelemetry/exporter/logging/otlp/internal/logs/OtlpStdoutLogRecordExporter.java @@ -0,0 +1,92 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.exporter.logging.otlp.internal.logs; + +import io.opentelemetry.exporter.internal.otlp.logs.LogsRequestMarshaler; +import io.opentelemetry.exporter.internal.otlp.logs.ResourceLogsMarshaler; +import io.opentelemetry.exporter.logging.otlp.internal.writer.JsonWriter; +import io.opentelemetry.sdk.common.CompletableResultCode; +import io.opentelemetry.sdk.logs.data.LogRecordData; +import io.opentelemetry.sdk.logs.export.LogRecordExporter; +import java.util.Collection; +import java.util.StringJoiner; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.logging.Level; +import java.util.logging.Logger; + +/** + * Exporter for sending OTLP log records to stdout. + * + *

      This class is internal and is hence not for public use. Its APIs are unstable and can change + * at any time. + */ +public class OtlpStdoutLogRecordExporter implements LogRecordExporter { + + private static final Logger LOGGER = + Logger.getLogger(OtlpStdoutLogRecordExporter.class.getName()); + + private final AtomicBoolean isShutdown = new AtomicBoolean(); + + private final Logger logger; + private final JsonWriter jsonWriter; + private final boolean wrapperJsonObject; + + OtlpStdoutLogRecordExporter(Logger logger, JsonWriter jsonWriter, boolean wrapperJsonObject) { + this.logger = logger; + this.jsonWriter = jsonWriter; + this.wrapperJsonObject = wrapperJsonObject; + } + + /** Returns a new {@link OtlpStdoutLogRecordExporterBuilder}. */ + @SuppressWarnings("SystemOut") + public static OtlpStdoutLogRecordExporterBuilder builder() { + return new OtlpStdoutLogRecordExporterBuilder(LOGGER).setOutput(System.out); + } + + @Override + public CompletableResultCode export(Collection logs) { + if (isShutdown.get()) { + return CompletableResultCode.ofFailure(); + } + + if (wrapperJsonObject) { + LogsRequestMarshaler request = LogsRequestMarshaler.create(logs); + return jsonWriter.write(request); + } else { + for (ResourceLogsMarshaler resourceLogs : ResourceLogsMarshaler.create(logs)) { + CompletableResultCode resultCode = jsonWriter.write(resourceLogs); + if (!resultCode.isSuccess()) { + // already logged + return resultCode; + } + } + return CompletableResultCode.ofSuccess(); + } + } + + @Override + public CompletableResultCode flush() { + return jsonWriter.flush(); + } + + @Override + public CompletableResultCode shutdown() { + if (!isShutdown.compareAndSet(false, true)) { + logger.log(Level.INFO, "Calling shutdown() multiple times."); + } else { + jsonWriter.close(); + } + return CompletableResultCode.ofSuccess(); + } + + @Override + public String toString() { + StringJoiner joiner = new StringJoiner(", ", "OtlpStdoutLogRecordExporter{", "}"); + joiner.add("jsonWriter=" + jsonWriter); + joiner.add("wrapperJsonObject=" + wrapperJsonObject); + return joiner.toString(); + } +} diff --git a/exporters/logging-otlp/src/main/java/io/opentelemetry/exporter/logging/otlp/internal/logs/OtlpStdoutLogRecordExporterBuilder.java b/exporters/logging-otlp/src/main/java/io/opentelemetry/exporter/logging/otlp/internal/logs/OtlpStdoutLogRecordExporterBuilder.java new file mode 100644 index 00000000000..ea3f5c14234 --- /dev/null +++ b/exporters/logging-otlp/src/main/java/io/opentelemetry/exporter/logging/otlp/internal/logs/OtlpStdoutLogRecordExporterBuilder.java @@ -0,0 +1,76 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.exporter.logging.otlp.internal.logs; + +import static java.util.Objects.requireNonNull; + +import io.opentelemetry.exporter.logging.otlp.OtlpJsonLoggingLogRecordExporter; +import io.opentelemetry.exporter.logging.otlp.internal.writer.JsonWriter; +import io.opentelemetry.exporter.logging.otlp.internal.writer.LoggerJsonWriter; +import io.opentelemetry.exporter.logging.otlp.internal.writer.StreamJsonWriter; +import java.io.OutputStream; +import java.util.logging.Logger; + +/** + * Builder for {@link OtlpJsonLoggingLogRecordExporter}. + * + *

      This class is internal and is hence not for public use. Its APIs are unstable and can change + * at any time. + */ +public final class OtlpStdoutLogRecordExporterBuilder { + + private static final String TYPE = "log records"; + + private final Logger logger; + private JsonWriter jsonWriter; + private boolean wrapperJsonObject = true; + + public OtlpStdoutLogRecordExporterBuilder(Logger logger) { + this.logger = logger; + this.jsonWriter = new LoggerJsonWriter(logger, TYPE); + } + + /** + * Sets the exporter to use the specified JSON object wrapper. + * + * @param wrapperJsonObject whether to wrap the JSON object in an outer JSON "resourceLogs" + * object. + */ + public OtlpStdoutLogRecordExporterBuilder setWrapperJsonObject(boolean wrapperJsonObject) { + this.wrapperJsonObject = wrapperJsonObject; + return this; + } + + /** + * Sets the exporter to use the specified output stream. + * + *

      The output stream will be closed when {@link OtlpStdoutLogRecordExporter#shutdown()} is + * called unless it's {@link System#out} or {@link System#err}. + * + * @param outputStream the output stream to use. + */ + public OtlpStdoutLogRecordExporterBuilder setOutput(OutputStream outputStream) { + requireNonNull(outputStream, "outputStream"); + this.jsonWriter = new StreamJsonWriter(outputStream, TYPE); + return this; + } + + /** Sets the exporter to use the specified logger. */ + public OtlpStdoutLogRecordExporterBuilder setOutput(Logger logger) { + requireNonNull(logger, "logger"); + this.jsonWriter = new LoggerJsonWriter(logger, TYPE); + return this; + } + + /** + * Constructs a new instance of the exporter based on the builder's values. + * + * @return a new exporter's instance + */ + public OtlpStdoutLogRecordExporter build() { + return new OtlpStdoutLogRecordExporter(logger, jsonWriter, wrapperJsonObject); + } +} diff --git a/exporters/logging-otlp/src/main/java/io/opentelemetry/exporter/logging/otlp/internal/logs/OtlpStdoutLogRecordExporterComponentProvider.java b/exporters/logging-otlp/src/main/java/io/opentelemetry/exporter/logging/otlp/internal/logs/OtlpStdoutLogRecordExporterComponentProvider.java new file mode 100644 index 00000000000..204f5673c08 --- /dev/null +++ b/exporters/logging-otlp/src/main/java/io/opentelemetry/exporter/logging/otlp/internal/logs/OtlpStdoutLogRecordExporterComponentProvider.java @@ -0,0 +1,36 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.exporter.logging.otlp.internal.logs; + +import io.opentelemetry.sdk.autoconfigure.spi.internal.ComponentProvider; +import io.opentelemetry.sdk.autoconfigure.spi.internal.StructuredConfigProperties; +import io.opentelemetry.sdk.logs.export.LogRecordExporter; + +/** + * File configuration SPI implementation for {@link OtlpStdoutLogRecordExporter}. + * + *

      This class is internal and is hence not for public use. Its APIs are unstable and can change + * at any time. + */ +public class OtlpStdoutLogRecordExporterComponentProvider + implements ComponentProvider { + + @Override + public Class getType() { + return LogRecordExporter.class; + } + + @Override + public String getName() { + return "experimental-otlp/stdout"; + } + + @Override + public LogRecordExporter create(StructuredConfigProperties config) { + OtlpStdoutLogRecordExporterBuilder builder = OtlpStdoutLogRecordExporter.builder(); + return builder.build(); + } +} diff --git a/exporters/logging-otlp/src/main/java/io/opentelemetry/exporter/logging/otlp/internal/logs/OtlpStdoutLogRecordExporterProvider.java b/exporters/logging-otlp/src/main/java/io/opentelemetry/exporter/logging/otlp/internal/logs/OtlpStdoutLogRecordExporterProvider.java new file mode 100644 index 00000000000..b73262cea39 --- /dev/null +++ b/exporters/logging-otlp/src/main/java/io/opentelemetry/exporter/logging/otlp/internal/logs/OtlpStdoutLogRecordExporterProvider.java @@ -0,0 +1,29 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.exporter.logging.otlp.internal.logs; + +import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties; +import io.opentelemetry.sdk.autoconfigure.spi.logs.ConfigurableLogRecordExporterProvider; +import io.opentelemetry.sdk.logs.export.LogRecordExporter; + +/** + * {@link LogRecordExporter} SPI implementation for {@link OtlpStdoutLogRecordExporter}. + * + *

      This class is internal and is hence not for public use. Its APIs are unstable and can change + * at any time. + */ +public class OtlpStdoutLogRecordExporterProvider implements ConfigurableLogRecordExporterProvider { + @Override + public LogRecordExporter createExporter(ConfigProperties config) { + OtlpStdoutLogRecordExporterBuilder builder = OtlpStdoutLogRecordExporter.builder(); + return builder.build(); + } + + @Override + public String getName() { + return "experimental-otlp/stdout"; + } +} diff --git a/exporters/logging-otlp/src/main/java/io/opentelemetry/exporter/logging/otlp/JsonUtil.java b/exporters/logging-otlp/src/main/java/io/opentelemetry/exporter/logging/otlp/internal/writer/JsonUtil.java similarity index 58% rename from exporters/logging-otlp/src/main/java/io/opentelemetry/exporter/logging/otlp/JsonUtil.java rename to exporters/logging-otlp/src/main/java/io/opentelemetry/exporter/logging/otlp/internal/writer/JsonUtil.java index b4b8cbc577c..0b74ed8a478 100644 --- a/exporters/logging-otlp/src/main/java/io/opentelemetry/exporter/logging/otlp/JsonUtil.java +++ b/exporters/logging-otlp/src/main/java/io/opentelemetry/exporter/logging/otlp/internal/writer/JsonUtil.java @@ -3,18 +3,22 @@ * SPDX-License-Identifier: Apache-2.0 */ -package io.opentelemetry.exporter.logging.otlp; +package io.opentelemetry.exporter.logging.otlp.internal.writer; import com.fasterxml.jackson.core.JsonFactory; import com.fasterxml.jackson.core.JsonGenerator; import com.fasterxml.jackson.core.io.SegmentedStringWriter; import java.io.IOException; -final class JsonUtil { +/** + * This class is internal and is hence not for public use. Its APIs are unstable and can change at + * any time. + */ +public final class JsonUtil { - static final JsonFactory JSON_FACTORY = new JsonFactory(); + public static final JsonFactory JSON_FACTORY = new JsonFactory(); - static JsonGenerator create(SegmentedStringWriter stringWriter) { + public static JsonGenerator create(SegmentedStringWriter stringWriter) { try { return JSON_FACTORY.createGenerator(stringWriter); } catch (IOException e) { diff --git a/exporters/logging-otlp/src/main/java/io/opentelemetry/exporter/logging/otlp/internal/writer/JsonWriter.java b/exporters/logging-otlp/src/main/java/io/opentelemetry/exporter/logging/otlp/internal/writer/JsonWriter.java new file mode 100644 index 00000000000..bfee16cba65 --- /dev/null +++ b/exporters/logging-otlp/src/main/java/io/opentelemetry/exporter/logging/otlp/internal/writer/JsonWriter.java @@ -0,0 +1,21 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.exporter.logging.otlp.internal.writer; + +import io.opentelemetry.exporter.internal.marshal.Marshaler; +import io.opentelemetry.sdk.common.CompletableResultCode; + +/** + * This class is internal and is hence not for public use. Its APIs are unstable and can change at + * any time. + */ +public interface JsonWriter { + CompletableResultCode write(Marshaler exportRequest); + + CompletableResultCode flush(); + + CompletableResultCode close(); +} diff --git a/exporters/logging-otlp/src/main/java/io/opentelemetry/exporter/logging/otlp/internal/writer/LoggerJsonWriter.java b/exporters/logging-otlp/src/main/java/io/opentelemetry/exporter/logging/otlp/internal/writer/LoggerJsonWriter.java new file mode 100644 index 00000000000..1286e116f03 --- /dev/null +++ b/exporters/logging-otlp/src/main/java/io/opentelemetry/exporter/logging/otlp/internal/writer/LoggerJsonWriter.java @@ -0,0 +1,65 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.exporter.logging.otlp.internal.writer; + +import static io.opentelemetry.exporter.logging.otlp.internal.writer.JsonUtil.JSON_FACTORY; + +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.core.io.SegmentedStringWriter; +import io.opentelemetry.exporter.internal.marshal.Marshaler; +import io.opentelemetry.sdk.common.CompletableResultCode; +import java.io.IOException; +import java.util.logging.Level; +import java.util.logging.Logger; + +/** + * This class is internal and is hence not for public use. Its APIs are unstable and can change at + * any time. + */ +public class LoggerJsonWriter implements JsonWriter { + + private final Logger logger; + private final String type; + + public LoggerJsonWriter(Logger logger, String type) { + this.logger = logger; + this.type = type; + } + + @Override + public CompletableResultCode write(Marshaler exportRequest) { + SegmentedStringWriter sw = new SegmentedStringWriter(JSON_FACTORY._getBufferRecycler()); + try (JsonGenerator gen = JsonUtil.create(sw)) { + exportRequest.writeJsonTo(gen); + } catch (IOException e) { + logger.log(Level.WARNING, "Unable to write OTLP JSON " + type, e); + return CompletableResultCode.ofFailure(); + } + + try { + logger.log(Level.INFO, sw.getAndClear()); + return CompletableResultCode.ofSuccess(); + } catch (IOException e) { + logger.log(Level.WARNING, "Unable to write OTLP JSON " + type, e); + return CompletableResultCode.ofFailure(); + } + } + + @Override + public CompletableResultCode flush() { + return CompletableResultCode.ofSuccess(); + } + + @Override + public CompletableResultCode close() { + return CompletableResultCode.ofSuccess(); + } + + @Override + public String toString() { + return "LoggerJsonWriter"; + } +} diff --git a/exporters/logging-otlp/src/main/java/io/opentelemetry/exporter/logging/otlp/internal/writer/StreamJsonWriter.java b/exporters/logging-otlp/src/main/java/io/opentelemetry/exporter/logging/otlp/internal/writer/StreamJsonWriter.java new file mode 100644 index 00000000000..0674810fa5c --- /dev/null +++ b/exporters/logging-otlp/src/main/java/io/opentelemetry/exporter/logging/otlp/internal/writer/StreamJsonWriter.java @@ -0,0 +1,94 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.exporter.logging.otlp.internal.writer; + +import com.fasterxml.jackson.core.JsonFactory; +import com.fasterxml.jackson.core.JsonGenerator; +import io.opentelemetry.exporter.internal.marshal.Marshaler; +import io.opentelemetry.sdk.common.CompletableResultCode; +import io.opentelemetry.sdk.internal.ThrottlingLogger; +import java.io.IOException; +import java.io.OutputStream; +import java.util.logging.Level; +import java.util.logging.Logger; + +/** + * This class is internal and is hence not for public use. Its APIs are unstable and can change at + * any time. + */ +public class StreamJsonWriter implements JsonWriter { + + public static final JsonFactory JSON_FACTORY = new JsonFactory(); + + private static final Logger internalLogger = Logger.getLogger(StreamJsonWriter.class.getName()); + + private final ThrottlingLogger logger = new ThrottlingLogger(internalLogger); + + private final String type; + private final OutputStream outputStream; + + public StreamJsonWriter(OutputStream originalStream, String type) { + this.outputStream = originalStream; + this.type = type; + } + + @Override + public CompletableResultCode write(Marshaler exportRequest) { + try { + exportRequest.writeJsonTo( + JSON_FACTORY + .createGenerator(outputStream) + .disable(JsonGenerator.Feature.AUTO_CLOSE_TARGET)); + return CompletableResultCode.ofSuccess(); + } catch (IOException e) { + logger.log(Level.WARNING, "Unable to write OTLP JSON " + type, e); + return CompletableResultCode.ofFailure(); + } + } + + @Override + public CompletableResultCode flush() { + try { + outputStream.flush(); + return CompletableResultCode.ofSuccess(); + } catch (IOException e) { + logger.log(Level.WARNING, "Failed to flush items", e); + return CompletableResultCode.ofFailure(); + } + } + + @SuppressWarnings("SystemOut") + @Override + public CompletableResultCode close() { + if (outputStream == System.out || outputStream == System.err) { + // closing System.out or System.err is not allowed - it breaks the output stream + return CompletableResultCode.ofSuccess(); + } + try { + outputStream.close(); + return CompletableResultCode.ofSuccess(); + } catch (IOException e) { + logger.log(Level.WARNING, "Failed to close stream", e); + return CompletableResultCode.ofFailure(); + } + } + + @Override + public String toString() { + return "StreamJsonWriter{" + "outputStream=" + getName(outputStream) + '}'; + } + + @SuppressWarnings("SystemOut") + private static String getName(OutputStream outputStream) { + if (outputStream == System.out) { + return "stdout"; + } + if (outputStream == System.err) { + return "stderr"; + } + return outputStream.toString(); + } +} diff --git a/exporters/logging-otlp/src/main/resources/META-INF/services/io.opentelemetry.sdk.autoconfigure.spi.internal.ComponentProvider b/exporters/logging-otlp/src/main/resources/META-INF/services/io.opentelemetry.sdk.autoconfigure.spi.internal.ComponentProvider new file mode 100644 index 00000000000..76364a2dae4 --- /dev/null +++ b/exporters/logging-otlp/src/main/resources/META-INF/services/io.opentelemetry.sdk.autoconfigure.spi.internal.ComponentProvider @@ -0,0 +1 @@ +io.opentelemetry.exporter.logging.otlp.internal.logs.OtlpStdoutLogRecordExporterComponentProvider diff --git a/exporters/logging-otlp/src/main/resources/META-INF/services/io.opentelemetry.sdk.autoconfigure.spi.logs.ConfigurableLogRecordExporterProvider b/exporters/logging-otlp/src/main/resources/META-INF/services/io.opentelemetry.sdk.autoconfigure.spi.logs.ConfigurableLogRecordExporterProvider index 9119f54ef00..20763b2e4e5 100644 --- a/exporters/logging-otlp/src/main/resources/META-INF/services/io.opentelemetry.sdk.autoconfigure.spi.logs.ConfigurableLogRecordExporterProvider +++ b/exporters/logging-otlp/src/main/resources/META-INF/services/io.opentelemetry.sdk.autoconfigure.spi.logs.ConfigurableLogRecordExporterProvider @@ -1 +1,2 @@ -io.opentelemetry.exporter.logging.otlp.internal.LoggingLogRecordExporterProvider +io.opentelemetry.exporter.logging.otlp.internal.logs.LoggingLogRecordExporterProvider +io.opentelemetry.exporter.logging.otlp.internal.logs.OtlpStdoutLogRecordExporterProvider diff --git a/exporters/logging-otlp/src/test/java/io/opentelemetry/exporter/logging/otlp/OtlpJsonLoggingLogRecordExporterTest.java b/exporters/logging-otlp/src/test/java/io/opentelemetry/exporter/logging/otlp/OtlpJsonLoggingLogRecordExporterTest.java index 27ce4c3ea99..75677620dbb 100644 --- a/exporters/logging-otlp/src/test/java/io/opentelemetry/exporter/logging/otlp/OtlpJsonLoggingLogRecordExporterTest.java +++ b/exporters/logging-otlp/src/test/java/io/opentelemetry/exporter/logging/otlp/OtlpJsonLoggingLogRecordExporterTest.java @@ -5,25 +5,11 @@ package io.opentelemetry.exporter.logging.otlp; -import static io.opentelemetry.api.common.AttributeKey.booleanKey; -import static io.opentelemetry.api.common.AttributeKey.longKey; -import static io.opentelemetry.api.common.AttributeKey.stringKey; import static org.assertj.core.api.Assertions.assertThat; import io.github.netmikey.logunit.api.LogCapturer; -import io.opentelemetry.api.common.Attributes; -import io.opentelemetry.api.logs.Severity; -import io.opentelemetry.api.trace.SpanContext; -import io.opentelemetry.api.trace.TraceFlags; -import io.opentelemetry.api.trace.TraceState; import io.opentelemetry.internal.testing.slf4j.SuppressLogger; -import io.opentelemetry.sdk.common.InstrumentationScopeInfo; -import io.opentelemetry.sdk.logs.data.LogRecordData; import io.opentelemetry.sdk.logs.export.LogRecordExporter; -import io.opentelemetry.sdk.resources.Resource; -import io.opentelemetry.sdk.testing.logs.TestLogRecordData; -import java.util.Arrays; -import java.util.Collections; import java.util.concurrent.TimeUnit; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -34,49 +20,7 @@ @SuppressLogger(OtlpJsonLoggingLogRecordExporter.class) class OtlpJsonLoggingLogRecordExporterTest { - private static final Resource RESOURCE = - Resource.create(Attributes.builder().put("key", "value").build()); - - private static final LogRecordData LOG1 = - TestLogRecordData.builder() - .setResource(RESOURCE) - .setInstrumentationScopeInfo( - InstrumentationScopeInfo.builder("instrumentation") - .setVersion("1") - .setAttributes(Attributes.builder().put("key", "value").build()) - .build()) - .setBody("body1") - .setSeverity(Severity.INFO) - .setSeverityText("INFO") - .setTimestamp(100L, TimeUnit.NANOSECONDS) - .setObservedTimestamp(200L, TimeUnit.NANOSECONDS) - .setAttributes(Attributes.of(stringKey("animal"), "cat", longKey("lives"), 9L)) - .setSpanContext( - SpanContext.create( - "12345678876543211234567887654322", - "8765432112345876", - TraceFlags.getDefault(), - TraceState.getDefault())) - .build(); - - private static final LogRecordData LOG2 = - TestLogRecordData.builder() - .setResource(RESOURCE) - .setInstrumentationScopeInfo( - InstrumentationScopeInfo.builder("instrumentation2").setVersion("2").build()) - .setBody("body2") - .setSeverity(Severity.INFO) - .setSeverityText("INFO") - .setTimestamp(100L, TimeUnit.NANOSECONDS) - .setObservedTimestamp(200L, TimeUnit.NANOSECONDS) - .setAttributes(Attributes.of(booleanKey("important"), true)) - .setSpanContext( - SpanContext.create( - "12345678876543211234567887654322", - "8765432112345875", - TraceFlags.getDefault(), - TraceState.getDefault())) - .build(); + private final TestDataExporter testDataExporter = TestDataExporter.forLogs(); @RegisterExtension LogCapturer logs = LogCapturer.create().captureForType(OtlpJsonLoggingLogRecordExporter.class); @@ -90,90 +34,21 @@ void setUp() { @Test void log() throws Exception { - exporter.export(Arrays.asList(LOG1, LOG2)); + testDataExporter.export(exporter); assertThat(logs.getEvents()) .hasSize(1) .allSatisfy(log -> assertThat(log.getLevel()).isEqualTo(Level.INFO)); String message = logs.getEvents().get(0).getMessage(); - JSONAssert.assertEquals( - "{" - + " \"resource\": {" - + " \"attributes\": [{" - + " \"key\":\"key\"," - + " \"value\": {" - + " \"stringValue\":\"value\"" - + " }" - + " }]" - + " }," - + " \"scopeLogs\": [{" - + " \"scope\":{" - + " \"name\":\"instrumentation2\"," - + " \"version\":\"2\"" - + " }," - + " \"logRecords\": [{" - + " \"timeUnixNano\":\"100\"," - + " \"observedTimeUnixNano\":\"200\"," - + " \"severityNumber\":9," - + " \"severityText\":\"INFO\"," - + " \"body\": {" - + " \"stringValue\":\"body2\"" - + " }," - + " \"attributes\": [{" - + " \"key\":\"important\"," - + " \"value\": {" - + " \"boolValue\":true" - + " }" - + " }]," - + " \"traceId\":\"12345678876543211234567887654322\"," - + " \"spanId\":\"8765432112345875\"" - + " }]" - + " }, {" - + " \"scope\": {" - + " \"name\":\"instrumentation\"," - + " \"version\":\"1\"," - + " \"attributes\": [{" - + " \"key\":\"key\"," - + " \"value\": {" - + " \"stringValue\":\"value\"" - + " }" - + " }]" - + " }," - + " \"logRecords\": [{" - + " \"timeUnixNano\":\"100\"," - + " \"observedTimeUnixNano\":\"200\"," - + " \"severityNumber\":9," - + " \"severityText\":\"INFO\"," - + " \"body\": {" - + " \"stringValue\":\"body1\"" - + " }," - + " \"attributes\": [{" - + " \"key\":\"animal\"," - + " \"value\": {" - + " \"stringValue\":\"cat\"" - + " }" - + " }, {" - + " \"key\":\"lives\"," - + " \"value\":{" - + " \"intValue\":\"9\"" - + " }" - + " }]," - + " \"traceId\":\"12345678876543211234567887654322\"," - + " \"spanId\":\"8765432112345876\"" - + " }]" - + " }]" - + "}", - message, - /* strict= */ false); + String expectedJson = testDataExporter.getExpectedJson(false); + JSONAssert.assertEquals("Got \n" + message, expectedJson, message, /* strict= */ false); assertThat(message).doesNotContain("\n"); } @Test void shutdown() { assertThat(exporter.shutdown().isSuccess()).isTrue(); - assertThat( - exporter.export(Collections.singletonList(LOG1)).join(10, TimeUnit.SECONDS).isSuccess()) - .isFalse(); + assertThat(testDataExporter.export(exporter).join(10, TimeUnit.SECONDS).isSuccess()).isFalse(); assertThat(logs.getEvents()).isEmpty(); assertThat(exporter.shutdown().isSuccess()).isTrue(); logs.assertContains("Calling shutdown() multiple times."); diff --git a/exporters/logging-otlp/src/test/java/io/opentelemetry/exporter/logging/otlp/OtlpStdoutLogRecordExporterTest.java b/exporters/logging-otlp/src/test/java/io/opentelemetry/exporter/logging/otlp/OtlpStdoutLogRecordExporterTest.java new file mode 100644 index 00000000000..f98b81b69af --- /dev/null +++ b/exporters/logging-otlp/src/test/java/io/opentelemetry/exporter/logging/otlp/OtlpStdoutLogRecordExporterTest.java @@ -0,0 +1,287 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.exporter.logging.otlp; + +import static java.util.Collections.emptyMap; +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.mock; + +import com.google.common.collect.ImmutableList; +import com.google.common.collect.Streams; +import io.github.netmikey.logunit.api.LogCapturer; +import io.opentelemetry.exporter.logging.otlp.internal.logs.OtlpStdoutLogRecordExporter; +import io.opentelemetry.exporter.logging.otlp.internal.logs.OtlpStdoutLogRecordExporterBuilder; +import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties; +import io.opentelemetry.sdk.autoconfigure.spi.internal.ComponentProvider; +import io.opentelemetry.sdk.autoconfigure.spi.internal.DefaultConfigProperties; +import io.opentelemetry.sdk.autoconfigure.spi.internal.StructuredConfigProperties; +import io.opentelemetry.sdk.autoconfigure.spi.logs.ConfigurableLogRecordExporterProvider; +import io.opentelemetry.sdk.logs.export.LogRecordExporter; +import java.io.BufferedOutputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.io.PrintStream; +import java.io.UnsupportedEncodingException; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.ServiceLoader; +import java.util.concurrent.TimeUnit; +import java.util.logging.Logger; +import java.util.stream.Stream; +import javax.annotation.Nullable; +import org.json.JSONException; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; +import org.junit.jupiter.api.io.TempDir; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; +import org.skyscreamer.jsonassert.JSONAssert; +import org.slf4j.event.LoggingEvent; + +class OtlpStdoutLogRecordExporterTest { + + private static final ByteArrayOutputStream SYSTEM_OUT_STREAM = new ByteArrayOutputStream(); + private static final PrintStream SYSTEM_OUT_PRINT_STREAM = new PrintStream(SYSTEM_OUT_STREAM); + private static PrintStream systemOut; + private static final Class EXPORTER_CLASS = OtlpStdoutLogRecordExporter.class; + private static final String DEFAULT_CONFIG_STRING = + "OtlpStdoutLogRecordExporter{jsonWriter=StreamJsonWriter{outputStream=stdout}, wrapperJsonObject=true}"; + private static final String TYPE = "experimental-otlp/stdout"; + private static final TestDataExporter TEST_DATA_EXPORTER = + TestDataExporter.forLogs(); + private static final Class PROVIDER_CLASS = ConfigurableLogRecordExporterProvider.class; + private static final Class COMPONENT_PROVIDER_TYPE = LogRecordExporter.class; + + @RegisterExtension + LogCapturer logs = LogCapturer.create().captureForType(OtlpStdoutLogRecordExporter.class); + + @TempDir Path tempDir; + + @BeforeAll + @SuppressWarnings("SystemOut") + static void setUpStatic() { + systemOut = System.out; + System.setOut(SYSTEM_OUT_PRINT_STREAM); + } + + @AfterAll + @SuppressWarnings("SystemOut") + static void tearDownStatic() { + System.setOut(systemOut); + } + + @BeforeEach + void setUp() { + SYSTEM_OUT_STREAM.reset(); + } + + static Stream exportTestCases() { + return ImmutableList.of( + testCase(OutputType.SYSTEM_OUT, /* wrapperJsonObject= */ true), + testCase(OutputType.SYSTEM_OUT, /* wrapperJsonObject= */ false), + testCase(OutputType.FILE, /* wrapperJsonObject= */ true), + testCase(OutputType.FILE, /* wrapperJsonObject= */ false), + testCase(OutputType.FILE_AND_BUFFERED_WRITER, /* wrapperJsonObject= */ true), + testCase(OutputType.FILE_AND_BUFFERED_WRITER, /* wrapperJsonObject= */ false), + testCase(OutputType.LOGGER, /* wrapperJsonObject= */ true), + testCase(OutputType.LOGGER, /* wrapperJsonObject= */ false)) + .stream(); + } + + private static Arguments testCase(OutputType type, boolean wrapperJsonObject) { + return Arguments.of( + "output=" + type + ", wrapperJsonObject=" + wrapperJsonObject, + new TestCase(type, wrapperJsonObject)); + } + + private static Stream loadSpi(Class type) { + return Streams.stream(ServiceLoader.load(type, type.getClassLoader()).iterator()); + } + + private static OtlpStdoutLogRecordExporter createDefaultExporter() { + return OtlpStdoutLogRecordExporter.builder().build(); + } + + private static OtlpStdoutLogRecordExporter createExporter( + @Nullable OutputStream outputStream, boolean wrapperJsonObject) { + OtlpStdoutLogRecordExporterBuilder builder = + OtlpStdoutLogRecordExporter.builder().setWrapperJsonObject(wrapperJsonObject); + if (outputStream != null) { + builder.setOutput(outputStream); + } else { + builder.setOutput(Logger.getLogger(EXPORTER_CLASS.getName())); + } + return builder.build(); + } + + private String output(@Nullable OutputStream outputStream, @Nullable Path file) { + if (outputStream == null) { + return logs.getEvents().stream() + .map(LoggingEvent::getMessage) + .reduce("", (a, b) -> a + b + "\n") + .trim(); + } + + if (file != null) { + try { + return new String(Files.readAllBytes(file), StandardCharsets.UTF_8); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + + try { + return SYSTEM_OUT_STREAM.toString(StandardCharsets.UTF_8.name()); + } catch (UnsupportedEncodingException e) { + throw new RuntimeException(e); + } + } + + @SuppressWarnings("SystemOut") + @ParameterizedTest(name = "{0}") + @MethodSource("exportTestCases") + void exportWithProgrammaticConfig(String name, TestCase testCase) + throws JSONException, IOException { + OutputStream outputStream; + Path file = null; + switch (testCase.getOutputType()) { + case LOGGER: + outputStream = null; + break; + case SYSTEM_OUT: + outputStream = System.out; + break; + case FILE: + file = tempDir.resolve("test.log"); + outputStream = Files.newOutputStream(file); + break; + case FILE_AND_BUFFERED_WRITER: + file = tempDir.resolve("test.log"); + outputStream = new BufferedOutputStream(Files.newOutputStream(file)); + break; + default: + throw new IllegalStateException("Unexpected value: " + testCase.getOutputType()); + } + OtlpStdoutLogRecordExporter exporter = + createExporter(outputStream, testCase.isWrapperJsonObject()); + TEST_DATA_EXPORTER.export(exporter); + + String output = output(outputStream, file); + String expectedJson = TEST_DATA_EXPORTER.getExpectedJson(testCase.isWrapperJsonObject()); + JSONAssert.assertEquals("Got \n" + output, expectedJson, output, false); + + if (testCase.isWrapperJsonObject()) { + assertThat(output).doesNotContain("\n"); + } + } + + @Test + void testShutdown() { + OtlpStdoutLogRecordExporter exporter = createDefaultExporter(); + assertThat(TEST_DATA_EXPORTER.shutdown(exporter).isSuccess()).isTrue(); + assertThat(TEST_DATA_EXPORTER.export(exporter).join(10, TimeUnit.SECONDS).isSuccess()) + .isFalse(); + assertThat(TEST_DATA_EXPORTER.flush(exporter).join(10, TimeUnit.SECONDS).isSuccess()).isTrue(); + assertThat(output(null, null)).isEmpty(); + assertThat(TEST_DATA_EXPORTER.shutdown(exporter).isSuccess()).isTrue(); + logs.assertContains("Calling shutdown() multiple times."); + } + + @Test + void defaultToString() { + assertThat(createDefaultExporter().toString()).isEqualTo(DEFAULT_CONFIG_STRING); + + assertThat(loadExporter(DefaultConfigProperties.createFromMap(emptyMap()), TYPE).toString()) + .isEqualTo(DEFAULT_CONFIG_STRING); + } + + private OtlpStdoutLogRecordExporter exporterFromComponentProvider( + StructuredConfigProperties properties) { + return (OtlpStdoutLogRecordExporter) + ((ComponentProvider) + loadSpi(ComponentProvider.class) + .filter( + p -> { + ComponentProvider c = (ComponentProvider) p; + return "experimental-otlp/stdout".equals(c.getName()) + && c.getType().equals(COMPONENT_PROVIDER_TYPE); + }) + .findFirst() + .orElseThrow(() -> new IllegalStateException("No provider found"))) + .create(properties); + } + + @Test + void componentProviderConfig() { + StructuredConfigProperties properties = mock(StructuredConfigProperties.class); + OtlpStdoutLogRecordExporter exporter = exporterFromComponentProvider(properties); + + assertThat(exporter).extracting("wrapperJsonObject").isEqualTo(true); + assertThat(exporter) + .extracting("jsonWriter") + .extracting(Object::toString) + .isEqualTo("StreamJsonWriter{outputStream=stdout}"); + } + + private OtlpStdoutLogRecordExporter loadExporter(ConfigProperties config, String name) { + Object provider = loadProvider(name); + + try { + return (OtlpStdoutLogRecordExporter) + provider + .getClass() + .getDeclaredMethod("createExporter", ConfigProperties.class) + .invoke(provider, config); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + private Object loadProvider(String want) { + return loadSpi(PROVIDER_CLASS) + .filter( + p -> { + try { + return want.equals(p.getClass().getDeclaredMethod("getName").invoke(p)); + } catch (Exception e) { + throw new RuntimeException(e); + } + }) + .findFirst() + .orElseThrow(() -> new IllegalStateException("No provider found")); + } + + enum OutputType { + LOGGER, + SYSTEM_OUT, + FILE, + FILE_AND_BUFFERED_WRITER + } + + static class TestCase { + private final boolean wrapperJsonObject; + private final OutputType outputType; + + public TestCase(OutputType outputType, boolean wrapperJsonObject) { + this.outputType = outputType; + this.wrapperJsonObject = wrapperJsonObject; + } + + public OutputType getOutputType() { + return outputType; + } + + public boolean isWrapperJsonObject() { + return wrapperJsonObject; + } + } +} diff --git a/exporters/logging-otlp/src/test/java/io/opentelemetry/exporter/logging/otlp/TestDataExporter.java b/exporters/logging-otlp/src/test/java/io/opentelemetry/exporter/logging/otlp/TestDataExporter.java new file mode 100644 index 00000000000..53b51629e1c --- /dev/null +++ b/exporters/logging-otlp/src/test/java/io/opentelemetry/exporter/logging/otlp/TestDataExporter.java @@ -0,0 +1,112 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.exporter.logging.otlp; + +import static io.opentelemetry.api.common.AttributeKey.booleanKey; +import static io.opentelemetry.api.common.AttributeKey.longKey; +import static io.opentelemetry.api.common.AttributeKey.stringKey; + +import com.google.common.io.Resources; +import io.opentelemetry.api.common.Attributes; +import io.opentelemetry.api.logs.Severity; +import io.opentelemetry.api.trace.SpanContext; +import io.opentelemetry.api.trace.TraceFlags; +import io.opentelemetry.api.trace.TraceState; +import io.opentelemetry.sdk.common.CompletableResultCode; +import io.opentelemetry.sdk.common.InstrumentationScopeInfo; +import io.opentelemetry.sdk.logs.data.LogRecordData; +import io.opentelemetry.sdk.logs.export.LogRecordExporter; +import io.opentelemetry.sdk.resources.Resource; +import io.opentelemetry.sdk.testing.logs.TestLogRecordData; +import java.io.IOException; +import java.nio.charset.StandardCharsets; +import java.util.Arrays; +import java.util.concurrent.TimeUnit; + +abstract class TestDataExporter { + + private final String expectedFileNoWrapper; + private final String expectedFileWrapper; + private static final Resource RESOURCE = + Resource.create(Attributes.builder().put("key", "value").build()); + + private static final LogRecordData LOG1 = + TestLogRecordData.builder() + .setResource(RESOURCE) + .setInstrumentationScopeInfo( + InstrumentationScopeInfo.builder("instrumentation") + .setVersion("1") + .setAttributes(Attributes.builder().put("key", "value").build()) + .build()) + .setBody("body1") + .setSeverity(Severity.INFO) + .setSeverityText("INFO") + .setTimestamp(100L, TimeUnit.NANOSECONDS) + .setObservedTimestamp(200L, TimeUnit.NANOSECONDS) + .setAttributes(Attributes.of(stringKey("animal"), "cat", longKey("lives"), 9L)) + .setSpanContext( + SpanContext.create( + "12345678876543211234567887654322", + "8765432112345876", + TraceFlags.getDefault(), + TraceState.getDefault())) + .build(); + + private static final LogRecordData LOG2 = + TestLogRecordData.builder() + .setResource(RESOURCE) + .setInstrumentationScopeInfo( + InstrumentationScopeInfo.builder("instrumentation2").setVersion("2").build()) + .setBody("body2") + .setSeverity(Severity.INFO) + .setSeverityText("INFO") + .setTimestamp(100L, TimeUnit.NANOSECONDS) + .setObservedTimestamp(200L, TimeUnit.NANOSECONDS) + .setAttributes(Attributes.of(booleanKey("important"), true)) + .setSpanContext( + SpanContext.create( + "12345678876543211234567887654322", + "8765432112345875", + TraceFlags.getDefault(), + TraceState.getDefault())) + .build(); + + public TestDataExporter(String expectedFileNoWrapper, String expectedFileWrapper) { + this.expectedFileNoWrapper = expectedFileNoWrapper; + this.expectedFileWrapper = expectedFileWrapper; + } + + public String getExpectedJson(boolean withWrapper) throws IOException { + String file = withWrapper ? expectedFileWrapper : expectedFileNoWrapper; + return Resources.toString(Resources.getResource(file), StandardCharsets.UTF_8); + } + + abstract CompletableResultCode export(T exporter); + + abstract CompletableResultCode flush(T exporter); + + abstract CompletableResultCode shutdown(T exporter); + + static TestDataExporter forLogs() { + return new TestDataExporter( + "expected-logs.json", "expected-logs-wrapper.json") { + @Override + public CompletableResultCode export(LogRecordExporter exporter) { + return exporter.export(Arrays.asList(LOG1, LOG2)); + } + + @Override + public CompletableResultCode flush(LogRecordExporter exporter) { + return exporter.flush(); + } + + @Override + public CompletableResultCode shutdown(LogRecordExporter exporter) { + return exporter.shutdown(); + } + }; + } +} diff --git a/exporters/logging-otlp/src/test/java/io/opentelemetry/exporter/logging/otlp/internal/LoggingExporterProviderTest.java b/exporters/logging-otlp/src/test/java/io/opentelemetry/exporter/logging/otlp/internal/LoggingExporterProviderTest.java deleted file mode 100644 index decd00aec4b..00000000000 --- a/exporters/logging-otlp/src/test/java/io/opentelemetry/exporter/logging/otlp/internal/LoggingExporterProviderTest.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package io.opentelemetry.exporter.logging.otlp.internal; - -import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.assertThat; - -import io.opentelemetry.exporter.logging.otlp.OtlpJsonLoggingLogRecordExporter; -import io.opentelemetry.exporter.logging.otlp.OtlpJsonLoggingMetricExporter; -import io.opentelemetry.exporter.logging.otlp.OtlpJsonLoggingSpanExporter; -import io.opentelemetry.sdk.autoconfigure.spi.internal.DefaultConfigProperties; -import java.util.Collections; -import org.junit.jupiter.api.Test; - -class LoggingExporterProviderTest { - - @Test - void logRecordExporterProvider() { - LoggingLogRecordExporterProvider provider = new LoggingLogRecordExporterProvider(); - assertThat(provider.getName()).isEqualTo("logging-otlp"); - assertThat( - provider.createExporter(DefaultConfigProperties.createFromMap(Collections.emptyMap()))) - .isInstanceOf(OtlpJsonLoggingLogRecordExporter.class); - } - - @Test - void metricExporterProvider() { - LoggingMetricExporterProvider provider = new LoggingMetricExporterProvider(); - assertThat(provider.getName()).isEqualTo("logging-otlp"); - assertThat( - provider.createExporter(DefaultConfigProperties.createFromMap(Collections.emptyMap()))) - .isInstanceOf(OtlpJsonLoggingMetricExporter.class); - } - - @Test - void spanExporterProvider() { - LoggingSpanExporterProvider provider = new LoggingSpanExporterProvider(); - assertThat(provider.getName()).isEqualTo("logging-otlp"); - assertThat( - provider.createExporter(DefaultConfigProperties.createFromMap(Collections.emptyMap()))) - .isInstanceOf(OtlpJsonLoggingSpanExporter.class); - } -} diff --git a/exporters/logging-otlp/src/test/java/io/opentelemetry/exporter/logging/otlp/internal/writer/LoggerJsonWriterTest.java b/exporters/logging-otlp/src/test/java/io/opentelemetry/exporter/logging/otlp/internal/writer/LoggerJsonWriterTest.java new file mode 100644 index 00000000000..8cba4ef9707 --- /dev/null +++ b/exporters/logging-otlp/src/test/java/io/opentelemetry/exporter/logging/otlp/internal/writer/LoggerJsonWriterTest.java @@ -0,0 +1,44 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.exporter.logging.otlp.internal.writer; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.mock; + +import com.fasterxml.jackson.core.JsonGenerator; +import io.github.netmikey.logunit.api.LogCapturer; +import io.opentelemetry.exporter.internal.marshal.Marshaler; +import java.io.IOException; +import java.util.logging.Logger; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; +import org.mockito.Mockito; + +class LoggerJsonWriterTest { + + @RegisterExtension + static final LogCapturer logs = LogCapturer.create().captureForType(LoggerJsonWriter.class); + + @Test + void testToString() { + LoggerJsonWriter writer = new LoggerJsonWriter(null, "type"); + assertThat(writer.toString()).isEqualTo("LoggerJsonWriter"); + } + + @Test + void error() throws IOException { + Marshaler marshaler = mock(Marshaler.class); + Mockito.doThrow(new IOException("test")).when(marshaler).writeJsonTo(any(JsonGenerator.class)); + + Logger logger = Logger.getLogger(LoggerJsonWriter.class.getName()); + + LoggerJsonWriter writer = new LoggerJsonWriter(logger, "type"); + writer.write(marshaler); + + logs.assertContains("Unable to write OTLP JSON type"); + } +} diff --git a/exporters/logging-otlp/src/test/java/io/opentelemetry/exporter/logging/otlp/internal/writer/StreamJsonWriterTest.java b/exporters/logging-otlp/src/test/java/io/opentelemetry/exporter/logging/otlp/internal/writer/StreamJsonWriterTest.java new file mode 100644 index 00000000000..2245a15e0c0 --- /dev/null +++ b/exporters/logging-otlp/src/test/java/io/opentelemetry/exporter/logging/otlp/internal/writer/StreamJsonWriterTest.java @@ -0,0 +1,72 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.exporter.logging.otlp.internal.writer; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.mock; + +import com.fasterxml.jackson.core.JsonGenerator; +import io.github.netmikey.logunit.api.LogCapturer; +import io.opentelemetry.exporter.internal.marshal.Marshaler; +import java.io.FilterOutputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.nio.file.Files; +import java.nio.file.Path; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; +import org.junit.jupiter.api.io.TempDir; +import org.mockito.Mockito; + +@SuppressWarnings("SystemOut") +class StreamJsonWriterTest { + + @RegisterExtension + static final LogCapturer logs = LogCapturer.create().captureForType(StreamJsonWriter.class); + + @TempDir Path tempDir; + + @Test + @SuppressWarnings("SystemOut") + void testToString() throws IOException { + assertThat( + new StreamJsonWriter(Files.newOutputStream(tempDir.resolve("foo")), "type").toString()) + .startsWith("StreamJsonWriter{outputStream=") + .contains("Channel"); + assertThat(new StreamJsonWriter(System.out, "type").toString()) + .isEqualTo("StreamJsonWriter{outputStream=stdout}"); + assertThat(new StreamJsonWriter(System.err, "type").toString()) + .isEqualTo("StreamJsonWriter{outputStream=stderr}"); + } + + @Test + void errorWriting() throws IOException { + Marshaler marshaler = mock(Marshaler.class); + Mockito.doThrow(new IOException("test")).when(marshaler).writeJsonTo(any(JsonGenerator.class)); + + StreamJsonWriter writer = new StreamJsonWriter(System.out, "type"); + writer.write(marshaler); + + logs.assertContains("Unable to write OTLP JSON type"); + } + + @Test + void errorFlushing() { + OutputStream outputStream = + new FilterOutputStream(System.out) { + @Override + public void flush() throws IOException { + throw new IOException("No flush"); + } + }; + + StreamJsonWriter writer = new StreamJsonWriter(outputStream, "type"); + writer.flush(); + + logs.assertContains("Failed to flush items"); + } +} diff --git a/exporters/logging-otlp/src/test/resources/expected-logs-wrapper.json b/exporters/logging-otlp/src/test/resources/expected-logs-wrapper.json new file mode 100644 index 00000000000..887fdb13d4b --- /dev/null +++ b/exporters/logging-otlp/src/test/resources/expected-logs-wrapper.json @@ -0,0 +1,89 @@ +{ + "resourceLogs": [ + { + "resource": { + "attributes": [ + { + "key": "key", + "value": { + "stringValue": "value" + } + } + ] + }, + "scopeLogs": [ + { + "scope": { + "name": "instrumentation", + "version": "1", + "attributes": [ + { + "key": "key", + "value": { + "stringValue": "value" + } + } + ] + }, + "logRecords": [ + { + "timeUnixNano": "100", + "observedTimeUnixNano": "200", + "severityNumber": 9, + "severityText": "INFO", + "body": { + "stringValue": "body1" + }, + "attributes": [ + { + "key": "animal", + "value": { + "stringValue": "cat" + } + }, + { + "key": "lives", + "value": { + "intValue": "9" + } + } + ], + "droppedAttributesCount": -2, + "traceId": "12345678876543211234567887654322", + "spanId": "8765432112345876" + } + ] + }, + { + "scope": { + "name": "instrumentation2", + "version": "2", + "attributes": [] + }, + "logRecords": [ + { + "timeUnixNano": "100", + "observedTimeUnixNano": "200", + "severityNumber": 9, + "severityText": "INFO", + "body": { + "stringValue": "body2" + }, + "attributes": [ + { + "key": "important", + "value": { + "boolValue": true + } + } + ], + "droppedAttributesCount": -1, + "traceId": "12345678876543211234567887654322", + "spanId": "8765432112345875" + } + ] + } + ] + } + ] +} diff --git a/exporters/logging-otlp/src/test/resources/expected-logs.json b/exporters/logging-otlp/src/test/resources/expected-logs.json new file mode 100644 index 00000000000..fe84d67c4ef --- /dev/null +++ b/exporters/logging-otlp/src/test/resources/expected-logs.json @@ -0,0 +1,86 @@ +{ + "resource": { + "attributes": [ + { + "key": "key", + "value": { + "stringValue": "value" + } + } + ] + }, + "scopeLogs": [ + { + "scope": { + "name": "instrumentation", + "version": "1", + "attributes": [ + { + "key": "key", + "value": { + "stringValue": "value" + } + } + ] + }, + "logRecords": [ + { + "timeUnixNano": "100", + "observedTimeUnixNano": "200", + "severityNumber": 9, + "severityText": "INFO", + "body": { + "stringValue": "body1" + }, + "attributes": [ + { + "key": "animal", + "value": { + "stringValue": "cat" + } + }, + { + "key": "lives", + "value": { + "intValue": "9" + } + } + ], + "droppedAttributesCount": -2, + "traceId": "12345678876543211234567887654322", + "spanId": "8765432112345876" + } + ] + }, + { + "scope": { + "name": "instrumentation2", + "version": "2", + "attributes": [] + }, + "logRecords": [ + { + "timeUnixNano": "100", + "observedTimeUnixNano": "200", + "severityNumber": 9, + "severityText": "INFO", + "body": { + "stringValue": "body2" + }, + "attributes": [ + { + "key": "important", + "value": { + "boolValue": true + } + } + ], + "droppedAttributesCount": -1, + "traceId": "12345678876543211234567887654322", + "spanId": "8765432112345875" + } + ] + } + ] +} + diff --git a/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/LogRecordExporterConfiguration.java b/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/LogRecordExporterConfiguration.java index eacdf9d7c9a..ff70fa4d114 100644 --- a/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/LogRecordExporterConfiguration.java +++ b/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/LogRecordExporterConfiguration.java @@ -30,6 +30,8 @@ final class LogRecordExporterConfiguration { EXPORTER_ARTIFACT_ID_BY_NAME.put("console", "opentelemetry-exporter-logging"); EXPORTER_ARTIFACT_ID_BY_NAME.put("logging", "opentelemetry-exporter-logging"); EXPORTER_ARTIFACT_ID_BY_NAME.put("logging-otlp", "opentelemetry-exporter-logging-otlp"); + EXPORTER_ARTIFACT_ID_BY_NAME.put( + "experimental-otlp/stdout", "opentelemetry-exporter-logging-otlp"); EXPORTER_ARTIFACT_ID_BY_NAME.put("otlp", "opentelemetry-exporter-otlp"); } diff --git a/sdk-extensions/autoconfigure/src/test/java/io/opentelemetry/sdk/autoconfigure/LogRecordExporterConfigurationTest.java b/sdk-extensions/autoconfigure/src/test/java/io/opentelemetry/sdk/autoconfigure/LogRecordExporterConfigurationTest.java index 637cb5e80fe..b8577cebf41 100644 --- a/sdk-extensions/autoconfigure/src/test/java/io/opentelemetry/sdk/autoconfigure/LogRecordExporterConfigurationTest.java +++ b/sdk-extensions/autoconfigure/src/test/java/io/opentelemetry/sdk/autoconfigure/LogRecordExporterConfigurationTest.java @@ -46,6 +46,11 @@ void configureExporter_KnownSpiExportersNotOnClasspath() { .hasMessage( "otel.logs.exporter set to \"logging-otlp\" but opentelemetry-exporter-logging-otlp" + " not found on classpath. Make sure to add it as a dependency."); + assertThatThrownBy(() -> configureExporter("experimental-otlp/stdout", spiExportersManager)) + .isInstanceOf(ConfigurationException.class) + .hasMessage( + "otel.logs.exporter set to \"experimental-otlp/stdout\" but opentelemetry-exporter-logging-otlp" + + " not found on classpath. Make sure to add it as a dependency."); assertThatThrownBy(() -> configureExporter("otlp", spiExportersManager)) .isInstanceOf(ConfigurationException.class) .hasMessage( diff --git a/sdk-extensions/autoconfigure/src/testFullConfig/java/io/opentelemetry/sdk/autoconfigure/LogRecordExporterConfigurationTest.java b/sdk-extensions/autoconfigure/src/testFullConfig/java/io/opentelemetry/sdk/autoconfigure/LogRecordExporterConfigurationTest.java index 1d670b0e04e..9043a70cdc6 100644 --- a/sdk-extensions/autoconfigure/src/testFullConfig/java/io/opentelemetry/sdk/autoconfigure/LogRecordExporterConfigurationTest.java +++ b/sdk-extensions/autoconfigure/src/testFullConfig/java/io/opentelemetry/sdk/autoconfigure/LogRecordExporterConfigurationTest.java @@ -11,6 +11,7 @@ import com.google.common.collect.ImmutableMap; import io.opentelemetry.exporter.logging.SystemOutLogRecordExporter; import io.opentelemetry.exporter.logging.otlp.OtlpJsonLoggingLogRecordExporter; +import io.opentelemetry.exporter.logging.otlp.internal.logs.OtlpStdoutLogRecordExporter; import io.opentelemetry.exporter.otlp.logs.OtlpGrpcLogRecordExporter; import io.opentelemetry.sdk.autoconfigure.internal.NamedSpiManager; import io.opentelemetry.sdk.autoconfigure.internal.SpiHelper; @@ -38,6 +39,10 @@ void configureExporter_KnownSpiExportersOnClasspath() { assertThat( LogRecordExporterConfiguration.configureExporter("logging-otlp", spiExportersManager)) .isInstanceOf(OtlpJsonLoggingLogRecordExporter.class); + assertThat( + LogRecordExporterConfiguration.configureExporter( + "experimental-otlp/stdout", spiExportersManager)) + .isInstanceOf(OtlpStdoutLogRecordExporter.class); assertThat(LogRecordExporterConfiguration.configureExporter("otlp", spiExportersManager)) .isInstanceOf(OtlpGrpcLogRecordExporter.class); } From 9249653f695d8f8ee68c0ff22426a4eed2e61c4e Mon Sep 17 00:00:00 2001 From: Teja Date: Wed, 18 Sep 2024 17:02:06 -0400 Subject: [PATCH 566/901] Adding model as suffix to generated classes. (#6721) --- ...AutoConfiguredOpenTelemetrySdkBuilder.java | 2 +- sdk-extensions/incubator/build.gradle.kts | 3 + .../fileconfig/AggregationFactory.java | 14 +- .../fileconfig/AttributesFactory.java | 6 +- .../fileconfig/FileConfiguration.java | 29 +- .../fileconfig/InstrumentSelectorFactory.java | 6 +- .../fileconfig/LogLimitsFactory.java | 8 +- .../fileconfig/LogRecordExporterFactory.java | 14 +- .../LogRecordLimitsAndAttributeLimits.java | 10 +- .../fileconfig/LogRecordProcessorFactory.java | 23 +- .../LoggerProviderAndAttributeLimits.java | 11 +- .../fileconfig/LoggerProviderFactory.java | 8 +- .../fileconfig/MeterProviderFactory.java | 22 +- .../fileconfig/MetricExporterFactory.java | 14 +- .../fileconfig/MetricReaderFactory.java | 28 +- .../OpenTelemetryConfigurationFactory.java | 6 +- .../fileconfig/PropagatorFactory.java | 6 +- .../incubator/fileconfig/ResourceFactory.java | 9 +- .../incubator/fileconfig/SamplerFactory.java | 22 +- .../fileconfig/SpanExporterFactory.java | 18 +- .../SpanLimitsAndAttributeLimits.java | 10 +- .../fileconfig/SpanLimitsFactory.java | 8 +- .../fileconfig/SpanProcessorFactory.java | 24 +- .../TracerProviderAndAttributeLimits.java | 11 +- .../fileconfig/TracerProviderFactory.java | 8 +- .../incubator/fileconfig/ViewFactory.java | 6 +- .../YamlStructuredConfigProperties.java | 4 +- .../fileconfig/AggregationFactoryTest.java | 40 +-- .../fileconfig/AttributesFactoryTest.java | 14 +- .../FileConfigurationParseTest.java | 263 +++++++++--------- .../InstrumentSelectorFactoryTest.java | 8 +- .../fileconfig/LogLimitsFactoryTest.java | 21 +- .../LogRecordExporterFactoryTest.java | 20 +- .../LogRecordProcessorFactoryTest.java | 37 +-- .../fileconfig/LoggerProviderFactoryTest.java | 30 +- .../fileconfig/MeterProviderFactoryTest.java | 34 ++- .../fileconfig/MetricExporterFactoryTest.java | 34 +-- .../fileconfig/MetricReaderFactoryTest.java | 60 ++-- ...OpenTelemetryConfigurationFactoryTest.java | 120 ++++---- .../fileconfig/PropagatorFactoryTest.java | 6 +- .../fileconfig/ResourceFactoryTest.java | 8 +- .../fileconfig/SamplerFactoryTest.java | 65 +++-- .../fileconfig/SpanExporterFactoryTest.java | 34 +-- .../fileconfig/SpanLimitsFactoryTest.java | 18 +- .../fileconfig/SpanProcessorFactoryTest.java | 36 +-- .../fileconfig/TracerProviderFactoryTest.java | 34 +-- .../incubator/fileconfig/ViewFactoryTest.java | 14 +- .../YamlStructuredConfigPropertiesTest.java | 4 +- 48 files changed, 627 insertions(+), 603 deletions(-) diff --git a/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/AutoConfiguredOpenTelemetrySdkBuilder.java b/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/AutoConfiguredOpenTelemetrySdkBuilder.java index 7fd5d515f4c..06722b8cb18 100644 --- a/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/AutoConfiguredOpenTelemetrySdkBuilder.java +++ b/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/AutoConfiguredOpenTelemetrySdkBuilder.java @@ -551,7 +551,7 @@ private static AutoConfiguredOpenTelemetrySdk maybeConfigureFromFile(ConfigPrope Object model = parse.invoke(null, fis); Class openTelemetryConfiguration = Class.forName( - "io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.OpenTelemetryConfiguration"); + "io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.OpenTelemetryConfigurationModel"); Method create = configurationFactory.getMethod("create", openTelemetryConfiguration); OpenTelemetrySdk sdk = (OpenTelemetrySdk) create.invoke(null, model); Method toConfigProperties = diff --git a/sdk-extensions/incubator/build.gradle.kts b/sdk-extensions/incubator/build.gradle.kts index f562360655e..b7c50f4dee1 100644 --- a/sdk-extensions/incubator/build.gradle.kts +++ b/sdk-extensions/incubator/build.gradle.kts @@ -100,6 +100,9 @@ jsonSchema2Pojo { // Force java 9+ @Generated annotation, since java 8 @Generated annotation isn't detected by // jsonSchema2Pojo and annotation is skipped altogether targetVersion = "1.9" + + // Append Model as suffix to the generated classes. + classNameSuffix = "Model" } val generateJsonSchema2Pojo = tasks.getByName("generateJsonSchema2Pojo") diff --git a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/AggregationFactory.java b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/AggregationFactory.java index 45feb74c8cc..6e35ecbdbfb 100644 --- a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/AggregationFactory.java +++ b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/AggregationFactory.java @@ -7,14 +7,14 @@ import io.opentelemetry.sdk.autoconfigure.internal.SpiHelper; import io.opentelemetry.sdk.autoconfigure.spi.ConfigurationException; -import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.Aggregation; -import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.Base2ExponentialBucketHistogram; -import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.ExplicitBucketHistogram; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.AggregationModel; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.Base2ExponentialBucketHistogramModel; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.ExplicitBucketHistogramModel; import java.io.Closeable; import java.util.List; final class AggregationFactory - implements Factory { + implements Factory { private static final AggregationFactory INSTANCE = new AggregationFactory(); @@ -26,7 +26,7 @@ static AggregationFactory getInstance() { @Override public io.opentelemetry.sdk.metrics.Aggregation create( - Aggregation model, SpiHelper spiHelper, List closeables) { + AggregationModel model, SpiHelper spiHelper, List closeables) { if (model.getDrop() != null) { return io.opentelemetry.sdk.metrics.Aggregation.drop(); } @@ -36,7 +36,7 @@ public io.opentelemetry.sdk.metrics.Aggregation create( if (model.getLastValue() != null) { return io.opentelemetry.sdk.metrics.Aggregation.lastValue(); } - Base2ExponentialBucketHistogram exponentialBucketHistogram = + Base2ExponentialBucketHistogramModel exponentialBucketHistogram = model.getBase2ExponentialBucketHistogram(); if (exponentialBucketHistogram != null) { Integer maxScale = exponentialBucketHistogram.getMaxScale(); @@ -54,7 +54,7 @@ public io.opentelemetry.sdk.metrics.Aggregation create( throw new ConfigurationException("Invalid exponential bucket histogram", e); } } - ExplicitBucketHistogram explicitBucketHistogram = model.getExplicitBucketHistogram(); + ExplicitBucketHistogramModel explicitBucketHistogram = model.getExplicitBucketHistogram(); if (explicitBucketHistogram != null) { List boundaries = explicitBucketHistogram.getBoundaries(); if (boundaries == null) { diff --git a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/AttributesFactory.java b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/AttributesFactory.java index 70cd2e186ae..a45031a85f3 100644 --- a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/AttributesFactory.java +++ b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/AttributesFactory.java @@ -11,12 +11,12 @@ import io.opentelemetry.api.common.AttributesBuilder; import io.opentelemetry.sdk.autoconfigure.internal.SpiHelper; import io.opentelemetry.sdk.autoconfigure.spi.ConfigurationException; -import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.Attributes; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.AttributesModel; import java.io.Closeable; import java.util.List; final class AttributesFactory - implements Factory { + implements Factory { private static final AttributesFactory INSTANCE = new AttributesFactory(); @@ -28,7 +28,7 @@ static AttributesFactory getInstance() { @Override public io.opentelemetry.api.common.Attributes create( - Attributes model, SpiHelper spiHelper, List closeables) { + AttributesModel model, SpiHelper spiHelper, List closeables) { AttributesBuilder builder = io.opentelemetry.api.common.Attributes.builder(); String serviceName = model.getServiceName(); diff --git a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/FileConfiguration.java b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/FileConfiguration.java index ec7fe6407ac..06ab3cc755c 100644 --- a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/FileConfiguration.java +++ b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/FileConfiguration.java @@ -14,8 +14,8 @@ import io.opentelemetry.sdk.autoconfigure.spi.ConfigurationException; import io.opentelemetry.sdk.autoconfigure.spi.internal.ComponentProvider; import io.opentelemetry.sdk.autoconfigure.spi.internal.StructuredConfigProperties; -import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.OpenTelemetryConfiguration; -import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.Sampler; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.OpenTelemetryConfigurationModel; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.SamplerModel; import java.io.Closeable; import java.io.IOException; import java.io.InputStream; @@ -68,12 +68,12 @@ public final class FileConfiguration { private FileConfiguration() {} /** - * Combines {@link #parse(InputStream)} and {@link #create(OpenTelemetryConfiguration)}. + * Combines {@link #parse(InputStream)} and {@link #create(OpenTelemetryConfigurationModel)}. * * @throws ConfigurationException if unable to parse or interpret */ public static OpenTelemetrySdk parseAndCreate(InputStream inputStream) { - OpenTelemetryConfiguration configurationModel = parse(inputStream); + OpenTelemetryConfigurationModel configurationModel = parse(inputStream); return create(configurationModel); } @@ -85,7 +85,7 @@ public static OpenTelemetrySdk parseAndCreate(InputStream inputStream) { * @return the {@link OpenTelemetrySdk} * @throws ConfigurationException if unable to interpret */ - public static OpenTelemetrySdk create(OpenTelemetryConfiguration configurationModel) { + public static OpenTelemetrySdk create(OpenTelemetryConfigurationModel configurationModel) { return createAndMaybeCleanup( OpenTelemetryConfigurationFactory.getInstance(), SpiHelper.create(FileConfiguration.class.getClassLoader()), @@ -93,14 +93,14 @@ public static OpenTelemetrySdk create(OpenTelemetryConfiguration configurationMo } /** - * Parse the {@code configuration} YAML and return the {@link OpenTelemetryConfiguration}. + * Parse the {@code configuration} YAML and return the {@link OpenTelemetryConfigurationModel}. * *

      Before parsing, environment variable substitution is performed as described in {@link * EnvSubstitutionConstructor}. * * @throws ConfigurationException if unable to parse */ - public static OpenTelemetryConfiguration parse(InputStream configuration) { + public static OpenTelemetryConfigurationModel parse(InputStream configuration) { try { return parse(configuration, System.getenv()); } catch (RuntimeException e) { @@ -109,10 +109,10 @@ public static OpenTelemetryConfiguration parse(InputStream configuration) { } // Visible for testing - static OpenTelemetryConfiguration parse( + static OpenTelemetryConfigurationModel parse( InputStream configuration, Map environmentVariables) { Object yamlObj = loadYaml(configuration, environmentVariables); - return MAPPER.convertValue(yamlObj, OpenTelemetryConfiguration.class); + return MAPPER.convertValue(yamlObj, OpenTelemetryConfigurationModel.class); } // Visible for testing @@ -128,7 +128,8 @@ static Object loadYaml(InputStream inputStream, Map environmentV * @param model the configuration model * @return a generic {@link StructuredConfigProperties} representation of the model */ - public static StructuredConfigProperties toConfigProperties(OpenTelemetryConfiguration model) { + public static StructuredConfigProperties toConfigProperties( + OpenTelemetryConfigurationModel model) { return toConfigProperties((Object) model); } @@ -150,18 +151,18 @@ static StructuredConfigProperties toConfigProperties(Object model) { } /** - * Create a {@link Sampler} from the {@code samplerModel} representing the sampler config. + * Create a {@link SamplerModel} from the {@code samplerModel} representing the sampler config. * *

      This is used when samplers are composed, with one sampler accepting one or more additional * samplers as config properties. The {@link ComponentProvider} implementation can call this to - * configure a delegate {@link Sampler} from the {@link StructuredConfigProperties} corresponding - * to a particular config property. + * configure a delegate {@link SamplerModel} from the {@link StructuredConfigProperties} + * corresponding to a particular config property. */ // TODO(jack-berg): add create methods for all SDK extension components supported by // ComponentProvider public static io.opentelemetry.sdk.trace.samplers.Sampler createSampler( StructuredConfigProperties genericSamplerModel) { - Sampler samplerModel = convertToModel(genericSamplerModel, Sampler.class); + SamplerModel samplerModel = convertToModel(genericSamplerModel, SamplerModel.class); return createAndMaybeCleanup( SamplerFactory.getInstance(), SpiHelper.create(FileConfiguration.class.getClassLoader()), diff --git a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/InstrumentSelectorFactory.java b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/InstrumentSelectorFactory.java index f89a94ea507..767908c6595 100644 --- a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/InstrumentSelectorFactory.java +++ b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/InstrumentSelectorFactory.java @@ -7,14 +7,14 @@ import io.opentelemetry.sdk.autoconfigure.internal.SpiHelper; import io.opentelemetry.sdk.autoconfigure.spi.ConfigurationException; -import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.Selector; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.SelectorModel; import io.opentelemetry.sdk.metrics.InstrumentSelector; import io.opentelemetry.sdk.metrics.InstrumentSelectorBuilder; import io.opentelemetry.sdk.metrics.InstrumentType; import java.io.Closeable; import java.util.List; -final class InstrumentSelectorFactory implements Factory { +final class InstrumentSelectorFactory implements Factory { private static final InstrumentSelectorFactory INSTANCE = new InstrumentSelectorFactory(); @@ -26,7 +26,7 @@ static InstrumentSelectorFactory getInstance() { @Override public InstrumentSelector create( - Selector model, SpiHelper spiHelper, List closeables) { + SelectorModel model, SpiHelper spiHelper, List closeables) { InstrumentSelectorBuilder builder = InstrumentSelector.builder(); if (model.getInstrumentName() != null) { builder.setName(model.getInstrumentName()); diff --git a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/LogLimitsFactory.java b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/LogLimitsFactory.java index 765fdd5100e..a2f4ba2e6c4 100644 --- a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/LogLimitsFactory.java +++ b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/LogLimitsFactory.java @@ -6,8 +6,8 @@ package io.opentelemetry.sdk.extension.incubator.fileconfig; import io.opentelemetry.sdk.autoconfigure.internal.SpiHelper; -import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.AttributeLimits; -import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.LogRecordLimits; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.AttributeLimitsModel; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.LogRecordLimitsModel; import io.opentelemetry.sdk.logs.LogLimits; import io.opentelemetry.sdk.logs.LogLimitsBuilder; import java.io.Closeable; @@ -28,7 +28,7 @@ public LogLimits create( LogRecordLimitsAndAttributeLimits model, SpiHelper spiHelper, List closeables) { LogLimitsBuilder builder = LogLimits.builder(); - AttributeLimits attributeLimitsModel = model.getAttributeLimits(); + AttributeLimitsModel attributeLimitsModel = model.getAttributeLimits(); if (attributeLimitsModel != null) { if (attributeLimitsModel.getAttributeCountLimit() != null) { builder.setMaxNumberOfAttributes(attributeLimitsModel.getAttributeCountLimit()); @@ -38,7 +38,7 @@ public LogLimits create( } } - LogRecordLimits logRecordLimitsModel = model.getLogRecordLimits(); + LogRecordLimitsModel logRecordLimitsModel = model.getLogRecordLimits(); if (logRecordLimitsModel != null) { if (logRecordLimitsModel.getAttributeCountLimit() != null) { builder.setMaxNumberOfAttributes(logRecordLimitsModel.getAttributeCountLimit()); diff --git a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/LogRecordExporterFactory.java b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/LogRecordExporterFactory.java index 58ce105eddd..05be1719dbb 100644 --- a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/LogRecordExporterFactory.java +++ b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/LogRecordExporterFactory.java @@ -9,16 +9,14 @@ import io.opentelemetry.sdk.autoconfigure.internal.SpiHelper; import io.opentelemetry.sdk.autoconfigure.spi.ConfigurationException; -import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.Otlp; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.LogRecordExporterModel; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.OtlpModel; import io.opentelemetry.sdk.logs.export.LogRecordExporter; import java.io.Closeable; import java.util.List; import java.util.Map; -final class LogRecordExporterFactory - implements Factory< - io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.LogRecordExporter, - LogRecordExporter> { +final class LogRecordExporterFactory implements Factory { private static final LogRecordExporterFactory INSTANCE = new LogRecordExporterFactory(); @@ -30,10 +28,8 @@ static LogRecordExporterFactory getInstance() { @Override public LogRecordExporter create( - io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.LogRecordExporter model, - SpiHelper spiHelper, - List closeables) { - Otlp otlpModel = model.getOtlp(); + LogRecordExporterModel model, SpiHelper spiHelper, List closeables) { + OtlpModel otlpModel = model.getOtlp(); if (otlpModel != null) { model.getAdditionalProperties().put("otlp", otlpModel); } diff --git a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/LogRecordLimitsAndAttributeLimits.java b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/LogRecordLimitsAndAttributeLimits.java index ffcb42cdd48..bfea53b9a0e 100644 --- a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/LogRecordLimitsAndAttributeLimits.java +++ b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/LogRecordLimitsAndAttributeLimits.java @@ -6,21 +6,21 @@ package io.opentelemetry.sdk.extension.incubator.fileconfig; import com.google.auto.value.AutoValue; -import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.AttributeLimits; -import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.LogRecordLimits; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.AttributeLimitsModel; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.LogRecordLimitsModel; import javax.annotation.Nullable; @AutoValue abstract class LogRecordLimitsAndAttributeLimits { static LogRecordLimitsAndAttributeLimits create( - @Nullable AttributeLimits attributeLimits, @Nullable LogRecordLimits spanLimits) { + @Nullable AttributeLimitsModel attributeLimits, @Nullable LogRecordLimitsModel spanLimits) { return new AutoValue_LogRecordLimitsAndAttributeLimits(attributeLimits, spanLimits); } @Nullable - abstract AttributeLimits getAttributeLimits(); + abstract AttributeLimitsModel getAttributeLimits(); @Nullable - abstract LogRecordLimits getLogRecordLimits(); + abstract LogRecordLimitsModel getLogRecordLimits(); } diff --git a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/LogRecordProcessorFactory.java b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/LogRecordProcessorFactory.java index 882db7db24f..a9cec70455a 100644 --- a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/LogRecordProcessorFactory.java +++ b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/LogRecordProcessorFactory.java @@ -9,7 +9,10 @@ import io.opentelemetry.sdk.autoconfigure.internal.SpiHelper; import io.opentelemetry.sdk.autoconfigure.spi.ConfigurationException; -import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.LogRecordExporter; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.BatchLogRecordProcessorModel; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.LogRecordExporterModel; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.LogRecordProcessorModel; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.SimpleLogRecordProcessorModel; import io.opentelemetry.sdk.logs.LogRecordProcessor; import io.opentelemetry.sdk.logs.export.BatchLogRecordProcessor; import io.opentelemetry.sdk.logs.export.BatchLogRecordProcessorBuilder; @@ -20,9 +23,7 @@ import java.util.Map; final class LogRecordProcessorFactory - implements Factory< - io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.LogRecordProcessor, - LogRecordProcessor> { + implements Factory { private static final LogRecordProcessorFactory INSTANCE = new LogRecordProcessorFactory(); @@ -34,13 +35,10 @@ static LogRecordProcessorFactory getInstance() { @Override public LogRecordProcessor create( - io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.LogRecordProcessor model, - SpiHelper spiHelper, - List closeables) { - io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.BatchLogRecordProcessor - batchModel = model.getBatch(); + LogRecordProcessorModel model, SpiHelper spiHelper, List closeables) { + BatchLogRecordProcessorModel batchModel = model.getBatch(); if (batchModel != null) { - LogRecordExporter exporterModel = + LogRecordExporterModel exporterModel = FileConfigUtil.requireNonNull( batchModel.getExporter(), "batch log record processor exporter"); @@ -62,10 +60,9 @@ public LogRecordProcessor create( return FileConfigUtil.addAndReturn(closeables, builder.build()); } - io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.SimpleLogRecordProcessor - simpleModel = model.getSimple(); + SimpleLogRecordProcessorModel simpleModel = model.getSimple(); if (simpleModel != null) { - LogRecordExporter exporterModel = + LogRecordExporterModel exporterModel = FileConfigUtil.requireNonNull( simpleModel.getExporter(), "simple log record processor exporter"); io.opentelemetry.sdk.logs.export.LogRecordExporter logRecordExporter = diff --git a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/LoggerProviderAndAttributeLimits.java b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/LoggerProviderAndAttributeLimits.java index 43263c0972b..06abbb623f3 100644 --- a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/LoggerProviderAndAttributeLimits.java +++ b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/LoggerProviderAndAttributeLimits.java @@ -6,21 +6,22 @@ package io.opentelemetry.sdk.extension.incubator.fileconfig; import com.google.auto.value.AutoValue; -import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.AttributeLimits; -import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.LoggerProvider; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.AttributeLimitsModel; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.LoggerProviderModel; import javax.annotation.Nullable; @AutoValue abstract class LoggerProviderAndAttributeLimits { static LoggerProviderAndAttributeLimits create( - @Nullable AttributeLimits attributeLimits, @Nullable LoggerProvider loggerProvider) { + @Nullable AttributeLimitsModel attributeLimits, + @Nullable LoggerProviderModel loggerProvider) { return new AutoValue_LoggerProviderAndAttributeLimits(attributeLimits, loggerProvider); } @Nullable - abstract AttributeLimits getAttributeLimits(); + abstract AttributeLimitsModel getAttributeLimits(); @Nullable - abstract LoggerProvider getLoggerProvider(); + abstract LoggerProviderModel getLoggerProvider(); } diff --git a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/LoggerProviderFactory.java b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/LoggerProviderFactory.java index 3d46098ae9e..ceb208697a2 100644 --- a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/LoggerProviderFactory.java +++ b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/LoggerProviderFactory.java @@ -6,8 +6,8 @@ package io.opentelemetry.sdk.extension.incubator.fileconfig; import io.opentelemetry.sdk.autoconfigure.internal.SpiHelper; -import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.LogRecordProcessor; -import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.LoggerProvider; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.LogRecordProcessorModel; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.LoggerProviderModel; import io.opentelemetry.sdk.logs.LogLimits; import io.opentelemetry.sdk.logs.SdkLoggerProvider; import io.opentelemetry.sdk.logs.SdkLoggerProviderBuilder; @@ -30,7 +30,7 @@ public SdkLoggerProviderBuilder create( LoggerProviderAndAttributeLimits model, SpiHelper spiHelper, List closeables) { SdkLoggerProviderBuilder builder = SdkLoggerProvider.builder(); - LoggerProvider loggerProviderModel = model.getLoggerProvider(); + LoggerProviderModel loggerProviderModel = model.getLoggerProvider(); if (loggerProviderModel == null) { return builder; } @@ -44,7 +44,7 @@ public SdkLoggerProviderBuilder create( closeables); builder.setLogLimits(() -> logLimits); - List processors = loggerProviderModel.getProcessors(); + List processors = loggerProviderModel.getProcessors(); if (processors != null) { processors.forEach( processor -> diff --git a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/MeterProviderFactory.java b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/MeterProviderFactory.java index c675920a797..dd400eeeb1e 100644 --- a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/MeterProviderFactory.java +++ b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/MeterProviderFactory.java @@ -8,17 +8,17 @@ import static io.opentelemetry.sdk.extension.incubator.fileconfig.FileConfigUtil.requireNonNull; import io.opentelemetry.sdk.autoconfigure.internal.SpiHelper; -import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.MeterProvider; -import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.MetricReader; -import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.Selector; -import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.Stream; -import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.View; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.MeterProviderModel; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.MetricReaderModel; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.SelectorModel; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.StreamModel; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.ViewModel; import io.opentelemetry.sdk.metrics.SdkMeterProvider; import io.opentelemetry.sdk.metrics.SdkMeterProviderBuilder; import java.io.Closeable; import java.util.List; -final class MeterProviderFactory implements Factory { +final class MeterProviderFactory implements Factory { private static final MeterProviderFactory INSTANCE = new MeterProviderFactory(); @@ -30,10 +30,10 @@ static MeterProviderFactory getInstance() { @Override public SdkMeterProviderBuilder create( - MeterProvider model, SpiHelper spiHelper, List closeables) { + MeterProviderModel model, SpiHelper spiHelper, List closeables) { SdkMeterProviderBuilder builder = SdkMeterProvider.builder(); - List readerModels = model.getReaders(); + List readerModels = model.getReaders(); if (readerModels != null) { readerModels.forEach( readerModel -> { @@ -45,12 +45,12 @@ public SdkMeterProviderBuilder create( }); } - List viewModels = model.getViews(); + List viewModels = model.getViews(); if (viewModels != null) { viewModels.forEach( viewModel -> { - Selector selector = requireNonNull(viewModel.getSelector(), "view selector"); - Stream stream = requireNonNull(viewModel.getStream(), "view stream"); + SelectorModel selector = requireNonNull(viewModel.getSelector(), "view selector"); + StreamModel stream = requireNonNull(viewModel.getStream(), "view stream"); builder.registerView( InstrumentSelectorFactory.getInstance().create(selector, spiHelper, closeables), ViewFactory.getInstance().create(stream, spiHelper, closeables)); diff --git a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/MetricExporterFactory.java b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/MetricExporterFactory.java index f614761728a..cfda507de32 100644 --- a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/MetricExporterFactory.java +++ b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/MetricExporterFactory.java @@ -9,16 +9,14 @@ import io.opentelemetry.sdk.autoconfigure.internal.SpiHelper; import io.opentelemetry.sdk.autoconfigure.spi.ConfigurationException; -import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.OtlpMetric; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.MetricExporterModel; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.OtlpMetricModel; import io.opentelemetry.sdk.metrics.export.MetricExporter; import java.io.Closeable; import java.util.List; import java.util.Map; -final class MetricExporterFactory - implements Factory< - io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.MetricExporter, - MetricExporter> { +final class MetricExporterFactory implements Factory { private static final MetricExporterFactory INSTANCE = new MetricExporterFactory(); @@ -30,10 +28,8 @@ static MetricExporterFactory getInstance() { @Override public MetricExporter create( - io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.MetricExporter model, - SpiHelper spiHelper, - List closeables) { - OtlpMetric otlpModel = model.getOtlp(); + MetricExporterModel model, SpiHelper spiHelper, List closeables) { + OtlpMetricModel otlpModel = model.getOtlp(); if (otlpModel != null) { model.getAdditionalProperties().put("otlp", otlpModel); } diff --git a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/MetricReaderFactory.java b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/MetricReaderFactory.java index 00f3dfa17a0..1041d50ec6c 100644 --- a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/MetricReaderFactory.java +++ b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/MetricReaderFactory.java @@ -9,20 +9,18 @@ import io.opentelemetry.sdk.autoconfigure.internal.SpiHelper; import io.opentelemetry.sdk.autoconfigure.spi.ConfigurationException; -import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.MetricExporter; -import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.PeriodicMetricReader; -import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.Prometheus; -import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.PullMetricReader; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.MetricExporterModel; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.MetricReaderModel; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.PeriodicMetricReaderModel; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.PrometheusModel; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.PullMetricReaderModel; import io.opentelemetry.sdk.metrics.export.MetricReader; import io.opentelemetry.sdk.metrics.export.PeriodicMetricReaderBuilder; import java.io.Closeable; import java.time.Duration; import java.util.List; -final class MetricReaderFactory - implements Factory< - io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.MetricReader, - MetricReader> { +final class MetricReaderFactory implements Factory { private static final MetricReaderFactory INSTANCE = new MetricReaderFactory(); @@ -34,12 +32,10 @@ static MetricReaderFactory getInstance() { @Override public MetricReader create( - io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.MetricReader model, - SpiHelper spiHelper, - List closeables) { - PeriodicMetricReader periodicModel = model.getPeriodic(); + MetricReaderModel model, SpiHelper spiHelper, List closeables) { + PeriodicMetricReaderModel periodicModel = model.getPeriodic(); if (periodicModel != null) { - MetricExporter exporterModel = + MetricExporterModel exporterModel = requireNonNull(periodicModel.getExporter(), "periodic metric reader exporter"); io.opentelemetry.sdk.metrics.export.MetricExporter metricExporter = MetricExporterFactory.getInstance().create(exporterModel, spiHelper, closeables); @@ -52,11 +48,11 @@ public MetricReader create( return FileConfigUtil.addAndReturn(closeables, builder.build()); } - PullMetricReader pullModel = model.getPull(); + PullMetricReaderModel pullModel = model.getPull(); if (pullModel != null) { - MetricExporter exporterModel = + MetricExporterModel exporterModel = requireNonNull(pullModel.getExporter(), "pull metric reader exporter"); - Prometheus prometheusModel = exporterModel.getPrometheus(); + PrometheusModel prometheusModel = exporterModel.getPrometheus(); if (prometheusModel != null) { MetricReader metricReader = FileConfigUtil.loadComponent( diff --git a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/OpenTelemetryConfigurationFactory.java b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/OpenTelemetryConfigurationFactory.java index 1677361d8ae..0213839ee30 100644 --- a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/OpenTelemetryConfigurationFactory.java +++ b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/OpenTelemetryConfigurationFactory.java @@ -9,14 +9,14 @@ import io.opentelemetry.sdk.OpenTelemetrySdkBuilder; import io.opentelemetry.sdk.autoconfigure.internal.SpiHelper; import io.opentelemetry.sdk.autoconfigure.spi.ConfigurationException; -import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.OpenTelemetryConfiguration; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.OpenTelemetryConfigurationModel; import io.opentelemetry.sdk.resources.Resource; import java.io.Closeable; import java.util.List; import java.util.Objects; final class OpenTelemetryConfigurationFactory - implements Factory { + implements Factory { private static final OpenTelemetryConfigurationFactory INSTANCE = new OpenTelemetryConfigurationFactory(); @@ -29,7 +29,7 @@ static OpenTelemetryConfigurationFactory getInstance() { @Override public OpenTelemetrySdk create( - OpenTelemetryConfiguration model, SpiHelper spiHelper, List closeables) { + OpenTelemetryConfigurationModel model, SpiHelper spiHelper, List closeables) { OpenTelemetrySdkBuilder builder = OpenTelemetrySdk.builder(); if (!"0.1".equals(model.getFileFormat())) { throw new ConfigurationException("Unsupported file format. Supported formats include: 0.1"); diff --git a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/PropagatorFactory.java b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/PropagatorFactory.java index d9572fd8406..c53b6699062 100644 --- a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/PropagatorFactory.java +++ b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/PropagatorFactory.java @@ -10,11 +10,11 @@ import io.opentelemetry.context.propagation.ContextPropagators; import io.opentelemetry.context.propagation.TextMapPropagator; import io.opentelemetry.sdk.autoconfigure.internal.SpiHelper; -import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.Propagator; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.PropagatorModel; import java.io.Closeable; import java.util.List; -final class PropagatorFactory implements Factory { +final class PropagatorFactory implements Factory { private static final PropagatorFactory INSTANCE = new PropagatorFactory(); @@ -26,7 +26,7 @@ static PropagatorFactory getInstance() { @Override public ContextPropagators create( - Propagator model, SpiHelper spiHelper, List closeables) { + PropagatorModel model, SpiHelper spiHelper, List closeables) { List compositeModel = requireNonNull(model.getComposite(), "composite propagator"); TextMapPropagator textMapPropagator = TextMapPropagatorFactory.getInstance().create(compositeModel, spiHelper, closeables); diff --git a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/ResourceFactory.java b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/ResourceFactory.java index eaaf1ae98b3..f2d5da54fc2 100644 --- a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/ResourceFactory.java +++ b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/ResourceFactory.java @@ -10,7 +10,7 @@ import io.opentelemetry.sdk.autoconfigure.spi.Ordered; import io.opentelemetry.sdk.autoconfigure.spi.internal.ComponentProvider; import io.opentelemetry.sdk.autoconfigure.spi.internal.StructuredConfigProperties; -import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.Attributes; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.AttributesModel; import io.opentelemetry.sdk.resources.Resource; import java.io.Closeable; import java.util.ArrayList; @@ -21,7 +21,8 @@ final class ResourceFactory implements Factory< - io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.Resource, Resource> { + io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.ResourceModel, + Resource> { private static final StructuredConfigProperties EMPTY_CONFIG = FileConfiguration.toConfigProperties(Collections.emptyMap()); @@ -35,7 +36,7 @@ static ResourceFactory getInstance() { @Override public Resource create( - io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.Resource model, + io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.ResourceModel model, SpiHelper spiHelper, List closeables) { Resource result = Resource.getDefault(); @@ -45,7 +46,7 @@ public Resource create( result = result.merge(resourceProviderResource); } - Attributes attributesModel = model.getAttributes(); + AttributesModel attributesModel = model.getAttributes(); if (attributesModel != null) { result = result.toBuilder() diff --git a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/SamplerFactory.java b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/SamplerFactory.java index 2f8c3bc4520..0b38631e0db 100644 --- a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/SamplerFactory.java +++ b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/SamplerFactory.java @@ -9,18 +9,17 @@ import io.opentelemetry.sdk.autoconfigure.internal.SpiHelper; import io.opentelemetry.sdk.autoconfigure.spi.ConfigurationException; -import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.JaegerRemote; -import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.ParentBased; -import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.TraceIdRatioBased; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.JaegerRemoteModel; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.ParentBasedModel; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.SamplerModel; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.TraceIdRatioBasedModel; import io.opentelemetry.sdk.trace.samplers.ParentBasedSamplerBuilder; import io.opentelemetry.sdk.trace.samplers.Sampler; import java.io.Closeable; import java.util.List; import java.util.Map; -final class SamplerFactory - implements Factory< - io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.Sampler, Sampler> { +final class SamplerFactory implements Factory { private static final SamplerFactory INSTANCE = new SamplerFactory(); @@ -31,17 +30,14 @@ static SamplerFactory getInstance() { } @Override - public Sampler create( - io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.Sampler model, - SpiHelper spiHelper, - List closeables) { + public Sampler create(SamplerModel model, SpiHelper spiHelper, List closeables) { if (model.getAlwaysOn() != null) { return Sampler.alwaysOn(); } if (model.getAlwaysOff() != null) { return Sampler.alwaysOff(); } - TraceIdRatioBased traceIdRatioBasedModel = model.getTraceIdRatioBased(); + TraceIdRatioBasedModel traceIdRatioBasedModel = model.getTraceIdRatioBased(); if (traceIdRatioBasedModel != null) { Double ratio = traceIdRatioBasedModel.getRatio(); if (ratio == null) { @@ -49,7 +45,7 @@ public Sampler create( } return Sampler.traceIdRatioBased(ratio); } - ParentBased parentBasedModel = model.getParentBased(); + ParentBasedModel parentBasedModel = model.getParentBased(); if (parentBasedModel != null) { Sampler root = parentBasedModel.getRoot() == null @@ -77,7 +73,7 @@ public Sampler create( return builder.build(); } - JaegerRemote jaegerRemoteModel = model.getJaegerRemote(); + JaegerRemoteModel jaegerRemoteModel = model.getJaegerRemote(); if (jaegerRemoteModel != null) { model.getAdditionalProperties().put("jaeger_remote", jaegerRemoteModel); } diff --git a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/SpanExporterFactory.java b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/SpanExporterFactory.java index a48af93fb75..652b3917acf 100644 --- a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/SpanExporterFactory.java +++ b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/SpanExporterFactory.java @@ -9,17 +9,15 @@ import io.opentelemetry.sdk.autoconfigure.internal.SpiHelper; import io.opentelemetry.sdk.autoconfigure.spi.ConfigurationException; -import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.Otlp; -import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.Zipkin; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.OtlpModel; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.SpanExporterModel; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.ZipkinModel; import io.opentelemetry.sdk.trace.export.SpanExporter; import java.io.Closeable; import java.util.List; import java.util.Map; -final class SpanExporterFactory - implements Factory< - io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.SpanExporter, - SpanExporter> { +final class SpanExporterFactory implements Factory { private static final SpanExporterFactory INSTANCE = new SpanExporterFactory(); @@ -31,10 +29,8 @@ static SpanExporterFactory getInstance() { @Override public SpanExporter create( - io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.SpanExporter model, - SpiHelper spiHelper, - List closeables) { - Otlp otlpModel = model.getOtlp(); + SpanExporterModel model, SpiHelper spiHelper, List closeables) { + OtlpModel otlpModel = model.getOtlp(); if (otlpModel != null) { model.getAdditionalProperties().put("otlp", otlpModel); } @@ -43,7 +39,7 @@ public SpanExporter create( model.getAdditionalProperties().put("console", model.getConsole()); } - Zipkin zipkinModel = model.getZipkin(); + ZipkinModel zipkinModel = model.getZipkin(); if (zipkinModel != null) { model.getAdditionalProperties().put("zipkin", model.getZipkin()); } diff --git a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/SpanLimitsAndAttributeLimits.java b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/SpanLimitsAndAttributeLimits.java index 26049538a58..dad8dab1019 100644 --- a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/SpanLimitsAndAttributeLimits.java +++ b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/SpanLimitsAndAttributeLimits.java @@ -6,21 +6,21 @@ package io.opentelemetry.sdk.extension.incubator.fileconfig; import com.google.auto.value.AutoValue; -import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.AttributeLimits; -import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.SpanLimits; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.AttributeLimitsModel; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.SpanLimitsModel; import javax.annotation.Nullable; @AutoValue abstract class SpanLimitsAndAttributeLimits { static SpanLimitsAndAttributeLimits create( - @Nullable AttributeLimits attributeLimits, @Nullable SpanLimits spanLimits) { + @Nullable AttributeLimitsModel attributeLimits, @Nullable SpanLimitsModel spanLimits) { return new AutoValue_SpanLimitsAndAttributeLimits(attributeLimits, spanLimits); } @Nullable - abstract AttributeLimits getAttributeLimits(); + abstract AttributeLimitsModel getAttributeLimits(); @Nullable - abstract SpanLimits getSpanLimits(); + abstract SpanLimitsModel getSpanLimits(); } diff --git a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/SpanLimitsFactory.java b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/SpanLimitsFactory.java index b3e83b7a2ba..b669c99bf06 100644 --- a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/SpanLimitsFactory.java +++ b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/SpanLimitsFactory.java @@ -6,8 +6,8 @@ package io.opentelemetry.sdk.extension.incubator.fileconfig; import io.opentelemetry.sdk.autoconfigure.internal.SpiHelper; -import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.AttributeLimits; -import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.SpanLimits; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.AttributeLimitsModel; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.SpanLimitsModel; import io.opentelemetry.sdk.trace.SpanLimitsBuilder; import java.io.Closeable; import java.util.List; @@ -28,7 +28,7 @@ public io.opentelemetry.sdk.trace.SpanLimits create( SpanLimitsAndAttributeLimits model, SpiHelper spiHelper, List closeables) { SpanLimitsBuilder builder = io.opentelemetry.sdk.trace.SpanLimits.builder(); - AttributeLimits attributeLimitsModel = model.getAttributeLimits(); + AttributeLimitsModel attributeLimitsModel = model.getAttributeLimits(); if (attributeLimitsModel != null) { if (attributeLimitsModel.getAttributeCountLimit() != null) { builder.setMaxNumberOfAttributes(attributeLimitsModel.getAttributeCountLimit()); @@ -38,7 +38,7 @@ public io.opentelemetry.sdk.trace.SpanLimits create( } } - SpanLimits spanLimitsModel = model.getSpanLimits(); + SpanLimitsModel spanLimitsModel = model.getSpanLimits(); if (spanLimitsModel != null) { if (spanLimitsModel.getAttributeCountLimit() != null) { builder.setMaxNumberOfAttributes(spanLimitsModel.getAttributeCountLimit()); diff --git a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/SpanProcessorFactory.java b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/SpanProcessorFactory.java index 9d2e4362078..04a5a144303 100644 --- a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/SpanProcessorFactory.java +++ b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/SpanProcessorFactory.java @@ -9,7 +9,10 @@ import io.opentelemetry.sdk.autoconfigure.internal.SpiHelper; import io.opentelemetry.sdk.autoconfigure.spi.ConfigurationException; -import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.SpanExporter; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.BatchSpanProcessorModel; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.SimpleSpanProcessorModel; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.SpanExporterModel; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.SpanProcessorModel; import io.opentelemetry.sdk.trace.SpanProcessor; import io.opentelemetry.sdk.trace.export.BatchSpanProcessor; import io.opentelemetry.sdk.trace.export.BatchSpanProcessorBuilder; @@ -19,10 +22,7 @@ import java.util.List; import java.util.Map; -final class SpanProcessorFactory - implements Factory< - io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.SpanProcessor, - SpanProcessor> { +final class SpanProcessorFactory implements Factory { private static final SpanProcessorFactory INSTANCE = new SpanProcessorFactory(); @@ -34,13 +34,10 @@ static SpanProcessorFactory getInstance() { @Override public SpanProcessor create( - io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.SpanProcessor model, - SpiHelper spiHelper, - List closeables) { - io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.BatchSpanProcessor - batchModel = model.getBatch(); + SpanProcessorModel model, SpiHelper spiHelper, List closeables) { + BatchSpanProcessorModel batchModel = model.getBatch(); if (batchModel != null) { - SpanExporter exporterModel = + SpanExporterModel exporterModel = FileConfigUtil.requireNonNull(batchModel.getExporter(), "batch span processor exporter"); io.opentelemetry.sdk.trace.export.SpanExporter spanExporter = SpanExporterFactory.getInstance().create(exporterModel, spiHelper, closeables); @@ -60,10 +57,9 @@ public SpanProcessor create( return FileConfigUtil.addAndReturn(closeables, builder.build()); } - io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.SimpleSpanProcessor - simpleModel = model.getSimple(); + SimpleSpanProcessorModel simpleModel = model.getSimple(); if (simpleModel != null) { - SpanExporter exporterModel = + SpanExporterModel exporterModel = FileConfigUtil.requireNonNull( simpleModel.getExporter(), "simple span processor exporter"); io.opentelemetry.sdk.trace.export.SpanExporter spanExporter = diff --git a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/TracerProviderAndAttributeLimits.java b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/TracerProviderAndAttributeLimits.java index afc1a41a66e..bcc73943b63 100644 --- a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/TracerProviderAndAttributeLimits.java +++ b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/TracerProviderAndAttributeLimits.java @@ -6,21 +6,22 @@ package io.opentelemetry.sdk.extension.incubator.fileconfig; import com.google.auto.value.AutoValue; -import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.AttributeLimits; -import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.TracerProvider; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.AttributeLimitsModel; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.TracerProviderModel; import javax.annotation.Nullable; @AutoValue abstract class TracerProviderAndAttributeLimits { static TracerProviderAndAttributeLimits create( - @Nullable AttributeLimits attributeLimits, @Nullable TracerProvider tracerProvider) { + @Nullable AttributeLimitsModel attributeLimits, + @Nullable TracerProviderModel tracerProvider) { return new AutoValue_TracerProviderAndAttributeLimits(attributeLimits, tracerProvider); } @Nullable - abstract AttributeLimits getAttributeLimits(); + abstract AttributeLimitsModel getAttributeLimits(); @Nullable - abstract TracerProvider getTracerProvider(); + abstract TracerProviderModel getTracerProvider(); } diff --git a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/TracerProviderFactory.java b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/TracerProviderFactory.java index ff8000806c7..8634710b2c6 100644 --- a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/TracerProviderFactory.java +++ b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/TracerProviderFactory.java @@ -6,8 +6,8 @@ package io.opentelemetry.sdk.extension.incubator.fileconfig; import io.opentelemetry.sdk.autoconfigure.internal.SpiHelper; -import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.SpanProcessor; -import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.TracerProvider; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.SpanProcessorModel; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.TracerProviderModel; import io.opentelemetry.sdk.trace.SdkTracerProvider; import io.opentelemetry.sdk.trace.SdkTracerProviderBuilder; import io.opentelemetry.sdk.trace.SpanLimits; @@ -30,7 +30,7 @@ static TracerProviderFactory getInstance() { public SdkTracerProviderBuilder create( TracerProviderAndAttributeLimits model, SpiHelper spiHelper, List closeables) { SdkTracerProviderBuilder builder = SdkTracerProvider.builder(); - TracerProvider tracerProviderModel = model.getTracerProvider(); + TracerProviderModel tracerProviderModel = model.getTracerProvider(); if (tracerProviderModel == null) { return builder; } @@ -51,7 +51,7 @@ public SdkTracerProviderBuilder create( builder.setSampler(sampler); } - List processors = tracerProviderModel.getProcessors(); + List processors = tracerProviderModel.getProcessors(); if (processors != null) { processors.forEach( processor -> diff --git a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/ViewFactory.java b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/ViewFactory.java index cb23d699ecc..fecc4a81c59 100644 --- a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/ViewFactory.java +++ b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/ViewFactory.java @@ -6,14 +6,14 @@ package io.opentelemetry.sdk.extension.incubator.fileconfig; import io.opentelemetry.sdk.autoconfigure.internal.SpiHelper; -import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.Stream; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.StreamModel; import io.opentelemetry.sdk.metrics.View; import io.opentelemetry.sdk.metrics.ViewBuilder; import java.io.Closeable; import java.util.HashSet; import java.util.List; -final class ViewFactory implements Factory { +final class ViewFactory implements Factory { private static final ViewFactory INSTANCE = new ViewFactory(); @@ -24,7 +24,7 @@ static ViewFactory getInstance() { } @Override - public View create(Stream model, SpiHelper spiHelper, List closeables) { + public View create(StreamModel model, SpiHelper spiHelper, List closeables) { ViewBuilder builder = View.builder(); if (model.getName() != null) { builder.setName(model.getName()); diff --git a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/YamlStructuredConfigProperties.java b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/YamlStructuredConfigProperties.java index bc74b333cd4..04c432ce8a7 100644 --- a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/YamlStructuredConfigProperties.java +++ b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/YamlStructuredConfigProperties.java @@ -10,7 +10,7 @@ import io.opentelemetry.sdk.autoconfigure.spi.ConfigurationException; import io.opentelemetry.sdk.autoconfigure.spi.internal.StructuredConfigProperties; -import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.OpenTelemetryConfiguration; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.OpenTelemetryConfigurationModel; import java.util.Arrays; import java.util.Collections; import java.util.HashMap; @@ -54,7 +54,7 @@ private YamlStructuredConfigProperties( * com.fasterxml.jackson.databind.ObjectMapper}), and have values which are scalars, lists of * scalars, lists of maps, and maps. * - * @see FileConfiguration#toConfigProperties(OpenTelemetryConfiguration) + * @see FileConfiguration#toConfigProperties(OpenTelemetryConfigurationModel) */ @SuppressWarnings("unchecked") static YamlStructuredConfigProperties create(Map properties) { diff --git a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/AggregationFactoryTest.java b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/AggregationFactoryTest.java index 8e7dafad412..0efe2691b0a 100644 --- a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/AggregationFactoryTest.java +++ b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/AggregationFactoryTest.java @@ -9,12 +9,12 @@ import static org.mockito.Mockito.mock; import io.opentelemetry.sdk.autoconfigure.internal.SpiHelper; -import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.Aggregation; -import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.Base2ExponentialBucketHistogram; -import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.Drop; -import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.ExplicitBucketHistogram; -import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.LastValue; -import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.Sum; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.AggregationModel; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.Base2ExponentialBucketHistogramModel; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.DropModel; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.ExplicitBucketHistogramModel; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.LastValueModel; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.SumModel; import java.util.ArrayList; import java.util.Arrays; import java.util.stream.Stream; @@ -26,7 +26,7 @@ class AggregationFactoryTest { @ParameterizedTest @MethodSource("createTestCases") - void create(Aggregation model, io.opentelemetry.sdk.metrics.Aggregation expectedResult) { + void create(AggregationModel model, io.opentelemetry.sdk.metrics.Aggregation expectedResult) { io.opentelemetry.sdk.metrics.Aggregation aggregation = AggregationFactory.getInstance().create(model, mock(SpiHelper.class), new ArrayList<>()); assertThat(aggregation.toString()).isEqualTo(expectedResult.toString()); @@ -35,32 +35,34 @@ void create(Aggregation model, io.opentelemetry.sdk.metrics.Aggregation expected private static Stream createTestCases() { return Stream.of( Arguments.of( - new Aggregation(), io.opentelemetry.sdk.metrics.Aggregation.defaultAggregation()), + new AggregationModel(), io.opentelemetry.sdk.metrics.Aggregation.defaultAggregation()), Arguments.of( - new Aggregation().withDrop(new Drop()), + new AggregationModel().withDrop(new DropModel()), io.opentelemetry.sdk.metrics.Aggregation.drop()), Arguments.of( - new Aggregation().withSum(new Sum()), io.opentelemetry.sdk.metrics.Aggregation.sum()), + new AggregationModel().withSum(new SumModel()), + io.opentelemetry.sdk.metrics.Aggregation.sum()), Arguments.of( - new Aggregation().withLastValue(new LastValue()), + new AggregationModel().withLastValue(new LastValueModel()), io.opentelemetry.sdk.metrics.Aggregation.lastValue()), Arguments.of( - new Aggregation() - .withBase2ExponentialBucketHistogram(new Base2ExponentialBucketHistogram()), + new AggregationModel() + .withBase2ExponentialBucketHistogram(new Base2ExponentialBucketHistogramModel()), io.opentelemetry.sdk.metrics.Aggregation.base2ExponentialBucketHistogram()), Arguments.of( - new Aggregation() + new AggregationModel() .withBase2ExponentialBucketHistogram( - new Base2ExponentialBucketHistogram().withMaxSize(2).withMaxScale(2)), + new Base2ExponentialBucketHistogramModel().withMaxSize(2).withMaxScale(2)), io.opentelemetry.sdk.metrics.Aggregation.base2ExponentialBucketHistogram(2, 2)), Arguments.of( - new Aggregation() - .withExplicitBucketHistogram(new ExplicitBucketHistogram().withBoundaries(null)), + new AggregationModel() + .withExplicitBucketHistogram( + new ExplicitBucketHistogramModel().withBoundaries(null)), io.opentelemetry.sdk.metrics.Aggregation.explicitBucketHistogram()), Arguments.of( - new Aggregation() + new AggregationModel() .withExplicitBucketHistogram( - new ExplicitBucketHistogram().withBoundaries(Arrays.asList(1.0, 2.0))), + new ExplicitBucketHistogramModel().withBoundaries(Arrays.asList(1.0, 2.0))), io.opentelemetry.sdk.metrics.Aggregation.explicitBucketHistogram( Arrays.asList(1.0, 2.0)))); } diff --git a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/AttributesFactoryTest.java b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/AttributesFactoryTest.java index e50fa61209d..5bd8e42a540 100644 --- a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/AttributesFactoryTest.java +++ b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/AttributesFactoryTest.java @@ -11,7 +11,7 @@ import io.opentelemetry.sdk.autoconfigure.internal.SpiHelper; import io.opentelemetry.sdk.autoconfigure.spi.ConfigurationException; -import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.Attributes; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.AttributesModel; import java.util.Arrays; import java.util.Collections; import java.util.stream.Stream; @@ -24,7 +24,7 @@ class AttributesFactoryTest { @ParameterizedTest @MethodSource("invalidAttributes") - void create_InvalidAttributes(Attributes model, String expectedMessage) { + void create_InvalidAttributes(AttributesModel model, String expectedMessage) { assertThatThrownBy( () -> AttributesFactory.getInstance() @@ -36,16 +36,16 @@ void create_InvalidAttributes(Attributes model, String expectedMessage) { private static Stream invalidAttributes() { return Stream.of( Arguments.of( - new Attributes().withAdditionalProperty("key", null), + new AttributesModel().withAdditionalProperty("key", null), "Error processing attribute with key \"key\": unexpected null value"), Arguments.of( - new Attributes().withAdditionalProperty("key", new Object()), + new AttributesModel().withAdditionalProperty("key", new Object()), "Error processing attribute with key \"key\": unrecognized value type java.lang.Object"), Arguments.of( - new Attributes().withAdditionalProperty("key", Arrays.asList(1L, 1)), + new AttributesModel().withAdditionalProperty("key", Arrays.asList(1L, 1)), "Error processing attribute with key \"key\": expected value entries to be of type class java.lang.Long but found entry with type class java.lang.Integer"), Arguments.of( - new Attributes().withAdditionalProperty("key", Arrays.asList(1L, null)), + new AttributesModel().withAdditionalProperty("key", Arrays.asList(1L, null)), "Error processing attribute with key \"key\": unexpected null element in value")); } @@ -54,7 +54,7 @@ void create() { assertThat( AttributesFactory.getInstance() .create( - new Attributes() + new AttributesModel() .withServiceName("my-service") .withAdditionalProperty("strKey", "val") .withAdditionalProperty("longKey", 1L) diff --git a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/FileConfigurationParseTest.java b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/FileConfigurationParseTest.java index bfb0fe09f1b..0c03bdbd751 100644 --- a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/FileConfigurationParseTest.java +++ b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/FileConfigurationParseTest.java @@ -9,44 +9,43 @@ import static org.assertj.core.api.Assertions.assertThatThrownBy; import io.opentelemetry.sdk.autoconfigure.spi.ConfigurationException; -import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.Aggregation; -import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.AlwaysOff; -import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.AlwaysOn; -import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.AttributeLimits; -import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.Attributes; -import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.BatchLogRecordProcessor; -import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.BatchSpanProcessor; -import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.Console; -import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.ExplicitBucketHistogram; -import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.Headers; -import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.LogRecordExporter; -import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.LogRecordLimits; -import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.LogRecordProcessor; -import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.LoggerProvider; -import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.MeterProvider; -import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.MetricExporter; -import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.MetricReader; -import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.OpenTelemetryConfiguration; -import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.Otlp; -import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.OtlpMetric; -import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.OtlpMetric.DefaultHistogramAggregation; -import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.ParentBased; -import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.PeriodicMetricReader; -import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.Prometheus; -import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.Propagator; -import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.PullMetricReader; -import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.Resource; -import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.Sampler; -import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.Selector; -import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.SimpleSpanProcessor; -import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.SpanExporter; -import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.SpanLimits; -import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.SpanProcessor; -import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.Stream; -import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.TraceIdRatioBased; -import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.TracerProvider; -import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.View; -import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.Zipkin; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.AggregationModel; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.AlwaysOffModel; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.AlwaysOnModel; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.AttributeLimitsModel; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.AttributesModel; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.BatchLogRecordProcessorModel; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.BatchSpanProcessorModel; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.ConsoleModel; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.ExplicitBucketHistogramModel; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.HeadersModel; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.LogRecordExporterModel; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.LogRecordLimitsModel; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.LogRecordProcessorModel; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.LoggerProviderModel; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.MeterProviderModel; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.MetricExporterModel; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.MetricReaderModel; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.OpenTelemetryConfigurationModel; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.OtlpMetricModel; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.OtlpModel; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.ParentBasedModel; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.PeriodicMetricReaderModel; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.PrometheusModel; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.PropagatorModel; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.PullMetricReaderModel; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.ResourceModel; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.SamplerModel; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.SelectorModel; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.SimpleSpanProcessorModel; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.SpanExporterModel; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.SpanLimitsModel; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.SpanProcessorModel; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.StreamModel; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.TraceIdRatioBasedModel; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.TracerProviderModel; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.ViewModel; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.ZipkinModel; import java.io.ByteArrayInputStream; import java.io.FileInputStream; import java.io.IOException; @@ -76,32 +75,33 @@ void parse_BadInputStream() { @Test void parse_KitchenSinkExampleFile() throws IOException { - OpenTelemetryConfiguration expected = new OpenTelemetryConfiguration(); + OpenTelemetryConfigurationModel expected = new OpenTelemetryConfigurationModel(); expected.withFileFormat("0.1"); expected.withDisabled(false); // General config - Resource resource = - new Resource().withAttributes(new Attributes().withServiceName("unknown_service")); + ResourceModel resource = + new ResourceModel() + .withAttributes(new AttributesModel().withServiceName("unknown_service")); expected.withResource(resource); - AttributeLimits attributeLimits = - new AttributeLimits().withAttributeValueLengthLimit(4096).withAttributeCountLimit(128); + AttributeLimitsModel attributeLimits = + new AttributeLimitsModel().withAttributeValueLengthLimit(4096).withAttributeCountLimit(128); expected.withAttributeLimits(attributeLimits); - Propagator propagator = - new Propagator() + PropagatorModel propagator = + new PropagatorModel() .withComposite( Arrays.asList( "tracecontext", "baggage", "b3", "b3multi", "jaeger", "xray", "ottrace")); expected.withPropagator(propagator); // TracerProvider config - TracerProvider tracerProvider = new TracerProvider(); + TracerProviderModel tracerProvider = new TracerProviderModel(); - SpanLimits spanLimits = - new SpanLimits() + SpanLimitsModel spanLimits = + new SpanLimitsModel() .withAttributeValueLengthLimit(4096) .withAttributeCountLimit(128) .withEventCountLimit(128) @@ -110,86 +110,90 @@ void parse_KitchenSinkExampleFile() throws IOException { .withLinkAttributeCountLimit(128); tracerProvider.withLimits(spanLimits); - Sampler sampler = - new Sampler() + SamplerModel sampler = + new SamplerModel() .withParentBased( - new ParentBased() + new ParentBasedModel() .withRoot( - new Sampler() - .withTraceIdRatioBased(new TraceIdRatioBased().withRatio(0.0001))) - .withRemoteParentSampled(new Sampler().withAlwaysOn(new AlwaysOn())) - .withRemoteParentNotSampled(new Sampler().withAlwaysOff(new AlwaysOff())) - .withLocalParentSampled(new Sampler().withAlwaysOn(new AlwaysOn())) - .withLocalParentNotSampled(new Sampler().withAlwaysOff(new AlwaysOff()))); + new SamplerModel() + .withTraceIdRatioBased(new TraceIdRatioBasedModel().withRatio(0.0001))) + .withRemoteParentSampled(new SamplerModel().withAlwaysOn(new AlwaysOnModel())) + .withRemoteParentNotSampled( + new SamplerModel().withAlwaysOff(new AlwaysOffModel())) + .withLocalParentSampled(new SamplerModel().withAlwaysOn(new AlwaysOnModel())) + .withLocalParentNotSampled( + new SamplerModel().withAlwaysOff(new AlwaysOffModel()))); tracerProvider.withSampler(sampler); - SpanProcessor spanProcessor1 = - new SpanProcessor() + SpanProcessorModel spanProcessor1 = + new SpanProcessorModel() .withBatch( - new BatchSpanProcessor() + new BatchSpanProcessorModel() .withScheduleDelay(5_000) .withExportTimeout(30_000) .withMaxQueueSize(2048) .withMaxExportBatchSize(512) .withExporter( - new SpanExporter() + new SpanExporterModel() .withOtlp( - new Otlp() + new OtlpModel() .withProtocol("http/protobuf") .withEndpoint("http://localhost:4318") .withCertificate("/app/cert.pem") .withClientKey("/app/cert.pem") .withClientCertificate("/app/cert.pem") .withHeaders( - new Headers().withAdditionalProperty("api-key", "1234")) + new HeadersModel() + .withAdditionalProperty("api-key", "1234")) .withCompression("gzip") .withTimeout(10_000)))); - SpanProcessor spanProcessor2 = - new SpanProcessor() + SpanProcessorModel spanProcessor2 = + new SpanProcessorModel() .withBatch( - new BatchSpanProcessor() + new BatchSpanProcessorModel() .withExporter( - new SpanExporter() + new SpanExporterModel() .withZipkin( - new Zipkin() + new ZipkinModel() .withEndpoint("http://localhost:9411/api/v2/spans") .withTimeout(10_000)))); - SpanProcessor spanProcessor3 = - new SpanProcessor() + SpanProcessorModel spanProcessor3 = + new SpanProcessorModel() .withSimple( - new SimpleSpanProcessor() - .withExporter(new SpanExporter().withConsole(new Console()))); + new SimpleSpanProcessorModel() + .withExporter(new SpanExporterModel().withConsole(new ConsoleModel()))); tracerProvider.withProcessors(Arrays.asList(spanProcessor1, spanProcessor2, spanProcessor3)); expected.withTracerProvider(tracerProvider); // end TracerProvider config // LoggerProvider config - LoggerProvider loggerProvider = new LoggerProvider(); + LoggerProviderModel loggerProvider = new LoggerProviderModel(); - LogRecordLimits logRecordLimits = - new LogRecordLimits().withAttributeValueLengthLimit(4096).withAttributeCountLimit(128); + LogRecordLimitsModel logRecordLimits = + new LogRecordLimitsModel().withAttributeValueLengthLimit(4096).withAttributeCountLimit(128); loggerProvider.withLimits(logRecordLimits); - LogRecordProcessor logRecordProcessor = - new LogRecordProcessor() + LogRecordProcessorModel logRecordProcessor = + new LogRecordProcessorModel() .withBatch( - new BatchLogRecordProcessor() + new BatchLogRecordProcessorModel() .withScheduleDelay(5_000) .withExportTimeout(30_000) .withMaxQueueSize(2048) .withMaxExportBatchSize(512) .withExporter( - new LogRecordExporter() + new LogRecordExporterModel() .withOtlp( - new Otlp() + new OtlpModel() .withProtocol("http/protobuf") .withEndpoint("http://localhost:4318") .withCertificate("/app/cert.pem") .withClientKey("/app/cert.pem") .withClientCertificate("/app/cert.pem") .withHeaders( - new Headers().withAdditionalProperty("api-key", "1234")) + new HeadersModel() + .withAdditionalProperty("api-key", "1234")) .withCompression("gzip") .withTimeout(10_000)))); loggerProvider.withProcessors(Collections.singletonList(logRecordProcessor)); @@ -198,64 +202,65 @@ void parse_KitchenSinkExampleFile() throws IOException { // end LoggerProvider config // MeterProvider config - MeterProvider meterProvider = new MeterProvider(); + MeterProviderModel meterProvider = new MeterProviderModel(); - MetricReader metricReader1 = - new MetricReader() + MetricReaderModel metricReader1 = + new MetricReaderModel() .withPull( - new PullMetricReader() + new PullMetricReaderModel() .withExporter( - new MetricExporter() + new MetricExporterModel() .withPrometheus( - new Prometheus().withHost("localhost").withPort(9464)))); - MetricReader metricReader2 = - new MetricReader() + new PrometheusModel().withHost("localhost").withPort(9464)))); + MetricReaderModel metricReader2 = + new MetricReaderModel() .withPeriodic( - new PeriodicMetricReader() + new PeriodicMetricReaderModel() .withInterval(5_000) .withTimeout(30_000) .withExporter( - new MetricExporter() + new MetricExporterModel() .withOtlp( - new OtlpMetric() + new OtlpMetricModel() .withProtocol("http/protobuf") .withEndpoint("http://localhost:4318") .withCertificate("/app/cert.pem") .withClientKey("/app/cert.pem") .withClientCertificate("/app/cert.pem") .withHeaders( - new Headers().withAdditionalProperty("api-key", "1234")) + new HeadersModel() + .withAdditionalProperty("api-key", "1234")) .withCompression("gzip") .withTimeout(10_000) .withTemporalityPreference("delta") .withDefaultHistogramAggregation( - DefaultHistogramAggregation + OtlpMetricModel.DefaultHistogramAggregation .BASE_2_EXPONENTIAL_BUCKET_HISTOGRAM)))); - MetricReader metricReader3 = - new MetricReader() + MetricReaderModel metricReader3 = + new MetricReaderModel() .withPeriodic( - new PeriodicMetricReader() - .withExporter(new MetricExporter().withConsole(new Console()))); + new PeriodicMetricReaderModel() + .withExporter(new MetricExporterModel().withConsole(new ConsoleModel()))); meterProvider.withReaders(Arrays.asList(metricReader1, metricReader2, metricReader3)); - View view = - new View() + ViewModel view = + new ViewModel() .withSelector( - new Selector() + new SelectorModel() .withInstrumentName("my-instrument") - .withInstrumentType(Selector.InstrumentType.HISTOGRAM) + .withInstrumentType(SelectorModel.InstrumentType.HISTOGRAM) .withUnit("ms") .withMeterName("my-meter") .withMeterVersion("1.0.0") .withMeterSchemaUrl("https://opentelemetry.io/schemas/1.16.0")) .withStream( - new Stream() + new StreamModel() .withName("new_instrument_name") .withDescription("new_description") .withAggregation( - new Aggregation() + new AggregationModel() .withExplicitBucketHistogram( - new ExplicitBucketHistogram() + new ExplicitBucketHistogramModel() .withBoundaries( Arrays.asList( 0.0, 5.0, 10.0, 25.0, 50.0, 75.0, 100.0, 250.0, 500.0, @@ -269,7 +274,7 @@ void parse_KitchenSinkExampleFile() throws IOException { try (FileInputStream configExampleFile = new FileInputStream(System.getenv("CONFIG_EXAMPLE_DIR") + "/kitchen-sink.yaml")) { - OpenTelemetryConfiguration config = FileConfiguration.parse(configExampleFile); + OpenTelemetryConfigurationModel config = FileConfiguration.parse(configExampleFile); // General config assertThat(config.getFileFormat()).isEqualTo("0.1"); @@ -278,20 +283,20 @@ void parse_KitchenSinkExampleFile() throws IOException { assertThat(config.getPropagator()).isEqualTo(propagator); // TracerProvider config - TracerProvider configTracerProvider = config.getTracerProvider(); + TracerProviderModel configTracerProvider = config.getTracerProvider(); assertThat(configTracerProvider.getLimits()).isEqualTo(spanLimits); assertThat(configTracerProvider.getSampler()).isEqualTo(sampler); assertThat(configTracerProvider.getProcessors()) .isEqualTo(Arrays.asList(spanProcessor1, spanProcessor2, spanProcessor3)); // LoggerProvider config - LoggerProvider configLoggerProvider = config.getLoggerProvider(); + LoggerProviderModel configLoggerProvider = config.getLoggerProvider(); assertThat(configLoggerProvider.getLimits()).isEqualTo(logRecordLimits); assertThat(configLoggerProvider.getProcessors()) .isEqualTo(Collections.singletonList(logRecordProcessor)); // MeterProvider config - MeterProvider configMeterProvider = config.getMeterProvider(); + MeterProviderModel configMeterProvider = config.getMeterProvider(); assertThat(configMeterProvider.getReaders()) .isEqualTo(Arrays.asList(metricReader1, metricReader2, metricReader3)); assertThat(configMeterProvider.getViews()).isEqualTo(Collections.singletonList(view)); @@ -317,7 +322,7 @@ void parse_nullValuesParsedToEmptyObjects() { + " stream:\n" + " aggregation:\n" + " drop: {}\n"; - OpenTelemetryConfiguration objectPlaceholderModel = + OpenTelemetryConfigurationModel objectPlaceholderModel = FileConfiguration.parse( new ByteArrayInputStream(objectPlaceholderString.getBytes(StandardCharsets.UTF_8))); @@ -335,11 +340,11 @@ void parse_nullValuesParsedToEmptyObjects() { + " stream:\n" + " aggregation:\n" + " drop:\n"; - OpenTelemetryConfiguration noObjectPlaceholderModel = + OpenTelemetryConfigurationModel noObjectPlaceholderModel = FileConfiguration.parse( new ByteArrayInputStream(noOjbectPlaceholderString.getBytes(StandardCharsets.UTF_8))); - SpanExporter exporter = + SpanExporterModel exporter = noObjectPlaceholderModel .getTracerProvider() .getProcessors() @@ -349,7 +354,7 @@ void parse_nullValuesParsedToEmptyObjects() { assertThat(exporter.getConsole()).isNotNull(); assertThat(exporter.getOtlp()).isNull(); - Aggregation aggregation = + AggregationModel aggregation = noObjectPlaceholderModel.getMeterProvider().getViews().get(0).getStream().getAggregation(); assertThat(aggregation.getDrop()).isNotNull(); assertThat(aggregation.getSum()).isNull(); @@ -369,7 +374,7 @@ void parse_nullBoxedPrimitivesParsedToNull() { + " trace_id_ratio_based:\n" + " ratio:\n"; // Double - OpenTelemetryConfiguration model = + OpenTelemetryConfigurationModel model = FileConfiguration.parse(new ByteArrayInputStream(yaml.getBytes(StandardCharsets.UTF_8))); assertThat(model.getFileFormat()).isNull(); @@ -379,12 +384,13 @@ void parse_nullBoxedPrimitivesParsedToNull() { assertThat(model) .isEqualTo( - new OpenTelemetryConfiguration() - .withAttributeLimits(new AttributeLimits()) + new OpenTelemetryConfigurationModel() + .withAttributeLimits(new AttributeLimitsModel()) .withTracerProvider( - new TracerProvider() + new TracerProviderModel() .withSampler( - new Sampler().withTraceIdRatioBased(new TraceIdRatioBased())))); + new SamplerModel() + .withTraceIdRatioBased(new TraceIdRatioBasedModel())))); } @ParameterizedTest @@ -494,30 +500,31 @@ void read_WithEnvironmentVariables() { + " endpoint: ${UNSET_ENV_VAR}\n"; Map envVars = new HashMap<>(); envVars.put("OTEL_EXPORTER_OTLP_ENDPOINT", "http://collector:4317"); - OpenTelemetryConfiguration model = + OpenTelemetryConfigurationModel model = FileConfiguration.parse( new ByteArrayInputStream(yaml.getBytes(StandardCharsets.UTF_8)), envVars); assertThat(model) .isEqualTo( - new OpenTelemetryConfiguration() + new OpenTelemetryConfigurationModel() .withFileFormat("0.1") .withTracerProvider( - new TracerProvider() + new TracerProviderModel() .withProcessors( Arrays.asList( - new SpanProcessor() + new SpanProcessorModel() .withBatch( - new BatchSpanProcessor() + new BatchSpanProcessorModel() .withExporter( - new SpanExporter() + new SpanExporterModel() .withOtlp( - new Otlp() + new OtlpModel() .withEndpoint( "http://collector:4317")))), - new SpanProcessor() + new SpanProcessorModel() .withBatch( - new BatchSpanProcessor() + new BatchSpanProcessorModel() .withExporter( - new SpanExporter().withOtlp(new Otlp()))))))); + new SpanExporterModel() + .withOtlp(new OtlpModel()))))))); } } diff --git a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/InstrumentSelectorFactoryTest.java b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/InstrumentSelectorFactoryTest.java index 9b3ada1a6fe..fd9a2640708 100644 --- a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/InstrumentSelectorFactoryTest.java +++ b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/InstrumentSelectorFactoryTest.java @@ -11,7 +11,7 @@ import io.opentelemetry.sdk.autoconfigure.internal.SpiHelper; import io.opentelemetry.sdk.autoconfigure.spi.ConfigurationException; -import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.Selector; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.SelectorModel; import io.opentelemetry.sdk.metrics.InstrumentSelector; import io.opentelemetry.sdk.metrics.InstrumentType; import java.util.Collections; @@ -24,7 +24,7 @@ void create_Defaults() { assertThatThrownBy( () -> InstrumentSelectorFactory.getInstance() - .create(new Selector(), mock(SpiHelper.class), Collections.emptyList())) + .create(new SelectorModel(), mock(SpiHelper.class), Collections.emptyList())) .isInstanceOf(ConfigurationException.class) .hasMessage("Invalid selector"); } @@ -34,9 +34,9 @@ void create() { assertThat( InstrumentSelectorFactory.getInstance() .create( - new Selector() + new SelectorModel() .withInstrumentName("instrument-name") - .withInstrumentType(Selector.InstrumentType.COUNTER) + .withInstrumentType(SelectorModel.InstrumentType.COUNTER) .withMeterName("meter-name") .withMeterSchemaUrl("https://opentelemetry.io/schemas/1.16.0") .withMeterVersion("1.0.0"), diff --git a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/LogLimitsFactoryTest.java b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/LogLimitsFactoryTest.java index 492b8c4b425..53e811e6629 100644 --- a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/LogLimitsFactoryTest.java +++ b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/LogLimitsFactoryTest.java @@ -9,8 +9,8 @@ import static org.mockito.Mockito.mock; import io.opentelemetry.sdk.autoconfigure.internal.SpiHelper; -import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.AttributeLimits; -import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.LogRecordLimits; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.AttributeLimitsModel; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.LogRecordLimitsModel; import io.opentelemetry.sdk.logs.LogLimits; import java.util.Collections; import java.util.stream.Stream; @@ -34,17 +34,24 @@ private static Stream createArguments() { Arguments.of( LogRecordLimitsAndAttributeLimits.create(null, null), LogLimits.builder().build()), Arguments.of( - LogRecordLimitsAndAttributeLimits.create(new AttributeLimits(), new LogRecordLimits()), + LogRecordLimitsAndAttributeLimits.create( + new AttributeLimitsModel(), new LogRecordLimitsModel()), LogLimits.builder().build()), Arguments.of( LogRecordLimitsAndAttributeLimits.create( - new AttributeLimits().withAttributeValueLengthLimit(1).withAttributeCountLimit(2), - new LogRecordLimits()), + new AttributeLimitsModel() + .withAttributeValueLengthLimit(1) + .withAttributeCountLimit(2), + new LogRecordLimitsModel()), LogLimits.builder().setMaxAttributeValueLength(1).setMaxNumberOfAttributes(2).build()), Arguments.of( LogRecordLimitsAndAttributeLimits.create( - new AttributeLimits().withAttributeValueLengthLimit(1).withAttributeCountLimit(2), - new LogRecordLimits().withAttributeValueLengthLimit(3).withAttributeCountLimit(4)), + new AttributeLimitsModel() + .withAttributeValueLengthLimit(1) + .withAttributeCountLimit(2), + new LogRecordLimitsModel() + .withAttributeValueLengthLimit(3) + .withAttributeCountLimit(4)), LogLimits.builder().setMaxAttributeValueLength(3).setMaxNumberOfAttributes(4).build())); } } diff --git a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/LogRecordExporterFactoryTest.java b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/LogRecordExporterFactoryTest.java index a2a6d057139..e826411feee 100644 --- a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/LogRecordExporterFactoryTest.java +++ b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/LogRecordExporterFactoryTest.java @@ -22,8 +22,9 @@ import io.opentelemetry.sdk.autoconfigure.spi.ConfigurationException; import io.opentelemetry.sdk.autoconfigure.spi.internal.StructuredConfigProperties; import io.opentelemetry.sdk.extension.incubator.fileconfig.component.LogRecordExporterComponentProvider; -import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.Headers; -import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.Otlp; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.HeadersModel; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.LogRecordExporterModel; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.OtlpModel; import io.opentelemetry.sdk.logs.export.LogRecordExporter; import java.io.Closeable; import java.io.IOException; @@ -67,8 +68,8 @@ void create_OtlpDefaults() { LogRecordExporterFactory.getInstance() .create( new io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model - .LogRecordExporter() - .withOtlp(new Otlp()), + .LogRecordExporterModel() + .withOtlp(new OtlpModel()), spiHelper, closeables); cleanup.addCloseable(exporter); @@ -122,13 +123,13 @@ void create_OtlpConfigured(@TempDir Path tempDir) LogRecordExporterFactory.getInstance() .create( new io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model - .LogRecordExporter() + .LogRecordExporterModel() .withOtlp( - new Otlp() + new OtlpModel() .withProtocol("http/protobuf") .withEndpoint("http://example:4318") .withHeaders( - new Headers() + new HeadersModel() .withAdditionalProperty("key1", "value1") .withAdditionalProperty("key2", "value2")) .withCompression("gzip") @@ -171,7 +172,7 @@ void create_SpiExporter_Unknown() { LogRecordExporterFactory.getInstance() .create( new io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model - .LogRecordExporter() + .LogRecordExporterModel() .withAdditionalProperty( "unknown_key", ImmutableMap.of("key1", "value1")), spiHelper, @@ -187,8 +188,7 @@ void create_SpiExporter_Valid() { LogRecordExporter logRecordExporter = LogRecordExporterFactory.getInstance() .create( - new io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model - .LogRecordExporter() + new LogRecordExporterModel() .withAdditionalProperty("test", ImmutableMap.of("key1", "value1")), spiHelper, new ArrayList<>()); diff --git a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/LogRecordProcessorFactoryTest.java b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/LogRecordProcessorFactoryTest.java index 31038580e82..3f3adb75066 100644 --- a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/LogRecordProcessorFactoryTest.java +++ b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/LogRecordProcessorFactoryTest.java @@ -14,11 +14,11 @@ import io.opentelemetry.sdk.autoconfigure.internal.SpiHelper; import io.opentelemetry.sdk.autoconfigure.spi.ConfigurationException; import io.opentelemetry.sdk.extension.incubator.fileconfig.component.LogRecordProcessorComponentProvider; -import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.BatchLogRecordProcessor; -import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.LogRecordExporter; -import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.LogRecordProcessor; -import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.Otlp; -import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.SimpleLogRecordProcessor; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.BatchLogRecordProcessorModel; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.LogRecordExporterModel; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.LogRecordProcessorModel; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.OtlpModel; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.SimpleLogRecordProcessorModel; import java.io.Closeable; import java.time.Duration; import java.util.ArrayList; @@ -41,7 +41,7 @@ void create_BatchNullExporter() { () -> LogRecordProcessorFactory.getInstance() .create( - new LogRecordProcessor().withBatch(new BatchLogRecordProcessor()), + new LogRecordProcessorModel().withBatch(new BatchLogRecordProcessorModel()), spiHelper, Collections.emptyList())) .isInstanceOf(ConfigurationException.class) @@ -60,10 +60,10 @@ void create_BatchDefaults() { io.opentelemetry.sdk.logs.LogRecordProcessor processor = LogRecordProcessorFactory.getInstance() .create( - new LogRecordProcessor() + new LogRecordProcessorModel() .withBatch( - new BatchLogRecordProcessor() - .withExporter(new LogRecordExporter().withOtlp(new Otlp()))), + new BatchLogRecordProcessorModel() + .withExporter(new LogRecordExporterModel().withOtlp(new OtlpModel()))), spiHelper, closeables); cleanup.addCloseable(processor); @@ -87,10 +87,10 @@ void create_BatchConfigured() { io.opentelemetry.sdk.logs.LogRecordProcessor processor = LogRecordProcessorFactory.getInstance() .create( - new LogRecordProcessor() + new LogRecordProcessorModel() .withBatch( - new BatchLogRecordProcessor() - .withExporter(new LogRecordExporter().withOtlp(new Otlp())) + new BatchLogRecordProcessorModel() + .withExporter(new LogRecordExporterModel().withOtlp(new OtlpModel())) .withScheduleDelay(1) .withMaxExportBatchSize(2) .withExportTimeout(3)), @@ -108,7 +108,8 @@ void create_SimpleNullExporter() { () -> LogRecordProcessorFactory.getInstance() .create( - new LogRecordProcessor().withSimple(new SimpleLogRecordProcessor()), + new LogRecordProcessorModel() + .withSimple(new SimpleLogRecordProcessorModel()), spiHelper, Collections.emptyList())) .isInstanceOf(ConfigurationException.class) @@ -126,10 +127,10 @@ void create_SimpleConfigured() { io.opentelemetry.sdk.logs.LogRecordProcessor processor = LogRecordProcessorFactory.getInstance() .create( - new LogRecordProcessor() + new LogRecordProcessorModel() .withSimple( - new SimpleLogRecordProcessor() - .withExporter(new LogRecordExporter().withOtlp(new Otlp()))), + new SimpleLogRecordProcessorModel() + .withExporter(new LogRecordExporterModel().withOtlp(new OtlpModel()))), spiHelper, closeables); cleanup.addCloseable(processor); @@ -144,7 +145,7 @@ void create_SpiProcessor_Unknown() { () -> LogRecordProcessorFactory.getInstance() .create( - new LogRecordProcessor() + new LogRecordProcessorModel() .withAdditionalProperty( "unknown_key", ImmutableMap.of("key1", "value1")), spiHelper, @@ -159,7 +160,7 @@ void create_SpiExporter_Valid() { io.opentelemetry.sdk.logs.LogRecordProcessor logRecordProcessor = LogRecordProcessorFactory.getInstance() .create( - new LogRecordProcessor() + new LogRecordProcessorModel() .withAdditionalProperty("test", ImmutableMap.of("key1", "value1")), spiHelper, new ArrayList<>()); diff --git a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/LoggerProviderFactoryTest.java b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/LoggerProviderFactoryTest.java index 312c8dc85d4..5293520b700 100644 --- a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/LoggerProviderFactoryTest.java +++ b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/LoggerProviderFactoryTest.java @@ -10,13 +10,13 @@ import io.opentelemetry.exporter.otlp.logs.OtlpGrpcLogRecordExporter; import io.opentelemetry.internal.testing.CleanupExtension; import io.opentelemetry.sdk.autoconfigure.internal.SpiHelper; -import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.AttributeLimits; -import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.BatchLogRecordProcessor; -import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.LogRecordExporter; -import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.LogRecordLimits; -import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.LogRecordProcessor; -import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.LoggerProvider; -import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.Otlp; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.AttributeLimitsModel; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.BatchLogRecordProcessorModel; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.LogRecordExporterModel; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.LogRecordLimitsModel; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.LogRecordProcessorModel; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.LoggerProviderModel; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.OtlpModel; import io.opentelemetry.sdk.logs.LogLimits; import io.opentelemetry.sdk.logs.SdkLoggerProvider; import java.io.Closeable; @@ -56,23 +56,25 @@ private static Stream createArguments() { LoggerProviderAndAttributeLimits.create(null, null), SdkLoggerProvider.builder().build()), Arguments.of( - LoggerProviderAndAttributeLimits.create(new AttributeLimits(), new LoggerProvider()), + LoggerProviderAndAttributeLimits.create( + new AttributeLimitsModel(), new LoggerProviderModel()), SdkLoggerProvider.builder().build()), Arguments.of( LoggerProviderAndAttributeLimits.create( - new AttributeLimits(), - new LoggerProvider() + new AttributeLimitsModel(), + new LoggerProviderModel() .withLimits( - new LogRecordLimits() + new LogRecordLimitsModel() .withAttributeCountLimit(1) .withAttributeValueLengthLimit(2)) .withProcessors( Collections.singletonList( - new LogRecordProcessor() + new LogRecordProcessorModel() .withBatch( - new BatchLogRecordProcessor() + new BatchLogRecordProcessorModel() .withExporter( - new LogRecordExporter().withOtlp(new Otlp())))))), + new LogRecordExporterModel() + .withOtlp(new OtlpModel())))))), SdkLoggerProvider.builder() .setLogLimits( () -> diff --git a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/MeterProviderFactoryTest.java b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/MeterProviderFactoryTest.java index b2ac1d838d0..8094bb639c0 100644 --- a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/MeterProviderFactoryTest.java +++ b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/MeterProviderFactoryTest.java @@ -10,13 +10,13 @@ import io.opentelemetry.exporter.otlp.metrics.OtlpGrpcMetricExporter; import io.opentelemetry.internal.testing.CleanupExtension; import io.opentelemetry.sdk.autoconfigure.internal.SpiHelper; -import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.MeterProvider; -import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.MetricExporter; -import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.MetricReader; -import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.OtlpMetric; -import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.PeriodicMetricReader; -import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.Selector; -import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.Stream; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.MeterProviderModel; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.MetricExporterModel; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.MetricReaderModel; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.OtlpMetricModel; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.PeriodicMetricReaderModel; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.SelectorModel; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.StreamModel; import io.opentelemetry.sdk.metrics.InstrumentSelector; import io.opentelemetry.sdk.metrics.SdkMeterProvider; import io.opentelemetry.sdk.metrics.View; @@ -42,7 +42,7 @@ void create_Defaults() { SdkMeterProvider provider = MeterProviderFactory.getInstance() - .create(new MeterProvider(), spiHelper, closeables) + .create(new MeterProviderModel(), spiHelper, closeables) .build(); cleanup.addCloseable(provider); cleanup.addCloseables(closeables); @@ -68,21 +68,25 @@ void create_Configured() { SdkMeterProvider provider = MeterProviderFactory.getInstance() .create( - new MeterProvider() + new MeterProviderModel() .withReaders( Collections.singletonList( - new MetricReader() + new MetricReaderModel() .withPeriodic( - new PeriodicMetricReader() + new PeriodicMetricReaderModel() .withExporter( - new MetricExporter().withOtlp(new OtlpMetric()))))) + new MetricExporterModel() + .withOtlp(new OtlpMetricModel()))))) .withViews( Collections.singletonList( new io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model - .View() - .withSelector(new Selector().withInstrumentName("instrument-name")) + .ViewModel() + .withSelector( + new SelectorModel().withInstrumentName("instrument-name")) .withStream( - new Stream().withName("stream-name").withAttributeKeys(null)))), + new StreamModel() + .withName("stream-name") + .withAttributeKeys(null)))), spiHelper, closeables) .build(); diff --git a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/MetricExporterFactoryTest.java b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/MetricExporterFactoryTest.java index 64f0db469ec..3707a2d582c 100644 --- a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/MetricExporterFactoryTest.java +++ b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/MetricExporterFactoryTest.java @@ -23,11 +23,10 @@ import io.opentelemetry.sdk.autoconfigure.spi.ConfigurationException; import io.opentelemetry.sdk.autoconfigure.spi.internal.StructuredConfigProperties; import io.opentelemetry.sdk.extension.incubator.fileconfig.component.MetricExporterComponentProvider; -import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.Console; -import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.Headers; -import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.OtlpMetric; -import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.OtlpMetric.DefaultHistogramAggregation; -import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.Prometheus; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.ConsoleModel; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.HeadersModel; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.OtlpMetricModel; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.PrometheusModel; import io.opentelemetry.sdk.metrics.Aggregation; import io.opentelemetry.sdk.metrics.InstrumentType; import io.opentelemetry.sdk.metrics.export.AggregationTemporalitySelector; @@ -74,8 +73,8 @@ void create_OtlpDefaults() { MetricExporterFactory.getInstance() .create( new io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model - .MetricExporter() - .withOtlp(new OtlpMetric()), + .MetricExporterModel() + .withOtlp(new OtlpMetricModel()), spiHelper, closeables); cleanup.addCloseable(exporter); @@ -132,13 +131,13 @@ void create_OtlpConfigured(@TempDir Path tempDir) MetricExporterFactory.getInstance() .create( new io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model - .MetricExporter() + .MetricExporterModel() .withOtlp( - new OtlpMetric() + new OtlpMetricModel() .withProtocol("http/protobuf") .withEndpoint("http://example:4318") .withHeaders( - new Headers() + new HeadersModel() .withAdditionalProperty("key1", "value1") .withAdditionalProperty("key2", "value2")) .withCompression("gzip") @@ -148,7 +147,8 @@ void create_OtlpConfigured(@TempDir Path tempDir) .withClientCertificate(clientCertificatePath) .withTemporalityPreference("delta") .withDefaultHistogramAggregation( - DefaultHistogramAggregation.BASE_2_EXPONENTIAL_BUCKET_HISTOGRAM)), + OtlpMetricModel.DefaultHistogramAggregation + .BASE_2_EXPONENTIAL_BUCKET_HISTOGRAM)), spiHelper, closeables); cleanup.addCloseable(exporter); @@ -188,8 +188,8 @@ void create_Console() { MetricExporterFactory.getInstance() .create( new io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model - .MetricExporter() - .withConsole(new Console()), + .MetricExporterModel() + .withConsole(new ConsoleModel()), spiHelper, closeables); cleanup.addCloseable(exporter); @@ -207,8 +207,8 @@ void create_PrometheusExporter() { MetricExporterFactory.getInstance() .create( new io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model - .MetricExporter() - .withPrometheus(new Prometheus()), + .MetricExporterModel() + .withPrometheus(new PrometheusModel()), spiHelper, closeables)) .isInstanceOf(ConfigurationException.class) @@ -223,7 +223,7 @@ void create_SpiExporter_Unknown() { MetricExporterFactory.getInstance() .create( new io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model - .MetricExporter() + .MetricExporterModel() .withAdditionalProperty( "unknown_key", ImmutableMap.of("key1", "value1")), spiHelper, @@ -239,7 +239,7 @@ void create_SpiExporter_Valid() { MetricExporterFactory.getInstance() .create( new io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model - .MetricExporter() + .MetricExporterModel() .withAdditionalProperty("test", ImmutableMap.of("key1", "value1")), spiHelper, new ArrayList<>()); diff --git a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/MetricReaderFactoryTest.java b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/MetricReaderFactoryTest.java index 22a7d36106d..976bb6da3a2 100644 --- a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/MetricReaderFactoryTest.java +++ b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/MetricReaderFactoryTest.java @@ -17,12 +17,12 @@ import io.opentelemetry.sdk.autoconfigure.internal.SpiHelper; import io.opentelemetry.sdk.autoconfigure.spi.ConfigurationException; import io.opentelemetry.sdk.autoconfigure.spi.internal.ComponentProvider; -import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.MetricExporter; -import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.MetricReader; -import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.OtlpMetric; -import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.PeriodicMetricReader; -import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.Prometheus; -import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.PullMetricReader; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.MetricExporterModel; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.MetricReaderModel; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.OtlpMetricModel; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.PeriodicMetricReaderModel; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.PrometheusModel; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.PullMetricReaderModel; import java.io.Closeable; import java.io.IOException; import java.net.ServerSocket; @@ -49,7 +49,7 @@ void create_PeriodicNullExporter() { () -> MetricReaderFactory.getInstance() .create( - new MetricReader().withPeriodic(new PeriodicMetricReader()), + new MetricReaderModel().withPeriodic(new PeriodicMetricReaderModel()), spiHelper, Collections.emptyList())) .isInstanceOf(ConfigurationException.class) @@ -68,10 +68,11 @@ void create_PeriodicDefaults() { io.opentelemetry.sdk.metrics.export.MetricReader reader = MetricReaderFactory.getInstance() .create( - new MetricReader() + new MetricReaderModel() .withPeriodic( - new PeriodicMetricReader() - .withExporter(new MetricExporter().withOtlp(new OtlpMetric()))), + new PeriodicMetricReaderModel() + .withExporter( + new MetricExporterModel().withOtlp(new OtlpMetricModel()))), spiHelper, closeables); cleanup.addCloseable(reader); @@ -93,10 +94,10 @@ void create_PeriodicConfigured() { io.opentelemetry.sdk.metrics.export.MetricReader reader = MetricReaderFactory.getInstance() .create( - new MetricReader() + new MetricReaderModel() .withPeriodic( - new PeriodicMetricReader() - .withExporter(new MetricExporter().withOtlp(new OtlpMetric())) + new PeriodicMetricReaderModel() + .withExporter(new MetricExporterModel().withOtlp(new OtlpMetricModel())) .withInterval(1)), spiHelper, closeables); @@ -118,12 +119,12 @@ void create_PullPrometheusDefault() throws IOException { io.opentelemetry.sdk.metrics.export.MetricReader reader = MetricReaderFactory.getInstance() .create( - new MetricReader() + new MetricReaderModel() .withPull( - new PullMetricReader() + new PullMetricReaderModel() .withExporter( - new MetricExporter() - .withPrometheus(new Prometheus().withPort(port)))), + new MetricExporterModel() + .withPrometheus(new PrometheusModel().withPort(port)))), spiHelper, closeables); cleanup.addCloseable(reader); @@ -148,13 +149,15 @@ void create_PullPrometheusConfigured() throws IOException { io.opentelemetry.sdk.metrics.export.MetricReader reader = MetricReaderFactory.getInstance() .create( - new MetricReader() + new MetricReaderModel() .withPull( - new PullMetricReader() + new PullMetricReaderModel() .withExporter( - new MetricExporter() + new MetricExporterModel() .withPrometheus( - new Prometheus().withHost("localhost").withPort(port)))), + new PrometheusModel() + .withHost("localhost") + .withPort(port)))), spiHelper, closeables); cleanup.addCloseable(reader); @@ -171,7 +174,7 @@ void create_InvalidPullReader() { () -> MetricReaderFactory.getInstance() .create( - new MetricReader().withPull(new PullMetricReader()), + new MetricReaderModel().withPull(new PullMetricReaderModel()), spiHelper, Collections.emptyList())) .isInstanceOf(ConfigurationException.class) @@ -181,8 +184,10 @@ void create_InvalidPullReader() { () -> MetricReaderFactory.getInstance() .create( - new MetricReader() - .withPull(new PullMetricReader().withExporter(new MetricExporter())), + new MetricReaderModel() + .withPull( + new PullMetricReaderModel() + .withExporter(new MetricExporterModel())), spiHelper, Collections.emptyList())) .isInstanceOf(ConfigurationException.class) @@ -192,10 +197,11 @@ void create_InvalidPullReader() { () -> MetricReaderFactory.getInstance() .create( - new MetricReader() + new MetricReaderModel() .withPull( - new PullMetricReader() - .withExporter(new MetricExporter().withOtlp(new OtlpMetric()))), + new PullMetricReaderModel() + .withExporter( + new MetricExporterModel().withOtlp(new OtlpMetricModel()))), spiHelper, Collections.emptyList())) .isInstanceOf(ConfigurationException.class) diff --git a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/OpenTelemetryConfigurationFactoryTest.java b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/OpenTelemetryConfigurationFactoryTest.java index 7de50047ece..247e5932a23 100644 --- a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/OpenTelemetryConfigurationFactoryTest.java +++ b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/OpenTelemetryConfigurationFactoryTest.java @@ -23,30 +23,30 @@ import io.opentelemetry.sdk.OpenTelemetrySdk; import io.opentelemetry.sdk.autoconfigure.internal.SpiHelper; import io.opentelemetry.sdk.autoconfigure.spi.ConfigurationException; -import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.AlwaysOn; -import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.Attributes; -import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.BatchLogRecordProcessor; -import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.BatchSpanProcessor; -import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.LogRecordExporter; -import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.LogRecordLimits; -import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.LogRecordProcessor; -import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.LoggerProvider; -import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.MeterProvider; -import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.MetricExporter; -import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.MetricReader; -import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.OpenTelemetryConfiguration; -import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.Otlp; -import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.OtlpMetric; -import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.PeriodicMetricReader; -import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.Propagator; -import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.Resource; -import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.Sampler; -import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.Selector; -import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.SimpleLogRecordProcessor; -import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.SpanExporter; -import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.SpanProcessor; -import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.Stream; -import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.TracerProvider; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.AlwaysOnModel; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.AttributesModel; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.BatchLogRecordProcessorModel; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.BatchSpanProcessorModel; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.LogRecordExporterModel; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.LogRecordLimitsModel; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.LogRecordProcessorModel; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.LoggerProviderModel; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.MeterProviderModel; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.MetricExporterModel; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.MetricReaderModel; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.OpenTelemetryConfigurationModel; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.OtlpMetricModel; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.OtlpModel; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.PeriodicMetricReaderModel; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.PropagatorModel; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.ResourceModel; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.SamplerModel; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.SelectorModel; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.SimpleLogRecordProcessorModel; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.SpanExporterModel; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.SpanProcessorModel; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.StreamModel; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.TracerProviderModel; import io.opentelemetry.sdk.logs.LogLimits; import io.opentelemetry.sdk.logs.SdkLoggerProvider; import io.opentelemetry.sdk.metrics.InstrumentSelector; @@ -71,12 +71,13 @@ class OpenTelemetryConfigurationFactoryTest { @Test void create_InvalidFileFormat() { - List testCases = + List testCases = Arrays.asList( - new OpenTelemetryConfiguration(), new OpenTelemetryConfiguration().withFileFormat("1")); + new OpenTelemetryConfigurationModel(), + new OpenTelemetryConfigurationModel().withFileFormat("1")); List closeables = new ArrayList<>(); - for (OpenTelemetryConfiguration testCase : testCases) { + for (OpenTelemetryConfigurationModel testCase : testCases) { assertThatThrownBy( () -> OpenTelemetryConfigurationFactory.getInstance() @@ -95,7 +96,8 @@ void create_Defaults() { OpenTelemetrySdk sdk = OpenTelemetryConfigurationFactory.getInstance() - .create(new OpenTelemetryConfiguration().withFileFormat("0.1"), spiHelper, closeables); + .create( + new OpenTelemetryConfigurationModel().withFileFormat("0.1"), spiHelper, closeables); cleanup.addCloseable(sdk); cleanup.addCloseables(closeables); @@ -111,20 +113,20 @@ void create_Disabled() { OpenTelemetrySdk sdk = OpenTelemetryConfigurationFactory.getInstance() .create( - new OpenTelemetryConfiguration() + new OpenTelemetryConfigurationModel() .withFileFormat("0.1") .withDisabled(true) // Logger provider configuration should be ignored since SDK is disabled .withLoggerProvider( - new LoggerProvider() + new LoggerProviderModel() .withProcessors( Collections.singletonList( - new LogRecordProcessor() + new LogRecordProcessorModel() .withSimple( - new SimpleLogRecordProcessor() + new SimpleLogRecordProcessorModel() .withExporter( - new LogRecordExporter() - .withOtlp(new Otlp())))))), + new LogRecordExporterModel() + .withOtlp(new OtlpModel())))))), spiHelper, closeables); cleanup.addCloseable(sdk); @@ -205,10 +207,10 @@ void create_Configured() { OpenTelemetrySdk sdk = OpenTelemetryConfigurationFactory.getInstance() .create( - new OpenTelemetryConfiguration() + new OpenTelemetryConfigurationModel() .withFileFormat("0.1") .withPropagator( - new Propagator() + new PropagatorModel() .withComposite( Arrays.asList( "tracecontext", @@ -218,62 +220,64 @@ void create_Configured() { "b3", "jaeger"))) .withResource( - new Resource() + new ResourceModel() .withAttributes( - new Attributes() + new AttributesModel() .withServiceName("my-service") .withAdditionalProperty("key", "val"))) .withLoggerProvider( - new LoggerProvider() + new LoggerProviderModel() .withLimits( - new LogRecordLimits() + new LogRecordLimitsModel() .withAttributeValueLengthLimit(1) .withAttributeCountLimit(2)) .withProcessors( Collections.singletonList( - new LogRecordProcessor() + new LogRecordProcessorModel() .withBatch( - new BatchLogRecordProcessor() + new BatchLogRecordProcessorModel() .withExporter( - new LogRecordExporter() - .withOtlp(new Otlp())))))) + new LogRecordExporterModel() + .withOtlp(new OtlpModel())))))) .withTracerProvider( - new TracerProvider() + new TracerProviderModel() .withLimits( new io.opentelemetry.sdk.extension.incubator.fileconfig.internal - .model.SpanLimits() + .model.SpanLimitsModel() .withAttributeCountLimit(1) .withAttributeValueLengthLimit(2) .withEventCountLimit(3) .withLinkCountLimit(4) .withEventAttributeCountLimit(5) .withLinkAttributeCountLimit(6)) - .withSampler(new Sampler().withAlwaysOn(new AlwaysOn())) + .withSampler(new SamplerModel().withAlwaysOn(new AlwaysOnModel())) .withProcessors( Collections.singletonList( - new SpanProcessor() + new SpanProcessorModel() .withBatch( - new BatchSpanProcessor() + new BatchSpanProcessorModel() .withExporter( - new SpanExporter().withOtlp(new Otlp())))))) + new SpanExporterModel() + .withOtlp(new OtlpModel())))))) .withMeterProvider( - new MeterProvider() + new MeterProviderModel() .withReaders( Collections.singletonList( - new MetricReader() + new MetricReaderModel() .withPeriodic( - new PeriodicMetricReader() + new PeriodicMetricReaderModel() .withExporter( - new MetricExporter() - .withOtlp(new OtlpMetric()))))) + new MetricExporterModel() + .withOtlp(new OtlpMetricModel()))))) .withViews( Collections.singletonList( new io.opentelemetry.sdk.extension.incubator.fileconfig.internal - .model.View() + .model.ViewModel() .withSelector( - new Selector().withInstrumentName("instrument-name")) + new SelectorModel() + .withInstrumentName("instrument-name")) .withStream( - new Stream() + new StreamModel() .withName("stream-name") .withAttributeKeys(null))))), spiHelper, diff --git a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/PropagatorFactoryTest.java b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/PropagatorFactoryTest.java index 8eb099cffa5..80377f417d0 100644 --- a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/PropagatorFactoryTest.java +++ b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/PropagatorFactoryTest.java @@ -15,7 +15,7 @@ import io.opentelemetry.extension.trace.propagation.JaegerPropagator; import io.opentelemetry.extension.trace.propagation.OtTracePropagator; import io.opentelemetry.sdk.autoconfigure.internal.SpiHelper; -import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.Propagator; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.PropagatorModel; import java.util.Arrays; import java.util.Collections; import java.util.stream.Stream; @@ -30,7 +30,7 @@ class PropagatorFactoryTest { @ParameterizedTest @MethodSource("createArguments") - void create(Propagator model, ContextPropagators expectedPropagators) { + void create(PropagatorModel model, ContextPropagators expectedPropagators) { ContextPropagators propagators = PropagatorFactory.getInstance().create(model, spiHelper, Collections.emptyList()); @@ -40,7 +40,7 @@ void create(Propagator model, ContextPropagators expectedPropagators) { private static Stream createArguments() { return Stream.of( Arguments.of( - new Propagator() + new PropagatorModel() .withComposite( Arrays.asList("tracecontext", "baggage", "ottrace", "b3multi", "b3", "jaeger")), ContextPropagators.create( diff --git a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/ResourceFactoryTest.java b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/ResourceFactoryTest.java index 584f908431c..d567d7f45e4 100644 --- a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/ResourceFactoryTest.java +++ b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/ResourceFactoryTest.java @@ -9,7 +9,8 @@ import static org.mockito.Mockito.spy; import io.opentelemetry.sdk.autoconfigure.internal.SpiHelper; -import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.Attributes; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.AttributesModel; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.ResourceModel; import io.opentelemetry.sdk.resources.Resource; import java.util.Collections; import org.junit.jupiter.api.Test; @@ -24,10 +25,9 @@ void create() { assertThat( ResourceFactory.getInstance() .create( - new io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model - .Resource() + new ResourceModel() .withAttributes( - new Attributes() + new AttributesModel() .withServiceName("my-service") .withAdditionalProperty("key", "val") // Should override shape attribute from ResourceComponentProvider diff --git a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/SamplerFactoryTest.java b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/SamplerFactoryTest.java index 4413ddb34c7..363bb301975 100644 --- a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/SamplerFactoryTest.java +++ b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/SamplerFactoryTest.java @@ -14,12 +14,12 @@ import io.opentelemetry.sdk.autoconfigure.internal.SpiHelper; import io.opentelemetry.sdk.autoconfigure.spi.ConfigurationException; import io.opentelemetry.sdk.extension.incubator.fileconfig.component.SamplerComponentProvider; -import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.AlwaysOff; -import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.AlwaysOn; -import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.JaegerRemote; -import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.ParentBased; -import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.Sampler; -import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.TraceIdRatioBased; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.AlwaysOffModel; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.AlwaysOnModel; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.JaegerRemoteModel; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.ParentBasedModel; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.SamplerModel; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.TraceIdRatioBasedModel; import io.opentelemetry.sdk.extension.trace.jaeger.sampler.JaegerRemoteSampler; import java.io.Closeable; import java.time.Duration; @@ -45,7 +45,7 @@ class SamplerFactoryTest { @ParameterizedTest @MethodSource("createArguments") void create( - @Nullable Sampler model, io.opentelemetry.sdk.trace.samplers.Sampler expectedSampler) { + @Nullable SamplerModel model, io.opentelemetry.sdk.trace.samplers.Sampler expectedSampler) { // Some samplers like JaegerRemoteSampler are Closeable - ensure these get cleaned up if (expectedSampler instanceof Closeable) { cleanup.addCloseable((Closeable) expectedSampler); @@ -62,40 +62,45 @@ void create( private static Stream createArguments() { return Stream.of( Arguments.of( - new Sampler().withAlwaysOn(new AlwaysOn()), + new SamplerModel().withAlwaysOn(new AlwaysOnModel()), io.opentelemetry.sdk.trace.samplers.Sampler.alwaysOn()), Arguments.of( - new Sampler().withAlwaysOff(new AlwaysOff()), + new SamplerModel().withAlwaysOff(new AlwaysOffModel()), io.opentelemetry.sdk.trace.samplers.Sampler.alwaysOff()), Arguments.of( - new Sampler().withTraceIdRatioBased(new TraceIdRatioBased()), + new SamplerModel().withTraceIdRatioBased(new TraceIdRatioBasedModel()), io.opentelemetry.sdk.trace.samplers.Sampler.traceIdRatioBased(1.0d)), Arguments.of( - new Sampler().withTraceIdRatioBased(new TraceIdRatioBased().withRatio(0.5d)), + new SamplerModel().withTraceIdRatioBased(new TraceIdRatioBasedModel().withRatio(0.5d)), io.opentelemetry.sdk.trace.samplers.Sampler.traceIdRatioBased(0.5)), Arguments.of( - new Sampler().withParentBased(new ParentBased()), + new SamplerModel().withParentBased(new ParentBasedModel()), io.opentelemetry.sdk.trace.samplers.Sampler.parentBased( io.opentelemetry.sdk.trace.samplers.Sampler.alwaysOn())), Arguments.of( - new Sampler() + new SamplerModel() .withParentBased( - new ParentBased() + new ParentBasedModel() .withRoot( - new Sampler() - .withTraceIdRatioBased(new TraceIdRatioBased().withRatio(0.1d))) + new SamplerModel() + .withTraceIdRatioBased( + new TraceIdRatioBasedModel().withRatio(0.1d))) .withRemoteParentSampled( - new Sampler() - .withTraceIdRatioBased(new TraceIdRatioBased().withRatio(0.2d))) + new SamplerModel() + .withTraceIdRatioBased( + new TraceIdRatioBasedModel().withRatio(0.2d))) .withRemoteParentNotSampled( - new Sampler() - .withTraceIdRatioBased(new TraceIdRatioBased().withRatio(0.3d))) + new SamplerModel() + .withTraceIdRatioBased( + new TraceIdRatioBasedModel().withRatio(0.3d))) .withLocalParentSampled( - new Sampler() - .withTraceIdRatioBased(new TraceIdRatioBased().withRatio(0.4d))) + new SamplerModel() + .withTraceIdRatioBased( + new TraceIdRatioBasedModel().withRatio(0.4d))) .withLocalParentNotSampled( - new Sampler() - .withTraceIdRatioBased(new TraceIdRatioBased().withRatio(0.5d)))), + new SamplerModel() + .withTraceIdRatioBased( + new TraceIdRatioBasedModel().withRatio(0.5d)))), io.opentelemetry.sdk.trace.samplers.Sampler.parentBasedBuilder( io.opentelemetry.sdk.trace.samplers.Sampler.traceIdRatioBased(0.1d)) .setRemoteParentSampled( @@ -108,12 +113,13 @@ private static Stream createArguments() { io.opentelemetry.sdk.trace.samplers.Sampler.traceIdRatioBased(0.5d)) .build()), Arguments.of( - new Sampler() + new SamplerModel() .withJaegerRemote( - new JaegerRemote() + new JaegerRemoteModel() .withEndpoint("http://jaeger-remote-endpoint") .withInterval(10_000) - .withInitialSampler(new Sampler().withAlwaysOff(new AlwaysOff()))), + .withInitialSampler( + new SamplerModel().withAlwaysOff(new AlwaysOffModel()))), JaegerRemoteSampler.builder() .setEndpoint("http://jaeger-remote-endpoint") .setPollingInterval(Duration.ofSeconds(10)) @@ -129,8 +135,7 @@ void create_SpiExporter_Unknown() { () -> SamplerFactory.getInstance() .create( - new io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model - .Sampler() + new SamplerModel() .withAdditionalProperty( "unknown_key", ImmutableMap.of("key1", "value1")), spiHelper, @@ -146,7 +151,7 @@ void create_SpiExporter_Valid() { io.opentelemetry.sdk.trace.samplers.Sampler sampler = SamplerFactory.getInstance() .create( - new io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.Sampler() + new SamplerModel() .withAdditionalProperty("test", ImmutableMap.of("key1", "value1")), spiHelper, new ArrayList<>()); diff --git a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/SpanExporterFactoryTest.java b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/SpanExporterFactoryTest.java index b4192410110..942c9f4352e 100644 --- a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/SpanExporterFactoryTest.java +++ b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/SpanExporterFactoryTest.java @@ -24,10 +24,10 @@ import io.opentelemetry.sdk.autoconfigure.spi.ConfigurationException; import io.opentelemetry.sdk.autoconfigure.spi.internal.StructuredConfigProperties; import io.opentelemetry.sdk.extension.incubator.fileconfig.component.SpanExporterComponentProvider; -import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.Console; -import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.Headers; -import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.Otlp; -import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.Zipkin; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.ConsoleModel; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.HeadersModel; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.OtlpModel; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.ZipkinModel; import io.opentelemetry.sdk.trace.export.SpanExporter; import java.io.Closeable; import java.io.IOException; @@ -70,8 +70,8 @@ void create_OtlpDefaults() { SpanExporterFactory.getInstance() .create( new io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model - .SpanExporter() - .withOtlp(new Otlp()), + .SpanExporterModel() + .withOtlp(new OtlpModel()), spiHelper, closeables); cleanup.addCloseable(exporter); @@ -122,13 +122,13 @@ void create_OtlpConfigured(@TempDir Path tempDir) SpanExporterFactory.getInstance() .create( new io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model - .SpanExporter() + .SpanExporterModel() .withOtlp( - new Otlp() + new OtlpModel() .withProtocol("http/protobuf") .withEndpoint("http://example:4318") .withHeaders( - new Headers() + new HeadersModel() .withAdditionalProperty("key1", "value1") .withAdditionalProperty("key2", "value2")) .withCompression("gzip") @@ -172,8 +172,8 @@ void create_Console() { SpanExporterFactory.getInstance() .create( new io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model - .SpanExporter() - .withConsole(new Console()), + .SpanExporterModel() + .withConsole(new ConsoleModel()), spiHelper, closeables); cleanup.addCloseable(exporter); @@ -194,8 +194,8 @@ void create_ZipkinDefaults() { SpanExporterFactory.getInstance() .create( new io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model - .SpanExporter() - .withZipkin(new Zipkin()), + .SpanExporterModel() + .withZipkin(new ZipkinModel()), spiHelper, closeables); cleanup.addCloseable(exporter); @@ -226,9 +226,9 @@ void create_ZipkinConfigured() { SpanExporterFactory.getInstance() .create( new io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model - .SpanExporter() + .SpanExporterModel() .withZipkin( - new Zipkin() + new ZipkinModel() .withEndpoint("http://zipkin:9411/v1/v2/spans") .withTimeout(15_000)), spiHelper, @@ -255,7 +255,7 @@ void create_SpiExporter_Unknown() { SpanExporterFactory.getInstance() .create( new io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model - .SpanExporter() + .SpanExporterModel() .withAdditionalProperty( "unknown_key", ImmutableMap.of("key1", "value1")), spiHelper, @@ -272,7 +272,7 @@ void create_SpiExporter_Valid() { SpanExporterFactory.getInstance() .create( new io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model - .SpanExporter() + .SpanExporterModel() .withAdditionalProperty("test", ImmutableMap.of("key1", "value1")), spiHelper, new ArrayList<>()); diff --git a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/SpanLimitsFactoryTest.java b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/SpanLimitsFactoryTest.java index c6d78c3b777..c6879ecc529 100644 --- a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/SpanLimitsFactoryTest.java +++ b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/SpanLimitsFactoryTest.java @@ -9,8 +9,8 @@ import static org.mockito.Mockito.mock; import io.opentelemetry.sdk.autoconfigure.internal.SpiHelper; -import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.AttributeLimits; -import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.SpanLimits; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.AttributeLimitsModel; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.SpanLimitsModel; import java.util.Collections; import java.util.stream.Stream; import org.junit.jupiter.params.ParameterizedTest; @@ -36,20 +36,24 @@ private static Stream createArguments() { SpanLimitsAndAttributeLimits.create(null, null), io.opentelemetry.sdk.trace.SpanLimits.getDefault()), Arguments.of( - SpanLimitsAndAttributeLimits.create(new AttributeLimits(), new SpanLimits()), + SpanLimitsAndAttributeLimits.create(new AttributeLimitsModel(), new SpanLimitsModel()), io.opentelemetry.sdk.trace.SpanLimits.getDefault()), Arguments.of( SpanLimitsAndAttributeLimits.create( - new AttributeLimits().withAttributeCountLimit(1).withAttributeValueLengthLimit(2), - new SpanLimits()), + new AttributeLimitsModel() + .withAttributeCountLimit(1) + .withAttributeValueLengthLimit(2), + new SpanLimitsModel()), io.opentelemetry.sdk.trace.SpanLimits.builder() .setMaxNumberOfAttributes(1) .setMaxAttributeValueLength(2) .build()), Arguments.of( SpanLimitsAndAttributeLimits.create( - new AttributeLimits().withAttributeCountLimit(1).withAttributeValueLengthLimit(2), - new SpanLimits() + new AttributeLimitsModel() + .withAttributeCountLimit(1) + .withAttributeValueLengthLimit(2), + new SpanLimitsModel() .withAttributeCountLimit(3) .withAttributeValueLengthLimit(4) .withEventCountLimit(5) diff --git a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/SpanProcessorFactoryTest.java b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/SpanProcessorFactoryTest.java index 19426bd1244..98af1e81ddc 100644 --- a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/SpanProcessorFactoryTest.java +++ b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/SpanProcessorFactoryTest.java @@ -14,11 +14,11 @@ import io.opentelemetry.sdk.autoconfigure.internal.SpiHelper; import io.opentelemetry.sdk.autoconfigure.spi.ConfigurationException; import io.opentelemetry.sdk.extension.incubator.fileconfig.component.SpanProcessorComponentProvider; -import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.BatchSpanProcessor; -import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.Otlp; -import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.SimpleSpanProcessor; -import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.SpanExporter; -import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.SpanProcessor; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.BatchSpanProcessorModel; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.OtlpModel; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.SimpleSpanProcessorModel; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.SpanExporterModel; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.SpanProcessorModel; import java.io.Closeable; import java.time.Duration; import java.util.ArrayList; @@ -41,7 +41,7 @@ void create_BatchNullExporter() { () -> SpanProcessorFactory.getInstance() .create( - new SpanProcessor().withBatch(new BatchSpanProcessor()), + new SpanProcessorModel().withBatch(new BatchSpanProcessorModel()), spiHelper, Collections.emptyList())) .isInstanceOf(ConfigurationException.class) @@ -60,10 +60,10 @@ void create_BatchDefaults() { io.opentelemetry.sdk.trace.SpanProcessor processor = SpanProcessorFactory.getInstance() .create( - new SpanProcessor() + new SpanProcessorModel() .withBatch( - new BatchSpanProcessor() - .withExporter(new SpanExporter().withOtlp(new Otlp()))), + new BatchSpanProcessorModel() + .withExporter(new SpanExporterModel().withOtlp(new OtlpModel()))), spiHelper, closeables); cleanup.addCloseable(processor); @@ -87,10 +87,10 @@ void create_BatchConfigured() { io.opentelemetry.sdk.trace.SpanProcessor processor = SpanProcessorFactory.getInstance() .create( - new SpanProcessor() + new SpanProcessorModel() .withBatch( - new BatchSpanProcessor() - .withExporter(new SpanExporter().withOtlp(new Otlp())) + new BatchSpanProcessorModel() + .withExporter(new SpanExporterModel().withOtlp(new OtlpModel())) .withScheduleDelay(1) .withMaxExportBatchSize(2) .withExportTimeout(3)), @@ -108,7 +108,7 @@ void create_SimpleNullExporter() { () -> SpanProcessorFactory.getInstance() .create( - new SpanProcessor().withSimple(new SimpleSpanProcessor()), + new SpanProcessorModel().withSimple(new SimpleSpanProcessorModel()), spiHelper, Collections.emptyList())) .isInstanceOf(ConfigurationException.class) @@ -126,10 +126,10 @@ void create_SimpleConfigured() { io.opentelemetry.sdk.trace.SpanProcessor processor = SpanProcessorFactory.getInstance() .create( - new SpanProcessor() + new SpanProcessorModel() .withSimple( - new SimpleSpanProcessor() - .withExporter(new SpanExporter().withOtlp(new Otlp()))), + new SimpleSpanProcessorModel() + .withExporter(new SpanExporterModel().withOtlp(new OtlpModel()))), spiHelper, closeables); cleanup.addCloseable(processor); @@ -144,7 +144,7 @@ void create_SpiProcessor_Unknown() { () -> SpanProcessorFactory.getInstance() .create( - new SpanProcessor() + new SpanProcessorModel() .withAdditionalProperty( "unknown_key", ImmutableMap.of("key1", "value1")), spiHelper, @@ -159,7 +159,7 @@ void create_SpiExporter_Valid() { io.opentelemetry.sdk.trace.SpanProcessor spanProcessor = SpanProcessorFactory.getInstance() .create( - new SpanProcessor() + new SpanProcessorModel() .withAdditionalProperty("test", ImmutableMap.of("key1", "value1")), spiHelper, new ArrayList<>()); diff --git a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/TracerProviderFactoryTest.java b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/TracerProviderFactoryTest.java index b3c637e124f..a46ac9cdd79 100644 --- a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/TracerProviderFactoryTest.java +++ b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/TracerProviderFactoryTest.java @@ -11,14 +11,14 @@ import io.opentelemetry.exporter.otlp.trace.OtlpGrpcSpanExporter; import io.opentelemetry.internal.testing.CleanupExtension; import io.opentelemetry.sdk.autoconfigure.internal.SpiHelper; -import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.AlwaysOn; -import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.AttributeLimits; -import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.BatchSpanProcessor; -import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.Otlp; -import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.Sampler; -import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.SpanExporter; -import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.SpanProcessor; -import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.TracerProvider; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.AlwaysOnModel; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.AttributeLimitsModel; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.BatchSpanProcessorModel; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.OtlpModel; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.SamplerModel; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.SpanExporterModel; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.SpanProcessorModel; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.TracerProviderModel; import io.opentelemetry.sdk.trace.SdkTracerProvider; import io.opentelemetry.sdk.trace.SpanLimits; import java.io.Closeable; @@ -58,28 +58,30 @@ private static Stream createArguments() { TracerProviderAndAttributeLimits.create(null, null), SdkTracerProvider.builder().build()), Arguments.of( - TracerProviderAndAttributeLimits.create(new AttributeLimits(), new TracerProvider()), + TracerProviderAndAttributeLimits.create( + new AttributeLimitsModel(), new TracerProviderModel()), SdkTracerProvider.builder().build()), Arguments.of( TracerProviderAndAttributeLimits.create( - new AttributeLimits(), - new TracerProvider() + new AttributeLimitsModel(), + new TracerProviderModel() .withLimits( new io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model - .SpanLimits() + .SpanLimitsModel() .withAttributeCountLimit(1) .withAttributeValueLengthLimit(2) .withEventCountLimit(3) .withLinkCountLimit(4) .withEventAttributeCountLimit(5) .withLinkAttributeCountLimit(6)) - .withSampler(new Sampler().withAlwaysOn(new AlwaysOn())) + .withSampler(new SamplerModel().withAlwaysOn(new AlwaysOnModel())) .withProcessors( Collections.singletonList( - new SpanProcessor() + new SpanProcessorModel() .withBatch( - new BatchSpanProcessor() - .withExporter(new SpanExporter().withOtlp(new Otlp())))))), + new BatchSpanProcessorModel() + .withExporter( + new SpanExporterModel().withOtlp(new OtlpModel())))))), SdkTracerProvider.builder() .setSpanLimits( SpanLimits.builder() diff --git a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/ViewFactoryTest.java b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/ViewFactoryTest.java index 087e68d5790..3e09caa4ad9 100644 --- a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/ViewFactoryTest.java +++ b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/ViewFactoryTest.java @@ -9,9 +9,9 @@ import static org.mockito.Mockito.mock; import io.opentelemetry.sdk.autoconfigure.internal.SpiHelper; -import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.Aggregation; -import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.ExplicitBucketHistogram; -import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.Stream; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.AggregationModel; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.ExplicitBucketHistogramModel; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.StreamModel; import io.opentelemetry.sdk.metrics.View; import java.util.Arrays; import java.util.Collections; @@ -27,7 +27,7 @@ void create_Defaults() { View view = ViewFactory.getInstance() .create( - new Stream().withAttributeKeys(null), + new StreamModel().withAttributeKeys(null), mock(SpiHelper.class), Collections.emptyList()); @@ -49,14 +49,14 @@ void create() { View view = ViewFactory.getInstance() .create( - new Stream() + new StreamModel() .withName("name") .withDescription("description") .withAttributeKeys(Arrays.asList("foo", "bar")) .withAggregation( - new Aggregation() + new AggregationModel() .withExplicitBucketHistogram( - new ExplicitBucketHistogram() + new ExplicitBucketHistogramModel() .withBoundaries(Arrays.asList(1.0, 2.0)))), mock(SpiHelper.class), Collections.emptyList()); diff --git a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/YamlStructuredConfigPropertiesTest.java b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/YamlStructuredConfigPropertiesTest.java index b29e4c97162..7e6ba27b522 100644 --- a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/YamlStructuredConfigPropertiesTest.java +++ b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/YamlStructuredConfigPropertiesTest.java @@ -9,7 +9,7 @@ import com.google.common.collect.ImmutableSet; import io.opentelemetry.sdk.autoconfigure.spi.internal.StructuredConfigProperties; -import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.OpenTelemetryConfiguration; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.OpenTelemetryConfigurationModel; import java.io.ByteArrayInputStream; import java.nio.charset.StandardCharsets; import java.util.Arrays; @@ -58,7 +58,7 @@ class YamlStructuredConfigPropertiesTest { @BeforeEach void setup() { - OpenTelemetryConfiguration configuration = + OpenTelemetryConfigurationModel configuration = FileConfiguration.parse( new ByteArrayInputStream(extendedSchema.getBytes(StandardCharsets.UTF_8))); structuredConfigProps = FileConfiguration.toConfigProperties(configuration); From 5b421b6d57da7eb507788da11b2fb703d59355f0 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 18 Sep 2024 16:23:13 -0500 Subject: [PATCH 567/901] Update plugin com.gradleup.shadow to v8.3.2 (#6705) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- settings.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/settings.gradle.kts b/settings.gradle.kts index 83cd78db302..6ec9094880d 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -1,6 +1,6 @@ pluginManagement { plugins { - id("com.gradleup.shadow") version "8.3.0" + id("com.gradleup.shadow") version "8.3.2" id("com.gradle.develocity") version "3.18" id("de.undercouch.download") version "5.6.0" id("org.jsonschema2pojo") version "1.2.1" From a63f9195a1c17bddb21714a5ea951169c3cfcfd5 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 18 Sep 2024 16:23:51 -0500 Subject: [PATCH 568/901] Update errorProneVersion to v2.32.0 (#6713) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- dependencyManagement/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index 3a445c38436..88643677729 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -25,7 +25,7 @@ val DEPENDENCY_BOMS = listOf( ) val autoValueVersion = "1.11.0" -val errorProneVersion = "2.31.0" +val errorProneVersion = "2.32.0" val jmhVersion = "1.37" // Mockito 5.x.x requires Java 11 https://github.com/mockito/mockito/releases/tag/v5.0.0 val mockitoVersion = "4.11.0" From d773f3bfe2bf3a4869de0f4ae8202ebc3747d794 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 18 Sep 2024 16:24:04 -0500 Subject: [PATCH 569/901] Update gradle/actions action to v4.1.0 (#6722) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/gradle-wrapper-validation.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/gradle-wrapper-validation.yml b/.github/workflows/gradle-wrapper-validation.yml index c55680e34b8..a268b37d019 100644 --- a/.github/workflows/gradle-wrapper-validation.yml +++ b/.github/workflows/gradle-wrapper-validation.yml @@ -13,4 +13,4 @@ jobs: steps: - uses: actions/checkout@v4 - - uses: gradle/actions/wrapper-validation@v4.0.1 + - uses: gradle/actions/wrapper-validation@v4.1.0 From c9c857c9084a72de38718d69eec9ca6e115038f7 Mon Sep 17 00:00:00 2001 From: Gregor Zeitlinger Date: Wed, 18 Sep 2024 23:36:30 +0200 Subject: [PATCH 570/901] add context info about wrong span or trace (#6703) --- .../sdk/testing/assertj/TraceAssert.java | 3 ++- .../sdk/testing/assertj/TracesAssert.java | 2 +- .../sdk/testing/assertj/TraceAssertionsTest.java | 13 ++++++++++++- 3 files changed, 15 insertions(+), 3 deletions(-) diff --git a/sdk/testing/src/main/java/io/opentelemetry/sdk/testing/assertj/TraceAssert.java b/sdk/testing/src/main/java/io/opentelemetry/sdk/testing/assertj/TraceAssert.java index 5f3da9db7f4..ee19607e2cd 100644 --- a/sdk/testing/src/main/java/io/opentelemetry/sdk/testing/assertj/TraceAssert.java +++ b/sdk/testing/src/main/java/io/opentelemetry/sdk/testing/assertj/TraceAssert.java @@ -59,9 +59,10 @@ public TraceAssert hasSpansSatisfyingExactly( List> assertionsList = StreamSupport.stream(assertions.spliterator(), false).collect(Collectors.toList()); hasSize(assertionsList.size()); + // Avoid zipSatisfy - https://github.com/assertj/assertj-core/issues/2300 for (int i = 0; i < assertionsList.size(); i++) { - assertionsList.get(i).accept(new SpanDataAssert(actual.get(i))); + assertionsList.get(i).accept(new SpanDataAssert(actual.get(i)).describedAs("Span " + i)); } return this; } diff --git a/sdk/testing/src/main/java/io/opentelemetry/sdk/testing/assertj/TracesAssert.java b/sdk/testing/src/main/java/io/opentelemetry/sdk/testing/assertj/TracesAssert.java index e120ae7c854..d4c936fe5b2 100644 --- a/sdk/testing/src/main/java/io/opentelemetry/sdk/testing/assertj/TracesAssert.java +++ b/sdk/testing/src/main/java/io/opentelemetry/sdk/testing/assertj/TracesAssert.java @@ -105,7 +105,7 @@ public TracesAssert hasTracesSatisfyingExactly( hasSize(assertionsList.size()); // Avoid zipSatisfy - https://github.com/assertj/assertj-core/issues/2300 for (int i = 0; i < assertionsList.size(); i++) { - assertionsList.get(i).accept(new TraceAssert(actual.get(i))); + assertionsList.get(i).accept(new TraceAssert(actual.get(i)).describedAs("Trace " + i)); } return this; } diff --git a/sdk/testing/src/test/java/io/opentelemetry/sdk/testing/assertj/TraceAssertionsTest.java b/sdk/testing/src/test/java/io/opentelemetry/sdk/testing/assertj/TraceAssertionsTest.java index 825f067fdce..18ac3849690 100644 --- a/sdk/testing/src/test/java/io/opentelemetry/sdk/testing/assertj/TraceAssertionsTest.java +++ b/sdk/testing/src/test/java/io/opentelemetry/sdk/testing/assertj/TraceAssertionsTest.java @@ -680,6 +680,15 @@ void hasSpansSatisfyingExactly() { trace -> trace.hasSpansSatisfyingExactly( span -> span.hasSpanId(SPAN_ID1), span -> span.hasSpanId(SPAN_ID2))); + // wrong number of spans + assertThatThrownBy( + () -> + TracesAssert.assertThat(traces) + .hasTracesSatisfyingExactly( + trace -> trace.hasSpansSatisfyingExactly(span -> span.hasSpanId(SPAN_ID1)))) + .isInstanceOf(AssertionError.class) + .hasMessageStartingWith("[Trace 0] \n" + "Expected size: 1 but was: 2"); + // test asserting spans in wrong oder assertThatThrownBy( () -> @@ -689,7 +698,9 @@ void hasSpansSatisfyingExactly() { trace.hasSpansSatisfyingExactly( span -> span.hasSpanId(SPAN_ID2), span -> span.hasSpanId(SPAN_ID1)))) - .isInstanceOf(AssertionError.class); + .isInstanceOf(AssertionError.class) + .hasMessage( + "[Span 0] Expected span [span1] to have span ID <0000000000000004> but was <0000000000000003>"); // test asserting spans in any order TracesAssert.assertThat(traces) From 31e562f9a5c94ad6e3cc4ba5f1fc71cb68e7e860 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 18 Sep 2024 16:36:45 -0500 Subject: [PATCH 571/901] Update dependency com.squareup.okio:okio-bom to v3.9.1 (#6720) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- dependencyManagement/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index 88643677729..4d10fd93baa 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -13,7 +13,7 @@ val DEPENDENCY_BOMS = listOf( "com.google.protobuf:protobuf-bom:3.25.4", "com.linecorp.armeria:armeria-bom:1.30.1", "com.squareup.okhttp3:okhttp-bom:4.12.0", - "com.squareup.okio:okio-bom:3.9.0", // applies to transitive dependencies of okhttp + "com.squareup.okio:okio-bom:3.9.1", // applies to transitive dependencies of okhttp "io.grpc:grpc-bom:1.66.0", "io.netty:netty-bom:4.1.113.Final", "io.zipkin.brave:brave-bom:6.0.3", From bd88acae57aa51a60a33b4105dbfec551f1f16c9 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 18 Sep 2024 16:37:01 -0500 Subject: [PATCH 572/901] Update dependency com.squareup.wire:wire-bom to v5.1.0 (#6710) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- buildSrc/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts index 54dcfc1fb5e..d2cd29c3bfd 100644 --- a/buildSrc/build.gradle.kts +++ b/buildSrc/build.gradle.kts @@ -50,7 +50,7 @@ repositories { } dependencies { - implementation(enforcedPlatform("com.squareup.wire:wire-bom:5.0.0")) + implementation(enforcedPlatform("com.squareup.wire:wire-bom:5.1.0")) implementation("com.google.auto.value:auto-value-annotations:1.11.0") // When updating, update above in plugins too implementation("com.diffplug.spotless:spotless-plugin-gradle:6.25.0") From 9c466f4a1332cf1d3a6a1ae43e4e9c555c2715eb Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 18 Sep 2024 16:37:21 -0500 Subject: [PATCH 573/901] Update dependency org.snakeyaml:snakeyaml-engine to v2.8 (#6728) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- dependencyManagement/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index 4d10fd93baa..774c35f4968 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -21,7 +21,7 @@ val DEPENDENCY_BOMS = listOf( "org.assertj:assertj-bom:3.26.3", "org.junit:junit-bom:5.11.0", "org.testcontainers:testcontainers-bom:1.20.1", - "org.snakeyaml:snakeyaml-engine:2.7" + "org.snakeyaml:snakeyaml-engine:2.8" ) val autoValueVersion = "1.11.0" From 485c123a42d9cad47b5b90cf2d5e2f58b4ca18ab Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 18 Sep 2024 16:17:07 -0700 Subject: [PATCH 574/901] Update plugin com.gradle.develocity to v3.18.1 (#6708) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- settings.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/settings.gradle.kts b/settings.gradle.kts index 6ec9094880d..efc78a9f203 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -1,7 +1,7 @@ pluginManagement { plugins { id("com.gradleup.shadow") version "8.3.2" - id("com.gradle.develocity") version "3.18" + id("com.gradle.develocity") version "3.18.1" id("de.undercouch.download") version "5.6.0" id("org.jsonschema2pojo") version "1.2.1" id("io.github.gradle-nexus.publish-plugin") version "2.0.0" From de13ff183a24aef45dc2df8a4422e612765ea32a Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 19 Sep 2024 18:10:20 -0700 Subject: [PATCH 575/901] Update dependency io.zipkin.reporter2:zipkin-reporter-bom to v3.4.2 (#6704) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- dependencyManagement/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index 774c35f4968..2fd722085ea 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -17,7 +17,7 @@ val DEPENDENCY_BOMS = listOf( "io.grpc:grpc-bom:1.66.0", "io.netty:netty-bom:4.1.113.Final", "io.zipkin.brave:brave-bom:6.0.3", - "io.zipkin.reporter2:zipkin-reporter-bom:3.4.0", + "io.zipkin.reporter2:zipkin-reporter-bom:3.4.2", "org.assertj:assertj-bom:3.26.3", "org.junit:junit-bom:5.11.0", "org.testcontainers:testcontainers-bom:1.20.1", From 799039247b8d00195e385b335f32da548b0e23a2 Mon Sep 17 00:00:00 2001 From: Alex Boten <223565+codeboten@users.noreply.github.com> Date: Fri, 20 Sep 2024 09:49:44 -0700 Subject: [PATCH 576/901] tests: update references to logging exporter (#6692) Signed-off-by: Alex Boten <223565+codeboten@users.noreply.github.com> --- exporters/prometheus/src/test/resources/otel-config.yaml | 4 ++-- .../otlp/src/main/resources/otel-config.yaml | 8 ++++---- .../src/test/resources/otel-collector-config-perf.yaml | 8 ++++---- sdk/trace/src/jmh/resources/otel.yaml | 4 ++-- 4 files changed, 12 insertions(+), 12 deletions(-) diff --git a/exporters/prometheus/src/test/resources/otel-config.yaml b/exporters/prometheus/src/test/resources/otel-config.yaml index 649f8ba6d12..c6cec85cd94 100644 --- a/exporters/prometheus/src/test/resources/otel-config.yaml +++ b/exporters/prometheus/src/test/resources/otel-config.yaml @@ -10,7 +10,7 @@ receivers: static_configs: - targets: ['${APP_ENDPOINT}'] exporters: - logging: + debug: verbosity: ${LOGGING_EXPORTER_VERBOSITY} otlp: endpoint: ${OTLP_EXPORTER_ENDPOINT} @@ -22,4 +22,4 @@ service: pipelines: metrics: receivers: [prometheus] - exporters: [logging, otlp] + exporters: [debug, otlp] diff --git a/integration-tests/otlp/src/main/resources/otel-config.yaml b/integration-tests/otlp/src/main/resources/otel-config.yaml index e554f766b8e..614cb5443bd 100644 --- a/integration-tests/otlp/src/main/resources/otel-config.yaml +++ b/integration-tests/otlp/src/main/resources/otel-config.yaml @@ -23,7 +23,7 @@ receivers: cert_file: ${MTLS_SERVER_CERTIFICATE} key_file: ${MTLS_SERVER_KEY} exporters: - logging: + debug: verbosity: ${LOGGING_EXPORTER_VERBOSITY_LEVEL} otlp: endpoint: ${OTLP_EXPORTER_ENDPOINT} @@ -35,10 +35,10 @@ service: pipelines: metrics: receivers: [otlp, otlp/mtls] - exporters: [logging, otlp] + exporters: [debug, otlp] traces: receivers: [otlp, otlp/mtls] - exporters: [logging, otlp] + exporters: [debug, otlp] logs: receivers: [otlp, otlp/mtls] - exporters: [logging, otlp] + exporters: [debug, otlp] diff --git a/perf-harness/src/test/resources/otel-collector-config-perf.yaml b/perf-harness/src/test/resources/otel-collector-config-perf.yaml index 0aa39a4d998..8df61145341 100644 --- a/perf-harness/src/test/resources/otel-collector-config-perf.yaml +++ b/perf-harness/src/test/resources/otel-collector-config-perf.yaml @@ -4,8 +4,8 @@ receivers: grpc: exporters: - logging: - loglevel: info + debug: + verbosity: normal sampling_initial: 1 sampling_thereafter: 1 @@ -25,8 +25,8 @@ service: traces: receivers: [otlp] processors: [batch] - exporters: [logging] + exporters: [debug] metrics: receivers: [otlp] processors: [batch] - exporters: [logging] + exporters: [debug] diff --git a/sdk/trace/src/jmh/resources/otel.yaml b/sdk/trace/src/jmh/resources/otel.yaml index edd847f0c02..b2fe534507f 100644 --- a/sdk/trace/src/jmh/resources/otel.yaml +++ b/sdk/trace/src/jmh/resources/otel.yaml @@ -11,7 +11,7 @@ extensions: health_check: exporters: - logging: + debug: service: extensions: [health_check] @@ -19,4 +19,4 @@ service: traces: receivers: [otlp] processors: [batch] - exporters: [logging] + exporters: [debug] From af59cc4a0b1b2fb9c76a7f9edba05c02ed3ed6dc Mon Sep 17 00:00:00 2001 From: Jonathan Halliday Date: Fri, 20 Sep 2024 17:52:06 +0100 Subject: [PATCH 577/901] Add Marshalers for profiling signal type (#6680) --- ...InstrumentationScopeProfilesMarshaler.java | 49 +++++ .../profiles/ProfileContainerMarshaler.java | 110 ++++++++++++ .../profiles/ProfilesRequestMarshaler.java | 49 +++++ .../profiles/ResourceProfilesMarshaler.java | 100 +++++++++++ .../ProfilesRequestMarshalerTest.java | 167 ++++++++++++++---- 5 files changed, 439 insertions(+), 36 deletions(-) create mode 100644 exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/InstrumentationScopeProfilesMarshaler.java create mode 100644 exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/ProfileContainerMarshaler.java create mode 100644 exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/ProfilesRequestMarshaler.java create mode 100644 exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/ResourceProfilesMarshaler.java diff --git a/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/InstrumentationScopeProfilesMarshaler.java b/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/InstrumentationScopeProfilesMarshaler.java new file mode 100644 index 00000000000..63074ba15eb --- /dev/null +++ b/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/InstrumentationScopeProfilesMarshaler.java @@ -0,0 +1,49 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.exporter.otlp.profiles; + +import io.opentelemetry.exporter.internal.marshal.MarshalerUtil; +import io.opentelemetry.exporter.internal.marshal.MarshalerWithSize; +import io.opentelemetry.exporter.internal.marshal.Serializer; +import io.opentelemetry.exporter.internal.otlp.InstrumentationScopeMarshaler; +import io.opentelemetry.proto.profiles.v1experimental.internal.ScopeProfiles; +import java.io.IOException; +import java.util.List; + +final class InstrumentationScopeProfilesMarshaler extends MarshalerWithSize { + + private final InstrumentationScopeMarshaler instrumentationScope; + private final List profileContainerMarshalers; + private final byte[] schemaUrlUtf8; + + InstrumentationScopeProfilesMarshaler( + InstrumentationScopeMarshaler instrumentationScope, + byte[] schemaUrlUtf8, + List profileContainerMarshalers) { + super(calculateSize(instrumentationScope, schemaUrlUtf8, profileContainerMarshalers)); + this.instrumentationScope = instrumentationScope; + this.schemaUrlUtf8 = schemaUrlUtf8; + this.profileContainerMarshalers = profileContainerMarshalers; + } + + @Override + public void writeTo(Serializer output) throws IOException { + output.serializeMessage(ScopeProfiles.SCOPE, instrumentationScope); + output.serializeRepeatedMessage(ScopeProfiles.PROFILES, profileContainerMarshalers); + output.serializeString(ScopeProfiles.SCHEMA_URL, schemaUrlUtf8); + } + + private static int calculateSize( + InstrumentationScopeMarshaler instrumentationScope, + byte[] schemaUrlUtf8, + List profileContainerMarshalers) { + int size = 0; + size += MarshalerUtil.sizeMessage(ScopeProfiles.SCOPE, instrumentationScope); + size += MarshalerUtil.sizeRepeatedMessage(ScopeProfiles.PROFILES, profileContainerMarshalers); + size += MarshalerUtil.sizeBytes(ScopeProfiles.SCHEMA_URL, schemaUrlUtf8); + return size; + } +} diff --git a/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/ProfileContainerMarshaler.java b/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/ProfileContainerMarshaler.java new file mode 100644 index 00000000000..61369962296 --- /dev/null +++ b/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/ProfileContainerMarshaler.java @@ -0,0 +1,110 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.exporter.otlp.profiles; + +import io.opentelemetry.exporter.internal.marshal.MarshalerUtil; +import io.opentelemetry.exporter.internal.marshal.MarshalerWithSize; +import io.opentelemetry.exporter.internal.marshal.Serializer; +import io.opentelemetry.exporter.internal.otlp.KeyValueMarshaler; +import io.opentelemetry.proto.profiles.v1experimental.internal.ProfileContainer; +import java.io.IOException; + +final class ProfileContainerMarshaler extends MarshalerWithSize { + + private final byte[] profileId; + private final long startEpochNanos; + private final long endEpochNanos; + private final KeyValueMarshaler[] attributeMarshalers; + private final int droppedAttributesCount; + private final byte[] originalPayloadFormatUtf8; + private final byte[] originalPayload; + private final ProfileMarshaler profileMarshaler; + + static ProfileContainerMarshaler create(ProfileContainerData profileContainerData) { + int droppedAttributesCount = + profileContainerData.getTotalAttributeCount() - profileContainerData.getAttributes().size(); + + // Not ideal, but this will do for now. ByteBuffer support in + // Serialzer/CodedOutputStream/MarshalerUtilwill follow in a separate step. + byte[] originalPayload = new byte[profileContainerData.getOriginalPayload().remaining()]; + profileContainerData.getOriginalPayload().get(originalPayload); + + return new ProfileContainerMarshaler( + profileContainerData.getProfileIdBytes(), + profileContainerData.getStartEpochNanos(), + profileContainerData.getEndEpochNanos(), + KeyValueMarshaler.createForAttributes(profileContainerData.getAttributes()), + droppedAttributesCount, + MarshalerUtil.toBytes(profileContainerData.getOriginalPayloadFormat()), + originalPayload, + ProfileMarshaler.create(profileContainerData.getProfile())); + } + + private ProfileContainerMarshaler( + byte[] profileId, + long startEpochNanos, + long endEpochNanos, + KeyValueMarshaler[] attributeMarshalers, + int droppedAttributesCount, + byte[] originalPayloadFormat, + byte[] originalPayload, + ProfileMarshaler profileMarshaler) { + super( + calculateSize( + profileId, + startEpochNanos, + endEpochNanos, + attributeMarshalers, + droppedAttributesCount, + originalPayloadFormat, + originalPayload, + profileMarshaler)); + this.profileId = profileId; + this.startEpochNanos = startEpochNanos; + this.endEpochNanos = endEpochNanos; + this.attributeMarshalers = attributeMarshalers; + this.droppedAttributesCount = droppedAttributesCount; + this.originalPayloadFormatUtf8 = originalPayloadFormat; + this.originalPayload = originalPayload; + this.profileMarshaler = profileMarshaler; + } + + @Override + protected void writeTo(Serializer output) throws IOException { + output.serializeBytes(ProfileContainer.PROFILE_ID, profileId); + output.serializeFixed64(ProfileContainer.START_TIME_UNIX_NANO, startEpochNanos); + output.serializeFixed64(ProfileContainer.END_TIME_UNIX_NANO, endEpochNanos); + output.serializeRepeatedMessage(ProfileContainer.ATTRIBUTES, attributeMarshalers); + output.serializeUInt32(ProfileContainer.DROPPED_ATTRIBUTES_COUNT, droppedAttributesCount); + output.serializeString(ProfileContainer.ORIGINAL_PAYLOAD_FORMAT, originalPayloadFormatUtf8); + output.serializeBytes(ProfileContainer.ORIGINAL_PAYLOAD, originalPayload); + output.serializeMessage(ProfileContainer.PROFILE, profileMarshaler); + } + + private static int calculateSize( + byte[] profileId, + long startEpochNanos, + long endEpochNanos, + KeyValueMarshaler[] attributeMarshalers, + int droppedAttributesCount, + byte[] originalPayloadFormat, + byte[] originalPayload, + ProfileMarshaler profileMarshaler) { + int size; + size = 0; + size += MarshalerUtil.sizeBytes(ProfileContainer.PROFILE_ID, profileId); + size += MarshalerUtil.sizeFixed64(ProfileContainer.START_TIME_UNIX_NANO, startEpochNanos); + size += MarshalerUtil.sizeFixed64(ProfileContainer.END_TIME_UNIX_NANO, endEpochNanos); + size += MarshalerUtil.sizeRepeatedMessage(ProfileContainer.ATTRIBUTES, attributeMarshalers); + size += + MarshalerUtil.sizeUInt32(ProfileContainer.DROPPED_ATTRIBUTES_COUNT, droppedAttributesCount); + size += + MarshalerUtil.sizeBytes(ProfileContainer.ORIGINAL_PAYLOAD_FORMAT, originalPayloadFormat); + size += MarshalerUtil.sizeBytes(ProfileContainer.ORIGINAL_PAYLOAD, originalPayload); + size += MarshalerUtil.sizeMessage(ProfileContainer.PROFILE, profileMarshaler); + return size; + } +} diff --git a/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/ProfilesRequestMarshaler.java b/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/ProfilesRequestMarshaler.java new file mode 100644 index 00000000000..1d341449a6c --- /dev/null +++ b/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/ProfilesRequestMarshaler.java @@ -0,0 +1,49 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.exporter.otlp.profiles; + +import io.opentelemetry.exporter.internal.marshal.Marshaler; +import io.opentelemetry.exporter.internal.marshal.MarshalerUtil; +import io.opentelemetry.exporter.internal.marshal.MarshalerWithSize; +import io.opentelemetry.exporter.internal.marshal.ProtoFieldInfo; +import io.opentelemetry.exporter.internal.marshal.Serializer; +import io.opentelemetry.proto.collector.profiles.v1experimental.internal.ExportProfilesServiceRequest; +import java.io.IOException; +import java.util.Collection; + +/** + * {@link Marshaler} to convert SDK {@link ProfileContainerData} to OTLP + * ExportProfilesServiceRequest. + * + *

      This class is internal and is hence not for public use. Its APIs are unstable and can change + * at any time. + */ +public final class ProfilesRequestMarshaler extends MarshalerWithSize { + + private static final ProtoFieldInfo RESOURCE_PROFILES = + ExportProfilesServiceRequest.RESOURCE_PROFILES; + + private final ResourceProfilesMarshaler[] resourceProfilesMarshalers; + + /** + * Returns a {@link ProfilesRequestMarshaler} that can be used to convert the provided {@link + * ProfileContainerData} into a serialized OTLP ExportProfilesServiceRequest. + */ + public static ProfilesRequestMarshaler create( + Collection profileContainerList) { + return new ProfilesRequestMarshaler(ResourceProfilesMarshaler.create(profileContainerList)); + } + + private ProfilesRequestMarshaler(ResourceProfilesMarshaler[] resourceProfilesMarshalers) { + super(MarshalerUtil.sizeRepeatedMessage(RESOURCE_PROFILES, resourceProfilesMarshalers)); + this.resourceProfilesMarshalers = resourceProfilesMarshalers; + } + + @Override + public void writeTo(Serializer output) throws IOException { + output.serializeRepeatedMessage(RESOURCE_PROFILES, resourceProfilesMarshalers); + } +} diff --git a/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/ResourceProfilesMarshaler.java b/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/ResourceProfilesMarshaler.java new file mode 100644 index 00000000000..4000ff5f373 --- /dev/null +++ b/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/ResourceProfilesMarshaler.java @@ -0,0 +1,100 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.exporter.otlp.profiles; + +import io.opentelemetry.exporter.internal.marshal.MarshalerUtil; +import io.opentelemetry.exporter.internal.marshal.MarshalerWithSize; +import io.opentelemetry.exporter.internal.marshal.Serializer; +import io.opentelemetry.exporter.internal.otlp.InstrumentationScopeMarshaler; +import io.opentelemetry.exporter.internal.otlp.ResourceMarshaler; +import io.opentelemetry.proto.profiles.v1experimental.internal.ResourceProfiles; +import io.opentelemetry.sdk.common.InstrumentationScopeInfo; +import io.opentelemetry.sdk.resources.Resource; +import java.io.IOException; +import java.util.Collection; +import java.util.List; +import java.util.Map; + +final class ResourceProfilesMarshaler extends MarshalerWithSize { + + private final ResourceMarshaler resourceMarshaler; + private final byte[] schemaUrl; + private final InstrumentationScopeProfilesMarshaler[] instrumentationScopeProfilesMarshalers; + + /** Returns Marshalers of ResourceProfiles created by grouping the provided Profiles. */ + @SuppressWarnings("AvoidObjectArrays") + static ResourceProfilesMarshaler[] create(Collection profiles) { + Map>> + resourceAndScopeMap = groupByResourceAndScope(profiles); + + ResourceProfilesMarshaler[] resourceProfilesMarshalers = + new ResourceProfilesMarshaler[resourceAndScopeMap.size()]; + int posResource = 0; + for (Map.Entry>> entry : + resourceAndScopeMap.entrySet()) { + InstrumentationScopeProfilesMarshaler[] instrumentationLibrarySpansMarshalers = + new InstrumentationScopeProfilesMarshaler[entry.getValue().size()]; + int posInstrumentation = 0; + + for (Map.Entry> entryIs : + entry.getValue().entrySet()) { + instrumentationLibrarySpansMarshalers[posInstrumentation++] = + new InstrumentationScopeProfilesMarshaler( + InstrumentationScopeMarshaler.create(entryIs.getKey()), + MarshalerUtil.toBytes(entryIs.getKey().getSchemaUrl()), + entryIs.getValue()); + } + + resourceProfilesMarshalers[posResource++] = + new ResourceProfilesMarshaler( + ResourceMarshaler.create(entry.getKey()), + MarshalerUtil.toBytes(entry.getKey().getSchemaUrl()), + instrumentationLibrarySpansMarshalers); + } + + return resourceProfilesMarshalers; + } + + private ResourceProfilesMarshaler( + ResourceMarshaler resourceMarshaler, + byte[] schemaUrl, + InstrumentationScopeProfilesMarshaler[] instrumentationScopeProfilesMarshalers) { + super(calculateSize(resourceMarshaler, schemaUrl, instrumentationScopeProfilesMarshalers)); + this.resourceMarshaler = resourceMarshaler; + this.schemaUrl = schemaUrl; + this.instrumentationScopeProfilesMarshalers = instrumentationScopeProfilesMarshalers; + } + + @Override + protected void writeTo(Serializer output) throws IOException { + output.serializeMessage(ResourceProfiles.RESOURCE, resourceMarshaler); + output.serializeRepeatedMessage( + ResourceProfiles.SCOPE_PROFILES, instrumentationScopeProfilesMarshalers); + output.serializeString(ResourceProfiles.SCHEMA_URL, schemaUrl); + } + + private static int calculateSize( + ResourceMarshaler resourceMarshaler, + byte[] schemaUrl, + InstrumentationScopeProfilesMarshaler[] instrumentationScopeProfilesMarshalers) { + int size = 0; + size += MarshalerUtil.sizeMessage(ResourceProfiles.RESOURCE, resourceMarshaler); + size += + MarshalerUtil.sizeRepeatedMessage( + ResourceProfiles.SCOPE_PROFILES, instrumentationScopeProfilesMarshalers); + size += MarshalerUtil.sizeBytes(ResourceProfiles.SCHEMA_URL, schemaUrl); + return size; + } + + private static Map>> + groupByResourceAndScope(Collection profiles) { + return MarshalerUtil.groupByResourceAndScope( + profiles, + ProfileContainerData::getResource, + ProfileContainerData::getInstrumentationScopeInfo, + ProfileContainerMarshaler::create); + } +} diff --git a/exporters/otlp/profiles/src/test/java/io/opentelemetry/exporter/otlp/profiles/ProfilesRequestMarshalerTest.java b/exporters/otlp/profiles/src/test/java/io/opentelemetry/exporter/otlp/profiles/ProfilesRequestMarshalerTest.java index f4d57fe884d..927c403da17 100644 --- a/exporters/otlp/profiles/src/test/java/io/opentelemetry/exporter/otlp/profiles/ProfilesRequestMarshalerTest.java +++ b/exporters/otlp/profiles/src/test/java/io/opentelemetry/exporter/otlp/profiles/ProfilesRequestMarshalerTest.java @@ -19,9 +19,11 @@ import io.opentelemetry.exporter.otlp.internal.data.ImmutableLinkData; import io.opentelemetry.exporter.otlp.internal.data.ImmutableLocationData; import io.opentelemetry.exporter.otlp.internal.data.ImmutableMappingData; +import io.opentelemetry.exporter.otlp.internal.data.ImmutableProfileContainerData; import io.opentelemetry.exporter.otlp.internal.data.ImmutableProfileData; import io.opentelemetry.exporter.otlp.internal.data.ImmutableSampleData; import io.opentelemetry.exporter.otlp.internal.data.ImmutableValueTypeData; +import io.opentelemetry.proto.common.v1.InstrumentationScope; import io.opentelemetry.proto.profiles.v1experimental.AttributeUnit; import io.opentelemetry.proto.profiles.v1experimental.Function; import io.opentelemetry.proto.profiles.v1experimental.Line; @@ -29,13 +31,20 @@ import io.opentelemetry.proto.profiles.v1experimental.Location; import io.opentelemetry.proto.profiles.v1experimental.Mapping; import io.opentelemetry.proto.profiles.v1experimental.Profile; +import io.opentelemetry.proto.profiles.v1experimental.ProfileContainer; +import io.opentelemetry.proto.profiles.v1experimental.ResourceProfiles; import io.opentelemetry.proto.profiles.v1experimental.Sample; +import io.opentelemetry.proto.profiles.v1experimental.ScopeProfiles; import io.opentelemetry.proto.profiles.v1experimental.ValueType; +import io.opentelemetry.sdk.common.InstrumentationScopeInfo; +import io.opentelemetry.sdk.resources.Resource; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.UncheckedIOException; +import java.nio.ByteBuffer; import java.nio.charset.StandardCharsets; import java.util.ArrayList; +import java.util.Collection; import java.util.Collections; import java.util.List; import org.junit.jupiter.api.Test; @@ -131,47 +140,89 @@ void compareMappingMarshaling() { } @Test - void compareProfileMarshaling() { - ProfileData input = - ImmutableProfileData.create( - Collections.emptyList(), - Collections.emptyList(), - Collections.emptyList(), - Collections.emptyList(), - listOf(1L, 2L), - Collections.emptyList(), + void compareProfileContainerMarshaling() { + String profileId = "0123456789abcdef0123456789abcdef"; + ProfileContainerData input = + ImmutableProfileContainerData.create( + Resource.getDefault(), + InstrumentationScopeInfo.empty(), + profileId, + 1, + 2, + Attributes.empty(), + 3, + "format", + ByteBuffer.wrap(new byte[] {4, 5}), + sampleProfileData()); + + ProfileContainer builderResult = + ProfileContainer.newBuilder() + .setProfileId(ByteString.fromHex(profileId)) + .setStartTimeUnixNano(1) + .setEndTimeUnixNano(2) + .setDroppedAttributesCount(3) + .setOriginalPayloadFormat("format") + .setOriginalPayload(ByteString.copyFrom(new byte[] {4, 5})) + .setProfile(sampleProfileBuilder().build()) + .build(); + + ProfileContainer roundTripResult = + parse(ProfileContainer.getDefaultInstance(), ProfileContainerMarshaler.create(input)); + assertThat(roundTripResult).isEqualTo(builderResult); + } + + @Test + void compareResourceProfilesMarshaling() { + + String profileId = "0123456789abcdef0123456789abcdef"; + ProfileContainerData profileContainerData = + ImmutableProfileContainerData.create( + Resource.create(Attributes.empty()), + InstrumentationScopeInfo.create("testscope"), + profileId, + 1, + 2, Attributes.empty(), - Collections.emptyList(), - Collections.emptyList(), - Collections.emptyList(), 3, - 4, - 5, - 6, - ImmutableValueTypeData.create(1, 2, AggregationTemporality.CUMULATIVE), - 7, - listOf(8L, 9L), - 10); - Profile builderResult = - Profile.newBuilder() - .addAllLocationIndices(listOf(1L, 2L)) - .setDropFrames(3) - .setKeepFrames(4) - .setTimeNanos(5) - .setDurationNanos(6) - .setPeriod(7) - .setPeriodType( - ValueType.newBuilder() - .setType(1) - .setUnit(2) - .setAggregationTemporality( - io.opentelemetry.proto.profiles.v1experimental.AggregationTemporality - .AGGREGATION_TEMPORALITY_CUMULATIVE) + "format", + ByteBuffer.wrap(new byte[] {4, 5}), + sampleProfileData()); + + Collection input = new ArrayList<>(); + input.add(profileContainerData); + + ProfileContainer profileContainer = + ProfileContainer.newBuilder() + .setProfileId(ByteString.fromHex(profileId)) + .setStartTimeUnixNano(1) + .setEndTimeUnixNano(2) + .setDroppedAttributesCount(3) + .setOriginalPayloadFormat("format") + .setOriginalPayload(ByteString.copyFrom(new byte[] {4, 5})) + .setProfile(sampleProfileBuilder().build()) + .build(); + + ResourceProfiles builderResult = + ResourceProfiles.newBuilder() + .setResource(io.opentelemetry.proto.resource.v1.Resource.newBuilder().build()) + .addScopeProfiles( + ScopeProfiles.newBuilder() + .setScope(InstrumentationScope.newBuilder().setName("testscope").build()) + .addProfiles(profileContainer) .build()) - .addAllComment(listOf(8L, 9L)) - .setDefaultSampleType(10) .build(); + ResourceProfilesMarshaler[] marshalers = ResourceProfilesMarshaler.create(input); + assertThat(marshalers.length).isEqualTo(1); + ResourceProfiles roundTripResult = parse(ResourceProfiles.getDefaultInstance(), marshalers[0]); + assertThat(roundTripResult).isEqualTo(builderResult); + // TODO + } + + @Test + void compareProfileMarshaling() { + ProfileData input = sampleProfileData(); + Profile builderResult = sampleProfileBuilder().build(); Profile roundTripResult = parse(Profile.getDefaultInstance(), ProfileMarshaler.create(input)); assertThat(roundTripResult).isEqualTo(builderResult); } @@ -212,6 +263,50 @@ void compareValueTypeMarshaling() { assertThat(roundTripResult).isEqualTo(builderResult); } + // twin of sampleProfileBuilder + private static ProfileData sampleProfileData() { + return ImmutableProfileData.create( + Collections.emptyList(), + Collections.emptyList(), + Collections.emptyList(), + Collections.emptyList(), + listOf(1L, 2L), + Collections.emptyList(), + Attributes.empty(), + Collections.emptyList(), + Collections.emptyList(), + Collections.emptyList(), + 3, + 4, + 5, + 6, + ImmutableValueTypeData.create(1, 2, AggregationTemporality.CUMULATIVE), + 7, + listOf(8L, 9L), + 10); + } + + // twin of sampleProfileData + private static Profile.Builder sampleProfileBuilder() { + return Profile.newBuilder() + .addAllLocationIndices(listOf(1L, 2L)) + .setDropFrames(3) + .setKeepFrames(4) + .setTimeNanos(5) + .setDurationNanos(6) + .setPeriod(7) + .setPeriodType( + ValueType.newBuilder() + .setType(1) + .setUnit(2) + .setAggregationTemporality( + io.opentelemetry.proto.profiles.v1experimental.AggregationTemporality + .AGGREGATION_TEMPORALITY_CUMULATIVE) + .build()) + .addAllComment(listOf(8L, 9L)) + .setDefaultSampleType(10); + } + private static List listOf(T a, T b) { ArrayList list = new ArrayList<>(); list.add(a); From 39b24118a1f37cc6ced5106664ce4d729a2a3197 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 20 Sep 2024 12:05:58 -0500 Subject: [PATCH 578/901] fix(deps): update dependency io.grpc:grpc-bom to v1.68.0 (#6735) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- dependencyManagement/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index 2fd722085ea..8e9194daa5a 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -14,7 +14,7 @@ val DEPENDENCY_BOMS = listOf( "com.linecorp.armeria:armeria-bom:1.30.1", "com.squareup.okhttp3:okhttp-bom:4.12.0", "com.squareup.okio:okio-bom:3.9.1", // applies to transitive dependencies of okhttp - "io.grpc:grpc-bom:1.66.0", + "io.grpc:grpc-bom:1.68.0", "io.netty:netty-bom:4.1.113.Final", "io.zipkin.brave:brave-bom:6.0.3", "io.zipkin.reporter2:zipkin-reporter-bom:3.4.2", From 325822ce8527b83a09274c86a5123a214db80c1d Mon Sep 17 00:00:00 2001 From: jack-berg <34418638+jack-berg@users.noreply.github.com> Date: Fri, 20 Sep 2024 14:00:04 -0500 Subject: [PATCH 579/901] Use autoconfigured ClassLoader to load declarative config (#6725) --- ...AutoConfiguredOpenTelemetrySdkBuilder.java | 23 +++++---- .../sdk/autoconfigure/internal/SpiHelper.java | 12 ++++- .../incubator/fileconfig/FileConfigUtil.java | 3 +- .../fileconfig/FileConfiguration.java | 47 ++++++++++++++----- .../incubator/fileconfig/ResourceFactory.java | 4 +- .../YamlStructuredConfigProperties.java | 23 +++++++-- 6 files changed, 84 insertions(+), 28 deletions(-) diff --git a/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/AutoConfiguredOpenTelemetrySdkBuilder.java b/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/AutoConfiguredOpenTelemetrySdkBuilder.java index 06722b8cb18..030045ea52d 100644 --- a/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/AutoConfiguredOpenTelemetrySdkBuilder.java +++ b/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/AutoConfiguredOpenTelemetrySdkBuilder.java @@ -107,8 +107,8 @@ public final class AutoConfiguredOpenTelemetrySdkBuilder implements AutoConfigur private Function configPropertiesCustomizer = Function.identity(); - private SpiHelper spiHelper = - SpiHelper.create(AutoConfiguredOpenTelemetrySdk.class.getClassLoader()); + private ComponentLoader componentLoader = + SpiHelper.serviceComponentLoader(AutoConfiguredOpenTelemetrySdk.class.getClassLoader()); private boolean registerShutdownHook = true; @@ -401,14 +401,14 @@ public AutoConfiguredOpenTelemetrySdkBuilder setResultAsGlobal() { public AutoConfiguredOpenTelemetrySdkBuilder setServiceClassLoader( ClassLoader serviceClassLoader) { requireNonNull(serviceClassLoader, "serviceClassLoader"); - this.spiHelper = SpiHelper.create(serviceClassLoader); + this.componentLoader = SpiHelper.serviceComponentLoader(serviceClassLoader); return this; } /** Sets the {@link ComponentLoader} to be used to load SPI implementations. */ AutoConfiguredOpenTelemetrySdkBuilder setComponentLoader(ComponentLoader componentLoader) { requireNonNull(componentLoader, "componentLoader"); - this.spiHelper = SpiHelper.create(componentLoader); + this.componentLoader = componentLoader; return this; } @@ -417,6 +417,7 @@ AutoConfiguredOpenTelemetrySdkBuilder setComponentLoader(ComponentLoader compone * the settings of this {@link AutoConfiguredOpenTelemetrySdkBuilder}. */ public AutoConfiguredOpenTelemetrySdk build() { + SpiHelper spiHelper = SpiHelper.create(componentLoader); if (!customized) { customized = true; mergeSdkTracerProviderConfigurer(); @@ -428,7 +429,8 @@ public AutoConfiguredOpenTelemetrySdk build() { ConfigProperties config = getConfig(); - AutoConfiguredOpenTelemetrySdk fromFileConfiguration = maybeConfigureFromFile(config); + AutoConfiguredOpenTelemetrySdk fromFileConfiguration = + maybeConfigureFromFile(config, componentLoader); if (fromFileConfiguration != null) { maybeRegisterShutdownHook(fromFileConfiguration.getOpenTelemetrySdk()); maybeSetAsGlobal(fromFileConfiguration.getOpenTelemetrySdk()); @@ -527,7 +529,8 @@ public AutoConfiguredOpenTelemetrySdk build() { } @Nullable - private static AutoConfiguredOpenTelemetrySdk maybeConfigureFromFile(ConfigProperties config) { + private static AutoConfiguredOpenTelemetrySdk maybeConfigureFromFile( + ConfigProperties config, ComponentLoader componentLoader) { String otelConfigFile = config.getString("otel.config.file"); if (otelConfigFile != null && !otelConfigFile.isEmpty()) { logger.warning( @@ -552,8 +555,10 @@ private static AutoConfiguredOpenTelemetrySdk maybeConfigureFromFile(ConfigPrope Class openTelemetryConfiguration = Class.forName( "io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.OpenTelemetryConfigurationModel"); - Method create = configurationFactory.getMethod("create", openTelemetryConfiguration); - OpenTelemetrySdk sdk = (OpenTelemetrySdk) create.invoke(null, model); + Method create = + configurationFactory.getMethod( + "create", openTelemetryConfiguration, ComponentLoader.class); + OpenTelemetrySdk sdk = (OpenTelemetrySdk) create.invoke(null, model, componentLoader); Method toConfigProperties = configurationFactory.getMethod("toConfigProperties", openTelemetryConfiguration); StructuredConfigProperties structuredConfigProperties = @@ -608,7 +613,7 @@ void callAutoConfigureListeners(SpiHelper spiHelper, OpenTelemetrySdk openTeleme @SuppressWarnings("deprecation") // Support deprecated SdkTracerProviderConfigurer private void mergeSdkTracerProviderConfigurer() { for (io.opentelemetry.sdk.autoconfigure.spi.traces.SdkTracerProviderConfigurer configurer : - spiHelper.load( + componentLoader.load( io.opentelemetry.sdk.autoconfigure.spi.traces.SdkTracerProviderConfigurer.class)) { addTracerProviderCustomizer( (builder, config) -> { diff --git a/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/internal/SpiHelper.java b/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/internal/SpiHelper.java index c8c40e63e07..6f3196a6f61 100644 --- a/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/internal/SpiHelper.java +++ b/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/internal/SpiHelper.java @@ -41,7 +41,7 @@ private SpiHelper(ComponentLoader componentLoader) { /** Create a {@link SpiHelper} which loads SPIs using the {@code classLoader}. */ public static SpiHelper create(ClassLoader classLoader) { - return new SpiHelper(new ServiceLoaderComponentLoader(classLoader)); + return new SpiHelper(serviceComponentLoader(classLoader)); } /** Create a {@link SpiHelper} which loads SPIs using the {@code componentLoader}. */ @@ -49,6 +49,16 @@ public static SpiHelper create(ComponentLoader componentLoader) { return new SpiHelper(componentLoader); } + /** Create a {@link ComponentLoader} which loads using the {@code classLoader}. */ + public static ComponentLoader serviceComponentLoader(ClassLoader classLoader) { + return new ServiceLoaderComponentLoader(classLoader); + } + + /** Return the backing underlying {@link ComponentLoader}. */ + public ComponentLoader getComponentLoader() { + return componentLoader; + } + /** * Load implementations of an SPI which are configurable (i.e. they accept {@link * ConfigProperties}. diff --git a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/FileConfigUtil.java b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/FileConfigUtil.java index 75fd08858a7..f4c1346dc72 100644 --- a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/FileConfigUtil.java +++ b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/FileConfigUtil.java @@ -49,7 +49,8 @@ static T requireNonNull(@Nullable T object, String description) { */ static T loadComponent(SpiHelper spiHelper, Class type, String name, Object model) { // Map model to generic structured config properties - StructuredConfigProperties config = FileConfiguration.toConfigProperties(model); + StructuredConfigProperties config = + FileConfiguration.toConfigProperties(model, spiHelper.getComponentLoader()); return spiHelper.loadComponent(type, name, config); } } diff --git a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/FileConfiguration.java b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/FileConfiguration.java index 06ab3cc755c..5b1b3dd32f0 100644 --- a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/FileConfiguration.java +++ b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/FileConfiguration.java @@ -10,6 +10,7 @@ import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.databind.ObjectMapper; import io.opentelemetry.sdk.OpenTelemetrySdk; +import io.opentelemetry.sdk.autoconfigure.internal.ComponentLoader; import io.opentelemetry.sdk.autoconfigure.internal.SpiHelper; import io.opentelemetry.sdk.autoconfigure.spi.ConfigurationException; import io.opentelemetry.sdk.autoconfigure.spi.internal.ComponentProvider; @@ -49,6 +50,8 @@ public final class FileConfiguration { private static final Logger logger = Logger.getLogger(FileConfiguration.class.getName()); private static final Pattern ENV_VARIABLE_REFERENCE = Pattern.compile("\\$\\{([a-zA-Z_][a-zA-Z0-9_]*)}"); + private static final ComponentLoader DEFAULT_COMPONENT_LOADER = + SpiHelper.serviceComponentLoader(FileConfiguration.class.getClassLoader()); private static final ObjectMapper MAPPER; @@ -86,9 +89,24 @@ public static OpenTelemetrySdk parseAndCreate(InputStream inputStream) { * @throws ConfigurationException if unable to interpret */ public static OpenTelemetrySdk create(OpenTelemetryConfigurationModel configurationModel) { + return create(configurationModel, DEFAULT_COMPONENT_LOADER); + } + + /** + * Interpret the {@code configurationModel} to create {@link OpenTelemetrySdk} instance + * corresponding to the configuration. + * + * @param configurationModel the configuration model + * @param componentLoader the component loader used to load {@link ComponentProvider} + * implementations + * @return the {@link OpenTelemetrySdk} + * @throws ConfigurationException if unable to interpret + */ + public static OpenTelemetrySdk create( + OpenTelemetryConfigurationModel configurationModel, ComponentLoader componentLoader) { return createAndMaybeCleanup( OpenTelemetryConfigurationFactory.getInstance(), - SpiHelper.create(FileConfiguration.class.getClassLoader()), + SpiHelper.create(componentLoader), configurationModel); } @@ -130,7 +148,7 @@ static Object loadYaml(InputStream inputStream, Map environmentV */ public static StructuredConfigProperties toConfigProperties( OpenTelemetryConfigurationModel model) { - return toConfigProperties((Object) model); + return toConfigProperties(model, DEFAULT_COMPONENT_LOADER); } /** @@ -141,13 +159,14 @@ public static StructuredConfigProperties toConfigProperties( */ public static StructuredConfigProperties toConfigProperties(InputStream configuration) { Object yamlObj = loadYaml(configuration, System.getenv()); - return toConfigProperties(yamlObj); + return toConfigProperties(yamlObj, DEFAULT_COMPONENT_LOADER); } - static StructuredConfigProperties toConfigProperties(Object model) { + static StructuredConfigProperties toConfigProperties( + Object model, ComponentLoader componentLoader) { Map configurationMap = MAPPER.convertValue(model, new TypeReference>() {}); - return YamlStructuredConfigProperties.create(configurationMap); + return YamlStructuredConfigProperties.create(configurationMap, componentLoader); } /** @@ -162,21 +181,27 @@ static StructuredConfigProperties toConfigProperties(Object model) { // ComponentProvider public static io.opentelemetry.sdk.trace.samplers.Sampler createSampler( StructuredConfigProperties genericSamplerModel) { - SamplerModel samplerModel = convertToModel(genericSamplerModel, SamplerModel.class); + YamlStructuredConfigProperties yamlStructuredConfigProperties = + requireYamlStructuredConfigProperties(genericSamplerModel); + SamplerModel samplerModel = convertToModel(yamlStructuredConfigProperties, SamplerModel.class); return createAndMaybeCleanup( SamplerFactory.getInstance(), - SpiHelper.create(FileConfiguration.class.getClassLoader()), + SpiHelper.create(yamlStructuredConfigProperties.getComponentLoader()), samplerModel); } - static T convertToModel( - StructuredConfigProperties structuredConfigProperties, Class modelType) { + private static YamlStructuredConfigProperties requireYamlStructuredConfigProperties( + StructuredConfigProperties structuredConfigProperties) { if (!(structuredConfigProperties instanceof YamlStructuredConfigProperties)) { throw new ConfigurationException( "Only YamlStructuredConfigProperties can be converted to model"); } - return MAPPER.convertValue( - ((YamlStructuredConfigProperties) structuredConfigProperties).toMap(), modelType); + return (YamlStructuredConfigProperties) structuredConfigProperties; + } + + static T convertToModel( + YamlStructuredConfigProperties structuredConfigProperties, Class modelType) { + return MAPPER.convertValue(structuredConfigProperties.toMap(), modelType); } static R createAndMaybeCleanup(Factory factory, SpiHelper spiHelper, M model) { diff --git a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/ResourceFactory.java b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/ResourceFactory.java index f2d5da54fc2..bb5540268a8 100644 --- a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/ResourceFactory.java +++ b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/ResourceFactory.java @@ -25,7 +25,9 @@ final class ResourceFactory Resource> { private static final StructuredConfigProperties EMPTY_CONFIG = - FileConfiguration.toConfigProperties(Collections.emptyMap()); + FileConfiguration.toConfigProperties( + Collections.emptyMap(), + SpiHelper.serviceComponentLoader(ResourceFactory.class.getClassLoader())); private static final ResourceFactory INSTANCE = new ResourceFactory(); private ResourceFactory() {} diff --git a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/YamlStructuredConfigProperties.java b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/YamlStructuredConfigProperties.java index 04c432ce8a7..87cbc5f8fc8 100644 --- a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/YamlStructuredConfigProperties.java +++ b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/YamlStructuredConfigProperties.java @@ -8,6 +8,7 @@ import static java.util.stream.Collectors.joining; import static java.util.stream.Collectors.toList; +import io.opentelemetry.sdk.autoconfigure.internal.ComponentLoader; import io.opentelemetry.sdk.autoconfigure.spi.ConfigurationException; import io.opentelemetry.sdk.autoconfigure.spi.internal.StructuredConfigProperties; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.OpenTelemetryConfigurationModel; @@ -37,14 +38,17 @@ final class YamlStructuredConfigProperties implements StructuredConfigProperties private final Map> listEntries; private final Map mapEntries; + private final ComponentLoader componentLoader; private YamlStructuredConfigProperties( Map simpleEntries, Map> listEntries, - Map mapEntries) { + Map mapEntries, + ComponentLoader componentLoader) { this.simpleEntries = simpleEntries; this.listEntries = listEntries; this.mapEntries = mapEntries; + this.componentLoader = componentLoader; } /** @@ -57,7 +61,8 @@ private YamlStructuredConfigProperties( * @see FileConfiguration#toConfigProperties(OpenTelemetryConfigurationModel) */ @SuppressWarnings("unchecked") - static YamlStructuredConfigProperties create(Map properties) { + static YamlStructuredConfigProperties create( + Map properties, ComponentLoader componentLoader) { Map simpleEntries = new HashMap<>(); Map> listEntries = new HashMap<>(); Map mapEntries = new HashMap<>(); @@ -75,13 +80,15 @@ static YamlStructuredConfigProperties create(Map properties) { if (isListOfMaps(value)) { List list = ((List>) value) - .stream().map(YamlStructuredConfigProperties::create).collect(toList()); + .stream() + .map(map -> YamlStructuredConfigProperties.create(map, componentLoader)) + .collect(toList()); listEntries.put(key, list); continue; } if (isMap(value)) { YamlStructuredConfigProperties configProperties = - YamlStructuredConfigProperties.create((Map) value); + YamlStructuredConfigProperties.create((Map) value, componentLoader); mapEntries.put(key, configProperties); continue; } @@ -91,7 +98,8 @@ static YamlStructuredConfigProperties create(Map properties) { + "\" has unrecognized object type " + value.getClass().getName()); } - return new YamlStructuredConfigProperties(simpleEntries, listEntries, mapEntries); + return new YamlStructuredConfigProperties( + simpleEntries, listEntries, mapEntries, componentLoader); } private static boolean isPrimitiveList(Object object) { @@ -292,4 +300,9 @@ public Map toMap() { mapEntries.forEach((key, value) -> result.put(key, value.toMap())); return Collections.unmodifiableMap(result); } + + /** Return the {@link ComponentLoader}. */ + public ComponentLoader getComponentLoader() { + return componentLoader; + } } From c5f6218ded0e1baf72c603cb231be8295689d4ef Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 23 Sep 2024 11:06:27 -0500 Subject: [PATCH 580/901] fix(deps): update dependency com.uber.nullaway:nullaway to v0.11.3 (#6727) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- dependencyManagement/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index 8e9194daa5a..b26c8bcd96c 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -61,7 +61,7 @@ val DEPENDENCIES = listOf( "com.google.guava:guava-beta-checker:1.0", "com.sun.net.httpserver:http:20070405", "com.tngtech.archunit:archunit-junit5:1.3.0", - "com.uber.nullaway:nullaway:0.11.2", + "com.uber.nullaway:nullaway:0.11.3", "edu.berkeley.cs.jqf:jqf-fuzz:1.7", // jqf-fuzz version 1.8+ requires Java 11+ "eu.rekawek.toxiproxy:toxiproxy-java:2.1.7", "io.github.netmikey.logunit:logunit-jul:2.0.0", From a5de6d5cbb240724770eab89c2d29f6775357100 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 23 Sep 2024 11:06:51 -0500 Subject: [PATCH 581/901] chore(deps): update plugin org.jsonschema2pojo to v1.2.2 (#6736) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- settings.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/settings.gradle.kts b/settings.gradle.kts index efc78a9f203..222c497d44b 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -3,7 +3,7 @@ pluginManagement { id("com.gradleup.shadow") version "8.3.2" id("com.gradle.develocity") version "3.18.1" id("de.undercouch.download") version "5.6.0" - id("org.jsonschema2pojo") version "1.2.1" + id("org.jsonschema2pojo") version "1.2.2" id("io.github.gradle-nexus.publish-plugin") version "2.0.0" id("org.graalvm.buildtools.native") version "0.10.3" } From fa826fdef07167b22089b96b957749e9f41e72e2 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 23 Sep 2024 11:07:08 -0500 Subject: [PATCH 582/901] fix(deps): update dependency com.google.protobuf:protobuf-bom to v3.25.5 (#6730) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- dependencyManagement/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index b26c8bcd96c..98dc07742b9 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -10,7 +10,7 @@ rootProject.extra["versions"] = dependencyVersions val DEPENDENCY_BOMS = listOf( "com.fasterxml.jackson:jackson-bom:2.17.2", "com.google.guava:guava-bom:33.3.0-jre", - "com.google.protobuf:protobuf-bom:3.25.4", + "com.google.protobuf:protobuf-bom:3.25.5", "com.linecorp.armeria:armeria-bom:1.30.1", "com.squareup.okhttp3:okhttp-bom:4.12.0", "com.squareup.okio:okio-bom:3.9.1", // applies to transitive dependencies of okhttp From 697b4e0c7021eeff545afa7b2929ad8ab2bd3474 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 25 Sep 2024 18:35:32 -0700 Subject: [PATCH 583/901] fix(deps): update dependency org.junit:junit-bom to v5.11.1 (#6748) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- dependencyManagement/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index 98dc07742b9..5ecff0a0fe8 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -19,7 +19,7 @@ val DEPENDENCY_BOMS = listOf( "io.zipkin.brave:brave-bom:6.0.3", "io.zipkin.reporter2:zipkin-reporter-bom:3.4.2", "org.assertj:assertj-bom:3.26.3", - "org.junit:junit-bom:5.11.0", + "org.junit:junit-bom:5.11.1", "org.testcontainers:testcontainers-bom:1.20.1", "org.snakeyaml:snakeyaml-engine:2.8" ) From 2dbb8de3498a609af5f1746bea160c6b523b1c54 Mon Sep 17 00:00:00 2001 From: jack-berg <34418638+jack-berg@users.noreply.github.com> Date: Mon, 30 Sep 2024 14:12:25 -0500 Subject: [PATCH 584/901] Update to opentelemetry-configuration v0.3.0 (#6733) --- dependencyManagement/build.gradle.kts | 2 +- .../otlp/internal/OtlpConfigUtil.java | 73 +++--- .../autoconfigure/FileConfigurationTest.java | 3 +- .../autoconfigure/FileConfigurationTest.java | 6 +- sdk-extensions/incubator/build.gradle.kts | 18 +- .../fileconfig/AttributeListFactory.java | 140 +++++++++++ .../fileconfig/AttributesFactory.java | 152 ------------ .../fileconfig/FileConfiguration.java | 9 +- .../fileconfig/LogRecordExporterFactory.java | 6 + .../fileconfig/MetricExporterFactory.java | 10 +- .../fileconfig/MetricReaderFactory.java | 7 +- .../incubator/fileconfig/ResourceFactory.java | 97 +++++++- .../incubator/fileconfig/ViewFactory.java | 29 ++- .../fileconfig/AttributeListFactoryTest.java | 140 +++++++++++ .../fileconfig/AttributesFactoryTest.java | 91 ------- .../FileConfigurationCreateTest.java | 5 +- .../FileConfigurationParseTest.java | 233 ++++++++++++++++-- .../LogRecordExporterFactoryTest.java | 35 ++- .../fileconfig/MeterProviderFactoryTest.java | 4 +- .../fileconfig/MetricExporterFactoryTest.java | 64 +++-- .../fileconfig/MetricReaderFactoryTest.java | 28 +-- ...OpenTelemetryConfigurationFactoryTest.java | 16 +- .../fileconfig/ResourceFactoryTest.java | 106 +++++++- .../fileconfig/SpanExporterFactoryTest.java | 35 ++- .../incubator/fileconfig/ViewFactoryTest.java | 4 +- .../YamlStructuredConfigPropertiesTest.java | 15 +- 26 files changed, 890 insertions(+), 438 deletions(-) create mode 100644 sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/AttributeListFactory.java delete mode 100644 sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/AttributesFactory.java create mode 100644 sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/AttributeListFactoryTest.java delete mode 100644 sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/AttributesFactoryTest.java diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index 5ecff0a0fe8..9a6f015b098 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -66,7 +66,7 @@ val DEPENDENCIES = listOf( "eu.rekawek.toxiproxy:toxiproxy-java:2.1.7", "io.github.netmikey.logunit:logunit-jul:2.0.0", "io.jaegertracing:jaeger-client:1.8.1", - "io.opentelemetry.contrib:opentelemetry-aws-xray-propagator:1.29.0-alpha", + "io.opentelemetry.contrib:opentelemetry-aws-xray-propagator:1.39.0-alpha", "io.opentelemetry.semconv:opentelemetry-semconv-incubating:1.27.0-alpha", "io.opentelemetry.proto:opentelemetry-proto:1.3.2-alpha", "io.opentracing:opentracing-api:0.33.0", diff --git a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/OtlpConfigUtil.java b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/OtlpConfigUtil.java index 7fbc5107fd1..1ca885bf5a0 100644 --- a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/OtlpConfigUtil.java +++ b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/OtlpConfigUtil.java @@ -10,6 +10,7 @@ import io.opentelemetry.exporter.internal.ExporterBuilderUtil; import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties; import io.opentelemetry.sdk.autoconfigure.spi.ConfigurationException; +import io.opentelemetry.sdk.autoconfigure.spi.internal.DefaultConfigProperties; import io.opentelemetry.sdk.autoconfigure.spi.internal.StructuredConfigProperties; import io.opentelemetry.sdk.common.export.MemoryMode; import io.opentelemetry.sdk.common.export.RetryPolicy; @@ -27,6 +28,8 @@ import java.net.URLDecoder; import java.nio.charset.StandardCharsets; import java.time.Duration; +import java.util.Collections; +import java.util.List; import java.util.Locale; import java.util.Map; import java.util.function.BiConsumer; @@ -97,21 +100,7 @@ public static void configureOtlpExporterBuilder( setEndpoint.accept(endpoint.toString()); } - Map headers = config.getMap("otel.exporter.otlp." + dataType + ".headers"); - if (headers.isEmpty()) { - headers = config.getMap("otel.exporter.otlp.headers"); - } - for (Map.Entry entry : headers.entrySet()) { - String key = entry.getKey(); - String value = entry.getValue(); - try { - // headers are encoded as URL - see - // https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/protocol/exporter.md#specifying-headers-via-environment-variables - addHeader.accept(key, URLDecoder.decode(value, StandardCharsets.UTF_8.displayName())); - } catch (Exception e) { - throw new ConfigurationException("Cannot decode header value: " + value, e); - } - } + configureOtlpHeaders(config, dataType, addHeader); String compression = config.getString("otel.exporter.otlp." + dataType + ".compression"); if (compression == null) { @@ -190,29 +179,28 @@ public static void configureOtlpExporterBuilder( String protocol = getStructuredConfigOtlpProtocol(config); boolean isHttpProtobuf = protocol.equals(PROTOCOL_HTTP_PROTOBUF); URL endpoint = validateEndpoint(config.getString("endpoint"), isHttpProtobuf); - if (endpoint != null && isHttpProtobuf) { - String path = endpoint.getPath(); - if (!path.endsWith("/")) { - path += "/"; - } - path += signalPath(dataType); - endpoint = createUrl(endpoint, path); - } if (endpoint != null) { setEndpoint.accept(endpoint.toString()); } - StructuredConfigProperties headers = config.getStructured("headers"); + String headerList = config.getString("headers_list"); + if (headerList != null) { + ConfigProperties headersListConfig = + DefaultConfigProperties.createFromMap( + Collections.singletonMap("otel.exporter.otlp.headers", headerList)); + configureOtlpHeaders(headersListConfig, dataType, addHeader); + } + + List headers = config.getStructuredList("headers"); if (headers != null) { - headers - .getPropertyKeys() - .forEach( - header -> { - String value = headers.getString(header); - if (value != null) { - addHeader.accept(header, value); - } - }); + headers.forEach( + header -> { + String name = header.getString("name"); + String value = header.getString("value"); + if (name != null && value != null) { + addHeader.accept(name, value); + } + }); } String compression = config.getString("compression"); @@ -249,6 +237,25 @@ public static void configureOtlpExporterBuilder( ExporterBuilderUtil.configureExporterMemoryMode(config, setMemoryMode); } + private static void configureOtlpHeaders( + ConfigProperties config, String dataType, BiConsumer addHeader) { + Map headers = config.getMap("otel.exporter.otlp." + dataType + ".headers"); + if (headers.isEmpty()) { + headers = config.getMap("otel.exporter.otlp.headers"); + } + for (Map.Entry entry : headers.entrySet()) { + String key = entry.getKey(); + String value = entry.getValue(); + try { + // headers are encoded as URL - see + // https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/protocol/exporter.md#specifying-headers-via-environment-variables + addHeader.accept(key, URLDecoder.decode(value, StandardCharsets.UTF_8.displayName())); + } catch (Exception e) { + throw new ConfigurationException("Cannot decode header value: " + value, e); + } + } + } + /** * Invoke the {@code aggregationTemporalitySelectorConsumer} with the configured {@link * AggregationTemporality}. diff --git a/sdk-extensions/autoconfigure/src/test/java/io/opentelemetry/sdk/autoconfigure/FileConfigurationTest.java b/sdk-extensions/autoconfigure/src/test/java/io/opentelemetry/sdk/autoconfigure/FileConfigurationTest.java index 332c70352ee..e3a9bb3ed10 100644 --- a/sdk-extensions/autoconfigure/src/test/java/io/opentelemetry/sdk/autoconfigure/FileConfigurationTest.java +++ b/sdk-extensions/autoconfigure/src/test/java/io/opentelemetry/sdk/autoconfigure/FileConfigurationTest.java @@ -34,7 +34,8 @@ void configFile(@TempDir Path tempDir) throws IOException { "file_format: \"0.1\"\n" + "resource:\n" + " attributes:\n" - + " service.name: test\n" + + " - name: service.name\n" + + " value: test\n" + "tracer_provider:\n" + " processors:\n" + " - simple:\n" diff --git a/sdk-extensions/autoconfigure/src/testFullConfig/java/io/opentelemetry/sdk/autoconfigure/FileConfigurationTest.java b/sdk-extensions/autoconfigure/src/testFullConfig/java/io/opentelemetry/sdk/autoconfigure/FileConfigurationTest.java index c49208aa917..3b3869e5bf6 100644 --- a/sdk-extensions/autoconfigure/src/testFullConfig/java/io/opentelemetry/sdk/autoconfigure/FileConfigurationTest.java +++ b/sdk-extensions/autoconfigure/src/testFullConfig/java/io/opentelemetry/sdk/autoconfigure/FileConfigurationTest.java @@ -58,7 +58,8 @@ void setup() throws IOException { "file_format: \"0.1\"\n" + "resource:\n" + " attributes:\n" - + " service.name: test\n" + + " - name: service.name\n" + + " value: test\n" + "tracer_provider:\n" + " processors:\n" + " - simple:\n" @@ -162,7 +163,8 @@ void configFile_Error(@TempDir Path tempDir) throws IOException { "file_format: \"0.1\"\n" + "resource:\n" + " attributes:\n" - + " service.name: test\n" + + " - name: service.name\n" + + " value: test\n" + "tracer_provider:\n" + " processors:\n" + " - simple:\n" diff --git a/sdk-extensions/incubator/build.gradle.kts b/sdk-extensions/incubator/build.gradle.kts index b7c50f4dee1..59acac261ef 100644 --- a/sdk-extensions/incubator/build.gradle.kts +++ b/sdk-extensions/incubator/build.gradle.kts @@ -49,13 +49,14 @@ dependencies { // The sequence of tasks is: // 1. downloadConfigurationSchema - download configuration schema from open-telemetry/opentelemetry-configuration // 2. unzipConfigurationSchema - unzip the configuration schema archive contents to $buildDir/configuration/ -// 3. generateJsonSchema2Pojo - generate java POJOs from the configuration schema -// 4. jsonSchema2PojoPostProcessing - perform various post processing on the generated POJOs, e.g. replace javax.annotation.processing.Generated with javax.annotation.Generated, add @SuppressWarning("rawtypes") annotation -// 5. overwriteJs2p - overwrite original generated classes with versions containing updated @Generated annotation -// 6. deleteJs2pTmp - delete tmp directory +// 3. deleteTypeDescriptions - delete type_descriptions.yaml $buildDir/configuration/schema, which is not part of core schema and causes problems resolving type refs +// 4. generateJsonSchema2Pojo - generate java POJOs from the configuration schema +// 5. jsonSchema2PojoPostProcessing - perform various post processing on the generated POJOs, e.g. replace javax.annotation.processing.Generated with javax.annotation.Generated, add @SuppressWarning("rawtypes") annotation +// 6. overwriteJs2p - overwrite original generated classes with versions containing updated @Generated annotation +// 7. deleteJs2pTmp - delete tmp directory // ... proceed with normal sourcesJar, compileJava, etc -val configurationTag = "0.1.0" +val configurationTag = "0.3.0" val configurationRef = "refs/tags/v$configurationTag" // Replace with commit SHA to point to experiment with a specific commit val configurationRepoZip = "https://github.com/open-telemetry/opentelemetry-configuration/archive/$configurationRef.zip" val buildDirectory = layout.buildDirectory.asFile.get() @@ -78,6 +79,11 @@ val unzipConfigurationSchema by tasks.registering(Copy::class) { into("$buildDirectory/configuration/") } +val deleteTypeDescriptions by tasks.registering(Delete::class) { + dependsOn(unzipConfigurationSchema) + delete("$buildDirectory/configuration/schema/type_descriptions.yaml") +} + jsonSchema2Pojo { sourceFiles = setOf(file("$buildDirectory/configuration/schema")) targetDirectory = file("$buildDirectory/generated/sources/js2p/java/main") @@ -106,7 +112,7 @@ jsonSchema2Pojo { } val generateJsonSchema2Pojo = tasks.getByName("generateJsonSchema2Pojo") -generateJsonSchema2Pojo.dependsOn(unzipConfigurationSchema) +generateJsonSchema2Pojo.dependsOn(deleteTypeDescriptions) val jsonSchema2PojoPostProcessing by tasks.registering(Copy::class) { dependsOn(generateJsonSchema2Pojo) diff --git a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/AttributeListFactory.java b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/AttributeListFactory.java new file mode 100644 index 00000000000..c3bba8925b3 --- /dev/null +++ b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/AttributeListFactory.java @@ -0,0 +1,140 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.sdk.extension.incubator.fileconfig; + +import static java.util.stream.Collectors.toList; + +import io.opentelemetry.api.common.AttributeKey; +import io.opentelemetry.api.common.AttributesBuilder; +import io.opentelemetry.sdk.autoconfigure.internal.SpiHelper; +import io.opentelemetry.sdk.autoconfigure.spi.ConfigurationException; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.AttributeNameValueModel; +import java.io.Closeable; +import java.util.List; +import javax.annotation.Nullable; + +final class AttributeListFactory + implements Factory, io.opentelemetry.api.common.Attributes> { + + private static final AttributeListFactory INSTANCE = new AttributeListFactory(); + + private AttributeListFactory() {} + + static AttributeListFactory getInstance() { + return INSTANCE; + } + + @Override + public io.opentelemetry.api.common.Attributes create( + List model, SpiHelper spiHelper, List closeables) { + AttributesBuilder builder = io.opentelemetry.api.common.Attributes.builder(); + + for (AttributeNameValueModel nameValueModel : model) { + addToBuilder(nameValueModel, builder); + } + + return builder.build(); + } + + private static void addToBuilder( + AttributeNameValueModel nameValueModel, AttributesBuilder builder) { + String name = FileConfigUtil.requireNonNull(nameValueModel.getName(), "attribute name"); + Object value = FileConfigUtil.requireNonNull(nameValueModel.getValue(), "attribute value"); + AttributeNameValueModel.Type type = nameValueModel.getType(); + if (type == null) { + type = AttributeNameValueModel.Type.STRING; + } + switch (type) { + case STRING: + if (value instanceof String) { + builder.put(name, (String) value); + return; + } + break; + case BOOL: + if (value instanceof Boolean) { + builder.put(name, (boolean) value); + return; + } + break; + case INT: + if ((value instanceof Integer) || (value instanceof Long)) { + builder.put(name, ((Number) value).longValue()); + return; + } + break; + case DOUBLE: + if (value instanceof Number) { + builder.put(name, ((Number) value).doubleValue()); + return; + } + break; + case STRING_ARRAY: + List stringList = checkListOfType(value, String.class); + if (stringList != null) { + builder.put(AttributeKey.stringArrayKey(name), stringList); + return; + } + break; + case BOOL_ARRAY: + List boolList = checkListOfType(value, Boolean.class); + if (boolList != null) { + builder.put(AttributeKey.booleanArrayKey(name), boolList); + return; + } + break; + case INT_ARRAY: + List longList = checkListOfType(value, Long.class); + if (longList != null) { + builder.put(AttributeKey.longArrayKey(name), longList); + return; + } + List intList = checkListOfType(value, Integer.class); + if (intList != null) { + builder.put( + AttributeKey.longArrayKey(name), + intList.stream().map(i -> (long) i).collect(toList())); + return; + } + break; + case DOUBLE_ARRAY: + List doubleList = checkListOfType(value, Double.class); + if (doubleList != null) { + builder.put(AttributeKey.doubleArrayKey(name), doubleList); + return; + } + List floatList = checkListOfType(value, Float.class); + if (floatList != null) { + builder.put( + AttributeKey.doubleArrayKey(name), + floatList.stream().map(i -> (double) i).collect(toList())); + return; + } + break; + } + throw new ConfigurationException( + "Error processing attribute with name \"" + + name + + "\": value did not match type " + + type.name()); + } + + @SuppressWarnings("unchecked") + @Nullable + private static List checkListOfType(Object value, Class expectedType) { + if (!(value instanceof List)) { + return null; + } + List list = (List) value; + if (list.isEmpty()) { + return null; + } + if (!list.stream().allMatch(entry -> expectedType.isAssignableFrom(entry.getClass()))) { + return null; + } + return (List) value; + } +} diff --git a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/AttributesFactory.java b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/AttributesFactory.java deleted file mode 100644 index a45031a85f3..00000000000 --- a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/AttributesFactory.java +++ /dev/null @@ -1,152 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package io.opentelemetry.sdk.extension.incubator.fileconfig; - -import static io.opentelemetry.api.common.AttributeKey.stringKey; - -import io.opentelemetry.api.common.AttributeKey; -import io.opentelemetry.api.common.AttributesBuilder; -import io.opentelemetry.sdk.autoconfigure.internal.SpiHelper; -import io.opentelemetry.sdk.autoconfigure.spi.ConfigurationException; -import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.AttributesModel; -import java.io.Closeable; -import java.util.List; - -final class AttributesFactory - implements Factory { - - private static final AttributesFactory INSTANCE = new AttributesFactory(); - - private AttributesFactory() {} - - static AttributesFactory getInstance() { - return INSTANCE; - } - - @Override - public io.opentelemetry.api.common.Attributes create( - AttributesModel model, SpiHelper spiHelper, List closeables) { - AttributesBuilder builder = io.opentelemetry.api.common.Attributes.builder(); - - String serviceName = model.getServiceName(); - if (serviceName != null) { - builder.put(stringKey("service.name"), serviceName); - } - - model - .getAdditionalProperties() - .forEach( - (key, value) -> { - if (value == null) { - throw new ConfigurationException( - "Error processing attribute with key \"" + key + "\": unexpected null value"); - } - if (value instanceof String) { - builder.put(key, (String) value); - return; - } - if (value instanceof Integer) { - builder.put(key, (int) value); - return; - } - if (value instanceof Long) { - builder.put(key, (long) value); - return; - } - if (value instanceof Double) { - builder.put(key, (double) value); - return; - } - if (value instanceof Float) { - builder.put(key, (float) value); - return; - } - if (value instanceof Boolean) { - builder.put(key, (boolean) value); - return; - } - if (value instanceof List) { - List values = (List) value; - if (values.isEmpty()) { - return; - } - Object first = values.get(0); - if (first instanceof String) { - checkAllEntriesOfType(key, values, String.class); - builder.put( - AttributeKey.stringArrayKey(key), - values.stream().map(obj -> (String) obj).toArray(String[]::new)); - return; - } - if (first instanceof Long) { - checkAllEntriesOfType(key, values, Long.class); - builder.put( - AttributeKey.longArrayKey(key), - values.stream().map(obj -> (long) obj).toArray(Long[]::new)); - return; - } - if (first instanceof Integer) { - checkAllEntriesOfType(key, values, Integer.class); - builder.put( - AttributeKey.longArrayKey(key), - values.stream().map(obj -> Long.valueOf((int) obj)).toArray(Long[]::new)); - return; - } - if (first instanceof Double) { - checkAllEntriesOfType(key, values, Double.class); - builder.put( - AttributeKey.doubleArrayKey(key), - values.stream().map(obj -> (double) obj).toArray(Double[]::new)); - return; - } - if (first instanceof Float) { - checkAllEntriesOfType(key, values, Float.class); - builder.put( - AttributeKey.doubleArrayKey(key), - values.stream() - .map(obj -> Double.valueOf((float) obj)) - .toArray(Double[]::new)); - return; - } - if (first instanceof Boolean) { - checkAllEntriesOfType(key, values, Boolean.class); - builder.put( - AttributeKey.booleanArrayKey(key), - values.stream().map(obj -> (Boolean) obj).toArray(Boolean[]::new)); - return; - } - } - throw new ConfigurationException( - "Error processing attribute with key \"" - + key - + "\": unrecognized value type " - + value.getClass().getName()); - }); - - return builder.build(); - } - - private static void checkAllEntriesOfType(String key, List values, Class expectedType) { - values.forEach( - value -> { - if (value == null) { - throw new ConfigurationException( - "Error processing attribute with key \"" - + key - + "\": unexpected null element in value"); - } - if (!expectedType.isAssignableFrom(value.getClass())) { - throw new ConfigurationException( - "Error processing attribute with key \"" - + key - + "\": expected value entries to be of type " - + expectedType - + " but found entry with type " - + value.getClass()); - } - }); - } -} diff --git a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/FileConfiguration.java b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/FileConfiguration.java index 5b1b3dd32f0..76cf9cc1fbe 100644 --- a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/FileConfiguration.java +++ b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/FileConfiguration.java @@ -49,7 +49,7 @@ public final class FileConfiguration { private static final Logger logger = Logger.getLogger(FileConfiguration.class.getName()); private static final Pattern ENV_VARIABLE_REFERENCE = - Pattern.compile("\\$\\{([a-zA-Z_][a-zA-Z0-9_]*)}"); + Pattern.compile("\\$\\{([a-zA-Z_][a-zA-Z0-9_]*)(:-([^\n]*))?\\}"); private static final ComponentLoader DEFAULT_COMPONENT_LOADER = SpiHelper.serviceComponentLoader(FileConfiguration.class.getClassLoader()); @@ -313,7 +313,12 @@ private Object constructValueObject(Node node) { ScalarStyle scalarStyle = ((ScalarNode) node).getScalarStyle(); do { MatchResult matchResult = matcher.toMatchResult(); - String replacement = environmentVariables.getOrDefault(matcher.group(1), ""); + String envVarKey = matcher.group(1); + String defaultValue = matcher.group(3); + if (defaultValue == null) { + defaultValue = ""; + } + String replacement = environmentVariables.getOrDefault(envVarKey, defaultValue); newVal.append(val, offset, matchResult.start()).append(replacement); offset = matchResult.end(); } while (matcher.find()); diff --git a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/LogRecordExporterFactory.java b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/LogRecordExporterFactory.java index 05be1719dbb..e006befe0f7 100644 --- a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/LogRecordExporterFactory.java +++ b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/LogRecordExporterFactory.java @@ -9,6 +9,7 @@ import io.opentelemetry.sdk.autoconfigure.internal.SpiHelper; import io.opentelemetry.sdk.autoconfigure.spi.ConfigurationException; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.ConsoleModel; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.LogRecordExporterModel; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.OtlpModel; import io.opentelemetry.sdk.logs.export.LogRecordExporter; @@ -34,6 +35,11 @@ public LogRecordExporter create( model.getAdditionalProperties().put("otlp", otlpModel); } + ConsoleModel consoleModel = model.getConsole(); + if (consoleModel != null) { + model.getAdditionalProperties().put("console", consoleModel); + } + if (!model.getAdditionalProperties().isEmpty()) { Map additionalProperties = model.getAdditionalProperties(); if (additionalProperties.size() > 1) { diff --git a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/MetricExporterFactory.java b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/MetricExporterFactory.java index cfda507de32..6d9616f8524 100644 --- a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/MetricExporterFactory.java +++ b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/MetricExporterFactory.java @@ -9,14 +9,14 @@ import io.opentelemetry.sdk.autoconfigure.internal.SpiHelper; import io.opentelemetry.sdk.autoconfigure.spi.ConfigurationException; -import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.MetricExporterModel; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.OtlpMetricModel; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.PushMetricExporterModel; import io.opentelemetry.sdk.metrics.export.MetricExporter; import java.io.Closeable; import java.util.List; import java.util.Map; -final class MetricExporterFactory implements Factory { +final class MetricExporterFactory implements Factory { private static final MetricExporterFactory INSTANCE = new MetricExporterFactory(); @@ -28,7 +28,7 @@ static MetricExporterFactory getInstance() { @Override public MetricExporter create( - MetricExporterModel model, SpiHelper spiHelper, List closeables) { + PushMetricExporterModel model, SpiHelper spiHelper, List closeables) { OtlpMetricModel otlpModel = model.getOtlp(); if (otlpModel != null) { model.getAdditionalProperties().put("otlp", otlpModel); @@ -38,10 +38,6 @@ public MetricExporter create( model.getAdditionalProperties().put("console", model.getConsole()); } - if (model.getPrometheus() != null) { - throw new ConfigurationException("prometheus exporter not supported in this context"); - } - if (!model.getAdditionalProperties().isEmpty()) { Map additionalProperties = model.getAdditionalProperties(); if (additionalProperties.size() > 1) { diff --git a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/MetricReaderFactory.java b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/MetricReaderFactory.java index 1041d50ec6c..c30ac774b60 100644 --- a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/MetricReaderFactory.java +++ b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/MetricReaderFactory.java @@ -9,11 +9,12 @@ import io.opentelemetry.sdk.autoconfigure.internal.SpiHelper; import io.opentelemetry.sdk.autoconfigure.spi.ConfigurationException; -import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.MetricExporterModel; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.MetricReaderModel; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.PeriodicMetricReaderModel; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.PrometheusModel; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.PullMetricExporterModel; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.PullMetricReaderModel; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.PushMetricExporterModel; import io.opentelemetry.sdk.metrics.export.MetricReader; import io.opentelemetry.sdk.metrics.export.PeriodicMetricReaderBuilder; import java.io.Closeable; @@ -35,7 +36,7 @@ public MetricReader create( MetricReaderModel model, SpiHelper spiHelper, List closeables) { PeriodicMetricReaderModel periodicModel = model.getPeriodic(); if (periodicModel != null) { - MetricExporterModel exporterModel = + PushMetricExporterModel exporterModel = requireNonNull(periodicModel.getExporter(), "periodic metric reader exporter"); io.opentelemetry.sdk.metrics.export.MetricExporter metricExporter = MetricExporterFactory.getInstance().create(exporterModel, spiHelper, closeables); @@ -50,7 +51,7 @@ public MetricReader create( PullMetricReaderModel pullModel = model.getPull(); if (pullModel != null) { - MetricExporterModel exporterModel = + PullMetricExporterModel exporterModel = requireNonNull(pullModel.getExporter(), "pull metric reader exporter"); PrometheusModel prometheusModel = exporterModel.getPrometheus(); if (prometheusModel != null) { diff --git a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/ResourceFactory.java b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/ResourceFactory.java index bb5540268a8..8f26e6a47e7 100644 --- a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/ResourceFactory.java +++ b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/ResourceFactory.java @@ -5,19 +5,28 @@ package io.opentelemetry.sdk.extension.incubator.fileconfig; +import static io.opentelemetry.sdk.internal.GlobUtil.toGlobPatternPredicate; + +import io.opentelemetry.sdk.autoconfigure.ResourceConfiguration; import io.opentelemetry.sdk.autoconfigure.internal.SpiHelper; import io.opentelemetry.sdk.autoconfigure.spi.ConfigurationException; import io.opentelemetry.sdk.autoconfigure.spi.Ordered; import io.opentelemetry.sdk.autoconfigure.spi.internal.ComponentProvider; +import io.opentelemetry.sdk.autoconfigure.spi.internal.DefaultConfigProperties; import io.opentelemetry.sdk.autoconfigure.spi.internal.StructuredConfigProperties; -import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.AttributesModel; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.AttributeNameValueModel; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.DetectorAttributesModel; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.DetectorsModel; import io.opentelemetry.sdk.resources.Resource; +import io.opentelemetry.sdk.resources.ResourceBuilder; import java.io.Closeable; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.List; +import java.util.function.Predicate; import java.util.stream.Collectors; +import javax.annotation.Nullable; final class ResourceFactory implements Factory< @@ -41,23 +50,39 @@ public Resource create( io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.ResourceModel model, SpiHelper spiHelper, List closeables) { - Resource result = Resource.getDefault(); + ResourceBuilder builder = Resource.getDefault().toBuilder(); + ResourceBuilder detectedResourceBuilder = Resource.builder(); List resourceDetectorResources = loadFromResourceDetectors(spiHelper); for (Resource resourceProviderResource : resourceDetectorResources) { - result = result.merge(resourceProviderResource); + detectedResourceBuilder.putAll(resourceProviderResource); } + Predicate detectorAttributeFilter = detectorAttributeFilter(model.getDetectors()); + builder + .putAll( + detectedResourceBuilder.build().getAttributes().toBuilder() + .removeIf(attributeKey -> !detectorAttributeFilter.test(attributeKey.getKey())) + .build()) + .build(); - AttributesModel attributesModel = model.getAttributes(); - if (attributesModel != null) { - result = - result.toBuilder() - .putAll( - AttributesFactory.getInstance().create(attributesModel, spiHelper, closeables)) - .build(); + String attributeList = model.getAttributesList(); + if (attributeList != null) { + builder.putAll( + ResourceConfiguration.createEnvironmentResource( + DefaultConfigProperties.createFromMap( + Collections.singletonMap("otel.resource.attributes", attributeList)))); } - return result; + List attributeNameValueModel = model.getAttributes(); + if (attributeNameValueModel != null) { + builder + .putAll( + AttributeListFactory.getInstance() + .create(attributeNameValueModel, spiHelper, closeables)) + .build(); + } + + return builder.build(); } /** @@ -115,4 +140,54 @@ private int order() { return order; } } + + private static boolean matchAll(String attributeKey) { + return true; + } + + private static Predicate detectorAttributeFilter( + @Nullable DetectorsModel detectorsModel) { + if (detectorsModel == null) { + return ResourceFactory::matchAll; + } + DetectorAttributesModel detectorAttributesModel = detectorsModel.getAttributes(); + if (detectorAttributesModel == null) { + return ResourceFactory::matchAll; + } + List included = detectorAttributesModel.getIncluded(); + List excluded = detectorAttributesModel.getExcluded(); + if (included == null && excluded == null) { + return ResourceFactory::matchAll; + } + if (included == null) { + return excludedPredicate(excluded); + } + if (excluded == null) { + return includedPredicate(included); + } + return includedPredicate(included).and(excludedPredicate(excluded)); + } + + /** + * Returns a predicate which matches strings matching any of the {@code included} glob patterns. + */ + private static Predicate includedPredicate(List included) { + Predicate result = attributeKey -> false; + for (String include : included) { + result = result.or(toGlobPatternPredicate(include)); + } + return result; + } + + /** + * Returns a predicate which matches strings NOT matching any of the {@code excluded} glob + * patterns. + */ + private static Predicate excludedPredicate(List excluded) { + Predicate result = attributeKey -> true; + for (String exclude : excluded) { + result = result.and(toGlobPatternPredicate(exclude).negate()); + } + return result; + } } diff --git a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/ViewFactory.java b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/ViewFactory.java index fecc4a81c59..38ad79d7669 100644 --- a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/ViewFactory.java +++ b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/ViewFactory.java @@ -6,12 +6,15 @@ package io.opentelemetry.sdk.extension.incubator.fileconfig; import io.opentelemetry.sdk.autoconfigure.internal.SpiHelper; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.IncludeExcludeModel; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.StreamModel; import io.opentelemetry.sdk.metrics.View; import io.opentelemetry.sdk.metrics.ViewBuilder; import java.io.Closeable; import java.util.HashSet; import java.util.List; +import java.util.Set; +import javax.annotation.Nullable; final class ViewFactory implements Factory { @@ -32,8 +35,9 @@ public View create(StreamModel model, SpiHelper spiHelper, List close if (model.getDescription() != null) { builder.setDescription(model.getDescription()); } - if (model.getAttributeKeys() != null) { - builder.setAttributeFilter(new HashSet<>(model.getAttributeKeys())); + IncludeExcludeModel attributeKeys = model.getAttributeKeys(); + if (attributeKeys != null) { + addAttributeKeyFilter(builder, attributeKeys.getIncluded(), attributeKeys.getExcluded()); } if (model.getAggregation() != null) { builder.setAggregation( @@ -41,4 +45,25 @@ public View create(StreamModel model, SpiHelper spiHelper, List close } return builder.build(); } + + private static void addAttributeKeyFilter( + ViewBuilder builder, @Nullable List included, @Nullable List excluded) { + if (included == null && excluded == null) { + return; + } + if (included == null) { + Set excludedKeys = new HashSet<>(excluded); + // TODO: set predicate with useful toString implementation + builder.setAttributeFilter(attributeKey -> !excludedKeys.contains(attributeKey)); + return; + } + if (excluded == null) { + Set includedKeys = new HashSet<>(included); + builder.setAttributeFilter(includedKeys); + return; + } + Set includedKeys = new HashSet<>(included); + excluded.forEach(includedKeys::remove); + builder.setAttributeFilter(includedKeys); + } } diff --git a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/AttributeListFactoryTest.java b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/AttributeListFactoryTest.java new file mode 100644 index 00000000000..59dd61c03cf --- /dev/null +++ b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/AttributeListFactoryTest.java @@ -0,0 +1,140 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.sdk.extension.incubator.fileconfig; + +import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.mockito.Mockito.mock; + +import io.opentelemetry.api.common.Attributes; +import io.opentelemetry.sdk.autoconfigure.internal.SpiHelper; +import io.opentelemetry.sdk.autoconfigure.spi.ConfigurationException; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.AttributeNameValueModel; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import java.util.stream.Stream; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; + +class AttributeListFactoryTest { + + @ParameterizedTest + @MethodSource("invalidAttributes") + void create_InvalidAttributes(List model, String expectedMessage) { + assertThatThrownBy( + () -> + AttributeListFactory.getInstance() + .create(model, mock(SpiHelper.class), Collections.emptyList())) + .isInstanceOf(ConfigurationException.class) + .hasMessageContaining(expectedMessage); + } + + private static Stream invalidAttributes() { + return Stream.of( + Arguments.of( + Collections.singletonList(new AttributeNameValueModel().withName("key")), + "attribute value is required but is null"), + Arguments.of( + Collections.singletonList( + new AttributeNameValueModel().withName("key").withValue(new Object())), + "Error processing attribute with name \"key\": value did not match type STRING"), + Arguments.of( + Collections.singletonList( + new AttributeNameValueModel() + .withName("key") + .withType(AttributeNameValueModel.Type.INT) + .withValue(Arrays.asList(1L, 1))), + "Error processing attribute with name \"key\": value did not match type INT"), + Arguments.of( + Collections.singletonList( + new AttributeNameValueModel() + .withName("key") + .withType(AttributeNameValueModel.Type.INT) + .withValue(true)), + "Error processing attribute with name \"key\": value did not match type INT")); + } + + @Test + void create() { + Attributes expectedAttributes = + Attributes.builder() + .put("service.name", "my-service") + .put("strKey", "val") + .put("longKey", 1L) + .put("intKey", 2) + .put("doubleKey", 1.0d) + .put("floatKey", 2.0f) + .put("boolKey", true) + .put("strArrKey", "val1", "val2") + .put("longArrKey", 1L, 2L) + .put("intArrKey", 1, 2) + .put("doubleArrKey", 1.0d, 2.0d) + .put("floatArrKey", 1.0f, 2.0f) + .put("boolArrKey", true, false) + .build(); + assertThat( + AttributeListFactory.getInstance() + .create( + Arrays.asList( + new AttributeNameValueModel() + .withName("service.name") + .withValue("my-service"), + new AttributeNameValueModel() + .withName("strKey") + .withValue("val") + .withType(AttributeNameValueModel.Type.STRING), + new AttributeNameValueModel() + .withName("longKey") + .withValue(1L) + .withType(AttributeNameValueModel.Type.INT), + new AttributeNameValueModel() + .withName("intKey") + .withValue(2) + .withType(AttributeNameValueModel.Type.INT), + new AttributeNameValueModel() + .withName("doubleKey") + .withValue(1.0d) + .withType(AttributeNameValueModel.Type.DOUBLE), + new AttributeNameValueModel() + .withName("floatKey") + .withValue(2.0f) + .withType(AttributeNameValueModel.Type.DOUBLE), + new AttributeNameValueModel() + .withName("boolKey") + .withValue(true) + .withType(AttributeNameValueModel.Type.BOOL), + new AttributeNameValueModel() + .withName("strArrKey") + .withValue(Arrays.asList("val1", "val2")) + .withType(AttributeNameValueModel.Type.STRING_ARRAY), + new AttributeNameValueModel() + .withName("longArrKey") + .withValue(Arrays.asList(1L, 2L)) + .withType(AttributeNameValueModel.Type.INT_ARRAY), + new AttributeNameValueModel() + .withName("intArrKey") + .withValue(Arrays.asList(1, 2)) + .withType(AttributeNameValueModel.Type.INT_ARRAY), + new AttributeNameValueModel() + .withName("doubleArrKey") + .withValue(Arrays.asList(1.0d, 2.0d)) + .withType(AttributeNameValueModel.Type.DOUBLE_ARRAY), + new AttributeNameValueModel() + .withName("floatArrKey") + .withValue(Arrays.asList(1.0f, 2.0f)) + .withType(AttributeNameValueModel.Type.DOUBLE_ARRAY), + new AttributeNameValueModel() + .withName("boolArrKey") + .withValue(Arrays.asList(true, false)) + .withType(AttributeNameValueModel.Type.BOOL_ARRAY)), + mock(SpiHelper.class), + Collections.emptyList())) + .isEqualTo(expectedAttributes); + } +} diff --git a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/AttributesFactoryTest.java b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/AttributesFactoryTest.java deleted file mode 100644 index 5bd8e42a540..00000000000 --- a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/AttributesFactoryTest.java +++ /dev/null @@ -1,91 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package io.opentelemetry.sdk.extension.incubator.fileconfig; - -import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatThrownBy; -import static org.mockito.Mockito.mock; - -import io.opentelemetry.sdk.autoconfigure.internal.SpiHelper; -import io.opentelemetry.sdk.autoconfigure.spi.ConfigurationException; -import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.AttributesModel; -import java.util.Arrays; -import java.util.Collections; -import java.util.stream.Stream; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.Arguments; -import org.junit.jupiter.params.provider.MethodSource; - -class AttributesFactoryTest { - - @ParameterizedTest - @MethodSource("invalidAttributes") - void create_InvalidAttributes(AttributesModel model, String expectedMessage) { - assertThatThrownBy( - () -> - AttributesFactory.getInstance() - .create(model, mock(SpiHelper.class), Collections.emptyList())) - .isInstanceOf(ConfigurationException.class) - .hasMessageContaining(expectedMessage); - } - - private static Stream invalidAttributes() { - return Stream.of( - Arguments.of( - new AttributesModel().withAdditionalProperty("key", null), - "Error processing attribute with key \"key\": unexpected null value"), - Arguments.of( - new AttributesModel().withAdditionalProperty("key", new Object()), - "Error processing attribute with key \"key\": unrecognized value type java.lang.Object"), - Arguments.of( - new AttributesModel().withAdditionalProperty("key", Arrays.asList(1L, 1)), - "Error processing attribute with key \"key\": expected value entries to be of type class java.lang.Long but found entry with type class java.lang.Integer"), - Arguments.of( - new AttributesModel().withAdditionalProperty("key", Arrays.asList(1L, null)), - "Error processing attribute with key \"key\": unexpected null element in value")); - } - - @Test - void create() { - assertThat( - AttributesFactory.getInstance() - .create( - new AttributesModel() - .withServiceName("my-service") - .withAdditionalProperty("strKey", "val") - .withAdditionalProperty("longKey", 1L) - .withAdditionalProperty("intKey", 2) - .withAdditionalProperty("doubleKey", 1.0d) - .withAdditionalProperty("floatKey", 2.0f) - .withAdditionalProperty("boolKey", true) - .withAdditionalProperty("strArrKey", Arrays.asList("val1", "val2")) - .withAdditionalProperty("longArrKey", Arrays.asList(1L, 2L)) - .withAdditionalProperty("intArrKey", Arrays.asList(1, 2)) - .withAdditionalProperty("doubleArrKey", Arrays.asList(1.0d, 2.0d)) - .withAdditionalProperty("floatArrKey", Arrays.asList(1.0f, 2.0f)) - .withAdditionalProperty("boolArrKey", Arrays.asList(true, false)) - .withAdditionalProperty("emptyArrKey", Collections.emptyList()), - mock(SpiHelper.class), - Collections.emptyList())) - .isEqualTo( - io.opentelemetry.api.common.Attributes.builder() - .put("service.name", "my-service") - .put("strKey", "val") - .put("longKey", 1L) - .put("intKey", 2) - .put("doubleKey", 1.0d) - .put("floatKey", 2.0f) - .put("boolKey", true) - .put("strArrKey", "val1", "val2") - .put("longArrKey", 1L, 2L) - .put("intArrKey", 1, 2) - .put("doubleArrKey", 1.0d, 2.0d) - .put("floatArrKey", 1.0f, 2.0f) - .put("boolArrKey", true, false) - .build()); - } -} diff --git a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/FileConfigurationCreateTest.java b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/FileConfigurationCreateTest.java index 51f70d930ec..d47ae14eb9a 100644 --- a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/FileConfigurationCreateTest.java +++ b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/FileConfigurationCreateTest.java @@ -86,10 +86,7 @@ void parseAndCreate_Examples(@TempDir Path tempDir) "client_key: .*\n", "client_key: " + clientKeyPath + System.lineSeparator()) .replaceAll( "client_certificate: .*\n", - "client_certificate: " + clientCertificatePath + System.lineSeparator()) - // TODO: remove once ComponentProvider SPI implemented in - // https://github.com/open-telemetry/opentelemetry-java-contrib/tree/main/aws-xray-propagator - .replaceAll("xray,", ""); + "client_certificate: " + clientCertificatePath + System.lineSeparator()); InputStream is = new ByteArrayInputStream(rewrittenExampleContent.getBytes(StandardCharsets.UTF_8)); diff --git a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/FileConfigurationParseTest.java b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/FileConfigurationParseTest.java index 0c03bdbd751..81aa6f4487e 100644 --- a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/FileConfigurationParseTest.java +++ b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/FileConfigurationParseTest.java @@ -13,30 +13,45 @@ import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.AlwaysOffModel; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.AlwaysOnModel; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.AttributeLimitsModel; -import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.AttributesModel; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.AttributeNameValueModel; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.BatchLogRecordProcessorModel; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.BatchSpanProcessorModel; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.ClientModel; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.ConsoleModel; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.DetectorAttributesModel; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.DetectorsModel; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.ExplicitBucketHistogramModel; -import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.HeadersModel; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.GeneralInstrumentationModel; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.HttpModel; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.IncludeExcludeModel; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.InstrumentationModel; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.LanguageSpecificInstrumentationModel; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.LogRecordExporterModel; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.LogRecordLimitsModel; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.LogRecordProcessorModel; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.LoggerProviderModel; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.MeterProviderModel; -import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.MetricExporterModel; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.MetricProducerModel; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.MetricReaderModel; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.NameStringValuePairModel; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.OpenTelemetryConfigurationModel; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.OpencensusModel; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.OtlpMetricModel; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.OtlpModel; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.ParentBasedModel; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.PeerModel; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.PeriodicMetricReaderModel; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.PrometheusModel; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.PropagatorModel; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.PullMetricExporterModel; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.PullMetricReaderModel; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.PushMetricExporterModel; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.ResourceModel; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.SamplerModel; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.SelectorModel; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.ServerModel; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.ServiceMappingModel; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.SimpleLogRecordProcessorModel; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.SimpleSpanProcessorModel; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.SpanExporterModel; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.SpanLimitsModel; @@ -83,7 +98,51 @@ void parse_KitchenSinkExampleFile() throws IOException { // General config ResourceModel resource = new ResourceModel() - .withAttributes(new AttributesModel().withServiceName("unknown_service")); + .withAttributes( + Arrays.asList( + new AttributeNameValueModel() + .withName("service.name") + .withValue("unknown_service"), + new AttributeNameValueModel() + .withName("string_key") + .withValue("value") + .withType(AttributeNameValueModel.Type.STRING), + new AttributeNameValueModel() + .withName("bool_key") + .withValue(true) + .withType(AttributeNameValueModel.Type.BOOL), + new AttributeNameValueModel() + .withName("int_key") + .withValue(1) + .withType(AttributeNameValueModel.Type.INT), + new AttributeNameValueModel() + .withName("double_key") + .withValue(1.1) + .withType(AttributeNameValueModel.Type.DOUBLE), + new AttributeNameValueModel() + .withName("string_array_key") + .withValue(Arrays.asList("value1", "value2")) + .withType(AttributeNameValueModel.Type.STRING_ARRAY), + new AttributeNameValueModel() + .withName("bool_array_key") + .withValue(Arrays.asList(true, false)) + .withType(AttributeNameValueModel.Type.BOOL_ARRAY), + new AttributeNameValueModel() + .withName("int_array_key") + .withValue(Arrays.asList(1, 2)) + .withType(AttributeNameValueModel.Type.INT_ARRAY), + new AttributeNameValueModel() + .withName("double_array_key") + .withValue(Arrays.asList(1.1, 2.2)) + .withType(AttributeNameValueModel.Type.DOUBLE_ARRAY))) + .withAttributesList("service.namespace=my-namespace,service.version=1.0.0") + .withDetectors( + new DetectorsModel() + .withAttributes( + new DetectorAttributesModel() + .withIncluded(Collections.singletonList("process.*")) + .withExcluded(Collections.singletonList("process.command_args")))) + .withSchemaUrl("https://opentelemetry.io/schemas/1.16.0"); expected.withResource(resource); AttributeLimitsModel attributeLimits = @@ -138,15 +197,19 @@ void parse_KitchenSinkExampleFile() throws IOException { .withOtlp( new OtlpModel() .withProtocol("http/protobuf") - .withEndpoint("http://localhost:4318") + .withEndpoint("http://localhost:4318/v1/traces") .withCertificate("/app/cert.pem") .withClientKey("/app/cert.pem") .withClientCertificate("/app/cert.pem") .withHeaders( - new HeadersModel() - .withAdditionalProperty("api-key", "1234")) + Collections.singletonList( + new NameStringValuePairModel() + .withName("api-key") + .withValue("1234"))) + .withHeadersList("api-key=1234") .withCompression("gzip") - .withTimeout(10_000)))); + .withTimeout(10_000) + .withInsecure(false)))); SpanProcessorModel spanProcessor2 = new SpanProcessorModel() .withBatch( @@ -174,7 +237,7 @@ void parse_KitchenSinkExampleFile() throws IOException { new LogRecordLimitsModel().withAttributeValueLengthLimit(4096).withAttributeCountLimit(128); loggerProvider.withLimits(logRecordLimits); - LogRecordProcessorModel logRecordProcessor = + LogRecordProcessorModel logRecordProcessor1 = new LogRecordProcessorModel() .withBatch( new BatchLogRecordProcessorModel() @@ -187,16 +250,25 @@ void parse_KitchenSinkExampleFile() throws IOException { .withOtlp( new OtlpModel() .withProtocol("http/protobuf") - .withEndpoint("http://localhost:4318") + .withEndpoint("http://localhost:4318/v1/logs") .withCertificate("/app/cert.pem") .withClientKey("/app/cert.pem") .withClientCertificate("/app/cert.pem") .withHeaders( - new HeadersModel() - .withAdditionalProperty("api-key", "1234")) + Collections.singletonList( + new NameStringValuePairModel() + .withName("api-key") + .withValue("1234"))) + .withHeadersList("api-key=1234") .withCompression("gzip") - .withTimeout(10_000)))); - loggerProvider.withProcessors(Collections.singletonList(logRecordProcessor)); + .withTimeout(10_000) + .withInsecure(false)))); + LogRecordProcessorModel logRecordProcessor2 = + new LogRecordProcessorModel() + .withSimple( + new SimpleLogRecordProcessorModel() + .withExporter(new LogRecordExporterModel().withConsole(new ConsoleModel()))); + loggerProvider.withProcessors(Arrays.asList(logRecordProcessor1, logRecordProcessor2)); expected.withLoggerProvider(loggerProvider); // end LoggerProvider config @@ -209,9 +281,22 @@ void parse_KitchenSinkExampleFile() throws IOException { .withPull( new PullMetricReaderModel() .withExporter( - new MetricExporterModel() + new PullMetricExporterModel() .withPrometheus( - new PrometheusModel().withHost("localhost").withPort(9464)))); + new PrometheusModel() + .withHost("localhost") + .withPort(9464) + .withWithoutUnits(false) + .withWithoutTypeSuffix(false) + .withWithoutScopeInfo(false) + .withWithResourceConstantLabels( + new IncludeExcludeModel() + .withIncluded(Collections.singletonList("service*")) + .withExcluded( + Collections.singletonList("service.attr1")))))) + .withProducers( + Collections.singletonList( + new MetricProducerModel().withOpencensus(new OpencensusModel()))); MetricReaderModel metricReader2 = new MetricReaderModel() .withPeriodic( @@ -219,28 +304,36 @@ void parse_KitchenSinkExampleFile() throws IOException { .withInterval(5_000) .withTimeout(30_000) .withExporter( - new MetricExporterModel() + new PushMetricExporterModel() .withOtlp( new OtlpMetricModel() .withProtocol("http/protobuf") - .withEndpoint("http://localhost:4318") + .withEndpoint("http://localhost:4318/v1/metrics") .withCertificate("/app/cert.pem") .withClientKey("/app/cert.pem") .withClientCertificate("/app/cert.pem") .withHeaders( - new HeadersModel() - .withAdditionalProperty("api-key", "1234")) + Collections.singletonList( + new NameStringValuePairModel() + .withName("api-key") + .withValue("1234"))) + .withHeadersList("api-key=1234") .withCompression("gzip") .withTimeout(10_000) + .withInsecure(false) .withTemporalityPreference("delta") .withDefaultHistogramAggregation( OtlpMetricModel.DefaultHistogramAggregation - .BASE_2_EXPONENTIAL_BUCKET_HISTOGRAM)))); + .BASE_2_EXPONENTIAL_BUCKET_HISTOGRAM)))) + .withProducers( + Collections.singletonList( + new MetricProducerModel() + .withAdditionalProperty("prometheus", Collections.emptyMap()))); MetricReaderModel metricReader3 = new MetricReaderModel() .withPeriodic( new PeriodicMetricReaderModel() - .withExporter(new MetricExporterModel().withConsole(new ConsoleModel()))); + .withExporter(new PushMetricExporterModel().withConsole(new ConsoleModel()))); meterProvider.withReaders(Arrays.asList(metricReader1, metricReader2, metricReader3)); ViewModel view = @@ -266,12 +359,91 @@ void parse_KitchenSinkExampleFile() throws IOException { 0.0, 5.0, 10.0, 25.0, 50.0, 75.0, 100.0, 250.0, 500.0, 750.0, 1000.0, 2500.0, 5000.0, 7500.0, 10000.0)) .withRecordMinMax(true))) - .withAttributeKeys(Arrays.asList("key1", "key2"))); + .withAttributeKeys( + new IncludeExcludeModel() + .withIncluded(Arrays.asList("key1", "key2")) + .withExcluded(Collections.singletonList("key3")))); meterProvider.withViews(Collections.singletonList(view)); expected.withMeterProvider(meterProvider); // end MeterProvider config + // start instrumentation config + InstrumentationModel instrumentation = + new InstrumentationModel() + .withGeneral( + new GeneralInstrumentationModel() + .withPeer( + new PeerModel() + .withServiceMapping( + Arrays.asList( + new ServiceMappingModel() + .withPeer("1.2.3.4") + .withService("FooService"), + new ServiceMappingModel() + .withPeer("2.3.4.5") + .withService("BarService")))) + .withHttp( + new HttpModel() + .withClient( + new ClientModel() + .withRequestCapturedHeaders( + Arrays.asList("Content-Type", "Accept")) + .withResponseCapturedHeaders( + Arrays.asList("Content-Type", "Content-Encoding"))) + .withServer( + new ServerModel() + .withRequestCapturedHeaders( + Arrays.asList("Content-Type", "Accept")) + .withResponseCapturedHeaders( + Arrays.asList("Content-Type", "Content-Encoding"))))) + .withCpp( + new LanguageSpecificInstrumentationModel() + .withAdditionalProperty( + "example", Collections.singletonMap("property", "value"))) + .withDotnet( + new LanguageSpecificInstrumentationModel() + .withAdditionalProperty( + "example", Collections.singletonMap("property", "value"))) + .withErlang( + new LanguageSpecificInstrumentationModel() + .withAdditionalProperty( + "example", Collections.singletonMap("property", "value"))) + .withGo( + new LanguageSpecificInstrumentationModel() + .withAdditionalProperty( + "example", Collections.singletonMap("property", "value"))) + .withJava( + new LanguageSpecificInstrumentationModel() + .withAdditionalProperty( + "example", Collections.singletonMap("property", "value"))) + .withJs( + new LanguageSpecificInstrumentationModel() + .withAdditionalProperty( + "example", Collections.singletonMap("property", "value"))) + .withPhp( + new LanguageSpecificInstrumentationModel() + .withAdditionalProperty( + "example", Collections.singletonMap("property", "value"))) + .withPython( + new LanguageSpecificInstrumentationModel() + .withAdditionalProperty( + "example", Collections.singletonMap("property", "value"))) + .withRuby( + new LanguageSpecificInstrumentationModel() + .withAdditionalProperty( + "example", Collections.singletonMap("property", "value"))) + .withRust( + new LanguageSpecificInstrumentationModel() + .withAdditionalProperty( + "example", Collections.singletonMap("property", "value"))) + .withSwift( + new LanguageSpecificInstrumentationModel() + .withAdditionalProperty( + "example", Collections.singletonMap("property", "value"))); + expected.withInstrumentation(instrumentation); + // end instrumentation config + try (FileInputStream configExampleFile = new FileInputStream(System.getenv("CONFIG_EXAMPLE_DIR") + "/kitchen-sink.yaml")) { OpenTelemetryConfigurationModel config = FileConfiguration.parse(configExampleFile); @@ -293,7 +465,7 @@ void parse_KitchenSinkExampleFile() throws IOException { LoggerProviderModel configLoggerProvider = config.getLoggerProvider(); assertThat(configLoggerProvider.getLimits()).isEqualTo(logRecordLimits); assertThat(configLoggerProvider.getProcessors()) - .isEqualTo(Collections.singletonList(logRecordProcessor)); + .isEqualTo(Arrays.asList(logRecordProcessor1, logRecordProcessor2)); // MeterProvider config MeterProviderModel configMeterProvider = config.getMeterProvider(); @@ -301,6 +473,10 @@ void parse_KitchenSinkExampleFile() throws IOException { .isEqualTo(Arrays.asList(metricReader1, metricReader2, metricReader3)); assertThat(configMeterProvider.getViews()).isEqualTo(Collections.singletonList(view)); + // Instrumentation config + InstrumentationModel configInstrumentation = config.getInstrumentation(); + assertThat(configInstrumentation).isEqualTo(instrumentation); + // All configuration assertThat(config).isEqualTo(expected); } @@ -446,6 +622,15 @@ private static java.util.stream.Stream envVarSubstitutionArgs() { Arguments.of( "key1: ${STR_1} value1\n" + "key2: value2\n", mapOf(entry("key1", "value1 value1"), entry("key2", "value2"))), + // Default cases + Arguments.of("key1: ${NOT_SET:-value1}\n", mapOf(entry("key1", "value1"))), + Arguments.of("key1: ${NOT_SET:-true}\n", mapOf(entry("key1", true))), + Arguments.of("key1: ${NOT_SET:-1}\n", mapOf(entry("key1", 1))), + Arguments.of("key1: ${NOT_SET:-1.1}\n", mapOf(entry("key1", 1.1))), + Arguments.of("key1: ${NOT_SET:-0xdeadbeef}\n", mapOf(entry("key1", 3735928559L))), + Arguments.of( + "key1: ${NOT_SET:-value1} value2\n" + "key2: value2\n", + mapOf(entry("key1", "value1 value2"), entry("key2", "value2"))), // Multiple environment variables referenced Arguments.of("key1: ${STR_1}${STR_2}\n", mapOf(entry("key1", "value1value2"))), Arguments.of("key1: ${STR_1} ${STR_2}\n", mapOf(entry("key1", "value1 value2"))), diff --git a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/LogRecordExporterFactoryTest.java b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/LogRecordExporterFactoryTest.java index e826411feee..a9d9e4019c9 100644 --- a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/LogRecordExporterFactoryTest.java +++ b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/LogRecordExporterFactoryTest.java @@ -13,7 +13,6 @@ import static org.mockito.Mockito.verify; import com.google.common.collect.ImmutableMap; -import com.google.common.collect.ImmutableSet; import com.linecorp.armeria.testing.junit5.server.SelfSignedCertificateExtension; import io.opentelemetry.exporter.otlp.http.logs.OtlpHttpLogRecordExporter; import io.opentelemetry.exporter.otlp.logs.OtlpGrpcLogRecordExporter; @@ -22,8 +21,8 @@ import io.opentelemetry.sdk.autoconfigure.spi.ConfigurationException; import io.opentelemetry.sdk.autoconfigure.spi.internal.StructuredConfigProperties; import io.opentelemetry.sdk.extension.incubator.fileconfig.component.LogRecordExporterComponentProvider; -import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.HeadersModel; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.LogRecordExporterModel; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.NameStringValuePairModel; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.OtlpModel; import io.opentelemetry.sdk.logs.export.LogRecordExporter; import java.io.Closeable; @@ -32,6 +31,7 @@ import java.security.cert.CertificateEncodingException; import java.time.Duration; import java.util.ArrayList; +import java.util.Arrays; import java.util.List; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; @@ -127,11 +127,15 @@ void create_OtlpConfigured(@TempDir Path tempDir) .withOtlp( new OtlpModel() .withProtocol("http/protobuf") - .withEndpoint("http://example:4318") + .withEndpoint("http://example:4318/v1/logs") .withHeaders( - new HeadersModel() - .withAdditionalProperty("key1", "value1") - .withAdditionalProperty("key2", "value2")) + Arrays.asList( + new NameStringValuePairModel() + .withName("key1") + .withValue("value1"), + new NameStringValuePairModel() + .withName("key2") + .withValue("value2"))) .withCompression("gzip") .withTimeout(15_000) .withCertificate(certificatePath) @@ -150,12 +154,19 @@ void create_OtlpConfigured(@TempDir Path tempDir) .loadComponent(eq(LogRecordExporter.class), eq("otlp"), configCaptor.capture()); StructuredConfigProperties configProperties = configCaptor.getValue(); assertThat(configProperties.getString("protocol")).isEqualTo("http/protobuf"); - assertThat(configProperties.getString("endpoint")).isEqualTo("http://example:4318"); - StructuredConfigProperties headers = configProperties.getStructured("headers"); - assertThat(headers).isNotNull(); - assertThat(headers.getPropertyKeys()).isEqualTo(ImmutableSet.of("key1", "key2")); - assertThat(headers.getString("key1")).isEqualTo("value1"); - assertThat(headers.getString("key2")).isEqualTo("value2"); + assertThat(configProperties.getString("endpoint")).isEqualTo("http://example:4318/v1/logs"); + List headers = configProperties.getStructuredList("headers"); + assertThat(headers) + .isNotNull() + .satisfiesExactly( + header -> { + assertThat(header.getString("name")).isEqualTo("key1"); + assertThat(header.getString("value")).isEqualTo("value1"); + }, + header -> { + assertThat(header.getString("name")).isEqualTo("key2"); + assertThat(header.getString("value")).isEqualTo("value2"); + }); assertThat(configProperties.getString("compression")).isEqualTo("gzip"); assertThat(configProperties.getInt("timeout")).isEqualTo(Duration.ofSeconds(15).toMillis()); assertThat(configProperties.getString("certificate")).isEqualTo(certificatePath); diff --git a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/MeterProviderFactoryTest.java b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/MeterProviderFactoryTest.java index 8094bb639c0..c84e0744992 100644 --- a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/MeterProviderFactoryTest.java +++ b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/MeterProviderFactoryTest.java @@ -11,10 +11,10 @@ import io.opentelemetry.internal.testing.CleanupExtension; import io.opentelemetry.sdk.autoconfigure.internal.SpiHelper; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.MeterProviderModel; -import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.MetricExporterModel; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.MetricReaderModel; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.OtlpMetricModel; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.PeriodicMetricReaderModel; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.PushMetricExporterModel; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.SelectorModel; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.StreamModel; import io.opentelemetry.sdk.metrics.InstrumentSelector; @@ -75,7 +75,7 @@ void create_Configured() { .withPeriodic( new PeriodicMetricReaderModel() .withExporter( - new MetricExporterModel() + new PushMetricExporterModel() .withOtlp(new OtlpMetricModel()))))) .withViews( Collections.singletonList( diff --git a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/MetricExporterFactoryTest.java b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/MetricExporterFactoryTest.java index 3707a2d582c..4f8b47f2e0c 100644 --- a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/MetricExporterFactoryTest.java +++ b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/MetricExporterFactoryTest.java @@ -13,7 +13,6 @@ import static org.mockito.Mockito.verify; import com.google.common.collect.ImmutableMap; -import com.google.common.collect.ImmutableSet; import com.linecorp.armeria.testing.junit5.server.SelfSignedCertificateExtension; import io.opentelemetry.exporter.logging.LoggingMetricExporter; import io.opentelemetry.exporter.otlp.http.metrics.OtlpHttpMetricExporter; @@ -24,9 +23,8 @@ import io.opentelemetry.sdk.autoconfigure.spi.internal.StructuredConfigProperties; import io.opentelemetry.sdk.extension.incubator.fileconfig.component.MetricExporterComponentProvider; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.ConsoleModel; -import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.HeadersModel; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.NameStringValuePairModel; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.OtlpMetricModel; -import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.PrometheusModel; import io.opentelemetry.sdk.metrics.Aggregation; import io.opentelemetry.sdk.metrics.InstrumentType; import io.opentelemetry.sdk.metrics.export.AggregationTemporalitySelector; @@ -38,6 +36,7 @@ import java.security.cert.CertificateEncodingException; import java.time.Duration; import java.util.ArrayList; +import java.util.Arrays; import java.util.List; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; @@ -73,7 +72,7 @@ void create_OtlpDefaults() { MetricExporterFactory.getInstance() .create( new io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model - .MetricExporterModel() + .PushMetricExporterModel() .withOtlp(new OtlpMetricModel()), spiHelper, closeables); @@ -131,15 +130,19 @@ void create_OtlpConfigured(@TempDir Path tempDir) MetricExporterFactory.getInstance() .create( new io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model - .MetricExporterModel() + .PushMetricExporterModel() .withOtlp( new OtlpMetricModel() .withProtocol("http/protobuf") - .withEndpoint("http://example:4318") + .withEndpoint("http://example:4318/v1/metrics") .withHeaders( - new HeadersModel() - .withAdditionalProperty("key1", "value1") - .withAdditionalProperty("key2", "value2")) + Arrays.asList( + new NameStringValuePairModel() + .withName("key1") + .withValue("value1"), + new NameStringValuePairModel() + .withName("key2") + .withValue("value2"))) .withCompression("gzip") .withTimeout(15_000) .withCertificate(certificatePath) @@ -161,12 +164,19 @@ void create_OtlpConfigured(@TempDir Path tempDir) verify(spiHelper).loadComponent(eq(MetricExporter.class), eq("otlp"), configCaptor.capture()); StructuredConfigProperties configProperties = configCaptor.getValue(); assertThat(configProperties.getString("protocol")).isEqualTo("http/protobuf"); - assertThat(configProperties.getString("endpoint")).isEqualTo("http://example:4318"); - StructuredConfigProperties headers = configProperties.getStructured("headers"); - assertThat(headers).isNotNull(); - assertThat(headers.getPropertyKeys()).isEqualTo(ImmutableSet.of("key1", "key2")); - assertThat(headers.getString("key1")).isEqualTo("value1"); - assertThat(headers.getString("key2")).isEqualTo("value2"); + assertThat(configProperties.getString("endpoint")).isEqualTo("http://example:4318/v1/metrics"); + List headers = configProperties.getStructuredList("headers"); + assertThat(headers) + .isNotNull() + .satisfiesExactly( + header -> { + assertThat(header.getString("name")).isEqualTo("key1"); + assertThat(header.getString("value")).isEqualTo("value1"); + }, + header -> { + assertThat(header.getString("name")).isEqualTo("key2"); + assertThat(header.getString("value")).isEqualTo("value2"); + }); assertThat(configProperties.getString("compression")).isEqualTo("gzip"); assertThat(configProperties.getInt("timeout")).isEqualTo(Duration.ofSeconds(15).toMillis()); assertThat(configProperties.getString("certificate")).isEqualTo(certificatePath); @@ -188,7 +198,7 @@ void create_Console() { MetricExporterFactory.getInstance() .create( new io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model - .MetricExporterModel() + .PushMetricExporterModel() .withConsole(new ConsoleModel()), spiHelper, closeables); @@ -198,24 +208,6 @@ void create_Console() { assertThat(exporter.toString()).isEqualTo(expectedExporter.toString()); } - @Test - void create_PrometheusExporter() { - List closeables = new ArrayList<>(); - - assertThatThrownBy( - () -> - MetricExporterFactory.getInstance() - .create( - new io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model - .MetricExporterModel() - .withPrometheus(new PrometheusModel()), - spiHelper, - closeables)) - .isInstanceOf(ConfigurationException.class) - .hasMessage("prometheus exporter not supported in this context"); - cleanup.addCloseables(closeables); - } - @Test void create_SpiExporter_Unknown() { assertThatThrownBy( @@ -223,7 +215,7 @@ void create_SpiExporter_Unknown() { MetricExporterFactory.getInstance() .create( new io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model - .MetricExporterModel() + .PushMetricExporterModel() .withAdditionalProperty( "unknown_key", ImmutableMap.of("key1", "value1")), spiHelper, @@ -239,7 +231,7 @@ void create_SpiExporter_Valid() { MetricExporterFactory.getInstance() .create( new io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model - .MetricExporterModel() + .PushMetricExporterModel() .withAdditionalProperty("test", ImmutableMap.of("key1", "value1")), spiHelper, new ArrayList<>()); diff --git a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/MetricReaderFactoryTest.java b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/MetricReaderFactoryTest.java index 976bb6da3a2..cde7a9db49b 100644 --- a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/MetricReaderFactoryTest.java +++ b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/MetricReaderFactoryTest.java @@ -17,12 +17,13 @@ import io.opentelemetry.sdk.autoconfigure.internal.SpiHelper; import io.opentelemetry.sdk.autoconfigure.spi.ConfigurationException; import io.opentelemetry.sdk.autoconfigure.spi.internal.ComponentProvider; -import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.MetricExporterModel; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.MetricReaderModel; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.OtlpMetricModel; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.PeriodicMetricReaderModel; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.PrometheusModel; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.PullMetricExporterModel; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.PullMetricReaderModel; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.PushMetricExporterModel; import java.io.Closeable; import java.io.IOException; import java.net.ServerSocket; @@ -72,7 +73,7 @@ void create_PeriodicDefaults() { .withPeriodic( new PeriodicMetricReaderModel() .withExporter( - new MetricExporterModel().withOtlp(new OtlpMetricModel()))), + new PushMetricExporterModel().withOtlp(new OtlpMetricModel()))), spiHelper, closeables); cleanup.addCloseable(reader); @@ -97,7 +98,8 @@ void create_PeriodicConfigured() { new MetricReaderModel() .withPeriodic( new PeriodicMetricReaderModel() - .withExporter(new MetricExporterModel().withOtlp(new OtlpMetricModel())) + .withExporter( + new PushMetricExporterModel().withOtlp(new OtlpMetricModel())) .withInterval(1)), spiHelper, closeables); @@ -123,7 +125,7 @@ void create_PullPrometheusDefault() throws IOException { .withPull( new PullMetricReaderModel() .withExporter( - new MetricExporterModel() + new PullMetricExporterModel() .withPrometheus(new PrometheusModel().withPort(port)))), spiHelper, closeables); @@ -153,7 +155,7 @@ void create_PullPrometheusConfigured() throws IOException { .withPull( new PullMetricReaderModel() .withExporter( - new MetricExporterModel() + new PullMetricExporterModel() .withPrometheus( new PrometheusModel() .withHost("localhost") @@ -187,21 +189,7 @@ void create_InvalidPullReader() { new MetricReaderModel() .withPull( new PullMetricReaderModel() - .withExporter(new MetricExporterModel())), - spiHelper, - Collections.emptyList())) - .isInstanceOf(ConfigurationException.class) - .hasMessage("prometheus is the only currently supported pull reader"); - - assertThatThrownBy( - () -> - MetricReaderFactory.getInstance() - .create( - new MetricReaderModel() - .withPull( - new PullMetricReaderModel() - .withExporter( - new MetricExporterModel().withOtlp(new OtlpMetricModel()))), + .withExporter(new PullMetricExporterModel())), spiHelper, Collections.emptyList())) .isInstanceOf(ConfigurationException.class) diff --git a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/OpenTelemetryConfigurationFactoryTest.java b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/OpenTelemetryConfigurationFactoryTest.java index 247e5932a23..0284a16bac4 100644 --- a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/OpenTelemetryConfigurationFactoryTest.java +++ b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/OpenTelemetryConfigurationFactoryTest.java @@ -24,7 +24,7 @@ import io.opentelemetry.sdk.autoconfigure.internal.SpiHelper; import io.opentelemetry.sdk.autoconfigure.spi.ConfigurationException; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.AlwaysOnModel; -import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.AttributesModel; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.AttributeNameValueModel; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.BatchLogRecordProcessorModel; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.BatchSpanProcessorModel; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.LogRecordExporterModel; @@ -32,13 +32,13 @@ import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.LogRecordProcessorModel; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.LoggerProviderModel; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.MeterProviderModel; -import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.MetricExporterModel; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.MetricReaderModel; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.OpenTelemetryConfigurationModel; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.OtlpMetricModel; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.OtlpModel; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.PeriodicMetricReaderModel; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.PropagatorModel; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.PushMetricExporterModel; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.ResourceModel; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.SamplerModel; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.SelectorModel; @@ -222,9 +222,13 @@ void create_Configured() { .withResource( new ResourceModel() .withAttributes( - new AttributesModel() - .withServiceName("my-service") - .withAdditionalProperty("key", "val"))) + Arrays.asList( + new AttributeNameValueModel() + .withName("service.name") + .withValue("my-service"), + new AttributeNameValueModel() + .withName("key") + .withValue("val")))) .withLoggerProvider( new LoggerProviderModel() .withLimits( @@ -267,7 +271,7 @@ void create_Configured() { .withPeriodic( new PeriodicMetricReaderModel() .withExporter( - new MetricExporterModel() + new PushMetricExporterModel() .withOtlp(new OtlpMetricModel()))))) .withViews( Collections.singletonList( diff --git a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/ResourceFactoryTest.java b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/ResourceFactoryTest.java index d567d7f45e4..e863a4ecb51 100644 --- a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/ResourceFactoryTest.java +++ b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/ResourceFactoryTest.java @@ -9,11 +9,20 @@ import static org.mockito.Mockito.spy; import io.opentelemetry.sdk.autoconfigure.internal.SpiHelper; -import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.AttributesModel; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.AttributeNameValueModel; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.DetectorAttributesModel; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.DetectorsModel; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.ResourceModel; import io.opentelemetry.sdk.resources.Resource; +import java.util.Arrays; import java.util.Collections; +import java.util.List; +import java.util.stream.Stream; +import javax.annotation.Nullable; import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; class ResourceFactoryTest { @@ -27,11 +36,14 @@ void create() { .create( new ResourceModel() .withAttributes( - new AttributesModel() - .withServiceName("my-service") - .withAdditionalProperty("key", "val") - // Should override shape attribute from ResourceComponentProvider - .withAdditionalProperty("shape", "circle")), + Arrays.asList( + new AttributeNameValueModel() + .withName("service.name") + .withValue("my-service"), + new AttributeNameValueModel().withName("key").withValue("val"), + new AttributeNameValueModel() + .withName("shape") + .withValue("circle"))), spiHelper, Collections.emptyList())) .isEqualTo( @@ -46,4 +58,86 @@ void create() { .put("order", "second") .build()); } + + @ParameterizedTest + @MethodSource("createWithDetectorsArgs") + void createWithDetectors( + @Nullable List included, @Nullable List excluded, Resource expectedResource) { + ResourceModel resourceModel = + new ResourceModel() + .withDetectors( + new DetectorsModel() + .withAttributes( + new DetectorAttributesModel() + .withIncluded(included) + .withExcluded(excluded))); + Resource resource = + ResourceFactory.getInstance().create(resourceModel, spiHelper, Collections.emptyList()); + assertThat(resource).isEqualTo(expectedResource); + } + + private static Stream createWithDetectorsArgs() { + return Stream.of( + Arguments.of( + null, + null, + Resource.getDefault().toBuilder() + .put("color", "red") + .put("shape", "square") + .put("order", "second") + .build()), + Arguments.of( + Collections.singletonList("color"), + null, + Resource.getDefault().toBuilder().put("color", "red").build()), + Arguments.of( + Arrays.asList("color", "shape"), + null, + Resource.getDefault().toBuilder().put("color", "red").put("shape", "square").build()), + Arguments.of( + null, + Collections.singletonList("color"), + Resource.getDefault().toBuilder() + .put("shape", "square") + .put("order", "second") + .build()), + Arguments.of( + null, + Arrays.asList("color", "shape"), + Resource.getDefault().toBuilder().put("order", "second").build()), + Arguments.of( + Collections.singletonList("color"), + Collections.singletonList("color"), + Resource.getDefault().toBuilder().build()), + Arguments.of( + Arrays.asList("color", "shape"), + Collections.singletonList("color"), + Resource.getDefault().toBuilder().put("shape", "square").build()), + Arguments.of( + Collections.singletonList("c*"), + null, + Resource.getDefault().toBuilder().put("color", "red").build()), + Arguments.of( + Collections.singletonList("c?lor"), + null, + Resource.getDefault().toBuilder().put("color", "red").build()), + Arguments.of( + null, + Collections.singletonList("c*"), + Resource.getDefault().toBuilder() + .put("shape", "square") + .put("order", "second") + .build()), + Arguments.of( + null, + Collections.singletonList("c?lor"), + Resource.getDefault().toBuilder() + .put("shape", "square") + .put("order", "second") + .build()), + Arguments.of( + Collections.singletonList("*o*"), + Collections.singletonList("order"), + Resource.getDefault().toBuilder().put("color", "red").build())); + } } diff --git a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/SpanExporterFactoryTest.java b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/SpanExporterFactoryTest.java index 942c9f4352e..a6edf4039f1 100644 --- a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/SpanExporterFactoryTest.java +++ b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/SpanExporterFactoryTest.java @@ -13,7 +13,6 @@ import static org.mockito.Mockito.verify; import com.google.common.collect.ImmutableMap; -import com.google.common.collect.ImmutableSet; import com.linecorp.armeria.testing.junit5.server.SelfSignedCertificateExtension; import io.opentelemetry.exporter.logging.LoggingSpanExporter; import io.opentelemetry.exporter.otlp.http.trace.OtlpHttpSpanExporter; @@ -25,7 +24,7 @@ import io.opentelemetry.sdk.autoconfigure.spi.internal.StructuredConfigProperties; import io.opentelemetry.sdk.extension.incubator.fileconfig.component.SpanExporterComponentProvider; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.ConsoleModel; -import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.HeadersModel; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.NameStringValuePairModel; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.OtlpModel; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.ZipkinModel; import io.opentelemetry.sdk.trace.export.SpanExporter; @@ -35,6 +34,7 @@ import java.security.cert.CertificateEncodingException; import java.time.Duration; import java.util.ArrayList; +import java.util.Arrays; import java.util.List; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; @@ -126,11 +126,15 @@ void create_OtlpConfigured(@TempDir Path tempDir) .withOtlp( new OtlpModel() .withProtocol("http/protobuf") - .withEndpoint("http://example:4318") + .withEndpoint("http://example:4318/v1/traces") .withHeaders( - new HeadersModel() - .withAdditionalProperty("key1", "value1") - .withAdditionalProperty("key2", "value2")) + Arrays.asList( + new NameStringValuePairModel() + .withName("key1") + .withValue("value1"), + new NameStringValuePairModel() + .withName("key2") + .withValue("value2"))) .withCompression("gzip") .withTimeout(15_000) .withCertificate(certificatePath) @@ -148,12 +152,19 @@ void create_OtlpConfigured(@TempDir Path tempDir) verify(spiHelper).loadComponent(eq(SpanExporter.class), eq("otlp"), configCaptor.capture()); StructuredConfigProperties configProperties = configCaptor.getValue(); assertThat(configProperties.getString("protocol")).isEqualTo("http/protobuf"); - assertThat(configProperties.getString("endpoint")).isEqualTo("http://example:4318"); - StructuredConfigProperties headers = configProperties.getStructured("headers"); - assertThat(headers).isNotNull(); - assertThat(headers.getPropertyKeys()).isEqualTo(ImmutableSet.of("key1", "key2")); - assertThat(headers.getString("key1")).isEqualTo("value1"); - assertThat(headers.getString("key2")).isEqualTo("value2"); + assertThat(configProperties.getString("endpoint")).isEqualTo("http://example:4318/v1/traces"); + List headers = configProperties.getStructuredList("headers"); + assertThat(headers) + .isNotNull() + .satisfiesExactly( + header -> { + assertThat(header.getString("name")).isEqualTo("key1"); + assertThat(header.getString("value")).isEqualTo("value1"); + }, + header -> { + assertThat(header.getString("name")).isEqualTo("key2"); + assertThat(header.getString("value")).isEqualTo("value2"); + }); assertThat(configProperties.getString("compression")).isEqualTo("gzip"); assertThat(configProperties.getInt("timeout")).isEqualTo(Duration.ofSeconds(15).toMillis()); assertThat(configProperties.getString("certificate")).isEqualTo(certificatePath); diff --git a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/ViewFactoryTest.java b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/ViewFactoryTest.java index 3e09caa4ad9..9196b354bf3 100644 --- a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/ViewFactoryTest.java +++ b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/ViewFactoryTest.java @@ -11,6 +11,7 @@ import io.opentelemetry.sdk.autoconfigure.internal.SpiHelper; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.AggregationModel; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.ExplicitBucketHistogramModel; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.IncludeExcludeModel; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.StreamModel; import io.opentelemetry.sdk.metrics.View; import java.util.Arrays; @@ -52,7 +53,8 @@ void create() { new StreamModel() .withName("name") .withDescription("description") - .withAttributeKeys(Arrays.asList("foo", "bar")) + .withAttributeKeys( + new IncludeExcludeModel().withIncluded(Arrays.asList("foo", "bar"))) .withAggregation( new AggregationModel() .withExplicitBucketHistogram( diff --git a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/YamlStructuredConfigPropertiesTest.java b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/YamlStructuredConfigPropertiesTest.java index 7e6ba27b522..2e64e93fe94 100644 --- a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/YamlStructuredConfigPropertiesTest.java +++ b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/YamlStructuredConfigPropertiesTest.java @@ -26,7 +26,8 @@ class YamlStructuredConfigPropertiesTest { + "\n" + "resource:\n" + " attributes:\n" - + " service.name: \"unknown_service\"\n" + + " - name: service.name\n" + + " value: \"unknown_service\"\n" + "\n" + "other:\n" + " str_key: str_value\n" @@ -70,9 +71,15 @@ void configurationSchema() { assertThat(structuredConfigProps.getString("file_format")).isEqualTo("0.1"); StructuredConfigProperties resourceProps = structuredConfigProps.getStructured("resource"); assertThat(resourceProps).isNotNull(); - StructuredConfigProperties resourceAttributesProps = resourceProps.getStructured("attributes"); - assertThat(resourceAttributesProps).isNotNull(); - assertThat(resourceAttributesProps.getString("service.name")).isEqualTo("unknown_service"); + List resourceAttributesList = + resourceProps.getStructuredList("attributes"); + assertThat(resourceAttributesList) + .isNotNull() + .satisfiesExactly( + attributeEntry -> { + assertThat(attributeEntry.getString("name")).isEqualTo("service.name"); + assertThat(attributeEntry.getString("value")).isEqualTo("unknown_service"); + }); } @Test From 46b28eb45e617a94ad8a1e322b7ca74206d52870 Mon Sep 17 00:00:00 2001 From: viveksing Date: Mon, 30 Sep 2024 21:13:09 +0200 Subject: [PATCH 585/901] Fix ottracepropagation for short span ids (#6734) --- .../extension/trace/propagation/Common.java | 4 +- .../trace/propagation/OtTracePropagator.java | 10 ++++- .../propagation/OtTracePropagatorTest.java | 41 +++++++++++++++++++ 3 files changed, 53 insertions(+), 2 deletions(-) diff --git a/extensions/trace-propagators/src/main/java/io/opentelemetry/extension/trace/propagation/Common.java b/extensions/trace-propagators/src/main/java/io/opentelemetry/extension/trace/propagation/Common.java index aabbc190e03..9d04262e7d1 100644 --- a/extensions/trace-propagators/src/main/java/io/opentelemetry/extension/trace/propagation/Common.java +++ b/extensions/trace-propagators/src/main/java/io/opentelemetry/extension/trace/propagation/Common.java @@ -29,6 +29,8 @@ final class Common { static final int MAX_TRACE_ID_LENGTH = TraceId.getLength(); static final int MIN_TRACE_ID_LENGTH = MAX_TRACE_ID_LENGTH / 2; + static final int MAX_SPAN_ID_LENGTH = SpanId.getLength(); + private Common() {} static SpanContext buildSpanContext( @@ -44,7 +46,7 @@ static SpanContext buildSpanContext( return SpanContext.createFromRemoteParent( StringUtils.padLeft(traceId, MAX_TRACE_ID_LENGTH), - spanId, + StringUtils.padLeft(spanId, MAX_SPAN_ID_LENGTH), traceFlags, TraceState.getDefault()); } catch (RuntimeException e) { diff --git a/extensions/trace-propagators/src/main/java/io/opentelemetry/extension/trace/propagation/OtTracePropagator.java b/extensions/trace-propagators/src/main/java/io/opentelemetry/extension/trace/propagation/OtTracePropagator.java index 105c3830c7e..3106382abd4 100644 --- a/extensions/trace-propagators/src/main/java/io/opentelemetry/extension/trace/propagation/OtTracePropagator.java +++ b/extensions/trace-propagators/src/main/java/io/opentelemetry/extension/trace/propagation/OtTracePropagator.java @@ -5,6 +5,7 @@ package io.opentelemetry.extension.trace.propagation; +import static io.opentelemetry.extension.trace.propagation.Common.MAX_SPAN_ID_LENGTH; import static io.opentelemetry.extension.trace.propagation.Common.MAX_TRACE_ID_LENGTH; import io.opentelemetry.api.baggage.Baggage; @@ -12,6 +13,7 @@ import io.opentelemetry.api.internal.StringUtils; import io.opentelemetry.api.trace.Span; import io.opentelemetry.api.trace.SpanContext; +import io.opentelemetry.api.trace.SpanId; import io.opentelemetry.api.trace.TraceId; import io.opentelemetry.context.Context; import io.opentelemetry.context.propagation.TextMapGetter; @@ -96,7 +98,13 @@ public Context extract(Context context, @Nullable C carrier, TextMapGetter> setter = Map::put; private static final TextMapGetter> getter = new TextMapGetter>() { @@ -261,6 +263,45 @@ void extract_NotSampledContext_Short_TraceId() { SHORT_TRACE_ID_FULL, SPAN_ID, TraceFlags.getDefault(), TraceState.getDefault())); } + @Test + void extract_SampledContext_Int_Short_SPanId() { + Map carrier = new LinkedHashMap<>(); + carrier.put(OtTracePropagator.TRACE_ID_HEADER, TRACE_ID); + carrier.put(OtTracePropagator.SPAN_ID_HEADER, SHORT_SPAN_ID); + carrier.put(OtTracePropagator.SAMPLED_HEADER, Common.TRUE_INT); + + assertThat(getSpanContext(propagator.extract(Context.current(), carrier, getter))) + .isEqualTo( + SpanContext.createFromRemoteParent( + TRACE_ID, SHORT_SPAN_ID_FULL, TraceFlags.getSampled(), TraceState.getDefault())); + } + + @Test + void extract_SampledContext_Bool_Short_SpanId() { + Map carrier = new LinkedHashMap<>(); + carrier.put(OtTracePropagator.TRACE_ID_HEADER, TRACE_ID); + carrier.put(OtTracePropagator.SPAN_ID_HEADER, SHORT_SPAN_ID); + carrier.put(OtTracePropagator.SAMPLED_HEADER, "true"); + + assertThat(getSpanContext(propagator.extract(Context.current(), carrier, getter))) + .isEqualTo( + SpanContext.createFromRemoteParent( + TRACE_ID, SHORT_SPAN_ID_FULL, TraceFlags.getSampled(), TraceState.getDefault())); + } + + @Test + void extract_NotSampledContext_Short_SpanId() { + Map carrier = new LinkedHashMap<>(); + carrier.put(OtTracePropagator.TRACE_ID_HEADER, TRACE_ID); + carrier.put(OtTracePropagator.SPAN_ID_HEADER, SHORT_SPAN_ID); + carrier.put(OtTracePropagator.SAMPLED_HEADER, Common.FALSE_INT); + + assertThat(getSpanContext(propagator.extract(Context.current(), carrier, getter))) + .isEqualTo( + SpanContext.createFromRemoteParent( + TRACE_ID, SHORT_SPAN_ID_FULL, TraceFlags.getDefault(), TraceState.getDefault())); + } + @Test void extract_InvalidTraceId() { Map invalidHeaders = new LinkedHashMap<>(); From 94b7d2590504f894f3335a502fcaa3444d43b535 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 30 Sep 2024 14:14:02 -0500 Subject: [PATCH 586/901] chore(deps): update dependency gradle to v8.10.2 (#6742) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- gradle/wrapper/gradle-wrapper.properties | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 8e876e1c557..fb602ee2af0 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,7 +1,7 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionSha256Sum=1541fa36599e12857140465f3c91a97409b4512501c26f9631fb113e392c5bd1 -distributionUrl=https\://services.gradle.org/distributions/gradle-8.10.1-bin.zip +distributionSha256Sum=31c55713e40233a8303827ceb42ca48a47267a0ad4bab9177123121e71524c26 +distributionUrl=https\://services.gradle.org/distributions/gradle-8.10.2-bin.zip networkTimeout=10000 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME From d904b133e4bbebab1cef1287025567e6541c5fa7 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 30 Sep 2024 14:14:19 -0500 Subject: [PATCH 587/901] fix(deps): update dependency com.google.guava:guava to v33.3.1-jre (#6743) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- buildSrc/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts index d2cd29c3bfd..7c7314b3140 100644 --- a/buildSrc/build.gradle.kts +++ b/buildSrc/build.gradle.kts @@ -55,7 +55,7 @@ dependencies { // When updating, update above in plugins too implementation("com.diffplug.spotless:spotless-plugin-gradle:6.25.0") // Needed for japicmp but not automatically brought in for some reason. - implementation("com.google.guava:guava:33.3.0-jre") + implementation("com.google.guava:guava:33.3.1-jre") implementation("com.squareup:javapoet:1.13.0") implementation("com.squareup.wire:wire-compiler") implementation("com.squareup.wire:wire-gradle-plugin") From fa7db47889d7deb2bdce344ba2a2201767c48970 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 30 Sep 2024 14:14:37 -0500 Subject: [PATCH 588/901] fix(deps): update dependency checkstyle to v10.18.2 (#6753) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- buildSrc/src/main/kotlin/otel.java-conventions.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/buildSrc/src/main/kotlin/otel.java-conventions.gradle.kts b/buildSrc/src/main/kotlin/otel.java-conventions.gradle.kts index c357dddc847..79d9311c37b 100644 --- a/buildSrc/src/main/kotlin/otel.java-conventions.gradle.kts +++ b/buildSrc/src/main/kotlin/otel.java-conventions.gradle.kts @@ -42,7 +42,7 @@ java { checkstyle { configDirectory.set(file("$rootDir/buildscripts/")) - toolVersion = "10.18.1" + toolVersion = "10.18.2" isIgnoreFailures = false configProperties["rootDir"] = rootDir } From de6efccb999f55bb877e3a85c58a1223faf6d9e5 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 30 Sep 2024 14:15:04 -0500 Subject: [PATCH 589/901] fix(deps): update dependency nl.jqno.equalsverifier:equalsverifier to v3.17 (#6745) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- dependencyManagement/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index 9a6f015b098..965150b923f 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -73,7 +73,7 @@ val DEPENDENCIES = listOf( "io.opentracing:opentracing-noop:0.33.0", "io.prometheus:prometheus-metrics-exporter-httpserver:1.3.1", "junit:junit:4.13.2", - "nl.jqno.equalsverifier:equalsverifier:3.16.2", + "nl.jqno.equalsverifier:equalsverifier:3.17", "org.awaitility:awaitility:4.2.2", "org.bouncycastle:bcpkix-jdk15on:1.70", "org.codehaus.mojo:animal-sniffer-annotations:1.24", From 184685536e4859175091188685ec4e5887719ca1 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 30 Sep 2024 14:15:24 -0500 Subject: [PATCH 590/901] fix(deps): update dependency com.google.guava:guava-bom to v33.3.1-jre (#6744) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- dependencyManagement/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index 965150b923f..f27394fd5a1 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -9,7 +9,7 @@ rootProject.extra["versions"] = dependencyVersions val DEPENDENCY_BOMS = listOf( "com.fasterxml.jackson:jackson-bom:2.17.2", - "com.google.guava:guava-bom:33.3.0-jre", + "com.google.guava:guava-bom:33.3.1-jre", "com.google.protobuf:protobuf-bom:3.25.5", "com.linecorp.armeria:armeria-bom:1.30.1", "com.squareup.okhttp3:okhttp-bom:4.12.0", From 7f8fbc9bbd38ef2acdb407c15bc15f625e8e835c Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 30 Sep 2024 14:53:51 -0500 Subject: [PATCH 591/901] fix(deps): update dependency com.fasterxml.jackson:jackson-bom to v2.18.0 (#6752) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Co-authored-by: Jack Berg --- dependencyManagement/build.gradle.kts | 2 +- .../exporter/prometheus/PrometheusIntegrationTest.java | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index f27394fd5a1..a9dee9da21d 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -8,7 +8,7 @@ val dependencyVersions = hashMapOf() rootProject.extra["versions"] = dependencyVersions val DEPENDENCY_BOMS = listOf( - "com.fasterxml.jackson:jackson-bom:2.17.2", + "com.fasterxml.jackson:jackson-bom:2.18.0", "com.google.guava:guava-bom:33.3.1-jre", "com.google.protobuf:protobuf-bom:3.25.5", "com.linecorp.armeria:armeria-bom:1.30.1", diff --git a/exporters/prometheus/src/test/java/io/opentelemetry/exporter/prometheus/PrometheusIntegrationTest.java b/exporters/prometheus/src/test/java/io/opentelemetry/exporter/prometheus/PrometheusIntegrationTest.java index cff688c129d..ce178566030 100644 --- a/exporters/prometheus/src/test/java/io/opentelemetry/exporter/prometheus/PrometheusIntegrationTest.java +++ b/exporters/prometheus/src/test/java/io/opentelemetry/exporter/prometheus/PrometheusIntegrationTest.java @@ -11,7 +11,7 @@ import com.fasterxml.jackson.core.TreeNode; import com.fasterxml.jackson.jr.ob.JSON; -import com.fasterxml.jackson.jr.stree.JacksonJrsTreeCodec; +import com.fasterxml.jackson.jr.stree.JrSimpleTreeExtension; import com.fasterxml.jackson.jr.stree.JrsString; import com.google.common.io.Resources; import com.linecorp.armeria.client.WebClient; @@ -88,7 +88,7 @@ void endToEnd() { result -> result.record(9, Attributes.builder().put("animal", "cat").build())); WebClient promClient = WebClient.of("http://localhost:" + prometheus.getMappedPort(9090)); - JSON json = JSON.builder().treeCodec(new JacksonJrsTreeCodec()).build(); + JSON json = JSON.builder().register(new JrSimpleTreeExtension()).build(); await() .untilAsserted( () -> { From 27f98681174f3367a25e2eb2d80e4eeebb4766d3 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 1 Oct 2024 15:19:48 -0500 Subject: [PATCH 592/901] fix(deps): update dependency io.netty:netty-bom to v4.1.114.final (#6757) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- dependencyManagement/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index a9dee9da21d..47a592a61fc 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -15,7 +15,7 @@ val DEPENDENCY_BOMS = listOf( "com.squareup.okhttp3:okhttp-bom:4.12.0", "com.squareup.okio:okio-bom:3.9.1", // applies to transitive dependencies of okhttp "io.grpc:grpc-bom:1.68.0", - "io.netty:netty-bom:4.1.113.Final", + "io.netty:netty-bom:4.1.114.Final", "io.zipkin.brave:brave-bom:6.0.3", "io.zipkin.reporter2:zipkin-reporter-bom:3.4.2", "org.assertj:assertj-bom:3.26.3", From 0260d82716a63d2b54ecb68651684f87e5c27231 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 1 Oct 2024 15:20:00 -0500 Subject: [PATCH 593/901] fix(deps): update dependency org.testcontainers:testcontainers-bom to v1.20.2 (#6755) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- dependencyManagement/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index 47a592a61fc..7739249cbad 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -20,7 +20,7 @@ val DEPENDENCY_BOMS = listOf( "io.zipkin.reporter2:zipkin-reporter-bom:3.4.2", "org.assertj:assertj-bom:3.26.3", "org.junit:junit-bom:5.11.1", - "org.testcontainers:testcontainers-bom:1.20.1", + "org.testcontainers:testcontainers-bom:1.20.2", "org.snakeyaml:snakeyaml-engine:2.8" ) From 6c7efe280bb93618d5370cc3df34ca3a34ef85cb Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 1 Oct 2024 15:20:19 -0500 Subject: [PATCH 594/901] fix(deps): update errorproneversion to v2.33.0 (#6754) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- dependencyManagement/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index 7739249cbad..f87440d890c 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -25,7 +25,7 @@ val DEPENDENCY_BOMS = listOf( ) val autoValueVersion = "1.11.0" -val errorProneVersion = "2.32.0" +val errorProneVersion = "2.33.0" val jmhVersion = "1.37" // Mockito 5.x.x requires Java 11 https://github.com/mockito/mockito/releases/tag/v5.0.0 val mockitoVersion = "4.11.0" From 4aa7f57842ca09a10c02362a68413b7e2ee880a9 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 1 Oct 2024 15:20:49 -0500 Subject: [PATCH 595/901] fix(deps): update dependency com.google.api.grpc:proto-google-common-protos to v2.45.1 (#6739) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- dependencyManagement/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index f87440d890c..eac6aa289d0 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -56,7 +56,7 @@ val DEPENDENCIES = listOf( "io.prometheus:simpleclient_httpserver:${prometheusClientVersion}", "javax.annotation:javax.annotation-api:1.3.2", "com.github.stefanbirkner:system-rules:1.19.0", - "com.google.api.grpc:proto-google-common-protos:2.44.0", + "com.google.api.grpc:proto-google-common-protos:2.45.1", "com.google.code.findbugs:jsr305:3.0.2", "com.google.guava:guava-beta-checker:1.0", "com.sun.net.httpserver:http:20070405", From 361f035efe50fb41274958a744f196581824ba5d Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 1 Oct 2024 15:48:54 -0500 Subject: [PATCH 596/901] chore(deps): update dependency ubuntu to v24 (#6751) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/build.yml | 2 +- .github/workflows/release.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 33d3cfe545b..442355d104a 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -124,7 +124,7 @@ jobs: name: publish-snapshots${{ (github.ref_name != 'main' || github.repository != 'open-telemetry/opentelemetry-java') && ' (skipped)' || '' }} # intentionally not blocking snapshot publishing on markdown-link-check or misspell-check needs: build - runs-on: ubuntu-22.04 + runs-on: ubuntu-24.04 steps: - uses: actions/checkout@v4 diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 30bc0809b39..7fea632b3d1 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -4,7 +4,7 @@ on: jobs: release: - runs-on: ubuntu-22.04 + runs-on: ubuntu-24.04 outputs: version: ${{ steps.create-github-release.outputs.version }} steps: From a6a9acb1dd62f43da195b1362f2e168a33f46228 Mon Sep 17 00:00:00 2001 From: jack-berg <34418638+jack-berg@users.noreply.github.com> Date: Wed, 2 Oct 2024 15:16:21 -0500 Subject: [PATCH 597/901] Add getStructured default method, add empty StructuredConfigProperties (#6759) --- .../EmptyStructuredConfigProperties.java | 77 +++++++++++++++++++ .../internal/StructuredConfigProperties.java | 35 +++++++++ .../YamlStructuredConfigPropertiesTest.java | 38 +++++++++ 3 files changed, 150 insertions(+) create mode 100644 sdk-extensions/autoconfigure-spi/src/main/java/io/opentelemetry/sdk/autoconfigure/spi/internal/EmptyStructuredConfigProperties.java diff --git a/sdk-extensions/autoconfigure-spi/src/main/java/io/opentelemetry/sdk/autoconfigure/spi/internal/EmptyStructuredConfigProperties.java b/sdk-extensions/autoconfigure-spi/src/main/java/io/opentelemetry/sdk/autoconfigure/spi/internal/EmptyStructuredConfigProperties.java new file mode 100644 index 00000000000..2315dfa013f --- /dev/null +++ b/sdk-extensions/autoconfigure-spi/src/main/java/io/opentelemetry/sdk/autoconfigure/spi/internal/EmptyStructuredConfigProperties.java @@ -0,0 +1,77 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.sdk.autoconfigure.spi.internal; + +import java.util.Collections; +import java.util.List; +import java.util.Set; +import javax.annotation.Nullable; + +/** Empty instance of {@link StructuredConfigProperties}. */ +final class EmptyStructuredConfigProperties implements StructuredConfigProperties { + + private static final EmptyStructuredConfigProperties INSTANCE = + new EmptyStructuredConfigProperties(); + + private EmptyStructuredConfigProperties() {} + + static EmptyStructuredConfigProperties getInstance() { + return INSTANCE; + } + + @Nullable + @Override + public String getString(String name) { + return null; + } + + @Nullable + @Override + public Boolean getBoolean(String name) { + return null; + } + + @Nullable + @Override + public Integer getInt(String name) { + return null; + } + + @Nullable + @Override + public Long getLong(String name) { + return null; + } + + @Nullable + @Override + public Double getDouble(String name) { + return null; + } + + @Nullable + @Override + public List getScalarList(String name, Class scalarType) { + return null; + } + + @Nullable + @Override + public StructuredConfigProperties getStructured(String name) { + return null; + } + + @Nullable + @Override + public List getStructuredList(String name) { + return null; + } + + @Override + public Set getPropertyKeys() { + return Collections.emptySet(); + } +} diff --git a/sdk-extensions/autoconfigure-spi/src/main/java/io/opentelemetry/sdk/autoconfigure/spi/internal/StructuredConfigProperties.java b/sdk-extensions/autoconfigure-spi/src/main/java/io/opentelemetry/sdk/autoconfigure/spi/internal/StructuredConfigProperties.java index ad1e3b5de3c..99eff27f00b 100644 --- a/sdk-extensions/autoconfigure-spi/src/main/java/io/opentelemetry/sdk/autoconfigure/spi/internal/StructuredConfigProperties.java +++ b/sdk-extensions/autoconfigure-spi/src/main/java/io/opentelemetry/sdk/autoconfigure/spi/internal/StructuredConfigProperties.java @@ -24,6 +24,17 @@ */ public interface StructuredConfigProperties { + /** + * Return an empty {@link StructuredConfigProperties} instance. + * + *

      Useful for walking the tree without checking for null. For example, to access a string key + * nested at .foo.bar.baz, call: {@code config.getStructured("foo", empty()).getStructured("bar", + * empty()).getString("baz")}. + */ + static StructuredConfigProperties empty() { + return EmptyStructuredConfigProperties.getInstance(); + } + /** * Returns a {@link String} configuration property. * @@ -168,6 +179,18 @@ default List getScalarList(String name, Class scalarType, List defa @Nullable StructuredConfigProperties getStructured(String name); + /** + * Returns a {@link StructuredConfigProperties} configuration property. + * + * @return a map-valued configuration property, or {@code defaultValue} if {@code name} has not + * been configured + * @throws ConfigurationException if the property is not a mapping + */ + default StructuredConfigProperties getStructured( + String name, StructuredConfigProperties defaultValue) { + return defaultIfNull(getStructured(name), defaultValue); + } + /** * Returns a list of {@link StructuredConfigProperties} configuration property. * @@ -178,6 +201,18 @@ default List getScalarList(String name, Class scalarType, List defa @Nullable List getStructuredList(String name); + /** + * Returns a list of {@link StructuredConfigProperties} configuration property. + * + * @return a list of map-valued configuration property, or {@code defaultValue} if {@code name} + * has not been configured + * @throws ConfigurationException if the property is not a sequence of mappings + */ + default List getStructuredList( + String name, List defaultValue) { + return defaultIfNull(getStructuredList(name), defaultValue); + } + /** * Returns a set of all configuration property keys. * diff --git a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/YamlStructuredConfigPropertiesTest.java b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/YamlStructuredConfigPropertiesTest.java index 2e64e93fe94..757331934bf 100644 --- a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/YamlStructuredConfigPropertiesTest.java +++ b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/YamlStructuredConfigPropertiesTest.java @@ -5,6 +5,7 @@ package io.opentelemetry.sdk.extension.incubator.fileconfig; +import static io.opentelemetry.sdk.autoconfigure.spi.internal.StructuredConfigProperties.empty; import static org.assertj.core.api.Assertions.assertThat; import com.google.common.collect.ImmutableSet; @@ -170,6 +171,18 @@ void additionalProperties() { assertThat(listKeyProps2.getInt("int_key1")).isEqualTo(2); } + @Test + void treeWalking() { + // Validate common pattern of walking down tree path which is not defined + // Access string at .foo.bar.baz without null checking and without exception. + assertThat( + structuredConfigProps + .getStructured("foo", empty()) + .getStructured("bar", empty()) + .getString("baz")) + .isNull(); + } + @Test void defaults() { assertThat(structuredConfigProps.getString("foo", "bar")).isEqualTo("bar"); @@ -181,6 +194,9 @@ void defaults() { structuredConfigProps.getScalarList( "foo", String.class, Collections.singletonList("bar"))) .isEqualTo(Collections.singletonList("bar")); + assertThat(structuredConfigProps.getStructured("foo", empty())).isEqualTo(empty()); + assertThat(structuredConfigProps.getStructuredList("foo", Collections.emptyList())) + .isEqualTo(Collections.emptyList()); } @Test @@ -209,4 +225,26 @@ void wrongType() { assertThat(otherProps.getStructured("str_key")).isNull(); assertThat(otherProps.getStructuredList("str_key")).isNull(); } + + @Test + void emptyProperties() { + assertThat(empty().getString("foo")).isNull(); + assertThat(empty().getInt("foo")).isNull(); + assertThat(empty().getLong("foo")).isNull(); + assertThat(empty().getDouble("foo")).isNull(); + assertThat(empty().getBoolean("foo")).isNull(); + assertThat(empty().getScalarList("foo", String.class)).isNull(); + assertThat(empty().getStructured("foo")).isNull(); + assertThat(empty().getStructuredList("foo")).isNull(); + assertThat(empty().getString("foo", "bar")).isEqualTo("bar"); + assertThat(empty().getInt("foo", 1)).isEqualTo(1); + assertThat(empty().getLong("foo", 1)).isEqualTo(1); + assertThat(empty().getDouble("foo", 1.1)).isEqualTo(1.1); + assertThat(empty().getBoolean("foo", true)).isTrue(); + assertThat(empty().getScalarList("foo", String.class, Collections.singletonList("bar"))) + .isEqualTo(Collections.singletonList("bar")); + assertThat(empty().getStructured("foo", empty())).isEqualTo(empty()); + assertThat(empty().getStructuredList("foo", Collections.emptyList())) + .isEqualTo(Collections.emptyList()); + } } From 814e06401dbddca18a0aa57522a8a192c7656c4e Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 4 Oct 2024 18:48:07 -0700 Subject: [PATCH 598/901] fix(deps): update dependency nl.jqno.equalsverifier:equalsverifier to v3.17.1 (#6760) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- dependencyManagement/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index eac6aa289d0..35e5daae7d7 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -73,7 +73,7 @@ val DEPENDENCIES = listOf( "io.opentracing:opentracing-noop:0.33.0", "io.prometheus:prometheus-metrics-exporter-httpserver:1.3.1", "junit:junit:4.13.2", - "nl.jqno.equalsverifier:equalsverifier:3.17", + "nl.jqno.equalsverifier:equalsverifier:3.17.1", "org.awaitility:awaitility:4.2.2", "org.bouncycastle:bcpkix-jdk15on:1.70", "org.codehaus.mojo:animal-sniffer-annotations:1.24", From 503cc533f267592939cb9e728d93884515cb5a46 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 5 Oct 2024 13:25:03 -0700 Subject: [PATCH 599/901] fix(deps): update dependency org.junit:junit-bom to v5.11.2 (#6764) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- dependencyManagement/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index 35e5daae7d7..0fea63941e4 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -19,7 +19,7 @@ val DEPENDENCY_BOMS = listOf( "io.zipkin.brave:brave-bom:6.0.3", "io.zipkin.reporter2:zipkin-reporter-bom:3.4.2", "org.assertj:assertj-bom:3.26.3", - "org.junit:junit-bom:5.11.1", + "org.junit:junit-bom:5.11.2", "org.testcontainers:testcontainers-bom:1.20.2", "org.snakeyaml:snakeyaml-engine:2.8" ) From 65af6511e5b838993ba579970d48b20b85d52e27 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 5 Oct 2024 19:51:14 -0700 Subject: [PATCH 600/901] fix(deps): update dependency com.toasttab.android:gummy-bears-api-21 to v0.10.0 (#6762) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- animal-sniffer-signature/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/animal-sniffer-signature/build.gradle.kts b/animal-sniffer-signature/build.gradle.kts index 4e927a9b63a..f571179e8ff 100644 --- a/animal-sniffer-signature/build.gradle.kts +++ b/animal-sniffer-signature/build.gradle.kts @@ -27,7 +27,7 @@ configurations.add(signatureJarClasspath) configurations.add(generatedSignature) dependencies { - signature("com.toasttab.android:gummy-bears-api-21:0.9.0@signature") + signature("com.toasttab.android:gummy-bears-api-21:0.10.0@signature") signatureJar("com.android.tools:desugar_jdk_libs") } From a7f950d7fded1199bc6f931fea4a4cd40461f5f9 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sun, 6 Oct 2024 12:22:53 -0700 Subject: [PATCH 601/901] fix(deps): update dependency com.google.api.grpc:proto-google-common-protos to v2.46.0 (#6766) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- dependencyManagement/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index 0fea63941e4..9194798c861 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -56,7 +56,7 @@ val DEPENDENCIES = listOf( "io.prometheus:simpleclient_httpserver:${prometheusClientVersion}", "javax.annotation:javax.annotation-api:1.3.2", "com.github.stefanbirkner:system-rules:1.19.0", - "com.google.api.grpc:proto-google-common-protos:2.45.1", + "com.google.api.grpc:proto-google-common-protos:2.46.0", "com.google.code.findbugs:jsr305:3.0.2", "com.google.guava:guava-beta-checker:1.0", "com.sun.net.httpserver:http:20070405", From 0f859b4385d12be9c0e8a36748813dd7553b46c6 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sun, 6 Oct 2024 14:04:26 -0700 Subject: [PATCH 602/901] chore(deps): update plugin com.gradleup.shadow to v8.3.3 (#6758) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- settings.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/settings.gradle.kts b/settings.gradle.kts index 222c497d44b..d6e6592dc68 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -1,6 +1,6 @@ pluginManagement { plugins { - id("com.gradleup.shadow") version "8.3.2" + id("com.gradleup.shadow") version "8.3.3" id("com.gradle.develocity") version "3.18.1" id("de.undercouch.download") version "5.6.0" id("org.jsonschema2pojo") version "1.2.2" From eb53fe3a614a5feb6ddd74d93b43722a0033fffe Mon Sep 17 00:00:00 2001 From: Adriano Machado <60320+ammachado@users.noreply.github.com> Date: Mon, 7 Oct 2024 11:08:21 -0400 Subject: [PATCH 603/901] Add helper class to capture context using ScheduledExecutorService (#6712) Signed-off-by: Adriano Machado <60320+ammachado@users.noreply.github.com> --- .gitignore | 1 + .../io/opentelemetry/context/Context.java | 29 ++ .../CurrentContextExecutorService.java | 2 +- ...urrentContextScheduledExecutorService.java | 44 +++ .../io/opentelemetry/context/ContextTest.java | 352 +++++++++++++++--- .../opentelemetry-context.txt | 4 +- 6 files changed, 383 insertions(+), 49 deletions(-) create mode 100644 context/src/main/java/io/opentelemetry/context/CurrentContextScheduledExecutorService.java diff --git a/.gitignore b/.gitignore index 69c5f8b7cf9..6dd7dc74f2f 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,7 @@ # Gradle build .gradle +.kotlin local.properties out/ diff --git a/context/src/main/java/io/opentelemetry/context/Context.java b/context/src/main/java/io/opentelemetry/context/Context.java index d9c9f50c889..bb9a48d6039 100644 --- a/context/src/main/java/io/opentelemetry/context/Context.java +++ b/context/src/main/java/io/opentelemetry/context/Context.java @@ -27,6 +27,7 @@ import java.util.concurrent.Executor; import java.util.concurrent.ExecutorService; import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.TimeUnit; import java.util.function.BiConsumer; import java.util.function.BiFunction; import java.util.function.Consumer; @@ -135,9 +136,37 @@ static Executor taskWrapping(Executor executor) { * @since 1.1.0 */ static ExecutorService taskWrapping(ExecutorService executorService) { + if (executorService instanceof CurrentContextExecutorService) { + return executorService; + } return new CurrentContextExecutorService(executorService); } + /** + * Returns an {@link ScheduledExecutorService} which delegates to the provided {@code + * executorService}, wrapping all invocations of {@link ExecutorService} methods such as {@link + * ExecutorService#execute(Runnable)} or {@link ExecutorService#submit(Runnable)} with the + * {@linkplain Context#current() current context} at the time of invocation. + * + *

      This is generally used to create an {@link ScheduledExecutorService} which will forward the + * {@link Context} during an invocation to another thread. For example, you may use something like + * {@code ScheduledExecutorService dbExecutor = Context.wrapTasks(threadPool)} to ensure calls + * like {@code dbExecutor.execute(() -> database.query())} have {@link Context} available on the + * thread executing database queries. + * + *

      Note: The context will not be propagated for {@link + * ScheduledExecutorService#scheduleAtFixedRate(Runnable, long, long, TimeUnit)} and {@link + * ScheduledExecutorService#scheduleWithFixedDelay(Runnable, long, long, TimeUnit)} calls. + * + * @since 1.43.0 + */ + static ScheduledExecutorService taskWrapping(ScheduledExecutorService executorService) { + if (executorService instanceof CurrentContextScheduledExecutorService) { + return executorService; + } + return new CurrentContextScheduledExecutorService(executorService); + } + /** * Returns the value stored in this {@link Context} for the given {@link ContextKey}, or {@code * null} if there is no value for the key in this context. diff --git a/context/src/main/java/io/opentelemetry/context/CurrentContextExecutorService.java b/context/src/main/java/io/opentelemetry/context/CurrentContextExecutorService.java index 346b8498781..f3e5f3aa81b 100644 --- a/context/src/main/java/io/opentelemetry/context/CurrentContextExecutorService.java +++ b/context/src/main/java/io/opentelemetry/context/CurrentContextExecutorService.java @@ -14,7 +14,7 @@ import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; -final class CurrentContextExecutorService extends ForwardingExecutorService { +class CurrentContextExecutorService extends ForwardingExecutorService { CurrentContextExecutorService(ExecutorService delegate) { super(delegate); diff --git a/context/src/main/java/io/opentelemetry/context/CurrentContextScheduledExecutorService.java b/context/src/main/java/io/opentelemetry/context/CurrentContextScheduledExecutorService.java new file mode 100644 index 00000000000..f32b1faf2a8 --- /dev/null +++ b/context/src/main/java/io/opentelemetry/context/CurrentContextScheduledExecutorService.java @@ -0,0 +1,44 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.context; + +import java.util.concurrent.Callable; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.ScheduledFuture; +import java.util.concurrent.TimeUnit; + +final class CurrentContextScheduledExecutorService extends CurrentContextExecutorService + implements ScheduledExecutorService { + + private final ScheduledExecutorService delegate; + + CurrentContextScheduledExecutorService(ScheduledExecutorService delegate) { + super(delegate); + this.delegate = delegate; + } + + @Override + public ScheduledFuture schedule(Runnable command, long delay, TimeUnit unit) { + return delegate.schedule(Context.current().wrap(command), delay, unit); + } + + @Override + public ScheduledFuture schedule(Callable callable, long delay, TimeUnit unit) { + return delegate.schedule(Context.current().wrap(callable), delay, unit); + } + + @Override + public ScheduledFuture scheduleAtFixedRate( + Runnable command, long initialDelay, long period, TimeUnit unit) { + return delegate.scheduleAtFixedRate(command, initialDelay, period, unit); + } + + @Override + public ScheduledFuture scheduleWithFixedDelay( + Runnable command, long initialDelay, long delay, TimeUnit unit) { + return delegate.scheduleWithFixedDelay(command, initialDelay, delay, unit); + } +} diff --git a/context/src/test/java/io/opentelemetry/context/ContextTest.java b/context/src/test/java/io/opentelemetry/context/ContextTest.java index d8a7a0b7bf8..3753e89bf30 100644 --- a/context/src/test/java/io/opentelemetry/context/ContextTest.java +++ b/context/src/test/java/io/opentelemetry/context/ContextTest.java @@ -9,6 +9,9 @@ import static org.awaitility.Awaitility.await; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyLong; +import static org.mockito.Mockito.doNothing; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verifyNoMoreInteractions; import static org.mockito.Mockito.when; @@ -28,6 +31,7 @@ import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicReference; +import java.util.concurrent.atomic.LongAdder; import java.util.function.BiConsumer; import java.util.function.BiFunction; import java.util.function.Consumer; @@ -118,7 +122,7 @@ void newThreadStartsWithRoot() throws Exception { } @Test - public void closingScopeWhenNotActiveIsNoopAndLogged() { + void closingScopeWhenNotActiveIsNoopAndLogged() { Context initial = Context.current(); Context context = initial.with(ANIMAL, "cat"); try (Scope scope = context.makeCurrent()) { @@ -137,7 +141,7 @@ public void closingScopeWhenNotActiveIsNoopAndLogged() { @SuppressWarnings("MustBeClosedChecker") @Test - public void closeScopeIsIdempotent() { + void closeScopeIsIdempotent() { Context initial = Context.current(); Context context1 = Context.root().with(ANIMAL, "cat"); Scope scope1 = context1.makeCurrent(); @@ -188,11 +192,10 @@ void withValues() { assertThat(context5).isSameAs(context4); String dog = new String("dog"); - assertThat(dog).isEqualTo("dog"); - assertThat(dog).isNotSameAs("dog"); + assertThat(dog).isEqualTo("dog").isNotSameAs("dog"); Context context6 = context5.with(ANIMAL, dog); assertThat(context6.get(ANIMAL)).isEqualTo("dog"); - // We reuse context object when values match by reference, not value. + // We reuse the context object when values match by reference, not value. assertThat(context6).isNotSameAs(context5); } @@ -234,7 +237,7 @@ void wrapCallable() throws Exception { void wrapFunction() { AtomicReference value = new AtomicReference<>(); Function callback = - (a) -> { + a -> { value.set(Context.current().get(ANIMAL)); return "foo"; }; @@ -273,7 +276,7 @@ void wrapConsumer() { AtomicReference value = new AtomicReference<>(); AtomicBoolean consumed = new AtomicBoolean(); Consumer callback = - (a) -> { + a -> { value.set(Context.current().get(ANIMAL)); consumed.set(true); }; @@ -362,7 +365,7 @@ void wrapExecutor() { @TestInstance(Lifecycle.PER_CLASS) class WrapExecutorService { - protected ScheduledExecutorService executor; + protected ExecutorService executor; protected ExecutorService wrapped; protected AtomicReference value; @@ -501,6 +504,204 @@ void invokeAnyTimeout() throws Exception { } } + @Nested + @TestInstance(Lifecycle.PER_CLASS) + class WrapScheduledExecutorService { + + protected ScheduledExecutorService executor; + protected ScheduledExecutorService wrapped; + protected AtomicReference value; + + protected ScheduledExecutorService wrap(ScheduledExecutorService executorService) { + return CAT.wrap(executorService); + } + + @BeforeAll + void initExecutor() { + executor = Executors.newSingleThreadScheduledExecutor(); + wrapped = wrap(executor); + } + + @AfterAll + void stopExecutor() { + executor.shutdown(); + } + + @BeforeEach + void setUp() { + value = new AtomicReference<>(); + } + + @Test + void execute() { + Runnable runnable = () -> value.set(Context.current().get(ANIMAL)); + wrapped.execute(runnable); + await().untilAsserted(() -> assertThat(value).hasValue("cat")); + } + + @Test + void submitRunnable() { + Runnable runnable = () -> value.set(Context.current().get(ANIMAL)); + Futures.getUnchecked(wrapped.submit(runnable)); + assertThat(value).hasValue("cat"); + } + + @Test + void submitRunnableResult() { + Runnable runnable = () -> value.set(Context.current().get(ANIMAL)); + assertThat(Futures.getUnchecked(wrapped.submit(runnable, "foo"))).isEqualTo("foo"); + assertThat(value).hasValue("cat"); + } + + @Test + void submitCallable() { + Callable callable = + () -> { + value.set(Context.current().get(ANIMAL)); + return "foo"; + }; + assertThat(Futures.getUnchecked(wrapped.submit(callable))).isEqualTo("foo"); + assertThat(value).hasValue("cat"); + } + + @Test + void invokeAll() throws Exception { + AtomicReference value1 = new AtomicReference<>(); + AtomicReference value2 = new AtomicReference<>(); + Callable callable1 = + () -> { + value1.set(Context.current().get(ANIMAL)); + return "foo"; + }; + Callable callable2 = + () -> { + value2.set(Context.current().get(ANIMAL)); + return "bar"; + }; + List> futures = wrapped.invokeAll(Arrays.asList(callable1, callable2)); + assertThat(futures.get(0).get()).isEqualTo("foo"); + assertThat(futures.get(1).get()).isEqualTo("bar"); + assertThat(value1).hasValue("cat"); + assertThat(value2).hasValue("cat"); + } + + @Test + void invokeAllTimeout() throws Exception { + AtomicReference value1 = new AtomicReference<>(); + AtomicReference value2 = new AtomicReference<>(); + Callable callable1 = + () -> { + value1.set(Context.current().get(ANIMAL)); + return "foo"; + }; + Callable callable2 = + () -> { + value2.set(Context.current().get(ANIMAL)); + return "bar"; + }; + List> futures = + wrapped.invokeAll(Arrays.asList(callable1, callable2), 10, TimeUnit.SECONDS); + assertThat(futures.get(0).get()).isEqualTo("foo"); + assertThat(futures.get(1).get()).isEqualTo("bar"); + assertThat(value1).hasValue("cat"); + assertThat(value2).hasValue("cat"); + } + + @Test + void invokeAny() throws Exception { + AtomicReference value1 = new AtomicReference<>(); + AtomicReference value2 = new AtomicReference<>(); + Callable callable1 = + () -> { + value1.set(Context.current().get(ANIMAL)); + throw new IllegalStateException("callable2 wins"); + }; + Callable callable2 = + () -> { + value2.set(Context.current().get(ANIMAL)); + return "bar"; + }; + assertThat(wrapped.invokeAny(Arrays.asList(callable1, callable2))).isEqualTo("bar"); + assertThat(value1).hasValue("cat"); + assertThat(value2).hasValue("cat"); + } + + @Test + void invokeAnyTimeout() throws Exception { + AtomicReference value1 = new AtomicReference<>(); + AtomicReference value2 = new AtomicReference<>(); + Callable callable1 = + () -> { + value1.set(Context.current().get(ANIMAL)); + throw new IllegalStateException("callable2 wins"); + }; + Callable callable2 = + () -> { + value2.set(Context.current().get(ANIMAL)); + return "bar"; + }; + assertThat(wrapped.invokeAny(Arrays.asList(callable1, callable2), 10, TimeUnit.SECONDS)) + .isEqualTo("bar"); + assertThat(value1).hasValue("cat"); + assertThat(value2).hasValue("cat"); + } + + @Test + void scheduleRunnable() { + Runnable runnable = () -> value.set(Context.current().get(ANIMAL)); + assertThat(Futures.getUnchecked(wrapped.schedule(runnable, 1L, TimeUnit.MILLISECONDS))) + .isNull(); + assertThat(value).hasValue("cat"); + } + + @Test + void scheduleCallable() { + Callable callable = + () -> { + value.set(Context.current().get(ANIMAL)); + return "foo"; + }; + assertThat(Futures.getUnchecked(wrapped.schedule(callable, 1L, TimeUnit.MILLISECONDS))) + .isEqualTo("foo"); + assertThat(value).hasValue("cat"); + } + + @Test + void scheduleAtFixedRate() { + LongAdder longAdder = new LongAdder(); + Runnable runnable = longAdder::increment; + Future future = wrapped.scheduleAtFixedRate(runnable, 1L, 2L, TimeUnit.NANOSECONDS); + assertThat(future).isNotNull(); + await() + .await() + .untilAsserted( + () -> { + if (!future.isCancelled()) { + future.cancel(true); + } + assertThat(longAdder.intValue()).isGreaterThan(1); + }); + assertThat(longAdder.intValue()).isGreaterThan(1); + } + + @Test + void scheduleWithFixedDelay() { + LongAdder longAdder = new LongAdder(); + Runnable runnable = longAdder::increment; + Future future = wrapped.scheduleWithFixedDelay(runnable, 1L, 2L, TimeUnit.NANOSECONDS); + assertThat(future).isNotNull(); + await() + .await() + .untilAsserted( + () -> { + if (!future.isCancelled()) { + future.cancel(true); + } + assertThat(longAdder.intValue()).isGreaterThan(1); + }); + } + } + @Nested @TestInstance(Lifecycle.PER_CLASS) class CurrentContextWrappingExecutorService extends WrapExecutorService { @@ -525,9 +726,34 @@ void close() { } } + @Nested + @TestInstance(Lifecycle.PER_CLASS) + class CurrentContextWrappingScheduledExecutorService extends WrapScheduledExecutorService { + + @Override + protected ScheduledExecutorService wrap(ScheduledExecutorService executorService) { + return Context.taskWrapping(executorService); + } + + private Scope scope; + + @BeforeEach + // Closed in AfterEach + @SuppressWarnings("MustBeClosedChecker") + void makeCurrent() { + scope = CAT.makeCurrent(); + } + + @AfterEach + void close() { + scope.close(); + scope = null; + } + } + @Test void keyToString() { - assertThat(ANIMAL.toString()).isEqualTo("animal"); + assertThat(ANIMAL).hasToString("animal"); } @Test @@ -552,6 +778,7 @@ class DelegatesToExecutorService { @Test void delegatesCleanupMethods() throws Exception { ExecutorService wrapped = CAT.wrap(executor); + doNothing().when(executor).shutdown(); wrapped.shutdown(); verify(executor).shutdown(); verifyNoMoreInteractions(executor); @@ -573,57 +800,74 @@ void delegatesCleanupMethods() throws Exception { } } + // We test real context-related above but should test cleanup gets delegated, which is best with + // a mock. @Nested @TestInstance(Lifecycle.PER_CLASS) - class WrapScheduledExecutorService extends WrapExecutorService { + @SuppressWarnings("MockitoDoSetup") + class DelegatesToScheduledExecutorService { - private ScheduledExecutorService wrapScheduled; - - @BeforeEach - void wrapScheduled() { - wrapScheduled = CAT.wrap(executor); - } + @Mock private ScheduledExecutorService executor; + @Mock private ScheduledFuture scheduledFuture; @Test - void scheduleRunnable() throws Exception { - Runnable runnable = () -> value.set(Context.current().get(ANIMAL)); - wrapScheduled.schedule(runnable, 0, TimeUnit.SECONDS).get(); - assertThat(value).hasValue("cat"); - } + void delegatesCleanupMethods() throws Exception { + ScheduledExecutorService wrapped = CAT.wrap(executor); - @Test - void scheduleCallable() throws Exception { - Callable callable = - () -> { - value.set(Context.current().get(ANIMAL)); - return "foo"; - }; - assertThat(wrapScheduled.schedule(callable, 0, TimeUnit.SECONDS).get()).isEqualTo("foo"); - assertThat(value).hasValue("cat"); - } + wrapped.shutdown(); + verify(executor).shutdown(); + verifyNoMoreInteractions(executor); - @Test - void scheduleAtFixedRate() { - Runnable runnable = () -> value.set(Context.current().get(ANIMAL)); - ScheduledFuture future = - wrapScheduled.scheduleAtFixedRate(runnable, 0, 10, TimeUnit.SECONDS); - await().untilAsserted(() -> assertThat(value).hasValue("cat")); - future.cancel(true); - } + wrapped.shutdownNow(); + verify(executor).shutdownNow(); + verifyNoMoreInteractions(executor); - @Test - void scheduleWithFixedDelay() { - Runnable runnable = () -> value.set(Context.current().get(ANIMAL)); - ScheduledFuture future = - wrapScheduled.scheduleWithFixedDelay(runnable, 0, 10, TimeUnit.SECONDS); - await().untilAsserted(() -> assertThat(value).hasValue("cat")); - future.cancel(true); + when(executor.isShutdown()).thenReturn(true); + assertThat(wrapped.isShutdown()).isTrue(); + verify(executor).isShutdown(); + verifyNoMoreInteractions(executor); + + when(wrapped.isTerminated()).thenReturn(true); + assertThat(wrapped.isTerminated()).isTrue(); + verify(executor).isTerminated(); + verifyNoMoreInteractions(executor); + + when(executor.awaitTermination(anyLong(), any())).thenReturn(true); + assertThat(wrapped.awaitTermination(1L, TimeUnit.SECONDS)).isTrue(); + verify(executor).awaitTermination(1L, TimeUnit.SECONDS); + verifyNoMoreInteractions(executor); + + doReturn(scheduledFuture) + .when(executor) + .schedule(any(Runnable.class), anyLong(), any(TimeUnit.class)); + assertThat((Future) wrapped.schedule(() -> {}, 1L, TimeUnit.SECONDS)) + .isSameAs(scheduledFuture); + verify(executor).schedule(any(Runnable.class), anyLong(), any(TimeUnit.class)); + verifyNoMoreInteractions(executor); + + doReturn(scheduledFuture) + .when(executor) + .scheduleAtFixedRate(any(Runnable.class), anyLong(), anyLong(), any(TimeUnit.class)); + assertThat((Future) wrapped.scheduleAtFixedRate(() -> {}, 1L, 1L, TimeUnit.SECONDS)) + .isSameAs(scheduledFuture); + verify(executor) + .scheduleAtFixedRate(any(Runnable.class), anyLong(), anyLong(), any(TimeUnit.class)); + verifyNoMoreInteractions(executor); + + doReturn(scheduledFuture) + .when(executor) + .scheduleWithFixedDelay(any(Runnable.class), anyLong(), anyLong(), any(TimeUnit.class)); + assertThat((Future) wrapped.scheduleWithFixedDelay(() -> {}, 1L, 1L, TimeUnit.SECONDS)) + .isSameAs(scheduledFuture); + verify(executor) + .scheduleWithFixedDelay(any(Runnable.class), anyLong(), anyLong(), any(TimeUnit.class)); + verifyNoMoreInteractions(executor); } } @Test void emptyContext() { - assertThat(Context.root().get(new HashCollidingKey())).isEqualTo(null); + assertThat(Context.root().get(new HashCollidingKey())).isNull(); } @Test @@ -646,6 +890,20 @@ void hashcodeCollidingKeys() { assertThat(twoKeys.get(cheese)).isEqualTo("whiz"); } + @Test + void doNotWrapExecutorService() { + ExecutorService executor = mock(CurrentContextExecutorService.class); + ExecutorService wrapped = Context.taskWrapping(executor); + assertThat(wrapped).isSameAs(executor); + } + + @Test + void doNotWrapScheduledExecutorService() { + ScheduledExecutorService executor = mock(CurrentContextScheduledExecutorService.class); + ScheduledExecutorService wrapped = Context.taskWrapping(executor); + assertThat(wrapped).isSameAs(executor); + } + @SuppressWarnings("HashCodeToString") private static class HashCollidingKey implements ContextKey { @Override diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-context.txt b/docs/apidiffs/current_vs_latest/opentelemetry-context.txt index c861601babb..1157c08dce0 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-context.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-context.txt @@ -1,2 +1,4 @@ Comparing source compatibility of opentelemetry-context-1.43.0-SNAPSHOT.jar against opentelemetry-context-1.42.1.jar -No changes. \ No newline at end of file +*** MODIFIED INTERFACE: PUBLIC ABSTRACT io.opentelemetry.context.Context (not serializable) + === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 + +++ NEW METHOD: PUBLIC(+) STATIC(+) java.util.concurrent.ScheduledExecutorService taskWrapping(java.util.concurrent.ScheduledExecutorService) From b927d9daf4de0211411c522aae081edf9f39cfa6 Mon Sep 17 00:00:00 2001 From: Gregor Zeitlinger Date: Wed, 9 Oct 2024 20:17:14 +0200 Subject: [PATCH 604/901] Stdout exporter for span and metrics (#6750) --- .../internal/ExporterBuilderUtil.java | 92 ++++++ .../otlp/OtlpJsonLoggingMetricExporter.java | 77 ++--- .../otlp/OtlpJsonLoggingSpanExporter.java | 51 +--- .../LoggingLogRecordExporterProvider.java | 3 +- .../logs/OtlpStdoutLogRecordExporter.java | 2 +- ...outLogRecordExporterComponentProvider.java | 2 +- .../OtlpStdoutLogRecordExporterProvider.java | 3 +- .../LoggingMetricExporterProvider.java | 5 +- .../metrics/OtlpStdoutMetricExporter.java | 115 +++++++ .../OtlpStdoutMetricExporterBuilder.java | 124 ++++++++ ...StdoutMetricExporterComponentProvider.java | 41 +++ .../OtlpStdoutMetricExporterProvider.java | 34 +++ .../LoggingSpanExporterProvider.java | 5 +- .../traces/OtlpStdoutSpanExporter.java | 91 ++++++ .../traces/OtlpStdoutSpanExporterBuilder.java | 76 +++++ ...lpStdoutSpanExporterComponentProvider.java | 36 +++ .../OtlpStdoutSpanExporterProvider.java | 29 ++ ...toconfigure.spi.internal.ComponentProvider | 2 + ...metrics.ConfigurableMetricExporterProvider | 4 +- ...pi.traces.ConfigurableSpanExporterProvider | 3 +- .../otlp/AbstractOtlpStdoutExporterTest.java | 287 ++++++++++++++++++ .../OtlpJsonLoggingMetricExporterTest.java | 118 +------ .../otlp/OtlpJsonLoggingSpanExporterTest.java | 148 +-------- .../otlp/OtlpStdoutLogRecordExporterTest.java | 270 +--------------- .../otlp/OtlpStdoutMetricExporterTest.java | 124 ++++++++ .../otlp/OtlpStdoutSpanExporterTest.java | 44 +++ .../logging/otlp/TestDataExporter.java | 135 ++++++++ .../resources/expected-metrics-wrapper.json | 93 ++++++ .../src/test/resources/expected-metrics.json | 89 ++++++ .../resources/expected-spans-wrapper.json | 99 ++++++ .../src/test/resources/expected-spans.json | 95 ++++++ .../otlp/internal/OtlpConfigUtil.java | 99 ------ .../OtlpMetricExporterComponentProvider.java | 9 +- .../internal/OtlpMetricExporterProvider.java | 9 +- .../otlp/internal/OtlpConfigUtilTest.java | 10 +- 35 files changed, 1704 insertions(+), 720 deletions(-) rename exporters/logging-otlp/src/main/java/io/opentelemetry/exporter/logging/otlp/internal/{ => metrics}/LoggingMetricExporterProvider.java (83%) create mode 100644 exporters/logging-otlp/src/main/java/io/opentelemetry/exporter/logging/otlp/internal/metrics/OtlpStdoutMetricExporter.java create mode 100644 exporters/logging-otlp/src/main/java/io/opentelemetry/exporter/logging/otlp/internal/metrics/OtlpStdoutMetricExporterBuilder.java create mode 100644 exporters/logging-otlp/src/main/java/io/opentelemetry/exporter/logging/otlp/internal/metrics/OtlpStdoutMetricExporterComponentProvider.java create mode 100644 exporters/logging-otlp/src/main/java/io/opentelemetry/exporter/logging/otlp/internal/metrics/OtlpStdoutMetricExporterProvider.java rename exporters/logging-otlp/src/main/java/io/opentelemetry/exporter/logging/otlp/internal/{ => traces}/LoggingSpanExporterProvider.java (83%) create mode 100644 exporters/logging-otlp/src/main/java/io/opentelemetry/exporter/logging/otlp/internal/traces/OtlpStdoutSpanExporter.java create mode 100644 exporters/logging-otlp/src/main/java/io/opentelemetry/exporter/logging/otlp/internal/traces/OtlpStdoutSpanExporterBuilder.java create mode 100644 exporters/logging-otlp/src/main/java/io/opentelemetry/exporter/logging/otlp/internal/traces/OtlpStdoutSpanExporterComponentProvider.java create mode 100644 exporters/logging-otlp/src/main/java/io/opentelemetry/exporter/logging/otlp/internal/traces/OtlpStdoutSpanExporterProvider.java create mode 100644 exporters/logging-otlp/src/test/java/io/opentelemetry/exporter/logging/otlp/AbstractOtlpStdoutExporterTest.java create mode 100644 exporters/logging-otlp/src/test/java/io/opentelemetry/exporter/logging/otlp/OtlpStdoutMetricExporterTest.java create mode 100644 exporters/logging-otlp/src/test/java/io/opentelemetry/exporter/logging/otlp/OtlpStdoutSpanExporterTest.java create mode 100644 exporters/logging-otlp/src/test/resources/expected-metrics-wrapper.json create mode 100644 exporters/logging-otlp/src/test/resources/expected-metrics.json create mode 100644 exporters/logging-otlp/src/test/resources/expected-spans-wrapper.json create mode 100644 exporters/logging-otlp/src/test/resources/expected-spans.json diff --git a/exporters/common/src/main/java/io/opentelemetry/exporter/internal/ExporterBuilderUtil.java b/exporters/common/src/main/java/io/opentelemetry/exporter/internal/ExporterBuilderUtil.java index 81caace0178..4e05183bb1a 100644 --- a/exporters/common/src/main/java/io/opentelemetry/exporter/internal/ExporterBuilderUtil.java +++ b/exporters/common/src/main/java/io/opentelemetry/exporter/internal/ExporterBuilderUtil.java @@ -13,6 +13,8 @@ import io.opentelemetry.sdk.common.export.MemoryMode; import io.opentelemetry.sdk.metrics.Aggregation; import io.opentelemetry.sdk.metrics.InstrumentType; +import io.opentelemetry.sdk.metrics.data.AggregationTemporality; +import io.opentelemetry.sdk.metrics.export.AggregationTemporalitySelector; import io.opentelemetry.sdk.metrics.export.DefaultAggregationSelector; import io.opentelemetry.sdk.metrics.internal.aggregator.AggregationUtil; import java.net.URI; @@ -96,5 +98,95 @@ public static void configureHistogramDefaultAggregation( } } + /** + * Invoke the {@code aggregationTemporalitySelectorConsumer} with the configured {@link + * AggregationTemporality}. + */ + public static void configureOtlpAggregationTemporality( + ConfigProperties config, + Consumer aggregationTemporalitySelectorConsumer) { + String temporalityStr = config.getString("otel.exporter.otlp.metrics.temporality.preference"); + if (temporalityStr == null) { + return; + } + AggregationTemporalitySelector temporalitySelector; + switch (temporalityStr.toLowerCase(Locale.ROOT)) { + case "cumulative": + temporalitySelector = AggregationTemporalitySelector.alwaysCumulative(); + break; + case "delta": + temporalitySelector = AggregationTemporalitySelector.deltaPreferred(); + break; + case "lowmemory": + temporalitySelector = AggregationTemporalitySelector.lowMemory(); + break; + default: + throw new ConfigurationException("Unrecognized aggregation temporality: " + temporalityStr); + } + aggregationTemporalitySelectorConsumer.accept(temporalitySelector); + } + + public static void configureOtlpAggregationTemporality( + StructuredConfigProperties config, + Consumer aggregationTemporalitySelectorConsumer) { + String temporalityStr = config.getString("temporality_preference"); + if (temporalityStr == null) { + return; + } + AggregationTemporalitySelector temporalitySelector; + switch (temporalityStr.toLowerCase(Locale.ROOT)) { + case "cumulative": + temporalitySelector = AggregationTemporalitySelector.alwaysCumulative(); + break; + case "delta": + temporalitySelector = AggregationTemporalitySelector.deltaPreferred(); + break; + case "lowmemory": + temporalitySelector = AggregationTemporalitySelector.lowMemory(); + break; + default: + throw new ConfigurationException("Unrecognized temporality_preference: " + temporalityStr); + } + aggregationTemporalitySelectorConsumer.accept(temporalitySelector); + } + + /** + * Invoke the {@code defaultAggregationSelectorConsumer} with the configured {@link + * DefaultAggregationSelector}. + */ + public static void configureOtlpHistogramDefaultAggregation( + ConfigProperties config, + Consumer defaultAggregationSelectorConsumer) { + String defaultHistogramAggregation = + config.getString("otel.exporter.otlp.metrics.default.histogram.aggregation"); + if (defaultHistogramAggregation != null) { + configureHistogramDefaultAggregation( + defaultHistogramAggregation, defaultAggregationSelectorConsumer); + } + } + + /** + * Invoke the {@code defaultAggregationSelectorConsumer} with the configured {@link + * DefaultAggregationSelector}. + */ + public static void configureOtlpHistogramDefaultAggregation( + StructuredConfigProperties config, + Consumer defaultAggregationSelectorConsumer) { + String defaultHistogramAggregation = config.getString("default_histogram_aggregation"); + if (defaultHistogramAggregation == null) { + return; + } + if (AggregationUtil.aggregationName(Aggregation.base2ExponentialBucketHistogram()) + .equalsIgnoreCase(defaultHistogramAggregation)) { + defaultAggregationSelectorConsumer.accept( + DefaultAggregationSelector.getDefault() + .with(InstrumentType.HISTOGRAM, Aggregation.base2ExponentialBucketHistogram())); + } else if (!AggregationUtil.aggregationName(explicitBucketHistogram()) + .equalsIgnoreCase(defaultHistogramAggregation)) { + throw new ConfigurationException( + "Unrecognized default_histogram_aggregation: " + defaultHistogramAggregation); + } + } + private ExporterBuilderUtil() {} } diff --git a/exporters/logging-otlp/src/main/java/io/opentelemetry/exporter/logging/otlp/OtlpJsonLoggingMetricExporter.java b/exporters/logging-otlp/src/main/java/io/opentelemetry/exporter/logging/otlp/OtlpJsonLoggingMetricExporter.java index 0f66cc57c95..b42ef4acab7 100644 --- a/exporters/logging-otlp/src/main/java/io/opentelemetry/exporter/logging/otlp/OtlpJsonLoggingMetricExporter.java +++ b/exporters/logging-otlp/src/main/java/io/opentelemetry/exporter/logging/otlp/OtlpJsonLoggingMetricExporter.java @@ -5,21 +5,14 @@ package io.opentelemetry.exporter.logging.otlp; -import static io.opentelemetry.exporter.logging.otlp.internal.writer.JsonUtil.JSON_FACTORY; - -import com.fasterxml.jackson.core.JsonGenerator; -import com.fasterxml.jackson.core.io.SegmentedStringWriter; -import io.opentelemetry.exporter.internal.otlp.metrics.ResourceMetricsMarshaler; -import io.opentelemetry.exporter.logging.otlp.internal.writer.JsonUtil; +import io.opentelemetry.exporter.logging.otlp.internal.metrics.OtlpStdoutMetricExporter; +import io.opentelemetry.exporter.logging.otlp.internal.metrics.OtlpStdoutMetricExporterBuilder; import io.opentelemetry.sdk.common.CompletableResultCode; import io.opentelemetry.sdk.metrics.InstrumentType; import io.opentelemetry.sdk.metrics.data.AggregationTemporality; import io.opentelemetry.sdk.metrics.data.MetricData; import io.opentelemetry.sdk.metrics.export.MetricExporter; -import java.io.IOException; import java.util.Collection; -import java.util.concurrent.atomic.AtomicBoolean; -import java.util.logging.Level; import java.util.logging.Logger; /** @@ -31,16 +24,16 @@ public final class OtlpJsonLoggingMetricExporter implements MetricExporter { private static final Logger logger = Logger.getLogger(OtlpJsonLoggingMetricExporter.class.getName()); - private final AtomicBoolean isShutdown = new AtomicBoolean(); - private final AggregationTemporality aggregationTemporality; + private final OtlpStdoutMetricExporter delegate; + /** * Returns a new {@link OtlpJsonLoggingMetricExporter} with a aggregation temporality of {@link * AggregationTemporality#CUMULATIVE}. */ public static MetricExporter create() { - return new OtlpJsonLoggingMetricExporter(AggregationTemporality.CUMULATIVE); + return create(AggregationTemporality.CUMULATIVE); } /** @@ -48,13 +41,32 @@ public static MetricExporter create() { * aggregationTemporality}. */ public static MetricExporter create(AggregationTemporality aggregationTemporality) { - return new OtlpJsonLoggingMetricExporter(aggregationTemporality); + OtlpStdoutMetricExporter delegate = + new OtlpStdoutMetricExporterBuilder(logger).setWrapperJsonObject(false).build(); + return new OtlpJsonLoggingMetricExporter(delegate, aggregationTemporality); } - private OtlpJsonLoggingMetricExporter(AggregationTemporality aggregationTemporality) { + OtlpJsonLoggingMetricExporter( + OtlpStdoutMetricExporter delegate, AggregationTemporality aggregationTemporality) { + this.delegate = delegate; this.aggregationTemporality = aggregationTemporality; } + @Override + public CompletableResultCode export(Collection logs) { + return delegate.export(logs); + } + + @Override + public CompletableResultCode flush() { + return delegate.flush(); + } + + @Override + public CompletableResultCode shutdown() { + return delegate.shutdown(); + } + /** * Return the aggregation temporality. * @@ -69,41 +81,4 @@ public AggregationTemporality getPreferredTemporality() { public AggregationTemporality getAggregationTemporality(InstrumentType instrumentType) { return aggregationTemporality; } - - @Override - public CompletableResultCode export(Collection metrics) { - if (isShutdown.get()) { - return CompletableResultCode.ofFailure(); - } - - ResourceMetricsMarshaler[] allResourceMetrics = ResourceMetricsMarshaler.create(metrics); - for (ResourceMetricsMarshaler resourceMetrics : allResourceMetrics) { - SegmentedStringWriter sw = new SegmentedStringWriter(JSON_FACTORY._getBufferRecycler()); - try (JsonGenerator gen = JsonUtil.create(sw)) { - resourceMetrics.writeJsonTo(gen); - } catch (IOException e) { - // Shouldn't happen in practice, just skip it. - continue; - } - try { - logger.log(Level.INFO, sw.getAndClear()); - } catch (IOException e) { - logger.log(Level.WARNING, "Unable to read OTLP JSON metrics", e); - } - } - return CompletableResultCode.ofSuccess(); - } - - @Override - public CompletableResultCode flush() { - return CompletableResultCode.ofSuccess(); - } - - @Override - public CompletableResultCode shutdown() { - if (!isShutdown.compareAndSet(false, true)) { - logger.log(Level.INFO, "Calling shutdown() multiple times."); - } - return CompletableResultCode.ofSuccess(); - } } diff --git a/exporters/logging-otlp/src/main/java/io/opentelemetry/exporter/logging/otlp/OtlpJsonLoggingSpanExporter.java b/exporters/logging-otlp/src/main/java/io/opentelemetry/exporter/logging/otlp/OtlpJsonLoggingSpanExporter.java index cc944e9bab6..63901351326 100644 --- a/exporters/logging-otlp/src/main/java/io/opentelemetry/exporter/logging/otlp/OtlpJsonLoggingSpanExporter.java +++ b/exporters/logging-otlp/src/main/java/io/opentelemetry/exporter/logging/otlp/OtlpJsonLoggingSpanExporter.java @@ -5,19 +5,12 @@ package io.opentelemetry.exporter.logging.otlp; -import static io.opentelemetry.exporter.logging.otlp.internal.writer.JsonUtil.JSON_FACTORY; - -import com.fasterxml.jackson.core.JsonGenerator; -import com.fasterxml.jackson.core.io.SegmentedStringWriter; -import io.opentelemetry.exporter.internal.otlp.traces.ResourceSpansMarshaler; -import io.opentelemetry.exporter.logging.otlp.internal.writer.JsonUtil; +import io.opentelemetry.exporter.logging.otlp.internal.traces.OtlpStdoutSpanExporter; +import io.opentelemetry.exporter.logging.otlp.internal.traces.OtlpStdoutSpanExporterBuilder; import io.opentelemetry.sdk.common.CompletableResultCode; import io.opentelemetry.sdk.trace.data.SpanData; import io.opentelemetry.sdk.trace.export.SpanExporter; -import java.io.IOException; import java.util.Collection; -import java.util.concurrent.atomic.AtomicBoolean; -import java.util.logging.Level; import java.util.logging.Logger; /** @@ -29,49 +22,31 @@ public final class OtlpJsonLoggingSpanExporter implements SpanExporter { private static final Logger logger = Logger.getLogger(OtlpJsonLoggingSpanExporter.class.getName()); - private final AtomicBoolean isShutdown = new AtomicBoolean(); + private final OtlpStdoutSpanExporter delegate; /** Returns a new {@link OtlpJsonLoggingSpanExporter}. */ public static SpanExporter create() { - return new OtlpJsonLoggingSpanExporter(); + OtlpStdoutSpanExporter delegate = + new OtlpStdoutSpanExporterBuilder(logger).setWrapperJsonObject(false).build(); + return new OtlpJsonLoggingSpanExporter(delegate); } - private OtlpJsonLoggingSpanExporter() {} + OtlpJsonLoggingSpanExporter(OtlpStdoutSpanExporter delegate) { + this.delegate = delegate; + } @Override - public CompletableResultCode export(Collection spans) { - if (isShutdown.get()) { - return CompletableResultCode.ofFailure(); - } - - ResourceSpansMarshaler[] allResourceSpans = ResourceSpansMarshaler.create(spans); - for (ResourceSpansMarshaler resourceSpans : allResourceSpans) { - SegmentedStringWriter sw = new SegmentedStringWriter(JSON_FACTORY._getBufferRecycler()); - try (JsonGenerator gen = JsonUtil.create(sw)) { - resourceSpans.writeJsonTo(gen); - } catch (IOException e) { - // Shouldn't happen in practice, just skip it. - continue; - } - try { - logger.log(Level.INFO, sw.getAndClear()); - } catch (IOException e) { - logger.log(Level.WARNING, "Unable to read OTLP JSON spans", e); - } - } - return CompletableResultCode.ofSuccess(); + public CompletableResultCode export(Collection logs) { + return delegate.export(logs); } @Override public CompletableResultCode flush() { - return CompletableResultCode.ofSuccess(); + return delegate.flush(); } @Override public CompletableResultCode shutdown() { - if (!isShutdown.compareAndSet(false, true)) { - logger.log(Level.INFO, "Calling shutdown() multiple times."); - } - return CompletableResultCode.ofSuccess(); + return delegate.shutdown(); } } diff --git a/exporters/logging-otlp/src/main/java/io/opentelemetry/exporter/logging/otlp/internal/logs/LoggingLogRecordExporterProvider.java b/exporters/logging-otlp/src/main/java/io/opentelemetry/exporter/logging/otlp/internal/logs/LoggingLogRecordExporterProvider.java index a08aafee355..5e038f3c892 100644 --- a/exporters/logging-otlp/src/main/java/io/opentelemetry/exporter/logging/otlp/internal/logs/LoggingLogRecordExporterProvider.java +++ b/exporters/logging-otlp/src/main/java/io/opentelemetry/exporter/logging/otlp/internal/logs/LoggingLogRecordExporterProvider.java @@ -16,7 +16,8 @@ *

      This class is internal and is hence not for public use. Its APIs are unstable and can change * at any time. */ -public class LoggingLogRecordExporterProvider implements ConfigurableLogRecordExporterProvider { +public final class LoggingLogRecordExporterProvider + implements ConfigurableLogRecordExporterProvider { @Override public LogRecordExporter createExporter(ConfigProperties config) { diff --git a/exporters/logging-otlp/src/main/java/io/opentelemetry/exporter/logging/otlp/internal/logs/OtlpStdoutLogRecordExporter.java b/exporters/logging-otlp/src/main/java/io/opentelemetry/exporter/logging/otlp/internal/logs/OtlpStdoutLogRecordExporter.java index 6a7adb6f742..96331e56d23 100644 --- a/exporters/logging-otlp/src/main/java/io/opentelemetry/exporter/logging/otlp/internal/logs/OtlpStdoutLogRecordExporter.java +++ b/exporters/logging-otlp/src/main/java/io/opentelemetry/exporter/logging/otlp/internal/logs/OtlpStdoutLogRecordExporter.java @@ -23,7 +23,7 @@ *

      This class is internal and is hence not for public use. Its APIs are unstable and can change * at any time. */ -public class OtlpStdoutLogRecordExporter implements LogRecordExporter { +public final class OtlpStdoutLogRecordExporter implements LogRecordExporter { private static final Logger LOGGER = Logger.getLogger(OtlpStdoutLogRecordExporter.class.getName()); diff --git a/exporters/logging-otlp/src/main/java/io/opentelemetry/exporter/logging/otlp/internal/logs/OtlpStdoutLogRecordExporterComponentProvider.java b/exporters/logging-otlp/src/main/java/io/opentelemetry/exporter/logging/otlp/internal/logs/OtlpStdoutLogRecordExporterComponentProvider.java index 204f5673c08..0806b7f0b40 100644 --- a/exporters/logging-otlp/src/main/java/io/opentelemetry/exporter/logging/otlp/internal/logs/OtlpStdoutLogRecordExporterComponentProvider.java +++ b/exporters/logging-otlp/src/main/java/io/opentelemetry/exporter/logging/otlp/internal/logs/OtlpStdoutLogRecordExporterComponentProvider.java @@ -15,7 +15,7 @@ *

      This class is internal and is hence not for public use. Its APIs are unstable and can change * at any time. */ -public class OtlpStdoutLogRecordExporterComponentProvider +public final class OtlpStdoutLogRecordExporterComponentProvider implements ComponentProvider { @Override diff --git a/exporters/logging-otlp/src/main/java/io/opentelemetry/exporter/logging/otlp/internal/logs/OtlpStdoutLogRecordExporterProvider.java b/exporters/logging-otlp/src/main/java/io/opentelemetry/exporter/logging/otlp/internal/logs/OtlpStdoutLogRecordExporterProvider.java index b73262cea39..23ba0079295 100644 --- a/exporters/logging-otlp/src/main/java/io/opentelemetry/exporter/logging/otlp/internal/logs/OtlpStdoutLogRecordExporterProvider.java +++ b/exporters/logging-otlp/src/main/java/io/opentelemetry/exporter/logging/otlp/internal/logs/OtlpStdoutLogRecordExporterProvider.java @@ -15,7 +15,8 @@ *

      This class is internal and is hence not for public use. Its APIs are unstable and can change * at any time. */ -public class OtlpStdoutLogRecordExporterProvider implements ConfigurableLogRecordExporterProvider { +public final class OtlpStdoutLogRecordExporterProvider + implements ConfigurableLogRecordExporterProvider { @Override public LogRecordExporter createExporter(ConfigProperties config) { OtlpStdoutLogRecordExporterBuilder builder = OtlpStdoutLogRecordExporter.builder(); diff --git a/exporters/logging-otlp/src/main/java/io/opentelemetry/exporter/logging/otlp/internal/LoggingMetricExporterProvider.java b/exporters/logging-otlp/src/main/java/io/opentelemetry/exporter/logging/otlp/internal/metrics/LoggingMetricExporterProvider.java similarity index 83% rename from exporters/logging-otlp/src/main/java/io/opentelemetry/exporter/logging/otlp/internal/LoggingMetricExporterProvider.java rename to exporters/logging-otlp/src/main/java/io/opentelemetry/exporter/logging/otlp/internal/metrics/LoggingMetricExporterProvider.java index b5669b5426a..6748bbd99d1 100644 --- a/exporters/logging-otlp/src/main/java/io/opentelemetry/exporter/logging/otlp/internal/LoggingMetricExporterProvider.java +++ b/exporters/logging-otlp/src/main/java/io/opentelemetry/exporter/logging/otlp/internal/metrics/LoggingMetricExporterProvider.java @@ -3,7 +3,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -package io.opentelemetry.exporter.logging.otlp.internal; +package io.opentelemetry.exporter.logging.otlp.internal.metrics; import io.opentelemetry.exporter.logging.otlp.OtlpJsonLoggingMetricExporter; import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties; @@ -16,7 +16,8 @@ *

      This class is internal and is hence not for public use. Its APIs are unstable and can change * at any time. */ -public class LoggingMetricExporterProvider implements ConfigurableMetricExporterProvider { +public final class LoggingMetricExporterProvider implements ConfigurableMetricExporterProvider { + @Override public MetricExporter createExporter(ConfigProperties config) { return OtlpJsonLoggingMetricExporter.create(); diff --git a/exporters/logging-otlp/src/main/java/io/opentelemetry/exporter/logging/otlp/internal/metrics/OtlpStdoutMetricExporter.java b/exporters/logging-otlp/src/main/java/io/opentelemetry/exporter/logging/otlp/internal/metrics/OtlpStdoutMetricExporter.java new file mode 100644 index 00000000000..81e9bef105c --- /dev/null +++ b/exporters/logging-otlp/src/main/java/io/opentelemetry/exporter/logging/otlp/internal/metrics/OtlpStdoutMetricExporter.java @@ -0,0 +1,115 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.exporter.logging.otlp.internal.metrics; + +import io.opentelemetry.exporter.internal.otlp.metrics.MetricsRequestMarshaler; +import io.opentelemetry.exporter.internal.otlp.metrics.ResourceMetricsMarshaler; +import io.opentelemetry.exporter.logging.otlp.internal.writer.JsonWriter; +import io.opentelemetry.sdk.common.CompletableResultCode; +import io.opentelemetry.sdk.metrics.Aggregation; +import io.opentelemetry.sdk.metrics.InstrumentType; +import io.opentelemetry.sdk.metrics.data.AggregationTemporality; +import io.opentelemetry.sdk.metrics.data.MetricData; +import io.opentelemetry.sdk.metrics.export.AggregationTemporalitySelector; +import io.opentelemetry.sdk.metrics.export.DefaultAggregationSelector; +import io.opentelemetry.sdk.metrics.export.MetricExporter; +import java.util.Collection; +import java.util.StringJoiner; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.logging.Level; +import java.util.logging.Logger; + +/** + * Exporter for sending OTLP metrics to stdout. + * + *

      This class is internal and is hence not for public use. Its APIs are unstable and can change + * at any time. + */ +public final class OtlpStdoutMetricExporter implements MetricExporter { + + private static final Logger LOGGER = Logger.getLogger(OtlpStdoutMetricExporter.class.getName()); + + private final AtomicBoolean isShutdown = new AtomicBoolean(); + + private final Logger logger; + private final JsonWriter jsonWriter; + private final boolean wrapperJsonObject; + private final AggregationTemporalitySelector aggregationTemporalitySelector; + private final DefaultAggregationSelector defaultAggregationSelector; + + OtlpStdoutMetricExporter( + Logger logger, + JsonWriter jsonWriter, + boolean wrapperJsonObject, + AggregationTemporalitySelector aggregationTemporalitySelector, + DefaultAggregationSelector defaultAggregationSelector) { + this.logger = logger; + this.jsonWriter = jsonWriter; + this.wrapperJsonObject = wrapperJsonObject; + this.aggregationTemporalitySelector = aggregationTemporalitySelector; + this.defaultAggregationSelector = defaultAggregationSelector; + } + + /** Returns a new {@link OtlpStdoutMetricExporterBuilder}. */ + @SuppressWarnings("SystemOut") + public static OtlpStdoutMetricExporterBuilder builder() { + return new OtlpStdoutMetricExporterBuilder(LOGGER).setOutput(System.out); + } + + @Override + public AggregationTemporality getAggregationTemporality(InstrumentType instrumentType) { + return aggregationTemporalitySelector.getAggregationTemporality(instrumentType); + } + + @Override + public Aggregation getDefaultAggregation(InstrumentType instrumentType) { + return defaultAggregationSelector.getDefaultAggregation(instrumentType); + } + + @Override + public CompletableResultCode export(Collection metrics) { + if (isShutdown.get()) { + return CompletableResultCode.ofFailure(); + } + + if (wrapperJsonObject) { + MetricsRequestMarshaler request = MetricsRequestMarshaler.create(metrics); + return jsonWriter.write(request); + } else { + for (ResourceMetricsMarshaler resourceMetrics : ResourceMetricsMarshaler.create(metrics)) { + CompletableResultCode resultCode = jsonWriter.write(resourceMetrics); + if (!resultCode.isSuccess()) { + // already logged + return resultCode; + } + } + return CompletableResultCode.ofSuccess(); + } + } + + @Override + public CompletableResultCode flush() { + return jsonWriter.flush(); + } + + @Override + public CompletableResultCode shutdown() { + if (!isShutdown.compareAndSet(false, true)) { + logger.log(Level.INFO, "Calling shutdown() multiple times."); + } else { + jsonWriter.close(); + } + return CompletableResultCode.ofSuccess(); + } + + @Override + public String toString() { + StringJoiner joiner = new StringJoiner(", ", "OtlpStdoutMetricExporter{", "}"); + joiner.add("jsonWriter=" + jsonWriter); + joiner.add("wrapperJsonObject=" + wrapperJsonObject); + return joiner.toString(); + } +} diff --git a/exporters/logging-otlp/src/main/java/io/opentelemetry/exporter/logging/otlp/internal/metrics/OtlpStdoutMetricExporterBuilder.java b/exporters/logging-otlp/src/main/java/io/opentelemetry/exporter/logging/otlp/internal/metrics/OtlpStdoutMetricExporterBuilder.java new file mode 100644 index 00000000000..63f16c09060 --- /dev/null +++ b/exporters/logging-otlp/src/main/java/io/opentelemetry/exporter/logging/otlp/internal/metrics/OtlpStdoutMetricExporterBuilder.java @@ -0,0 +1,124 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.exporter.logging.otlp.internal.metrics; + +import static java.util.Objects.requireNonNull; + +import io.opentelemetry.exporter.logging.otlp.OtlpJsonLoggingMetricExporter; +import io.opentelemetry.exporter.logging.otlp.internal.writer.JsonWriter; +import io.opentelemetry.exporter.logging.otlp.internal.writer.LoggerJsonWriter; +import io.opentelemetry.exporter.logging.otlp.internal.writer.StreamJsonWriter; +import io.opentelemetry.sdk.metrics.InstrumentType; +import io.opentelemetry.sdk.metrics.export.AggregationTemporalitySelector; +import io.opentelemetry.sdk.metrics.export.DefaultAggregationSelector; +import io.opentelemetry.sdk.metrics.export.MetricExporter; +import java.io.OutputStream; +import java.util.logging.Logger; + +/** + * Builder for {@link OtlpJsonLoggingMetricExporter}. + * + *

      This class is internal and is hence not for public use. Its APIs are unstable and can change + * at any time. + */ +public final class OtlpStdoutMetricExporterBuilder { + + private static final String TYPE = "metrics"; + + private static final AggregationTemporalitySelector DEFAULT_AGGREGATION_TEMPORALITY_SELECTOR = + AggregationTemporalitySelector.alwaysCumulative(); + + private AggregationTemporalitySelector aggregationTemporalitySelector = + DEFAULT_AGGREGATION_TEMPORALITY_SELECTOR; + + private DefaultAggregationSelector defaultAggregationSelector = + DefaultAggregationSelector.getDefault(); + + private final Logger logger; + private JsonWriter jsonWriter; + private boolean wrapperJsonObject = true; + + public OtlpStdoutMetricExporterBuilder(Logger logger) { + this.logger = logger; + this.jsonWriter = new LoggerJsonWriter(logger, TYPE); + } + + /** + * Sets the exporter to use the specified JSON object wrapper. + * + * @param wrapperJsonObject whether to wrap the JSON object in an outer JSON "resourceMetrics" + * object. + */ + public OtlpStdoutMetricExporterBuilder setWrapperJsonObject(boolean wrapperJsonObject) { + this.wrapperJsonObject = wrapperJsonObject; + return this; + } + + /** + * Sets the exporter to use the specified output stream. + * + *

      The output stream will be closed when {@link OtlpStdoutMetricExporter#shutdown()} is called + * unless it's {@link System#out} or {@link System#err}. + * + * @param outputStream the output stream to use. + */ + public OtlpStdoutMetricExporterBuilder setOutput(OutputStream outputStream) { + requireNonNull(outputStream, "outputStream"); + this.jsonWriter = new StreamJsonWriter(outputStream, TYPE); + return this; + } + + /** Sets the exporter to use the specified logger. */ + public OtlpStdoutMetricExporterBuilder setOutput(Logger logger) { + requireNonNull(logger, "logger"); + this.jsonWriter = new LoggerJsonWriter(logger, TYPE); + return this; + } + + /** + * Set the {@link AggregationTemporalitySelector} used for {@link + * MetricExporter#getAggregationTemporality(InstrumentType)}. + * + *

      If unset, defaults to {@link AggregationTemporalitySelector#alwaysCumulative()}. + * + *

      {@link AggregationTemporalitySelector#deltaPreferred()} is a common configuration for delta + * backends. + */ + public OtlpStdoutMetricExporterBuilder setAggregationTemporalitySelector( + AggregationTemporalitySelector aggregationTemporalitySelector) { + requireNonNull(aggregationTemporalitySelector, "aggregationTemporalitySelector"); + this.aggregationTemporalitySelector = aggregationTemporalitySelector; + return this; + } + + /** + * Set the {@link DefaultAggregationSelector} used for {@link + * MetricExporter#getDefaultAggregation(InstrumentType)}. + * + *

      If unset, defaults to {@link DefaultAggregationSelector#getDefault()}. + */ + public OtlpStdoutMetricExporterBuilder setDefaultAggregationSelector( + DefaultAggregationSelector defaultAggregationSelector) { + requireNonNull(defaultAggregationSelector, "defaultAggregationSelector"); + this.defaultAggregationSelector = defaultAggregationSelector; + + return this; + } + + /** + * Constructs a new instance of the exporter based on the builder's values. + * + * @return a new exporter's instance + */ + public OtlpStdoutMetricExporter build() { + return new OtlpStdoutMetricExporter( + logger, + jsonWriter, + wrapperJsonObject, + aggregationTemporalitySelector, + defaultAggregationSelector); + } +} diff --git a/exporters/logging-otlp/src/main/java/io/opentelemetry/exporter/logging/otlp/internal/metrics/OtlpStdoutMetricExporterComponentProvider.java b/exporters/logging-otlp/src/main/java/io/opentelemetry/exporter/logging/otlp/internal/metrics/OtlpStdoutMetricExporterComponentProvider.java new file mode 100644 index 00000000000..dd8b3f643fa --- /dev/null +++ b/exporters/logging-otlp/src/main/java/io/opentelemetry/exporter/logging/otlp/internal/metrics/OtlpStdoutMetricExporterComponentProvider.java @@ -0,0 +1,41 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.exporter.logging.otlp.internal.metrics; + +import io.opentelemetry.exporter.internal.ExporterBuilderUtil; +import io.opentelemetry.sdk.autoconfigure.spi.internal.ComponentProvider; +import io.opentelemetry.sdk.autoconfigure.spi.internal.StructuredConfigProperties; +import io.opentelemetry.sdk.metrics.export.MetricExporter; + +/** + * File configuration SPI implementation for {@link OtlpStdoutMetricExporter}. + * + *

      This class is internal and is hence not for public use. Its APIs are unstable and can change + * at any time. + */ +public final class OtlpStdoutMetricExporterComponentProvider + implements ComponentProvider { + + @Override + public Class getType() { + return MetricExporter.class; + } + + @Override + public String getName() { + return "experimental-otlp/stdout"; + } + + @Override + public MetricExporter create(StructuredConfigProperties config) { + OtlpStdoutMetricExporterBuilder builder = OtlpStdoutMetricExporter.builder(); + ExporterBuilderUtil.configureOtlpAggregationTemporality( + config, builder::setAggregationTemporalitySelector); + ExporterBuilderUtil.configureOtlpHistogramDefaultAggregation( + config, builder::setDefaultAggregationSelector); + return builder.build(); + } +} diff --git a/exporters/logging-otlp/src/main/java/io/opentelemetry/exporter/logging/otlp/internal/metrics/OtlpStdoutMetricExporterProvider.java b/exporters/logging-otlp/src/main/java/io/opentelemetry/exporter/logging/otlp/internal/metrics/OtlpStdoutMetricExporterProvider.java new file mode 100644 index 00000000000..9eace851190 --- /dev/null +++ b/exporters/logging-otlp/src/main/java/io/opentelemetry/exporter/logging/otlp/internal/metrics/OtlpStdoutMetricExporterProvider.java @@ -0,0 +1,34 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.exporter.logging.otlp.internal.metrics; + +import io.opentelemetry.exporter.internal.ExporterBuilderUtil; +import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties; +import io.opentelemetry.sdk.autoconfigure.spi.metrics.ConfigurableMetricExporterProvider; +import io.opentelemetry.sdk.metrics.export.MetricExporter; + +/** + * {@link MetricExporter} SPI implementation for {@link OtlpStdoutMetricExporter}. + * + *

      This class is internal and is hence not for public use. Its APIs are unstable and can change + * at any time. + */ +public final class OtlpStdoutMetricExporterProvider implements ConfigurableMetricExporterProvider { + @Override + public MetricExporter createExporter(ConfigProperties config) { + OtlpStdoutMetricExporterBuilder builder = OtlpStdoutMetricExporter.builder(); + ExporterBuilderUtil.configureOtlpAggregationTemporality( + config, builder::setAggregationTemporalitySelector); + ExporterBuilderUtil.configureOtlpHistogramDefaultAggregation( + config, builder::setDefaultAggregationSelector); + return builder.build(); + } + + @Override + public String getName() { + return "experimental-otlp/stdout"; + } +} diff --git a/exporters/logging-otlp/src/main/java/io/opentelemetry/exporter/logging/otlp/internal/LoggingSpanExporterProvider.java b/exporters/logging-otlp/src/main/java/io/opentelemetry/exporter/logging/otlp/internal/traces/LoggingSpanExporterProvider.java similarity index 83% rename from exporters/logging-otlp/src/main/java/io/opentelemetry/exporter/logging/otlp/internal/LoggingSpanExporterProvider.java rename to exporters/logging-otlp/src/main/java/io/opentelemetry/exporter/logging/otlp/internal/traces/LoggingSpanExporterProvider.java index 6ce1856a894..6394acf78aa 100644 --- a/exporters/logging-otlp/src/main/java/io/opentelemetry/exporter/logging/otlp/internal/LoggingSpanExporterProvider.java +++ b/exporters/logging-otlp/src/main/java/io/opentelemetry/exporter/logging/otlp/internal/traces/LoggingSpanExporterProvider.java @@ -3,7 +3,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -package io.opentelemetry.exporter.logging.otlp.internal; +package io.opentelemetry.exporter.logging.otlp.internal.traces; import io.opentelemetry.exporter.logging.otlp.OtlpJsonLoggingSpanExporter; import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties; @@ -16,7 +16,8 @@ *

      This class is internal and is hence not for public use. Its APIs are unstable and can change * at any time. */ -public class LoggingSpanExporterProvider implements ConfigurableSpanExporterProvider { +public final class LoggingSpanExporterProvider implements ConfigurableSpanExporterProvider { + @Override public SpanExporter createExporter(ConfigProperties config) { return OtlpJsonLoggingSpanExporter.create(); diff --git a/exporters/logging-otlp/src/main/java/io/opentelemetry/exporter/logging/otlp/internal/traces/OtlpStdoutSpanExporter.java b/exporters/logging-otlp/src/main/java/io/opentelemetry/exporter/logging/otlp/internal/traces/OtlpStdoutSpanExporter.java new file mode 100644 index 00000000000..39c8829ef9b --- /dev/null +++ b/exporters/logging-otlp/src/main/java/io/opentelemetry/exporter/logging/otlp/internal/traces/OtlpStdoutSpanExporter.java @@ -0,0 +1,91 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.exporter.logging.otlp.internal.traces; + +import io.opentelemetry.exporter.internal.otlp.traces.ResourceSpansMarshaler; +import io.opentelemetry.exporter.internal.otlp.traces.TraceRequestMarshaler; +import io.opentelemetry.exporter.logging.otlp.internal.writer.JsonWriter; +import io.opentelemetry.sdk.common.CompletableResultCode; +import io.opentelemetry.sdk.trace.data.SpanData; +import io.opentelemetry.sdk.trace.export.SpanExporter; +import java.util.Collection; +import java.util.StringJoiner; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.logging.Level; +import java.util.logging.Logger; + +/** + * Exporter for sending OTLP spans to stdout. + * + *

      This class is internal and is hence not for public use. Its APIs are unstable and can change + * at any time. + */ +public final class OtlpStdoutSpanExporter implements SpanExporter { + + private static final Logger LOGGER = Logger.getLogger(OtlpStdoutSpanExporter.class.getName()); + + private final AtomicBoolean isShutdown = new AtomicBoolean(); + + private final Logger logger; + private final JsonWriter jsonWriter; + private final boolean wrapperJsonObject; + + OtlpStdoutSpanExporter(Logger logger, JsonWriter jsonWriter, boolean wrapperJsonObject) { + this.logger = logger; + this.jsonWriter = jsonWriter; + this.wrapperJsonObject = wrapperJsonObject; + } + + /** Returns a new {@link OtlpStdoutSpanExporterBuilder}. */ + @SuppressWarnings("SystemOut") + public static OtlpStdoutSpanExporterBuilder builder() { + return new OtlpStdoutSpanExporterBuilder(LOGGER).setOutput(System.out); + } + + @Override + public CompletableResultCode export(Collection spans) { + if (isShutdown.get()) { + return CompletableResultCode.ofFailure(); + } + + if (wrapperJsonObject) { + TraceRequestMarshaler request = TraceRequestMarshaler.create(spans); + return jsonWriter.write(request); + } else { + for (ResourceSpansMarshaler resourceSpans : ResourceSpansMarshaler.create(spans)) { + CompletableResultCode resultCode = jsonWriter.write(resourceSpans); + if (!resultCode.isSuccess()) { + // already logged + return resultCode; + } + } + return CompletableResultCode.ofSuccess(); + } + } + + @Override + public CompletableResultCode flush() { + return jsonWriter.flush(); + } + + @Override + public CompletableResultCode shutdown() { + if (!isShutdown.compareAndSet(false, true)) { + logger.log(Level.INFO, "Calling shutdown() multiple times."); + } else { + jsonWriter.close(); + } + return CompletableResultCode.ofSuccess(); + } + + @Override + public String toString() { + StringJoiner joiner = new StringJoiner(", ", "OtlpStdoutSpanExporter{", "}"); + joiner.add("jsonWriter=" + jsonWriter); + joiner.add("wrapperJsonObject=" + wrapperJsonObject); + return joiner.toString(); + } +} diff --git a/exporters/logging-otlp/src/main/java/io/opentelemetry/exporter/logging/otlp/internal/traces/OtlpStdoutSpanExporterBuilder.java b/exporters/logging-otlp/src/main/java/io/opentelemetry/exporter/logging/otlp/internal/traces/OtlpStdoutSpanExporterBuilder.java new file mode 100644 index 00000000000..2ca9e5a97b3 --- /dev/null +++ b/exporters/logging-otlp/src/main/java/io/opentelemetry/exporter/logging/otlp/internal/traces/OtlpStdoutSpanExporterBuilder.java @@ -0,0 +1,76 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.exporter.logging.otlp.internal.traces; + +import static java.util.Objects.requireNonNull; + +import io.opentelemetry.exporter.logging.otlp.OtlpJsonLoggingSpanExporter; +import io.opentelemetry.exporter.logging.otlp.internal.writer.JsonWriter; +import io.opentelemetry.exporter.logging.otlp.internal.writer.LoggerJsonWriter; +import io.opentelemetry.exporter.logging.otlp.internal.writer.StreamJsonWriter; +import java.io.OutputStream; +import java.util.logging.Logger; + +/** + * Builder for {@link OtlpJsonLoggingSpanExporter}. + * + *

      This class is internal and is hence not for public use. Its APIs are unstable and can change + * at any time. + */ +public final class OtlpStdoutSpanExporterBuilder { + + private static final String TYPE = "spans"; + + private final Logger logger; + private JsonWriter jsonWriter; + private boolean wrapperJsonObject = true; + + public OtlpStdoutSpanExporterBuilder(Logger logger) { + this.logger = logger; + this.jsonWriter = new LoggerJsonWriter(logger, TYPE); + } + + /** + * Sets the exporter to use the specified JSON object wrapper. + * + * @param wrapperJsonObject whether to wrap the JSON object in an outer JSON "resourceSpans" + * object. + */ + public OtlpStdoutSpanExporterBuilder setWrapperJsonObject(boolean wrapperJsonObject) { + this.wrapperJsonObject = wrapperJsonObject; + return this; + } + + /** + * Sets the exporter to use the specified output stream. + * + *

      The output stream will be closed when {@link OtlpStdoutSpanExporter#shutdown()} is called + * unless it's {@link System#out} or {@link System#err}. + * + * @param outputStream the output stream to use. + */ + public OtlpStdoutSpanExporterBuilder setOutput(OutputStream outputStream) { + requireNonNull(outputStream, "outputStream"); + this.jsonWriter = new StreamJsonWriter(outputStream, TYPE); + return this; + } + + /** Sets the exporter to use the specified logger. */ + public OtlpStdoutSpanExporterBuilder setOutput(Logger logger) { + requireNonNull(logger, "logger"); + this.jsonWriter = new LoggerJsonWriter(logger, TYPE); + return this; + } + + /** + * Constructs a new instance of the exporter based on the builder's values. + * + * @return a new exporter's instance + */ + public OtlpStdoutSpanExporter build() { + return new OtlpStdoutSpanExporter(logger, jsonWriter, wrapperJsonObject); + } +} diff --git a/exporters/logging-otlp/src/main/java/io/opentelemetry/exporter/logging/otlp/internal/traces/OtlpStdoutSpanExporterComponentProvider.java b/exporters/logging-otlp/src/main/java/io/opentelemetry/exporter/logging/otlp/internal/traces/OtlpStdoutSpanExporterComponentProvider.java new file mode 100644 index 00000000000..1d60e1a37b8 --- /dev/null +++ b/exporters/logging-otlp/src/main/java/io/opentelemetry/exporter/logging/otlp/internal/traces/OtlpStdoutSpanExporterComponentProvider.java @@ -0,0 +1,36 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.exporter.logging.otlp.internal.traces; + +import io.opentelemetry.sdk.autoconfigure.spi.internal.ComponentProvider; +import io.opentelemetry.sdk.autoconfigure.spi.internal.StructuredConfigProperties; +import io.opentelemetry.sdk.trace.export.SpanExporter; + +/** + * File configuration SPI implementation for {@link OtlpStdoutSpanExporter}. + * + *

      This class is internal and is hence not for public use. Its APIs are unstable and can change + * at any time. + */ +public final class OtlpStdoutSpanExporterComponentProvider + implements ComponentProvider { + + @Override + public Class getType() { + return SpanExporter.class; + } + + @Override + public String getName() { + return "experimental-otlp/stdout"; + } + + @Override + public SpanExporter create(StructuredConfigProperties config) { + OtlpStdoutSpanExporterBuilder builder = OtlpStdoutSpanExporter.builder(); + return builder.build(); + } +} diff --git a/exporters/logging-otlp/src/main/java/io/opentelemetry/exporter/logging/otlp/internal/traces/OtlpStdoutSpanExporterProvider.java b/exporters/logging-otlp/src/main/java/io/opentelemetry/exporter/logging/otlp/internal/traces/OtlpStdoutSpanExporterProvider.java new file mode 100644 index 00000000000..e5d2f008315 --- /dev/null +++ b/exporters/logging-otlp/src/main/java/io/opentelemetry/exporter/logging/otlp/internal/traces/OtlpStdoutSpanExporterProvider.java @@ -0,0 +1,29 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.exporter.logging.otlp.internal.traces; + +import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties; +import io.opentelemetry.sdk.autoconfigure.spi.traces.ConfigurableSpanExporterProvider; +import io.opentelemetry.sdk.trace.export.SpanExporter; + +/** + * {@link SpanExporter} SPI implementation for {@link OtlpStdoutSpanExporter}. + * + *

      This class is internal and is hence not for public use. Its APIs are unstable and can change + * at any time. + */ +public final class OtlpStdoutSpanExporterProvider implements ConfigurableSpanExporterProvider { + @Override + public SpanExporter createExporter(ConfigProperties config) { + OtlpStdoutSpanExporterBuilder builder = OtlpStdoutSpanExporter.builder(); + return builder.build(); + } + + @Override + public String getName() { + return "experimental-otlp/stdout"; + } +} diff --git a/exporters/logging-otlp/src/main/resources/META-INF/services/io.opentelemetry.sdk.autoconfigure.spi.internal.ComponentProvider b/exporters/logging-otlp/src/main/resources/META-INF/services/io.opentelemetry.sdk.autoconfigure.spi.internal.ComponentProvider index 76364a2dae4..b90ec18cc20 100644 --- a/exporters/logging-otlp/src/main/resources/META-INF/services/io.opentelemetry.sdk.autoconfigure.spi.internal.ComponentProvider +++ b/exporters/logging-otlp/src/main/resources/META-INF/services/io.opentelemetry.sdk.autoconfigure.spi.internal.ComponentProvider @@ -1 +1,3 @@ io.opentelemetry.exporter.logging.otlp.internal.logs.OtlpStdoutLogRecordExporterComponentProvider +io.opentelemetry.exporter.logging.otlp.internal.metrics.OtlpStdoutMetricExporterComponentProvider +io.opentelemetry.exporter.logging.otlp.internal.traces.OtlpStdoutSpanExporterComponentProvider diff --git a/exporters/logging-otlp/src/main/resources/META-INF/services/io.opentelemetry.sdk.autoconfigure.spi.metrics.ConfigurableMetricExporterProvider b/exporters/logging-otlp/src/main/resources/META-INF/services/io.opentelemetry.sdk.autoconfigure.spi.metrics.ConfigurableMetricExporterProvider index 2b532ca9a38..b1641bbe303 100644 --- a/exporters/logging-otlp/src/main/resources/META-INF/services/io.opentelemetry.sdk.autoconfigure.spi.metrics.ConfigurableMetricExporterProvider +++ b/exporters/logging-otlp/src/main/resources/META-INF/services/io.opentelemetry.sdk.autoconfigure.spi.metrics.ConfigurableMetricExporterProvider @@ -1 +1,3 @@ -io.opentelemetry.exporter.logging.otlp.internal.LoggingMetricExporterProvider +io.opentelemetry.exporter.logging.otlp.internal.metrics.LoggingMetricExporterProvider +io.opentelemetry.exporter.logging.otlp.internal.metrics.OtlpStdoutMetricExporterProvider + diff --git a/exporters/logging-otlp/src/main/resources/META-INF/services/io.opentelemetry.sdk.autoconfigure.spi.traces.ConfigurableSpanExporterProvider b/exporters/logging-otlp/src/main/resources/META-INF/services/io.opentelemetry.sdk.autoconfigure.spi.traces.ConfigurableSpanExporterProvider index fe444f4acf3..d1a8bfa347a 100644 --- a/exporters/logging-otlp/src/main/resources/META-INF/services/io.opentelemetry.sdk.autoconfigure.spi.traces.ConfigurableSpanExporterProvider +++ b/exporters/logging-otlp/src/main/resources/META-INF/services/io.opentelemetry.sdk.autoconfigure.spi.traces.ConfigurableSpanExporterProvider @@ -1 +1,2 @@ -io.opentelemetry.exporter.logging.otlp.internal.LoggingSpanExporterProvider +io.opentelemetry.exporter.logging.otlp.internal.traces.LoggingSpanExporterProvider +io.opentelemetry.exporter.logging.otlp.internal.traces.OtlpStdoutSpanExporterProvider diff --git a/exporters/logging-otlp/src/test/java/io/opentelemetry/exporter/logging/otlp/AbstractOtlpStdoutExporterTest.java b/exporters/logging-otlp/src/test/java/io/opentelemetry/exporter/logging/otlp/AbstractOtlpStdoutExporterTest.java new file mode 100644 index 00000000000..b18f432a4de --- /dev/null +++ b/exporters/logging-otlp/src/test/java/io/opentelemetry/exporter/logging/otlp/AbstractOtlpStdoutExporterTest.java @@ -0,0 +1,287 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.exporter.logging.otlp; + +import static java.util.Collections.emptyMap; +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.mock; + +import com.google.common.collect.ImmutableList; +import com.google.common.collect.Streams; +import io.github.netmikey.logunit.api.LogCapturer; +import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties; +import io.opentelemetry.sdk.autoconfigure.spi.internal.ComponentProvider; +import io.opentelemetry.sdk.autoconfigure.spi.internal.DefaultConfigProperties; +import io.opentelemetry.sdk.autoconfigure.spi.internal.StructuredConfigProperties; +import java.io.BufferedOutputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.io.PrintStream; +import java.io.UnsupportedEncodingException; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.ServiceLoader; +import java.util.concurrent.TimeUnit; +import java.util.stream.Stream; +import javax.annotation.Nullable; +import org.json.JSONException; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; +import org.junit.jupiter.api.io.TempDir; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; +import org.skyscreamer.jsonassert.JSONAssert; +import org.slf4j.event.LoggingEvent; + +abstract class AbstractOtlpStdoutExporterTest { + + private static PrintStream systemOut; + + private static final String TYPE = "experimental-otlp/stdout"; + + private static final ByteArrayOutputStream SYSTEM_OUT_STREAM = new ByteArrayOutputStream(); + private static final PrintStream SYSTEM_OUT_PRINT_STREAM = new PrintStream(SYSTEM_OUT_STREAM); + + @RegisterExtension LogCapturer logs; + private final String defaultConfigString; + private final TestDataExporter testDataExporter; + protected final Class exporterClass; + private final Class providerClass; + private final Class componentProviderType; + + @TempDir Path tempDir; + + public AbstractOtlpStdoutExporterTest( + TestDataExporter testDataExporter, + Class exporterClass, + Class providerClass, + Class componentProviderType, + String defaultConfigString) { + this.testDataExporter = testDataExporter; + this.exporterClass = exporterClass; + this.providerClass = providerClass; + logs = LogCapturer.create().captureForType(exporterClass); + this.defaultConfigString = defaultConfigString; + this.componentProviderType = componentProviderType; + } + + protected abstract T createExporter( + @Nullable OutputStream outputStream, boolean wrapperJsonObject); + + protected abstract T createDefaultExporter(); + + private String output(@Nullable OutputStream outputStream, @Nullable Path file) { + if (outputStream == null) { + return logs.getEvents().stream() + .map(LoggingEvent::getMessage) + .reduce("", (a, b) -> a + b + "\n") + .trim(); + } + + if (file != null) { + try { + return new String(Files.readAllBytes(file), StandardCharsets.UTF_8); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + + try { + return SYSTEM_OUT_STREAM.toString(StandardCharsets.UTF_8.name()); + } catch (UnsupportedEncodingException e) { + throw new RuntimeException(e); + } + } + + @BeforeAll + @SuppressWarnings("SystemOut") + static void setUpStatic() { + systemOut = System.out; + System.setOut(SYSTEM_OUT_PRINT_STREAM); + } + + @AfterAll + @SuppressWarnings("SystemOut") + static void tearDownStatic() { + System.setOut(systemOut); + } + + @BeforeEach + void setUp() { + SYSTEM_OUT_STREAM.reset(); + } + + enum OutputType { + LOGGER, + SYSTEM_OUT, + FILE, + FILE_AND_BUFFERED_WRITER + } + + public static class TestCase { + + private final boolean wrapperJsonObject; + private final OutputType outputType; + + public TestCase(OutputType outputType, boolean wrapperJsonObject) { + this.outputType = outputType; + this.wrapperJsonObject = wrapperJsonObject; + } + + public OutputType getOutputType() { + return outputType; + } + + public boolean isWrapperJsonObject() { + return wrapperJsonObject; + } + } + + static Stream exportTestCases() { + return ImmutableList.of( + testCase(OutputType.SYSTEM_OUT, /* wrapperJsonObject= */ true), + testCase(OutputType.SYSTEM_OUT, /* wrapperJsonObject= */ false), + testCase(OutputType.FILE, /* wrapperJsonObject= */ true), + testCase(OutputType.FILE, /* wrapperJsonObject= */ false), + testCase(OutputType.FILE_AND_BUFFERED_WRITER, /* wrapperJsonObject= */ true), + testCase(OutputType.FILE_AND_BUFFERED_WRITER, /* wrapperJsonObject= */ false), + testCase(OutputType.LOGGER, /* wrapperJsonObject= */ true), + testCase(OutputType.LOGGER, /* wrapperJsonObject= */ false)) + .stream(); + } + + private static Arguments testCase(OutputType type, boolean wrapperJsonObject) { + return Arguments.of( + "output=" + type + ", wrapperJsonObject=" + wrapperJsonObject, + new TestCase(type, wrapperJsonObject)); + } + + @SuppressWarnings("SystemOut") + @ParameterizedTest(name = "{0}") + @MethodSource("exportTestCases") + void exportWithProgrammaticConfig(String name, TestCase testCase) + throws JSONException, IOException { + OutputStream outputStream; + Path file = null; + switch (testCase.getOutputType()) { + case LOGGER: + outputStream = null; + break; + case SYSTEM_OUT: + outputStream = System.out; + break; + case FILE: + file = tempDir.resolve("test.log"); + outputStream = Files.newOutputStream(file); + break; + case FILE_AND_BUFFERED_WRITER: + file = tempDir.resolve("test.log"); + outputStream = new BufferedOutputStream(Files.newOutputStream(file)); + break; + default: + throw new IllegalStateException("Unexpected value: " + testCase.getOutputType()); + } + T exporter = createExporter(outputStream, testCase.isWrapperJsonObject()); + testDataExporter.export(exporter); + + String output = output(outputStream, file); + String expectedJson = testDataExporter.getExpectedJson(testCase.isWrapperJsonObject()); + JSONAssert.assertEquals("Got \n" + output, expectedJson, output, false); + + if (testCase.isWrapperJsonObject()) { + assertThat(output).doesNotContain("\n"); + } + } + + @Test + void testShutdown() { + T exporter = createDefaultExporter(); + assertThat(testDataExporter.shutdown(exporter).isSuccess()).isTrue(); + assertThat(testDataExporter.export(exporter).join(10, TimeUnit.SECONDS).isSuccess()).isFalse(); + assertThat(testDataExporter.flush(exporter).join(10, TimeUnit.SECONDS).isSuccess()).isTrue(); + assertThat(output(null, null)).isEmpty(); + assertThat(testDataExporter.shutdown(exporter).isSuccess()).isTrue(); + logs.assertContains("Calling shutdown() multiple times."); + } + + @Test + void defaultToString() { + assertFullToString(createDefaultExporter(), defaultConfigString); + + assertFullToString( + loadExporter(DefaultConfigProperties.createFromMap(emptyMap())), defaultConfigString); + } + + protected Object exporterFromComponentProvider(StructuredConfigProperties properties) { + return ((ComponentProvider) + loadSpi(ComponentProvider.class) + .filter( + p -> { + ComponentProvider c = (ComponentProvider) p; + return "experimental-otlp/stdout".equals(c.getName()) + && c.getType().equals(componentProviderType); + }) + .findFirst() + .orElseThrow(() -> new IllegalStateException("No provider found"))) + .create(properties); + } + + @Test + void componentProviderConfig() { + StructuredConfigProperties properties = mock(StructuredConfigProperties.class); + Object exporter = exporterFromComponentProvider(properties); + + assertThat(exporter).extracting("wrapperJsonObject").isEqualTo(true); + assertThat(exporter) + .extracting("jsonWriter") + .extracting(Object::toString) + .isEqualTo("StreamJsonWriter{outputStream=stdout}"); + } + + @SuppressWarnings("unchecked") + protected T loadExporter(ConfigProperties config) { + Object provider = loadProvider(); + + try { + return (T) + provider + .getClass() + .getDeclaredMethod("createExporter", ConfigProperties.class) + .invoke(provider, config); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + private Object loadProvider() { + return loadSpi(providerClass) + .filter( + p -> { + try { + return AbstractOtlpStdoutExporterTest.TYPE.equals( + p.getClass().getDeclaredMethod("getName").invoke(p)); + } catch (Exception e) { + throw new RuntimeException(e); + } + }) + .findFirst() + .orElseThrow(() -> new IllegalStateException("No provider found")); + } + + protected static Stream loadSpi(Class type) { + return Streams.stream(ServiceLoader.load(type, type.getClassLoader()).iterator()); + } + + private void assertFullToString(T exporter, String expected) { + assertThat(exporter.toString()).isEqualTo(expected); + } +} diff --git a/exporters/logging-otlp/src/test/java/io/opentelemetry/exporter/logging/otlp/OtlpJsonLoggingMetricExporterTest.java b/exporters/logging-otlp/src/test/java/io/opentelemetry/exporter/logging/otlp/OtlpJsonLoggingMetricExporterTest.java index 287ec7b74a1..ccbfdb26dce 100644 --- a/exporters/logging-otlp/src/test/java/io/opentelemetry/exporter/logging/otlp/OtlpJsonLoggingMetricExporterTest.java +++ b/exporters/logging-otlp/src/test/java/io/opentelemetry/exporter/logging/otlp/OtlpJsonLoggingMetricExporterTest.java @@ -5,22 +5,13 @@ package io.opentelemetry.exporter.logging.otlp; -import static io.opentelemetry.api.common.AttributeKey.stringKey; import static org.assertj.core.api.Assertions.assertThat; import io.github.netmikey.logunit.api.LogCapturer; -import io.opentelemetry.api.common.Attributes; import io.opentelemetry.internal.testing.slf4j.SuppressLogger; -import io.opentelemetry.sdk.common.InstrumentationScopeInfo; import io.opentelemetry.sdk.metrics.InstrumentType; import io.opentelemetry.sdk.metrics.data.AggregationTemporality; -import io.opentelemetry.sdk.metrics.data.MetricData; import io.opentelemetry.sdk.metrics.export.MetricExporter; -import io.opentelemetry.sdk.metrics.internal.data.ImmutableDoublePointData; -import io.opentelemetry.sdk.metrics.internal.data.ImmutableMetricData; -import io.opentelemetry.sdk.metrics.internal.data.ImmutableSumData; -import io.opentelemetry.sdk.resources.Resource; -import java.util.Arrays; import java.util.Collections; import java.util.concurrent.TimeUnit; import org.junit.jupiter.api.BeforeEach; @@ -32,39 +23,7 @@ @SuppressLogger(OtlpJsonLoggingMetricExporter.class) class OtlpJsonLoggingMetricExporterTest { - private static final Resource RESOURCE = - Resource.create(Attributes.builder().put("key", "value").build()); - - private static final MetricData METRIC1 = - ImmutableMetricData.createDoubleSum( - RESOURCE, - InstrumentationScopeInfo.builder("instrumentation") - .setVersion("1") - .setAttributes(Attributes.builder().put("key", "value").build()) - .build(), - "metric1", - "metric1 description", - "m", - ImmutableSumData.create( - true, - AggregationTemporality.CUMULATIVE, - Arrays.asList( - ImmutableDoublePointData.create( - 1, 2, Attributes.of(stringKey("cat"), "meow"), 4)))); - - private static final MetricData METRIC2 = - ImmutableMetricData.createDoubleSum( - RESOURCE, - InstrumentationScopeInfo.builder("instrumentation2").setVersion("2").build(), - "metric2", - "metric2 description", - "s", - ImmutableSumData.create( - true, - AggregationTemporality.CUMULATIVE, - Arrays.asList( - ImmutableDoublePointData.create( - 1, 2, Attributes.of(stringKey("cat"), "meow"), 4)))); + private final TestDataExporter testDataExporter = TestDataExporter.forMetrics(); @RegisterExtension LogCapturer logs = LogCapturer.create().captureForType(OtlpJsonLoggingMetricExporter.class); @@ -90,78 +49,15 @@ void getAggregationTemporality() { @Test void log() throws Exception { - exporter.export(Arrays.asList(METRIC1, METRIC2)); + testDataExporter.export(exporter); assertThat(logs.getEvents()) .hasSize(1) .allSatisfy(log -> assertThat(log.getLevel()).isEqualTo(Level.INFO)); - JSONAssert.assertEquals( - "{" - + " \"resource\": {" - + " \"attributes\": [{" - + " \"key\": \"key\"," - + " \"value\": {" - + " \"stringValue\": \"value\"" - + " }" - + " }]" - + " }," - + " \"scopeMetrics\": [{" - + " \"scope\": {" - + " \"name\": \"instrumentation2\"," - + " \"version\": \"2\"" - + " }," - + " \"metrics\": [{" - + " \"name\": \"metric2\"," - + " \"description\": \"metric2 description\"," - + " \"unit\": \"s\"," - + " \"sum\": {" - + " \"dataPoints\": [{" - + " \"attributes\": [{" - + " \"key\": \"cat\"," - + " \"value\": {\"stringValue\": \"meow\"}" - + " }]," - + " \"startTimeUnixNano\": \"1\"," - + " \"timeUnixNano\": \"2\"," - + " \"asDouble\": 4.0" - + " }]," - + " \"aggregationTemporality\": 2," - + " \"isMonotonic\": true" - + " }" - + " }]" - + " }, {" - + " \"scope\": {" - + " \"name\": \"instrumentation\"," - + " \"version\": \"1\"," - + " \"attributes\":[{" - + " \"key\":\"key\"," - + " \"value\":{" - + " \"stringValue\":\"value\"" - + " }" - + " }]" - + " }," - + " \"metrics\": [{" - + " \"name\": \"metric1\"," - + " \"description\": \"metric1 description\"," - + " \"unit\": \"m\"," - + " \"sum\": {" - + " \"dataPoints\": [{" - + " \"attributes\": [{" - + " \"key\": \"cat\"," - + " \"value\": {\"stringValue\": \"meow\"}" - + " }]," - + " \"startTimeUnixNano\": \"1\"," - + " \"timeUnixNano\": \"2\"," - + " \"asDouble\": 4.0" - + " }]," - + " \"aggregationTemporality\": 2," - + " \"isMonotonic\": true" - + " }" - + " }]" - + " }]" - + "}", - logs.getEvents().get(0).getMessage(), - /* strict= */ false); - assertThat(logs.getEvents().get(0).getMessage()).doesNotContain("\n"); + String message = logs.getEvents().get(0).getMessage(); + String expectedJson = testDataExporter.getExpectedJson(false); + JSONAssert.assertEquals("Got \n" + message, expectedJson, message, /* strict= */ false); + assertThat(message).doesNotContain("\n"); } @Test @@ -174,7 +70,7 @@ void shutdown() { assertThat(exporter.shutdown().isSuccess()).isTrue(); assertThat( exporter - .export(Collections.singletonList(METRIC1)) + .export(Collections.singletonList(TestDataExporter.METRIC1)) .join(10, TimeUnit.SECONDS) .isSuccess()) .isFalse(); diff --git a/exporters/logging-otlp/src/test/java/io/opentelemetry/exporter/logging/otlp/OtlpJsonLoggingSpanExporterTest.java b/exporters/logging-otlp/src/test/java/io/opentelemetry/exporter/logging/otlp/OtlpJsonLoggingSpanExporterTest.java index 309cf7afaf0..ac3129f4a1c 100644 --- a/exporters/logging-otlp/src/test/java/io/opentelemetry/exporter/logging/otlp/OtlpJsonLoggingSpanExporterTest.java +++ b/exporters/logging-otlp/src/test/java/io/opentelemetry/exporter/logging/otlp/OtlpJsonLoggingSpanExporterTest.java @@ -5,26 +5,11 @@ package io.opentelemetry.exporter.logging.otlp; -import static io.opentelemetry.api.common.AttributeKey.booleanKey; -import static io.opentelemetry.api.common.AttributeKey.longKey; -import static io.opentelemetry.api.common.AttributeKey.stringKey; import static org.assertj.core.api.Assertions.assertThat; import io.github.netmikey.logunit.api.LogCapturer; -import io.opentelemetry.api.common.Attributes; -import io.opentelemetry.api.trace.SpanContext; -import io.opentelemetry.api.trace.SpanKind; -import io.opentelemetry.api.trace.TraceFlags; -import io.opentelemetry.api.trace.TraceState; import io.opentelemetry.internal.testing.slf4j.SuppressLogger; -import io.opentelemetry.sdk.common.InstrumentationScopeInfo; -import io.opentelemetry.sdk.resources.Resource; -import io.opentelemetry.sdk.testing.trace.TestSpanData; -import io.opentelemetry.sdk.trace.data.EventData; -import io.opentelemetry.sdk.trace.data.SpanData; -import io.opentelemetry.sdk.trace.data.StatusData; import io.opentelemetry.sdk.trace.export.SpanExporter; -import java.util.Arrays; import java.util.Collections; import java.util.concurrent.TimeUnit; import org.junit.jupiter.api.BeforeEach; @@ -36,59 +21,7 @@ @SuppressLogger(OtlpJsonLoggingSpanExporter.class) class OtlpJsonLoggingSpanExporterTest { - private static final Resource RESOURCE = - Resource.create(Attributes.builder().put("key", "value").build()); - - private static final SpanData SPAN1 = - TestSpanData.builder() - .setHasEnded(true) - .setSpanContext( - SpanContext.create( - "12345678876543211234567887654321", - "8765432112345678", - TraceFlags.getSampled(), - TraceState.getDefault())) - .setStartEpochNanos(100) - .setEndEpochNanos(100 + 1000) - .setStatus(StatusData.ok()) - .setName("testSpan1") - .setKind(SpanKind.INTERNAL) - .setAttributes(Attributes.of(stringKey("animal"), "cat", longKey("lives"), 9L)) - .setEvents( - Collections.singletonList( - EventData.create( - 100 + 500, - "somethingHappenedHere", - Attributes.of(booleanKey("important"), true)))) - .setTotalAttributeCount(2) - .setTotalRecordedEvents(1) - .setTotalRecordedLinks(0) - .setInstrumentationScopeInfo( - InstrumentationScopeInfo.builder("instrumentation") - .setVersion("1") - .setAttributes(Attributes.builder().put("key", "value").build()) - .build()) - .setResource(RESOURCE) - .build(); - - private static final SpanData SPAN2 = - TestSpanData.builder() - .setHasEnded(false) - .setSpanContext( - SpanContext.create( - "12340000000043211234000000004321", - "8765000000005678", - TraceFlags.getSampled(), - TraceState.getDefault())) - .setStartEpochNanos(500) - .setEndEpochNanos(500 + 1001) - .setStatus(StatusData.error()) - .setName("testSpan2") - .setKind(SpanKind.CLIENT) - .setResource(RESOURCE) - .setInstrumentationScopeInfo( - InstrumentationScopeInfo.builder("instrumentation2").setVersion("2").build()) - .build(); + private final TestDataExporter testDataExporter = TestDataExporter.forSpans(); @RegisterExtension LogCapturer logs = LogCapturer.create().captureForType(OtlpJsonLoggingSpanExporter.class); @@ -102,85 +35,14 @@ void setUp() { @Test void log() throws Exception { - exporter.export(Arrays.asList(SPAN1, SPAN2)); + testDataExporter.export(exporter); assertThat(logs.getEvents()) .hasSize(1) .allSatisfy(log -> assertThat(log.getLevel()).isEqualTo(Level.INFO)); String message = logs.getEvents().get(0).getMessage(); - JSONAssert.assertEquals( - "{" - + " \"resource\": {" - + " \"attributes\": [{" - + " \"key\": \"key\"," - + " \"value\": {" - + " \"stringValue\": \"value\"" - + " }" - + " }]" - + " }," - + " \"scopeSpans\": [{" - + " \"scope\": {" - + " \"name\": \"instrumentation2\"," - + " \"version\": \"2\"" - + " }," - + " \"spans\": [{" - + " \"traceId\": \"12340000000043211234000000004321\"," - + " \"spanId\": \"8765000000005678\"," - + " \"name\": \"testSpan2\"," - + " \"kind\": 3," - + " \"startTimeUnixNano\": \"500\"," - + " \"endTimeUnixNano\": \"1501\"," - + " \"status\": {" - + " \"code\": 2" - + " }" - + " }]" - + " }, {" - + " \"scope\": {" - + " \"name\": \"instrumentation\"," - + " \"version\": \"1\"," - + " \"attributes\":[{" - + " \"key\":\"key\"," - + " \"value\":{" - + " \"stringValue\":\"value\"" - + " }" - + " }]" - + " }," - + " \"spans\": [{" - + " \"traceId\": \"12345678876543211234567887654321\"," - + " \"spanId\": \"8765432112345678\"," - + " \"name\": \"testSpan1\"," - + " \"kind\": 1," - + " \"startTimeUnixNano\": \"100\"," - + " \"endTimeUnixNano\": \"1100\"," - + " \"attributes\": [{" - + " \"key\": \"animal\"," - + " \"value\": {" - + " \"stringValue\": \"cat\"" - + " }" - + " }, {" - + " \"key\": \"lives\"," - + " \"value\": {" - + " \"intValue\": \"9\"" - + " }" - + " }]," - + " \"events\": [{" - + " \"timeUnixNano\": \"600\"," - + " \"name\": \"somethingHappenedHere\"," - + " \"attributes\": [{" - + " \"key\": \"important\"," - + " \"value\": {" - + " \"boolValue\": true" - + " }" - + " }]" - + " }]," - + " \"status\": {" - + " \"code\": 1" - + " }" - + " }]" - + " }]" - + "}", - message, - /* strict= */ false); + String expectedJson = testDataExporter.getExpectedJson(false); + JSONAssert.assertEquals("Got \n" + message, expectedJson, message, /* strict= */ false); assertThat(message).doesNotContain("\n"); } @@ -194,7 +56,7 @@ void shutdown() { assertThat(exporter.shutdown().isSuccess()).isTrue(); assertThat( exporter - .export(Collections.singletonList(SPAN1)) + .export(Collections.singletonList(TestDataExporter.SPAN1)) .join(10, TimeUnit.SECONDS) .isSuccess()) .isFalse(); diff --git a/exporters/logging-otlp/src/test/java/io/opentelemetry/exporter/logging/otlp/OtlpStdoutLogRecordExporterTest.java b/exporters/logging-otlp/src/test/java/io/opentelemetry/exporter/logging/otlp/OtlpStdoutLogRecordExporterTest.java index f98b81b69af..e234b9745dc 100644 --- a/exporters/logging-otlp/src/test/java/io/opentelemetry/exporter/logging/otlp/OtlpStdoutLogRecordExporterTest.java +++ b/exporters/logging-otlp/src/test/java/io/opentelemetry/exporter/logging/otlp/OtlpStdoutLogRecordExporterTest.java @@ -5,283 +5,41 @@ package io.opentelemetry.exporter.logging.otlp; -import static java.util.Collections.emptyMap; -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.Mockito.mock; - -import com.google.common.collect.ImmutableList; -import com.google.common.collect.Streams; -import io.github.netmikey.logunit.api.LogCapturer; import io.opentelemetry.exporter.logging.otlp.internal.logs.OtlpStdoutLogRecordExporter; import io.opentelemetry.exporter.logging.otlp.internal.logs.OtlpStdoutLogRecordExporterBuilder; -import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties; -import io.opentelemetry.sdk.autoconfigure.spi.internal.ComponentProvider; -import io.opentelemetry.sdk.autoconfigure.spi.internal.DefaultConfigProperties; -import io.opentelemetry.sdk.autoconfigure.spi.internal.StructuredConfigProperties; import io.opentelemetry.sdk.autoconfigure.spi.logs.ConfigurableLogRecordExporterProvider; import io.opentelemetry.sdk.logs.export.LogRecordExporter; -import java.io.BufferedOutputStream; -import java.io.ByteArrayOutputStream; -import java.io.IOException; import java.io.OutputStream; -import java.io.PrintStream; -import java.io.UnsupportedEncodingException; -import java.nio.charset.StandardCharsets; -import java.nio.file.Files; -import java.nio.file.Path; -import java.util.ServiceLoader; -import java.util.concurrent.TimeUnit; import java.util.logging.Logger; -import java.util.stream.Stream; import javax.annotation.Nullable; -import org.json.JSONException; -import org.junit.jupiter.api.AfterAll; -import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.RegisterExtension; -import org.junit.jupiter.api.io.TempDir; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.Arguments; -import org.junit.jupiter.params.provider.MethodSource; -import org.skyscreamer.jsonassert.JSONAssert; -import org.slf4j.event.LoggingEvent; - -class OtlpStdoutLogRecordExporterTest { - - private static final ByteArrayOutputStream SYSTEM_OUT_STREAM = new ByteArrayOutputStream(); - private static final PrintStream SYSTEM_OUT_PRINT_STREAM = new PrintStream(SYSTEM_OUT_STREAM); - private static PrintStream systemOut; - private static final Class EXPORTER_CLASS = OtlpStdoutLogRecordExporter.class; - private static final String DEFAULT_CONFIG_STRING = - "OtlpStdoutLogRecordExporter{jsonWriter=StreamJsonWriter{outputStream=stdout}, wrapperJsonObject=true}"; - private static final String TYPE = "experimental-otlp/stdout"; - private static final TestDataExporter TEST_DATA_EXPORTER = - TestDataExporter.forLogs(); - private static final Class PROVIDER_CLASS = ConfigurableLogRecordExporterProvider.class; - private static final Class COMPONENT_PROVIDER_TYPE = LogRecordExporter.class; - - @RegisterExtension - LogCapturer logs = LogCapturer.create().captureForType(OtlpStdoutLogRecordExporter.class); - - @TempDir Path tempDir; - - @BeforeAll - @SuppressWarnings("SystemOut") - static void setUpStatic() { - systemOut = System.out; - System.setOut(SYSTEM_OUT_PRINT_STREAM); - } - @AfterAll - @SuppressWarnings("SystemOut") - static void tearDownStatic() { - System.setOut(systemOut); - } - - @BeforeEach - void setUp() { - SYSTEM_OUT_STREAM.reset(); - } - - static Stream exportTestCases() { - return ImmutableList.of( - testCase(OutputType.SYSTEM_OUT, /* wrapperJsonObject= */ true), - testCase(OutputType.SYSTEM_OUT, /* wrapperJsonObject= */ false), - testCase(OutputType.FILE, /* wrapperJsonObject= */ true), - testCase(OutputType.FILE, /* wrapperJsonObject= */ false), - testCase(OutputType.FILE_AND_BUFFERED_WRITER, /* wrapperJsonObject= */ true), - testCase(OutputType.FILE_AND_BUFFERED_WRITER, /* wrapperJsonObject= */ false), - testCase(OutputType.LOGGER, /* wrapperJsonObject= */ true), - testCase(OutputType.LOGGER, /* wrapperJsonObject= */ false)) - .stream(); - } - - private static Arguments testCase(OutputType type, boolean wrapperJsonObject) { - return Arguments.of( - "output=" + type + ", wrapperJsonObject=" + wrapperJsonObject, - new TestCase(type, wrapperJsonObject)); - } +class OtlpStdoutLogRecordExporterTest + extends AbstractOtlpStdoutExporterTest { - private static Stream loadSpi(Class type) { - return Streams.stream(ServiceLoader.load(type, type.getClassLoader()).iterator()); + public OtlpStdoutLogRecordExporterTest() { + super( + TestDataExporter.forLogs(), + OtlpStdoutLogRecordExporter.class, + ConfigurableLogRecordExporterProvider.class, + LogRecordExporter.class, + "OtlpStdoutLogRecordExporter{jsonWriter=StreamJsonWriter{outputStream=stdout}, wrapperJsonObject=true}"); } - private static OtlpStdoutLogRecordExporter createDefaultExporter() { + @Override + protected OtlpStdoutLogRecordExporter createDefaultExporter() { return OtlpStdoutLogRecordExporter.builder().build(); } - private static OtlpStdoutLogRecordExporter createExporter( + @Override + protected OtlpStdoutLogRecordExporter createExporter( @Nullable OutputStream outputStream, boolean wrapperJsonObject) { OtlpStdoutLogRecordExporterBuilder builder = OtlpStdoutLogRecordExporter.builder().setWrapperJsonObject(wrapperJsonObject); if (outputStream != null) { builder.setOutput(outputStream); } else { - builder.setOutput(Logger.getLogger(EXPORTER_CLASS.getName())); + builder.setOutput(Logger.getLogger(exporterClass.getName())); } return builder.build(); } - - private String output(@Nullable OutputStream outputStream, @Nullable Path file) { - if (outputStream == null) { - return logs.getEvents().stream() - .map(LoggingEvent::getMessage) - .reduce("", (a, b) -> a + b + "\n") - .trim(); - } - - if (file != null) { - try { - return new String(Files.readAllBytes(file), StandardCharsets.UTF_8); - } catch (IOException e) { - throw new RuntimeException(e); - } - } - - try { - return SYSTEM_OUT_STREAM.toString(StandardCharsets.UTF_8.name()); - } catch (UnsupportedEncodingException e) { - throw new RuntimeException(e); - } - } - - @SuppressWarnings("SystemOut") - @ParameterizedTest(name = "{0}") - @MethodSource("exportTestCases") - void exportWithProgrammaticConfig(String name, TestCase testCase) - throws JSONException, IOException { - OutputStream outputStream; - Path file = null; - switch (testCase.getOutputType()) { - case LOGGER: - outputStream = null; - break; - case SYSTEM_OUT: - outputStream = System.out; - break; - case FILE: - file = tempDir.resolve("test.log"); - outputStream = Files.newOutputStream(file); - break; - case FILE_AND_BUFFERED_WRITER: - file = tempDir.resolve("test.log"); - outputStream = new BufferedOutputStream(Files.newOutputStream(file)); - break; - default: - throw new IllegalStateException("Unexpected value: " + testCase.getOutputType()); - } - OtlpStdoutLogRecordExporter exporter = - createExporter(outputStream, testCase.isWrapperJsonObject()); - TEST_DATA_EXPORTER.export(exporter); - - String output = output(outputStream, file); - String expectedJson = TEST_DATA_EXPORTER.getExpectedJson(testCase.isWrapperJsonObject()); - JSONAssert.assertEquals("Got \n" + output, expectedJson, output, false); - - if (testCase.isWrapperJsonObject()) { - assertThat(output).doesNotContain("\n"); - } - } - - @Test - void testShutdown() { - OtlpStdoutLogRecordExporter exporter = createDefaultExporter(); - assertThat(TEST_DATA_EXPORTER.shutdown(exporter).isSuccess()).isTrue(); - assertThat(TEST_DATA_EXPORTER.export(exporter).join(10, TimeUnit.SECONDS).isSuccess()) - .isFalse(); - assertThat(TEST_DATA_EXPORTER.flush(exporter).join(10, TimeUnit.SECONDS).isSuccess()).isTrue(); - assertThat(output(null, null)).isEmpty(); - assertThat(TEST_DATA_EXPORTER.shutdown(exporter).isSuccess()).isTrue(); - logs.assertContains("Calling shutdown() multiple times."); - } - - @Test - void defaultToString() { - assertThat(createDefaultExporter().toString()).isEqualTo(DEFAULT_CONFIG_STRING); - - assertThat(loadExporter(DefaultConfigProperties.createFromMap(emptyMap()), TYPE).toString()) - .isEqualTo(DEFAULT_CONFIG_STRING); - } - - private OtlpStdoutLogRecordExporter exporterFromComponentProvider( - StructuredConfigProperties properties) { - return (OtlpStdoutLogRecordExporter) - ((ComponentProvider) - loadSpi(ComponentProvider.class) - .filter( - p -> { - ComponentProvider c = (ComponentProvider) p; - return "experimental-otlp/stdout".equals(c.getName()) - && c.getType().equals(COMPONENT_PROVIDER_TYPE); - }) - .findFirst() - .orElseThrow(() -> new IllegalStateException("No provider found"))) - .create(properties); - } - - @Test - void componentProviderConfig() { - StructuredConfigProperties properties = mock(StructuredConfigProperties.class); - OtlpStdoutLogRecordExporter exporter = exporterFromComponentProvider(properties); - - assertThat(exporter).extracting("wrapperJsonObject").isEqualTo(true); - assertThat(exporter) - .extracting("jsonWriter") - .extracting(Object::toString) - .isEqualTo("StreamJsonWriter{outputStream=stdout}"); - } - - private OtlpStdoutLogRecordExporter loadExporter(ConfigProperties config, String name) { - Object provider = loadProvider(name); - - try { - return (OtlpStdoutLogRecordExporter) - provider - .getClass() - .getDeclaredMethod("createExporter", ConfigProperties.class) - .invoke(provider, config); - } catch (Exception e) { - throw new RuntimeException(e); - } - } - - private Object loadProvider(String want) { - return loadSpi(PROVIDER_CLASS) - .filter( - p -> { - try { - return want.equals(p.getClass().getDeclaredMethod("getName").invoke(p)); - } catch (Exception e) { - throw new RuntimeException(e); - } - }) - .findFirst() - .orElseThrow(() -> new IllegalStateException("No provider found")); - } - - enum OutputType { - LOGGER, - SYSTEM_OUT, - FILE, - FILE_AND_BUFFERED_WRITER - } - - static class TestCase { - private final boolean wrapperJsonObject; - private final OutputType outputType; - - public TestCase(OutputType outputType, boolean wrapperJsonObject) { - this.outputType = outputType; - this.wrapperJsonObject = wrapperJsonObject; - } - - public OutputType getOutputType() { - return outputType; - } - - public boolean isWrapperJsonObject() { - return wrapperJsonObject; - } - } } diff --git a/exporters/logging-otlp/src/test/java/io/opentelemetry/exporter/logging/otlp/OtlpStdoutMetricExporterTest.java b/exporters/logging-otlp/src/test/java/io/opentelemetry/exporter/logging/otlp/OtlpStdoutMetricExporterTest.java new file mode 100644 index 00000000000..fdc6d945fc4 --- /dev/null +++ b/exporters/logging-otlp/src/test/java/io/opentelemetry/exporter/logging/otlp/OtlpStdoutMetricExporterTest.java @@ -0,0 +1,124 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.exporter.logging.otlp; + +import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatCode; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import com.google.common.collect.ImmutableMap; +import io.opentelemetry.exporter.logging.otlp.internal.metrics.OtlpStdoutMetricExporter; +import io.opentelemetry.exporter.logging.otlp.internal.metrics.OtlpStdoutMetricExporterBuilder; +import io.opentelemetry.sdk.autoconfigure.spi.internal.DefaultConfigProperties; +import io.opentelemetry.sdk.autoconfigure.spi.internal.StructuredConfigProperties; +import io.opentelemetry.sdk.autoconfigure.spi.metrics.ConfigurableMetricExporterProvider; +import io.opentelemetry.sdk.metrics.Aggregation; +import io.opentelemetry.sdk.metrics.InstrumentType; +import io.opentelemetry.sdk.metrics.data.AggregationTemporality; +import io.opentelemetry.sdk.metrics.export.AggregationTemporalitySelector; +import io.opentelemetry.sdk.metrics.export.DefaultAggregationSelector; +import io.opentelemetry.sdk.metrics.export.MetricExporter; +import java.io.OutputStream; +import java.util.logging.Logger; +import javax.annotation.Nullable; +import org.junit.jupiter.api.Test; + +class OtlpStdoutMetricExporterTest + extends AbstractOtlpStdoutExporterTest { + + public OtlpStdoutMetricExporterTest() { + super( + TestDataExporter.forMetrics(), + OtlpStdoutMetricExporter.class, + ConfigurableMetricExporterProvider.class, + MetricExporter.class, + "OtlpStdoutMetricExporter{jsonWriter=StreamJsonWriter{outputStream=stdout}, wrapperJsonObject=true}"); + } + + @Override + protected OtlpStdoutMetricExporter createDefaultExporter() { + return OtlpStdoutMetricExporter.builder().build(); + } + + @Override + protected OtlpStdoutMetricExporter createExporter( + @Nullable OutputStream outputStream, boolean wrapperJsonObject) { + OtlpStdoutMetricExporterBuilder builder = + OtlpStdoutMetricExporter.builder().setWrapperJsonObject(wrapperJsonObject); + if (outputStream != null) { + builder.setOutput(outputStream); + } else { + builder.setOutput(Logger.getLogger(exporterClass.getName())); + } + return builder.build(); + } + + /** Test configuration specific to metric exporter. */ + @Test + void providerMetricConfig() { + OtlpStdoutMetricExporter exporter = + loadExporter( + DefaultConfigProperties.createFromMap( + ImmutableMap.of( + "otel.exporter.otlp.metrics.temporality.preference", + "DELTA", + "otel.exporter.otlp.metrics.default.histogram.aggregation", + "BASE2_EXPONENTIAL_BUCKET_HISTOGRAM"))); + + assertThat(exporter.getAggregationTemporality(InstrumentType.COUNTER)) + .isEqualTo(AggregationTemporality.DELTA); + + assertThat(exporter.getDefaultAggregation(InstrumentType.HISTOGRAM)) + .isEqualTo(Aggregation.base2ExponentialBucketHistogram()); + } + + @Test + void componentProviderMetricConfig() { + StructuredConfigProperties properties = mock(StructuredConfigProperties.class); + when(properties.getString("temporality_preference")).thenReturn("DELTA"); + when(properties.getString("default_histogram_aggregation")) + .thenReturn("BASE2_EXPONENTIAL_BUCKET_HISTOGRAM"); + + OtlpStdoutMetricExporter exporter = + (OtlpStdoutMetricExporter) exporterFromComponentProvider(properties); + assertThat(exporter.getAggregationTemporality(InstrumentType.COUNTER)) + .isEqualTo(AggregationTemporality.DELTA); + + assertThat(exporter.getDefaultAggregation(InstrumentType.HISTOGRAM)) + .isEqualTo(Aggregation.base2ExponentialBucketHistogram()); + } + + @Test + void validMetricConfig() { + assertThatCode( + () -> + OtlpStdoutMetricExporter.builder() + .setAggregationTemporalitySelector( + AggregationTemporalitySelector.deltaPreferred())) + .doesNotThrowAnyException(); + assertThat( + OtlpStdoutMetricExporter.builder() + .setAggregationTemporalitySelector(AggregationTemporalitySelector.deltaPreferred()) + .build() + .getAggregationTemporality(InstrumentType.COUNTER)) + .isEqualTo(AggregationTemporality.DELTA); + assertThat( + OtlpStdoutMetricExporter.builder() + .build() + .getAggregationTemporality(InstrumentType.COUNTER)) + .isEqualTo(AggregationTemporality.CUMULATIVE); + + assertThat( + OtlpStdoutMetricExporter.builder() + .setDefaultAggregationSelector( + DefaultAggregationSelector.getDefault() + .with(InstrumentType.HISTOGRAM, Aggregation.drop())) + .build() + .getDefaultAggregation(InstrumentType.HISTOGRAM)) + .isEqualTo(Aggregation.drop()); + } +} diff --git a/exporters/logging-otlp/src/test/java/io/opentelemetry/exporter/logging/otlp/OtlpStdoutSpanExporterTest.java b/exporters/logging-otlp/src/test/java/io/opentelemetry/exporter/logging/otlp/OtlpStdoutSpanExporterTest.java new file mode 100644 index 00000000000..472ff4cd731 --- /dev/null +++ b/exporters/logging-otlp/src/test/java/io/opentelemetry/exporter/logging/otlp/OtlpStdoutSpanExporterTest.java @@ -0,0 +1,44 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.exporter.logging.otlp; + +import io.opentelemetry.exporter.logging.otlp.internal.traces.OtlpStdoutSpanExporter; +import io.opentelemetry.exporter.logging.otlp.internal.traces.OtlpStdoutSpanExporterBuilder; +import io.opentelemetry.sdk.autoconfigure.spi.traces.ConfigurableSpanExporterProvider; +import io.opentelemetry.sdk.trace.export.SpanExporter; +import java.io.OutputStream; +import java.util.logging.Logger; +import javax.annotation.Nullable; + +class OtlpStdoutSpanExporterTest extends AbstractOtlpStdoutExporterTest { + + public OtlpStdoutSpanExporterTest() { + super( + TestDataExporter.forSpans(), + OtlpStdoutSpanExporter.class, + ConfigurableSpanExporterProvider.class, + SpanExporter.class, + "OtlpStdoutSpanExporter{jsonWriter=StreamJsonWriter{outputStream=stdout}, wrapperJsonObject=true}"); + } + + @Override + protected OtlpStdoutSpanExporter createDefaultExporter() { + return OtlpStdoutSpanExporter.builder().build(); + } + + @Override + protected OtlpStdoutSpanExporter createExporter( + @Nullable OutputStream outputStream, boolean wrapperJsonObject) { + OtlpStdoutSpanExporterBuilder builder = + OtlpStdoutSpanExporter.builder().setWrapperJsonObject(wrapperJsonObject); + if (outputStream != null) { + builder.setOutput(outputStream); + } else { + builder.setOutput(Logger.getLogger(exporterClass.getName())); + } + return builder.build(); + } +} diff --git a/exporters/logging-otlp/src/test/java/io/opentelemetry/exporter/logging/otlp/TestDataExporter.java b/exporters/logging-otlp/src/test/java/io/opentelemetry/exporter/logging/otlp/TestDataExporter.java index 53b51629e1c..54032fca3e0 100644 --- a/exporters/logging-otlp/src/test/java/io/opentelemetry/exporter/logging/otlp/TestDataExporter.java +++ b/exporters/logging-otlp/src/test/java/io/opentelemetry/exporter/logging/otlp/TestDataExporter.java @@ -13,17 +13,30 @@ import io.opentelemetry.api.common.Attributes; import io.opentelemetry.api.logs.Severity; import io.opentelemetry.api.trace.SpanContext; +import io.opentelemetry.api.trace.SpanKind; import io.opentelemetry.api.trace.TraceFlags; import io.opentelemetry.api.trace.TraceState; import io.opentelemetry.sdk.common.CompletableResultCode; import io.opentelemetry.sdk.common.InstrumentationScopeInfo; import io.opentelemetry.sdk.logs.data.LogRecordData; import io.opentelemetry.sdk.logs.export.LogRecordExporter; +import io.opentelemetry.sdk.metrics.data.AggregationTemporality; +import io.opentelemetry.sdk.metrics.data.MetricData; +import io.opentelemetry.sdk.metrics.export.MetricExporter; +import io.opentelemetry.sdk.metrics.internal.data.ImmutableDoublePointData; +import io.opentelemetry.sdk.metrics.internal.data.ImmutableMetricData; +import io.opentelemetry.sdk.metrics.internal.data.ImmutableSumData; import io.opentelemetry.sdk.resources.Resource; import io.opentelemetry.sdk.testing.logs.TestLogRecordData; +import io.opentelemetry.sdk.testing.trace.TestSpanData; +import io.opentelemetry.sdk.trace.data.EventData; +import io.opentelemetry.sdk.trace.data.SpanData; +import io.opentelemetry.sdk.trace.data.StatusData; +import io.opentelemetry.sdk.trace.export.SpanExporter; import java.io.IOException; import java.nio.charset.StandardCharsets; import java.util.Arrays; +import java.util.Collections; import java.util.concurrent.TimeUnit; abstract class TestDataExporter { @@ -74,6 +87,88 @@ abstract class TestDataExporter { TraceState.getDefault())) .build(); + static final SpanData SPAN1 = + TestSpanData.builder() + .setHasEnded(true) + .setSpanContext( + SpanContext.create( + "12345678876543211234567887654321", + "8765432112345678", + TraceFlags.getSampled(), + TraceState.getDefault())) + .setStartEpochNanos(100) + .setEndEpochNanos(100 + 1000) + .setStatus(StatusData.ok()) + .setName("testSpan1") + .setKind(SpanKind.INTERNAL) + .setAttributes(Attributes.of(stringKey("animal"), "cat", longKey("lives"), 9L)) + .setEvents( + Collections.singletonList( + EventData.create( + 100 + 500, + "somethingHappenedHere", + Attributes.of(booleanKey("important"), true)))) + .setTotalAttributeCount(2) + .setTotalRecordedEvents(1) + .setTotalRecordedLinks(0) + .setInstrumentationScopeInfo( + InstrumentationScopeInfo.builder("instrumentation") + .setVersion("1") + .setAttributes(Attributes.builder().put("key", "value").build()) + .build()) + .setResource(RESOURCE) + .build(); + + private static final SpanData SPAN2 = + TestSpanData.builder() + .setHasEnded(false) + .setSpanContext( + SpanContext.create( + "12340000000043211234000000004321", + "8765000000005678", + TraceFlags.getSampled(), + TraceState.getDefault())) + .setStartEpochNanos(500) + .setEndEpochNanos(500 + 1001) + .setStatus(StatusData.error()) + .setName("testSpan2") + .setKind(SpanKind.CLIENT) + .setResource(RESOURCE) + .setInstrumentationScopeInfo( + InstrumentationScopeInfo.builder("instrumentation2").setVersion("2").build()) + .build(); + + static final MetricData METRIC1 = + ImmutableMetricData.createDoubleSum( + RESOURCE, + InstrumentationScopeInfo.builder("instrumentation") + .setVersion("1") + .setAttributes(Attributes.builder().put("key", "value").build()) + .build(), + "metric1", + "metric1 description", + "m", + ImmutableSumData.create( + true, + AggregationTemporality.CUMULATIVE, + Collections.singletonList( + ImmutableDoublePointData.create( + 1, 2, Attributes.of(stringKey("cat"), "meow"), 4)))); + + private static final MetricData METRIC2 = + ImmutableMetricData.createDoubleSum( + RESOURCE, + InstrumentationScopeInfo.builder("instrumentation2").setVersion("2").build(), + "metric2", + "metric2 description", + "s", + ImmutableSumData.create( + true, + AggregationTemporality.CUMULATIVE, + Collections.singletonList( + ImmutableDoublePointData.create( + 1, 2, Attributes.of(stringKey("cat"), "meow"), 4)))); + public TestDataExporter(String expectedFileNoWrapper, String expectedFileWrapper) { this.expectedFileNoWrapper = expectedFileNoWrapper; this.expectedFileWrapper = expectedFileWrapper; @@ -109,4 +204,44 @@ public CompletableResultCode shutdown(LogRecordExporter exporter) { } }; } + + static TestDataExporter forSpans() { + return new TestDataExporter( + "expected-spans.json", "expected-spans-wrapper.json") { + @Override + public CompletableResultCode export(SpanExporter exporter) { + return exporter.export(Arrays.asList(SPAN1, SPAN2)); + } + + @Override + public CompletableResultCode flush(SpanExporter exporter) { + return exporter.flush(); + } + + @Override + public CompletableResultCode shutdown(SpanExporter exporter) { + return exporter.shutdown(); + } + }; + } + + static TestDataExporter forMetrics() { + return new TestDataExporter( + "expected-metrics.json", "expected-metrics-wrapper.json") { + @Override + public CompletableResultCode export(MetricExporter exporter) { + return exporter.export(Arrays.asList(METRIC1, METRIC2)); + } + + @Override + public CompletableResultCode flush(MetricExporter exporter) { + return exporter.flush(); + } + + @Override + public CompletableResultCode shutdown(MetricExporter exporter) { + return exporter.shutdown(); + } + }; + } } diff --git a/exporters/logging-otlp/src/test/resources/expected-metrics-wrapper.json b/exporters/logging-otlp/src/test/resources/expected-metrics-wrapper.json new file mode 100644 index 00000000000..9c1255a6279 --- /dev/null +++ b/exporters/logging-otlp/src/test/resources/expected-metrics-wrapper.json @@ -0,0 +1,93 @@ +{ + "resourceMetrics": [ + { + "resource": { + "attributes": [ + { + "key": "key", + "value": { + "stringValue": "value" + } + } + ] + }, + "scopeMetrics": [ + { + "scope": { + "name": "instrumentation", + "version": "1", + "attributes": [ + { + "key": "key", + "value": { + "stringValue": "value" + } + } + ] + }, + "metrics": [ + { + "name": "metric1", + "description": "metric1 description", + "unit": "m", + "sum": { + "dataPoints": [ + { + "startTimeUnixNano": "1", + "timeUnixNano": "2", + "asDouble": 4.0, + "exemplars": [], + "attributes": [ + { + "key": "cat", + "value": { + "stringValue": "meow" + } + } + ] + } + ], + "aggregationTemporality": 2, + "isMonotonic": true + } + } + ] + }, + { + "scope": { + "name": "instrumentation2", + "version": "2", + "attributes": [] + }, + "metrics": [ + { + "name": "metric2", + "description": "metric2 description", + "unit": "s", + "sum": { + "dataPoints": [ + { + "startTimeUnixNano": "1", + "timeUnixNano": "2", + "asDouble": 4.0, + "exemplars": [], + "attributes": [ + { + "key": "cat", + "value": { + "stringValue": "meow" + } + } + ] + } + ], + "aggregationTemporality": 2, + "isMonotonic": true + } + } + ] + } + ] + } + ] +} diff --git a/exporters/logging-otlp/src/test/resources/expected-metrics.json b/exporters/logging-otlp/src/test/resources/expected-metrics.json new file mode 100644 index 00000000000..1a05a682e56 --- /dev/null +++ b/exporters/logging-otlp/src/test/resources/expected-metrics.json @@ -0,0 +1,89 @@ +{ + "resource": { + "attributes": [ + { + "key": "key", + "value": { + "stringValue": "value" + } + } + ] + }, + "scopeMetrics": [ + { + "scope": { + "name": "instrumentation", + "version": "1", + "attributes": [ + { + "key": "key", + "value": { + "stringValue": "value" + } + } + ] + }, + "metrics": [ + { + "name": "metric1", + "description": "metric1 description", + "unit": "m", + "sum": { + "dataPoints": [ + { + "startTimeUnixNano": "1", + "timeUnixNano": "2", + "asDouble": 4.0, + "exemplars": [], + "attributes": [ + { + "key": "cat", + "value": { + "stringValue": "meow" + } + } + ] + } + ], + "aggregationTemporality": 2, + "isMonotonic": true + } + } + ] + }, + { + "scope": { + "name": "instrumentation2", + "version": "2", + "attributes": [] + }, + "metrics": [ + { + "name": "metric2", + "description": "metric2 description", + "unit": "s", + "sum": { + "dataPoints": [ + { + "startTimeUnixNano": "1", + "timeUnixNano": "2", + "asDouble": 4.0, + "exemplars": [], + "attributes": [ + { + "key": "cat", + "value": { + "stringValue": "meow" + } + } + ] + } + ], + "aggregationTemporality": 2, + "isMonotonic": true + } + } + ] + } + ] +} diff --git a/exporters/logging-otlp/src/test/resources/expected-spans-wrapper.json b/exporters/logging-otlp/src/test/resources/expected-spans-wrapper.json new file mode 100644 index 00000000000..f1dd80ed9e8 --- /dev/null +++ b/exporters/logging-otlp/src/test/resources/expected-spans-wrapper.json @@ -0,0 +1,99 @@ +{ + "resourceSpans": [ + { + "resource": { + "attributes": [ + { + "key": "key", + "value": { + "stringValue": "value" + } + } + ] + }, + "scopeSpans": [ + { + "scope": { + "name": "instrumentation", + "version": "1", + "attributes": [ + { + "key": "key", + "value": { + "stringValue": "value" + } + } + ] + }, + "spans": [ + { + "traceId": "12345678876543211234567887654321", + "spanId": "8765432112345678", + "name": "testSpan1", + "kind": 1, + "startTimeUnixNano": "100", + "endTimeUnixNano": "1100", + "attributes": [ + { + "key": "animal", + "value": { + "stringValue": "cat" + } + }, + { + "key": "lives", + "value": { + "intValue": "9" + } + } + ], + "events": [ + { + "timeUnixNano": "600", + "name": "somethingHappenedHere", + "attributes": [ + { + "key": "important", + "value": { + "boolValue": true + } + } + ] + } + ], + "links": [], + "status": { + "code": 1 + }, + "flags": 257 + } + ] + }, + { + "scope": { + "name": "instrumentation2", + "version": "2", + "attributes": [] + }, + "spans": [ + { + "traceId": "12340000000043211234000000004321", + "spanId": "8765000000005678", + "name": "testSpan2", + "kind": 3, + "startTimeUnixNano": "500", + "endTimeUnixNano": "1501", + "attributes": [], + "events": [], + "links": [], + "status": { + "code": 2 + }, + "flags": 257 + } + ] + } + ] + } + ] +} diff --git a/exporters/logging-otlp/src/test/resources/expected-spans.json b/exporters/logging-otlp/src/test/resources/expected-spans.json new file mode 100644 index 00000000000..22e57949d90 --- /dev/null +++ b/exporters/logging-otlp/src/test/resources/expected-spans.json @@ -0,0 +1,95 @@ +{ + "resource": { + "attributes": [ + { + "key": "key", + "value": { + "stringValue": "value" + } + } + ] + }, + "scopeSpans": [ + { + "scope": { + "name": "instrumentation", + "version": "1", + "attributes": [ + { + "key": "key", + "value": { + "stringValue": "value" + } + } + ] + }, + "spans": [ + { + "traceId": "12345678876543211234567887654321", + "spanId": "8765432112345678", + "name": "testSpan1", + "kind": 1, + "startTimeUnixNano": "100", + "endTimeUnixNano": "1100", + "attributes": [ + { + "key": "animal", + "value": { + "stringValue": "cat" + } + }, + { + "key": "lives", + "value": { + "intValue": "9" + } + } + ], + "events": [ + { + "timeUnixNano": "600", + "name": "somethingHappenedHere", + "attributes": [ + { + "key": "important", + "value": { + "boolValue": true + } + } + ] + } + ], + "links": [], + "status": { + "code": 1 + }, + "flags": 257 + } + ] + }, + { + "scope": { + "name": "instrumentation2", + "version": "2", + "attributes": [] + }, + "spans": [ + { + "traceId": "12340000000043211234000000004321", + "spanId": "8765000000005678", + "name": "testSpan2", + "kind": 3, + "startTimeUnixNano": "500", + "endTimeUnixNano": "1501", + "attributes": [], + "events": [], + "links": [], + "status": { + "code": 2 + }, + "flags": 257 + } + ] + } + ] +} diff --git a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/OtlpConfigUtil.java b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/OtlpConfigUtil.java index 1ca885bf5a0..c49430d4468 100644 --- a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/OtlpConfigUtil.java +++ b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/OtlpConfigUtil.java @@ -5,8 +5,6 @@ package io.opentelemetry.exporter.otlp.internal; -import static io.opentelemetry.sdk.metrics.Aggregation.explicitBucketHistogram; - import io.opentelemetry.exporter.internal.ExporterBuilderUtil; import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties; import io.opentelemetry.sdk.autoconfigure.spi.ConfigurationException; @@ -14,12 +12,6 @@ import io.opentelemetry.sdk.autoconfigure.spi.internal.StructuredConfigProperties; import io.opentelemetry.sdk.common.export.MemoryMode; import io.opentelemetry.sdk.common.export.RetryPolicy; -import io.opentelemetry.sdk.metrics.Aggregation; -import io.opentelemetry.sdk.metrics.InstrumentType; -import io.opentelemetry.sdk.metrics.data.AggregationTemporality; -import io.opentelemetry.sdk.metrics.export.AggregationTemporalitySelector; -import io.opentelemetry.sdk.metrics.export.DefaultAggregationSelector; -import io.opentelemetry.sdk.metrics.internal.aggregator.AggregationUtil; import java.io.File; import java.io.IOException; import java.io.RandomAccessFile; @@ -30,7 +22,6 @@ import java.time.Duration; import java.util.Collections; import java.util.List; -import java.util.Locale; import java.util.Map; import java.util.function.BiConsumer; import java.util.function.Consumer; @@ -256,96 +247,6 @@ private static void configureOtlpHeaders( } } - /** - * Invoke the {@code aggregationTemporalitySelectorConsumer} with the configured {@link - * AggregationTemporality}. - */ - public static void configureOtlpAggregationTemporality( - ConfigProperties config, - Consumer aggregationTemporalitySelectorConsumer) { - String temporalityStr = config.getString("otel.exporter.otlp.metrics.temporality.preference"); - if (temporalityStr == null) { - return; - } - AggregationTemporalitySelector temporalitySelector; - switch (temporalityStr.toLowerCase(Locale.ROOT)) { - case "cumulative": - temporalitySelector = AggregationTemporalitySelector.alwaysCumulative(); - break; - case "delta": - temporalitySelector = AggregationTemporalitySelector.deltaPreferred(); - break; - case "lowmemory": - temporalitySelector = AggregationTemporalitySelector.lowMemory(); - break; - default: - throw new ConfigurationException("Unrecognized aggregation temporality: " + temporalityStr); - } - aggregationTemporalitySelectorConsumer.accept(temporalitySelector); - } - - public static void configureOtlpAggregationTemporality( - StructuredConfigProperties config, - Consumer aggregationTemporalitySelectorConsumer) { - String temporalityStr = config.getString("temporality_preference"); - if (temporalityStr == null) { - return; - } - AggregationTemporalitySelector temporalitySelector; - switch (temporalityStr.toLowerCase(Locale.ROOT)) { - case "cumulative": - temporalitySelector = AggregationTemporalitySelector.alwaysCumulative(); - break; - case "delta": - temporalitySelector = AggregationTemporalitySelector.deltaPreferred(); - break; - case "lowmemory": - temporalitySelector = AggregationTemporalitySelector.lowMemory(); - break; - default: - throw new ConfigurationException("Unrecognized temporality_preference: " + temporalityStr); - } - aggregationTemporalitySelectorConsumer.accept(temporalitySelector); - } - - /** - * Invoke the {@code defaultAggregationSelectorConsumer} with the configured {@link - * DefaultAggregationSelector}. - */ - public static void configureOtlpHistogramDefaultAggregation( - ConfigProperties config, - Consumer defaultAggregationSelectorConsumer) { - String defaultHistogramAggregation = - config.getString("otel.exporter.otlp.metrics.default.histogram.aggregation"); - if (defaultHistogramAggregation != null) { - ExporterBuilderUtil.configureHistogramDefaultAggregation( - defaultHistogramAggregation, defaultAggregationSelectorConsumer); - } - } - - /** - * Invoke the {@code defaultAggregationSelectorConsumer} with the configured {@link - * DefaultAggregationSelector}. - */ - public static void configureOtlpHistogramDefaultAggregation( - StructuredConfigProperties config, - Consumer defaultAggregationSelectorConsumer) { - String defaultHistogramAggregation = config.getString("default_histogram_aggregation"); - if (defaultHistogramAggregation == null) { - return; - } - if (AggregationUtil.aggregationName(Aggregation.base2ExponentialBucketHistogram()) - .equalsIgnoreCase(defaultHistogramAggregation)) { - defaultAggregationSelectorConsumer.accept( - DefaultAggregationSelector.getDefault() - .with(InstrumentType.HISTOGRAM, Aggregation.base2ExponentialBucketHistogram())); - } else if (!AggregationUtil.aggregationName(explicitBucketHistogram()) - .equalsIgnoreCase(defaultHistogramAggregation)) { - throw new ConfigurationException( - "Unrecognized default_histogram_aggregation: " + defaultHistogramAggregation); - } - } - private static URL createUrl(URL context, String spec) { try { return new URL(context, spec); diff --git a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/OtlpMetricExporterComponentProvider.java b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/OtlpMetricExporterComponentProvider.java index bac3b205835..2bbec38c533 100644 --- a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/OtlpMetricExporterComponentProvider.java +++ b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/OtlpMetricExporterComponentProvider.java @@ -9,6 +9,7 @@ import static io.opentelemetry.exporter.otlp.internal.OtlpConfigUtil.PROTOCOL_GRPC; import static io.opentelemetry.exporter.otlp.internal.OtlpConfigUtil.PROTOCOL_HTTP_PROTOBUF; +import io.opentelemetry.exporter.internal.ExporterBuilderUtil; import io.opentelemetry.exporter.otlp.http.metrics.OtlpHttpMetricExporter; import io.opentelemetry.exporter.otlp.http.metrics.OtlpHttpMetricExporterBuilder; import io.opentelemetry.exporter.otlp.metrics.OtlpGrpcMetricExporter; @@ -55,9 +56,9 @@ public MetricExporter create(StructuredConfigProperties config) { builder::setClientTls, builder::setRetryPolicy, builder::setMemoryMode); - OtlpConfigUtil.configureOtlpAggregationTemporality( + ExporterBuilderUtil.configureOtlpAggregationTemporality( config, builder::setAggregationTemporalitySelector); - OtlpConfigUtil.configureOtlpHistogramDefaultAggregation( + ExporterBuilderUtil.configureOtlpHistogramDefaultAggregation( config, builder::setDefaultAggregationSelector); return builder.build(); @@ -75,9 +76,9 @@ public MetricExporter create(StructuredConfigProperties config) { builder::setClientTls, builder::setRetryPolicy, builder::setMemoryMode); - OtlpConfigUtil.configureOtlpAggregationTemporality( + ExporterBuilderUtil.configureOtlpAggregationTemporality( config, builder::setAggregationTemporalitySelector); - OtlpConfigUtil.configureOtlpHistogramDefaultAggregation( + ExporterBuilderUtil.configureOtlpHistogramDefaultAggregation( config, builder::setDefaultAggregationSelector); return builder.build(); diff --git a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/OtlpMetricExporterProvider.java b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/OtlpMetricExporterProvider.java index 8103e9426cf..a60f57a250c 100644 --- a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/OtlpMetricExporterProvider.java +++ b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/OtlpMetricExporterProvider.java @@ -9,6 +9,7 @@ import static io.opentelemetry.exporter.otlp.internal.OtlpConfigUtil.PROTOCOL_GRPC; import static io.opentelemetry.exporter.otlp.internal.OtlpConfigUtil.PROTOCOL_HTTP_PROTOBUF; +import io.opentelemetry.exporter.internal.ExporterBuilderUtil; import io.opentelemetry.exporter.otlp.http.metrics.OtlpHttpMetricExporter; import io.opentelemetry.exporter.otlp.http.metrics.OtlpHttpMetricExporterBuilder; import io.opentelemetry.exporter.otlp.metrics.OtlpGrpcMetricExporter; @@ -45,9 +46,9 @@ public MetricExporter createExporter(ConfigProperties config) { builder::setClientTls, builder::setRetryPolicy, builder::setMemoryMode); - OtlpConfigUtil.configureOtlpAggregationTemporality( + ExporterBuilderUtil.configureOtlpAggregationTemporality( config, builder::setAggregationTemporalitySelector); - OtlpConfigUtil.configureOtlpHistogramDefaultAggregation( + ExporterBuilderUtil.configureOtlpHistogramDefaultAggregation( config, builder::setDefaultAggregationSelector); return builder.build(); @@ -65,9 +66,9 @@ public MetricExporter createExporter(ConfigProperties config) { builder::setClientTls, builder::setRetryPolicy, builder::setMemoryMode); - OtlpConfigUtil.configureOtlpAggregationTemporality( + ExporterBuilderUtil.configureOtlpAggregationTemporality( config, builder::setAggregationTemporalitySelector); - OtlpConfigUtil.configureOtlpHistogramDefaultAggregation( + ExporterBuilderUtil.configureOtlpHistogramDefaultAggregation( config, builder::setDefaultAggregationSelector); return builder.build(); diff --git a/exporters/otlp/all/src/test/java/io/opentelemetry/exporter/otlp/internal/OtlpConfigUtilTest.java b/exporters/otlp/all/src/test/java/io/opentelemetry/exporter/otlp/internal/OtlpConfigUtilTest.java index 5c678670519..25a0d5cf7ee 100644 --- a/exporters/otlp/all/src/test/java/io/opentelemetry/exporter/otlp/internal/OtlpConfigUtilTest.java +++ b/exporters/otlp/all/src/test/java/io/opentelemetry/exporter/otlp/internal/OtlpConfigUtilTest.java @@ -15,6 +15,8 @@ import static org.assertj.core.api.Assertions.assertThatThrownBy; import com.google.common.collect.ImmutableMap; +import io.opentelemetry.exporter.internal.ExporterBuilderUtil; +import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties; import io.opentelemetry.sdk.autoconfigure.spi.ConfigurationException; import io.opentelemetry.sdk.autoconfigure.spi.internal.DefaultConfigProperties; import io.opentelemetry.sdk.metrics.Aggregation; @@ -362,8 +364,8 @@ void configureOtlpAggregationTemporality() { private static AggregationTemporality configureAggregationTemporality( Map properties) { AtomicReference temporalityRef = new AtomicReference<>(); - OtlpConfigUtil.configureOtlpAggregationTemporality( - DefaultConfigProperties.createFromMap(properties), temporalityRef::set); + ConfigProperties config = DefaultConfigProperties.createFromMap(properties); + ExporterBuilderUtil.configureOtlpAggregationTemporality(config, temporalityRef::set); // We apply the temporality selector to a HISTOGRAM instrument to simplify assertions return temporalityRef.get().getAggregationTemporality(InstrumentType.HISTOGRAM); } @@ -409,8 +411,8 @@ void configureOtlpHistogramDefaultAggregation() { private static DefaultAggregationSelector configureHistogramDefaultAggregation( Map properties) { AtomicReference aggregationRef = new AtomicReference<>(); - OtlpConfigUtil.configureOtlpHistogramDefaultAggregation( - DefaultConfigProperties.createFromMap(properties), aggregationRef::set); + ConfigProperties config = DefaultConfigProperties.createFromMap(properties); + ExporterBuilderUtil.configureOtlpHistogramDefaultAggregation(config, aggregationRef::set); // We apply the temporality selector to a HISTOGRAM instrument to simplify assertions return aggregationRef.get(); } From e6eceb51154eae1c719c5229ace8d6bf1029fd42 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 10 Oct 2024 18:13:41 -0700 Subject: [PATCH 605/901] fix(deps): update dependency org.jetbrains.kotlin:kotlin-gradle-plugin to v2.0.21 (#6778) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- buildSrc/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts index 7c7314b3140..e2e5e3e1ebe 100644 --- a/buildSrc/build.gradle.kts +++ b/buildSrc/build.gradle.kts @@ -65,7 +65,7 @@ dependencies { implementation("me.champeau.jmh:jmh-gradle-plugin:0.7.2") implementation("net.ltgt.gradle:gradle-errorprone-plugin:4.0.1") implementation("net.ltgt.gradle:gradle-nullaway-plugin:2.0.0") - implementation("org.jetbrains.kotlin:kotlin-gradle-plugin:2.0.20") + implementation("org.jetbrains.kotlin:kotlin-gradle-plugin:2.0.21") implementation("org.owasp:dependency-check-gradle:10.0.4") implementation("ru.vyarus:gradle-animalsniffer-plugin:1.7.1") } From b6badb2ca39063869ef8b7bcb219468c830ab5d7 Mon Sep 17 00:00:00 2001 From: jason plumb <75337021+breedx-splk@users.noreply.github.com> Date: Fri, 11 Oct 2024 16:33:11 +0200 Subject: [PATCH 606/901] Adds Baggage.getEntry(String key) (#6765) Co-authored-by: Trask Stalnaker Co-authored-by: Jack Berg --- .../io/opentelemetry/api/baggage/Baggage.java | 18 ++++++++ .../api/baggage/ImmutableBaggage.java | 7 +++ .../api/baggage/propagation/Parser.java | 2 +- .../api/baggage/BaggageTest.java | 45 +++++++++++++++++++ .../api/baggage/ImmutableBaggageTest.java | 13 ++++++ .../current_vs_latest/opentelemetry-api.txt | 5 ++- 6 files changed, 88 insertions(+), 2 deletions(-) diff --git a/api/all/src/main/java/io/opentelemetry/api/baggage/Baggage.java b/api/all/src/main/java/io/opentelemetry/api/baggage/Baggage.java index 5dd2924d432..f530b790c2a 100644 --- a/api/all/src/main/java/io/opentelemetry/api/baggage/Baggage.java +++ b/api/all/src/main/java/io/opentelemetry/api/baggage/Baggage.java @@ -99,4 +99,22 @@ default boolean isEmpty() { * be set to not use an implicit parent, so any parent assignment must be done manually. */ BaggageBuilder toBuilder(); + + /** + * Returns the {@code BaggageEntry} associated with the given key. + * + * @param entryKey entry key to return the {@code BaggageEntry} for, or {@code null} if no {@code + * Entry} with the given {@code entryKey} is in this {@code Baggage}. + */ + @Nullable + default BaggageEntry getEntry(String entryKey) { + BaggageEntry[] result = new BaggageEntry[] {null}; + forEach( + (key, entry) -> { + if (entryKey.equals(key)) { + result[0] = entry; + } + }); + return result[0]; + } } diff --git a/api/all/src/main/java/io/opentelemetry/api/baggage/ImmutableBaggage.java b/api/all/src/main/java/io/opentelemetry/api/baggage/ImmutableBaggage.java index 7faf4152fe7..d628e89b282 100644 --- a/api/all/src/main/java/io/opentelemetry/api/baggage/ImmutableBaggage.java +++ b/api/all/src/main/java/io/opentelemetry/api/baggage/ImmutableBaggage.java @@ -37,6 +37,13 @@ public String getEntryValue(String entryKey) { return entry != null ? entry.getValue() : null; } + // Overrides the default implementation to provide a more performant implementation. + @Nullable + @Override + public BaggageEntry getEntry(String entryKey) { + return get(entryKey); + } + @Override public BaggageBuilder toBuilder() { return new Builder(new ArrayList<>(data())); diff --git a/api/all/src/main/java/io/opentelemetry/api/baggage/propagation/Parser.java b/api/all/src/main/java/io/opentelemetry/api/baggage/propagation/Parser.java index c9d619c1bf3..a616e8e24d2 100644 --- a/api/all/src/main/java/io/opentelemetry/api/baggage/propagation/Parser.java +++ b/api/all/src/main/java/io/opentelemetry/api/baggage/propagation/Parser.java @@ -37,7 +37,7 @@ private enum State { private boolean skipToNext; - public Parser(String baggageHeader) { + Parser(String baggageHeader) { this.baggageHeader = baggageHeader; reset(0); } diff --git a/api/all/src/test/java/io/opentelemetry/api/baggage/BaggageTest.java b/api/all/src/test/java/io/opentelemetry/api/baggage/BaggageTest.java index 4c141276e1d..f30ee5703cc 100644 --- a/api/all/src/test/java/io/opentelemetry/api/baggage/BaggageTest.java +++ b/api/all/src/test/java/io/opentelemetry/api/baggage/BaggageTest.java @@ -9,6 +9,10 @@ import io.opentelemetry.context.Context; import io.opentelemetry.context.Scope; +import java.util.HashMap; +import java.util.Map; +import java.util.function.BiConsumer; +import javax.annotation.Nullable; import org.junit.jupiter.api.Test; class BaggageTest { @@ -27,4 +31,45 @@ void current() { assertThat(result.getEntryValue("foo")).isEqualTo("bar"); } } + + @Test + void getEntryDefault() { + BaggageEntryMetadata metadata = BaggageEntryMetadata.create("flib"); + Map result = new HashMap<>(); + result.put("a", ImmutableEntry.create("b", metadata)); + // Implementation that only implements asMap() which is used by getEntry() + Baggage baggage = + new Baggage() { + + @Override + public Map asMap() { + return result; + } + + @Override + public int size() { + return 0; + } + + @Override + public void forEach(BiConsumer consumer) { + result.forEach(consumer); + } + + @Nullable + @Override + public String getEntryValue(String entryKey) { + return null; + } + + @Override + public BaggageBuilder toBuilder() { + return null; + } + }; + + BaggageEntry entry = baggage.getEntry("a"); + assertThat(entry.getValue()).isEqualTo("b"); + assertThat(entry.getMetadata().getValue()).isEqualTo("flib"); + } } diff --git a/api/all/src/test/java/io/opentelemetry/api/baggage/ImmutableBaggageTest.java b/api/all/src/test/java/io/opentelemetry/api/baggage/ImmutableBaggageTest.java index 311c8bae337..a10d2ca1902 100644 --- a/api/all/src/test/java/io/opentelemetry/api/baggage/ImmutableBaggageTest.java +++ b/api/all/src/test/java/io/opentelemetry/api/baggage/ImmutableBaggageTest.java @@ -9,6 +9,8 @@ import static org.assertj.core.api.Assertions.entry; import com.google.common.testing.EqualsTester; +import io.opentelemetry.context.Context; +import io.opentelemetry.context.Scope; import org.junit.jupiter.api.Test; /** @@ -190,4 +192,15 @@ void testEquals() { .addEqualityGroup(baggage2, baggage3) .testEquals(); } + + @Test + void getEntry() { + BaggageEntryMetadata metadata = BaggageEntryMetadata.create("flib"); + try (Scope scope = + Context.root().with(Baggage.builder().put("a", "b", metadata).build()).makeCurrent()) { + Baggage result = Baggage.current(); + assertThat(result.getEntry("a").getValue()).isEqualTo("b"); + assertThat(result.getEntry("a").getMetadata().getValue()).isEqualTo("flib"); + } + } } diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-api.txt b/docs/apidiffs/current_vs_latest/opentelemetry-api.txt index 547ea83e519..fb5d54460b0 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-api.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-api.txt @@ -1,2 +1,5 @@ Comparing source compatibility of opentelemetry-api-1.43.0-SNAPSHOT.jar against opentelemetry-api-1.42.1.jar -No changes. \ No newline at end of file +*** MODIFIED INTERFACE: PUBLIC ABSTRACT io.opentelemetry.api.baggage.Baggage (not serializable) + === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 + +++ NEW METHOD: PUBLIC(+) io.opentelemetry.api.baggage.BaggageEntry getEntry(java.lang.String) + +++ NEW ANNOTATION: javax.annotation.Nullable From b1cd30ef7f2a28aaf321253464fdad0c373a4bc7 Mon Sep 17 00:00:00 2001 From: jack-berg <34418638+jack-berg@users.noreply.github.com> Date: Fri, 11 Oct 2024 11:01:55 -0500 Subject: [PATCH 607/901] Prepare changelog for 1.43.0 release (#6782) --- CHANGELOG.md | 44 +++++++++++++++++++ .../io/opentelemetry/api/baggage/Baggage.java | 1 + 2 files changed, 45 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 74beb601dd6..79fdea8ea9a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,50 @@ ## Unreleased +### API + +* Add helper class to capture context using ScheduledExecutorService + ([#6712](https://github.com/open-telemetry/opentelemetry-java/pull/6712)) +* Adds Baggage.getEntry(String key) + ([#6765](https://github.com/open-telemetry/opentelemetry-java/pull/6765)) + +#### Extensions + +* Fix ottracepropagation for short span ids + ([#6734](https://github.com/open-telemetry/opentelemetry-java/pull/6734)) + +### SDK + +#### Metrics + +* Optimize advice with FilteredAttributes + ([#6633](https://github.com/open-telemetry/opentelemetry-java/pull/6633)) + +#### Exporters + +* Add experimental stdout log, metric, trace exporters for printing records to stdout in standard + OTLP JSON format. + ([#6675](https://github.com/open-telemetry/opentelemetry-java/pull/6675), [#6750](https://github.com/open-telemetry/opentelemetry-java/pull/6750)) +* Add Marshalers for profiling signal type + ([#6680](https://github.com/open-telemetry/opentelemetry-java/pull/6680)) + +#### Extensions + +* Add `*Model` suffix to declarative config generated classes. + ([#6721](https://github.com/open-telemetry/opentelemetry-java/pull/6721)) +* Use autoconfigured ClassLoader to load declarative config + ([#6725](https://github.com/open-telemetry/opentelemetry-java/pull/6725)) +* Update declarative config to use opentelemetry-configuration v0.3.0 + ([#6733](https://github.com/open-telemetry/opentelemetry-java/pull/6733)) +* Add `StructuredConfigProperties#getStructured` default method, + add `StructuredConfigProperties.empty()` + ([#6759](https://github.com/open-telemetry/opentelemetry-java/pull/6759)) + +#### Testing + +* Add context info about wrong span or trace. + ([#6703](https://github.com/open-telemetry/opentelemetry-java/pull/6703)) + ## Version 1.42.1 (2024-09-10) ### API diff --git a/api/all/src/main/java/io/opentelemetry/api/baggage/Baggage.java b/api/all/src/main/java/io/opentelemetry/api/baggage/Baggage.java index f530b790c2a..12b81d7b033 100644 --- a/api/all/src/main/java/io/opentelemetry/api/baggage/Baggage.java +++ b/api/all/src/main/java/io/opentelemetry/api/baggage/Baggage.java @@ -105,6 +105,7 @@ default boolean isEmpty() { * * @param entryKey entry key to return the {@code BaggageEntry} for, or {@code null} if no {@code * Entry} with the given {@code entryKey} is in this {@code Baggage}. + * @since 1.43.0 */ @Nullable default BaggageEntry getEntry(String entryKey) { From 1554ccbf1813d2d8fed2ccf9048c62f359bd502a Mon Sep 17 00:00:00 2001 From: OpenTelemetry Bot <107717825+opentelemetrybot@users.noreply.github.com> Date: Fri, 11 Oct 2024 11:54:50 -0500 Subject: [PATCH 608/901] Update version to 1.44.0 (#6784) --- CHANGELOG.md | 2 ++ version.gradle.kts | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 79fdea8ea9a..aa3f1afb9ac 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,8 @@ ## Unreleased +## Version 1.43.0 (2024-10-11) + ### API * Add helper class to capture context using ScheduledExecutorService diff --git a/version.gradle.kts b/version.gradle.kts index 84022c4cb09..eb508c5fbc1 100644 --- a/version.gradle.kts +++ b/version.gradle.kts @@ -1,7 +1,7 @@ val snapshot = true allprojects { - var ver = "1.43.0" + var ver = "1.44.0" val release = findProperty("otel.release") if (release != null) { ver += "-" + release From e4d5109c496dce9fb2341711e4fbc0c888ecd785 Mon Sep 17 00:00:00 2001 From: OpenTelemetry Bot <107717825+opentelemetrybot@users.noreply.github.com> Date: Fri, 11 Oct 2024 17:01:39 -0500 Subject: [PATCH 609/901] Post release for version 1.43.0 (#6785) --- README.md | 70 +++++++++---------- .../1.43.0_vs_1.42.0/opentelemetry-api.txt | 5 ++ .../opentelemetry-context.txt | 4 ++ .../opentelemetry-exporter-common.txt | 2 + .../opentelemetry-exporter-logging-otlp.txt | 2 + .../opentelemetry-exporter-logging.txt | 2 + .../opentelemetry-exporter-otlp-common.txt | 2 + .../opentelemetry-exporter-otlp.txt | 2 + ...y-exporter-sender-grpc-managed-channel.txt | 2 + .../opentelemetry-exporter-sender-jdk.txt | 2 + .../opentelemetry-exporter-sender-okhttp.txt | 2 + .../opentelemetry-exporter-zipkin.txt | 2 + .../opentelemetry-extension-kotlin.txt | 2 + ...ntelemetry-extension-trace-propagators.txt | 2 + .../opentelemetry-opentracing-shim.txt | 2 + .../opentelemetry-sdk-common.txt | 2 + ...emetry-sdk-extension-autoconfigure-spi.txt | 2 + ...ntelemetry-sdk-extension-autoconfigure.txt | 2 + ...ry-sdk-extension-jaeger-remote-sampler.txt | 2 + .../opentelemetry-sdk-logs.txt | 2 + .../opentelemetry-sdk-metrics.txt | 2 + .../opentelemetry-sdk-testing.txt | 2 + .../opentelemetry-sdk-trace.txt | 2 + .../1.43.0_vs_1.42.0/opentelemetry-sdk.txt | 2 + .../current_vs_latest/opentelemetry-api.txt | 7 +- .../opentelemetry-context.txt | 6 +- .../opentelemetry-exporter-common.txt | 2 +- .../opentelemetry-exporter-logging-otlp.txt | 2 +- .../opentelemetry-exporter-logging.txt | 2 +- .../opentelemetry-exporter-otlp-common.txt | 2 +- .../opentelemetry-exporter-otlp.txt | 2 +- ...y-exporter-sender-grpc-managed-channel.txt | 2 +- .../opentelemetry-exporter-sender-jdk.txt | 2 +- .../opentelemetry-exporter-sender-okhttp.txt | 2 +- .../opentelemetry-exporter-zipkin.txt | 2 +- .../opentelemetry-extension-kotlin.txt | 2 +- ...ntelemetry-extension-trace-propagators.txt | 2 +- .../opentelemetry-opentracing-shim.txt | 2 +- .../opentelemetry-sdk-common.txt | 2 +- ...emetry-sdk-extension-autoconfigure-spi.txt | 2 +- ...ntelemetry-sdk-extension-autoconfigure.txt | 2 +- ...ry-sdk-extension-jaeger-remote-sampler.txt | 2 +- .../opentelemetry-sdk-logs.txt | 2 +- .../opentelemetry-sdk-metrics.txt | 2 +- .../opentelemetry-sdk-testing.txt | 2 +- .../opentelemetry-sdk-trace.txt | 2 +- .../current_vs_latest/opentelemetry-sdk.txt | 2 +- 47 files changed, 111 insertions(+), 65 deletions(-) create mode 100644 docs/apidiffs/1.43.0_vs_1.42.0/opentelemetry-api.txt create mode 100644 docs/apidiffs/1.43.0_vs_1.42.0/opentelemetry-context.txt create mode 100644 docs/apidiffs/1.43.0_vs_1.42.0/opentelemetry-exporter-common.txt create mode 100644 docs/apidiffs/1.43.0_vs_1.42.0/opentelemetry-exporter-logging-otlp.txt create mode 100644 docs/apidiffs/1.43.0_vs_1.42.0/opentelemetry-exporter-logging.txt create mode 100644 docs/apidiffs/1.43.0_vs_1.42.0/opentelemetry-exporter-otlp-common.txt create mode 100644 docs/apidiffs/1.43.0_vs_1.42.0/opentelemetry-exporter-otlp.txt create mode 100644 docs/apidiffs/1.43.0_vs_1.42.0/opentelemetry-exporter-sender-grpc-managed-channel.txt create mode 100644 docs/apidiffs/1.43.0_vs_1.42.0/opentelemetry-exporter-sender-jdk.txt create mode 100644 docs/apidiffs/1.43.0_vs_1.42.0/opentelemetry-exporter-sender-okhttp.txt create mode 100644 docs/apidiffs/1.43.0_vs_1.42.0/opentelemetry-exporter-zipkin.txt create mode 100644 docs/apidiffs/1.43.0_vs_1.42.0/opentelemetry-extension-kotlin.txt create mode 100644 docs/apidiffs/1.43.0_vs_1.42.0/opentelemetry-extension-trace-propagators.txt create mode 100644 docs/apidiffs/1.43.0_vs_1.42.0/opentelemetry-opentracing-shim.txt create mode 100644 docs/apidiffs/1.43.0_vs_1.42.0/opentelemetry-sdk-common.txt create mode 100644 docs/apidiffs/1.43.0_vs_1.42.0/opentelemetry-sdk-extension-autoconfigure-spi.txt create mode 100644 docs/apidiffs/1.43.0_vs_1.42.0/opentelemetry-sdk-extension-autoconfigure.txt create mode 100644 docs/apidiffs/1.43.0_vs_1.42.0/opentelemetry-sdk-extension-jaeger-remote-sampler.txt create mode 100644 docs/apidiffs/1.43.0_vs_1.42.0/opentelemetry-sdk-logs.txt create mode 100644 docs/apidiffs/1.43.0_vs_1.42.0/opentelemetry-sdk-metrics.txt create mode 100644 docs/apidiffs/1.43.0_vs_1.42.0/opentelemetry-sdk-testing.txt create mode 100644 docs/apidiffs/1.43.0_vs_1.42.0/opentelemetry-sdk-trace.txt create mode 100644 docs/apidiffs/1.43.0_vs_1.42.0/opentelemetry-sdk.txt diff --git a/README.md b/README.md index 27c83571802..3356c358bc7 100644 --- a/README.md +++ b/README.md @@ -104,7 +104,7 @@ dependency versions in sync. io.opentelemetry opentelemetry-bom - 1.42.0 + 1.43.0 pom import @@ -123,7 +123,7 @@ dependency versions in sync. ```groovy dependencies { - implementation platform("io.opentelemetry:opentelemetry-bom:1.42.0") + implementation platform("io.opentelemetry:opentelemetry-bom:1.43.0") implementation('io.opentelemetry:opentelemetry-api') } ``` @@ -132,8 +132,8 @@ Note that if you want to use any artifacts that have not fully stabilized yet (s ```groovy dependencies { - implementation platform("io.opentelemetry:opentelemetry-bom:1.42.0") - implementation platform('io.opentelemetry:opentelemetry-bom-alpha:1.42.0-alpha') + implementation platform("io.opentelemetry:opentelemetry-bom:1.43.0") + implementation platform('io.opentelemetry:opentelemetry-bom-alpha:1.43.0-alpha') implementation('io.opentelemetry:opentelemetry-api') implementation('io.opentelemetry:opentelemetry-exporter-prometheus') @@ -161,7 +161,7 @@ We strongly recommend using our published BOM to keep all dependency versions in io.opentelemetry opentelemetry-bom - 1.43.0-SNAPSHOT + 1.44.0-SNAPSHOT pom import @@ -184,7 +184,7 @@ repositories { } dependencies { - implementation platform("io.opentelemetry:opentelemetry-bom:1.43.0-SNAPSHOT") + implementation platform("io.opentelemetry:opentelemetry-bom:1.44.0-SNAPSHOT") implementation('io.opentelemetry:opentelemetry-api') } ``` @@ -229,66 +229,66 @@ dependency as follows, replacing `{{artifact-id}}` with the value from the "Arti | Component | Description | Artifact ID | Version | Javadoc | |----------------------------------------------|----------------------------------------|---------------------------|-------------------------------------------------------------|---------| -| [Bill of Materials (BOM)](./bom) | Bill of materials for stable artifacts | `opentelemetry-bom` | 1.42.0 | N/A | -| [Alpha Bill of Materials (BOM)](./bom-alpha) | Bill of materials for alpha artifacts | `opentelemetry-bom-alpha` | 1.42.0-alpha | N/A | +| [Bill of Materials (BOM)](./bom) | Bill of materials for stable artifacts | `opentelemetry-bom` | 1.43.0 | N/A | +| [Alpha Bill of Materials (BOM)](./bom-alpha) | Bill of materials for alpha artifacts | `opentelemetry-bom-alpha` | 1.43.0-alpha | N/A | ### API | Component | Description | Artifact ID | Version | Javadoc | |-----------------------------------|--------------------------------------------------------------------------------------|-------------------------------|---------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| [API](./api/all) | OpenTelemetry API, including metrics, traces, baggage, context | `opentelemetry-api` | 1.42.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-api.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-api) | -| [API Incubator](./api/incubator) | API incubator, including pass through propagator, and extended tracer, and Event API | `opentelemetry-api-incubator` | 1.42.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-api-incubator.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-api-incubator) | -| [Context API](./context) | OpenTelemetry context API | `opentelemetry-context` | 1.42.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-context.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-context) | +| [API](./api/all) | OpenTelemetry API, including metrics, traces, baggage, context | `opentelemetry-api` | 1.43.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-api.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-api) | +| [API Incubator](./api/incubator) | API incubator, including pass through propagator, and extended tracer, and Event API | `opentelemetry-api-incubator` | 1.43.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-api-incubator.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-api-incubator) | +| [Context API](./context) | OpenTelemetry context API | `opentelemetry-context` | 1.43.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-context.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-context) | ### API Extensions | Component | Description | Artifact ID | Version | Javadoc | |---------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|---------------------------------------------|-------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| [Kotlin Extension](./extensions/kotlin) | Context extension for coroutines | `opentelemetry-extension-kotlin` | 1.42.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-extension-kotlin.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-extension-kotlin) | -| [Trace Propagators Extension](./extensions/trace-propagators) | Trace propagators, including B3, Jaeger, OT Trace | `opentelemetry-extension-trace-propagators` | 1.42.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-extension-trace-propagators.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-extension-trace-propagators) | +| [Kotlin Extension](./extensions/kotlin) | Context extension for coroutines | `opentelemetry-extension-kotlin` | 1.43.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-extension-kotlin.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-extension-kotlin) | +| [Trace Propagators Extension](./extensions/trace-propagators) | Trace propagators, including B3, Jaeger, OT Trace | `opentelemetry-extension-trace-propagators` | 1.43.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-extension-trace-propagators.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-extension-trace-propagators) | ### SDK | Component | Description | Artifact ID | Version | Javadoc | |------------------------------|--------------------------------------------------------|-----------------------------|---------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| [SDK](./sdk/all) | OpenTelemetry SDK, including metrics, traces, and logs | `opentelemetry-sdk` | 1.42.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk) | -| [Metrics SDK](./sdk/metrics) | OpenTelemetry metrics SDK | `opentelemetry-sdk-metrics` | 1.42.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-metrics.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-metrics) | -| [Trace SDK](./sdk/trace) | OpenTelemetry trace SDK | `opentelemetry-sdk-trace` | 1.42.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-trace.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-trace) | -| [Log SDK](./sdk/logs) | OpenTelemetry log SDK | `opentelemetry-sdk-logs` | 1.42.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-logs.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-logs) | -| [SDK Common](./sdk/common) | Shared SDK components | `opentelemetry-sdk-common` | 1.42.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-common.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-common) | -| [SDK Testing](./sdk/testing) | Components for testing OpenTelemetry instrumentation | `opentelemetry-sdk-testing` | 1.42.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-testing.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-testing) | +| [SDK](./sdk/all) | OpenTelemetry SDK, including metrics, traces, and logs | `opentelemetry-sdk` | 1.43.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk) | +| [Metrics SDK](./sdk/metrics) | OpenTelemetry metrics SDK | `opentelemetry-sdk-metrics` | 1.43.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-metrics.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-metrics) | +| [Trace SDK](./sdk/trace) | OpenTelemetry trace SDK | `opentelemetry-sdk-trace` | 1.43.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-trace.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-trace) | +| [Log SDK](./sdk/logs) | OpenTelemetry log SDK | `opentelemetry-sdk-logs` | 1.43.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-logs.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-logs) | +| [SDK Common](./sdk/common) | Shared SDK components | `opentelemetry-sdk-common` | 1.43.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-common.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-common) | +| [SDK Testing](./sdk/testing) | Components for testing OpenTelemetry instrumentation | `opentelemetry-sdk-testing` | 1.43.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-testing.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-testing) | ### SDK Exporters | Component | Description | Artifact ID | Version | Javadoc | |-----------------------------------------------------------------------|------------------------------------------------------------------------------|------------------------------------------------------|-------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| [OTLP Exporters](./exporters/otlp/all) | OTLP gRPC & HTTP exporters, including traces, metrics, and logs | `opentelemetry-exporter-otlp` | 1.42.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-otlp.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-otlp) | -| [OTLP Logging Exporters](./exporters/logging-otlp) | Logging exporters in OTLP JSON encoding, including traces, metrics, and logs | `opentelemetry-exporter-logging-otlp` | 1.42.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-logging-otlp.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-logging-otlp) | -| [OTLP Common](./exporters/otlp/common) | Shared OTLP components (internal) | `opentelemetry-exporter-otlp-common` | 1.42.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-otlp-common.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-otlp-common) | -| [Logging Exporter](./exporters/logging) | Logging exporters, including metrics, traces, and logs | `opentelemetry-exporter-logging` | 1.42.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-logging.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-logging) | -| [Zipkin Exporter](./exporters/zipkin) | Zipkin trace exporter | `opentelemetry-exporter-zipkin` | 1.42.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-zipkin.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-zipkin) | -| [Prometheus Exporter](./exporters/prometheus) | Prometheus metric exporter | `opentelemetry-exporter-prometheus` | 1.42.0-alpha | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-prometheus.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-prometheus) | -| [Exporter Common](./exporters/common) | Shared exporter components (internal) | `opentelemetry-exporter-common` | 1.42.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-common.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-common) | -| [OkHttp Sender](./exporters/sender/okhttp) | OkHttp implementation of HttpSender (internal) | `opentelemetry-exporter-sender-okhttp` | 1.42.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-sender-okhttp.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-sender-okhttp) | -| [JDK Sender](./exporters/sender/jdk) | Java 11+ native HttpClient implementation of HttpSender (internal) | `opentelemetry-exporter-sender-jdk` | 1.42.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-sender-jdk.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-sender-jdk) | | -| [gRPC ManagedChannel Sender](./exporters/sender/grpc-managed-channel) | gRPC ManagedChannel implementation of GrpcSender (internal) | `opentelemetry-exporter-sender-grpc-managed-channel` | 1.42.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-sender-grpc-managed-channel.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-sender-grpc-managed-channel) | | +| [OTLP Exporters](./exporters/otlp/all) | OTLP gRPC & HTTP exporters, including traces, metrics, and logs | `opentelemetry-exporter-otlp` | 1.43.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-otlp.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-otlp) | +| [OTLP Logging Exporters](./exporters/logging-otlp) | Logging exporters in OTLP JSON encoding, including traces, metrics, and logs | `opentelemetry-exporter-logging-otlp` | 1.43.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-logging-otlp.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-logging-otlp) | +| [OTLP Common](./exporters/otlp/common) | Shared OTLP components (internal) | `opentelemetry-exporter-otlp-common` | 1.43.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-otlp-common.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-otlp-common) | +| [Logging Exporter](./exporters/logging) | Logging exporters, including metrics, traces, and logs | `opentelemetry-exporter-logging` | 1.43.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-logging.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-logging) | +| [Zipkin Exporter](./exporters/zipkin) | Zipkin trace exporter | `opentelemetry-exporter-zipkin` | 1.43.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-zipkin.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-zipkin) | +| [Prometheus Exporter](./exporters/prometheus) | Prometheus metric exporter | `opentelemetry-exporter-prometheus` | 1.43.0-alpha | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-prometheus.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-prometheus) | +| [Exporter Common](./exporters/common) | Shared exporter components (internal) | `opentelemetry-exporter-common` | 1.43.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-common.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-common) | +| [OkHttp Sender](./exporters/sender/okhttp) | OkHttp implementation of HttpSender (internal) | `opentelemetry-exporter-sender-okhttp` | 1.43.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-sender-okhttp.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-sender-okhttp) | +| [JDK Sender](./exporters/sender/jdk) | Java 11+ native HttpClient implementation of HttpSender (internal) | `opentelemetry-exporter-sender-jdk` | 1.43.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-sender-jdk.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-sender-jdk) | | +| [gRPC ManagedChannel Sender](./exporters/sender/grpc-managed-channel) | gRPC ManagedChannel implementation of GrpcSender (internal) | `opentelemetry-exporter-sender-grpc-managed-channel` | 1.43.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-sender-grpc-managed-channel.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-sender-grpc-managed-channel) | | ### SDK Extensions | Component | Description | Artifact ID | Version | Javadoc | |-------------------------------------------------------------------------------|------------------------------------------------------------------------------------|-----------------------------------------------------|-------------------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| [SDK Autoconfigure](./sdk-extensions/autoconfigure) | Autoconfigure OpenTelemetry SDK from env vars, system properties, and SPI | `opentelemetry-sdk-extension-autoconfigure` | 1.42.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-extension-autoconfigure.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-extension-autoconfigure) | -| [SDK Autoconfigure SPI](./sdk-extensions/autoconfigure-spi) | Service Provider Interface (SPI) definitions for autoconfigure | `opentelemetry-sdk-extension-autoconfigure-spi` | 1.42.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-extension-autoconfigure-spi.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-extension-autoconfigure-spi) | -| [SDK Jaeger Remote Sampler Extension](./sdk-extensions/jaeger-remote-sampler) | Sampler which obtains sampling configuration from remote Jaeger server | `opentelemetry-sdk-extension-jaeger-remote-sampler` | 1.42.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-extension-jaeger-remote-sampler.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-extension-jaeger-remote-sampler) | -| [SDK Incubator](./sdk-extensions/incubator) | SDK incubator, including YAML based view configuration, LeakDetectingSpanProcessor | `opentelemetry-sdk-extension-incubator` | 1.42.0-alpha | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-extension-incubator.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-extension-incubator) | +| [SDK Autoconfigure](./sdk-extensions/autoconfigure) | Autoconfigure OpenTelemetry SDK from env vars, system properties, and SPI | `opentelemetry-sdk-extension-autoconfigure` | 1.43.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-extension-autoconfigure.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-extension-autoconfigure) | +| [SDK Autoconfigure SPI](./sdk-extensions/autoconfigure-spi) | Service Provider Interface (SPI) definitions for autoconfigure | `opentelemetry-sdk-extension-autoconfigure-spi` | 1.43.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-extension-autoconfigure-spi.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-extension-autoconfigure-spi) | +| [SDK Jaeger Remote Sampler Extension](./sdk-extensions/jaeger-remote-sampler) | Sampler which obtains sampling configuration from remote Jaeger server | `opentelemetry-sdk-extension-jaeger-remote-sampler` | 1.43.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-extension-jaeger-remote-sampler.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-extension-jaeger-remote-sampler) | +| [SDK Incubator](./sdk-extensions/incubator) | SDK incubator, including YAML based view configuration, LeakDetectingSpanProcessor | `opentelemetry-sdk-extension-incubator` | 1.43.0-alpha | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-extension-incubator.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-extension-incubator) | ### Shims | Component | Description | Artifact ID | Version | Javadoc | |----------------------------------------|--------------------------------------------------------------|----------------------------------|-------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| [OpenCensus Shim](./opencensus-shim) | Bridge opencensus metrics into the OpenTelemetry metrics SDK | `opentelemetry-opencensus-shim` | 1.42.0-alpha | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-opencensus-shim.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-opencensus-shim) | -| [OpenTracing Shim](./opentracing-shim) | Bridge opentracing spans into the OpenTelemetry trace API | `opentelemetry-opentracing-shim` | 1.42.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-opentracing-shim.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-opentracing-shim) | +| [OpenCensus Shim](./opencensus-shim) | Bridge opencensus metrics into the OpenTelemetry metrics SDK | `opentelemetry-opencensus-shim` | 1.43.0-alpha | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-opencensus-shim.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-opencensus-shim) | +| [OpenTracing Shim](./opentracing-shim) | Bridge opentracing spans into the OpenTelemetry trace API | `opentelemetry-opentracing-shim` | 1.43.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-opentracing-shim.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-opentracing-shim) | ## Contributing diff --git a/docs/apidiffs/1.43.0_vs_1.42.0/opentelemetry-api.txt b/docs/apidiffs/1.43.0_vs_1.42.0/opentelemetry-api.txt new file mode 100644 index 00000000000..b11bbc44363 --- /dev/null +++ b/docs/apidiffs/1.43.0_vs_1.42.0/opentelemetry-api.txt @@ -0,0 +1,5 @@ +Comparing source compatibility of opentelemetry-api-1.43.0.jar against opentelemetry-api-1.42.0.jar +*** MODIFIED INTERFACE: PUBLIC ABSTRACT io.opentelemetry.api.baggage.Baggage (not serializable) + === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 + +++ NEW METHOD: PUBLIC(+) io.opentelemetry.api.baggage.BaggageEntry getEntry(java.lang.String) + +++ NEW ANNOTATION: javax.annotation.Nullable diff --git a/docs/apidiffs/1.43.0_vs_1.42.0/opentelemetry-context.txt b/docs/apidiffs/1.43.0_vs_1.42.0/opentelemetry-context.txt new file mode 100644 index 00000000000..f01838a847d --- /dev/null +++ b/docs/apidiffs/1.43.0_vs_1.42.0/opentelemetry-context.txt @@ -0,0 +1,4 @@ +Comparing source compatibility of opentelemetry-context-1.43.0.jar against opentelemetry-context-1.42.0.jar +*** MODIFIED INTERFACE: PUBLIC ABSTRACT io.opentelemetry.context.Context (not serializable) + === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 + +++ NEW METHOD: PUBLIC(+) STATIC(+) java.util.concurrent.ScheduledExecutorService taskWrapping(java.util.concurrent.ScheduledExecutorService) diff --git a/docs/apidiffs/1.43.0_vs_1.42.0/opentelemetry-exporter-common.txt b/docs/apidiffs/1.43.0_vs_1.42.0/opentelemetry-exporter-common.txt new file mode 100644 index 00000000000..4f61afb8eb1 --- /dev/null +++ b/docs/apidiffs/1.43.0_vs_1.42.0/opentelemetry-exporter-common.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of opentelemetry-exporter-common-1.43.0.jar against opentelemetry-exporter-common-1.42.0.jar +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.43.0_vs_1.42.0/opentelemetry-exporter-logging-otlp.txt b/docs/apidiffs/1.43.0_vs_1.42.0/opentelemetry-exporter-logging-otlp.txt new file mode 100644 index 00000000000..2df260f443c --- /dev/null +++ b/docs/apidiffs/1.43.0_vs_1.42.0/opentelemetry-exporter-logging-otlp.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of opentelemetry-exporter-logging-otlp-1.43.0.jar against opentelemetry-exporter-logging-otlp-1.42.0.jar +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.43.0_vs_1.42.0/opentelemetry-exporter-logging.txt b/docs/apidiffs/1.43.0_vs_1.42.0/opentelemetry-exporter-logging.txt new file mode 100644 index 00000000000..486843d7ca4 --- /dev/null +++ b/docs/apidiffs/1.43.0_vs_1.42.0/opentelemetry-exporter-logging.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of opentelemetry-exporter-logging-1.43.0.jar against opentelemetry-exporter-logging-1.42.0.jar +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.43.0_vs_1.42.0/opentelemetry-exporter-otlp-common.txt b/docs/apidiffs/1.43.0_vs_1.42.0/opentelemetry-exporter-otlp-common.txt new file mode 100644 index 00000000000..67ed4e71728 --- /dev/null +++ b/docs/apidiffs/1.43.0_vs_1.42.0/opentelemetry-exporter-otlp-common.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of opentelemetry-exporter-otlp-common-1.43.0.jar against opentelemetry-exporter-otlp-common-1.42.0.jar +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.43.0_vs_1.42.0/opentelemetry-exporter-otlp.txt b/docs/apidiffs/1.43.0_vs_1.42.0/opentelemetry-exporter-otlp.txt new file mode 100644 index 00000000000..4c3afc0f107 --- /dev/null +++ b/docs/apidiffs/1.43.0_vs_1.42.0/opentelemetry-exporter-otlp.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of opentelemetry-exporter-otlp-1.43.0.jar against opentelemetry-exporter-otlp-1.42.0.jar +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.43.0_vs_1.42.0/opentelemetry-exporter-sender-grpc-managed-channel.txt b/docs/apidiffs/1.43.0_vs_1.42.0/opentelemetry-exporter-sender-grpc-managed-channel.txt new file mode 100644 index 00000000000..f9e1ee6e790 --- /dev/null +++ b/docs/apidiffs/1.43.0_vs_1.42.0/opentelemetry-exporter-sender-grpc-managed-channel.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of opentelemetry-exporter-sender-grpc-managed-channel-1.43.0.jar against opentelemetry-exporter-sender-grpc-managed-channel-1.42.0.jar +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.43.0_vs_1.42.0/opentelemetry-exporter-sender-jdk.txt b/docs/apidiffs/1.43.0_vs_1.42.0/opentelemetry-exporter-sender-jdk.txt new file mode 100644 index 00000000000..6c717fd3eec --- /dev/null +++ b/docs/apidiffs/1.43.0_vs_1.42.0/opentelemetry-exporter-sender-jdk.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of opentelemetry-exporter-sender-jdk-1.43.0.jar against opentelemetry-exporter-sender-jdk-1.42.0.jar +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.43.0_vs_1.42.0/opentelemetry-exporter-sender-okhttp.txt b/docs/apidiffs/1.43.0_vs_1.42.0/opentelemetry-exporter-sender-okhttp.txt new file mode 100644 index 00000000000..3517b983a81 --- /dev/null +++ b/docs/apidiffs/1.43.0_vs_1.42.0/opentelemetry-exporter-sender-okhttp.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of opentelemetry-exporter-sender-okhttp-1.43.0.jar against opentelemetry-exporter-sender-okhttp-1.42.0.jar +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.43.0_vs_1.42.0/opentelemetry-exporter-zipkin.txt b/docs/apidiffs/1.43.0_vs_1.42.0/opentelemetry-exporter-zipkin.txt new file mode 100644 index 00000000000..bad70283ecf --- /dev/null +++ b/docs/apidiffs/1.43.0_vs_1.42.0/opentelemetry-exporter-zipkin.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of opentelemetry-exporter-zipkin-1.43.0.jar against opentelemetry-exporter-zipkin-1.42.0.jar +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.43.0_vs_1.42.0/opentelemetry-extension-kotlin.txt b/docs/apidiffs/1.43.0_vs_1.42.0/opentelemetry-extension-kotlin.txt new file mode 100644 index 00000000000..a734b74463d --- /dev/null +++ b/docs/apidiffs/1.43.0_vs_1.42.0/opentelemetry-extension-kotlin.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of opentelemetry-extension-kotlin-1.43.0.jar against opentelemetry-extension-kotlin-1.42.0.jar +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.43.0_vs_1.42.0/opentelemetry-extension-trace-propagators.txt b/docs/apidiffs/1.43.0_vs_1.42.0/opentelemetry-extension-trace-propagators.txt new file mode 100644 index 00000000000..66ba7fd51af --- /dev/null +++ b/docs/apidiffs/1.43.0_vs_1.42.0/opentelemetry-extension-trace-propagators.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of opentelemetry-extension-trace-propagators-1.43.0.jar against opentelemetry-extension-trace-propagators-1.42.0.jar +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.43.0_vs_1.42.0/opentelemetry-opentracing-shim.txt b/docs/apidiffs/1.43.0_vs_1.42.0/opentelemetry-opentracing-shim.txt new file mode 100644 index 00000000000..f2bd7607ce4 --- /dev/null +++ b/docs/apidiffs/1.43.0_vs_1.42.0/opentelemetry-opentracing-shim.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of opentelemetry-opentracing-shim-1.43.0.jar against opentelemetry-opentracing-shim-1.42.0.jar +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.43.0_vs_1.42.0/opentelemetry-sdk-common.txt b/docs/apidiffs/1.43.0_vs_1.42.0/opentelemetry-sdk-common.txt new file mode 100644 index 00000000000..c6c737f6f6f --- /dev/null +++ b/docs/apidiffs/1.43.0_vs_1.42.0/opentelemetry-sdk-common.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of opentelemetry-sdk-common-1.43.0.jar against opentelemetry-sdk-common-1.42.0.jar +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.43.0_vs_1.42.0/opentelemetry-sdk-extension-autoconfigure-spi.txt b/docs/apidiffs/1.43.0_vs_1.42.0/opentelemetry-sdk-extension-autoconfigure-spi.txt new file mode 100644 index 00000000000..7e2e0155064 --- /dev/null +++ b/docs/apidiffs/1.43.0_vs_1.42.0/opentelemetry-sdk-extension-autoconfigure-spi.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of opentelemetry-sdk-extension-autoconfigure-spi-1.43.0.jar against opentelemetry-sdk-extension-autoconfigure-spi-1.42.0.jar +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.43.0_vs_1.42.0/opentelemetry-sdk-extension-autoconfigure.txt b/docs/apidiffs/1.43.0_vs_1.42.0/opentelemetry-sdk-extension-autoconfigure.txt new file mode 100644 index 00000000000..3d38546b923 --- /dev/null +++ b/docs/apidiffs/1.43.0_vs_1.42.0/opentelemetry-sdk-extension-autoconfigure.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of opentelemetry-sdk-extension-autoconfigure-1.43.0.jar against opentelemetry-sdk-extension-autoconfigure-1.42.0.jar +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.43.0_vs_1.42.0/opentelemetry-sdk-extension-jaeger-remote-sampler.txt b/docs/apidiffs/1.43.0_vs_1.42.0/opentelemetry-sdk-extension-jaeger-remote-sampler.txt new file mode 100644 index 00000000000..b58ac546dc1 --- /dev/null +++ b/docs/apidiffs/1.43.0_vs_1.42.0/opentelemetry-sdk-extension-jaeger-remote-sampler.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of opentelemetry-sdk-extension-jaeger-remote-sampler-1.43.0.jar against opentelemetry-sdk-extension-jaeger-remote-sampler-1.42.0.jar +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.43.0_vs_1.42.0/opentelemetry-sdk-logs.txt b/docs/apidiffs/1.43.0_vs_1.42.0/opentelemetry-sdk-logs.txt new file mode 100644 index 00000000000..70fcf9a7e92 --- /dev/null +++ b/docs/apidiffs/1.43.0_vs_1.42.0/opentelemetry-sdk-logs.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of opentelemetry-sdk-logs-1.43.0.jar against opentelemetry-sdk-logs-1.42.0.jar +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.43.0_vs_1.42.0/opentelemetry-sdk-metrics.txt b/docs/apidiffs/1.43.0_vs_1.42.0/opentelemetry-sdk-metrics.txt new file mode 100644 index 00000000000..a6a67209348 --- /dev/null +++ b/docs/apidiffs/1.43.0_vs_1.42.0/opentelemetry-sdk-metrics.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of opentelemetry-sdk-metrics-1.43.0.jar against opentelemetry-sdk-metrics-1.42.0.jar +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.43.0_vs_1.42.0/opentelemetry-sdk-testing.txt b/docs/apidiffs/1.43.0_vs_1.42.0/opentelemetry-sdk-testing.txt new file mode 100644 index 00000000000..1b0720243f5 --- /dev/null +++ b/docs/apidiffs/1.43.0_vs_1.42.0/opentelemetry-sdk-testing.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of opentelemetry-sdk-testing-1.43.0.jar against opentelemetry-sdk-testing-1.42.0.jar +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.43.0_vs_1.42.0/opentelemetry-sdk-trace.txt b/docs/apidiffs/1.43.0_vs_1.42.0/opentelemetry-sdk-trace.txt new file mode 100644 index 00000000000..dc14e4e2560 --- /dev/null +++ b/docs/apidiffs/1.43.0_vs_1.42.0/opentelemetry-sdk-trace.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of opentelemetry-sdk-trace-1.43.0.jar against opentelemetry-sdk-trace-1.42.0.jar +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.43.0_vs_1.42.0/opentelemetry-sdk.txt b/docs/apidiffs/1.43.0_vs_1.42.0/opentelemetry-sdk.txt new file mode 100644 index 00000000000..5530c784a30 --- /dev/null +++ b/docs/apidiffs/1.43.0_vs_1.42.0/opentelemetry-sdk.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of opentelemetry-sdk-1.43.0.jar against opentelemetry-sdk-1.42.0.jar +No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-api.txt b/docs/apidiffs/current_vs_latest/opentelemetry-api.txt index fb5d54460b0..22b25875a3a 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-api.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-api.txt @@ -1,5 +1,2 @@ -Comparing source compatibility of opentelemetry-api-1.43.0-SNAPSHOT.jar against opentelemetry-api-1.42.1.jar -*** MODIFIED INTERFACE: PUBLIC ABSTRACT io.opentelemetry.api.baggage.Baggage (not serializable) - === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 - +++ NEW METHOD: PUBLIC(+) io.opentelemetry.api.baggage.BaggageEntry getEntry(java.lang.String) - +++ NEW ANNOTATION: javax.annotation.Nullable +Comparing source compatibility of opentelemetry-api-1.44.0-SNAPSHOT.jar against opentelemetry-api-1.43.0.jar +No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-context.txt b/docs/apidiffs/current_vs_latest/opentelemetry-context.txt index 1157c08dce0..cac847ecf2e 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-context.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-context.txt @@ -1,4 +1,2 @@ -Comparing source compatibility of opentelemetry-context-1.43.0-SNAPSHOT.jar against opentelemetry-context-1.42.1.jar -*** MODIFIED INTERFACE: PUBLIC ABSTRACT io.opentelemetry.context.Context (not serializable) - === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 - +++ NEW METHOD: PUBLIC(+) STATIC(+) java.util.concurrent.ScheduledExecutorService taskWrapping(java.util.concurrent.ScheduledExecutorService) +Comparing source compatibility of opentelemetry-context-1.44.0-SNAPSHOT.jar against opentelemetry-context-1.43.0.jar +No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-common.txt b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-common.txt index 9e03ebcd3c3..27662633e4a 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-common.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-common.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of opentelemetry-exporter-common-1.43.0-SNAPSHOT.jar against opentelemetry-exporter-common-1.42.1.jar +Comparing source compatibility of opentelemetry-exporter-common-1.44.0-SNAPSHOT.jar against opentelemetry-exporter-common-1.43.0.jar No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-logging-otlp.txt b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-logging-otlp.txt index 58fedf2a521..f4eb50807c8 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-logging-otlp.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-logging-otlp.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of opentelemetry-exporter-logging-otlp-1.43.0-SNAPSHOT.jar against opentelemetry-exporter-logging-otlp-1.42.1.jar +Comparing source compatibility of opentelemetry-exporter-logging-otlp-1.44.0-SNAPSHOT.jar against opentelemetry-exporter-logging-otlp-1.43.0.jar No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-logging.txt b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-logging.txt index c893f199396..19151b77a28 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-logging.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-logging.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of opentelemetry-exporter-logging-1.43.0-SNAPSHOT.jar against opentelemetry-exporter-logging-1.42.1.jar +Comparing source compatibility of opentelemetry-exporter-logging-1.44.0-SNAPSHOT.jar against opentelemetry-exporter-logging-1.43.0.jar No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-otlp-common.txt b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-otlp-common.txt index 4e744fdd9ac..cfc37ac9e71 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-otlp-common.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-otlp-common.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of opentelemetry-exporter-otlp-common-1.43.0-SNAPSHOT.jar against opentelemetry-exporter-otlp-common-1.42.1.jar +Comparing source compatibility of opentelemetry-exporter-otlp-common-1.44.0-SNAPSHOT.jar against opentelemetry-exporter-otlp-common-1.43.0.jar No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-otlp.txt b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-otlp.txt index 7b0edf4faa9..dff93d3af84 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-otlp.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-otlp.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of opentelemetry-exporter-otlp-1.43.0-SNAPSHOT.jar against opentelemetry-exporter-otlp-1.42.1.jar +Comparing source compatibility of opentelemetry-exporter-otlp-1.44.0-SNAPSHOT.jar against opentelemetry-exporter-otlp-1.43.0.jar No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-sender-grpc-managed-channel.txt b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-sender-grpc-managed-channel.txt index b7a41b5c2d0..1dd4bb6cf92 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-sender-grpc-managed-channel.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-sender-grpc-managed-channel.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of opentelemetry-exporter-sender-grpc-managed-channel-1.43.0-SNAPSHOT.jar against opentelemetry-exporter-sender-grpc-managed-channel-1.42.1.jar +Comparing source compatibility of opentelemetry-exporter-sender-grpc-managed-channel-1.44.0-SNAPSHOT.jar against opentelemetry-exporter-sender-grpc-managed-channel-1.43.0.jar No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-sender-jdk.txt b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-sender-jdk.txt index 2440c50dc8a..9ec3d17ba48 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-sender-jdk.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-sender-jdk.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of opentelemetry-exporter-sender-jdk-1.43.0-SNAPSHOT.jar against opentelemetry-exporter-sender-jdk-1.42.1.jar +Comparing source compatibility of opentelemetry-exporter-sender-jdk-1.44.0-SNAPSHOT.jar against opentelemetry-exporter-sender-jdk-1.43.0.jar No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-sender-okhttp.txt b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-sender-okhttp.txt index dfa3073e783..5569153a8e9 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-sender-okhttp.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-sender-okhttp.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of opentelemetry-exporter-sender-okhttp-1.43.0-SNAPSHOT.jar against opentelemetry-exporter-sender-okhttp-1.42.1.jar +Comparing source compatibility of opentelemetry-exporter-sender-okhttp-1.44.0-SNAPSHOT.jar against opentelemetry-exporter-sender-okhttp-1.43.0.jar No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-zipkin.txt b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-zipkin.txt index 537e948dcc2..692173ab320 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-zipkin.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-zipkin.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of opentelemetry-exporter-zipkin-1.43.0-SNAPSHOT.jar against opentelemetry-exporter-zipkin-1.42.1.jar +Comparing source compatibility of opentelemetry-exporter-zipkin-1.44.0-SNAPSHOT.jar against opentelemetry-exporter-zipkin-1.43.0.jar No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-extension-kotlin.txt b/docs/apidiffs/current_vs_latest/opentelemetry-extension-kotlin.txt index 7c65c448a0b..ba6ef24dc0c 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-extension-kotlin.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-extension-kotlin.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of opentelemetry-extension-kotlin-1.43.0-SNAPSHOT.jar against opentelemetry-extension-kotlin-1.42.1.jar +Comparing source compatibility of opentelemetry-extension-kotlin-1.44.0-SNAPSHOT.jar against opentelemetry-extension-kotlin-1.43.0.jar No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-extension-trace-propagators.txt b/docs/apidiffs/current_vs_latest/opentelemetry-extension-trace-propagators.txt index 98a141a6aeb..13c133ff51c 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-extension-trace-propagators.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-extension-trace-propagators.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of opentelemetry-extension-trace-propagators-1.43.0-SNAPSHOT.jar against opentelemetry-extension-trace-propagators-1.42.1.jar +Comparing source compatibility of opentelemetry-extension-trace-propagators-1.44.0-SNAPSHOT.jar against opentelemetry-extension-trace-propagators-1.43.0.jar No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-opentracing-shim.txt b/docs/apidiffs/current_vs_latest/opentelemetry-opentracing-shim.txt index 05003fc7f80..f99d150208f 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-opentracing-shim.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-opentracing-shim.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of opentelemetry-opentracing-shim-1.43.0-SNAPSHOT.jar against opentelemetry-opentracing-shim-1.42.1.jar +Comparing source compatibility of opentelemetry-opentracing-shim-1.44.0-SNAPSHOT.jar against opentelemetry-opentracing-shim-1.43.0.jar No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-common.txt b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-common.txt index 86896440efc..7c5dcaabee9 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-common.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-common.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of opentelemetry-sdk-common-1.43.0-SNAPSHOT.jar against opentelemetry-sdk-common-1.42.1.jar +Comparing source compatibility of opentelemetry-sdk-common-1.44.0-SNAPSHOT.jar against opentelemetry-sdk-common-1.43.0.jar No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-extension-autoconfigure-spi.txt b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-extension-autoconfigure-spi.txt index b2d9f314311..6dc02f3d53f 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-extension-autoconfigure-spi.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-extension-autoconfigure-spi.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of opentelemetry-sdk-extension-autoconfigure-spi-1.43.0-SNAPSHOT.jar against opentelemetry-sdk-extension-autoconfigure-spi-1.42.1.jar +Comparing source compatibility of opentelemetry-sdk-extension-autoconfigure-spi-1.44.0-SNAPSHOT.jar against opentelemetry-sdk-extension-autoconfigure-spi-1.43.0.jar No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-extension-autoconfigure.txt b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-extension-autoconfigure.txt index 71e51b48273..b7251779550 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-extension-autoconfigure.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-extension-autoconfigure.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of opentelemetry-sdk-extension-autoconfigure-1.43.0-SNAPSHOT.jar against opentelemetry-sdk-extension-autoconfigure-1.42.1.jar +Comparing source compatibility of opentelemetry-sdk-extension-autoconfigure-1.44.0-SNAPSHOT.jar against opentelemetry-sdk-extension-autoconfigure-1.43.0.jar No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-extension-jaeger-remote-sampler.txt b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-extension-jaeger-remote-sampler.txt index 908a8c453d1..2afdbaa513d 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-extension-jaeger-remote-sampler.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-extension-jaeger-remote-sampler.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of opentelemetry-sdk-extension-jaeger-remote-sampler-1.43.0-SNAPSHOT.jar against opentelemetry-sdk-extension-jaeger-remote-sampler-1.42.1.jar +Comparing source compatibility of opentelemetry-sdk-extension-jaeger-remote-sampler-1.44.0-SNAPSHOT.jar against opentelemetry-sdk-extension-jaeger-remote-sampler-1.43.0.jar No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-logs.txt b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-logs.txt index 2b74b883472..47e56fdd20f 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-logs.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-logs.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of opentelemetry-sdk-logs-1.43.0-SNAPSHOT.jar against opentelemetry-sdk-logs-1.42.1.jar +Comparing source compatibility of opentelemetry-sdk-logs-1.44.0-SNAPSHOT.jar against opentelemetry-sdk-logs-1.43.0.jar No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-metrics.txt b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-metrics.txt index d72c3db4aa0..3650627a2d9 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-metrics.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-metrics.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of opentelemetry-sdk-metrics-1.43.0-SNAPSHOT.jar against opentelemetry-sdk-metrics-1.42.1.jar +Comparing source compatibility of opentelemetry-sdk-metrics-1.44.0-SNAPSHOT.jar against opentelemetry-sdk-metrics-1.43.0.jar No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-testing.txt b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-testing.txt index dce15125b1c..ecf7cf7c9ef 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-testing.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-testing.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of opentelemetry-sdk-testing-1.43.0-SNAPSHOT.jar against opentelemetry-sdk-testing-1.42.1.jar +Comparing source compatibility of opentelemetry-sdk-testing-1.44.0-SNAPSHOT.jar against opentelemetry-sdk-testing-1.43.0.jar No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-trace.txt b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-trace.txt index d9256c134de..10464c237f1 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-trace.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-trace.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of opentelemetry-sdk-trace-1.43.0-SNAPSHOT.jar against opentelemetry-sdk-trace-1.42.1.jar +Comparing source compatibility of opentelemetry-sdk-trace-1.44.0-SNAPSHOT.jar against opentelemetry-sdk-trace-1.43.0.jar No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-sdk.txt b/docs/apidiffs/current_vs_latest/opentelemetry-sdk.txt index b44828c2284..59adccb88e8 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-sdk.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-sdk.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of opentelemetry-sdk-1.43.0-SNAPSHOT.jar against opentelemetry-sdk-1.42.1.jar +Comparing source compatibility of opentelemetry-sdk-1.44.0-SNAPSHOT.jar against opentelemetry-sdk-1.43.0.jar No changes. \ No newline at end of file From 3e650f00a11b67c4c30d03fe2d2eaf30c400f217 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 15 Oct 2024 10:15:15 -0500 Subject: [PATCH 610/901] fix(deps): update dependency io.opentelemetry.semconv:opentelemetry-semconv-incubating to v1.28.0-alpha (#6792) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- dependencyManagement/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index 9194798c861..806ed9abaa2 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -67,7 +67,7 @@ val DEPENDENCIES = listOf( "io.github.netmikey.logunit:logunit-jul:2.0.0", "io.jaegertracing:jaeger-client:1.8.1", "io.opentelemetry.contrib:opentelemetry-aws-xray-propagator:1.39.0-alpha", - "io.opentelemetry.semconv:opentelemetry-semconv-incubating:1.27.0-alpha", + "io.opentelemetry.semconv:opentelemetry-semconv-incubating:1.28.0-alpha", "io.opentelemetry.proto:opentelemetry-proto:1.3.2-alpha", "io.opentracing:opentracing-api:0.33.0", "io.opentracing:opentracing-noop:0.33.0", From 83b30b5d0e58158ba3e42d334aadde77fe614bd7 Mon Sep 17 00:00:00 2001 From: Trask Stalnaker Date: Tue, 15 Oct 2024 11:13:51 -0700 Subject: [PATCH 611/901] Bump config file format version (#6786) --- .../sdk/autoconfigure/FileConfigurationTest.java | 2 +- .../sdk/autoconfigure/FileConfigurationTest.java | 4 ++-- sdk-extensions/incubator/build.gradle.kts | 7 +++++-- .../OpenTelemetryConfigurationFactory.java | 4 ++-- .../fileconfig/FileConfigurationCreateTest.java | 2 +- .../fileconfig/FileConfigurationParseTest.java | 12 ++++++------ .../OpenTelemetryConfigurationFactoryTest.java | 8 ++++---- .../YamlStructuredConfigPropertiesTest.java | 4 ++-- 8 files changed, 23 insertions(+), 20 deletions(-) diff --git a/sdk-extensions/autoconfigure/src/test/java/io/opentelemetry/sdk/autoconfigure/FileConfigurationTest.java b/sdk-extensions/autoconfigure/src/test/java/io/opentelemetry/sdk/autoconfigure/FileConfigurationTest.java index e3a9bb3ed10..955e5817693 100644 --- a/sdk-extensions/autoconfigure/src/test/java/io/opentelemetry/sdk/autoconfigure/FileConfigurationTest.java +++ b/sdk-extensions/autoconfigure/src/test/java/io/opentelemetry/sdk/autoconfigure/FileConfigurationTest.java @@ -31,7 +31,7 @@ class FileConfigurationTest { @Test void configFile(@TempDir Path tempDir) throws IOException { String yaml = - "file_format: \"0.1\"\n" + "file_format: \"0.3\"\n" + "resource:\n" + " attributes:\n" + " - name: service.name\n" diff --git a/sdk-extensions/autoconfigure/src/testFullConfig/java/io/opentelemetry/sdk/autoconfigure/FileConfigurationTest.java b/sdk-extensions/autoconfigure/src/testFullConfig/java/io/opentelemetry/sdk/autoconfigure/FileConfigurationTest.java index 3b3869e5bf6..7eface52c5e 100644 --- a/sdk-extensions/autoconfigure/src/testFullConfig/java/io/opentelemetry/sdk/autoconfigure/FileConfigurationTest.java +++ b/sdk-extensions/autoconfigure/src/testFullConfig/java/io/opentelemetry/sdk/autoconfigure/FileConfigurationTest.java @@ -55,7 +55,7 @@ class FileConfigurationTest { @BeforeEach void setup() throws IOException { String yaml = - "file_format: \"0.1\"\n" + "file_format: \"0.3\"\n" + "resource:\n" + " attributes:\n" + " - name: service.name\n" @@ -160,7 +160,7 @@ void configFile_setResultAsGlobalTrue() { @Test void configFile_Error(@TempDir Path tempDir) throws IOException { String yaml = - "file_format: \"0.1\"\n" + "file_format: \"0.3\"\n" + "resource:\n" + " attributes:\n" + " - name: service.name\n" diff --git a/sdk-extensions/incubator/build.gradle.kts b/sdk-extensions/incubator/build.gradle.kts index 59acac261ef..92be979672f 100644 --- a/sdk-extensions/incubator/build.gradle.kts +++ b/sdk-extensions/incubator/build.gradle.kts @@ -56,8 +56,11 @@ dependencies { // 7. deleteJs2pTmp - delete tmp directory // ... proceed with normal sourcesJar, compileJava, etc -val configurationTag = "0.3.0" -val configurationRef = "refs/tags/v$configurationTag" // Replace with commit SHA to point to experiment with a specific commit +// TODO (trask) revert after the 0.4.0 release +// it was needed after 0.3.0 release because file_format in the examples weren't updated prior to the release tag +// val configurationTag = "0.3.0" +// val configurationRef = "refs/tags/v$configurationTag" // Replace with commit SHA to point to experiment with a specific commit +val configurationRef = "cea3905ce0a542d573968c3c47d413143d473cf4" val configurationRepoZip = "https://github.com/open-telemetry/opentelemetry-configuration/archive/$configurationRef.zip" val buildDirectory = layout.buildDirectory.asFile.get() diff --git a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/OpenTelemetryConfigurationFactory.java b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/OpenTelemetryConfigurationFactory.java index 0213839ee30..5df6a4766a3 100644 --- a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/OpenTelemetryConfigurationFactory.java +++ b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/OpenTelemetryConfigurationFactory.java @@ -31,8 +31,8 @@ static OpenTelemetryConfigurationFactory getInstance() { public OpenTelemetrySdk create( OpenTelemetryConfigurationModel model, SpiHelper spiHelper, List closeables) { OpenTelemetrySdkBuilder builder = OpenTelemetrySdk.builder(); - if (!"0.1".equals(model.getFileFormat())) { - throw new ConfigurationException("Unsupported file format. Supported formats include: 0.1"); + if (!"0.3".equals(model.getFileFormat())) { + throw new ConfigurationException("Unsupported file format. Supported formats include: 0.3"); } if (Objects.equals(Boolean.TRUE, model.getDisabled())) { diff --git a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/FileConfigurationCreateTest.java b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/FileConfigurationCreateTest.java index d47ae14eb9a..c1a97a8e265 100644 --- a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/FileConfigurationCreateTest.java +++ b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/FileConfigurationCreateTest.java @@ -103,7 +103,7 @@ void parseAndCreate_Exception_CleansUpPartials() { // exporter with OTLP exporter, following by invalid batch exporter which references invalid // exporter "foo". String yaml = - "file_format: \"0.1\"\n" + "file_format: \"0.3\"\n" + "logger_provider:\n" + " processors:\n" + " - batch:\n" diff --git a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/FileConfigurationParseTest.java b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/FileConfigurationParseTest.java index 81aa6f4487e..b90c154205a 100644 --- a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/FileConfigurationParseTest.java +++ b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/FileConfigurationParseTest.java @@ -92,7 +92,7 @@ void parse_BadInputStream() { void parse_KitchenSinkExampleFile() throws IOException { OpenTelemetryConfigurationModel expected = new OpenTelemetryConfigurationModel(); - expected.withFileFormat("0.1"); + expected.withFileFormat("0.3"); expected.withDisabled(false); // General config @@ -449,7 +449,7 @@ void parse_KitchenSinkExampleFile() throws IOException { OpenTelemetryConfigurationModel config = FileConfiguration.parse(configExampleFile); // General config - assertThat(config.getFileFormat()).isEqualTo("0.1"); + assertThat(config.getFileFormat()).isEqualTo("0.3"); assertThat(config.getResource()).isEqualTo(resource); assertThat(config.getAttributeLimits()).isEqualTo(attributeLimits); assertThat(config.getPropagator()).isEqualTo(propagator); @@ -485,7 +485,7 @@ void parse_KitchenSinkExampleFile() throws IOException { @Test void parse_nullValuesParsedToEmptyObjects() { String objectPlaceholderString = - "file_format: \"0.1\"\n" + "file_format: \"0.3\"\n" + "tracer_provider:\n" + " processors:\n" + " - batch:\n" @@ -503,7 +503,7 @@ void parse_nullValuesParsedToEmptyObjects() { new ByteArrayInputStream(objectPlaceholderString.getBytes(StandardCharsets.UTF_8))); String noOjbectPlaceholderString = - "file_format: \"0.1\"\n" + "file_format: \"0.3\"\n" + "tracer_provider:\n" + " processors:\n" + " - batch:\n" @@ -672,7 +672,7 @@ private static Map mapOf(Map.Entry... entries) { @Test void read_WithEnvironmentVariables() { String yaml = - "file_format: \"0.1\"\n" + "file_format: \"0.3\"\n" + "tracer_provider:\n" + " processors:\n" + " - batch:\n" @@ -691,7 +691,7 @@ void read_WithEnvironmentVariables() { assertThat(model) .isEqualTo( new OpenTelemetryConfigurationModel() - .withFileFormat("0.1") + .withFileFormat("0.3") .withTracerProvider( new TracerProviderModel() .withProcessors( diff --git a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/OpenTelemetryConfigurationFactoryTest.java b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/OpenTelemetryConfigurationFactoryTest.java index 0284a16bac4..5630ea99767 100644 --- a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/OpenTelemetryConfigurationFactoryTest.java +++ b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/OpenTelemetryConfigurationFactoryTest.java @@ -83,7 +83,7 @@ void create_InvalidFileFormat() { OpenTelemetryConfigurationFactory.getInstance() .create(testCase, spiHelper, closeables)) .isInstanceOf(ConfigurationException.class) - .hasMessage("Unsupported file format. Supported formats include: 0.1"); + .hasMessage("Unsupported file format. Supported formats include: 0.3"); cleanup.addCloseables(closeables); } } @@ -97,7 +97,7 @@ void create_Defaults() { OpenTelemetrySdk sdk = OpenTelemetryConfigurationFactory.getInstance() .create( - new OpenTelemetryConfigurationModel().withFileFormat("0.1"), spiHelper, closeables); + new OpenTelemetryConfigurationModel().withFileFormat("0.3"), spiHelper, closeables); cleanup.addCloseable(sdk); cleanup.addCloseables(closeables); @@ -114,7 +114,7 @@ void create_Disabled() { OpenTelemetryConfigurationFactory.getInstance() .create( new OpenTelemetryConfigurationModel() - .withFileFormat("0.1") + .withFileFormat("0.3") .withDisabled(true) // Logger provider configuration should be ignored since SDK is disabled .withLoggerProvider( @@ -208,7 +208,7 @@ void create_Configured() { OpenTelemetryConfigurationFactory.getInstance() .create( new OpenTelemetryConfigurationModel() - .withFileFormat("0.1") + .withFileFormat("0.3") .withPropagator( new PropagatorModel() .withComposite( diff --git a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/YamlStructuredConfigPropertiesTest.java b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/YamlStructuredConfigPropertiesTest.java index 757331934bf..25f9a877c95 100644 --- a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/YamlStructuredConfigPropertiesTest.java +++ b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/YamlStructuredConfigPropertiesTest.java @@ -22,7 +22,7 @@ class YamlStructuredConfigPropertiesTest { private static final String extendedSchema = - "file_format: \"0.1\"\n" + "file_format: \"0.3\"\n" + "disabled: false\n" + "\n" + "resource:\n" @@ -69,7 +69,7 @@ void setup() { @Test void configurationSchema() { // Validate can read file configuration schema properties - assertThat(structuredConfigProps.getString("file_format")).isEqualTo("0.1"); + assertThat(structuredConfigProps.getString("file_format")).isEqualTo("0.3"); StructuredConfigProperties resourceProps = structuredConfigProps.getStructured("resource"); assertThat(resourceProps).isNotNull(); List resourceAttributesList = From 8194c10b785b7f8d232b4bce0b5f70c91669201a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Herv=C3=A9=20Boutemy?= Date: Wed, 16 Oct 2024 02:14:45 +0200 Subject: [PATCH 612/901] add Reproducible Builds badge (#6788) --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 3356c358bc7..3503236b277 100644 --- a/README.md +++ b/README.md @@ -2,6 +2,7 @@ [![Continuous Build][ci-image]][ci-url] [![Coverage Status][codecov-image]][codecov-url] [![Maven Central][maven-image]][maven-url] +[![Reproducible Builds](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/jvm-repo-rebuild/reproducible-central/master/content/io/opentelemetry/java/badge.json)](https://github.com/jvm-repo-rebuild/reproducible-central/blob/master/content/io/opentelemetry/java/README.md) ## Project Status From 537f5c4e79e99f82dae53d16f7167caf7041a0c3 Mon Sep 17 00:00:00 2001 From: jack-berg <34418638+jack-berg@users.noreply.github.com> Date: Wed, 16 Oct 2024 08:39:12 -0500 Subject: [PATCH 613/901] Fix declarative config env substitution by disallowing '}' in default value (#6793) --- .../sdk/extension/incubator/fileconfig/FileConfiguration.java | 2 +- .../incubator/fileconfig/FileConfigurationParseTest.java | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/FileConfiguration.java b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/FileConfiguration.java index 76cf9cc1fbe..e4004516b73 100644 --- a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/FileConfiguration.java +++ b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/FileConfiguration.java @@ -49,7 +49,7 @@ public final class FileConfiguration { private static final Logger logger = Logger.getLogger(FileConfiguration.class.getName()); private static final Pattern ENV_VARIABLE_REFERENCE = - Pattern.compile("\\$\\{([a-zA-Z_][a-zA-Z0-9_]*)(:-([^\n]*))?\\}"); + Pattern.compile("\\$\\{([a-zA-Z_][a-zA-Z0-9_]*)(:-([^\n}]*))?}"); private static final ComponentLoader DEFAULT_COMPONENT_LOADER = SpiHelper.serviceComponentLoader(FileConfiguration.class.getClassLoader()); diff --git a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/FileConfigurationParseTest.java b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/FileConfigurationParseTest.java index b90c154205a..7de63dcb45c 100644 --- a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/FileConfigurationParseTest.java +++ b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/FileConfigurationParseTest.java @@ -634,6 +634,9 @@ private static java.util.stream.Stream envVarSubstitutionArgs() { // Multiple environment variables referenced Arguments.of("key1: ${STR_1}${STR_2}\n", mapOf(entry("key1", "value1value2"))), Arguments.of("key1: ${STR_1} ${STR_2}\n", mapOf(entry("key1", "value1 value2"))), + Arguments.of( + "key1: ${STR_1} ${NOT_SET:-default} ${STR_2}\n", + mapOf(entry("key1", "value1 default value2"))), // Undefined / empty environment variable Arguments.of("key1: ${EMPTY_STR}\n", mapOf(entry("key1", null))), Arguments.of("key1: ${STR_3}\n", mapOf(entry("key1", null))), From 07b6903b85d73d90fda42696de2ba8c4e6eeaf54 Mon Sep 17 00:00:00 2001 From: jack-berg <34418638+jack-berg@users.noreply.github.com> Date: Thu, 17 Oct 2024 09:32:25 -0500 Subject: [PATCH 614/901] Stabilize metric cardinality limits APIs (#6794) --- .../opentelemetry-sdk-metrics.txt | 16 +++++++- .../MeterProviderConfiguration.java | 4 +- .../MeterProviderConfigurationTest.java | 2 +- .../InstrumentGarbageCollectionBenchmark.java | 5 +-- .../sdk/metrics/SdkMeterProvider.java | 2 +- .../sdk/metrics/SdkMeterProviderBuilder.java | 13 ++---- .../io/opentelemetry/sdk/metrics/View.java | 2 +- .../sdk/metrics/ViewBuilder.java | 8 +--- .../export/CardinalityLimitSelector.java | 7 +--- .../internal/SdkMeterProviderUtil.java | 24 ----------- .../metrics/internal/view/ViewRegistry.java | 2 +- .../sdk/metrics/CardinalityTest.java | 41 ++++++++----------- .../internal/view/ViewRegistryTest.java | 2 +- 13 files changed, 49 insertions(+), 79 deletions(-) rename sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/{internal => }/export/CardinalityLimitSelector.java (78%) diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-metrics.txt b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-metrics.txt index 3650627a2d9..aaa00f2eefb 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-metrics.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-metrics.txt @@ -1,2 +1,16 @@ Comparing source compatibility of opentelemetry-sdk-metrics-1.44.0-SNAPSHOT.jar against opentelemetry-sdk-metrics-1.43.0.jar -No changes. \ No newline at end of file ++++ NEW INTERFACE: PUBLIC(+) ABSTRACT(+) io.opentelemetry.sdk.metrics.export.CardinalityLimitSelector (not serializable) + +++ CLASS FILE FORMAT VERSION: 52.0 <- n.a. + +++ NEW SUPERCLASS: java.lang.Object + +++ NEW METHOD: PUBLIC(+) STATIC(+) io.opentelemetry.sdk.metrics.export.CardinalityLimitSelector defaultCardinalityLimitSelector() + +++ NEW METHOD: PUBLIC(+) ABSTRACT(+) int getCardinalityLimit(io.opentelemetry.sdk.metrics.InstrumentType) + +++ NEW ANNOTATION: java.lang.FunctionalInterface +*** MODIFIED CLASS: PUBLIC FINAL io.opentelemetry.sdk.metrics.SdkMeterProviderBuilder (not serializable) + === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 + +++ NEW METHOD: PUBLIC(+) io.opentelemetry.sdk.metrics.SdkMeterProviderBuilder registerMetricReader(io.opentelemetry.sdk.metrics.export.MetricReader, io.opentelemetry.sdk.metrics.export.CardinalityLimitSelector) +*** MODIFIED CLASS: PUBLIC ABSTRACT io.opentelemetry.sdk.metrics.View (not serializable) + === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 + *** MODIFIED METHOD: PUBLIC (<- PACKAGE_PROTECTED) ABSTRACT int getCardinalityLimit() +*** MODIFIED CLASS: PUBLIC FINAL io.opentelemetry.sdk.metrics.ViewBuilder (not serializable) + === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 + *** MODIFIED METHOD: PUBLIC (<- PACKAGE_PROTECTED) io.opentelemetry.sdk.metrics.ViewBuilder setCardinalityLimit(int) diff --git a/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/MeterProviderConfiguration.java b/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/MeterProviderConfiguration.java index 3689161b906..161fc4895b1 100644 --- a/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/MeterProviderConfiguration.java +++ b/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/MeterProviderConfiguration.java @@ -62,8 +62,8 @@ static void configureMeterProvider( config, spiHelper, metricReaderCustomizer, metricExporterCustomizer, closeables) .forEach( reader -> - SdkMeterProviderUtil.registerMetricReaderWithCardinalitySelector( - meterProviderBuilder, reader, instrumentType -> cardinalityLimit)); + meterProviderBuilder.registerMetricReader( + reader, instrumentType -> cardinalityLimit)); } static List configureMetricReaders( diff --git a/sdk-extensions/autoconfigure/src/testFullConfig/java/io/opentelemetry/sdk/autoconfigure/MeterProviderConfigurationTest.java b/sdk-extensions/autoconfigure/src/testFullConfig/java/io/opentelemetry/sdk/autoconfigure/MeterProviderConfigurationTest.java index b2062c20dd5..52945668621 100644 --- a/sdk-extensions/autoconfigure/src/testFullConfig/java/io/opentelemetry/sdk/autoconfigure/MeterProviderConfigurationTest.java +++ b/sdk-extensions/autoconfigure/src/testFullConfig/java/io/opentelemetry/sdk/autoconfigure/MeterProviderConfigurationTest.java @@ -17,8 +17,8 @@ import io.opentelemetry.sdk.metrics.InstrumentType; import io.opentelemetry.sdk.metrics.SdkMeterProvider; import io.opentelemetry.sdk.metrics.SdkMeterProviderBuilder; +import io.opentelemetry.sdk.metrics.export.CardinalityLimitSelector; import io.opentelemetry.sdk.metrics.export.MetricReader; -import io.opentelemetry.sdk.metrics.internal.export.CardinalityLimitSelector; import java.io.Closeable; import java.util.ArrayList; import java.util.Collections; diff --git a/sdk/metrics/src/jmhBasedTest/java/io/opentelemetry/sdk/metrics/internal/state/InstrumentGarbageCollectionBenchmark.java b/sdk/metrics/src/jmhBasedTest/java/io/opentelemetry/sdk/metrics/internal/state/InstrumentGarbageCollectionBenchmark.java index f9056a6e6e0..9e761d6b2bb 100644 --- a/sdk/metrics/src/jmhBasedTest/java/io/opentelemetry/sdk/metrics/internal/state/InstrumentGarbageCollectionBenchmark.java +++ b/sdk/metrics/src/jmhBasedTest/java/io/opentelemetry/sdk/metrics/internal/state/InstrumentGarbageCollectionBenchmark.java @@ -90,9 +90,8 @@ public void setup() { // Effectively disable periodic reading so reading is only done on #flush() .setInterval(Duration.ofSeconds(Integer.MAX_VALUE)) .build(); - SdkMeterProviderBuilder builder = SdkMeterProvider.builder(); - SdkMeterProviderUtil.registerMetricReaderWithCardinalitySelector( - builder, metricReader, unused -> cardinality + 1); + SdkMeterProviderBuilder builder = + SdkMeterProvider.builder().registerMetricReader(metricReader, unused -> cardinality + 1); attributesList = AttributesGenerator.generate(cardinality); diff --git a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkMeterProvider.java b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkMeterProvider.java index 6990ea30cac..bb140a0c59d 100644 --- a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkMeterProvider.java +++ b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkMeterProvider.java @@ -15,13 +15,13 @@ import io.opentelemetry.sdk.internal.ComponentRegistry; import io.opentelemetry.sdk.internal.ScopeConfigurator; import io.opentelemetry.sdk.metrics.data.MetricData; +import io.opentelemetry.sdk.metrics.export.CardinalityLimitSelector; import io.opentelemetry.sdk.metrics.export.CollectionRegistration; import io.opentelemetry.sdk.metrics.export.MetricProducer; import io.opentelemetry.sdk.metrics.export.MetricReader; import io.opentelemetry.sdk.metrics.internal.MeterConfig; import io.opentelemetry.sdk.metrics.internal.SdkMeterProviderUtil; import io.opentelemetry.sdk.metrics.internal.exemplar.ExemplarFilter; -import io.opentelemetry.sdk.metrics.internal.export.CardinalityLimitSelector; import io.opentelemetry.sdk.metrics.internal.export.RegisteredReader; import io.opentelemetry.sdk.metrics.internal.state.MeterProviderSharedState; import io.opentelemetry.sdk.metrics.internal.view.RegisteredView; diff --git a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkMeterProviderBuilder.java b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkMeterProviderBuilder.java index 57895d45035..1a9e5b27a64 100644 --- a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkMeterProviderBuilder.java +++ b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkMeterProviderBuilder.java @@ -9,13 +9,13 @@ import io.opentelemetry.sdk.common.InstrumentationScopeInfo; import io.opentelemetry.sdk.internal.ScopeConfigurator; import io.opentelemetry.sdk.internal.ScopeConfiguratorBuilder; +import io.opentelemetry.sdk.metrics.export.CardinalityLimitSelector; import io.opentelemetry.sdk.metrics.export.MetricProducer; import io.opentelemetry.sdk.metrics.export.MetricReader; import io.opentelemetry.sdk.metrics.internal.MeterConfig; import io.opentelemetry.sdk.metrics.internal.SdkMeterProviderUtil; import io.opentelemetry.sdk.metrics.internal.debug.SourceInfo; import io.opentelemetry.sdk.metrics.internal.exemplar.ExemplarFilter; -import io.opentelemetry.sdk.metrics.internal.export.CardinalityLimitSelector; import io.opentelemetry.sdk.metrics.internal.view.RegisteredView; import io.opentelemetry.sdk.resources.Resource; import java.util.ArrayList; @@ -137,15 +137,10 @@ public SdkMeterProviderBuilder registerMetricReader(MetricReader reader) { /** * Registers a {@link MetricReader} with a {@link CardinalityLimitSelector}. * - *

      This method is experimental so not public. You may reflectively call it using {@link - * SdkMeterProviderUtil#registerMetricReaderWithCardinalitySelector(SdkMeterProviderBuilder, - * MetricReader, CardinalityLimitSelector)} - * - *

      Note: not currently stable but available for experimental use via {@link - * SdkMeterProviderUtil#registerMetricReaderWithCardinalitySelector(SdkMeterProviderBuilder, - * MetricReader, CardinalityLimitSelector)}. + *

      If {@link #registerMetricReader(MetricReader)} is used, the {@link + * CardinalityLimitSelector#defaultCardinalityLimitSelector()} is used. */ - SdkMeterProviderBuilder registerMetricReader( + public SdkMeterProviderBuilder registerMetricReader( MetricReader reader, CardinalityLimitSelector cardinalityLimitSelector) { metricReaders.put(reader, cardinalityLimitSelector); return this; diff --git a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/View.java b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/View.java index e545b716459..be60974eaed 100644 --- a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/View.java +++ b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/View.java @@ -61,7 +61,7 @@ static View create( abstract AttributesProcessor getAttributesProcessor(); /** Returns the cardinality limit for this view. */ - abstract int getCardinalityLimit(); + public abstract int getCardinalityLimit(); @Override public final String toString() { diff --git a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/ViewBuilder.java b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/ViewBuilder.java index 8172abce8ca..af591c2ef62 100644 --- a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/ViewBuilder.java +++ b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/ViewBuilder.java @@ -110,18 +110,12 @@ ViewBuilder addAttributesProcessor(AttributesProcessor attributesProcessor) { /** * Set the cardinality limit. * - *

      This method is experimental so not public. You may reflectively call it using {@link - * SdkMeterProviderUtil#setCardinalityLimit(ViewBuilder, int)} - * - *

      Note: not currently stable but cardinality limit can be configured via - * SdkMeterProviderUtil#setCardinalityLimit(ViewBuilder, int). - * *

      Read {@link MemoryMode} to understand the memory usage behavior of reaching cardinality * limit. * * @param cardinalityLimit the maximum number of series for a metric */ - ViewBuilder setCardinalityLimit(int cardinalityLimit) { + public ViewBuilder setCardinalityLimit(int cardinalityLimit) { if (cardinalityLimit <= 0) { throw new IllegalArgumentException("cardinalityLimit must be > 0"); } diff --git a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/export/CardinalityLimitSelector.java b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/export/CardinalityLimitSelector.java similarity index 78% rename from sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/export/CardinalityLimitSelector.java rename to sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/export/CardinalityLimitSelector.java index 44f155162c9..ad0d4e717e2 100644 --- a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/export/CardinalityLimitSelector.java +++ b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/export/CardinalityLimitSelector.java @@ -3,19 +3,16 @@ * SPDX-License-Identifier: Apache-2.0 */ -package io.opentelemetry.sdk.metrics.internal.export; +package io.opentelemetry.sdk.metrics.export; import io.opentelemetry.sdk.metrics.InstrumentType; import io.opentelemetry.sdk.metrics.SdkMeterProviderBuilder; -import io.opentelemetry.sdk.metrics.export.MetricReader; -import io.opentelemetry.sdk.metrics.internal.SdkMeterProviderUtil; import io.opentelemetry.sdk.metrics.internal.state.MetricStorage; /** * Customize the {@link io.opentelemetry.sdk.metrics.export.MetricReader} cardinality limit as a * function of {@link InstrumentType}. Register via {@link - * SdkMeterProviderUtil#registerMetricReaderWithCardinalitySelector(SdkMeterProviderBuilder, - * MetricReader, CardinalityLimitSelector)}. + * SdkMeterProviderBuilder#registerMetricReader(MetricReader, CardinalityLimitSelector)}. * *

      This class is internal and is hence not for public use. Its APIs are unstable and can change * at any time. diff --git a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/SdkMeterProviderUtil.java b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/SdkMeterProviderUtil.java index e27856881e1..c559fc4c76f 100644 --- a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/SdkMeterProviderUtil.java +++ b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/SdkMeterProviderUtil.java @@ -10,9 +10,7 @@ import io.opentelemetry.sdk.metrics.SdkMeterProvider; import io.opentelemetry.sdk.metrics.SdkMeterProviderBuilder; import io.opentelemetry.sdk.metrics.ViewBuilder; -import io.opentelemetry.sdk.metrics.export.MetricReader; import io.opentelemetry.sdk.metrics.internal.exemplar.ExemplarFilter; -import io.opentelemetry.sdk.metrics.internal.export.CardinalityLimitSelector; import io.opentelemetry.sdk.metrics.internal.view.AttributesProcessor; import io.opentelemetry.sdk.metrics.internal.view.StringPredicates; import java.lang.reflect.InvocationTargetException; @@ -49,28 +47,6 @@ public static void setExemplarFilter( } } - /** - * Reflectively add a {@link MetricReader} with the {@link CardinalityLimitSelector} to the {@link - * SdkMeterProviderBuilder}. - * - * @param sdkMeterProviderBuilder the builder - */ - public static void registerMetricReaderWithCardinalitySelector( - SdkMeterProviderBuilder sdkMeterProviderBuilder, - MetricReader metricReader, - CardinalityLimitSelector cardinalityLimitSelector) { - try { - Method method = - SdkMeterProviderBuilder.class.getDeclaredMethod( - "registerMetricReader", MetricReader.class, CardinalityLimitSelector.class); - method.setAccessible(true); - method.invoke(sdkMeterProviderBuilder, metricReader, cardinalityLimitSelector); - } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) { - throw new IllegalStateException( - "Error calling addMetricReader on SdkMeterProviderBuilder", e); - } - } - /** Reflectively set the {@link ScopeConfigurator} to the {@link SdkMeterProviderBuilder}. */ public static void setMeterConfigurator( SdkMeterProviderBuilder sdkMeterProviderBuilder, diff --git a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/view/ViewRegistry.java b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/view/ViewRegistry.java index 4df9f1a35ec..0904a38ff0f 100644 --- a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/view/ViewRegistry.java +++ b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/view/ViewRegistry.java @@ -15,13 +15,13 @@ import io.opentelemetry.sdk.metrics.InstrumentType; import io.opentelemetry.sdk.metrics.SdkMeterProviderBuilder; import io.opentelemetry.sdk.metrics.View; +import io.opentelemetry.sdk.metrics.export.CardinalityLimitSelector; import io.opentelemetry.sdk.metrics.export.DefaultAggregationSelector; import io.opentelemetry.sdk.metrics.internal.aggregator.AggregationUtil; import io.opentelemetry.sdk.metrics.internal.aggregator.AggregatorFactory; import io.opentelemetry.sdk.metrics.internal.debug.SourceInfo; import io.opentelemetry.sdk.metrics.internal.descriptor.Advice; import io.opentelemetry.sdk.metrics.internal.descriptor.InstrumentDescriptor; -import io.opentelemetry.sdk.metrics.internal.export.CardinalityLimitSelector; import io.opentelemetry.sdk.metrics.internal.state.MetricStorage; import java.util.ArrayList; import java.util.Collections; diff --git a/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/CardinalityTest.java b/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/CardinalityTest.java index 3a5c0edc733..17989d14a1a 100644 --- a/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/CardinalityTest.java +++ b/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/CardinalityTest.java @@ -20,9 +20,8 @@ import io.opentelemetry.sdk.metrics.data.LongPointData; import io.opentelemetry.sdk.metrics.data.PointData; import io.opentelemetry.sdk.metrics.data.SumData; +import io.opentelemetry.sdk.metrics.export.CardinalityLimitSelector; import io.opentelemetry.sdk.metrics.export.MetricReader; -import io.opentelemetry.sdk.metrics.internal.SdkMeterProviderUtil; -import io.opentelemetry.sdk.metrics.internal.export.CardinalityLimitSelector; import io.opentelemetry.sdk.metrics.internal.state.DefaultSynchronousMetricStorage; import io.opentelemetry.sdk.metrics.internal.state.MetricStorage; import io.opentelemetry.sdk.testing.exporter.InMemoryMetricReader; @@ -315,28 +314,24 @@ void readerAndViewCardinalityConfiguration() { // other instrument kinds CardinalityLimitSelector cardinalityLimitSelector = instrumentType -> instrumentType == InstrumentType.COUNTER ? counterLimit : generalLimit; - SdkMeterProviderBuilder builder = SdkMeterProvider.builder(); - - // Register both the delta and cumulative reader with the customized cardinality selector - SdkMeterProviderUtil.registerMetricReaderWithCardinalitySelector( - builder, deltaReader, cardinalityLimitSelector); - SdkMeterProviderUtil.registerMetricReaderWithCardinalitySelector( - builder, cumulativeReader, cardinalityLimitSelector); - - // Register a view which defines a custom cardinality limit for instrumented named "counter2" - ViewBuilder viewBuilder1 = View.builder(); - SdkMeterProviderUtil.setCardinalityLimit(viewBuilder1, counter2Limit); - builder.registerView( - InstrumentSelector.builder().setName("counter2").build(), viewBuilder1.build()); - - // Register a view which defines a custom cardinality limit for instrumented named - // "asyncCounter" - ViewBuilder viewBuilder2 = View.builder(); - SdkMeterProviderUtil.setCardinalityLimit(viewBuilder2, asyncCounterLimit); - builder.registerView( - InstrumentSelector.builder().setName("asyncCounter").build(), viewBuilder2.build()); + SdkMeterProvider sdkMeterProvider = + SdkMeterProvider.builder() + // Register both the delta and cumulative reader with the customized cardinality + // selector + .registerMetricReader(deltaReader, cardinalityLimitSelector) + .registerMetricReader(cumulativeReader, cardinalityLimitSelector) + // Register a view which defines a custom cardinality limit for instrumented named + // "counter2" + .registerView( + InstrumentSelector.builder().setName("counter2").build(), + View.builder().setCardinalityLimit(counter2Limit).build()) + // Register a view which defines a custom cardinality limit for instrumented named + // "asyncCounter" + .registerView( + InstrumentSelector.builder().setName("asyncCounter").build(), + View.builder().setCardinalityLimit(asyncCounterLimit).build()) + .build(); - SdkMeterProvider sdkMeterProvider = builder.build(); meter = sdkMeterProvider.get(CardinalityTest.class.getName()); LongCounter counter1 = meter.counterBuilder("counter1").build(); diff --git a/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/internal/view/ViewRegistryTest.java b/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/internal/view/ViewRegistryTest.java index d2f5925873c..8eb4997fb76 100644 --- a/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/internal/view/ViewRegistryTest.java +++ b/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/internal/view/ViewRegistryTest.java @@ -18,11 +18,11 @@ import io.opentelemetry.sdk.metrics.InstrumentType; import io.opentelemetry.sdk.metrics.InstrumentValueType; import io.opentelemetry.sdk.metrics.View; +import io.opentelemetry.sdk.metrics.export.CardinalityLimitSelector; import io.opentelemetry.sdk.metrics.export.DefaultAggregationSelector; import io.opentelemetry.sdk.metrics.internal.debug.SourceInfo; import io.opentelemetry.sdk.metrics.internal.descriptor.Advice; import io.opentelemetry.sdk.metrics.internal.descriptor.InstrumentDescriptor; -import io.opentelemetry.sdk.metrics.internal.export.CardinalityLimitSelector; import io.opentelemetry.sdk.metrics.internal.state.MetricStorage; import java.util.Arrays; import java.util.Collections; From 1ac476b3b796ff2a13eeecaa873d065c854fae88 Mon Sep 17 00:00:00 2001 From: Gregor Zeitlinger Date: Thu, 17 Oct 2024 17:49:01 +0200 Subject: [PATCH 615/901] add stdout memory mode (#6774) --- .../logs/OtlpStdoutLogRecordExporter.java | 48 ++++-- .../OtlpStdoutLogRecordExporterBuilder.java | 19 ++- ...outLogRecordExporterComponentProvider.java | 2 + .../OtlpStdoutLogRecordExporterProvider.java | 2 + .../metrics/OtlpStdoutMetricExporter.java | 57 +++++-- .../OtlpStdoutMetricExporterBuilder.java | 18 +++ ...StdoutMetricExporterComponentProvider.java | 1 + .../OtlpStdoutMetricExporterProvider.java | 1 + .../traces/OtlpStdoutSpanExporter.java | 48 ++++-- .../traces/OtlpStdoutSpanExporterBuilder.java | 19 ++- ...lpStdoutSpanExporterComponentProvider.java | 2 + .../OtlpStdoutSpanExporterProvider.java | 2 + .../otlp/AbstractOtlpStdoutExporterTest.java | 146 +++++++++++++----- .../otlp/OtlpStdoutLogRecordExporterTest.java | 9 +- .../otlp/OtlpStdoutMetricExporterTest.java | 14 +- .../otlp/OtlpStdoutSpanExporterTest.java | 9 +- .../http/logs/OtlpHttpLogRecordExporter.java | 33 +--- .../http/metrics/OtlpHttpMetricExporter.java | 35 +---- .../otlp/http/trace/OtlpHttpSpanExporter.java | 33 +--- .../otlp/logs/OtlpGrpcLogRecordExporter.java | 33 +--- .../otlp/metrics/OtlpGrpcMetricExporter.java | 35 +---- .../otlp/trace/OtlpGrpcSpanExporter.java | 33 +--- .../OtlpLogRecordExporterProviderTest.java | 13 +- .../OtlpSpanExporterProviderTest.java | 15 +- .../otlp/logs/LogReusableDataMarshaler.java | 58 +++++++ .../metrics/MetricReusableDataMarshaler.java | 58 +++++++ .../traces/SpanReusableDataMarshaler.java | 58 +++++++ 27 files changed, 533 insertions(+), 268 deletions(-) create mode 100644 exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/logs/LogReusableDataMarshaler.java create mode 100644 exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/metrics/MetricReusableDataMarshaler.java create mode 100644 exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/traces/SpanReusableDataMarshaler.java diff --git a/exporters/logging-otlp/src/main/java/io/opentelemetry/exporter/logging/otlp/internal/logs/OtlpStdoutLogRecordExporter.java b/exporters/logging-otlp/src/main/java/io/opentelemetry/exporter/logging/otlp/internal/logs/OtlpStdoutLogRecordExporter.java index 96331e56d23..11798e938f0 100644 --- a/exporters/logging-otlp/src/main/java/io/opentelemetry/exporter/logging/otlp/internal/logs/OtlpStdoutLogRecordExporter.java +++ b/exporters/logging-otlp/src/main/java/io/opentelemetry/exporter/logging/otlp/internal/logs/OtlpStdoutLogRecordExporter.java @@ -5,15 +5,17 @@ package io.opentelemetry.exporter.logging.otlp.internal.logs; -import io.opentelemetry.exporter.internal.otlp.logs.LogsRequestMarshaler; +import io.opentelemetry.exporter.internal.otlp.logs.LogReusableDataMarshaler; import io.opentelemetry.exporter.internal.otlp.logs.ResourceLogsMarshaler; import io.opentelemetry.exporter.logging.otlp.internal.writer.JsonWriter; import io.opentelemetry.sdk.common.CompletableResultCode; +import io.opentelemetry.sdk.common.export.MemoryMode; import io.opentelemetry.sdk.logs.data.LogRecordData; import io.opentelemetry.sdk.logs.export.LogRecordExporter; import java.util.Collection; import java.util.StringJoiner; import java.util.concurrent.atomic.AtomicBoolean; +import java.util.function.Function; import java.util.logging.Level; import java.util.logging.Logger; @@ -33,11 +35,16 @@ public final class OtlpStdoutLogRecordExporter implements LogRecordExporter { private final Logger logger; private final JsonWriter jsonWriter; private final boolean wrapperJsonObject; + private final MemoryMode memoryMode; + private final Function, CompletableResultCode> marshaler; - OtlpStdoutLogRecordExporter(Logger logger, JsonWriter jsonWriter, boolean wrapperJsonObject) { + OtlpStdoutLogRecordExporter( + Logger logger, JsonWriter jsonWriter, boolean wrapperJsonObject, MemoryMode memoryMode) { this.logger = logger; this.jsonWriter = jsonWriter; this.wrapperJsonObject = wrapperJsonObject; + this.memoryMode = memoryMode; + marshaler = createMarshaler(jsonWriter, memoryMode, wrapperJsonObject); } /** Returns a new {@link OtlpStdoutLogRecordExporterBuilder}. */ @@ -46,25 +53,35 @@ public static OtlpStdoutLogRecordExporterBuilder builder() { return new OtlpStdoutLogRecordExporterBuilder(LOGGER).setOutput(System.out); } + private static Function, CompletableResultCode> createMarshaler( + JsonWriter jsonWriter, MemoryMode memoryMode, boolean wrapperJsonObject) { + if (wrapperJsonObject) { + LogReusableDataMarshaler reusableDataMarshaler = + new LogReusableDataMarshaler( + memoryMode, (marshaler, numItems) -> jsonWriter.write(marshaler)); + return reusableDataMarshaler::export; + } else { + return logs -> { + // no support for low allocation marshaler + for (ResourceLogsMarshaler marshaler : ResourceLogsMarshaler.create(logs)) { + CompletableResultCode resultCode = jsonWriter.write(marshaler); + if (!resultCode.isSuccess()) { + // already logged + return resultCode; + } + } + return CompletableResultCode.ofSuccess(); + }; + } + } + @Override public CompletableResultCode export(Collection logs) { if (isShutdown.get()) { return CompletableResultCode.ofFailure(); } - if (wrapperJsonObject) { - LogsRequestMarshaler request = LogsRequestMarshaler.create(logs); - return jsonWriter.write(request); - } else { - for (ResourceLogsMarshaler resourceLogs : ResourceLogsMarshaler.create(logs)) { - CompletableResultCode resultCode = jsonWriter.write(resourceLogs); - if (!resultCode.isSuccess()) { - // already logged - return resultCode; - } - } - return CompletableResultCode.ofSuccess(); - } + return marshaler.apply(logs); } @Override @@ -87,6 +104,7 @@ public String toString() { StringJoiner joiner = new StringJoiner(", ", "OtlpStdoutLogRecordExporter{", "}"); joiner.add("jsonWriter=" + jsonWriter); joiner.add("wrapperJsonObject=" + wrapperJsonObject); + joiner.add("memoryMode=" + memoryMode); return joiner.toString(); } } diff --git a/exporters/logging-otlp/src/main/java/io/opentelemetry/exporter/logging/otlp/internal/logs/OtlpStdoutLogRecordExporterBuilder.java b/exporters/logging-otlp/src/main/java/io/opentelemetry/exporter/logging/otlp/internal/logs/OtlpStdoutLogRecordExporterBuilder.java index ea3f5c14234..76e6adb20ad 100644 --- a/exporters/logging-otlp/src/main/java/io/opentelemetry/exporter/logging/otlp/internal/logs/OtlpStdoutLogRecordExporterBuilder.java +++ b/exporters/logging-otlp/src/main/java/io/opentelemetry/exporter/logging/otlp/internal/logs/OtlpStdoutLogRecordExporterBuilder.java @@ -11,6 +11,7 @@ import io.opentelemetry.exporter.logging.otlp.internal.writer.JsonWriter; import io.opentelemetry.exporter.logging.otlp.internal.writer.LoggerJsonWriter; import io.opentelemetry.exporter.logging.otlp.internal.writer.StreamJsonWriter; +import io.opentelemetry.sdk.common.export.MemoryMode; import java.io.OutputStream; import java.util.logging.Logger; @@ -27,6 +28,7 @@ public final class OtlpStdoutLogRecordExporterBuilder { private final Logger logger; private JsonWriter jsonWriter; private boolean wrapperJsonObject = true; + private MemoryMode memoryMode = MemoryMode.IMMUTABLE_DATA; public OtlpStdoutLogRecordExporterBuilder(Logger logger) { this.logger = logger; @@ -44,6 +46,17 @@ public OtlpStdoutLogRecordExporterBuilder setWrapperJsonObject(boolean wrapperJs return this; } + /** + * Set the {@link MemoryMode}. If unset, defaults to {@link MemoryMode#IMMUTABLE_DATA}. + * + *

      When memory mode is {@link MemoryMode#REUSABLE_DATA}, serialization is optimized to reduce + * memory allocation. + */ + public OtlpStdoutLogRecordExporterBuilder setMemoryMode(MemoryMode memoryMode) { + this.memoryMode = memoryMode; + return this; + } + /** * Sets the exporter to use the specified output stream. * @@ -71,6 +84,10 @@ public OtlpStdoutLogRecordExporterBuilder setOutput(Logger logger) { * @return a new exporter's instance */ public OtlpStdoutLogRecordExporter build() { - return new OtlpStdoutLogRecordExporter(logger, jsonWriter, wrapperJsonObject); + if (memoryMode == MemoryMode.REUSABLE_DATA && !wrapperJsonObject) { + throw new IllegalArgumentException( + "Reusable data mode is not supported without wrapperJsonObject"); + } + return new OtlpStdoutLogRecordExporter(logger, jsonWriter, wrapperJsonObject, memoryMode); } } diff --git a/exporters/logging-otlp/src/main/java/io/opentelemetry/exporter/logging/otlp/internal/logs/OtlpStdoutLogRecordExporterComponentProvider.java b/exporters/logging-otlp/src/main/java/io/opentelemetry/exporter/logging/otlp/internal/logs/OtlpStdoutLogRecordExporterComponentProvider.java index 0806b7f0b40..8afd4e58c85 100644 --- a/exporters/logging-otlp/src/main/java/io/opentelemetry/exporter/logging/otlp/internal/logs/OtlpStdoutLogRecordExporterComponentProvider.java +++ b/exporters/logging-otlp/src/main/java/io/opentelemetry/exporter/logging/otlp/internal/logs/OtlpStdoutLogRecordExporterComponentProvider.java @@ -5,6 +5,7 @@ package io.opentelemetry.exporter.logging.otlp.internal.logs; +import io.opentelemetry.exporter.internal.ExporterBuilderUtil; import io.opentelemetry.sdk.autoconfigure.spi.internal.ComponentProvider; import io.opentelemetry.sdk.autoconfigure.spi.internal.StructuredConfigProperties; import io.opentelemetry.sdk.logs.export.LogRecordExporter; @@ -31,6 +32,7 @@ public String getName() { @Override public LogRecordExporter create(StructuredConfigProperties config) { OtlpStdoutLogRecordExporterBuilder builder = OtlpStdoutLogRecordExporter.builder(); + ExporterBuilderUtil.configureExporterMemoryMode(config, builder::setMemoryMode); return builder.build(); } } diff --git a/exporters/logging-otlp/src/main/java/io/opentelemetry/exporter/logging/otlp/internal/logs/OtlpStdoutLogRecordExporterProvider.java b/exporters/logging-otlp/src/main/java/io/opentelemetry/exporter/logging/otlp/internal/logs/OtlpStdoutLogRecordExporterProvider.java index 23ba0079295..08b8021590d 100644 --- a/exporters/logging-otlp/src/main/java/io/opentelemetry/exporter/logging/otlp/internal/logs/OtlpStdoutLogRecordExporterProvider.java +++ b/exporters/logging-otlp/src/main/java/io/opentelemetry/exporter/logging/otlp/internal/logs/OtlpStdoutLogRecordExporterProvider.java @@ -5,6 +5,7 @@ package io.opentelemetry.exporter.logging.otlp.internal.logs; +import io.opentelemetry.exporter.internal.ExporterBuilderUtil; import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties; import io.opentelemetry.sdk.autoconfigure.spi.logs.ConfigurableLogRecordExporterProvider; import io.opentelemetry.sdk.logs.export.LogRecordExporter; @@ -20,6 +21,7 @@ public final class OtlpStdoutLogRecordExporterProvider @Override public LogRecordExporter createExporter(ConfigProperties config) { OtlpStdoutLogRecordExporterBuilder builder = OtlpStdoutLogRecordExporter.builder(); + ExporterBuilderUtil.configureExporterMemoryMode(config, builder::setMemoryMode); return builder.build(); } diff --git a/exporters/logging-otlp/src/main/java/io/opentelemetry/exporter/logging/otlp/internal/metrics/OtlpStdoutMetricExporter.java b/exporters/logging-otlp/src/main/java/io/opentelemetry/exporter/logging/otlp/internal/metrics/OtlpStdoutMetricExporter.java index 81e9bef105c..4294c1d2571 100644 --- a/exporters/logging-otlp/src/main/java/io/opentelemetry/exporter/logging/otlp/internal/metrics/OtlpStdoutMetricExporter.java +++ b/exporters/logging-otlp/src/main/java/io/opentelemetry/exporter/logging/otlp/internal/metrics/OtlpStdoutMetricExporter.java @@ -5,10 +5,11 @@ package io.opentelemetry.exporter.logging.otlp.internal.metrics; -import io.opentelemetry.exporter.internal.otlp.metrics.MetricsRequestMarshaler; +import io.opentelemetry.exporter.internal.otlp.metrics.MetricReusableDataMarshaler; import io.opentelemetry.exporter.internal.otlp.metrics.ResourceMetricsMarshaler; import io.opentelemetry.exporter.logging.otlp.internal.writer.JsonWriter; import io.opentelemetry.sdk.common.CompletableResultCode; +import io.opentelemetry.sdk.common.export.MemoryMode; import io.opentelemetry.sdk.metrics.Aggregation; import io.opentelemetry.sdk.metrics.InstrumentType; import io.opentelemetry.sdk.metrics.data.AggregationTemporality; @@ -19,6 +20,7 @@ import java.util.Collection; import java.util.StringJoiner; import java.util.concurrent.atomic.AtomicBoolean; +import java.util.function.Function; import java.util.logging.Level; import java.util.logging.Logger; @@ -37,6 +39,8 @@ public final class OtlpStdoutMetricExporter implements MetricExporter { private final Logger logger; private final JsonWriter jsonWriter; private final boolean wrapperJsonObject; + private final MemoryMode memoryMode; + private final Function, CompletableResultCode> marshaler; private final AggregationTemporalitySelector aggregationTemporalitySelector; private final DefaultAggregationSelector defaultAggregationSelector; @@ -44,13 +48,16 @@ public final class OtlpStdoutMetricExporter implements MetricExporter { Logger logger, JsonWriter jsonWriter, boolean wrapperJsonObject, + MemoryMode memoryMode, AggregationTemporalitySelector aggregationTemporalitySelector, DefaultAggregationSelector defaultAggregationSelector) { this.logger = logger; this.jsonWriter = jsonWriter; this.wrapperJsonObject = wrapperJsonObject; + this.memoryMode = memoryMode; this.aggregationTemporalitySelector = aggregationTemporalitySelector; this.defaultAggregationSelector = defaultAggregationSelector; + marshaler = createMarshaler(jsonWriter, memoryMode, wrapperJsonObject); } /** Returns a new {@link OtlpStdoutMetricExporterBuilder}. */ @@ -59,6 +66,28 @@ public static OtlpStdoutMetricExporterBuilder builder() { return new OtlpStdoutMetricExporterBuilder(LOGGER).setOutput(System.out); } + private static Function, CompletableResultCode> createMarshaler( + JsonWriter jsonWriter, MemoryMode memoryMode, boolean wrapperJsonObject) { + if (wrapperJsonObject) { + MetricReusableDataMarshaler reusableDataMarshaler = + new MetricReusableDataMarshaler( + memoryMode, (marshaler, numItems) -> jsonWriter.write(marshaler)); + return reusableDataMarshaler::export; + } else { + return metrics -> { + // no support for low allocation marshaler + for (ResourceMetricsMarshaler marshaler : ResourceMetricsMarshaler.create(metrics)) { + CompletableResultCode resultCode = jsonWriter.write(marshaler); + if (!resultCode.isSuccess()) { + // already logged + return resultCode; + } + } + return CompletableResultCode.ofSuccess(); + }; + } + } + @Override public AggregationTemporality getAggregationTemporality(InstrumentType instrumentType) { return aggregationTemporalitySelector.getAggregationTemporality(instrumentType); @@ -69,25 +98,18 @@ public Aggregation getDefaultAggregation(InstrumentType instrumentType) { return defaultAggregationSelector.getDefaultAggregation(instrumentType); } + @Override + public MemoryMode getMemoryMode() { + return memoryMode; + } + @Override public CompletableResultCode export(Collection metrics) { if (isShutdown.get()) { return CompletableResultCode.ofFailure(); } - if (wrapperJsonObject) { - MetricsRequestMarshaler request = MetricsRequestMarshaler.create(metrics); - return jsonWriter.write(request); - } else { - for (ResourceMetricsMarshaler resourceMetrics : ResourceMetricsMarshaler.create(metrics)) { - CompletableResultCode resultCode = jsonWriter.write(resourceMetrics); - if (!resultCode.isSuccess()) { - // already logged - return resultCode; - } - } - return CompletableResultCode.ofSuccess(); - } + return marshaler.apply(metrics); } @Override @@ -110,6 +132,13 @@ public String toString() { StringJoiner joiner = new StringJoiner(", ", "OtlpStdoutMetricExporter{", "}"); joiner.add("jsonWriter=" + jsonWriter); joiner.add("wrapperJsonObject=" + wrapperJsonObject); + joiner.add("memoryMode=" + memoryMode); + joiner.add( + "aggregationTemporalitySelector=" + + AggregationTemporalitySelector.asString(aggregationTemporalitySelector)); + joiner.add( + "defaultAggregationSelector=" + + DefaultAggregationSelector.asString(defaultAggregationSelector)); return joiner.toString(); } } diff --git a/exporters/logging-otlp/src/main/java/io/opentelemetry/exporter/logging/otlp/internal/metrics/OtlpStdoutMetricExporterBuilder.java b/exporters/logging-otlp/src/main/java/io/opentelemetry/exporter/logging/otlp/internal/metrics/OtlpStdoutMetricExporterBuilder.java index 63f16c09060..945ffd778bd 100644 --- a/exporters/logging-otlp/src/main/java/io/opentelemetry/exporter/logging/otlp/internal/metrics/OtlpStdoutMetricExporterBuilder.java +++ b/exporters/logging-otlp/src/main/java/io/opentelemetry/exporter/logging/otlp/internal/metrics/OtlpStdoutMetricExporterBuilder.java @@ -11,6 +11,7 @@ import io.opentelemetry.exporter.logging.otlp.internal.writer.JsonWriter; import io.opentelemetry.exporter.logging.otlp.internal.writer.LoggerJsonWriter; import io.opentelemetry.exporter.logging.otlp.internal.writer.StreamJsonWriter; +import io.opentelemetry.sdk.common.export.MemoryMode; import io.opentelemetry.sdk.metrics.InstrumentType; import io.opentelemetry.sdk.metrics.export.AggregationTemporalitySelector; import io.opentelemetry.sdk.metrics.export.DefaultAggregationSelector; @@ -40,6 +41,7 @@ public final class OtlpStdoutMetricExporterBuilder { private final Logger logger; private JsonWriter jsonWriter; private boolean wrapperJsonObject = true; + private MemoryMode memoryMode = MemoryMode.IMMUTABLE_DATA; public OtlpStdoutMetricExporterBuilder(Logger logger) { this.logger = logger; @@ -57,6 +59,17 @@ public OtlpStdoutMetricExporterBuilder setWrapperJsonObject(boolean wrapperJsonO return this; } + /** + * Set the {@link MemoryMode}. If unset, defaults to {@link MemoryMode#IMMUTABLE_DATA}. + * + *

      When memory mode is {@link MemoryMode#REUSABLE_DATA}, serialization is optimized to reduce + * memory allocation. + */ + public OtlpStdoutMetricExporterBuilder setMemoryMode(MemoryMode memoryMode) { + this.memoryMode = memoryMode; + return this; + } + /** * Sets the exporter to use the specified output stream. * @@ -114,10 +127,15 @@ public OtlpStdoutMetricExporterBuilder setDefaultAggregationSelector( * @return a new exporter's instance */ public OtlpStdoutMetricExporter build() { + if (memoryMode == MemoryMode.REUSABLE_DATA && !wrapperJsonObject) { + throw new IllegalArgumentException( + "Reusable data mode is not supported without wrapperJsonObject"); + } return new OtlpStdoutMetricExporter( logger, jsonWriter, wrapperJsonObject, + memoryMode, aggregationTemporalitySelector, defaultAggregationSelector); } diff --git a/exporters/logging-otlp/src/main/java/io/opentelemetry/exporter/logging/otlp/internal/metrics/OtlpStdoutMetricExporterComponentProvider.java b/exporters/logging-otlp/src/main/java/io/opentelemetry/exporter/logging/otlp/internal/metrics/OtlpStdoutMetricExporterComponentProvider.java index dd8b3f643fa..e1e2dc88153 100644 --- a/exporters/logging-otlp/src/main/java/io/opentelemetry/exporter/logging/otlp/internal/metrics/OtlpStdoutMetricExporterComponentProvider.java +++ b/exporters/logging-otlp/src/main/java/io/opentelemetry/exporter/logging/otlp/internal/metrics/OtlpStdoutMetricExporterComponentProvider.java @@ -32,6 +32,7 @@ public String getName() { @Override public MetricExporter create(StructuredConfigProperties config) { OtlpStdoutMetricExporterBuilder builder = OtlpStdoutMetricExporter.builder(); + ExporterBuilderUtil.configureExporterMemoryMode(config, builder::setMemoryMode); ExporterBuilderUtil.configureOtlpAggregationTemporality( config, builder::setAggregationTemporalitySelector); ExporterBuilderUtil.configureOtlpHistogramDefaultAggregation( diff --git a/exporters/logging-otlp/src/main/java/io/opentelemetry/exporter/logging/otlp/internal/metrics/OtlpStdoutMetricExporterProvider.java b/exporters/logging-otlp/src/main/java/io/opentelemetry/exporter/logging/otlp/internal/metrics/OtlpStdoutMetricExporterProvider.java index 9eace851190..84f32f56c7b 100644 --- a/exporters/logging-otlp/src/main/java/io/opentelemetry/exporter/logging/otlp/internal/metrics/OtlpStdoutMetricExporterProvider.java +++ b/exporters/logging-otlp/src/main/java/io/opentelemetry/exporter/logging/otlp/internal/metrics/OtlpStdoutMetricExporterProvider.java @@ -20,6 +20,7 @@ public final class OtlpStdoutMetricExporterProvider implements ConfigurableMetri @Override public MetricExporter createExporter(ConfigProperties config) { OtlpStdoutMetricExporterBuilder builder = OtlpStdoutMetricExporter.builder(); + ExporterBuilderUtil.configureExporterMemoryMode(config, builder::setMemoryMode); ExporterBuilderUtil.configureOtlpAggregationTemporality( config, builder::setAggregationTemporalitySelector); ExporterBuilderUtil.configureOtlpHistogramDefaultAggregation( diff --git a/exporters/logging-otlp/src/main/java/io/opentelemetry/exporter/logging/otlp/internal/traces/OtlpStdoutSpanExporter.java b/exporters/logging-otlp/src/main/java/io/opentelemetry/exporter/logging/otlp/internal/traces/OtlpStdoutSpanExporter.java index 39c8829ef9b..187cdacc245 100644 --- a/exporters/logging-otlp/src/main/java/io/opentelemetry/exporter/logging/otlp/internal/traces/OtlpStdoutSpanExporter.java +++ b/exporters/logging-otlp/src/main/java/io/opentelemetry/exporter/logging/otlp/internal/traces/OtlpStdoutSpanExporter.java @@ -6,14 +6,16 @@ package io.opentelemetry.exporter.logging.otlp.internal.traces; import io.opentelemetry.exporter.internal.otlp.traces.ResourceSpansMarshaler; -import io.opentelemetry.exporter.internal.otlp.traces.TraceRequestMarshaler; +import io.opentelemetry.exporter.internal.otlp.traces.SpanReusableDataMarshaler; import io.opentelemetry.exporter.logging.otlp.internal.writer.JsonWriter; import io.opentelemetry.sdk.common.CompletableResultCode; +import io.opentelemetry.sdk.common.export.MemoryMode; import io.opentelemetry.sdk.trace.data.SpanData; import io.opentelemetry.sdk.trace.export.SpanExporter; import java.util.Collection; import java.util.StringJoiner; import java.util.concurrent.atomic.AtomicBoolean; +import java.util.function.Function; import java.util.logging.Level; import java.util.logging.Logger; @@ -32,11 +34,16 @@ public final class OtlpStdoutSpanExporter implements SpanExporter { private final Logger logger; private final JsonWriter jsonWriter; private final boolean wrapperJsonObject; + private final MemoryMode memoryMode; + private final Function, CompletableResultCode> marshaler; - OtlpStdoutSpanExporter(Logger logger, JsonWriter jsonWriter, boolean wrapperJsonObject) { + OtlpStdoutSpanExporter( + Logger logger, JsonWriter jsonWriter, boolean wrapperJsonObject, MemoryMode memoryMode) { this.logger = logger; this.jsonWriter = jsonWriter; this.wrapperJsonObject = wrapperJsonObject; + this.memoryMode = memoryMode; + marshaler = createMarshaler(jsonWriter, memoryMode, wrapperJsonObject); } /** Returns a new {@link OtlpStdoutSpanExporterBuilder}. */ @@ -45,25 +52,35 @@ public static OtlpStdoutSpanExporterBuilder builder() { return new OtlpStdoutSpanExporterBuilder(LOGGER).setOutput(System.out); } + private static Function, CompletableResultCode> createMarshaler( + JsonWriter jsonWriter, MemoryMode memoryMode, boolean wrapperJsonObject) { + if (wrapperJsonObject) { + SpanReusableDataMarshaler reusableDataMarshaler = + new SpanReusableDataMarshaler( + memoryMode, (marshaler, numItems) -> jsonWriter.write(marshaler)); + return reusableDataMarshaler::export; + } else { + return spans -> { + // no support for low allocation marshaler + for (ResourceSpansMarshaler marshaler : ResourceSpansMarshaler.create(spans)) { + CompletableResultCode resultCode = jsonWriter.write(marshaler); + if (!resultCode.isSuccess()) { + // already logged + return resultCode; + } + } + return CompletableResultCode.ofSuccess(); + }; + } + } + @Override public CompletableResultCode export(Collection spans) { if (isShutdown.get()) { return CompletableResultCode.ofFailure(); } - if (wrapperJsonObject) { - TraceRequestMarshaler request = TraceRequestMarshaler.create(spans); - return jsonWriter.write(request); - } else { - for (ResourceSpansMarshaler resourceSpans : ResourceSpansMarshaler.create(spans)) { - CompletableResultCode resultCode = jsonWriter.write(resourceSpans); - if (!resultCode.isSuccess()) { - // already logged - return resultCode; - } - } - return CompletableResultCode.ofSuccess(); - } + return marshaler.apply(spans); } @Override @@ -86,6 +103,7 @@ public String toString() { StringJoiner joiner = new StringJoiner(", ", "OtlpStdoutSpanExporter{", "}"); joiner.add("jsonWriter=" + jsonWriter); joiner.add("wrapperJsonObject=" + wrapperJsonObject); + joiner.add("memoryMode=" + memoryMode); return joiner.toString(); } } diff --git a/exporters/logging-otlp/src/main/java/io/opentelemetry/exporter/logging/otlp/internal/traces/OtlpStdoutSpanExporterBuilder.java b/exporters/logging-otlp/src/main/java/io/opentelemetry/exporter/logging/otlp/internal/traces/OtlpStdoutSpanExporterBuilder.java index 2ca9e5a97b3..341f63c6e49 100644 --- a/exporters/logging-otlp/src/main/java/io/opentelemetry/exporter/logging/otlp/internal/traces/OtlpStdoutSpanExporterBuilder.java +++ b/exporters/logging-otlp/src/main/java/io/opentelemetry/exporter/logging/otlp/internal/traces/OtlpStdoutSpanExporterBuilder.java @@ -11,6 +11,7 @@ import io.opentelemetry.exporter.logging.otlp.internal.writer.JsonWriter; import io.opentelemetry.exporter.logging.otlp.internal.writer.LoggerJsonWriter; import io.opentelemetry.exporter.logging.otlp.internal.writer.StreamJsonWriter; +import io.opentelemetry.sdk.common.export.MemoryMode; import java.io.OutputStream; import java.util.logging.Logger; @@ -27,6 +28,7 @@ public final class OtlpStdoutSpanExporterBuilder { private final Logger logger; private JsonWriter jsonWriter; private boolean wrapperJsonObject = true; + private MemoryMode memoryMode = MemoryMode.IMMUTABLE_DATA; public OtlpStdoutSpanExporterBuilder(Logger logger) { this.logger = logger; @@ -44,6 +46,17 @@ public OtlpStdoutSpanExporterBuilder setWrapperJsonObject(boolean wrapperJsonObj return this; } + /** + * Set the {@link MemoryMode}. If unset, defaults to {@link MemoryMode#IMMUTABLE_DATA}. + * + *

      When memory mode is {@link MemoryMode#REUSABLE_DATA}, serialization is optimized to reduce + * memory allocation. + */ + public OtlpStdoutSpanExporterBuilder setMemoryMode(MemoryMode memoryMode) { + this.memoryMode = memoryMode; + return this; + } + /** * Sets the exporter to use the specified output stream. * @@ -71,6 +84,10 @@ public OtlpStdoutSpanExporterBuilder setOutput(Logger logger) { * @return a new exporter's instance */ public OtlpStdoutSpanExporter build() { - return new OtlpStdoutSpanExporter(logger, jsonWriter, wrapperJsonObject); + if (memoryMode == MemoryMode.REUSABLE_DATA && !wrapperJsonObject) { + throw new IllegalArgumentException( + "Reusable data mode is not supported without wrapperJsonObject"); + } + return new OtlpStdoutSpanExporter(logger, jsonWriter, wrapperJsonObject, memoryMode); } } diff --git a/exporters/logging-otlp/src/main/java/io/opentelemetry/exporter/logging/otlp/internal/traces/OtlpStdoutSpanExporterComponentProvider.java b/exporters/logging-otlp/src/main/java/io/opentelemetry/exporter/logging/otlp/internal/traces/OtlpStdoutSpanExporterComponentProvider.java index 1d60e1a37b8..af299c16251 100644 --- a/exporters/logging-otlp/src/main/java/io/opentelemetry/exporter/logging/otlp/internal/traces/OtlpStdoutSpanExporterComponentProvider.java +++ b/exporters/logging-otlp/src/main/java/io/opentelemetry/exporter/logging/otlp/internal/traces/OtlpStdoutSpanExporterComponentProvider.java @@ -5,6 +5,7 @@ package io.opentelemetry.exporter.logging.otlp.internal.traces; +import io.opentelemetry.exporter.internal.ExporterBuilderUtil; import io.opentelemetry.sdk.autoconfigure.spi.internal.ComponentProvider; import io.opentelemetry.sdk.autoconfigure.spi.internal.StructuredConfigProperties; import io.opentelemetry.sdk.trace.export.SpanExporter; @@ -31,6 +32,7 @@ public String getName() { @Override public SpanExporter create(StructuredConfigProperties config) { OtlpStdoutSpanExporterBuilder builder = OtlpStdoutSpanExporter.builder(); + ExporterBuilderUtil.configureExporterMemoryMode(config, builder::setMemoryMode); return builder.build(); } } diff --git a/exporters/logging-otlp/src/main/java/io/opentelemetry/exporter/logging/otlp/internal/traces/OtlpStdoutSpanExporterProvider.java b/exporters/logging-otlp/src/main/java/io/opentelemetry/exporter/logging/otlp/internal/traces/OtlpStdoutSpanExporterProvider.java index e5d2f008315..84514492f24 100644 --- a/exporters/logging-otlp/src/main/java/io/opentelemetry/exporter/logging/otlp/internal/traces/OtlpStdoutSpanExporterProvider.java +++ b/exporters/logging-otlp/src/main/java/io/opentelemetry/exporter/logging/otlp/internal/traces/OtlpStdoutSpanExporterProvider.java @@ -5,6 +5,7 @@ package io.opentelemetry.exporter.logging.otlp.internal.traces; +import io.opentelemetry.exporter.internal.ExporterBuilderUtil; import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties; import io.opentelemetry.sdk.autoconfigure.spi.traces.ConfigurableSpanExporterProvider; import io.opentelemetry.sdk.trace.export.SpanExporter; @@ -19,6 +20,7 @@ public final class OtlpStdoutSpanExporterProvider implements ConfigurableSpanExp @Override public SpanExporter createExporter(ConfigProperties config) { OtlpStdoutSpanExporterBuilder builder = OtlpStdoutSpanExporter.builder(); + ExporterBuilderUtil.configureExporterMemoryMode(config, builder::setMemoryMode); return builder.build(); } diff --git a/exporters/logging-otlp/src/test/java/io/opentelemetry/exporter/logging/otlp/AbstractOtlpStdoutExporterTest.java b/exporters/logging-otlp/src/test/java/io/opentelemetry/exporter/logging/otlp/AbstractOtlpStdoutExporterTest.java index b18f432a4de..3988fae332d 100644 --- a/exporters/logging-otlp/src/test/java/io/opentelemetry/exporter/logging/otlp/AbstractOtlpStdoutExporterTest.java +++ b/exporters/logging-otlp/src/test/java/io/opentelemetry/exporter/logging/otlp/AbstractOtlpStdoutExporterTest.java @@ -6,8 +6,11 @@ package io.opentelemetry.exporter.logging.otlp; import static java.util.Collections.emptyMap; +import static java.util.Collections.singletonMap; import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatExceptionOfType; import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; import com.google.common.collect.ImmutableList; import com.google.common.collect.Streams; @@ -16,6 +19,7 @@ import io.opentelemetry.sdk.autoconfigure.spi.internal.ComponentProvider; import io.opentelemetry.sdk.autoconfigure.spi.internal.DefaultConfigProperties; import io.opentelemetry.sdk.autoconfigure.spi.internal.StructuredConfigProperties; +import io.opentelemetry.sdk.common.export.MemoryMode; import java.io.BufferedOutputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; @@ -27,6 +31,7 @@ import java.nio.file.Path; import java.util.ServiceLoader; import java.util.concurrent.TimeUnit; +import java.util.function.Supplier; import java.util.stream.Stream; import javax.annotation.Nullable; import org.json.JSONException; @@ -75,7 +80,7 @@ public AbstractOtlpStdoutExporterTest( } protected abstract T createExporter( - @Nullable OutputStream outputStream, boolean wrapperJsonObject); + @Nullable OutputStream outputStream, MemoryMode memoryMode, boolean wrapperJsonObject); protected abstract T createDefaultExporter(); @@ -128,12 +133,13 @@ enum OutputType { } public static class TestCase { - + private final MemoryMode memoryMode; private final boolean wrapperJsonObject; private final OutputType outputType; - public TestCase(OutputType outputType, boolean wrapperJsonObject) { + public TestCase(OutputType outputType, MemoryMode memoryMode, boolean wrapperJsonObject) { this.outputType = outputType; + this.memoryMode = memoryMode; this.wrapperJsonObject = wrapperJsonObject; } @@ -144,25 +150,55 @@ public OutputType getOutputType() { public boolean isWrapperJsonObject() { return wrapperJsonObject; } + + public MemoryMode getMemoryMode() { + return memoryMode; + } } static Stream exportTestCases() { return ImmutableList.of( - testCase(OutputType.SYSTEM_OUT, /* wrapperJsonObject= */ true), - testCase(OutputType.SYSTEM_OUT, /* wrapperJsonObject= */ false), - testCase(OutputType.FILE, /* wrapperJsonObject= */ true), - testCase(OutputType.FILE, /* wrapperJsonObject= */ false), - testCase(OutputType.FILE_AND_BUFFERED_WRITER, /* wrapperJsonObject= */ true), - testCase(OutputType.FILE_AND_BUFFERED_WRITER, /* wrapperJsonObject= */ false), - testCase(OutputType.LOGGER, /* wrapperJsonObject= */ true), - testCase(OutputType.LOGGER, /* wrapperJsonObject= */ false)) + testCase(OutputType.SYSTEM_OUT, MemoryMode.IMMUTABLE_DATA, /* wrapperJsonObject= */ true), + testCase(OutputType.SYSTEM_OUT, MemoryMode.IMMUTABLE_DATA, /* wrapperJsonObject= */ false), + testCase(OutputType.FILE, MemoryMode.IMMUTABLE_DATA, /* wrapperJsonObject= */ true), + testCase(OutputType.FILE, MemoryMode.IMMUTABLE_DATA, /* wrapperJsonObject= */ false), + testCase( + OutputType.FILE_AND_BUFFERED_WRITER, + MemoryMode.IMMUTABLE_DATA, + /* wrapperJsonObject= */ true), + testCase( + OutputType.FILE_AND_BUFFERED_WRITER, + MemoryMode.IMMUTABLE_DATA, + /* wrapperJsonObject= */ false), + testCase(OutputType.LOGGER, MemoryMode.IMMUTABLE_DATA, /* wrapperJsonObject= */ true), + testCase(OutputType.LOGGER, MemoryMode.IMMUTABLE_DATA, /* wrapperJsonObject= */ false), + testCase(OutputType.SYSTEM_OUT, MemoryMode.REUSABLE_DATA, /* wrapperJsonObject= */ true), + testCase(OutputType.SYSTEM_OUT, MemoryMode.REUSABLE_DATA, /* wrapperJsonObject= */ false), + testCase(OutputType.FILE, MemoryMode.REUSABLE_DATA, /* wrapperJsonObject= */ true), + testCase(OutputType.FILE, MemoryMode.REUSABLE_DATA, /* wrapperJsonObject= */ false), + testCase( + OutputType.FILE_AND_BUFFERED_WRITER, + MemoryMode.REUSABLE_DATA, + /* wrapperJsonObject= */ true), + testCase( + OutputType.FILE_AND_BUFFERED_WRITER, + MemoryMode.REUSABLE_DATA, + /* wrapperJsonObject= */ false), + testCase(OutputType.LOGGER, MemoryMode.REUSABLE_DATA, /* wrapperJsonObject= */ true), + testCase(OutputType.LOGGER, MemoryMode.REUSABLE_DATA, /* wrapperJsonObject= */ false)) .stream(); } - private static Arguments testCase(OutputType type, boolean wrapperJsonObject) { + private static Arguments testCase( + OutputType type, MemoryMode memoryMode, boolean wrapperJsonObject) { return Arguments.of( - "output=" + type + ", wrapperJsonObject=" + wrapperJsonObject, - new TestCase(type, wrapperJsonObject)); + "output=" + + type + + ", wrapperJsonObject=" + + wrapperJsonObject + + ", memoryMode=" + + memoryMode, + new TestCase(type, memoryMode, wrapperJsonObject)); } @SuppressWarnings("SystemOut") @@ -190,8 +226,19 @@ void exportWithProgrammaticConfig(String name, TestCase testCase) default: throw new IllegalStateException("Unexpected value: " + testCase.getOutputType()); } - T exporter = createExporter(outputStream, testCase.isWrapperJsonObject()); - testDataExporter.export(exporter); + + Supplier exporter = + () -> + createExporter(outputStream, testCase.getMemoryMode(), testCase.isWrapperJsonObject()); + + if (testCase.getMemoryMode() == MemoryMode.REUSABLE_DATA && !testCase.isWrapperJsonObject()) { + assertThatExceptionOfType(IllegalArgumentException.class) + .isThrownBy(exporter::get) + .withMessage("Reusable data mode is not supported without wrapperJsonObject"); + return; + } + + testDataExporter.export(exporter.get()); String output = output(outputStream, file); String expectedJson = testDataExporter.getExpectedJson(testCase.isWrapperJsonObject()); @@ -215,40 +262,69 @@ void testShutdown() { @Test void defaultToString() { - assertFullToString(createDefaultExporter(), defaultConfigString); + assertThat(createDefaultExporter()).hasToString(defaultConfigString); - assertFullToString( - loadExporter(DefaultConfigProperties.createFromMap(emptyMap())), defaultConfigString); + assertThat(exporterFromProvider(DefaultConfigProperties.createFromMap(emptyMap()))) + .hasToString(defaultConfigString); } - protected Object exporterFromComponentProvider(StructuredConfigProperties properties) { - return ((ComponentProvider) - loadSpi(ComponentProvider.class) - .filter( - p -> { - ComponentProvider c = (ComponentProvider) p; - return "experimental-otlp/stdout".equals(c.getName()) - && c.getType().equals(componentProviderType); - }) - .findFirst() - .orElseThrow(() -> new IllegalStateException("No provider found"))) - .create(properties); + @Test + void providerConfig() { + assertThat( + exporterFromProvider( + DefaultConfigProperties.createFromMap( + singletonMap("otel.java.experimental.exporter.memory_mode", "immutable_data")))) + .extracting("memoryMode") + .isEqualTo(MemoryMode.IMMUTABLE_DATA); + assertThat( + exporterFromProvider( + DefaultConfigProperties.createFromMap( + singletonMap("otel.java.experimental.exporter.memory_mode", "reusable_data")))) + .extracting("memoryMode") + .isEqualTo(MemoryMode.REUSABLE_DATA); } @Test void componentProviderConfig() { StructuredConfigProperties properties = mock(StructuredConfigProperties.class); - Object exporter = exporterFromComponentProvider(properties); + T exporter = exporterFromComponentProvider(properties); assertThat(exporter).extracting("wrapperJsonObject").isEqualTo(true); + assertThat(exporter).extracting("memoryMode").isEqualTo(MemoryMode.IMMUTABLE_DATA); assertThat(exporter) .extracting("jsonWriter") .extracting(Object::toString) .isEqualTo("StreamJsonWriter{outputStream=stdout}"); + + when(properties.getString("memory_mode")).thenReturn("IMMUTABLE_DATA"); + assertThat(exporterFromComponentProvider(properties)) + .extracting("memoryMode") + .isEqualTo(MemoryMode.IMMUTABLE_DATA); + + when(properties.getString("memory_mode")).thenReturn("REUSABLE_DATA"); + assertThat(exporterFromComponentProvider(properties)) + .extracting("memoryMode") + .isEqualTo(MemoryMode.REUSABLE_DATA); } @SuppressWarnings("unchecked") - protected T loadExporter(ConfigProperties config) { + protected T exporterFromComponentProvider(StructuredConfigProperties properties) { + return (T) + ((ComponentProvider) + loadSpi(ComponentProvider.class) + .filter( + p -> { + ComponentProvider c = (ComponentProvider) p; + return "experimental-otlp/stdout".equals(c.getName()) + && c.getType().equals(componentProviderType); + }) + .findFirst() + .orElseThrow(() -> new IllegalStateException("No provider found"))) + .create(properties); + } + + @SuppressWarnings("unchecked") + protected T exporterFromProvider(ConfigProperties config) { Object provider = loadProvider(); try { @@ -280,8 +356,4 @@ private Object loadProvider() { protected static Stream loadSpi(Class type) { return Streams.stream(ServiceLoader.load(type, type.getClassLoader()).iterator()); } - - private void assertFullToString(T exporter, String expected) { - assertThat(exporter.toString()).isEqualTo(expected); - } } diff --git a/exporters/logging-otlp/src/test/java/io/opentelemetry/exporter/logging/otlp/OtlpStdoutLogRecordExporterTest.java b/exporters/logging-otlp/src/test/java/io/opentelemetry/exporter/logging/otlp/OtlpStdoutLogRecordExporterTest.java index e234b9745dc..c19fba0fe3e 100644 --- a/exporters/logging-otlp/src/test/java/io/opentelemetry/exporter/logging/otlp/OtlpStdoutLogRecordExporterTest.java +++ b/exporters/logging-otlp/src/test/java/io/opentelemetry/exporter/logging/otlp/OtlpStdoutLogRecordExporterTest.java @@ -8,6 +8,7 @@ import io.opentelemetry.exporter.logging.otlp.internal.logs.OtlpStdoutLogRecordExporter; import io.opentelemetry.exporter.logging.otlp.internal.logs.OtlpStdoutLogRecordExporterBuilder; import io.opentelemetry.sdk.autoconfigure.spi.logs.ConfigurableLogRecordExporterProvider; +import io.opentelemetry.sdk.common.export.MemoryMode; import io.opentelemetry.sdk.logs.export.LogRecordExporter; import java.io.OutputStream; import java.util.logging.Logger; @@ -22,7 +23,7 @@ public OtlpStdoutLogRecordExporterTest() { OtlpStdoutLogRecordExporter.class, ConfigurableLogRecordExporterProvider.class, LogRecordExporter.class, - "OtlpStdoutLogRecordExporter{jsonWriter=StreamJsonWriter{outputStream=stdout}, wrapperJsonObject=true}"); + "OtlpStdoutLogRecordExporter{jsonWriter=StreamJsonWriter{outputStream=stdout}, wrapperJsonObject=true, memoryMode=IMMUTABLE_DATA}"); } @Override @@ -32,9 +33,11 @@ protected OtlpStdoutLogRecordExporter createDefaultExporter() { @Override protected OtlpStdoutLogRecordExporter createExporter( - @Nullable OutputStream outputStream, boolean wrapperJsonObject) { + @Nullable OutputStream outputStream, MemoryMode memoryMode, boolean wrapperJsonObject) { OtlpStdoutLogRecordExporterBuilder builder = - OtlpStdoutLogRecordExporter.builder().setWrapperJsonObject(wrapperJsonObject); + OtlpStdoutLogRecordExporter.builder() + .setMemoryMode(memoryMode) + .setWrapperJsonObject(wrapperJsonObject); if (outputStream != null) { builder.setOutput(outputStream); } else { diff --git a/exporters/logging-otlp/src/test/java/io/opentelemetry/exporter/logging/otlp/OtlpStdoutMetricExporterTest.java b/exporters/logging-otlp/src/test/java/io/opentelemetry/exporter/logging/otlp/OtlpStdoutMetricExporterTest.java index fdc6d945fc4..fc081e229f4 100644 --- a/exporters/logging-otlp/src/test/java/io/opentelemetry/exporter/logging/otlp/OtlpStdoutMetricExporterTest.java +++ b/exporters/logging-otlp/src/test/java/io/opentelemetry/exporter/logging/otlp/OtlpStdoutMetricExporterTest.java @@ -16,6 +16,7 @@ import io.opentelemetry.sdk.autoconfigure.spi.internal.DefaultConfigProperties; import io.opentelemetry.sdk.autoconfigure.spi.internal.StructuredConfigProperties; import io.opentelemetry.sdk.autoconfigure.spi.metrics.ConfigurableMetricExporterProvider; +import io.opentelemetry.sdk.common.export.MemoryMode; import io.opentelemetry.sdk.metrics.Aggregation; import io.opentelemetry.sdk.metrics.InstrumentType; import io.opentelemetry.sdk.metrics.data.AggregationTemporality; @@ -36,7 +37,7 @@ public OtlpStdoutMetricExporterTest() { OtlpStdoutMetricExporter.class, ConfigurableMetricExporterProvider.class, MetricExporter.class, - "OtlpStdoutMetricExporter{jsonWriter=StreamJsonWriter{outputStream=stdout}, wrapperJsonObject=true}"); + "OtlpStdoutMetricExporter{jsonWriter=StreamJsonWriter{outputStream=stdout}, wrapperJsonObject=true, memoryMode=IMMUTABLE_DATA, aggregationTemporalitySelector=AggregationTemporalitySelector{COUNTER=CUMULATIVE, UP_DOWN_COUNTER=CUMULATIVE, HISTOGRAM=CUMULATIVE, OBSERVABLE_COUNTER=CUMULATIVE, OBSERVABLE_UP_DOWN_COUNTER=CUMULATIVE, OBSERVABLE_GAUGE=CUMULATIVE, GAUGE=CUMULATIVE}, defaultAggregationSelector=DefaultAggregationSelector{COUNTER=default, UP_DOWN_COUNTER=default, HISTOGRAM=default, OBSERVABLE_COUNTER=default, OBSERVABLE_UP_DOWN_COUNTER=default, OBSERVABLE_GAUGE=default, GAUGE=default}}"); } @Override @@ -46,9 +47,11 @@ protected OtlpStdoutMetricExporter createDefaultExporter() { @Override protected OtlpStdoutMetricExporter createExporter( - @Nullable OutputStream outputStream, boolean wrapperJsonObject) { + @Nullable OutputStream outputStream, MemoryMode memoryMode, boolean wrapperJsonObject) { OtlpStdoutMetricExporterBuilder builder = - OtlpStdoutMetricExporter.builder().setWrapperJsonObject(wrapperJsonObject); + OtlpStdoutMetricExporter.builder() + .setMemoryMode(memoryMode) + .setWrapperJsonObject(wrapperJsonObject); if (outputStream != null) { builder.setOutput(outputStream); } else { @@ -61,7 +64,7 @@ protected OtlpStdoutMetricExporter createExporter( @Test void providerMetricConfig() { OtlpStdoutMetricExporter exporter = - loadExporter( + exporterFromProvider( DefaultConfigProperties.createFromMap( ImmutableMap.of( "otel.exporter.otlp.metrics.temporality.preference", @@ -83,8 +86,7 @@ void componentProviderMetricConfig() { when(properties.getString("default_histogram_aggregation")) .thenReturn("BASE2_EXPONENTIAL_BUCKET_HISTOGRAM"); - OtlpStdoutMetricExporter exporter = - (OtlpStdoutMetricExporter) exporterFromComponentProvider(properties); + OtlpStdoutMetricExporter exporter = exporterFromComponentProvider(properties); assertThat(exporter.getAggregationTemporality(InstrumentType.COUNTER)) .isEqualTo(AggregationTemporality.DELTA); diff --git a/exporters/logging-otlp/src/test/java/io/opentelemetry/exporter/logging/otlp/OtlpStdoutSpanExporterTest.java b/exporters/logging-otlp/src/test/java/io/opentelemetry/exporter/logging/otlp/OtlpStdoutSpanExporterTest.java index 472ff4cd731..01d3a96ccd2 100644 --- a/exporters/logging-otlp/src/test/java/io/opentelemetry/exporter/logging/otlp/OtlpStdoutSpanExporterTest.java +++ b/exporters/logging-otlp/src/test/java/io/opentelemetry/exporter/logging/otlp/OtlpStdoutSpanExporterTest.java @@ -8,6 +8,7 @@ import io.opentelemetry.exporter.logging.otlp.internal.traces.OtlpStdoutSpanExporter; import io.opentelemetry.exporter.logging.otlp.internal.traces.OtlpStdoutSpanExporterBuilder; import io.opentelemetry.sdk.autoconfigure.spi.traces.ConfigurableSpanExporterProvider; +import io.opentelemetry.sdk.common.export.MemoryMode; import io.opentelemetry.sdk.trace.export.SpanExporter; import java.io.OutputStream; import java.util.logging.Logger; @@ -21,7 +22,7 @@ public OtlpStdoutSpanExporterTest() { OtlpStdoutSpanExporter.class, ConfigurableSpanExporterProvider.class, SpanExporter.class, - "OtlpStdoutSpanExporter{jsonWriter=StreamJsonWriter{outputStream=stdout}, wrapperJsonObject=true}"); + "OtlpStdoutSpanExporter{jsonWriter=StreamJsonWriter{outputStream=stdout}, wrapperJsonObject=true, memoryMode=IMMUTABLE_DATA}"); } @Override @@ -31,9 +32,11 @@ protected OtlpStdoutSpanExporter createDefaultExporter() { @Override protected OtlpStdoutSpanExporter createExporter( - @Nullable OutputStream outputStream, boolean wrapperJsonObject) { + @Nullable OutputStream outputStream, MemoryMode memoryMode, boolean wrapperJsonObject) { OtlpStdoutSpanExporterBuilder builder = - OtlpStdoutSpanExporter.builder().setWrapperJsonObject(wrapperJsonObject); + OtlpStdoutSpanExporter.builder() + .setMemoryMode(memoryMode) + .setWrapperJsonObject(wrapperJsonObject); if (outputStream != null) { builder.setOutput(outputStream); } else { diff --git a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/logs/OtlpHttpLogRecordExporter.java b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/logs/OtlpHttpLogRecordExporter.java index 4f3202ceb99..dcc8b4bcc7a 100644 --- a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/logs/OtlpHttpLogRecordExporter.java +++ b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/logs/OtlpHttpLogRecordExporter.java @@ -8,15 +8,12 @@ import io.opentelemetry.exporter.internal.http.HttpExporter; import io.opentelemetry.exporter.internal.http.HttpExporterBuilder; import io.opentelemetry.exporter.internal.marshal.Marshaler; -import io.opentelemetry.exporter.internal.otlp.logs.LogsRequestMarshaler; -import io.opentelemetry.exporter.internal.otlp.logs.LowAllocationLogsRequestMarshaler; +import io.opentelemetry.exporter.internal.otlp.logs.LogReusableDataMarshaler; import io.opentelemetry.sdk.common.CompletableResultCode; import io.opentelemetry.sdk.common.export.MemoryMode; import io.opentelemetry.sdk.logs.data.LogRecordData; import io.opentelemetry.sdk.logs.export.LogRecordExporter; -import java.util.ArrayDeque; import java.util.Collection; -import java.util.Deque; import java.util.StringJoiner; import javax.annotation.concurrent.ThreadSafe; @@ -28,10 +25,9 @@ @ThreadSafe public final class OtlpHttpLogRecordExporter implements LogRecordExporter { - private final Deque marshalerPool = new ArrayDeque<>(); private final HttpExporterBuilder builder; private final HttpExporter delegate; - private final MemoryMode memoryMode; + private final LogReusableDataMarshaler marshaler; OtlpHttpLogRecordExporter( HttpExporterBuilder builder, @@ -39,7 +35,7 @@ public final class OtlpHttpLogRecordExporter implements LogRecordExporter { MemoryMode memoryMode) { this.builder = builder; this.delegate = delegate; - this.memoryMode = memoryMode; + this.marshaler = new LogReusableDataMarshaler(memoryMode, delegate::export); } /** @@ -71,7 +67,7 @@ public static OtlpHttpLogRecordExporterBuilder builder() { * @since 1.29.0 */ public OtlpHttpLogRecordExporterBuilder toBuilder() { - return new OtlpHttpLogRecordExporterBuilder(builder.copy(), memoryMode); + return new OtlpHttpLogRecordExporterBuilder(builder.copy(), marshaler.getMemoryMode()); } /** @@ -82,24 +78,7 @@ public OtlpHttpLogRecordExporterBuilder toBuilder() { */ @Override public CompletableResultCode export(Collection logs) { - if (memoryMode == MemoryMode.REUSABLE_DATA) { - LowAllocationLogsRequestMarshaler marshaler = marshalerPool.poll(); - if (marshaler == null) { - marshaler = new LowAllocationLogsRequestMarshaler(); - } - LowAllocationLogsRequestMarshaler exportMarshaler = marshaler; - exportMarshaler.initialize(logs); - return delegate - .export(exportMarshaler, logs.size()) - .whenComplete( - () -> { - exportMarshaler.reset(); - marshalerPool.add(exportMarshaler); - }); - } - // MemoryMode == MemoryMode.IMMUTABLE_DATA - LogsRequestMarshaler request = LogsRequestMarshaler.create(logs); - return delegate.export(request, logs.size()); + return marshaler.export(logs); } @Override @@ -117,7 +96,7 @@ public CompletableResultCode shutdown() { public String toString() { StringJoiner joiner = new StringJoiner(", ", "OtlpHttpLogRecordExporter{", "}"); joiner.add(builder.toString(false)); - joiner.add("memoryMode=" + memoryMode); + joiner.add("memoryMode=" + marshaler.getMemoryMode()); return joiner.toString(); } } diff --git a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/metrics/OtlpHttpMetricExporter.java b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/metrics/OtlpHttpMetricExporter.java index 1634d47fee5..87d7b4c7a10 100644 --- a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/metrics/OtlpHttpMetricExporter.java +++ b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/metrics/OtlpHttpMetricExporter.java @@ -8,8 +8,7 @@ import io.opentelemetry.exporter.internal.http.HttpExporter; import io.opentelemetry.exporter.internal.http.HttpExporterBuilder; import io.opentelemetry.exporter.internal.marshal.Marshaler; -import io.opentelemetry.exporter.internal.otlp.metrics.LowAllocationMetricsRequestMarshaler; -import io.opentelemetry.exporter.internal.otlp.metrics.MetricsRequestMarshaler; +import io.opentelemetry.exporter.internal.otlp.metrics.MetricReusableDataMarshaler; import io.opentelemetry.sdk.common.CompletableResultCode; import io.opentelemetry.sdk.common.export.MemoryMode; import io.opentelemetry.sdk.metrics.Aggregation; @@ -19,9 +18,7 @@ import io.opentelemetry.sdk.metrics.export.AggregationTemporalitySelector; import io.opentelemetry.sdk.metrics.export.DefaultAggregationSelector; import io.opentelemetry.sdk.metrics.export.MetricExporter; -import java.util.ArrayDeque; import java.util.Collection; -import java.util.Deque; import java.util.StringJoiner; import javax.annotation.concurrent.ThreadSafe; @@ -33,12 +30,11 @@ @ThreadSafe public final class OtlpHttpMetricExporter implements MetricExporter { - private final Deque marshalerPool = new ArrayDeque<>(); private final HttpExporterBuilder builder; private final HttpExporter delegate; private final AggregationTemporalitySelector aggregationTemporalitySelector; private final DefaultAggregationSelector defaultAggregationSelector; - private final MemoryMode memoryMode; + private final MetricReusableDataMarshaler marshaler; OtlpHttpMetricExporter( HttpExporterBuilder builder, @@ -50,7 +46,7 @@ public final class OtlpHttpMetricExporter implements MetricExporter { this.delegate = delegate; this.aggregationTemporalitySelector = aggregationTemporalitySelector; this.defaultAggregationSelector = defaultAggregationSelector; - this.memoryMode = memoryMode; + this.marshaler = new MetricReusableDataMarshaler(memoryMode, delegate::export); } /** @@ -82,7 +78,7 @@ public static OtlpHttpMetricExporterBuilder builder() { * @since 1.29.0 */ public OtlpHttpMetricExporterBuilder toBuilder() { - return new OtlpHttpMetricExporterBuilder(builder.copy(), memoryMode); + return new OtlpHttpMetricExporterBuilder(builder.copy(), marshaler.getMemoryMode()); } @Override @@ -97,7 +93,7 @@ public Aggregation getDefaultAggregation(InstrumentType instrumentType) { @Override public MemoryMode getMemoryMode() { - return memoryMode; + return marshaler.getMemoryMode(); } /** @@ -108,24 +104,7 @@ public MemoryMode getMemoryMode() { */ @Override public CompletableResultCode export(Collection metrics) { - if (memoryMode == MemoryMode.REUSABLE_DATA) { - LowAllocationMetricsRequestMarshaler marshaler = marshalerPool.poll(); - if (marshaler == null) { - marshaler = new LowAllocationMetricsRequestMarshaler(); - } - LowAllocationMetricsRequestMarshaler exportMarshaler = marshaler; - exportMarshaler.initialize(metrics); - return delegate - .export(exportMarshaler, metrics.size()) - .whenComplete( - () -> { - exportMarshaler.reset(); - marshalerPool.add(exportMarshaler); - }); - } - // MemoryMode == MemoryMode.IMMUTABLE_DATA - MetricsRequestMarshaler request = MetricsRequestMarshaler.create(metrics); - return delegate.export(request, metrics.size()); + return marshaler.export(metrics); } /** @@ -154,7 +133,7 @@ public String toString() { joiner.add( "defaultAggregationSelector=" + DefaultAggregationSelector.asString(defaultAggregationSelector)); - joiner.add("memoryMode=" + memoryMode); + joiner.add("memoryMode=" + marshaler.getMemoryMode()); return joiner.toString(); } } diff --git a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/trace/OtlpHttpSpanExporter.java b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/trace/OtlpHttpSpanExporter.java index 86d4016adb6..71870e12b54 100644 --- a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/trace/OtlpHttpSpanExporter.java +++ b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/trace/OtlpHttpSpanExporter.java @@ -8,15 +8,12 @@ import io.opentelemetry.exporter.internal.http.HttpExporter; import io.opentelemetry.exporter.internal.http.HttpExporterBuilder; import io.opentelemetry.exporter.internal.marshal.Marshaler; -import io.opentelemetry.exporter.internal.otlp.traces.LowAllocationTraceRequestMarshaler; -import io.opentelemetry.exporter.internal.otlp.traces.TraceRequestMarshaler; +import io.opentelemetry.exporter.internal.otlp.traces.SpanReusableDataMarshaler; import io.opentelemetry.sdk.common.CompletableResultCode; import io.opentelemetry.sdk.common.export.MemoryMode; import io.opentelemetry.sdk.trace.data.SpanData; import io.opentelemetry.sdk.trace.export.SpanExporter; -import java.util.ArrayDeque; import java.util.Collection; -import java.util.Deque; import java.util.StringJoiner; import javax.annotation.concurrent.ThreadSafe; @@ -28,10 +25,9 @@ @ThreadSafe public final class OtlpHttpSpanExporter implements SpanExporter { - private final Deque marshalerPool = new ArrayDeque<>(); private final HttpExporterBuilder builder; private final HttpExporter delegate; - private final MemoryMode memoryMode; + private final SpanReusableDataMarshaler marshaler; OtlpHttpSpanExporter( HttpExporterBuilder builder, @@ -39,7 +35,7 @@ public final class OtlpHttpSpanExporter implements SpanExporter { MemoryMode memoryMode) { this.builder = builder; this.delegate = delegate; - this.memoryMode = memoryMode; + this.marshaler = new SpanReusableDataMarshaler(memoryMode, delegate::export); } /** @@ -71,7 +67,7 @@ public static OtlpHttpSpanExporterBuilder builder() { * @since 1.29.0 */ public OtlpHttpSpanExporterBuilder toBuilder() { - return new OtlpHttpSpanExporterBuilder(builder.copy(), memoryMode); + return new OtlpHttpSpanExporterBuilder(builder.copy(), marshaler.getMemoryMode()); } /** @@ -82,24 +78,7 @@ public OtlpHttpSpanExporterBuilder toBuilder() { */ @Override public CompletableResultCode export(Collection spans) { - if (memoryMode == MemoryMode.REUSABLE_DATA) { - LowAllocationTraceRequestMarshaler marshaler = marshalerPool.poll(); - if (marshaler == null) { - marshaler = new LowAllocationTraceRequestMarshaler(); - } - LowAllocationTraceRequestMarshaler exportMarshaler = marshaler; - exportMarshaler.initialize(spans); - return delegate - .export(exportMarshaler, spans.size()) - .whenComplete( - () -> { - exportMarshaler.reset(); - marshalerPool.add(exportMarshaler); - }); - } - // MemoryMode == MemoryMode.IMMUTABLE_DATA - TraceRequestMarshaler request = TraceRequestMarshaler.create(spans); - return delegate.export(request, spans.size()); + return marshaler.export(spans); } /** @@ -122,7 +101,7 @@ public CompletableResultCode shutdown() { public String toString() { StringJoiner joiner = new StringJoiner(", ", "OtlpHttpSpanExporter{", "}"); joiner.add(builder.toString(false)); - joiner.add("memoryMode=" + memoryMode); + joiner.add("memoryMode=" + marshaler.getMemoryMode()); return joiner.toString(); } } diff --git a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/logs/OtlpGrpcLogRecordExporter.java b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/logs/OtlpGrpcLogRecordExporter.java index efde0010450..e85cb76b78f 100644 --- a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/logs/OtlpGrpcLogRecordExporter.java +++ b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/logs/OtlpGrpcLogRecordExporter.java @@ -8,15 +8,12 @@ import io.opentelemetry.exporter.internal.grpc.GrpcExporter; import io.opentelemetry.exporter.internal.grpc.GrpcExporterBuilder; import io.opentelemetry.exporter.internal.marshal.Marshaler; -import io.opentelemetry.exporter.internal.otlp.logs.LogsRequestMarshaler; -import io.opentelemetry.exporter.internal.otlp.logs.LowAllocationLogsRequestMarshaler; +import io.opentelemetry.exporter.internal.otlp.logs.LogReusableDataMarshaler; import io.opentelemetry.sdk.common.CompletableResultCode; import io.opentelemetry.sdk.common.export.MemoryMode; import io.opentelemetry.sdk.logs.data.LogRecordData; import io.opentelemetry.sdk.logs.export.LogRecordExporter; -import java.util.ArrayDeque; import java.util.Collection; -import java.util.Deque; import java.util.StringJoiner; import javax.annotation.concurrent.ThreadSafe; @@ -28,10 +25,9 @@ @ThreadSafe public final class OtlpGrpcLogRecordExporter implements LogRecordExporter { - private final Deque marshalerPool = new ArrayDeque<>(); private final GrpcExporterBuilder builder; private final GrpcExporter delegate; - private final MemoryMode memoryMode; + private final LogReusableDataMarshaler marshaler; /** * Returns a new {@link OtlpGrpcLogRecordExporter} using the default values. @@ -60,7 +56,7 @@ public static OtlpGrpcLogRecordExporterBuilder builder() { MemoryMode memoryMode) { this.builder = builder; this.delegate = delegate; - this.memoryMode = memoryMode; + this.marshaler = new LogReusableDataMarshaler(memoryMode, delegate::export); } /** @@ -71,7 +67,7 @@ public static OtlpGrpcLogRecordExporterBuilder builder() { * @since 1.29.0 */ public OtlpGrpcLogRecordExporterBuilder toBuilder() { - return new OtlpGrpcLogRecordExporterBuilder(builder.copy(), memoryMode); + return new OtlpGrpcLogRecordExporterBuilder(builder.copy(), marshaler.getMemoryMode()); } /** @@ -82,24 +78,7 @@ public OtlpGrpcLogRecordExporterBuilder toBuilder() { */ @Override public CompletableResultCode export(Collection logs) { - if (memoryMode == MemoryMode.REUSABLE_DATA) { - LowAllocationLogsRequestMarshaler marshaler = marshalerPool.poll(); - if (marshaler == null) { - marshaler = new LowAllocationLogsRequestMarshaler(); - } - LowAllocationLogsRequestMarshaler exportMarshaler = marshaler; - exportMarshaler.initialize(logs); - return delegate - .export(exportMarshaler, logs.size()) - .whenComplete( - () -> { - exportMarshaler.reset(); - marshalerPool.add(exportMarshaler); - }); - } - // MemoryMode == MemoryMode.IMMUTABLE_DATA - LogsRequestMarshaler request = LogsRequestMarshaler.create(logs); - return delegate.export(request, logs.size()); + return marshaler.export(logs); } @Override @@ -120,7 +99,7 @@ public CompletableResultCode shutdown() { public String toString() { StringJoiner joiner = new StringJoiner(", ", "OtlpGrpcLogRecordExporter{", "}"); joiner.add(builder.toString(false)); - joiner.add("memoryMode=" + memoryMode); + joiner.add("memoryMode=" + marshaler.getMemoryMode()); return joiner.toString(); } } diff --git a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/metrics/OtlpGrpcMetricExporter.java b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/metrics/OtlpGrpcMetricExporter.java index 1a9d3ed20e2..5dd48db4908 100644 --- a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/metrics/OtlpGrpcMetricExporter.java +++ b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/metrics/OtlpGrpcMetricExporter.java @@ -8,8 +8,7 @@ import io.opentelemetry.exporter.internal.grpc.GrpcExporter; import io.opentelemetry.exporter.internal.grpc.GrpcExporterBuilder; import io.opentelemetry.exporter.internal.marshal.Marshaler; -import io.opentelemetry.exporter.internal.otlp.metrics.LowAllocationMetricsRequestMarshaler; -import io.opentelemetry.exporter.internal.otlp.metrics.MetricsRequestMarshaler; +import io.opentelemetry.exporter.internal.otlp.metrics.MetricReusableDataMarshaler; import io.opentelemetry.sdk.common.CompletableResultCode; import io.opentelemetry.sdk.common.export.MemoryMode; import io.opentelemetry.sdk.metrics.Aggregation; @@ -19,9 +18,7 @@ import io.opentelemetry.sdk.metrics.export.AggregationTemporalitySelector; import io.opentelemetry.sdk.metrics.export.DefaultAggregationSelector; import io.opentelemetry.sdk.metrics.export.MetricExporter; -import java.util.ArrayDeque; import java.util.Collection; -import java.util.Deque; import java.util.StringJoiner; import javax.annotation.concurrent.ThreadSafe; @@ -33,12 +30,11 @@ @ThreadSafe public final class OtlpGrpcMetricExporter implements MetricExporter { - private final Deque marshalerPool = new ArrayDeque<>(); private final GrpcExporterBuilder builder; private final GrpcExporter delegate; private final AggregationTemporalitySelector aggregationTemporalitySelector; private final DefaultAggregationSelector defaultAggregationSelector; - private final MemoryMode memoryMode; + private final MetricReusableDataMarshaler marshaler; /** * Returns a new {@link OtlpGrpcMetricExporter} using the default values. @@ -71,7 +67,7 @@ public static OtlpGrpcMetricExporterBuilder builder() { this.delegate = delegate; this.aggregationTemporalitySelector = aggregationTemporalitySelector; this.defaultAggregationSelector = defaultAggregationSelector; - this.memoryMode = memoryMode; + this.marshaler = new MetricReusableDataMarshaler(memoryMode, delegate::export); } /** @@ -82,7 +78,7 @@ public static OtlpGrpcMetricExporterBuilder builder() { * @since 1.29.0 */ public OtlpGrpcMetricExporterBuilder toBuilder() { - return new OtlpGrpcMetricExporterBuilder(builder.copy(), memoryMode); + return new OtlpGrpcMetricExporterBuilder(builder.copy(), marshaler.getMemoryMode()); } @Override @@ -97,7 +93,7 @@ public Aggregation getDefaultAggregation(InstrumentType instrumentType) { @Override public MemoryMode getMemoryMode() { - return memoryMode; + return marshaler.getMemoryMode(); } /** @@ -108,24 +104,7 @@ public MemoryMode getMemoryMode() { */ @Override public CompletableResultCode export(Collection metrics) { - if (memoryMode == MemoryMode.REUSABLE_DATA) { - LowAllocationMetricsRequestMarshaler marshaler = marshalerPool.poll(); - if (marshaler == null) { - marshaler = new LowAllocationMetricsRequestMarshaler(); - } - LowAllocationMetricsRequestMarshaler exportMarshaler = marshaler; - exportMarshaler.initialize(metrics); - return delegate - .export(exportMarshaler, metrics.size()) - .whenComplete( - () -> { - exportMarshaler.reset(); - marshalerPool.add(exportMarshaler); - }); - } - // MemoryMode == MemoryMode.IMMUTABLE_DATA - MetricsRequestMarshaler request = MetricsRequestMarshaler.create(metrics); - return delegate.export(request, metrics.size()); + return marshaler.export(metrics); } /** @@ -157,7 +136,7 @@ public String toString() { joiner.add( "defaultAggregationSelector=" + DefaultAggregationSelector.asString(defaultAggregationSelector)); - joiner.add("memoryMode=" + memoryMode); + joiner.add("memoryMode=" + marshaler.getMemoryMode()); return joiner.toString(); } } diff --git a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/trace/OtlpGrpcSpanExporter.java b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/trace/OtlpGrpcSpanExporter.java index a2c29d87bc1..6d0d3d2fffa 100644 --- a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/trace/OtlpGrpcSpanExporter.java +++ b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/trace/OtlpGrpcSpanExporter.java @@ -8,15 +8,12 @@ import io.opentelemetry.exporter.internal.grpc.GrpcExporter; import io.opentelemetry.exporter.internal.grpc.GrpcExporterBuilder; import io.opentelemetry.exporter.internal.marshal.Marshaler; -import io.opentelemetry.exporter.internal.otlp.traces.LowAllocationTraceRequestMarshaler; -import io.opentelemetry.exporter.internal.otlp.traces.TraceRequestMarshaler; +import io.opentelemetry.exporter.internal.otlp.traces.SpanReusableDataMarshaler; import io.opentelemetry.sdk.common.CompletableResultCode; import io.opentelemetry.sdk.common.export.MemoryMode; import io.opentelemetry.sdk.trace.data.SpanData; import io.opentelemetry.sdk.trace.export.SpanExporter; -import java.util.ArrayDeque; import java.util.Collection; -import java.util.Deque; import java.util.StringJoiner; import javax.annotation.concurrent.ThreadSafe; @@ -24,10 +21,9 @@ @ThreadSafe public final class OtlpGrpcSpanExporter implements SpanExporter { - private final Deque marshalerPool = new ArrayDeque<>(); private final GrpcExporterBuilder builder; private final GrpcExporter delegate; - private final MemoryMode memoryMode; + private final SpanReusableDataMarshaler marshaler; /** * Returns a new {@link OtlpGrpcSpanExporter} using the default values. @@ -56,7 +52,7 @@ public static OtlpGrpcSpanExporterBuilder builder() { MemoryMode memoryMode) { this.builder = builder; this.delegate = delegate; - this.memoryMode = memoryMode; + this.marshaler = new SpanReusableDataMarshaler(memoryMode, delegate::export); } /** @@ -67,7 +63,7 @@ public static OtlpGrpcSpanExporterBuilder builder() { * @since 1.29.0 */ public OtlpGrpcSpanExporterBuilder toBuilder() { - return new OtlpGrpcSpanExporterBuilder(builder.copy(), memoryMode); + return new OtlpGrpcSpanExporterBuilder(builder.copy(), marshaler.getMemoryMode()); } /** @@ -78,24 +74,7 @@ public OtlpGrpcSpanExporterBuilder toBuilder() { */ @Override public CompletableResultCode export(Collection spans) { - if (memoryMode == MemoryMode.REUSABLE_DATA) { - LowAllocationTraceRequestMarshaler marshaler = marshalerPool.poll(); - if (marshaler == null) { - marshaler = new LowAllocationTraceRequestMarshaler(); - } - LowAllocationTraceRequestMarshaler exportMarshaler = marshaler; - exportMarshaler.initialize(spans); - return delegate - .export(exportMarshaler, spans.size()) - .whenComplete( - () -> { - exportMarshaler.reset(); - marshalerPool.add(exportMarshaler); - }); - } - // MemoryMode == MemoryMode.IMMUTABLE_DATA - TraceRequestMarshaler request = TraceRequestMarshaler.create(spans); - return delegate.export(request, spans.size()); + return marshaler.export(spans); } /** @@ -121,7 +100,7 @@ public CompletableResultCode shutdown() { public String toString() { StringJoiner joiner = new StringJoiner(", ", "OtlpGrpcSpanExporter{", "}"); joiner.add(builder.toString(false)); - joiner.add("memoryMode=" + memoryMode); + joiner.add("memoryMode=" + marshaler.getMemoryMode()); return joiner.toString(); } } diff --git a/exporters/otlp/all/src/test/java/io/opentelemetry/exporter/otlp/internal/OtlpLogRecordExporterProviderTest.java b/exporters/otlp/all/src/test/java/io/opentelemetry/exporter/otlp/internal/OtlpLogRecordExporterProviderTest.java index 2f882b3ebfd..bab89d8a69a 100644 --- a/exporters/otlp/all/src/test/java/io/opentelemetry/exporter/otlp/internal/OtlpLogRecordExporterProviderTest.java +++ b/exporters/otlp/all/src/test/java/io/opentelemetry/exporter/otlp/internal/OtlpLogRecordExporterProviderTest.java @@ -30,6 +30,7 @@ import java.util.Collections; import java.util.HashMap; import java.util.Map; +import org.assertj.core.api.AbstractObjectAssert; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; @@ -128,11 +129,15 @@ void createExporter_GrpcDefaults() { verify(grpcBuilder, never()).setTrustedCertificates(any()); verify(grpcBuilder, never()).setClientTls(any(), any()); assertThat(grpcBuilder).extracting("delegate").extracting("retryPolicy").isNotNull(); - assertThat(exporter).extracting("memoryMode").isEqualTo(MemoryMode.IMMUTABLE_DATA); + getMemoryMode(exporter).isEqualTo(MemoryMode.IMMUTABLE_DATA); } Mockito.verifyNoInteractions(httpBuilder); } + private static AbstractObjectAssert getMemoryMode(LogRecordExporter exporter) { + return assertThat(exporter).extracting("marshaler").extracting("memoryMode"); + } + @Test void createExporter_GrpcWithGeneralConfiguration() throws CertificateEncodingException { Map config = new HashMap<>(); @@ -191,7 +196,7 @@ void createExporter_GrpcWithSignalConfiguration() throws CertificateEncodingExce verify(grpcBuilder).setTrustedCertificates(serverTls.certificate().getEncoded()); verify(grpcBuilder) .setClientTls(clientTls.privateKey().getEncoded(), clientTls.certificate().getEncoded()); - assertThat(exporter).extracting("memoryMode").isEqualTo(MemoryMode.REUSABLE_DATA); + getMemoryMode(exporter).isEqualTo(MemoryMode.REUSABLE_DATA); } Mockito.verifyNoInteractions(httpBuilder); } @@ -211,7 +216,7 @@ void createExporter_HttpDefaults() { verify(httpBuilder, never()).setTrustedCertificates(any()); verify(httpBuilder, never()).setClientTls(any(), any()); assertThat(httpBuilder).extracting("delegate").extracting("retryPolicy").isNotNull(); - assertThat(exporter).extracting("memoryMode").isEqualTo(MemoryMode.IMMUTABLE_DATA); + getMemoryMode(exporter).isEqualTo(MemoryMode.IMMUTABLE_DATA); } Mockito.verifyNoInteractions(grpcBuilder); } @@ -277,7 +282,7 @@ void createExporter_HttpWithSignalConfiguration() throws CertificateEncodingExce verify(httpBuilder).setTrustedCertificates(serverTls.certificate().getEncoded()); verify(httpBuilder) .setClientTls(clientTls.privateKey().getEncoded(), clientTls.certificate().getEncoded()); - assertThat(exporter).extracting("memoryMode").isEqualTo(MemoryMode.REUSABLE_DATA); + getMemoryMode(exporter).isEqualTo(MemoryMode.REUSABLE_DATA); } Mockito.verifyNoInteractions(grpcBuilder); } diff --git a/exporters/otlp/all/src/test/java/io/opentelemetry/exporter/otlp/internal/OtlpSpanExporterProviderTest.java b/exporters/otlp/all/src/test/java/io/opentelemetry/exporter/otlp/internal/OtlpSpanExporterProviderTest.java index 06d39054a0f..084826d47ff 100644 --- a/exporters/otlp/all/src/test/java/io/opentelemetry/exporter/otlp/internal/OtlpSpanExporterProviderTest.java +++ b/exporters/otlp/all/src/test/java/io/opentelemetry/exporter/otlp/internal/OtlpSpanExporterProviderTest.java @@ -30,6 +30,7 @@ import java.util.Collections; import java.util.HashMap; import java.util.Map; +import org.assertj.core.api.AbstractObjectAssert; import org.assertj.core.api.Assertions; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -129,11 +130,15 @@ void createExporter_GrpcDefaults() { verify(grpcBuilder, never()).setTrustedCertificates(any()); verify(grpcBuilder, never()).setClientTls(any(), any()); assertThat(grpcBuilder).extracting("delegate").extracting("retryPolicy").isNotNull(); - assertThat(exporter).extracting("memoryMode").isEqualTo(MemoryMode.IMMUTABLE_DATA); + getMemoryMode(exporter).isEqualTo(MemoryMode.IMMUTABLE_DATA); } Mockito.verifyNoInteractions(httpBuilder); } + private static AbstractObjectAssert getMemoryMode(SpanExporter exporter) { + return assertThat(exporter).extracting("marshaler").extracting("memoryMode"); + } + @Test void createExporter_GrpcWithGeneralConfiguration() throws CertificateEncodingException { Map config = new HashMap<>(); @@ -192,7 +197,7 @@ void createExporter_GrpcWithSignalConfiguration() throws CertificateEncodingExce verify(grpcBuilder).setTrustedCertificates(serverTls.certificate().getEncoded()); verify(grpcBuilder) .setClientTls(clientTls.privateKey().getEncoded(), clientTls.certificate().getEncoded()); - assertThat(exporter).extracting("memoryMode").isEqualTo(MemoryMode.REUSABLE_DATA); + getMemoryMode(exporter).isEqualTo(MemoryMode.REUSABLE_DATA); } Mockito.verifyNoInteractions(httpBuilder); } @@ -212,7 +217,7 @@ void createExporter_HttpDefaults() { verify(httpBuilder, never()).setTrustedCertificates(any()); verify(httpBuilder, never()).setClientTls(any(), any()); assertThat(httpBuilder).extracting("delegate").extracting("retryPolicy").isNotNull(); - assertThat(exporter).extracting("memoryMode").isEqualTo(MemoryMode.IMMUTABLE_DATA); + getMemoryMode(exporter).isEqualTo(MemoryMode.IMMUTABLE_DATA); } Mockito.verifyNoInteractions(grpcBuilder); } @@ -244,7 +249,7 @@ void createExporter_HttpWithGeneralConfiguration() throws CertificateEncodingExc verify(httpBuilder) .setClientTls(clientTls.privateKey().getEncoded(), clientTls.certificate().getEncoded()); assertThat(httpBuilder).extracting("delegate").extracting("retryPolicy").isNull(); - assertThat(exporter).extracting("memoryMode").isEqualTo(MemoryMode.IMMUTABLE_DATA); + getMemoryMode(exporter).isEqualTo(MemoryMode.IMMUTABLE_DATA); } Mockito.verifyNoInteractions(grpcBuilder); } @@ -281,7 +286,7 @@ void createExporter_HttpWithSignalConfiguration() throws CertificateEncodingExce verify(httpBuilder).setTrustedCertificates(serverTls.certificate().getEncoded()); verify(httpBuilder) .setClientTls(clientTls.privateKey().getEncoded(), clientTls.certificate().getEncoded()); - assertThat(exporter).extracting("memoryMode").isEqualTo(MemoryMode.REUSABLE_DATA); + getMemoryMode(exporter).isEqualTo(MemoryMode.REUSABLE_DATA); } Mockito.verifyNoInteractions(grpcBuilder); } diff --git a/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/logs/LogReusableDataMarshaler.java b/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/logs/LogReusableDataMarshaler.java new file mode 100644 index 00000000000..5f3fc50a5f5 --- /dev/null +++ b/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/logs/LogReusableDataMarshaler.java @@ -0,0 +1,58 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.exporter.internal.otlp.logs; + +import io.opentelemetry.exporter.internal.marshal.Marshaler; +import io.opentelemetry.sdk.common.CompletableResultCode; +import io.opentelemetry.sdk.common.export.MemoryMode; +import io.opentelemetry.sdk.logs.data.LogRecordData; +import java.util.ArrayDeque; +import java.util.Collection; +import java.util.Deque; +import java.util.function.BiFunction; + +/** + * This class is internal and is hence not for public use. Its APIs are unstable and can change at + * any time. + */ +public class LogReusableDataMarshaler { + + private final Deque marshalerPool = new ArrayDeque<>(); + + private final MemoryMode memoryMode; + private final BiFunction doExport; + + public LogReusableDataMarshaler( + MemoryMode memoryMode, BiFunction doExport) { + this.memoryMode = memoryMode; + this.doExport = doExport; + } + + public MemoryMode getMemoryMode() { + return memoryMode; + } + + public CompletableResultCode export(Collection logs) { + if (memoryMode == MemoryMode.REUSABLE_DATA) { + LowAllocationLogsRequestMarshaler marshaler = marshalerPool.poll(); + if (marshaler == null) { + marshaler = new LowAllocationLogsRequestMarshaler(); + } + LowAllocationLogsRequestMarshaler exportMarshaler = marshaler; + exportMarshaler.initialize(logs); + return doExport + .apply(exportMarshaler, logs.size()) + .whenComplete( + () -> { + exportMarshaler.reset(); + marshalerPool.add(exportMarshaler); + }); + } + // MemoryMode == MemoryMode.IMMUTABLE_DATA + LogsRequestMarshaler request = LogsRequestMarshaler.create(logs); + return doExport.apply(request, logs.size()); + } +} diff --git a/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/metrics/MetricReusableDataMarshaler.java b/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/metrics/MetricReusableDataMarshaler.java new file mode 100644 index 00000000000..c143e94fa5d --- /dev/null +++ b/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/metrics/MetricReusableDataMarshaler.java @@ -0,0 +1,58 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.exporter.internal.otlp.metrics; + +import io.opentelemetry.exporter.internal.marshal.Marshaler; +import io.opentelemetry.sdk.common.CompletableResultCode; +import io.opentelemetry.sdk.common.export.MemoryMode; +import io.opentelemetry.sdk.metrics.data.MetricData; +import java.util.ArrayDeque; +import java.util.Collection; +import java.util.Deque; +import java.util.function.BiFunction; + +/** + * This class is internal and is hence not for public use. Its APIs are unstable and can change at + * any time. + */ +public class MetricReusableDataMarshaler { + + private final Deque marshalerPool = new ArrayDeque<>(); + + private final MemoryMode memoryMode; + private final BiFunction doExport; + + public MetricReusableDataMarshaler( + MemoryMode memoryMode, BiFunction doExport) { + this.memoryMode = memoryMode; + this.doExport = doExport; + } + + public MemoryMode getMemoryMode() { + return memoryMode; + } + + public CompletableResultCode export(Collection metrics) { + if (memoryMode == MemoryMode.REUSABLE_DATA) { + LowAllocationMetricsRequestMarshaler marshaler = marshalerPool.poll(); + if (marshaler == null) { + marshaler = new LowAllocationMetricsRequestMarshaler(); + } + LowAllocationMetricsRequestMarshaler exportMarshaler = marshaler; + exportMarshaler.initialize(metrics); + return doExport + .apply(exportMarshaler, metrics.size()) + .whenComplete( + () -> { + exportMarshaler.reset(); + marshalerPool.add(exportMarshaler); + }); + } + // MemoryMode == MemoryMode.IMMUTABLE_DATA + MetricsRequestMarshaler request = MetricsRequestMarshaler.create(metrics); + return doExport.apply(request, metrics.size()); + } +} diff --git a/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/traces/SpanReusableDataMarshaler.java b/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/traces/SpanReusableDataMarshaler.java new file mode 100644 index 00000000000..af69e811c89 --- /dev/null +++ b/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/traces/SpanReusableDataMarshaler.java @@ -0,0 +1,58 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.exporter.internal.otlp.traces; + +import io.opentelemetry.exporter.internal.marshal.Marshaler; +import io.opentelemetry.sdk.common.CompletableResultCode; +import io.opentelemetry.sdk.common.export.MemoryMode; +import io.opentelemetry.sdk.trace.data.SpanData; +import java.util.ArrayDeque; +import java.util.Collection; +import java.util.Deque; +import java.util.function.BiFunction; + +/** + * This class is internal and is hence not for public use. Its APIs are unstable and can change at + * any time. + */ +public class SpanReusableDataMarshaler { + + private final Deque marshalerPool = new ArrayDeque<>(); + + private final MemoryMode memoryMode; + private final BiFunction doExport; + + public SpanReusableDataMarshaler( + MemoryMode memoryMode, BiFunction doExport) { + this.memoryMode = memoryMode; + this.doExport = doExport; + } + + public MemoryMode getMemoryMode() { + return memoryMode; + } + + public CompletableResultCode export(Collection spans) { + if (memoryMode == MemoryMode.REUSABLE_DATA) { + LowAllocationTraceRequestMarshaler marshaler = marshalerPool.poll(); + if (marshaler == null) { + marshaler = new LowAllocationTraceRequestMarshaler(); + } + LowAllocationTraceRequestMarshaler exportMarshaler = marshaler; + exportMarshaler.initialize(spans); + return doExport + .apply(exportMarshaler, spans.size()) + .whenComplete( + () -> { + exportMarshaler.reset(); + marshalerPool.add(exportMarshaler); + }); + } + // MemoryMode == MemoryMode.IMMUTABLE_DATA + TraceRequestMarshaler request = TraceRequestMarshaler.create(spans); + return doExport.apply(request, spans.size()); + } +} From 62df13200788c9d3b207eff54eb6913fe71413a8 Mon Sep 17 00:00:00 2001 From: jack-berg <34418638+jack-berg@users.noreply.github.com> Date: Thu, 17 Oct 2024 12:42:37 -0500 Subject: [PATCH 616/901] Set declarative config default OTLP protocol to http/protobuf (#6800) --- .../exporter/otlp/internal/OtlpConfigUtil.java | 9 ++++++++- .../fileconfig/FileConfigurationCreateTest.java | 2 +- .../fileconfig/LogRecordExporterFactoryTest.java | 3 +-- .../fileconfig/LogRecordProcessorFactoryTest.java | 8 ++++---- .../fileconfig/LoggerProviderFactoryTest.java | 4 ++-- .../fileconfig/MeterProviderFactoryTest.java | 4 ++-- .../fileconfig/MetricExporterFactoryTest.java | 3 +-- .../fileconfig/MetricReaderFactoryTest.java | 6 +++--- .../OpenTelemetryConfigurationFactoryTest.java | 12 ++++++------ .../fileconfig/SpanExporterFactoryTest.java | 3 +-- .../fileconfig/SpanProcessorFactoryTest.java | 8 ++++---- .../fileconfig/TracerProviderFactoryTest.java | 4 ++-- 12 files changed, 35 insertions(+), 31 deletions(-) diff --git a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/OtlpConfigUtil.java b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/OtlpConfigUtil.java index c49430d4468..4a653aea6ee 100644 --- a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/OtlpConfigUtil.java +++ b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/OtlpConfigUtil.java @@ -51,7 +51,14 @@ public static String getOtlpProtocol(String dataType, ConfigProperties config) { /** Determine the configured OTLP protocol for the {@code dataType}. */ public static String getStructuredConfigOtlpProtocol(StructuredConfigProperties config) { - return config.getString("protocol", PROTOCOL_GRPC); + // NOTE: The default OTLP protocol is different for declarative config than for env var / system + // property based config. This is intentional. OpenTelemetry changed the default protocol + // recommendation from grpc to http/protobuf, but the autoconfigure's env var / system property + // based config did not update to reflect this before stabilizing, and changing is a breaking + // change requiring a major version bump. Declarative config is not yet stable and therefore can + // switch to the current default recommendation, which aligns also aligns with the behavior of + // the OpenTelemetry Java Agent 2.x+. + return config.getString("protocol", PROTOCOL_HTTP_PROTOBUF); } /** Invoke the setters with the OTLP configuration for the {@code dataType}. */ diff --git a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/FileConfigurationCreateTest.java b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/FileConfigurationCreateTest.java index c1a97a8e265..4ed182f03f4 100644 --- a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/FileConfigurationCreateTest.java +++ b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/FileConfigurationCreateTest.java @@ -123,7 +123,7 @@ void parseAndCreate_Exception_CleansUpPartials() { logCapturer.assertContains( "Error encountered interpreting model. Closing partially configured components."); logCapturer.assertContains( - "Closing io.opentelemetry.exporter.otlp.logs.OtlpGrpcLogRecordExporter"); + "Closing io.opentelemetry.exporter.otlp.http.logs.OtlpHttpLogRecordExporter"); logCapturer.assertContains("Closing io.opentelemetry.sdk.logs.export.BatchLogRecordProcessor"); } } diff --git a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/LogRecordExporterFactoryTest.java b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/LogRecordExporterFactoryTest.java index a9d9e4019c9..802b1b9d4c0 100644 --- a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/LogRecordExporterFactoryTest.java +++ b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/LogRecordExporterFactoryTest.java @@ -15,7 +15,6 @@ import com.google.common.collect.ImmutableMap; import com.linecorp.armeria.testing.junit5.server.SelfSignedCertificateExtension; import io.opentelemetry.exporter.otlp.http.logs.OtlpHttpLogRecordExporter; -import io.opentelemetry.exporter.otlp.logs.OtlpGrpcLogRecordExporter; import io.opentelemetry.internal.testing.CleanupExtension; import io.opentelemetry.sdk.autoconfigure.internal.SpiHelper; import io.opentelemetry.sdk.autoconfigure.spi.ConfigurationException; @@ -61,7 +60,7 @@ class LogRecordExporterFactoryTest { void create_OtlpDefaults() { spiHelper = spy(spiHelper); List closeables = new ArrayList<>(); - OtlpGrpcLogRecordExporter expectedExporter = OtlpGrpcLogRecordExporter.getDefault(); + OtlpHttpLogRecordExporter expectedExporter = OtlpHttpLogRecordExporter.getDefault(); cleanup.addCloseable(expectedExporter); LogRecordExporter exporter = diff --git a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/LogRecordProcessorFactoryTest.java b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/LogRecordProcessorFactoryTest.java index 3f3adb75066..e5e29c26981 100644 --- a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/LogRecordProcessorFactoryTest.java +++ b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/LogRecordProcessorFactoryTest.java @@ -9,7 +9,7 @@ import static org.assertj.core.api.Assertions.assertThatThrownBy; import com.google.common.collect.ImmutableMap; -import io.opentelemetry.exporter.otlp.logs.OtlpGrpcLogRecordExporter; +import io.opentelemetry.exporter.otlp.http.logs.OtlpHttpLogRecordExporter; import io.opentelemetry.internal.testing.CleanupExtension; import io.opentelemetry.sdk.autoconfigure.internal.SpiHelper; import io.opentelemetry.sdk.autoconfigure.spi.ConfigurationException; @@ -53,7 +53,7 @@ void create_BatchDefaults() { List closeables = new ArrayList<>(); io.opentelemetry.sdk.logs.export.BatchLogRecordProcessor expectedProcessor = io.opentelemetry.sdk.logs.export.BatchLogRecordProcessor.builder( - OtlpGrpcLogRecordExporter.getDefault()) + OtlpHttpLogRecordExporter.getDefault()) .build(); cleanup.addCloseable(expectedProcessor); @@ -77,7 +77,7 @@ void create_BatchConfigured() { List closeables = new ArrayList<>(); io.opentelemetry.sdk.logs.export.BatchLogRecordProcessor expectedProcessor = io.opentelemetry.sdk.logs.export.BatchLogRecordProcessor.builder( - OtlpGrpcLogRecordExporter.getDefault()) + OtlpHttpLogRecordExporter.getDefault()) .setScheduleDelay(Duration.ofMillis(1)) .setMaxExportBatchSize(2) .setExporterTimeout(Duration.ofMillis(3)) @@ -121,7 +121,7 @@ void create_SimpleConfigured() { List closeables = new ArrayList<>(); io.opentelemetry.sdk.logs.LogRecordProcessor expectedProcessor = io.opentelemetry.sdk.logs.export.SimpleLogRecordProcessor.create( - OtlpGrpcLogRecordExporter.getDefault()); + OtlpHttpLogRecordExporter.getDefault()); cleanup.addCloseable(expectedProcessor); io.opentelemetry.sdk.logs.LogRecordProcessor processor = diff --git a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/LoggerProviderFactoryTest.java b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/LoggerProviderFactoryTest.java index 5293520b700..78aceb89896 100644 --- a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/LoggerProviderFactoryTest.java +++ b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/LoggerProviderFactoryTest.java @@ -7,7 +7,7 @@ import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.assertThat; -import io.opentelemetry.exporter.otlp.logs.OtlpGrpcLogRecordExporter; +import io.opentelemetry.exporter.otlp.http.logs.OtlpHttpLogRecordExporter; import io.opentelemetry.internal.testing.CleanupExtension; import io.opentelemetry.sdk.autoconfigure.internal.SpiHelper; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.AttributeLimitsModel; @@ -84,7 +84,7 @@ private static Stream createArguments() { .build()) .addLogRecordProcessor( io.opentelemetry.sdk.logs.export.BatchLogRecordProcessor.builder( - OtlpGrpcLogRecordExporter.getDefault()) + OtlpHttpLogRecordExporter.getDefault()) .build()) .build())); } diff --git a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/MeterProviderFactoryTest.java b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/MeterProviderFactoryTest.java index c84e0744992..29f7996f519 100644 --- a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/MeterProviderFactoryTest.java +++ b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/MeterProviderFactoryTest.java @@ -7,7 +7,7 @@ import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.assertThat; -import io.opentelemetry.exporter.otlp.metrics.OtlpGrpcMetricExporter; +import io.opentelemetry.exporter.otlp.http.metrics.OtlpHttpMetricExporter; import io.opentelemetry.internal.testing.CleanupExtension; import io.opentelemetry.sdk.autoconfigure.internal.SpiHelper; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.MeterProviderModel; @@ -57,7 +57,7 @@ void create_Configured() { SdkMeterProvider.builder() .registerMetricReader( io.opentelemetry.sdk.metrics.export.PeriodicMetricReader.builder( - OtlpGrpcMetricExporter.getDefault()) + OtlpHttpMetricExporter.getDefault()) .build()) .registerView( InstrumentSelector.builder().setName("instrument-name").build(), diff --git a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/MetricExporterFactoryTest.java b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/MetricExporterFactoryTest.java index 4f8b47f2e0c..0474bbcba6f 100644 --- a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/MetricExporterFactoryTest.java +++ b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/MetricExporterFactoryTest.java @@ -16,7 +16,6 @@ import com.linecorp.armeria.testing.junit5.server.SelfSignedCertificateExtension; import io.opentelemetry.exporter.logging.LoggingMetricExporter; import io.opentelemetry.exporter.otlp.http.metrics.OtlpHttpMetricExporter; -import io.opentelemetry.exporter.otlp.metrics.OtlpGrpcMetricExporter; import io.opentelemetry.internal.testing.CleanupExtension; import io.opentelemetry.sdk.autoconfigure.internal.SpiHelper; import io.opentelemetry.sdk.autoconfigure.spi.ConfigurationException; @@ -65,7 +64,7 @@ class MetricExporterFactoryTest { void create_OtlpDefaults() { spiHelper = spy(spiHelper); List closeables = new ArrayList<>(); - OtlpGrpcMetricExporter expectedExporter = OtlpGrpcMetricExporter.getDefault(); + OtlpHttpMetricExporter expectedExporter = OtlpHttpMetricExporter.getDefault(); cleanup.addCloseable(expectedExporter); MetricExporter exporter = diff --git a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/MetricReaderFactoryTest.java b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/MetricReaderFactoryTest.java index cde7a9db49b..db065d8c1cd 100644 --- a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/MetricReaderFactoryTest.java +++ b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/MetricReaderFactoryTest.java @@ -11,7 +11,7 @@ import static org.mockito.Mockito.verify; import io.github.netmikey.logunit.api.LogCapturer; -import io.opentelemetry.exporter.otlp.metrics.OtlpGrpcMetricExporter; +import io.opentelemetry.exporter.otlp.http.metrics.OtlpHttpMetricExporter; import io.opentelemetry.exporter.prometheus.PrometheusHttpServer; import io.opentelemetry.internal.testing.CleanupExtension; import io.opentelemetry.sdk.autoconfigure.internal.SpiHelper; @@ -62,7 +62,7 @@ void create_PeriodicDefaults() { List closeables = new ArrayList<>(); io.opentelemetry.sdk.metrics.export.PeriodicMetricReader expectedReader = io.opentelemetry.sdk.metrics.export.PeriodicMetricReader.builder( - OtlpGrpcMetricExporter.getDefault()) + OtlpHttpMetricExporter.getDefault()) .build(); cleanup.addCloseable(expectedReader); @@ -87,7 +87,7 @@ void create_PeriodicConfigured() { List closeables = new ArrayList<>(); io.opentelemetry.sdk.metrics.export.MetricReader expectedReader = io.opentelemetry.sdk.metrics.export.PeriodicMetricReader.builder( - OtlpGrpcMetricExporter.getDefault()) + OtlpHttpMetricExporter.getDefault()) .setInterval(Duration.ofMillis(1)) .build(); cleanup.addCloseable(expectedReader); diff --git a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/OpenTelemetryConfigurationFactoryTest.java b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/OpenTelemetryConfigurationFactoryTest.java index 5630ea99767..449eb59ab0d 100644 --- a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/OpenTelemetryConfigurationFactoryTest.java +++ b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/OpenTelemetryConfigurationFactoryTest.java @@ -13,9 +13,9 @@ import io.opentelemetry.api.trace.propagation.W3CTraceContextPropagator; import io.opentelemetry.context.propagation.ContextPropagators; import io.opentelemetry.context.propagation.TextMapPropagator; -import io.opentelemetry.exporter.otlp.logs.OtlpGrpcLogRecordExporter; -import io.opentelemetry.exporter.otlp.metrics.OtlpGrpcMetricExporter; -import io.opentelemetry.exporter.otlp.trace.OtlpGrpcSpanExporter; +import io.opentelemetry.exporter.otlp.http.logs.OtlpHttpLogRecordExporter; +import io.opentelemetry.exporter.otlp.http.metrics.OtlpHttpMetricExporter; +import io.opentelemetry.exporter.otlp.http.trace.OtlpHttpSpanExporter; import io.opentelemetry.extension.trace.propagation.B3Propagator; import io.opentelemetry.extension.trace.propagation.JaegerPropagator; import io.opentelemetry.extension.trace.propagation.OtTracePropagator; @@ -169,7 +169,7 @@ void create_Configured() { .build()) .addLogRecordProcessor( io.opentelemetry.sdk.logs.export.BatchLogRecordProcessor.builder( - OtlpGrpcLogRecordExporter.getDefault()) + OtlpHttpLogRecordExporter.getDefault()) .build()) .build()) .setTracerProvider( @@ -187,7 +187,7 @@ void create_Configured() { .setSampler(alwaysOn()) .addSpanProcessor( io.opentelemetry.sdk.trace.export.BatchSpanProcessor.builder( - OtlpGrpcSpanExporter.getDefault()) + OtlpHttpSpanExporter.getDefault()) .build()) .build()) .setMeterProvider( @@ -195,7 +195,7 @@ void create_Configured() { .setResource(expectedResource) .registerMetricReader( io.opentelemetry.sdk.metrics.export.PeriodicMetricReader.builder( - OtlpGrpcMetricExporter.getDefault()) + OtlpHttpMetricExporter.getDefault()) .build()) .registerView( InstrumentSelector.builder().setName("instrument-name").build(), diff --git a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/SpanExporterFactoryTest.java b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/SpanExporterFactoryTest.java index a6edf4039f1..bccfcc560c4 100644 --- a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/SpanExporterFactoryTest.java +++ b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/SpanExporterFactoryTest.java @@ -16,7 +16,6 @@ import com.linecorp.armeria.testing.junit5.server.SelfSignedCertificateExtension; import io.opentelemetry.exporter.logging.LoggingSpanExporter; import io.opentelemetry.exporter.otlp.http.trace.OtlpHttpSpanExporter; -import io.opentelemetry.exporter.otlp.trace.OtlpGrpcSpanExporter; import io.opentelemetry.exporter.zipkin.ZipkinSpanExporter; import io.opentelemetry.internal.testing.CleanupExtension; import io.opentelemetry.sdk.autoconfigure.internal.SpiHelper; @@ -63,7 +62,7 @@ class SpanExporterFactoryTest { void create_OtlpDefaults() { spiHelper = spy(spiHelper); List closeables = new ArrayList<>(); - OtlpGrpcSpanExporter expectedExporter = OtlpGrpcSpanExporter.getDefault(); + OtlpHttpSpanExporter expectedExporter = OtlpHttpSpanExporter.getDefault(); cleanup.addCloseable(expectedExporter); SpanExporter exporter = diff --git a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/SpanProcessorFactoryTest.java b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/SpanProcessorFactoryTest.java index 98af1e81ddc..6da913c6f65 100644 --- a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/SpanProcessorFactoryTest.java +++ b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/SpanProcessorFactoryTest.java @@ -9,7 +9,7 @@ import static org.assertj.core.api.Assertions.assertThatThrownBy; import com.google.common.collect.ImmutableMap; -import io.opentelemetry.exporter.otlp.trace.OtlpGrpcSpanExporter; +import io.opentelemetry.exporter.otlp.http.trace.OtlpHttpSpanExporter; import io.opentelemetry.internal.testing.CleanupExtension; import io.opentelemetry.sdk.autoconfigure.internal.SpiHelper; import io.opentelemetry.sdk.autoconfigure.spi.ConfigurationException; @@ -53,7 +53,7 @@ void create_BatchDefaults() { List closeables = new ArrayList<>(); io.opentelemetry.sdk.trace.export.BatchSpanProcessor expectedProcessor = io.opentelemetry.sdk.trace.export.BatchSpanProcessor.builder( - OtlpGrpcSpanExporter.getDefault()) + OtlpHttpSpanExporter.getDefault()) .build(); cleanup.addCloseable(expectedProcessor); @@ -77,7 +77,7 @@ void create_BatchConfigured() { List closeables = new ArrayList<>(); io.opentelemetry.sdk.trace.export.BatchSpanProcessor expectedProcessor = io.opentelemetry.sdk.trace.export.BatchSpanProcessor.builder( - OtlpGrpcSpanExporter.getDefault()) + OtlpHttpSpanExporter.getDefault()) .setScheduleDelay(Duration.ofMillis(1)) .setMaxExportBatchSize(2) .setExporterTimeout(Duration.ofMillis(3)) @@ -120,7 +120,7 @@ void create_SimpleConfigured() { List closeables = new ArrayList<>(); io.opentelemetry.sdk.trace.SpanProcessor expectedProcessor = io.opentelemetry.sdk.trace.export.SimpleSpanProcessor.create( - OtlpGrpcSpanExporter.getDefault()); + OtlpHttpSpanExporter.getDefault()); cleanup.addCloseable(expectedProcessor); io.opentelemetry.sdk.trace.SpanProcessor processor = diff --git a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/TracerProviderFactoryTest.java b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/TracerProviderFactoryTest.java index a46ac9cdd79..af6b3a20d07 100644 --- a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/TracerProviderFactoryTest.java +++ b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/TracerProviderFactoryTest.java @@ -8,7 +8,7 @@ import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.assertThat; import static io.opentelemetry.sdk.trace.samplers.Sampler.alwaysOn; -import io.opentelemetry.exporter.otlp.trace.OtlpGrpcSpanExporter; +import io.opentelemetry.exporter.otlp.http.trace.OtlpHttpSpanExporter; import io.opentelemetry.internal.testing.CleanupExtension; import io.opentelemetry.sdk.autoconfigure.internal.SpiHelper; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.AlwaysOnModel; @@ -95,7 +95,7 @@ private static Stream createArguments() { .setSampler(alwaysOn()) .addSpanProcessor( io.opentelemetry.sdk.trace.export.BatchSpanProcessor.builder( - OtlpGrpcSpanExporter.getDefault()) + OtlpHttpSpanExporter.getDefault()) .build()) .build())); } From 680c9406fda7a728abd7cb970a295ff4ab14932a Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 18 Oct 2024 16:34:53 -0700 Subject: [PATCH 617/901] fix(deps): update dependency com.uber.nullaway:nullaway to v0.12.0 (#6803) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- dependencyManagement/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index 806ed9abaa2..dbf409a427e 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -61,7 +61,7 @@ val DEPENDENCIES = listOf( "com.google.guava:guava-beta-checker:1.0", "com.sun.net.httpserver:http:20070405", "com.tngtech.archunit:archunit-junit5:1.3.0", - "com.uber.nullaway:nullaway:0.11.3", + "com.uber.nullaway:nullaway:0.12.0", "edu.berkeley.cs.jqf:jqf-fuzz:1.7", // jqf-fuzz version 1.8+ requires Java 11+ "eu.rekawek.toxiproxy:toxiproxy-java:2.1.7", "io.github.netmikey.logunit:logunit-jul:2.0.0", From 628db61339c4277160117543c23c9bf7a806989f Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 19 Oct 2024 11:40:36 -0700 Subject: [PATCH 618/901] fix(deps): update dependency com.google.errorprone:error_prone_annotations to v2.34.0 (#6804) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- dependencyManagement/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index dbf409a427e..07bc8c20cc9 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -25,7 +25,7 @@ val DEPENDENCY_BOMS = listOf( ) val autoValueVersion = "1.11.0" -val errorProneVersion = "2.33.0" +val errorProneVersion = "2.34.0" val jmhVersion = "1.37" // Mockito 5.x.x requires Java 11 https://github.com/mockito/mockito/releases/tag/v5.0.0 val mockitoVersion = "4.11.0" From 8793935d8fd07ad40dca7d991bd9b0ca23b7c74d Mon Sep 17 00:00:00 2001 From: jack-berg <34418638+jack-berg@users.noreply.github.com> Date: Tue, 22 Oct 2024 09:11:41 -0500 Subject: [PATCH 619/901] Add note about updating autoconfigure docs when releasing (#6811) --- RELEASING.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/RELEASING.md b/RELEASING.md index bbea33223bb..a6e7a29b68e 100644 --- a/RELEASING.md +++ b/RELEASING.md @@ -59,6 +59,9 @@ and deadlocks. in which case no pull request will be created). * The [website](https://github.com/open-telemetry/opentelemetry.io) contains automation to update to the newly released version. Review and approve the pull request when available. + * The [website](https://opentelemetry.io/docs/languages/java/configuration/#zero-code-sdk-autoconfigure) + contains documentation on autoconfiguration properties. If the release has updated or modified any + properties, open and merge a pull request to update the documentation. ## Update release versions in documentations From f52554bc52f7e3de6a11432e85ea53dec54f3ad0 Mon Sep 17 00:00:00 2001 From: jack-berg <34418638+jack-berg@users.noreply.github.com> Date: Tue, 22 Oct 2024 09:12:07 -0500 Subject: [PATCH 620/901] Rebrand file configuration to declarative configuration in documentation (#6812) --- ...tdoutLogRecordExporterComponentProvider.java | 2 +- ...lpStdoutMetricExporterComponentProvider.java | 2 +- ...OtlpStdoutSpanExporterComponentProvider.java | 2 +- ...nsoleLogRecordExporterComponentProvider.java | 2 +- .../ConsoleMetricExporterComponentProvider.java | 2 +- .../ConsoleSpanExporterComponentProvider.java | 2 +- .../OtlpLogRecordExporterComponentProvider.java | 2 +- .../OtlpMetricExporterComponentProvider.java | 2 +- .../OtlpSpanExporterComponentProvider.java | 2 +- .../internal/PrometheusComponentProvider.java | 2 +- .../ZipkinSpanExporterComponentProvider.java | 2 +- .../internal/B3ComponentProvider.java | 4 ++-- .../internal/B3MultiComponentProvider.java | 4 ++-- .../internal/JaegerComponentProvider.java | 2 +- .../internal/OtTraceComponentProvider.java | 2 +- .../spi/internal/ComponentProvider.java | 2 +- .../AutoConfiguredOpenTelemetrySdk.java | 6 +++--- .../AutoConfiguredOpenTelemetrySdkBuilder.java | 2 +- sdk-extensions/incubator/README.md | 17 +++++++++++++---- .../incubator/fileconfig/ResourceFactory.java | 2 +- .../YamlStructuredConfigProperties.java | 7 ++++--- .../YamlStructuredConfigPropertiesTest.java | 2 +- 22 files changed, 41 insertions(+), 31 deletions(-) diff --git a/exporters/logging-otlp/src/main/java/io/opentelemetry/exporter/logging/otlp/internal/logs/OtlpStdoutLogRecordExporterComponentProvider.java b/exporters/logging-otlp/src/main/java/io/opentelemetry/exporter/logging/otlp/internal/logs/OtlpStdoutLogRecordExporterComponentProvider.java index 8afd4e58c85..e80747a86ea 100644 --- a/exporters/logging-otlp/src/main/java/io/opentelemetry/exporter/logging/otlp/internal/logs/OtlpStdoutLogRecordExporterComponentProvider.java +++ b/exporters/logging-otlp/src/main/java/io/opentelemetry/exporter/logging/otlp/internal/logs/OtlpStdoutLogRecordExporterComponentProvider.java @@ -11,7 +11,7 @@ import io.opentelemetry.sdk.logs.export.LogRecordExporter; /** - * File configuration SPI implementation for {@link OtlpStdoutLogRecordExporter}. + * Declarative configuration SPI implementation for {@link OtlpStdoutLogRecordExporter}. * *

      This class is internal and is hence not for public use. Its APIs are unstable and can change * at any time. diff --git a/exporters/logging-otlp/src/main/java/io/opentelemetry/exporter/logging/otlp/internal/metrics/OtlpStdoutMetricExporterComponentProvider.java b/exporters/logging-otlp/src/main/java/io/opentelemetry/exporter/logging/otlp/internal/metrics/OtlpStdoutMetricExporterComponentProvider.java index e1e2dc88153..2a69bd0c7d1 100644 --- a/exporters/logging-otlp/src/main/java/io/opentelemetry/exporter/logging/otlp/internal/metrics/OtlpStdoutMetricExporterComponentProvider.java +++ b/exporters/logging-otlp/src/main/java/io/opentelemetry/exporter/logging/otlp/internal/metrics/OtlpStdoutMetricExporterComponentProvider.java @@ -11,7 +11,7 @@ import io.opentelemetry.sdk.metrics.export.MetricExporter; /** - * File configuration SPI implementation for {@link OtlpStdoutMetricExporter}. + * Declarative configuration SPI implementation for {@link OtlpStdoutMetricExporter}. * *

      This class is internal and is hence not for public use. Its APIs are unstable and can change * at any time. diff --git a/exporters/logging-otlp/src/main/java/io/opentelemetry/exporter/logging/otlp/internal/traces/OtlpStdoutSpanExporterComponentProvider.java b/exporters/logging-otlp/src/main/java/io/opentelemetry/exporter/logging/otlp/internal/traces/OtlpStdoutSpanExporterComponentProvider.java index af299c16251..c21029ed133 100644 --- a/exporters/logging-otlp/src/main/java/io/opentelemetry/exporter/logging/otlp/internal/traces/OtlpStdoutSpanExporterComponentProvider.java +++ b/exporters/logging-otlp/src/main/java/io/opentelemetry/exporter/logging/otlp/internal/traces/OtlpStdoutSpanExporterComponentProvider.java @@ -11,7 +11,7 @@ import io.opentelemetry.sdk.trace.export.SpanExporter; /** - * File configuration SPI implementation for {@link OtlpStdoutSpanExporter}. + * Declarative configuration SPI implementation for {@link OtlpStdoutSpanExporter}. * *

      This class is internal and is hence not for public use. Its APIs are unstable and can change * at any time. diff --git a/exporters/logging/src/main/java/io/opentelemetry/exporter/logging/internal/ConsoleLogRecordExporterComponentProvider.java b/exporters/logging/src/main/java/io/opentelemetry/exporter/logging/internal/ConsoleLogRecordExporterComponentProvider.java index 4d03480b335..8c9d048c3b0 100644 --- a/exporters/logging/src/main/java/io/opentelemetry/exporter/logging/internal/ConsoleLogRecordExporterComponentProvider.java +++ b/exporters/logging/src/main/java/io/opentelemetry/exporter/logging/internal/ConsoleLogRecordExporterComponentProvider.java @@ -11,7 +11,7 @@ import io.opentelemetry.sdk.logs.export.LogRecordExporter; /** - * File configuration SPI implementation for {@link SystemOutLogRecordExporter}. + * Declarative configuration SPI implementation for {@link SystemOutLogRecordExporter}. * *

      This class is internal and is hence not for public use. Its APIs are unstable and can change * at any time. diff --git a/exporters/logging/src/main/java/io/opentelemetry/exporter/logging/internal/ConsoleMetricExporterComponentProvider.java b/exporters/logging/src/main/java/io/opentelemetry/exporter/logging/internal/ConsoleMetricExporterComponentProvider.java index 48a449ff0f0..df5270ca11a 100644 --- a/exporters/logging/src/main/java/io/opentelemetry/exporter/logging/internal/ConsoleMetricExporterComponentProvider.java +++ b/exporters/logging/src/main/java/io/opentelemetry/exporter/logging/internal/ConsoleMetricExporterComponentProvider.java @@ -11,7 +11,7 @@ import io.opentelemetry.sdk.metrics.export.MetricExporter; /** - * File configuration SPI implementation for {@link LoggingMetricExporter}. + * Declarative configuration SPI implementation for {@link LoggingMetricExporter}. * *

      This class is internal and is hence not for public use. Its APIs are unstable and can change * at any time. diff --git a/exporters/logging/src/main/java/io/opentelemetry/exporter/logging/internal/ConsoleSpanExporterComponentProvider.java b/exporters/logging/src/main/java/io/opentelemetry/exporter/logging/internal/ConsoleSpanExporterComponentProvider.java index c212a77d5d4..a6fa1950bdf 100644 --- a/exporters/logging/src/main/java/io/opentelemetry/exporter/logging/internal/ConsoleSpanExporterComponentProvider.java +++ b/exporters/logging/src/main/java/io/opentelemetry/exporter/logging/internal/ConsoleSpanExporterComponentProvider.java @@ -11,7 +11,7 @@ import io.opentelemetry.sdk.trace.export.SpanExporter; /** - * File configuration SPI implementation for {@link LoggingSpanExporter}. + * Declarative configuration SPI implementation for {@link LoggingSpanExporter}. * *

      This class is internal and is hence not for public use. Its APIs are unstable and can change * at any time. diff --git a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/OtlpLogRecordExporterComponentProvider.java b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/OtlpLogRecordExporterComponentProvider.java index cd7d97a1d46..9134976e495 100644 --- a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/OtlpLogRecordExporterComponentProvider.java +++ b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/OtlpLogRecordExporterComponentProvider.java @@ -19,7 +19,7 @@ import io.opentelemetry.sdk.logs.export.LogRecordExporter; /** - * File configuration SPI implementation for {@link OtlpHttpLogRecordExporter} and {@link + * Declarative configuration SPI implementation for {@link OtlpHttpLogRecordExporter} and {@link * OtlpGrpcLogRecordExporter}. * *

      This class is internal and is hence not for public use. Its APIs are unstable and can change diff --git a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/OtlpMetricExporterComponentProvider.java b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/OtlpMetricExporterComponentProvider.java index 2bbec38c533..a08cab883b1 100644 --- a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/OtlpMetricExporterComponentProvider.java +++ b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/OtlpMetricExporterComponentProvider.java @@ -20,7 +20,7 @@ import io.opentelemetry.sdk.metrics.export.MetricExporter; /** - * File configuration SPI implementation for {@link OtlpHttpMetricExporter} and {@link + * Declarative configuration SPI implementation for {@link OtlpHttpMetricExporter} and {@link * OtlpGrpcMetricExporter}. * *

      This class is internal and is hence not for public use. Its APIs are unstable and can change diff --git a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/OtlpSpanExporterComponentProvider.java b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/OtlpSpanExporterComponentProvider.java index 707ff0c4383..1f84115b252 100644 --- a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/OtlpSpanExporterComponentProvider.java +++ b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/OtlpSpanExporterComponentProvider.java @@ -19,7 +19,7 @@ import io.opentelemetry.sdk.trace.export.SpanExporter; /** - * File configuration SPI implementation for {@link OtlpHttpSpanExporter} and {@link + * Declarative configuration SPI implementation for {@link OtlpHttpSpanExporter} and {@link * OtlpGrpcSpanExporter}. * *

      This class is internal and is hence not for public use. Its APIs are unstable and can change diff --git a/exporters/prometheus/src/main/java/io/opentelemetry/exporter/prometheus/internal/PrometheusComponentProvider.java b/exporters/prometheus/src/main/java/io/opentelemetry/exporter/prometheus/internal/PrometheusComponentProvider.java index dc57d2bcbe3..7599619a3a5 100644 --- a/exporters/prometheus/src/main/java/io/opentelemetry/exporter/prometheus/internal/PrometheusComponentProvider.java +++ b/exporters/prometheus/src/main/java/io/opentelemetry/exporter/prometheus/internal/PrometheusComponentProvider.java @@ -12,7 +12,7 @@ import io.opentelemetry.sdk.metrics.export.MetricReader; /** - * File configuration SPI implementation for {@link PrometheusHttpServer}. + * Declarative configuration SPI implementation for {@link PrometheusHttpServer}. * *

      This class is internal and is hence not for public use. Its APIs are unstable and can change * at any time. diff --git a/exporters/zipkin/src/main/java/io/opentelemetry/exporter/zipkin/internal/ZipkinSpanExporterComponentProvider.java b/exporters/zipkin/src/main/java/io/opentelemetry/exporter/zipkin/internal/ZipkinSpanExporterComponentProvider.java index eafd62479f0..f539a8ecde6 100644 --- a/exporters/zipkin/src/main/java/io/opentelemetry/exporter/zipkin/internal/ZipkinSpanExporterComponentProvider.java +++ b/exporters/zipkin/src/main/java/io/opentelemetry/exporter/zipkin/internal/ZipkinSpanExporterComponentProvider.java @@ -13,7 +13,7 @@ import java.time.Duration; /** - * File configuration SPI implementation for {@link ZipkinSpanExporter}. + * Declarative configuration SPI implementation for {@link ZipkinSpanExporter}. * *

      This class is internal and is hence not for public use. Its APIs are unstable and can change * at any time. diff --git a/extensions/trace-propagators/src/main/java/io/opentelemetry/extension/trace/propagation/internal/B3ComponentProvider.java b/extensions/trace-propagators/src/main/java/io/opentelemetry/extension/trace/propagation/internal/B3ComponentProvider.java index b97134eda7a..ba42a1fd07e 100644 --- a/extensions/trace-propagators/src/main/java/io/opentelemetry/extension/trace/propagation/internal/B3ComponentProvider.java +++ b/extensions/trace-propagators/src/main/java/io/opentelemetry/extension/trace/propagation/internal/B3ComponentProvider.java @@ -11,8 +11,8 @@ import io.opentelemetry.sdk.autoconfigure.spi.internal.StructuredConfigProperties; /** - * File configuration SPI implementation for {@link B3Propagator} which allows enables the {@link - * B3Propagator#injectingSingleHeader()}. + * Declarative configuration SPI implementation for {@link B3Propagator} which allows enables the + * {@link B3Propagator#injectingSingleHeader()}. * *

      This class is internal and is hence not for public use. Its APIs are unstable and can change * at any time. diff --git a/extensions/trace-propagators/src/main/java/io/opentelemetry/extension/trace/propagation/internal/B3MultiComponentProvider.java b/extensions/trace-propagators/src/main/java/io/opentelemetry/extension/trace/propagation/internal/B3MultiComponentProvider.java index 77ac501a2ea..a95e195621c 100644 --- a/extensions/trace-propagators/src/main/java/io/opentelemetry/extension/trace/propagation/internal/B3MultiComponentProvider.java +++ b/extensions/trace-propagators/src/main/java/io/opentelemetry/extension/trace/propagation/internal/B3MultiComponentProvider.java @@ -11,8 +11,8 @@ import io.opentelemetry.sdk.autoconfigure.spi.internal.StructuredConfigProperties; /** - * File configuration SPI implementation for {@link B3Propagator} which allows enables the {@link - * B3Propagator#injectingMultiHeaders()}. + * Declarative configuration SPI implementation for {@link B3Propagator} which allows enables the + * {@link B3Propagator#injectingMultiHeaders()}. * *

      This class is internal and is hence not for public use. Its APIs are unstable and can change * at any time. diff --git a/extensions/trace-propagators/src/main/java/io/opentelemetry/extension/trace/propagation/internal/JaegerComponentProvider.java b/extensions/trace-propagators/src/main/java/io/opentelemetry/extension/trace/propagation/internal/JaegerComponentProvider.java index 0fb844a40da..d3e3111b3fd 100644 --- a/extensions/trace-propagators/src/main/java/io/opentelemetry/extension/trace/propagation/internal/JaegerComponentProvider.java +++ b/extensions/trace-propagators/src/main/java/io/opentelemetry/extension/trace/propagation/internal/JaegerComponentProvider.java @@ -11,7 +11,7 @@ import io.opentelemetry.sdk.autoconfigure.spi.internal.StructuredConfigProperties; /** - * File configuration SPI implementation for {@link JaegerPropagator}. + * Declarative configuration SPI implementation for {@link JaegerPropagator}. * *

      This class is internal and is hence not for public use. Its APIs are unstable and can change * at any time. diff --git a/extensions/trace-propagators/src/main/java/io/opentelemetry/extension/trace/propagation/internal/OtTraceComponentProvider.java b/extensions/trace-propagators/src/main/java/io/opentelemetry/extension/trace/propagation/internal/OtTraceComponentProvider.java index 97b41aad3af..3e4f978f626 100644 --- a/extensions/trace-propagators/src/main/java/io/opentelemetry/extension/trace/propagation/internal/OtTraceComponentProvider.java +++ b/extensions/trace-propagators/src/main/java/io/opentelemetry/extension/trace/propagation/internal/OtTraceComponentProvider.java @@ -12,7 +12,7 @@ import io.opentelemetry.sdk.autoconfigure.spi.internal.StructuredConfigProperties; /** - * File configuration SPI implementation for {@link B3Propagator}. + * Declarative configuration SPI implementation for {@link B3Propagator}. * *

      This class is internal and is hence not for public use. Its APIs are unstable and can change * at any time. diff --git a/sdk-extensions/autoconfigure-spi/src/main/java/io/opentelemetry/sdk/autoconfigure/spi/internal/ComponentProvider.java b/sdk-extensions/autoconfigure-spi/src/main/java/io/opentelemetry/sdk/autoconfigure/spi/internal/ComponentProvider.java index 335c9a7c0ab..b7f93b615db 100644 --- a/sdk-extensions/autoconfigure-spi/src/main/java/io/opentelemetry/sdk/autoconfigure/spi/internal/ComponentProvider.java +++ b/sdk-extensions/autoconfigure-spi/src/main/java/io/opentelemetry/sdk/autoconfigure/spi/internal/ComponentProvider.java @@ -16,7 +16,7 @@ /** * Provides configured instances of SDK extension components. {@link ComponentProvider} allows SDK - * extension components which are not part of the core SDK to be referenced in file based + * extension components which are not part of the core SDK to be referenced in declarative based * configuration. * *

      NOTE: when {@link #getType()} is {@link Resource}, the {@link #getName()} is not (currently) diff --git a/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/AutoConfiguredOpenTelemetrySdk.java b/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/AutoConfiguredOpenTelemetrySdk.java index 6751da7ad7f..666da0f89c7 100644 --- a/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/AutoConfiguredOpenTelemetrySdk.java +++ b/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/AutoConfiguredOpenTelemetrySdk.java @@ -67,8 +67,8 @@ static AutoConfiguredOpenTelemetrySdk create( abstract Resource getResource(); /** - * Returns the {@link ConfigProperties} used for auto-configuration, or {@code null} if file - * configuration was used. + * Returns the {@link ConfigProperties} used for auto-configuration, or {@code null} if + * declarative configuration was used. * * @see #getStructuredConfig() */ @@ -77,7 +77,7 @@ static AutoConfiguredOpenTelemetrySdk create( /** * Returns the {@link StructuredConfigProperties} used for auto-configuration, or {@code null} if - * file configuration was not used. + * declarative configuration was not used. * * @see #getConfig() */ diff --git a/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/AutoConfiguredOpenTelemetrySdkBuilder.java b/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/AutoConfiguredOpenTelemetrySdkBuilder.java index 030045ea52d..995417b8fd7 100644 --- a/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/AutoConfiguredOpenTelemetrySdkBuilder.java +++ b/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/AutoConfiguredOpenTelemetrySdkBuilder.java @@ -563,7 +563,7 @@ private static AutoConfiguredOpenTelemetrySdk maybeConfigureFromFile( configurationFactory.getMethod("toConfigProperties", openTelemetryConfiguration); StructuredConfigProperties structuredConfigProperties = (StructuredConfigProperties) toConfigProperties.invoke(null, model); - // Note: can't access file configuration resource without reflection so setting a dummy + // Note: can't access declarative configuration resource without reflection so setting a dummy // resource return AutoConfiguredOpenTelemetrySdk.create( sdk, Resource.getDefault(), null, structuredConfigProperties); diff --git a/sdk-extensions/incubator/README.md b/sdk-extensions/incubator/README.md index abdb90cf9a7..1938182c9e3 100644 --- a/sdk-extensions/incubator/README.md +++ b/sdk-extensions/incubator/README.md @@ -2,9 +2,9 @@ This artifact contains experimental code related to the trace and metric SDKs. -## File Configuration +## Declarative Configuration -Allows for YAML based file configuration of `OpenTelemetrySdk` as defined in the [specification](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/configuration/data-model.md#file-based-configuration-model). +The [declarative configuration interface](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/configuration/README.md#declarative-configuration) allows for YAML based file configuration of `OpenTelemetrySdk`. Usage: @@ -19,8 +19,17 @@ try (FileInputStream yamlConfigFileInputStream = new FileInputStream("/path/to/c Notes: * Environment variable substitution is supported as [defined in the spec](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/configuration/data-model.md#environment-variable-substitution) -* Currently, there is no support for the SPIs defined in [opentelemetry-sdk-extension-autoconfigure-spi](../autoconfigure-spi). Only built in samplers, processors, exporters, etc can be configured. -* You can use file configuration with [autoconfigure](https://github.com/open-telemetry/opentelemetry-java/tree/main/sdk-extensions/autoconfigure#file-configuration) to specify a configuration file via environment variable, e.g. `OTEL_EXPERIMENTAL_CONFIG_FILE=/path/to/config.yaml`. +* Currently, there is no support for the customization (i.e. `AutoConfigurationCustomizerProvider`) SPIs defined in [opentelemetry-sdk-extension-autoconfigure-spi](../autoconfigure-spi). +* Custom SDK extension components which reference the [ComponentProvider](https://github.com/open-telemetry/opentelemetry-java/blob/main/sdk-extensions/autoconfigure-spi/src/main/java/io/opentelemetry/sdk/autoconfigure/spi/internal/ComponentProvider.java) SPI can be referenced in declarative configuration. Supported types include: + * `Resource` + * `SpanExporter` + * `MetricExporter` + * `LogRecordExporter` + * `SpanProcessor` + * `LogRecordProcessor` + * `TextMapPropagator` + * `Sampler` +* You can use declarative configuration with [autoconfigure](https://opentelemetry.io/docs/languages/java/configuration/#declarative-configuration) to specify a configuration file via environment variable, e.g. `OTEL_EXPERIMENTAL_CONFIG_FILE=/path/to/config.yaml`. ## View File Configuration diff --git a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/ResourceFactory.java b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/ResourceFactory.java index 8f26e6a47e7..0f3a8164c9f 100644 --- a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/ResourceFactory.java +++ b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/ResourceFactory.java @@ -88,7 +88,7 @@ public Resource create( /** * Load resources from resource detectors, in order of lowest priority to highest priority. * - *

      In file configuration, a resource detector is a {@link ComponentProvider} with {@link + *

      In declarative configuration, a resource detector is a {@link ComponentProvider} with {@link * ComponentProvider#getType()} set to {@link Resource}. Unlike other {@link ComponentProvider}s, * the resource detector version does not use {@link ComponentProvider#getName()} (except for * debug messages), and {@link ComponentProvider#create(StructuredConfigProperties)} is called diff --git a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/YamlStructuredConfigProperties.java b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/YamlStructuredConfigProperties.java index 87cbc5f8fc8..f302ee5c805 100644 --- a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/YamlStructuredConfigProperties.java +++ b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/YamlStructuredConfigProperties.java @@ -24,12 +24,13 @@ import javax.annotation.Nullable; /** - * Implementation of {@link StructuredConfigProperties} which uses a file configuration model as a - * source. + * Implementation of {@link StructuredConfigProperties} which uses a declarative configuration model + * as a source. * * @see #getStructured(String) Accessing nested maps * @see #getStructuredList(String) Accessing lists of maps - * @see FileConfiguration#toConfigProperties(Object) Converting configuration model to properties + * @see FileConfiguration#toConfigProperties(Object, ComponentLoader) Converting configuration model + * to properties */ final class YamlStructuredConfigProperties implements StructuredConfigProperties { diff --git a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/YamlStructuredConfigPropertiesTest.java b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/YamlStructuredConfigPropertiesTest.java index 25f9a877c95..3bbd11bcef5 100644 --- a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/YamlStructuredConfigPropertiesTest.java +++ b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/YamlStructuredConfigPropertiesTest.java @@ -68,7 +68,7 @@ void setup() { @Test void configurationSchema() { - // Validate can read file configuration schema properties + // Validate can read declarative configuration schema properties assertThat(structuredConfigProps.getString("file_format")).isEqualTo("0.3"); StructuredConfigProperties resourceProps = structuredConfigProps.getStructured("resource"); assertThat(resourceProps).isNotNull(); From 45b8c13b120bc5c3ebeca3e46414dc998f6c9a1a Mon Sep 17 00:00:00 2001 From: jack-berg <34418638+jack-berg@users.noreply.github.com> Date: Tue, 22 Oct 2024 09:30:08 -0500 Subject: [PATCH 621/901] Log a warning if OTLP endpoint port is likely incorrect given the protocol (#6813) --- .../otlp/internal/OtlpConfigUtil.java | 25 +++++++++- .../otlp/internal/OtlpConfigUtilTest.java | 50 +++++++++++++++++++ 2 files changed, 73 insertions(+), 2 deletions(-) diff --git a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/OtlpConfigUtil.java b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/OtlpConfigUtil.java index 4a653aea6ee..5040280850f 100644 --- a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/OtlpConfigUtil.java +++ b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/OtlpConfigUtil.java @@ -25,6 +25,7 @@ import java.util.Map; import java.util.function.BiConsumer; import java.util.function.Consumer; +import java.util.logging.Logger; import javax.annotation.Nullable; /** @@ -33,6 +34,8 @@ */ public final class OtlpConfigUtil { + private static final Logger logger = Logger.getLogger(OtlpConfigUtil.class.getName()); + public static final String DATA_TYPE_TRACES = "traces"; public static final String DATA_TYPE_METRICS = "metrics"; public static final String DATA_TYPE_LOGS = "logs"; @@ -263,7 +266,7 @@ private static URL createUrl(URL context, String spec) { } @Nullable - private static URL validateEndpoint(@Nullable String endpoint, boolean allowPath) { + private static URL validateEndpoint(@Nullable String endpoint, boolean isHttpProtobuf) { if (endpoint == null) { return null; } @@ -285,10 +288,28 @@ private static URL validateEndpoint(@Nullable String endpoint, boolean allowPath throw new ConfigurationException( "OTLP endpoint must not have a fragment: " + endpointUrl.getRef()); } - if (!allowPath && (!endpointUrl.getPath().isEmpty() && !endpointUrl.getPath().equals("/"))) { + if (!isHttpProtobuf + && (!endpointUrl.getPath().isEmpty() && !endpointUrl.getPath().equals("/"))) { throw new ConfigurationException( "OTLP endpoint must not have a path: " + endpointUrl.getPath()); } + if ((endpointUrl.getPort() == 4317 && isHttpProtobuf) + || (endpointUrl.getPort() == 4318 && !isHttpProtobuf)) { + int expectedPort = isHttpProtobuf ? 4318 : 4317; + String protocol = isHttpProtobuf ? PROTOCOL_HTTP_PROTOBUF : PROTOCOL_GRPC; + logger.warning( + "OTLP exporter endpoint port is likely incorrect for protocol version \"" + + protocol + + "\". The endpoint " + + endpointUrl + + " has port " + + endpointUrl.getPort() + + ". Typically, the \"" + + protocol + + "\" version of OTLP uses port " + + expectedPort + + "."); + } return endpointUrl; } diff --git a/exporters/otlp/all/src/test/java/io/opentelemetry/exporter/otlp/internal/OtlpConfigUtilTest.java b/exporters/otlp/all/src/test/java/io/opentelemetry/exporter/otlp/internal/OtlpConfigUtilTest.java index 25a0d5cf7ee..5716d604ec0 100644 --- a/exporters/otlp/all/src/test/java/io/opentelemetry/exporter/otlp/internal/OtlpConfigUtilTest.java +++ b/exporters/otlp/all/src/test/java/io/opentelemetry/exporter/otlp/internal/OtlpConfigUtilTest.java @@ -11,11 +11,14 @@ import static io.opentelemetry.exporter.otlp.internal.OtlpConfigUtil.PROTOCOL_GRPC; import static io.opentelemetry.exporter.otlp.internal.OtlpConfigUtil.PROTOCOL_HTTP_PROTOBUF; import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.assertThat; +import static java.util.stream.Collectors.toList; import static org.assertj.core.api.Assertions.assertThatCode; import static org.assertj.core.api.Assertions.assertThatThrownBy; import com.google.common.collect.ImmutableMap; +import io.github.netmikey.logunit.api.LogCapturer; import io.opentelemetry.exporter.internal.ExporterBuilderUtil; +import io.opentelemetry.internal.testing.slf4j.SuppressLogger; import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties; import io.opentelemetry.sdk.autoconfigure.spi.ConfigurationException; import io.opentelemetry.sdk.autoconfigure.spi.internal.DefaultConfigProperties; @@ -25,13 +28,24 @@ import io.opentelemetry.sdk.metrics.export.AggregationTemporalitySelector; import io.opentelemetry.sdk.metrics.export.DefaultAggregationSelector; import java.util.Collections; +import java.util.List; import java.util.Map; import java.util.concurrent.atomic.AtomicReference; +import java.util.stream.Stream; +import javax.annotation.Nullable; import org.assertj.core.api.ThrowableAssert.ThrowingCallable; import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; +import org.slf4j.event.LoggingEvent; class OtlpConfigUtilTest { + @RegisterExtension + final LogCapturer logs = LogCapturer.create().captureForType(OtlpConfigUtil.class); + private static final String GENERIC_ENDPOINT_KEY = "otel.exporter.otlp.endpoint"; private static final String TRACES_ENDPOINT_KEY = "otel.exporter.otlp.traces.endpoint"; private static final String METRICS_ENDPOINT_KEY = "otel.exporter.otlp.metrics.endpoint"; @@ -122,6 +136,42 @@ void configureOtlpExporterBuilder_InvalidEndpoints() { .hasMessageContaining("OTLP endpoint must not have a path:"); } + @SuppressLogger(OtlpConfigUtil.class) + @ParameterizedTest + @MethodSource("misalignedOtlpPortArgs") + void configureOtlpExporterBuilder_MisalignedOtlpPort( + String protocol, String endpoint, @Nullable String expectedLog) { + configureEndpoint( + DATA_TYPE_TRACES, + ImmutableMap.of(GENERIC_ENDPOINT_KEY, endpoint, "otel.exporter.otlp.protocol", protocol)); + + List logMessages = + logs.getEvents().stream().map(LoggingEvent::getMessage).collect(toList()); + if (expectedLog == null) { + assertThat(logMessages).isEmpty(); + } else { + assertThat(logMessages).contains(expectedLog); + } + } + + private static Stream misalignedOtlpPortArgs() { + return Stream.of( + Arguments.of("http/protobuf", "http://localhost:4318/path", null), + Arguments.of("http/protobuf", "http://localhost:8080/path", null), + Arguments.of("http/protobuf", "http://localhost/path", null), + Arguments.of( + "http/protobuf", + "http://localhost:4317/path", + "OTLP exporter endpoint port is likely incorrect for protocol version \"http/protobuf\". The endpoint http://localhost:4317/path has port 4317. Typically, the \"http/protobuf\" version of OTLP uses port 4318."), + Arguments.of("grpc", "http://localhost:4317/", null), + Arguments.of("grpc", "http://localhost:8080/", null), + Arguments.of("grpc", "http://localhost/", null), + Arguments.of( + "grpc", + "http://localhost:4318/", + "OTLP exporter endpoint port is likely incorrect for protocol version \"grpc\". The endpoint http://localhost:4318/ has port 4318. Typically, the \"grpc\" version of OTLP uses port 4317.")); + } + private static ThrowingCallable configureEndpointCallable(Map properties) { return () -> configureEndpoint(DATA_TYPE_TRACES, properties); } From 5ec1e8688e4c036e8e4a9af38cf18c81863988a5 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 22 Oct 2024 13:09:18 -0700 Subject: [PATCH 622/901] fix(deps): update dependency org.junit:junit-bom to v5.11.3 (#6810) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- dependencyManagement/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index 07bc8c20cc9..ab2eec59905 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -19,7 +19,7 @@ val DEPENDENCY_BOMS = listOf( "io.zipkin.brave:brave-bom:6.0.3", "io.zipkin.reporter2:zipkin-reporter-bom:3.4.2", "org.assertj:assertj-bom:3.26.3", - "org.junit:junit-bom:5.11.2", + "org.junit:junit-bom:5.11.3", "org.testcontainers:testcontainers-bom:1.20.2", "org.snakeyaml:snakeyaml-engine:2.8" ) From 10bca8b2b2482e83272c8cfc353ede89999a84ce Mon Sep 17 00:00:00 2001 From: jack-berg <34418638+jack-berg@users.noreply.github.com> Date: Wed, 23 Oct 2024 14:28:41 -0500 Subject: [PATCH 623/901] Enable reusuable_data memory mode by default (#6799) --- .../internal/ExporterBuilderUtil.java | 12 +++++++++++- .../OtlpHttpLogRecordExporterBuilder.java | 2 +- .../OtlpHttpMetricExporterBuilder.java | 2 +- .../trace/OtlpHttpSpanExporterBuilder.java | 2 +- .../OtlpGrpcLogRecordExporterBuilder.java | 2 +- .../OtlpGrpcMetricExporterBuilder.java | 2 +- .../trace/OtlpGrpcSpanExporterBuilder.java | 2 +- .../OtlpLogRecordExporterProviderTest.java | 12 ++++++------ .../OtlpMetricExporterProviderTest.java | 12 ++++++------ .../OtlpSpanExporterProviderTest.java | 14 +++++++------- .../testing/internal/FakeTelemetryUtil.java | 19 ++++++++----------- .../prometheus/PrometheusHttpServer.java | 11 +++++++++-- .../PrometheusHttpServerBuilder.java | 8 +++++++- .../prometheus/PrometheusHttpServerTest.java | 4 +++- .../PrometheusMetricReaderProviderTest.java | 6 +++--- 15 files changed, 66 insertions(+), 44 deletions(-) diff --git a/exporters/common/src/main/java/io/opentelemetry/exporter/internal/ExporterBuilderUtil.java b/exporters/common/src/main/java/io/opentelemetry/exporter/internal/ExporterBuilderUtil.java index 4e05183bb1a..9e3a1fcf266 100644 --- a/exporters/common/src/main/java/io/opentelemetry/exporter/internal/ExporterBuilderUtil.java +++ b/exporters/common/src/main/java/io/opentelemetry/exporter/internal/ExporterBuilderUtil.java @@ -21,6 +21,7 @@ import java.net.URISyntaxException; import java.util.Locale; import java.util.function.Consumer; +import java.util.logging.Logger; /** * Utilities for exporter builders. @@ -30,6 +31,8 @@ */ public final class ExporterBuilderUtil { + private static final Logger logger = Logger.getLogger(ExporterBuilderUtil.class.getName()); + /** Validate OTLP endpoint. */ public static URI validateEndpoint(String endpoint) { URI uri; @@ -50,7 +53,14 @@ public static URI validateEndpoint(String endpoint) { /** Invoke the {@code memoryModeConsumer} with the configured {@link MemoryMode}. */ public static void configureExporterMemoryMode( ConfigProperties config, Consumer memoryModeConsumer) { - String memoryModeStr = config.getString("otel.java.experimental.exporter.memory_mode"); + String memoryModeStr = config.getString("otel.java.exporter.memory_mode"); + if (memoryModeStr == null) { + memoryModeStr = config.getString("otel.java.experimental.exporter.memory_mode"); + if (memoryModeStr != null) { + logger.warning( + "otel.java.experimental.exporter.memory_mode was set but has been replaced with otel.java.exporter.memory_mode and will be removed in a future release"); + } + } if (memoryModeStr == null) { return; } diff --git a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/logs/OtlpHttpLogRecordExporterBuilder.java b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/logs/OtlpHttpLogRecordExporterBuilder.java index 0d2654051f4..0602cf2b506 100644 --- a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/logs/OtlpHttpLogRecordExporterBuilder.java +++ b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/logs/OtlpHttpLogRecordExporterBuilder.java @@ -35,7 +35,7 @@ public final class OtlpHttpLogRecordExporterBuilder { private static final String DEFAULT_ENDPOINT = "http://localhost:4318/v1/logs"; - private static final MemoryMode DEFAULT_MEMORY_MODE = MemoryMode.IMMUTABLE_DATA; + private static final MemoryMode DEFAULT_MEMORY_MODE = MemoryMode.REUSABLE_DATA; private final HttpExporterBuilder delegate; private MemoryMode memoryMode; diff --git a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/metrics/OtlpHttpMetricExporterBuilder.java b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/metrics/OtlpHttpMetricExporterBuilder.java index 49a1c45183d..e0cb6f4a493 100644 --- a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/metrics/OtlpHttpMetricExporterBuilder.java +++ b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/metrics/OtlpHttpMetricExporterBuilder.java @@ -43,7 +43,7 @@ public final class OtlpHttpMetricExporterBuilder { private static final AggregationTemporalitySelector DEFAULT_AGGREGATION_TEMPORALITY_SELECTOR = AggregationTemporalitySelector.alwaysCumulative(); - private static final MemoryMode DEFAULT_MEMORY_MODE = MemoryMode.IMMUTABLE_DATA; + private static final MemoryMode DEFAULT_MEMORY_MODE = MemoryMode.REUSABLE_DATA; private final HttpExporterBuilder delegate; private AggregationTemporalitySelector aggregationTemporalitySelector = diff --git a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/trace/OtlpHttpSpanExporterBuilder.java b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/trace/OtlpHttpSpanExporterBuilder.java index fe91ceb6da7..fb547af942a 100644 --- a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/trace/OtlpHttpSpanExporterBuilder.java +++ b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/trace/OtlpHttpSpanExporterBuilder.java @@ -35,7 +35,7 @@ public final class OtlpHttpSpanExporterBuilder { private static final String DEFAULT_ENDPOINT = "http://localhost:4318/v1/traces"; - private static final MemoryMode DEFAULT_MEMORY_MODE = MemoryMode.IMMUTABLE_DATA; + private static final MemoryMode DEFAULT_MEMORY_MODE = MemoryMode.REUSABLE_DATA; private final HttpExporterBuilder delegate; private MemoryMode memoryMode; diff --git a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/logs/OtlpGrpcLogRecordExporterBuilder.java b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/logs/OtlpGrpcLogRecordExporterBuilder.java index 8f082855b75..2ab6e29be09 100644 --- a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/logs/OtlpGrpcLogRecordExporterBuilder.java +++ b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/logs/OtlpGrpcLogRecordExporterBuilder.java @@ -43,7 +43,7 @@ public final class OtlpGrpcLogRecordExporterBuilder { private static final String DEFAULT_ENDPOINT_URL = "http://localhost:4317"; private static final URI DEFAULT_ENDPOINT = URI.create(DEFAULT_ENDPOINT_URL); private static final long DEFAULT_TIMEOUT_SECS = 10; - private static final MemoryMode DEFAULT_MEMORY_MODE = MemoryMode.IMMUTABLE_DATA; + private static final MemoryMode DEFAULT_MEMORY_MODE = MemoryMode.REUSABLE_DATA; // Visible for testing final GrpcExporterBuilder delegate; diff --git a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/metrics/OtlpGrpcMetricExporterBuilder.java b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/metrics/OtlpGrpcMetricExporterBuilder.java index 4a975e257c6..c6f02dec4c7 100644 --- a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/metrics/OtlpGrpcMetricExporterBuilder.java +++ b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/metrics/OtlpGrpcMetricExporterBuilder.java @@ -50,7 +50,7 @@ public final class OtlpGrpcMetricExporterBuilder { private static final long DEFAULT_TIMEOUT_SECS = 10; private static final AggregationTemporalitySelector DEFAULT_AGGREGATION_TEMPORALITY_SELECTOR = AggregationTemporalitySelector.alwaysCumulative(); - private static final MemoryMode DEFAULT_MEMORY_MODE = MemoryMode.IMMUTABLE_DATA; + private static final MemoryMode DEFAULT_MEMORY_MODE = MemoryMode.REUSABLE_DATA; // Visible for testing final GrpcExporterBuilder delegate; diff --git a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/trace/OtlpGrpcSpanExporterBuilder.java b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/trace/OtlpGrpcSpanExporterBuilder.java index 370c3b5bd2c..0a24398eeed 100644 --- a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/trace/OtlpGrpcSpanExporterBuilder.java +++ b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/trace/OtlpGrpcSpanExporterBuilder.java @@ -39,7 +39,7 @@ public final class OtlpGrpcSpanExporterBuilder { private static final String DEFAULT_ENDPOINT_URL = "http://localhost:4317"; private static final URI DEFAULT_ENDPOINT = URI.create(DEFAULT_ENDPOINT_URL); private static final long DEFAULT_TIMEOUT_SECS = 10; - private static final MemoryMode DEFAULT_MEMORY_MODE = MemoryMode.IMMUTABLE_DATA; + private static final MemoryMode DEFAULT_MEMORY_MODE = MemoryMode.REUSABLE_DATA; // Visible for testing final GrpcExporterBuilder delegate; diff --git a/exporters/otlp/all/src/test/java/io/opentelemetry/exporter/otlp/internal/OtlpLogRecordExporterProviderTest.java b/exporters/otlp/all/src/test/java/io/opentelemetry/exporter/otlp/internal/OtlpLogRecordExporterProviderTest.java index bab89d8a69a..47ed7859cd7 100644 --- a/exporters/otlp/all/src/test/java/io/opentelemetry/exporter/otlp/internal/OtlpLogRecordExporterProviderTest.java +++ b/exporters/otlp/all/src/test/java/io/opentelemetry/exporter/otlp/internal/OtlpLogRecordExporterProviderTest.java @@ -129,7 +129,7 @@ void createExporter_GrpcDefaults() { verify(grpcBuilder, never()).setTrustedCertificates(any()); verify(grpcBuilder, never()).setClientTls(any(), any()); assertThat(grpcBuilder).extracting("delegate").extracting("retryPolicy").isNotNull(); - getMemoryMode(exporter).isEqualTo(MemoryMode.IMMUTABLE_DATA); + getMemoryMode(exporter).isEqualTo(MemoryMode.REUSABLE_DATA); } Mockito.verifyNoInteractions(httpBuilder); } @@ -183,7 +183,7 @@ void createExporter_GrpcWithSignalConfiguration() throws CertificateEncodingExce config.put("otel.exporter.otlp.logs.compression", "gzip"); config.put("otel.exporter.otlp.timeout", "1s"); config.put("otel.exporter.otlp.logs.timeout", "15s"); - config.put("otel.java.experimental.exporter.memory_mode", "reusable_data"); + config.put("otel.java.exporter.memory_mode", "immutable_data"); try (LogRecordExporter exporter = provider.createExporter(DefaultConfigProperties.createFromMap(config))) { @@ -196,7 +196,7 @@ void createExporter_GrpcWithSignalConfiguration() throws CertificateEncodingExce verify(grpcBuilder).setTrustedCertificates(serverTls.certificate().getEncoded()); verify(grpcBuilder) .setClientTls(clientTls.privateKey().getEncoded(), clientTls.certificate().getEncoded()); - getMemoryMode(exporter).isEqualTo(MemoryMode.REUSABLE_DATA); + getMemoryMode(exporter).isEqualTo(MemoryMode.IMMUTABLE_DATA); } Mockito.verifyNoInteractions(httpBuilder); } @@ -216,7 +216,7 @@ void createExporter_HttpDefaults() { verify(httpBuilder, never()).setTrustedCertificates(any()); verify(httpBuilder, never()).setClientTls(any(), any()); assertThat(httpBuilder).extracting("delegate").extracting("retryPolicy").isNotNull(); - getMemoryMode(exporter).isEqualTo(MemoryMode.IMMUTABLE_DATA); + getMemoryMode(exporter).isEqualTo(MemoryMode.REUSABLE_DATA); } Mockito.verifyNoInteractions(grpcBuilder); } @@ -269,7 +269,7 @@ void createExporter_HttpWithSignalConfiguration() throws CertificateEncodingExce config.put("otel.exporter.otlp.logs.compression", "gzip"); config.put("otel.exporter.otlp.timeout", "1s"); config.put("otel.exporter.otlp.logs.timeout", "15s"); - config.put("otel.java.experimental.exporter.memory_mode", "reusable_data"); + config.put("otel.java.exporter.memory_mode", "immutable_data"); try (LogRecordExporter exporter = provider.createExporter(DefaultConfigProperties.createFromMap(config))) { @@ -282,7 +282,7 @@ void createExporter_HttpWithSignalConfiguration() throws CertificateEncodingExce verify(httpBuilder).setTrustedCertificates(serverTls.certificate().getEncoded()); verify(httpBuilder) .setClientTls(clientTls.privateKey().getEncoded(), clientTls.certificate().getEncoded()); - getMemoryMode(exporter).isEqualTo(MemoryMode.REUSABLE_DATA); + getMemoryMode(exporter).isEqualTo(MemoryMode.IMMUTABLE_DATA); } Mockito.verifyNoInteractions(grpcBuilder); } diff --git a/exporters/otlp/all/src/test/java/io/opentelemetry/exporter/otlp/internal/OtlpMetricExporterProviderTest.java b/exporters/otlp/all/src/test/java/io/opentelemetry/exporter/otlp/internal/OtlpMetricExporterProviderTest.java index 3956b4f62d8..3d0a4098328 100644 --- a/exporters/otlp/all/src/test/java/io/opentelemetry/exporter/otlp/internal/OtlpMetricExporterProviderTest.java +++ b/exporters/otlp/all/src/test/java/io/opentelemetry/exporter/otlp/internal/OtlpMetricExporterProviderTest.java @@ -128,7 +128,7 @@ void createExporter_GrpcDefaults() { verify(grpcBuilder, never()).setTrustedCertificates(any()); verify(grpcBuilder, never()).setClientTls(any(), any()); assertThat(grpcBuilder).extracting("delegate").extracting("retryPolicy").isNotNull(); - assertThat(exporter.getMemoryMode()).isEqualTo(MemoryMode.IMMUTABLE_DATA); + assertThat(exporter.getMemoryMode()).isEqualTo(MemoryMode.REUSABLE_DATA); } Mockito.verifyNoInteractions(httpBuilder); } @@ -178,7 +178,7 @@ void createExporter_GrpcWithSignalConfiguration() throws CertificateEncodingExce config.put("otel.exporter.otlp.metrics.compression", "gzip"); config.put("otel.exporter.otlp.timeout", "1s"); config.put("otel.exporter.otlp.metrics.timeout", "15s"); - config.put("otel.java.experimental.exporter.memory_mode", "reusable_data"); + config.put("otel.java.exporter.memory_mode", "immutable_data"); try (MetricExporter exporter = provider.createExporter(DefaultConfigProperties.createFromMap(config))) { @@ -191,7 +191,7 @@ void createExporter_GrpcWithSignalConfiguration() throws CertificateEncodingExce verify(grpcBuilder).setTrustedCertificates(serverTls.certificate().getEncoded()); verify(grpcBuilder) .setClientTls(clientTls.privateKey().getEncoded(), clientTls.certificate().getEncoded()); - assertThat(exporter.getMemoryMode()).isEqualTo(MemoryMode.REUSABLE_DATA); + assertThat(exporter.getMemoryMode()).isEqualTo(MemoryMode.IMMUTABLE_DATA); } Mockito.verifyNoInteractions(httpBuilder); } @@ -212,7 +212,7 @@ void createExporter_HttpDefaults() { verify(httpBuilder, never()).setTrustedCertificates(any()); verify(httpBuilder, never()).setClientTls(any(), any()); assertThat(httpBuilder).extracting("delegate").extracting("retryPolicy").isNotNull(); - assertThat(exporter.getMemoryMode()).isEqualTo(MemoryMode.IMMUTABLE_DATA); + assertThat(exporter.getMemoryMode()).isEqualTo(MemoryMode.REUSABLE_DATA); } Mockito.verifyNoInteractions(grpcBuilder); } @@ -265,7 +265,7 @@ void createExporter_HttpWithSignalConfiguration() throws CertificateEncodingExce config.put("otel.exporter.otlp.metrics.compression", "gzip"); config.put("otel.exporter.otlp.timeout", "1s"); config.put("otel.exporter.otlp.metrics.timeout", "15s"); - config.put("otel.java.experimental.exporter.memory_mode", "reusable_data"); + config.put("otel.java.exporter.memory_mode", "immutable_data"); try (MetricExporter exporter = provider.createExporter(DefaultConfigProperties.createFromMap(config))) { @@ -278,7 +278,7 @@ void createExporter_HttpWithSignalConfiguration() throws CertificateEncodingExce verify(httpBuilder).setTrustedCertificates(serverTls.certificate().getEncoded()); verify(httpBuilder) .setClientTls(clientTls.privateKey().getEncoded(), clientTls.certificate().getEncoded()); - assertThat(exporter.getMemoryMode()).isEqualTo(MemoryMode.REUSABLE_DATA); + assertThat(exporter.getMemoryMode()).isEqualTo(MemoryMode.IMMUTABLE_DATA); } Mockito.verifyNoInteractions(grpcBuilder); } diff --git a/exporters/otlp/all/src/test/java/io/opentelemetry/exporter/otlp/internal/OtlpSpanExporterProviderTest.java b/exporters/otlp/all/src/test/java/io/opentelemetry/exporter/otlp/internal/OtlpSpanExporterProviderTest.java index 084826d47ff..46d2e8ea218 100644 --- a/exporters/otlp/all/src/test/java/io/opentelemetry/exporter/otlp/internal/OtlpSpanExporterProviderTest.java +++ b/exporters/otlp/all/src/test/java/io/opentelemetry/exporter/otlp/internal/OtlpSpanExporterProviderTest.java @@ -130,7 +130,7 @@ void createExporter_GrpcDefaults() { verify(grpcBuilder, never()).setTrustedCertificates(any()); verify(grpcBuilder, never()).setClientTls(any(), any()); assertThat(grpcBuilder).extracting("delegate").extracting("retryPolicy").isNotNull(); - getMemoryMode(exporter).isEqualTo(MemoryMode.IMMUTABLE_DATA); + getMemoryMode(exporter).isEqualTo(MemoryMode.REUSABLE_DATA); } Mockito.verifyNoInteractions(httpBuilder); } @@ -184,7 +184,7 @@ void createExporter_GrpcWithSignalConfiguration() throws CertificateEncodingExce config.put("otel.exporter.otlp.traces.compression", "gzip"); config.put("otel.exporter.otlp.timeout", "1s"); config.put("otel.exporter.otlp.traces.timeout", "15s"); - config.put("otel.java.experimental.exporter.memory_mode", "reusable_data"); + config.put("otel.java.exporter.memory_mode", "immutable_data"); try (SpanExporter exporter = provider.createExporter(DefaultConfigProperties.createFromMap(config))) { @@ -197,7 +197,7 @@ void createExporter_GrpcWithSignalConfiguration() throws CertificateEncodingExce verify(grpcBuilder).setTrustedCertificates(serverTls.certificate().getEncoded()); verify(grpcBuilder) .setClientTls(clientTls.privateKey().getEncoded(), clientTls.certificate().getEncoded()); - getMemoryMode(exporter).isEqualTo(MemoryMode.REUSABLE_DATA); + getMemoryMode(exporter).isEqualTo(MemoryMode.IMMUTABLE_DATA); } Mockito.verifyNoInteractions(httpBuilder); } @@ -217,7 +217,7 @@ void createExporter_HttpDefaults() { verify(httpBuilder, never()).setTrustedCertificates(any()); verify(httpBuilder, never()).setClientTls(any(), any()); assertThat(httpBuilder).extracting("delegate").extracting("retryPolicy").isNotNull(); - getMemoryMode(exporter).isEqualTo(MemoryMode.IMMUTABLE_DATA); + getMemoryMode(exporter).isEqualTo(MemoryMode.REUSABLE_DATA); } Mockito.verifyNoInteractions(grpcBuilder); } @@ -249,7 +249,7 @@ void createExporter_HttpWithGeneralConfiguration() throws CertificateEncodingExc verify(httpBuilder) .setClientTls(clientTls.privateKey().getEncoded(), clientTls.certificate().getEncoded()); assertThat(httpBuilder).extracting("delegate").extracting("retryPolicy").isNull(); - getMemoryMode(exporter).isEqualTo(MemoryMode.IMMUTABLE_DATA); + getMemoryMode(exporter).isEqualTo(MemoryMode.REUSABLE_DATA); } Mockito.verifyNoInteractions(grpcBuilder); } @@ -273,7 +273,7 @@ void createExporter_HttpWithSignalConfiguration() throws CertificateEncodingExce config.put("otel.exporter.otlp.traces.compression", "gzip"); config.put("otel.exporter.otlp.timeout", "1s"); config.put("otel.exporter.otlp.traces.timeout", "15s"); - config.put("otel.java.experimental.exporter.memory_mode", "reusable_data"); + config.put("otel.java.exporter.memory_mode", "immutable_data"); try (SpanExporter exporter = provider.createExporter(DefaultConfigProperties.createFromMap(config))) { @@ -286,7 +286,7 @@ void createExporter_HttpWithSignalConfiguration() throws CertificateEncodingExce verify(httpBuilder).setTrustedCertificates(serverTls.certificate().getEncoded()); verify(httpBuilder) .setClientTls(clientTls.privateKey().getEncoded(), clientTls.certificate().getEncoded()); - getMemoryMode(exporter).isEqualTo(MemoryMode.REUSABLE_DATA); + getMemoryMode(exporter).isEqualTo(MemoryMode.IMMUTABLE_DATA); } Mockito.verifyNoInteractions(grpcBuilder); } diff --git a/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/FakeTelemetryUtil.java b/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/FakeTelemetryUtil.java index 2375e35aef1..2bdf65ef23e 100644 --- a/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/FakeTelemetryUtil.java +++ b/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/FakeTelemetryUtil.java @@ -33,6 +33,11 @@ public class FakeTelemetryUtil { private static final String TRACE_ID = "00000000000000000000000000abc123"; private static final String SPAN_ID = "0000000000def456"; + private static final InstrumentationScopeInfo SCOPE_INFO = + InstrumentationScopeInfo.builder("testLib") + .setVersion("1.0") + .setSchemaUrl("http://url") + .build(); /** Generate a fake {@link MetricData}. */ public static MetricData generateFakeMetricData() { @@ -40,7 +45,7 @@ public static MetricData generateFakeMetricData() { long endNs = startNs + TimeUnit.MILLISECONDS.toNanos(900); return ImmutableMetricData.createLongSum( Resource.empty(), - InstrumentationScopeInfo.empty(), + SCOPE_INFO, "name", "description", "1", @@ -69,11 +74,7 @@ public static SpanData generateFakeSpanData() { .setLinks(Collections.emptyList()) .setTotalRecordedLinks(0) .setTotalRecordedEvents(0) - .setInstrumentationScopeInfo( - InstrumentationScopeInfo.builder("testLib") - .setVersion("1.0") - .setSchemaUrl("http://url") - .build()) + .setInstrumentationScopeInfo(SCOPE_INFO) .build(); } @@ -81,11 +82,7 @@ public static SpanData generateFakeSpanData() { public static LogRecordData generateFakeLogRecordData() { return TestLogRecordData.builder() .setResource(Resource.getDefault()) - .setInstrumentationScopeInfo( - InstrumentationScopeInfo.builder("testLib") - .setVersion("1.0") - .setSchemaUrl("http://url") - .build()) + .setInstrumentationScopeInfo(SCOPE_INFO) .setBody("log body") .setAttributes(Attributes.builder().put("key", "value").build()) .setSeverity(Severity.INFO) diff --git a/exporters/prometheus/src/main/java/io/opentelemetry/exporter/prometheus/PrometheusHttpServer.java b/exporters/prometheus/src/main/java/io/opentelemetry/exporter/prometheus/PrometheusHttpServer.java index 78609ee7549..d07bfb8b3ae 100644 --- a/exporters/prometheus/src/main/java/io/opentelemetry/exporter/prometheus/PrometheusHttpServer.java +++ b/exporters/prometheus/src/main/java/io/opentelemetry/exporter/prometheus/PrometheusHttpServer.java @@ -26,7 +26,8 @@ import java.io.UncheckedIOException; import java.net.InetSocketAddress; import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; +import java.util.concurrent.LinkedBlockingQueue; +import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.TimeUnit; import java.util.function.Predicate; import javax.annotation.Nullable; @@ -82,7 +83,13 @@ public static PrometheusHttpServerBuilder builder() { // sequentially. if (memoryMode == MemoryMode.REUSABLE_DATA) { executor = - Executors.newSingleThreadExecutor(new DaemonThreadFactory("prometheus-http-server")); + new ThreadPoolExecutor( + 1, + 1, + 0L, + TimeUnit.MILLISECONDS, + new LinkedBlockingQueue<>(), + new DaemonThreadFactory("prometheus-http-server")); } try { this.httpServer = diff --git a/exporters/prometheus/src/main/java/io/opentelemetry/exporter/prometheus/PrometheusHttpServerBuilder.java b/exporters/prometheus/src/main/java/io/opentelemetry/exporter/prometheus/PrometheusHttpServerBuilder.java index c1138a6ea31..b43f7e089e1 100644 --- a/exporters/prometheus/src/main/java/io/opentelemetry/exporter/prometheus/PrometheusHttpServerBuilder.java +++ b/exporters/prometheus/src/main/java/io/opentelemetry/exporter/prometheus/PrometheusHttpServerBuilder.java @@ -24,7 +24,7 @@ public final class PrometheusHttpServerBuilder { static final int DEFAULT_PORT = 9464; private static final String DEFAULT_HOST = "0.0.0.0"; - private static final MemoryMode DEFAULT_MEMORY_MODE = MemoryMode.IMMUTABLE_DATA; + private static final MemoryMode DEFAULT_MEMORY_MODE = MemoryMode.REUSABLE_DATA; private String host = DEFAULT_HOST; private int port = DEFAULT_PORT; @@ -46,6 +46,7 @@ public final class PrometheusHttpServerBuilder { this.otelScopeEnabled = builder.otelScopeEnabled; this.allowedResourceAttributesFilter = builder.allowedResourceAttributesFilter; this.executor = builder.executor; + this.memoryMode = builder.memoryMode; this.defaultAggregationSelector = builder.defaultAggregationSelector; } @@ -150,6 +151,11 @@ public PrometheusHttpServerBuilder setDefaultAggregationSelector( * registered with a {@link io.opentelemetry.sdk.metrics.SdkMeterProvider}. */ public PrometheusHttpServer build() { + if (memoryMode == MemoryMode.REUSABLE_DATA && executor != null) { + throw new IllegalArgumentException( + "MemoryMode REUSEABLE_DATA cannot be used with custom executor, " + + "since data may be corrupted if reading metrics concurrently"); + } return new PrometheusHttpServer( new PrometheusHttpServerBuilder(this), // copy to prevent modification host, diff --git a/exporters/prometheus/src/test/java/io/opentelemetry/exporter/prometheus/PrometheusHttpServerTest.java b/exporters/prometheus/src/test/java/io/opentelemetry/exporter/prometheus/PrometheusHttpServerTest.java index 1ee412eff03..57726a47f63 100644 --- a/exporters/prometheus/src/test/java/io/opentelemetry/exporter/prometheus/PrometheusHttpServerTest.java +++ b/exporters/prometheus/src/test/java/io/opentelemetry/exporter/prometheus/PrometheusHttpServerTest.java @@ -427,6 +427,8 @@ void customExecutor() throws IOException { PrometheusHttpServer.builder() .setHost("localhost") .setPort(port) + // Memory mode must be IMMUTABLE_DATA to set custom executor + .setMemoryMode(MemoryMode.IMMUTABLE_DATA) .setExecutor(scheduledExecutor) .build()) { assertThat(server) @@ -520,7 +522,7 @@ void toBuilder() { builder.setAllowedResourceAttributesFilter(resourceAttributesFilter); ExecutorService executor = Executors.newSingleThreadExecutor(); - builder.setExecutor(executor); + builder.setExecutor(executor).setMemoryMode(MemoryMode.IMMUTABLE_DATA); PrometheusRegistry prometheusRegistry = new PrometheusRegistry(); builder.setPrometheusRegistry(prometheusRegistry); diff --git a/exporters/prometheus/src/test/java/io/opentelemetry/exporter/prometheus/internal/PrometheusMetricReaderProviderTest.java b/exporters/prometheus/src/test/java/io/opentelemetry/exporter/prometheus/internal/PrometheusMetricReaderProviderTest.java index e1fc42382e5..7945514af96 100644 --- a/exporters/prometheus/src/test/java/io/opentelemetry/exporter/prometheus/internal/PrometheusMetricReaderProviderTest.java +++ b/exporters/prometheus/src/test/java/io/opentelemetry/exporter/prometheus/internal/PrometheusMetricReaderProviderTest.java @@ -62,7 +62,7 @@ void createMetricReader_Default() throws IOException { assertThat(server.getAddress().getHostName()).isEqualTo("0:0:0:0:0:0:0:0"); assertThat(server.getAddress().getPort()).isEqualTo(9464); }); - assertThat(metricReader.getMemoryMode()).isEqualTo(MemoryMode.IMMUTABLE_DATA); + assertThat(metricReader.getMemoryMode()).isEqualTo(MemoryMode.REUSABLE_DATA); assertThat(metricReader.getDefaultAggregation(InstrumentType.HISTOGRAM)) .isEqualTo(Aggregation.defaultAggregation()); } @@ -81,7 +81,7 @@ void createMetricReader_WithConfiguration() throws IOException { Map config = new HashMap<>(); config.put("otel.exporter.prometheus.host", "localhost"); config.put("otel.exporter.prometheus.port", String.valueOf(port)); - config.put("otel.java.experimental.exporter.memory_mode", "reusable_data"); + config.put("otel.java.exporter.memory_mode", "immutable_data"); config.put( "otel.java.experimental.exporter.prometheus.metrics.default.histogram.aggregation", "BASE2_EXPONENTIAL_BUCKET_HISTOGRAM"); @@ -99,7 +99,7 @@ void createMetricReader_WithConfiguration() throws IOException { assertThat(server.getAddress().getHostName()).isEqualTo("localhost"); assertThat(server.getAddress().getPort()).isEqualTo(port); }); - assertThat(metricReader.getMemoryMode()).isEqualTo(MemoryMode.REUSABLE_DATA); + assertThat(metricReader.getMemoryMode()).isEqualTo(MemoryMode.IMMUTABLE_DATA); assertThat(metricReader.getDefaultAggregation(InstrumentType.HISTOGRAM)) .isEqualTo(Aggregation.base2ExponentialBucketHistogram()); } From bc4bacf5eec8ff88be2c0fb57af183ec94cc1a91 Mon Sep 17 00:00:00 2001 From: Teja Date: Wed, 23 Oct 2024 15:29:42 -0400 Subject: [PATCH 624/901] Stabilizing `otel.experimental.resource.disabled.keys` (#6809) Co-authored-by: jack-berg <34418638+jack-berg@users.noreply.github.com> --- .../autoconfigure/ResourceConfiguration.java | 19 +++++++++++++-- .../ResourceConfigurationTest.java | 23 ++++++++++++++++++- 2 files changed, 39 insertions(+), 3 deletions(-) diff --git a/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/ResourceConfiguration.java b/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/ResourceConfiguration.java index 010d219acba..21026fe75aa 100644 --- a/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/ResourceConfiguration.java +++ b/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/ResourceConfiguration.java @@ -21,9 +21,11 @@ import java.nio.charset.StandardCharsets; import java.util.Collections; import java.util.HashSet; +import java.util.List; import java.util.Map; import java.util.Set; import java.util.function.BiFunction; +import java.util.logging.Logger; /** * Auto-configuration for the OpenTelemetry {@link Resource}. @@ -32,12 +34,16 @@ */ public final class ResourceConfiguration { + private static final Logger logger = Logger.getLogger(ResourceConfiguration.class.getName()); + private static final AttributeKey SERVICE_NAME = AttributeKey.stringKey("service.name"); // Visible for testing static final String ATTRIBUTE_PROPERTY = "otel.resource.attributes"; static final String SERVICE_NAME_PROPERTY = "otel.service.name"; - static final String DISABLED_ATTRIBUTE_KEYS = "otel.experimental.resource.disabled.keys"; + static final String EXPERIMENTAL_DISABLED_ATTRIBUTE_KEYS = + "otel.experimental.resource.disabled.keys"; + static final String DISABLED_ATTRIBUTE_KEYS = "otel.resource.disabled.keys"; /** * Create a {@link Resource} from the environment. The resource contains attributes parsed from @@ -113,7 +119,16 @@ static Resource configureResource( // visible for testing static Resource filterAttributes(Resource resource, ConfigProperties configProperties) { - Set disabledKeys = new HashSet<>(configProperties.getList(DISABLED_ATTRIBUTE_KEYS)); + List disabledAttibuteKeys = configProperties.getList(DISABLED_ATTRIBUTE_KEYS); + // TODO: Remove this once the deprecated property is removed. + if (disabledAttibuteKeys.isEmpty()) { + disabledAttibuteKeys = configProperties.getList(EXPERIMENTAL_DISABLED_ATTRIBUTE_KEYS); + if (!disabledAttibuteKeys.isEmpty()) { + logger.warning( + "otel.experimental.resource.disabled.keys is deprecated and will be removed after 1.45.0 release. Please use otel.resource.disabled.keys instead."); + } + } + Set disabledKeys = new HashSet<>(disabledAttibuteKeys); ResourceBuilder builder = resource.toBuilder().removeIf(attributeKey -> disabledKeys.contains(attributeKey.getKey())); diff --git a/sdk-extensions/autoconfigure/src/test/java/io/opentelemetry/sdk/autoconfigure/ResourceConfigurationTest.java b/sdk-extensions/autoconfigure/src/test/java/io/opentelemetry/sdk/autoconfigure/ResourceConfigurationTest.java index 33cc9740639..8e6a42d3af6 100644 --- a/sdk-extensions/autoconfigure/src/test/java/io/opentelemetry/sdk/autoconfigure/ResourceConfigurationTest.java +++ b/sdk-extensions/autoconfigure/src/test/java/io/opentelemetry/sdk/autoconfigure/ResourceConfigurationTest.java @@ -26,7 +26,28 @@ class ResourceConfigurationTest { @Test - void customConfigResource() { + void customConfigResourceWithDisabledKeys() { + Map props = new HashMap<>(); + props.put("otel.service.name", "test-service"); + props.put( + "otel.resource.attributes", "food=cheesecake,drink=juice,animal= ,color=,shape=square"); + props.put("otel.resource.disabled-keys", "drink"); + + assertThat( + ResourceConfiguration.configureResource( + DefaultConfigProperties.create(props), + SpiHelper.create(ResourceConfigurationTest.class.getClassLoader()), + (r, c) -> r)) + .isEqualTo( + Resource.getDefault().toBuilder() + .put(stringKey("service.name"), "test-service") + .put("food", "cheesecake") + .put("shape", "square") + .build()); + } + + @Test + void customConfigResourceWithExperimentalDisabledKeys() { Map props = new HashMap<>(); props.put("otel.service.name", "test-service"); props.put( From 192f7fa4fe68f8acd7ace50e2c2479adc0cdb763 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 23 Oct 2024 18:28:58 -0700 Subject: [PATCH 625/901] fix(deps): update dependency com.google.api.grpc:proto-google-common-protos to v2.47.0 (#6818) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- dependencyManagement/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index ab2eec59905..ba43e86a8a5 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -56,7 +56,7 @@ val DEPENDENCIES = listOf( "io.prometheus:simpleclient_httpserver:${prometheusClientVersion}", "javax.annotation:javax.annotation-api:1.3.2", "com.github.stefanbirkner:system-rules:1.19.0", - "com.google.api.grpc:proto-google-common-protos:2.46.0", + "com.google.api.grpc:proto-google-common-protos:2.47.0", "com.google.code.findbugs:jsr305:3.0.2", "com.google.guava:guava-beta-checker:1.0", "com.sun.net.httpserver:http:20070405", From fd4e5fe56957ebe5516cc1056f76bd6accdbc610 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 24 Oct 2024 16:56:47 -0700 Subject: [PATCH 626/901] fix(deps): update dependency org.testcontainers:testcontainers-bom to v1.20.3 (#6816) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- dependencyManagement/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index ba43e86a8a5..30a65854062 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -20,7 +20,7 @@ val DEPENDENCY_BOMS = listOf( "io.zipkin.reporter2:zipkin-reporter-bom:3.4.2", "org.assertj:assertj-bom:3.26.3", "org.junit:junit-bom:5.11.3", - "org.testcontainers:testcontainers-bom:1.20.2", + "org.testcontainers:testcontainers-bom:1.20.3", "org.snakeyaml:snakeyaml-engine:2.8" ) From 74579aa2a1c1e8771d89e00adccb489d9f610737 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 25 Oct 2024 16:31:37 -0700 Subject: [PATCH 627/901] fix(deps): update dependency com.google.api.grpc:proto-google-common-protos to v2.48.0 (#6821) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- dependencyManagement/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index 30a65854062..196ff7f5e44 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -56,7 +56,7 @@ val DEPENDENCIES = listOf( "io.prometheus:simpleclient_httpserver:${prometheusClientVersion}", "javax.annotation:javax.annotation-api:1.3.2", "com.github.stefanbirkner:system-rules:1.19.0", - "com.google.api.grpc:proto-google-common-protos:2.47.0", + "com.google.api.grpc:proto-google-common-protos:2.48.0", "com.google.code.findbugs:jsr305:3.0.2", "com.google.guava:guava-beta-checker:1.0", "com.sun.net.httpserver:http:20070405", From 740dd14f521e2af210c3bd7ca69555cfc24fc259 Mon Sep 17 00:00:00 2001 From: Jiwon Date: Tue, 29 Oct 2024 09:40:00 +0900 Subject: [PATCH 628/901] Fix gRPC Retry Mechanism for Unsuccessful HTTP Responses (#6829) --- .../okhttp/internal/OkHttpGrpcSender.java | 8 +-- .../okhttp/internal/OkHttpGrpcSenderTest.java | 59 +++++++++++++++++++ 2 files changed, 62 insertions(+), 5 deletions(-) create mode 100644 exporters/sender/okhttp/src/test/java/io/opentelemetry/exporter/sender/okhttp/internal/OkHttpGrpcSenderTest.java diff --git a/exporters/sender/okhttp/src/main/java/io/opentelemetry/exporter/sender/okhttp/internal/OkHttpGrpcSender.java b/exporters/sender/okhttp/src/main/java/io/opentelemetry/exporter/sender/okhttp/internal/OkHttpGrpcSender.java index 8776762b62b..f8b4996b90e 100644 --- a/exporters/sender/okhttp/src/main/java/io/opentelemetry/exporter/sender/okhttp/internal/OkHttpGrpcSender.java +++ b/exporters/sender/okhttp/src/main/java/io/opentelemetry/exporter/sender/okhttp/internal/OkHttpGrpcSender.java @@ -201,14 +201,12 @@ public CompletableResultCode shutdown() { /** Whether response is retriable or not. */ public static boolean isRetryable(Response response) { - // Only retry on gRPC codes which will always come with an HTTP success - if (!response.isSuccessful()) { - return false; - } - // We don't check trailers for retry since retryable error codes always come with response // headers, not trailers, in practice. String grpcStatus = response.header(GRPC_STATUS); + if (grpcStatus == null) { + return false; + } return RetryUtil.retryableGrpcStatusCodes().contains(grpcStatus); } diff --git a/exporters/sender/okhttp/src/test/java/io/opentelemetry/exporter/sender/okhttp/internal/OkHttpGrpcSenderTest.java b/exporters/sender/okhttp/src/test/java/io/opentelemetry/exporter/sender/okhttp/internal/OkHttpGrpcSenderTest.java new file mode 100644 index 00000000000..c1a61a8aea5 --- /dev/null +++ b/exporters/sender/okhttp/src/test/java/io/opentelemetry/exporter/sender/okhttp/internal/OkHttpGrpcSenderTest.java @@ -0,0 +1,59 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.exporter.sender.okhttp.internal; + +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import io.opentelemetry.exporter.internal.RetryUtil; +import io.opentelemetry.exporter.internal.grpc.GrpcExporterUtil; +import java.util.Set; +import okhttp3.MediaType; +import okhttp3.Protocol; +import okhttp3.Request; +import okhttp3.Response; +import okhttp3.ResponseBody; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.MethodSource; + +class OkHttpGrpcSenderTest { + + private static final String GRPC_STATUS = "grpc-status"; + private static final MediaType TEXT_PLAIN = MediaType.get("text/plain"); + + static Set provideRetryableGrpcStatusCodes() { + return RetryUtil.retryableGrpcStatusCodes(); + } + + @ParameterizedTest(name = "isRetryable should return true for GRPC status code: {0}") + @MethodSource("provideRetryableGrpcStatusCodes") + void isRetryable_RetryableGrpcStatus(String retryableGrpcStatus) { + Response response = createResponse(503, retryableGrpcStatus, "Retryable"); + boolean isRetryable = OkHttpGrpcSender.isRetryable(response); + assertTrue(isRetryable); + } + + @Test + void isRetryable_NonRetryableGrpcStatus() { + String nonRetryableGrpcStatus = + Integer.valueOf(GrpcExporterUtil.GRPC_STATUS_UNKNOWN).toString(); // INVALID_ARGUMENT + Response response = createResponse(503, nonRetryableGrpcStatus, "Non-retryable"); + boolean isRetryable = OkHttpGrpcSender.isRetryable(response); + assertFalse(isRetryable); + } + + private static Response createResponse(int httpCode, String grpcStatus, String message) { + return new Response.Builder() + .request(new Request.Builder().url("http://localhost/").build()) + .protocol(Protocol.HTTP_2) + .code(httpCode) + .body(ResponseBody.create("body", TEXT_PLAIN)) + .message(message) + .header(GRPC_STATUS, grpcStatus) + .build(); + } +} From ee21d4dcf3757466e1c2fdcd63760e8a0a0aedf8 Mon Sep 17 00:00:00 2001 From: Trask Stalnaker Date: Tue, 29 Oct 2024 06:52:06 -0700 Subject: [PATCH 629/901] Run tests on Java 23 (#6825) --- .github/workflows/build.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 442355d104a..1dfc5fb6c72 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -28,6 +28,7 @@ jobs: - 11 - 17 - 21 + - 23 # Collect coverage on latest LTS include: - os: ubuntu-20.04 @@ -44,6 +45,8 @@ jobs: test-java-version: 17 - os: macos-13 test-java-version: 21 + - os: macos-13 + test-java-version: 23 steps: - uses: actions/checkout@v4 From 8af18033cfe193d1b14332c96c2035ade90b7ad0 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 29 Oct 2024 09:10:52 -0500 Subject: [PATCH 630/901] fix(deps): update dependency com.uber.nullaway:nullaway to v0.12.1 (#6830) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- dependencyManagement/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index 196ff7f5e44..e3a86e4b7e1 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -61,7 +61,7 @@ val DEPENDENCIES = listOf( "com.google.guava:guava-beta-checker:1.0", "com.sun.net.httpserver:http:20070405", "com.tngtech.archunit:archunit-junit5:1.3.0", - "com.uber.nullaway:nullaway:0.12.0", + "com.uber.nullaway:nullaway:0.12.1", "edu.berkeley.cs.jqf:jqf-fuzz:1.7", // jqf-fuzz version 1.8+ requires Java 11+ "eu.rekawek.toxiproxy:toxiproxy-java:2.1.7", "io.github.netmikey.logunit:logunit-jul:2.0.0", From e6e2f3c36a3310e4bc6b93fbb78fe7f8429313f1 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 29 Oct 2024 09:11:10 -0500 Subject: [PATCH 631/901] fix(deps): update dependency com.fasterxml.jackson:jackson-bom to v2.18.1 (#6831) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- dependencyManagement/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index e3a86e4b7e1..18fccde647f 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -8,7 +8,7 @@ val dependencyVersions = hashMapOf() rootProject.extra["versions"] = dependencyVersions val DEPENDENCY_BOMS = listOf( - "com.fasterxml.jackson:jackson-bom:2.18.0", + "com.fasterxml.jackson:jackson-bom:2.18.1", "com.google.guava:guava-bom:33.3.1-jre", "com.google.protobuf:protobuf-bom:3.25.5", "com.linecorp.armeria:armeria-bom:1.30.1", From 2b0df092dc1f4979fc9b0ce88089f0d7b5ff603f Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 29 Oct 2024 09:11:31 -0500 Subject: [PATCH 632/901] fix(deps): update dependency checkstyle to v10.19.0 (#6822) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- buildSrc/src/main/kotlin/otel.java-conventions.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/buildSrc/src/main/kotlin/otel.java-conventions.gradle.kts b/buildSrc/src/main/kotlin/otel.java-conventions.gradle.kts index 79d9311c37b..fd3830bc45a 100644 --- a/buildSrc/src/main/kotlin/otel.java-conventions.gradle.kts +++ b/buildSrc/src/main/kotlin/otel.java-conventions.gradle.kts @@ -42,7 +42,7 @@ java { checkstyle { configDirectory.set(file("$rootDir/buildscripts/")) - toolVersion = "10.18.2" + toolVersion = "10.19.0" isIgnoreFailures = false configProperties["rootDir"] = rootDir } From fc86a76c877386e6aa085b6a96928c0e146d4630 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 29 Oct 2024 09:11:56 -0500 Subject: [PATCH 633/901] fix(deps): update dependency net.ltgt.gradle:gradle-nullaway-plugin to v2.1.0 (#6807) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- buildSrc/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts index e2e5e3e1ebe..aac6936e17c 100644 --- a/buildSrc/build.gradle.kts +++ b/buildSrc/build.gradle.kts @@ -64,7 +64,7 @@ dependencies { implementation("me.champeau.gradle:japicmp-gradle-plugin:0.4.3") implementation("me.champeau.jmh:jmh-gradle-plugin:0.7.2") implementation("net.ltgt.gradle:gradle-errorprone-plugin:4.0.1") - implementation("net.ltgt.gradle:gradle-nullaway-plugin:2.0.0") + implementation("net.ltgt.gradle:gradle-nullaway-plugin:2.1.0") implementation("org.jetbrains.kotlin:kotlin-gradle-plugin:2.0.21") implementation("org.owasp:dependency-check-gradle:10.0.4") implementation("ru.vyarus:gradle-animalsniffer-plugin:1.7.1") From c8967098c7242970e79bf0202a82dd2ccb679ff0 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 29 Oct 2024 09:12:20 -0500 Subject: [PATCH 634/901] fix(deps): update dependency org.owasp:dependency-check-gradle to v11 (#6817) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- buildSrc/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts index aac6936e17c..ce536705308 100644 --- a/buildSrc/build.gradle.kts +++ b/buildSrc/build.gradle.kts @@ -66,7 +66,7 @@ dependencies { implementation("net.ltgt.gradle:gradle-errorprone-plugin:4.0.1") implementation("net.ltgt.gradle:gradle-nullaway-plugin:2.1.0") implementation("org.jetbrains.kotlin:kotlin-gradle-plugin:2.0.21") - implementation("org.owasp:dependency-check-gradle:10.0.4") + implementation("org.owasp:dependency-check-gradle:11.0.0") implementation("ru.vyarus:gradle-animalsniffer-plugin:1.7.1") } From c7e797c5b4f753b5fb019ba907834a351b1c0328 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 29 Oct 2024 09:12:49 -0500 Subject: [PATCH 635/901] fix(deps): update errorproneversion to v2.35.1 (#6820) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- dependencyManagement/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index 18fccde647f..42e8ae138aa 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -25,7 +25,7 @@ val DEPENDENCY_BOMS = listOf( ) val autoValueVersion = "1.11.0" -val errorProneVersion = "2.34.0" +val errorProneVersion = "2.35.1" val jmhVersion = "1.37" // Mockito 5.x.x requires Java 11 https://github.com/mockito/mockito/releases/tag/v5.0.0 val mockitoVersion = "4.11.0" From e65edd942b7f0c2084797a924fff2248999aaf52 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 29 Oct 2024 09:52:05 -0500 Subject: [PATCH 636/901] fix(deps): update dependency net.ltgt.gradle:gradle-errorprone-plugin to v4.1.0 (#6806) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- buildSrc/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts index ce536705308..013eb81d977 100644 --- a/buildSrc/build.gradle.kts +++ b/buildSrc/build.gradle.kts @@ -63,7 +63,7 @@ dependencies { implementation("gradle.plugin.io.morethan.jmhreport:gradle-jmh-report:0.9.6") implementation("me.champeau.gradle:japicmp-gradle-plugin:0.4.3") implementation("me.champeau.jmh:jmh-gradle-plugin:0.7.2") - implementation("net.ltgt.gradle:gradle-errorprone-plugin:4.0.1") + implementation("net.ltgt.gradle:gradle-errorprone-plugin:4.1.0") implementation("net.ltgt.gradle:gradle-nullaway-plugin:2.1.0") implementation("org.jetbrains.kotlin:kotlin-gradle-plugin:2.0.21") implementation("org.owasp:dependency-check-gradle:11.0.0") From 73894cfe96e7f73ac140f55cc97ce195810b135d Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 29 Oct 2024 09:52:47 -0500 Subject: [PATCH 637/901] chore(deps): update plugin com.gradleup.shadow to v8.3.4 (#6834) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- settings.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/settings.gradle.kts b/settings.gradle.kts index d6e6592dc68..c3542d49948 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -1,6 +1,6 @@ pluginManagement { plugins { - id("com.gradleup.shadow") version "8.3.3" + id("com.gradleup.shadow") version "8.3.4" id("com.gradle.develocity") version "3.18.1" id("de.undercouch.download") version "5.6.0" id("org.jsonschema2pojo") version "1.2.2" From 3f05bf6ae2c23c639132d215004eea43523e7c2f Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 29 Oct 2024 09:53:00 -0500 Subject: [PATCH 638/901] fix(deps): update dependency io.grpc:grpc-bom to v1.68.1 (#6835) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- dependencyManagement/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index 42e8ae138aa..17faea7240c 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -14,7 +14,7 @@ val DEPENDENCY_BOMS = listOf( "com.linecorp.armeria:armeria-bom:1.30.1", "com.squareup.okhttp3:okhttp-bom:4.12.0", "com.squareup.okio:okio-bom:3.9.1", // applies to transitive dependencies of okhttp - "io.grpc:grpc-bom:1.68.0", + "io.grpc:grpc-bom:1.68.1", "io.netty:netty-bom:4.1.114.Final", "io.zipkin.brave:brave-bom:6.0.3", "io.zipkin.reporter2:zipkin-reporter-bom:3.4.2", From fcae15e92707deb9a7627d0765915f40e1722e84 Mon Sep 17 00:00:00 2001 From: Teja Date: Tue, 29 Oct 2024 10:53:38 -0400 Subject: [PATCH 639/901] Stabilize ExceptionEventData (#6795) Co-authored-by: jack-berg <34418638+jack-berg@users.noreply.github.com> Co-authored-by: Jack Berg --- .../opentelemetry-sdk-trace.txt | 7 +- .../io/opentelemetry/sdk/trace/SdkSpan.java | 40 +++++++- .../sdk/trace/data/ExceptionEventData.java | 36 ++++++++ .../data/ImmutableExceptionEventData.java | 40 ++++++++ .../internal/data/ExceptionEventData.java | 51 ----------- .../data/ImmutableExceptionEventData.java | 91 ------------------- .../sdk/trace/internal/data/package-info.java | 15 --- .../opentelemetry/sdk/trace/SdkSpanTest.java | 38 +++----- 8 files changed, 132 insertions(+), 186 deletions(-) create mode 100644 sdk/trace/src/main/java/io/opentelemetry/sdk/trace/data/ExceptionEventData.java create mode 100644 sdk/trace/src/main/java/io/opentelemetry/sdk/trace/data/ImmutableExceptionEventData.java delete mode 100644 sdk/trace/src/main/java/io/opentelemetry/sdk/trace/internal/data/ExceptionEventData.java delete mode 100644 sdk/trace/src/main/java/io/opentelemetry/sdk/trace/internal/data/ImmutableExceptionEventData.java delete mode 100644 sdk/trace/src/main/java/io/opentelemetry/sdk/trace/internal/data/package-info.java diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-trace.txt b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-trace.txt index 10464c237f1..c6fd7e61bcd 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-trace.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-trace.txt @@ -1,2 +1,7 @@ Comparing source compatibility of opentelemetry-sdk-trace-1.44.0-SNAPSHOT.jar against opentelemetry-sdk-trace-1.43.0.jar -No changes. \ No newline at end of file ++++ NEW INTERFACE: PUBLIC(+) ABSTRACT(+) io.opentelemetry.sdk.trace.data.ExceptionEventData (not serializable) + +++ CLASS FILE FORMAT VERSION: 52.0 <- n.a. + +++ NEW INTERFACE: io.opentelemetry.sdk.trace.data.EventData + +++ NEW SUPERCLASS: java.lang.Object + +++ NEW METHOD: PUBLIC(+) STATIC(+) io.opentelemetry.sdk.trace.data.ExceptionEventData create(long, java.lang.Throwable, io.opentelemetry.api.common.Attributes, int) + +++ NEW METHOD: PUBLIC(+) ABSTRACT(+) java.lang.Throwable getException() diff --git a/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/SdkSpan.java b/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/SdkSpan.java index 1580b05c465..0d2c9ab83fd 100644 --- a/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/SdkSpan.java +++ b/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/SdkSpan.java @@ -20,11 +20,13 @@ import io.opentelemetry.sdk.internal.InstrumentationScopeUtil; import io.opentelemetry.sdk.resources.Resource; import io.opentelemetry.sdk.trace.data.EventData; +import io.opentelemetry.sdk.trace.data.ExceptionEventData; import io.opentelemetry.sdk.trace.data.LinkData; import io.opentelemetry.sdk.trace.data.SpanData; import io.opentelemetry.sdk.trace.data.StatusData; import io.opentelemetry.sdk.trace.internal.ExtendedSpanProcessor; -import io.opentelemetry.sdk.trace.internal.data.ExceptionEventData; +import java.io.PrintWriter; +import java.io.StringWriter; import java.util.ArrayList; import java.util.Collections; import java.util.List; @@ -115,6 +117,13 @@ private enum EndState { @Nullable private Thread spanEndingThread; + private static final AttributeKey EXCEPTION_TYPE = + AttributeKey.stringKey("exception.type"); + private static final AttributeKey EXCEPTION_MESSAGE = + AttributeKey.stringKey("exception.message"); + private static final AttributeKey EXCEPTION_STACKTRACE = + AttributeKey.stringKey("exception.stacktrace"); + private SdkSpan( SpanContext context, String name, @@ -436,7 +445,8 @@ public ReadWriteSpan setStatus(StatusCode statusCode, @Nullable String descripti @Override public ReadWriteSpan recordException(Throwable exception) { - recordException(exception, Attributes.empty()); + Attributes attributes = this.getAttributes(); + recordException(exception, attributes); return this; } @@ -449,8 +459,32 @@ public ReadWriteSpan recordException(Throwable exception, Attributes additionalA additionalAttributes = Attributes.empty(); } + AttributesMap attributes = + AttributesMap.create( + spanLimits.getMaxNumberOfAttributes(), spanLimits.getMaxAttributeValueLength()); + String exceptionName = exception.getClass().getCanonicalName(); + String exceptionMessage = exception.getMessage(); + StringWriter stringWriter = new StringWriter(); + try (PrintWriter printWriter = new PrintWriter(stringWriter)) { + exception.printStackTrace(printWriter); + } + String stackTrace = stringWriter.toString(); + + if (exceptionName != null) { + attributes.put(EXCEPTION_TYPE, exceptionName); + } + if (exceptionMessage != null) { + attributes.put(EXCEPTION_MESSAGE, exceptionMessage); + } + if (stackTrace != null) { + attributes.put(EXCEPTION_STACKTRACE, stackTrace); + } + + additionalAttributes.forEach(attributes::put); + addTimedEvent( - ExceptionEventData.create(spanLimits, clock.now(), exception, additionalAttributes)); + ExceptionEventData.create( + clock.now(), exception, attributes, attributes.getTotalAddedValues())); return this; } diff --git a/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/data/ExceptionEventData.java b/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/data/ExceptionEventData.java new file mode 100644 index 00000000000..f717a0aef00 --- /dev/null +++ b/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/data/ExceptionEventData.java @@ -0,0 +1,36 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.sdk.trace.data; + +import io.opentelemetry.api.common.Attributes; +import javax.annotation.concurrent.Immutable; + +/** Data representation of an event for a recorded exception. */ +@Immutable +public interface ExceptionEventData extends EventData { + + /** + * Returns a new immutable {@link ExceptionEventData}. + * + * @param epochNanos epoch timestamp in nanos of the {@link ExceptionEventData}. + * @param exception the {@link Throwable exception} of the {@code Event}. + * @param attributes the additional attributes of the {@link ExceptionEventData}. + * @param totalAttributeCount the total number of attributes for this {@code} Event. + * @return a new immutable {@link ExceptionEventData} + */ + static ExceptionEventData create( + long epochNanos, Throwable exception, Attributes attributes, int totalAttributeCount) { + return ImmutableExceptionEventData.create( + epochNanos, exception, attributes, totalAttributeCount); + } + + /** + * Return the {@link Throwable exception} of the {@link ExceptionEventData}. + * + * @return the {@link Throwable exception} of the {@link ExceptionEventData} + */ + Throwable getException(); +} diff --git a/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/data/ImmutableExceptionEventData.java b/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/data/ImmutableExceptionEventData.java new file mode 100644 index 00000000000..fd2e4bac752 --- /dev/null +++ b/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/data/ImmutableExceptionEventData.java @@ -0,0 +1,40 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.sdk.trace.data; + +import com.google.auto.value.AutoValue; +import io.opentelemetry.api.common.Attributes; +import javax.annotation.concurrent.Immutable; + +/** An effectively immutable implementation of {@link ExceptionEventData}. */ +@AutoValue +@Immutable +abstract class ImmutableExceptionEventData implements ExceptionEventData { + + private static final String EXCEPTION_EVENT_NAME = "exception"; + + @Override + public final String getName() { + return EXCEPTION_EVENT_NAME; + } + + /** + * Returns a new immutable {@code Event}. + * + * @param epochNanos epoch timestamp in nanos of the {@code Event}. + * @param exception the {@link Throwable exception} of the {@code Event}. + * @param attributes the additional {@link Attributes} of the {@code Event}. + * @param totalAttributeCount the total number of attributes for this {@code} Event. + * @return a new immutable {@code Event} + */ + static ExceptionEventData create( + long epochNanos, Throwable exception, Attributes attributes, int totalAttributeCount) { + return new AutoValue_ImmutableExceptionEventData( + attributes, epochNanos, totalAttributeCount, exception); + } + + ImmutableExceptionEventData() {} +} diff --git a/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/internal/data/ExceptionEventData.java b/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/internal/data/ExceptionEventData.java deleted file mode 100644 index 7e41c5a6b66..00000000000 --- a/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/internal/data/ExceptionEventData.java +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package io.opentelemetry.sdk.trace.internal.data; - -import io.opentelemetry.api.common.Attributes; -import io.opentelemetry.sdk.trace.SpanLimits; -import io.opentelemetry.sdk.trace.data.EventData; - -/** - * Data representation of an event for a recorded exception. - * - *

      This class is internal and is hence not for public use. Its APIs are unstable and can change - * at any time. - */ -public interface ExceptionEventData extends EventData { - - /** - * Returns a new immutable {@link ExceptionEventData}. - * - * @param spanLimits limits applied to {@link ExceptionEventData}. - * @param epochNanos epoch timestamp in nanos of the {@link ExceptionEventData}. - * @param exception the {@link Throwable exception} of the {@code Event}. - * @param additionalAttributes the additional attributes of the {@link ExceptionEventData}. - * @return a new immutable {@link ExceptionEventData} - */ - static ExceptionEventData create( - SpanLimits spanLimits, - long epochNanos, - Throwable exception, - Attributes additionalAttributes) { - return ImmutableExceptionEventData.create( - spanLimits, epochNanos, exception, additionalAttributes); - } - - /** - * Return the {@link Throwable exception} of the {@link ExceptionEventData}. - * - * @return the {@link Throwable exception} of the {@link ExceptionEventData} - */ - Throwable getException(); - - /** - * Return the additional {@link Attributes attributes} of the {@link ExceptionEventData}. - * - * @return the additional {@link Attributes attributes} of the {@link ExceptionEventData} - */ - Attributes getAdditionalAttributes(); -} diff --git a/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/internal/data/ImmutableExceptionEventData.java b/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/internal/data/ImmutableExceptionEventData.java deleted file mode 100644 index ee13f930775..00000000000 --- a/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/internal/data/ImmutableExceptionEventData.java +++ /dev/null @@ -1,91 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package io.opentelemetry.sdk.trace.internal.data; - -import com.google.auto.value.AutoValue; -import com.google.auto.value.extension.memoized.Memoized; -import io.opentelemetry.api.common.AttributeKey; -import io.opentelemetry.api.common.Attributes; -import io.opentelemetry.api.common.AttributesBuilder; -import io.opentelemetry.sdk.internal.AttributeUtil; -import io.opentelemetry.sdk.trace.SpanLimits; -import java.io.PrintWriter; -import java.io.StringWriter; -import javax.annotation.concurrent.Immutable; - -/** An effectively immutable implementation of {@link ExceptionEventData}. */ -@AutoValue -@Immutable -abstract class ImmutableExceptionEventData implements ExceptionEventData { - - private static final AttributeKey EXCEPTION_TYPE = - AttributeKey.stringKey("exception.type"); - private static final AttributeKey EXCEPTION_MESSAGE = - AttributeKey.stringKey("exception.message"); - private static final AttributeKey EXCEPTION_STACKTRACE = - AttributeKey.stringKey("exception.stacktrace"); - private static final String EXCEPTION_EVENT_NAME = "exception"; - - /** - * Returns a new immutable {@code Event}. - * - * @param spanLimits limits applied to {@code Event}. - * @param epochNanos epoch timestamp in nanos of the {@code Event}. - * @param exception the {@link Throwable exception} of the {@code Event}. - * @param additionalAttributes the additional {@link Attributes} of the {@code Event}. - * @return a new immutable {@code Event} - */ - static ExceptionEventData create( - SpanLimits spanLimits, - long epochNanos, - Throwable exception, - Attributes additionalAttributes) { - - return new AutoValue_ImmutableExceptionEventData( - epochNanos, exception, additionalAttributes, spanLimits); - } - - ImmutableExceptionEventData() {} - - protected abstract SpanLimits getSpanLimits(); - - @Override - public final String getName() { - return EXCEPTION_EVENT_NAME; - } - - @Override - @Memoized - public Attributes getAttributes() { - Throwable exception = getException(); - Attributes additionalAttributes = getAdditionalAttributes(); - AttributesBuilder attributesBuilder = Attributes.builder(); - - attributesBuilder.put(EXCEPTION_TYPE, exception.getClass().getCanonicalName()); - String message = exception.getMessage(); - if (message != null) { - attributesBuilder.put(EXCEPTION_MESSAGE, message); - } - - StringWriter stringWriter = new StringWriter(); - try (PrintWriter printWriter = new PrintWriter(stringWriter)) { - exception.printStackTrace(printWriter); - } - attributesBuilder.put(EXCEPTION_STACKTRACE, stringWriter.toString()); - attributesBuilder.putAll(additionalAttributes); - - SpanLimits spanLimits = getSpanLimits(); - return AttributeUtil.applyAttributesLimit( - attributesBuilder.build(), - spanLimits.getMaxNumberOfAttributesPerEvent(), - spanLimits.getMaxAttributeValueLength()); - } - - @Override - public final int getTotalAttributeCount() { - return getAttributes().size(); - } -} diff --git a/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/internal/data/package-info.java b/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/internal/data/package-info.java deleted file mode 100644 index bab18f74550..00000000000 --- a/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/internal/data/package-info.java +++ /dev/null @@ -1,15 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -/** - * Interfaces and implementations that are internal to OpenTelemetry. - * - *

      All the content under this package and its subpackages are considered not part of the public - * API, and must not be used by users of the OpenTelemetry library. - */ -@ParametersAreNonnullByDefault -package io.opentelemetry.sdk.trace.internal.data; - -import javax.annotation.ParametersAreNonnullByDefault; diff --git a/sdk/trace/src/test/java/io/opentelemetry/sdk/trace/SdkSpanTest.java b/sdk/trace/src/test/java/io/opentelemetry/sdk/trace/SdkSpanTest.java index 7814074269b..7fbd86ef229 100644 --- a/sdk/trace/src/test/java/io/opentelemetry/sdk/trace/SdkSpanTest.java +++ b/sdk/trace/src/test/java/io/opentelemetry/sdk/trace/SdkSpanTest.java @@ -41,11 +41,11 @@ import io.opentelemetry.sdk.resources.Resource; import io.opentelemetry.sdk.testing.time.TestClock; import io.opentelemetry.sdk.trace.data.EventData; +import io.opentelemetry.sdk.trace.data.ExceptionEventData; import io.opentelemetry.sdk.trace.data.LinkData; import io.opentelemetry.sdk.trace.data.SpanData; import io.opentelemetry.sdk.trace.data.StatusData; import io.opentelemetry.sdk.trace.internal.ExtendedSpanProcessor; -import io.opentelemetry.sdk.trace.internal.data.ExceptionEventData; import java.io.PrintWriter; import java.io.StringWriter; import java.time.Duration; @@ -1166,20 +1166,16 @@ void recordException() { EventData event = events.get(0); assertThat(event.getName()).isEqualTo("exception"); assertThat(event.getEpochNanos()).isEqualTo(timestamp); - assertThat(event.getAttributes()) - .isEqualTo( - Attributes.builder() - .put("exception.type", "java.lang.IllegalStateException") - .put("exception.message", "there was an exception") - .put("exception.stacktrace", stacktrace) - .build()); - + assertThat(event.getAttributes().get(stringKey("exception.message"))) + .isEqualTo("there was an exception"); + assertThat(event.getAttributes().get(stringKey("exception.type"))) + .isEqualTo(exception.getClass().getName()); + assertThat(event.getAttributes().get(stringKey("exception.stacktrace"))).isEqualTo(stacktrace); assertThat(event) .isInstanceOfSatisfying( ExceptionEventData.class, exceptionEvent -> { assertThat(exceptionEvent.getException()).isSameAs(exception); - assertThat(exceptionEvent.getAdditionalAttributes()).isEqualTo(Attributes.empty()); }); } @@ -1237,27 +1233,19 @@ void recordException_additionalAttributes() { EventData event = events.get(0); assertThat(event.getName()).isEqualTo("exception"); assertThat(event.getEpochNanos()).isEqualTo(timestamp); - assertThat(event.getAttributes()) - .isEqualTo( - Attributes.builder() - .put("key1", "this is an additional attribute") - .put("exception.type", "java.lang.IllegalStateException") - .put("exception.message", "this is a precedence attribute") - .put("exception.stacktrace", stacktrace) - .build()); + assertThat(event.getAttributes().get(stringKey("exception.message"))) + .isEqualTo("this is a precedence attribute"); + assertThat(event.getAttributes().get(stringKey("key1"))) + .isEqualTo("this is an additional attribute"); + assertThat(event.getAttributes().get(stringKey("exception.type"))) + .isEqualTo("java.lang.IllegalStateException"); + assertThat(event.getAttributes().get(stringKey("exception.stacktrace"))).isEqualTo(stacktrace); assertThat(event) .isInstanceOfSatisfying( ExceptionEventData.class, exceptionEvent -> { assertThat(exceptionEvent.getException()).isSameAs(exception); - assertThat(exceptionEvent.getAdditionalAttributes()) - .isEqualTo( - Attributes.of( - stringKey("key1"), - "this is an additional attribute", - stringKey("exception.message"), - "this is a precedence attribute")); }); } From 1e3cf0b7e34fe477abc273184d22db09d375477e Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 29 Oct 2024 10:01:16 -0500 Subject: [PATCH 640/901] fix(deps): update dependency me.champeau.gradle:japicmp-gradle-plugin to v0.4.4 (#6769) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Co-authored-by: Jack Berg --- buildSrc/build.gradle.kts | 2 +- buildSrc/src/main/kotlin/otel.japicmp-conventions.gradle.kts | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts index 013eb81d977..eebfe4e46de 100644 --- a/buildSrc/build.gradle.kts +++ b/buildSrc/build.gradle.kts @@ -61,7 +61,7 @@ dependencies { implementation("com.squareup.wire:wire-gradle-plugin") implementation("gradle.plugin.com.google.protobuf:protobuf-gradle-plugin:0.8.18") implementation("gradle.plugin.io.morethan.jmhreport:gradle-jmh-report:0.9.6") - implementation("me.champeau.gradle:japicmp-gradle-plugin:0.4.3") + implementation("me.champeau.gradle:japicmp-gradle-plugin:0.4.4") implementation("me.champeau.jmh:jmh-gradle-plugin:0.7.2") implementation("net.ltgt.gradle:gradle-errorprone-plugin:4.1.0") implementation("net.ltgt.gradle:gradle-nullaway-plugin:2.1.0") diff --git a/buildSrc/src/main/kotlin/otel.japicmp-conventions.gradle.kts b/buildSrc/src/main/kotlin/otel.japicmp-conventions.gradle.kts index 6a7a4139d6e..08dc25cfebc 100644 --- a/buildSrc/src/main/kotlin/otel.japicmp-conventions.gradle.kts +++ b/buildSrc/src/main/kotlin/otel.japicmp-conventions.gradle.kts @@ -27,8 +27,8 @@ val latestReleasedVersion: String by lazy { class AllowNewAbstractMethodOnAutovalueClasses : AbstractRecordingSeenMembers() { override fun maybeAddViolation(member: JApiCompatibility): Violation? { - val allowableAutovalueChanges = setOf(JApiCompatibilityChange.METHOD_ABSTRACT_ADDED_TO_CLASS, JApiCompatibilityChange.METHOD_ADDED_TO_PUBLIC_CLASS) - if (member.compatibilityChanges.filter { !allowableAutovalueChanges.contains(it) }.isEmpty() && + val allowableAutovalueChanges = setOf(JApiCompatibilityChangeType.METHOD_ABSTRACT_ADDED_TO_CLASS, JApiCompatibilityChangeType.METHOD_ADDED_TO_PUBLIC_CLASS) + if (member.compatibilityChanges.filter { !allowableAutovalueChanges.contains(it.type) }.isEmpty() && member is JApiMethod && isAutoValueClass(member.getjApiClass())) { return Violation.accept(member, "Autovalue will automatically add implementation") From 2de12fee5a6edbceed53bfd5c3f068f1c4d6d63f Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 29 Oct 2024 10:01:35 -0500 Subject: [PATCH 641/901] fix(deps): update dependency io.prometheus:prometheus-metrics-exporter-httpserver to v1.3.2 (#6805) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Co-authored-by: Jack Berg --- dependencyManagement/build.gradle.kts | 2 +- .../prometheus/Otel2PrometheusConverter.java | 27 ++++++++++--------- .../prometheus/PrometheusHttpServerTest.java | 4 +-- 3 files changed, 18 insertions(+), 15 deletions(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index 17faea7240c..5acf1a368f5 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -71,7 +71,7 @@ val DEPENDENCIES = listOf( "io.opentelemetry.proto:opentelemetry-proto:1.3.2-alpha", "io.opentracing:opentracing-api:0.33.0", "io.opentracing:opentracing-noop:0.33.0", - "io.prometheus:prometheus-metrics-exporter-httpserver:1.3.1", + "io.prometheus:prometheus-metrics-exporter-httpserver:1.3.2", "junit:junit:4.13.2", "nl.jqno.equalsverifier:equalsverifier:3.17.1", "org.awaitility:awaitility:4.2.2", diff --git a/exporters/prometheus/src/main/java/io/opentelemetry/exporter/prometheus/Otel2PrometheusConverter.java b/exporters/prometheus/src/main/java/io/opentelemetry/exporter/prometheus/Otel2PrometheusConverter.java index e1cb84d9766..f3a6eef744e 100644 --- a/exporters/prometheus/src/main/java/io/opentelemetry/exporter/prometheus/Otel2PrometheusConverter.java +++ b/exporters/prometheus/src/main/java/io/opentelemetry/exporter/prometheus/Otel2PrometheusConverter.java @@ -33,6 +33,7 @@ import io.prometheus.metrics.model.snapshots.ClassicHistogramBuckets; import io.prometheus.metrics.model.snapshots.CounterSnapshot; import io.prometheus.metrics.model.snapshots.CounterSnapshot.CounterDataPointSnapshot; +import io.prometheus.metrics.model.snapshots.DataPointSnapshot; import io.prometheus.metrics.model.snapshots.Exemplar; import io.prometheus.metrics.model.snapshots.Exemplars; import io.prometheus.metrics.model.snapshots.GaugeSnapshot; @@ -109,11 +110,11 @@ MetricSnapshots convert(@Nullable Collection metricDataCollection) { if (metricDataCollection == null || metricDataCollection.isEmpty()) { return MetricSnapshots.of(); } - Map snapshotsByName = new HashMap<>(metricDataCollection.size()); + Map> snapshotsByName = new HashMap<>(metricDataCollection.size()); Resource resource = null; Set scopes = new LinkedHashSet<>(); for (MetricData metricData : metricDataCollection) { - MetricSnapshot snapshot = convert(metricData); + MetricSnapshot snapshot = convert(metricData); if (snapshot == null) { continue; } @@ -135,7 +136,7 @@ MetricSnapshots convert(@Nullable Collection metricDataCollection) { } @Nullable - private MetricSnapshot convert(MetricData metricData) { + private MetricSnapshot convert(MetricData metricData) { // Note that AggregationTemporality.DELTA should never happen // because PrometheusMetricReader#getAggregationTemporality returns CUMULATIVE. @@ -548,10 +549,10 @@ private static MetricMetadata convertMetadata(MetricData metricData) { } private static void putOrMerge( - Map snapshotsByName, MetricSnapshot snapshot) { + Map> snapshotsByName, MetricSnapshot snapshot) { String name = snapshot.getMetadata().getPrometheusName(); if (snapshotsByName.containsKey(name)) { - MetricSnapshot merged = merge(snapshotsByName.get(name), snapshot); + MetricSnapshot merged = merge(snapshotsByName.get(name), snapshot); if (merged != null) { snapshotsByName.put(name, merged); } @@ -567,7 +568,9 @@ private static void putOrMerge( * type. If the type differs, we log a message and drop one of them. */ @Nullable - private static MetricSnapshot merge(MetricSnapshot a, MetricSnapshot b) { + @SuppressWarnings("unchecked") + private static MetricSnapshot merge( + MetricSnapshot a, MetricSnapshot b) { MetricMetadata metadata = mergeMetadata(a.getMetadata(), b.getMetadata()); if (metadata == null) { return null; @@ -577,27 +580,27 @@ private static MetricSnapshot merge(MetricSnapshot a, MetricSnapshot b) { List dataPoints = new ArrayList<>(numberOfDataPoints); dataPoints.addAll(((GaugeSnapshot) a).getDataPoints()); dataPoints.addAll(((GaugeSnapshot) b).getDataPoints()); - return new GaugeSnapshot(metadata, dataPoints); + return (MetricSnapshot) new GaugeSnapshot(metadata, dataPoints); } else if (a instanceof CounterSnapshot && b instanceof CounterSnapshot) { List dataPoints = new ArrayList<>(numberOfDataPoints); dataPoints.addAll(((CounterSnapshot) a).getDataPoints()); dataPoints.addAll(((CounterSnapshot) b).getDataPoints()); - return new CounterSnapshot(metadata, dataPoints); + return (MetricSnapshot) new CounterSnapshot(metadata, dataPoints); } else if (a instanceof HistogramSnapshot && b instanceof HistogramSnapshot) { List dataPoints = new ArrayList<>(numberOfDataPoints); dataPoints.addAll(((HistogramSnapshot) a).getDataPoints()); dataPoints.addAll(((HistogramSnapshot) b).getDataPoints()); - return new HistogramSnapshot(metadata, dataPoints); + return (MetricSnapshot) new HistogramSnapshot(metadata, dataPoints); } else if (a instanceof SummarySnapshot && b instanceof SummarySnapshot) { List dataPoints = new ArrayList<>(numberOfDataPoints); dataPoints.addAll(((SummarySnapshot) a).getDataPoints()); dataPoints.addAll(((SummarySnapshot) b).getDataPoints()); - return new SummarySnapshot(metadata, dataPoints); + return (MetricSnapshot) new SummarySnapshot(metadata, dataPoints); } else if (a instanceof InfoSnapshot && b instanceof InfoSnapshot) { List dataPoints = new ArrayList<>(numberOfDataPoints); dataPoints.addAll(((InfoSnapshot) a).getDataPoints()); dataPoints.addAll(((InfoSnapshot) b).getDataPoints()); - return new InfoSnapshot(metadata, dataPoints); + return (MetricSnapshot) new InfoSnapshot(metadata, dataPoints); } else { THROTTLING_LOGGER.log( Level.WARNING, @@ -638,7 +641,7 @@ private static MetricMetadata mergeMetadata(MetricMetadata a, MetricMetadata b) return new MetricMetadata(name, help, unit); } - private static String typeString(MetricSnapshot snapshot) { + private static String typeString(MetricSnapshot snapshot) { // Simple helper for a log message. return snapshot.getClass().getSimpleName().replace("Snapshot", "").toLowerCase(Locale.ENGLISH); } diff --git a/exporters/prometheus/src/test/java/io/opentelemetry/exporter/prometheus/PrometheusHttpServerTest.java b/exporters/prometheus/src/test/java/io/opentelemetry/exporter/prometheus/PrometheusHttpServerTest.java index 57726a47f63..8cf1440a023 100644 --- a/exporters/prometheus/src/test/java/io/opentelemetry/exporter/prometheus/PrometheusHttpServerTest.java +++ b/exporters/prometheus/src/test/java/io/opentelemetry/exporter/prometheus/PrometheusHttpServerTest.java @@ -42,9 +42,9 @@ import io.opentelemetry.sdk.resources.Resource; import io.prometheus.metrics.exporter.httpserver.HTTPServer; import io.prometheus.metrics.exporter.httpserver.MetricsHandler; -import io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics; +import io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics; import io.prometheus.metrics.model.registry.PrometheusRegistry; -import io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.TextFormat; +import io.prometheus.metrics.shaded.com_google_protobuf_4_28_2.TextFormat; import java.io.ByteArrayInputStream; import java.io.IOException; import java.net.ServerSocket; From 2e8bf7f9a1150f4c92f296505032a544ffd2bd51 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 30 Oct 2024 13:25:36 -0500 Subject: [PATCH 642/901] fix(deps): update dependency org.owasp:dependency-check-gradle to v11.1.0 (#6839) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- buildSrc/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts index eebfe4e46de..a00b575998d 100644 --- a/buildSrc/build.gradle.kts +++ b/buildSrc/build.gradle.kts @@ -66,7 +66,7 @@ dependencies { implementation("net.ltgt.gradle:gradle-errorprone-plugin:4.1.0") implementation("net.ltgt.gradle:gradle-nullaway-plugin:2.1.0") implementation("org.jetbrains.kotlin:kotlin-gradle-plugin:2.0.21") - implementation("org.owasp:dependency-check-gradle:11.0.0") + implementation("org.owasp:dependency-check-gradle:11.1.0") implementation("ru.vyarus:gradle-animalsniffer-plugin:1.7.1") } From ff4fe978e55d6afa0e8a9d7c3e2674c4083332f7 Mon Sep 17 00:00:00 2001 From: Trask Stalnaker Date: Fri, 1 Nov 2024 07:01:14 -0700 Subject: [PATCH 643/901] Test Windows in CI (#6824) --- .github/workflows/build.yml | 8 ++++++-- .../internal/shaded/WeakConcurrentMapTest.java | 12 ++++++++---- .../exporter/otlp/internal/OtlpConfigUtil.java | 3 +-- .../PrometheusMetricReaderProviderTest.java | 3 ++- .../okhttp/internal/RetryInterceptorTest.java | 2 +- .../opentracingshim/SpanShimTest.java | 2 +- .../AutoConfiguredOpenTelemetrySdkBuilder.java | 14 +++++++------- .../fileconfig/FileConfigurationCreateTest.java | 10 +++++++--- .../testing/assertj/AttributeAssertionTest.java | 5 ++++- .../sdk/testing/assertj/TraceAssertionsTest.java | 3 ++- 10 files changed, 39 insertions(+), 23 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 1dfc5fb6c72..a7a4430a67e 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -23,6 +23,7 @@ jobs: - macos-latest - macos-13 - ubuntu-latest + - windows-latest test-java-version: - 8 - 11 @@ -71,7 +72,8 @@ jobs: ./gradlew build ${{ matrix.coverage && 'jacocoTestReport' || '' }} -PtestJavaVersion=${{ matrix.test-java-version }} - -Porg.gradle.java.installations.paths=${{ steps.setup-java-test.outputs.path }},${{ steps.setup-java.outputs.path }} + "-Porg.gradle.java.installations.paths=${{ steps.setup-java-test.outputs.path }}" + "-Porg.gradle.java.installations.auto-download=false" env: GRADLE_ENTERPRISE_ACCESS_KEY: ${{ secrets.GRADLE_ENTERPRISE_ACCESS_KEY }} # JMH-based tests run only if this environment variable is set to true @@ -79,7 +81,9 @@ jobs: - name: Check for diff # The jApiCmp diff compares current to latest, which isn't appropriate for release branches, or for bot-generated PRs - if: ${{ !startsWith(github.ref_name, 'release/') && !startsWith(github.base_ref, 'release/') && (github.actor != 'opentelemetrybot') }} + # this fails on windows because of the bash-specific if/then/else syntax, but that's ok + # because we only need to run this validation once (on any platform) + if: ${{ matrix.os != 'windows-latest' && !startsWith(github.ref_name, 'release/') && !startsWith(github.base_ref, 'release/') && (github.actor != 'opentelemetrybot') }} run: | # need to "git add" in case any generated files did not already exist git add docs/apidiffs diff --git a/context/src/test/java/io/opentelemetry/context/internal/shaded/WeakConcurrentMapTest.java b/context/src/test/java/io/opentelemetry/context/internal/shaded/WeakConcurrentMapTest.java index 3d635be779c..6adfb18821f 100644 --- a/context/src/test/java/io/opentelemetry/context/internal/shaded/WeakConcurrentMapTest.java +++ b/context/src/test/java/io/opentelemetry/context/internal/shaded/WeakConcurrentMapTest.java @@ -25,6 +25,7 @@ package io.opentelemetry.context.internal.shaded; +import static org.awaitility.Awaitility.await; import static org.hamcrest.CoreMatchers.is; import static org.hamcrest.CoreMatchers.not; import static org.hamcrest.CoreMatchers.nullValue; @@ -75,8 +76,7 @@ void testInternalThread() throws Exception { assertThat(map.getCleanerThread(), not(nullValue(Thread.class))); new MapTestCase(map).doTest(); map.getCleanerThread().interrupt(); - Thread.sleep(200L); - assertThat(map.getCleanerThread().isAlive(), is(false)); + await().untilAsserted(() -> assertThat(map.getCleanerThread().isAlive(), is(false))); } static class KeyEqualToWeakRefOfItself { @@ -152,8 +152,12 @@ void doTest() throws Exception { assertThat(values.isEmpty(), is(true)); key1 = key2 = null; // Make eligible for GC System.gc(); - Thread.sleep(200L); - triggerClean(); + await() + .untilAsserted( + () -> { + triggerClean(); + assertThat(map.approximateSize(), is(2)); + }); assertThat(map.get(key3), is(value3)); assertThat(map.getIfPresent(key3), is(value3)); assertThat(map.get(key4), is(value4)); diff --git a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/OtlpConfigUtil.java b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/OtlpConfigUtil.java index 5040280850f..999fc412a5a 100644 --- a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/OtlpConfigUtil.java +++ b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/OtlpConfigUtil.java @@ -322,8 +322,7 @@ private static byte[] readFileBytes(@Nullable String filePath) { if (!file.exists()) { throw new ConfigurationException("Invalid OTLP certificate/key path: " + filePath); } - try { - RandomAccessFile raf = new RandomAccessFile(file, "r"); + try (RandomAccessFile raf = new RandomAccessFile(file, "r")) { byte[] bytes = new byte[(int) raf.length()]; raf.readFully(bytes); return bytes; diff --git a/exporters/prometheus/src/test/java/io/opentelemetry/exporter/prometheus/internal/PrometheusMetricReaderProviderTest.java b/exporters/prometheus/src/test/java/io/opentelemetry/exporter/prometheus/internal/PrometheusMetricReaderProviderTest.java index 7945514af96..1c00a604e17 100644 --- a/exporters/prometheus/src/test/java/io/opentelemetry/exporter/prometheus/internal/PrometheusMetricReaderProviderTest.java +++ b/exporters/prometheus/src/test/java/io/opentelemetry/exporter/prometheus/internal/PrometheusMetricReaderProviderTest.java @@ -96,7 +96,8 @@ void createMetricReader_WithConfiguration() throws IOException { .extracting("server", as(InstanceOfAssertFactories.type(HttpServer.class))) .satisfies( server -> { - assertThat(server.getAddress().getHostName()).isEqualTo("localhost"); + assertThat(server.getAddress().getHostName()) + .isIn("localhost", "127.0.0.1", "kubernetes.docker.internal"); assertThat(server.getAddress().getPort()).isEqualTo(port); }); assertThat(metricReader.getMemoryMode()).isEqualTo(MemoryMode.IMMUTABLE_DATA); diff --git a/exporters/sender/okhttp/src/test/java/io/opentelemetry/exporter/sender/okhttp/internal/RetryInterceptorTest.java b/exporters/sender/okhttp/src/test/java/io/opentelemetry/exporter/sender/okhttp/internal/RetryInterceptorTest.java index 1a6656c6217..8b47700e88b 100644 --- a/exporters/sender/okhttp/src/test/java/io/opentelemetry/exporter/sender/okhttp/internal/RetryInterceptorTest.java +++ b/exporters/sender/okhttp/src/test/java/io/opentelemetry/exporter/sender/okhttp/internal/RetryInterceptorTest.java @@ -172,7 +172,7 @@ void connectException() throws Exception { client .newCall(new Request.Builder().url("http://localhost:" + openPort).build()) .execute()) - .isInstanceOf(ConnectException.class); + .isInstanceOfAny(ConnectException.class, SocketTimeoutException.class); verify(isRetryableException, times(5)).apply(any()); // Should retry maxAttempts, and sleep maxAttempts - 1 times diff --git a/opentracing-shim/src/test/java/io/opentelemetry/opentracingshim/SpanShimTest.java b/opentracing-shim/src/test/java/io/opentelemetry/opentracingshim/SpanShimTest.java index 4014739e2f2..f681efe3938 100644 --- a/opentracing-shim/src/test/java/io/opentelemetry/opentracingshim/SpanShimTest.java +++ b/opentracing-shim/src/test/java/io/opentelemetry/opentracingshim/SpanShimTest.java @@ -135,7 +135,7 @@ void baggage_multipleThreads() throws Exception { IntStream.range(0, baggageItemsCount) .forEach(i -> executor.execute(() -> spanShim.setBaggageItem("key-" + i, "value-" + i))); executor.shutdown(); - executor.awaitTermination(5, TimeUnit.SECONDS); + executor.awaitTermination(10, TimeUnit.SECONDS); for (int i = 0; i < baggageItemsCount; i++) { assertThat(spanShim.getBaggageItem("key-" + i)).isEqualTo("value-" + i); diff --git a/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/AutoConfiguredOpenTelemetrySdkBuilder.java b/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/AutoConfiguredOpenTelemetrySdkBuilder.java index 995417b8fd7..1c293a002cd 100644 --- a/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/AutoConfiguredOpenTelemetrySdkBuilder.java +++ b/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/AutoConfiguredOpenTelemetrySdkBuilder.java @@ -541,13 +541,7 @@ private static AutoConfiguredOpenTelemetrySdk maybeConfigureFromFile( return null; } logger.fine("Autoconfiguring from configuration file: " + configurationFile); - FileInputStream fis; - try { - fis = new FileInputStream(configurationFile); - } catch (FileNotFoundException e) { - throw new ConfigurationException("Configuration file not found", e); - } - try { + try (FileInputStream fis = new FileInputStream(configurationFile)) { Class configurationFactory = Class.forName("io.opentelemetry.sdk.extension.incubator.fileconfig.FileConfiguration"); Method parse = configurationFactory.getMethod("parse", InputStream.class); @@ -567,6 +561,8 @@ private static AutoConfiguredOpenTelemetrySdk maybeConfigureFromFile( // resource return AutoConfiguredOpenTelemetrySdk.create( sdk, Resource.getDefault(), null, structuredConfigProperties); + } catch (FileNotFoundException e) { + throw new ConfigurationException("Configuration file not found", e); } catch (ClassNotFoundException | NoSuchMethodException | IllegalAccessException e) { throw new ConfigurationException( "Error configuring from file. Is opentelemetry-sdk-extension-incubator on the classpath?", @@ -577,6 +573,10 @@ private static AutoConfiguredOpenTelemetrySdk maybeConfigureFromFile( throw (ConfigurationException) cause; } throw new ConfigurationException("Unexpected error configuring from file", e); + } catch (IOException e) { + // IOException (other than FileNotFoundException which is caught above) is only thrown + // above by FileInputStream.close() + throw new ConfigurationException("Error closing file", e); } } diff --git a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/FileConfigurationCreateTest.java b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/FileConfigurationCreateTest.java index 4ed182f03f4..1230ce73832 100644 --- a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/FileConfigurationCreateTest.java +++ b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/FileConfigurationCreateTest.java @@ -81,12 +81,16 @@ void parseAndCreate_Examples(@TempDir Path tempDir) String rewrittenExampleContent = exampleContent .replaceAll( - "certificate: .*\n", "certificate: " + certificatePath + System.lineSeparator()) + "certificate: .*\n", + "certificate: " + certificatePath.replace("\\", "\\\\") + System.lineSeparator()) .replaceAll( - "client_key: .*\n", "client_key: " + clientKeyPath + System.lineSeparator()) + "client_key: .*\n", + "client_key: " + clientKeyPath.replace("\\", "\\\\") + System.lineSeparator()) .replaceAll( "client_certificate: .*\n", - "client_certificate: " + clientCertificatePath + System.lineSeparator()); + "client_certificate: " + + clientCertificatePath.replace("\\", "\\\\") + + System.lineSeparator()); InputStream is = new ByteArrayInputStream(rewrittenExampleContent.getBytes(StandardCharsets.UTF_8)); diff --git a/sdk/testing/src/test/java/io/opentelemetry/sdk/testing/assertj/AttributeAssertionTest.java b/sdk/testing/src/test/java/io/opentelemetry/sdk/testing/assertj/AttributeAssertionTest.java index aa229eefb31..44c09e39af2 100644 --- a/sdk/testing/src/test/java/io/opentelemetry/sdk/testing/assertj/AttributeAssertionTest.java +++ b/sdk/testing/src/test/java/io/opentelemetry/sdk/testing/assertj/AttributeAssertionTest.java @@ -23,6 +23,9 @@ void nullAttr_errorMessageContainsAttrName() { .getAssertion() .accept(AttributeAssertion.attributeValueAssertion(key, null))) .isInstanceOf(AssertionError.class) - .hasMessage("[STRING attribute 'flib'] \nExpecting actual not to be null"); + .hasMessage( + "[STRING attribute 'flib'] " + + System.lineSeparator() + + "Expecting actual not to be null"); } } diff --git a/sdk/testing/src/test/java/io/opentelemetry/sdk/testing/assertj/TraceAssertionsTest.java b/sdk/testing/src/test/java/io/opentelemetry/sdk/testing/assertj/TraceAssertionsTest.java index 18ac3849690..feb5eb9462a 100644 --- a/sdk/testing/src/test/java/io/opentelemetry/sdk/testing/assertj/TraceAssertionsTest.java +++ b/sdk/testing/src/test/java/io/opentelemetry/sdk/testing/assertj/TraceAssertionsTest.java @@ -687,7 +687,8 @@ void hasSpansSatisfyingExactly() { .hasTracesSatisfyingExactly( trace -> trace.hasSpansSatisfyingExactly(span -> span.hasSpanId(SPAN_ID1)))) .isInstanceOf(AssertionError.class) - .hasMessageStartingWith("[Trace 0] \n" + "Expected size: 1 but was: 2"); + .hasMessageStartingWith( + "[Trace 0] " + System.lineSeparator() + "Expected size: 1 but was: 2"); // test asserting spans in wrong oder assertThatThrownBy( From d9fce84689031883155ad0959948fa7fda7295f4 Mon Sep 17 00:00:00 2001 From: jack-berg <34418638+jack-berg@users.noreply.github.com> Date: Fri, 1 Nov 2024 14:29:48 -0500 Subject: [PATCH 644/901] Fix ConfigUtil#getString ConcurrentModificationException (#6841) Co-authored-by: neugartf Co-authored-by: Fabian Neugart --- .../api/internal/ConfigUtil.java | 16 +++++- .../api/internal/ConfigUtilTest.java | 49 +++++++++++++++++++ .../spi/internal/DefaultConfigProperties.java | 3 +- 3 files changed, 66 insertions(+), 2 deletions(-) diff --git a/api/all/src/main/java/io/opentelemetry/api/internal/ConfigUtil.java b/api/all/src/main/java/io/opentelemetry/api/internal/ConfigUtil.java index 56d2d378d72..3a10a23cb99 100644 --- a/api/all/src/main/java/io/opentelemetry/api/internal/ConfigUtil.java +++ b/api/all/src/main/java/io/opentelemetry/api/internal/ConfigUtil.java @@ -5,8 +5,10 @@ package io.opentelemetry.api.internal; +import java.util.ConcurrentModificationException; import java.util.Locale; import java.util.Map; +import java.util.Properties; import javax.annotation.Nullable; /** @@ -19,6 +21,17 @@ public final class ConfigUtil { private ConfigUtil() {} + /** + * Returns a copy of system properties which is safe to iterate over. + * + *

      In java 8 and android environments, iterating through system properties may trigger {@link + * ConcurrentModificationException}. This method ensures callers can iterate safely without risk + * of exception. See https://github.com/open-telemetry/opentelemetry-java/issues/6732 for details. + */ + public static Properties safeSystemProperties() { + return (Properties) System.getProperties().clone(); + } + /** * Return the system property or environment variable for the {@code key}. * @@ -33,8 +46,9 @@ private ConfigUtil() {} */ public static String getString(String key, String defaultValue) { String normalizedKey = normalizePropertyKey(key); + String systemProperty = - System.getProperties().entrySet().stream() + safeSystemProperties().entrySet().stream() .filter(entry -> normalizedKey.equals(normalizePropertyKey(entry.getKey().toString()))) .map(entry -> entry.getValue().toString()) .findFirst() diff --git a/api/all/src/test/java/io/opentelemetry/api/internal/ConfigUtilTest.java b/api/all/src/test/java/io/opentelemetry/api/internal/ConfigUtilTest.java index f7dde6a9735..a546c32862b 100644 --- a/api/all/src/test/java/io/opentelemetry/api/internal/ConfigUtilTest.java +++ b/api/all/src/test/java/io/opentelemetry/api/internal/ConfigUtilTest.java @@ -6,7 +6,15 @@ package io.opentelemetry.api.internal; import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatCode; +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.Future; import org.junit.jupiter.api.Test; import org.junitpioneer.jupiter.SetSystemProperty; @@ -56,4 +64,45 @@ void defaultIfnull() { assertThat(ConfigUtil.defaultIfNull("val1", "val2")).isEqualTo("val1"); assertThat(ConfigUtil.defaultIfNull(null, "val2")).isEqualTo("val2"); } + + @Test + @SuppressWarnings("ReturnValueIgnored") + void systemPropertiesConcurrentAccess() throws ExecutionException, InterruptedException { + int threads = 4; + ExecutorService executor = Executors.newFixedThreadPool(threads); + try { + int cycles = 1000; + CountDownLatch latch = new CountDownLatch(1); + List> futures = new ArrayList<>(); + for (int i = 0; i < threads; i++) { + futures.add( + executor.submit( + () -> { + try { + latch.await(); + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + } + + for (int j = 0; j < cycles; j++) { + String property = "prop " + j; + System.setProperty(property, "a"); + System.getProperties().remove(property); + } + })); + } + + latch.countDown(); + for (int i = 0; i < cycles; i++) { + assertThatCode(() -> ConfigUtil.getString("x", "y")).doesNotThrowAnyException(); + } + + for (Future future : futures) { + future.get(); + } + + } finally { + executor.shutdownNow(); + } + } } diff --git a/sdk-extensions/autoconfigure-spi/src/main/java/io/opentelemetry/sdk/autoconfigure/spi/internal/DefaultConfigProperties.java b/sdk-extensions/autoconfigure-spi/src/main/java/io/opentelemetry/sdk/autoconfigure/spi/internal/DefaultConfigProperties.java index af0e4bae2bf..b5496df7c48 100644 --- a/sdk-extensions/autoconfigure-spi/src/main/java/io/opentelemetry/sdk/autoconfigure/spi/internal/DefaultConfigProperties.java +++ b/sdk-extensions/autoconfigure-spi/src/main/java/io/opentelemetry/sdk/autoconfigure/spi/internal/DefaultConfigProperties.java @@ -47,7 +47,8 @@ public final class DefaultConfigProperties implements ConfigProperties { * priority over environment variables. */ public static DefaultConfigProperties create(Map defaultProperties) { - return new DefaultConfigProperties(System.getProperties(), System.getenv(), defaultProperties); + return new DefaultConfigProperties( + ConfigUtil.safeSystemProperties(), System.getenv(), defaultProperties); } /** From e4f39789bdef28f33ede79e20f4fc714fd10c173 Mon Sep 17 00:00:00 2001 From: jack-berg <34418638+jack-berg@users.noreply.github.com> Date: Fri, 1 Nov 2024 15:55:14 -0500 Subject: [PATCH 645/901] Add error prone checks for internal javadoc and private constructors (#6844) --- .../otel.errorprone-conventions.gradle.kts | 5 +- custom-checks/build.gradle.kts | 82 +++++++++++++++++++ .../customchecks/OtelInternalJavadoc.java | 72 ++++++++++++++++ ...OtelPrivateConstructorForUtilityClass.java | 38 +++++++++ ...m.google.errorprone.bugpatterns.BugChecker | 2 + .../customchecks/OtelInternalJavadocTest.java | 24 ++++++ .../InternalJavadocNegativeCases.java | 21 +++++ .../InternalJavadocPositiveCases.java | 17 ++++ dependencyManagement/build.gradle.kts | 1 + .../internal/FailedExportException.java | 14 +++- .../internal/InstrumentationUtil.java | 2 +- .../exporter/internal/http/HttpSender.java | 7 +- .../internal/marshal/MarshalerContext.java | 7 ++ .../otlp/KeyValueStatelessMarshaler.java | 7 +- .../internal/otlp/traces/SpanFlags.java | 3 + .../spi/internal/AutoConfigureListener.java | 3 + .../spi/internal/ComponentProvider.java | 3 + .../internal/StructuredConfigProperties.java | 3 + .../internal/EnvironmentResourceProvider.java | 3 + .../internal/DynamicPrimitiveLongList.java | 4 +- .../sdk/logs/internal/LoggerConfig.java | 3 + .../logs/internal/SdkEventLoggerProvider.java | 3 + .../ExponentialHistogramIndexerBenchmark.java | 7 +- .../sdk/metrics/internal/MeterConfig.java | 3 + .../internal/data/ImmutableSummaryData.java | 2 +- .../data/ImmutableSummaryPointData.java | 2 +- .../data/ImmutableValueAtQuantile.java | 2 +- .../metrics/internal/descriptor/Advice.java | 8 ++ .../sdk/trace/internal/TracerConfig.java | 3 + settings.gradle.kts | 1 + 30 files changed, 340 insertions(+), 12 deletions(-) create mode 100644 custom-checks/build.gradle.kts create mode 100644 custom-checks/src/main/java/io/opentelemetry/gradle/customchecks/OtelInternalJavadoc.java create mode 100644 custom-checks/src/main/java/io/opentelemetry/gradle/customchecks/OtelPrivateConstructorForUtilityClass.java create mode 100644 custom-checks/src/main/resources/META-INF/services/com.google.errorprone.bugpatterns.BugChecker create mode 100644 custom-checks/src/test/java/io/opentelemetry/gradle/customchecks/OtelInternalJavadocTest.java create mode 100644 custom-checks/src/test/resources/io/opentelemetry/gradle/customchecks/internal/InternalJavadocNegativeCases.java create mode 100644 custom-checks/src/test/resources/io/opentelemetry/gradle/customchecks/internal/InternalJavadocPositiveCases.java diff --git a/buildSrc/src/main/kotlin/otel.errorprone-conventions.gradle.kts b/buildSrc/src/main/kotlin/otel.errorprone-conventions.gradle.kts index e96a95f7992..be908aaae88 100644 --- a/buildSrc/src/main/kotlin/otel.errorprone-conventions.gradle.kts +++ b/buildSrc/src/main/kotlin/otel.errorprone-conventions.gradle.kts @@ -10,6 +10,7 @@ plugins { dependencies { errorprone("com.google.errorprone:error_prone_core") errorprone("com.uber.nullaway:nullaway") + errorprone(project(":custom-checks")) } val disableErrorProne = properties["disableErrorProne"]?.toString()?.toBoolean() ?: false @@ -86,9 +87,11 @@ tasks { // cognitive load is dubious. disable("YodaCondition") - if (name.contains("Jmh") || name.contains("Test")) { + if ((name.contains("Jmh") || name.contains("Test") || project.name.contains("testing-internal")) && !project.name.equals("custom-checks")) { // Allow underscore in test-type method names disable("MemberName") + // Internal javadoc not needed for test or jmh classes + disable("OtelInternalJavadoc") } option("NullAway:CustomContractAnnotations", "io.opentelemetry.api.internal.Contract") diff --git a/custom-checks/build.gradle.kts b/custom-checks/build.gradle.kts new file mode 100644 index 00000000000..5167a979be0 --- /dev/null +++ b/custom-checks/build.gradle.kts @@ -0,0 +1,82 @@ +plugins { + id("otel.java-conventions") +} + +dependencies { + implementation("com.google.errorprone:error_prone_core") + + testImplementation("com.google.errorprone:error_prone_test_helpers") +} + +otelJava.moduleName.set("io.opentelemetry.javaagent.customchecks") + +// We cannot use "--release" javac option here because that will forbid exporting com.sun.tools package. +// We also can't seem to use the toolchain without the "--release" option. So disable everything. + +java { + sourceCompatibility = JavaVersion.VERSION_17 + targetCompatibility = JavaVersion.VERSION_17 + toolchain { + languageVersion.set(null as JavaLanguageVersion?) + } +} + +tasks { + withType().configureEach { + with(options) { + release.set(null as Int?) + + compilerArgs.addAll( + listOf( + "--add-exports", + "jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED", + "--add-exports", + "jdk.compiler/com.sun.tools.javac.code=ALL-UNNAMED", + "--add-exports", + "jdk.compiler/com.sun.tools.javac.comp=ALL-UNNAMED", + "--add-exports", + "jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED", + "--add-exports", + "jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED", + ), + ) + } + } + + // only test on java 17+ + val testJavaVersion: String? by project + if (testJavaVersion != null && Integer.valueOf(testJavaVersion) < 17) { + test { + enabled = false + } + } +} + +tasks.withType().configureEach { + // required on jdk17 + jvmArgs("--add-opens=jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED") + jvmArgs("--add-opens=jdk.compiler/com.sun.tools.javac.code=ALL-UNNAMED") + jvmArgs("--add-opens=jdk.compiler/com.sun.tools.javac.comp=ALL-UNNAMED") + jvmArgs("--add-opens=jdk.compiler/com.sun.tools.javac.file=ALL-UNNAMED") + jvmArgs("--add-opens=jdk.compiler/com.sun.tools.javac.main=ALL-UNNAMED") + jvmArgs("--add-opens=jdk.compiler/com.sun.tools.javac.parser=ALL-UNNAMED") + jvmArgs("--add-opens=jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED") + jvmArgs("--add-opens=jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED") + jvmArgs("-XX:+IgnoreUnrecognizedVMOptions") +} + +tasks.withType().configureEach { + // using com.sun.tools.javac.api.JavacTrees breaks javadoc generation + enabled = false +} + +// Our conventions apply this project as a dependency in the errorprone configuration, which would cause +// a circular dependency if trying to compile this project with that still there. So we filter this +// project out. +configurations { + named("errorprone") { + dependencies.removeIf { + it is ProjectDependency && it.dependencyProject == project + } + } +} diff --git a/custom-checks/src/main/java/io/opentelemetry/gradle/customchecks/OtelInternalJavadoc.java b/custom-checks/src/main/java/io/opentelemetry/gradle/customchecks/OtelInternalJavadoc.java new file mode 100644 index 00000000000..3ac6b964dac --- /dev/null +++ b/custom-checks/src/main/java/io/opentelemetry/gradle/customchecks/OtelInternalJavadoc.java @@ -0,0 +1,72 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.gradle.customchecks; + +import static com.google.errorprone.BugPattern.SeverityLevel.WARNING; + +import com.google.errorprone.BugPattern; +import com.google.errorprone.VisitorState; +import com.google.errorprone.bugpatterns.BugChecker; +import com.google.errorprone.matchers.Description; +import com.sun.source.doctree.DocCommentTree; +import com.sun.source.tree.ClassTree; +import com.sun.source.tree.PackageTree; +import com.sun.tools.javac.api.JavacTrees; +import java.util.regex.Pattern; +import javax.annotation.Nullable; +import javax.lang.model.element.Modifier; + +@BugPattern( + summary = + "This public internal class doesn't end with the javadoc disclaimer: \"" + + OtelInternalJavadoc.EXPECTED_INTERNAL_COMMENT + + "\"", + severity = WARNING) +public class OtelInternalJavadoc extends BugChecker implements BugChecker.ClassTreeMatcher { + + private static final long serialVersionUID = 1L; + + private static final Pattern INTERNAL_PACKAGE_PATTERN = Pattern.compile("\\binternal\\b"); + + static final String EXPECTED_INTERNAL_COMMENT = + "This class is internal and is hence not for public use." + + " Its APIs are unstable and can change at any time."; + + @Override + public Description matchClass(ClassTree tree, VisitorState state) { + if (!isPublic(tree) || !isInternal(state) || tree.getSimpleName().toString().endsWith("Test")) { + return Description.NO_MATCH; + } + String javadoc = getJavadoc(state); + if (javadoc != null && javadoc.contains(EXPECTED_INTERNAL_COMMENT)) { + return Description.NO_MATCH; + } + return describeMatch(tree); + } + + private static boolean isPublic(ClassTree tree) { + return tree.getModifiers().getFlags().contains(Modifier.PUBLIC); + } + + private static boolean isInternal(VisitorState state) { + PackageTree packageTree = state.getPath().getCompilationUnit().getPackage(); + if (packageTree == null) { + return false; + } + String packageName = state.getSourceForNode(packageTree.getPackageName()); + return packageName != null && INTERNAL_PACKAGE_PATTERN.matcher(packageName).find(); + } + + @Nullable + private static String getJavadoc(VisitorState state) { + DocCommentTree docCommentTree = + JavacTrees.instance(state.context).getDocCommentTree(state.getPath()); + if (docCommentTree == null) { + return null; + } + return docCommentTree.toString().replace("\n", ""); + } +} diff --git a/custom-checks/src/main/java/io/opentelemetry/gradle/customchecks/OtelPrivateConstructorForUtilityClass.java b/custom-checks/src/main/java/io/opentelemetry/gradle/customchecks/OtelPrivateConstructorForUtilityClass.java new file mode 100644 index 00000000000..5aff2f1db4c --- /dev/null +++ b/custom-checks/src/main/java/io/opentelemetry/gradle/customchecks/OtelPrivateConstructorForUtilityClass.java @@ -0,0 +1,38 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.gradle.customchecks; + +import static com.google.errorprone.BugPattern.SeverityLevel.WARNING; +import static com.google.errorprone.matchers.Description.NO_MATCH; + +import com.google.errorprone.BugPattern; +import com.google.errorprone.VisitorState; +import com.google.errorprone.bugpatterns.BugChecker; +import com.google.errorprone.bugpatterns.PrivateConstructorForUtilityClass; +import com.google.errorprone.matchers.Description; +import com.sun.source.tree.ClassTree; + +@BugPattern( + summary = + "Classes which are not intended to be instantiated should be made non-instantiable with a private constructor. This includes utility classes (classes with only static members), and the main class.", + severity = WARNING) +public class OtelPrivateConstructorForUtilityClass extends BugChecker + implements BugChecker.ClassTreeMatcher { + + private static final long serialVersionUID = 1L; + + private final PrivateConstructorForUtilityClass delegate = + new PrivateConstructorForUtilityClass(); + + @Override + public Description matchClass(ClassTree tree, VisitorState state) { + Description description = delegate.matchClass(tree, state); + if (description == NO_MATCH) { + return description; + } + return describeMatch(tree); + } +} diff --git a/custom-checks/src/main/resources/META-INF/services/com.google.errorprone.bugpatterns.BugChecker b/custom-checks/src/main/resources/META-INF/services/com.google.errorprone.bugpatterns.BugChecker new file mode 100644 index 00000000000..e73ad8bbe73 --- /dev/null +++ b/custom-checks/src/main/resources/META-INF/services/com.google.errorprone.bugpatterns.BugChecker @@ -0,0 +1,2 @@ +io.opentelemetry.gradle.customchecks.OtelInternalJavadoc +io.opentelemetry.gradle.customchecks.OtelPrivateConstructorForUtilityClass diff --git a/custom-checks/src/test/java/io/opentelemetry/gradle/customchecks/OtelInternalJavadocTest.java b/custom-checks/src/test/java/io/opentelemetry/gradle/customchecks/OtelInternalJavadocTest.java new file mode 100644 index 00000000000..ae26844ca72 --- /dev/null +++ b/custom-checks/src/test/java/io/opentelemetry/gradle/customchecks/OtelInternalJavadocTest.java @@ -0,0 +1,24 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.gradle.customchecks; + +import com.google.errorprone.CompilationTestHelper; +import org.junit.jupiter.api.Test; + +class OtelInternalJavadocTest { + + @Test + void test() { + doTest("internal/InternalJavadocPositiveCases.java"); + doTest("internal/InternalJavadocNegativeCases.java"); + } + + private static void doTest(String path) { + CompilationTestHelper.newInstance(OtelInternalJavadoc.class, OtelInternalJavadocTest.class) + .addSourceFile(path) + .doTest(); + } +} diff --git a/custom-checks/src/test/resources/io/opentelemetry/gradle/customchecks/internal/InternalJavadocNegativeCases.java b/custom-checks/src/test/resources/io/opentelemetry/gradle/customchecks/internal/InternalJavadocNegativeCases.java new file mode 100644 index 00000000000..973c13aa2a3 --- /dev/null +++ b/custom-checks/src/test/resources/io/opentelemetry/gradle/customchecks/internal/InternalJavadocNegativeCases.java @@ -0,0 +1,21 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.gradle.customchecks.internal; + +/** + * This class is internal and is hence not for public use. Its APIs are unstable and can change at + * any time. + */ +public class InternalJavadocNegativeCases { + + /** + * This class is internal and is hence not for public use. Its APIs are unstable and can change at + * any time. + */ + public static class One {} + + static class Two {} +} diff --git a/custom-checks/src/test/resources/io/opentelemetry/gradle/customchecks/internal/InternalJavadocPositiveCases.java b/custom-checks/src/test/resources/io/opentelemetry/gradle/customchecks/internal/InternalJavadocPositiveCases.java new file mode 100644 index 00000000000..dc36e5ef636 --- /dev/null +++ b/custom-checks/src/test/resources/io/opentelemetry/gradle/customchecks/internal/InternalJavadocPositiveCases.java @@ -0,0 +1,17 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.gradle.customchecks.internal; + +// BUG: Diagnostic contains: doesn't end with the javadoc disclaimer +public class InternalJavadocPositiveCases { + + // BUG: Diagnostic contains: doesn't end with the javadoc disclaimer + public static class One {} + + /** Doesn't have the disclaimer. */ + // BUG: Diagnostic contains: doesn't end with the javadoc disclaimer + public static class Two {} +} diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index 5acf1a368f5..7b6c1d0a55b 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -38,6 +38,7 @@ val DEPENDENCIES = listOf( "com.google.auto.value:auto-value-annotations:${autoValueVersion}", "com.google.errorprone:error_prone_annotations:${errorProneVersion}", "com.google.errorprone:error_prone_core:${errorProneVersion}", + "com.google.errorprone:error_prone_test_helpers:${errorProneVersion}", "io.opencensus:opencensus-api:${opencensusVersion}", "io.opencensus:opencensus-impl-core:${opencensusVersion}", "io.opencensus:opencensus-impl:${opencensusVersion}", diff --git a/exporters/common/src/main/java/io/opentelemetry/exporter/internal/FailedExportException.java b/exporters/common/src/main/java/io/opentelemetry/exporter/internal/FailedExportException.java index 74f66dbfa1f..3d229514108 100644 --- a/exporters/common/src/main/java/io/opentelemetry/exporter/internal/FailedExportException.java +++ b/exporters/common/src/main/java/io/opentelemetry/exporter/internal/FailedExportException.java @@ -46,7 +46,12 @@ public static GrpcExportException grpcFailedExceptionally(Throwable cause) { /** Returns true if the export failed with a response from the server. */ public abstract boolean failedWithResponse(); - /** Represents the failure of an HTTP exporter. */ + /** + * Represents the failure of an HTTP exporter. + * + *

      This class is internal and is hence not for public use. Its APIs are unstable and can change + * at any time. + */ public static final class HttpExportException extends FailedExportException { private static final long serialVersionUID = -6787390183017184775L; @@ -85,7 +90,12 @@ public Throwable getCause() { } } - /** Represents the failure of a gRPC exporter. */ + /** + * Represents the failure of a gRPC exporter. + * + *

      This class is internal and is hence not for public use. Its APIs are unstable and can change + * at any time. + */ public static final class GrpcExportException extends FailedExportException { private static final long serialVersionUID = -9157548250286695364L; diff --git a/exporters/common/src/main/java/io/opentelemetry/exporter/internal/InstrumentationUtil.java b/exporters/common/src/main/java/io/opentelemetry/exporter/internal/InstrumentationUtil.java index 5eddab53b76..9a88fe85060 100644 --- a/exporters/common/src/main/java/io/opentelemetry/exporter/internal/InstrumentationUtil.java +++ b/exporters/common/src/main/java/io/opentelemetry/exporter/internal/InstrumentationUtil.java @@ -9,7 +9,7 @@ /** * This class is internal and is hence not for public use. Its APIs are unstable and can change at - * any time + * any time. * * @deprecated use {@link io.opentelemetry.api.internal.InstrumentationUtil} instead. This class * should be removed once instrumentation does not refer to it anymore. diff --git a/exporters/common/src/main/java/io/opentelemetry/exporter/internal/http/HttpSender.java b/exporters/common/src/main/java/io/opentelemetry/exporter/internal/http/HttpSender.java index dc5c775a530..aec50288ebd 100644 --- a/exporters/common/src/main/java/io/opentelemetry/exporter/internal/http/HttpSender.java +++ b/exporters/common/src/main/java/io/opentelemetry/exporter/internal/http/HttpSender.java @@ -41,7 +41,12 @@ void send( /** Shutdown the sender. */ CompletableResultCode shutdown(); - /** The HTTP response. */ + /** + * The HTTP response. + * + *

      This class is internal and is hence not for public use. Its APIs are unstable and can change + * at any time. + */ interface Response { /** The HTTP status code. */ diff --git a/exporters/common/src/main/java/io/opentelemetry/exporter/internal/marshal/MarshalerContext.java b/exporters/common/src/main/java/io/opentelemetry/exporter/internal/marshal/MarshalerContext.java index a9f69459e47..80d01e84392 100644 --- a/exporters/common/src/main/java/io/opentelemetry/exporter/internal/marshal/MarshalerContext.java +++ b/exporters/common/src/main/java/io/opentelemetry/exporter/internal/marshal/MarshalerContext.java @@ -21,6 +21,9 @@ * objects, that we call data. Both integers and objects can be read from the state in the order * they were added (first in, first out). Additionally, this class provides various pools and caches * for objects that can be reused between marshalling attempts. + * + *

      This class is internal and is hence not for public use. Its APIs are unstable and can change + * at any time. */ public final class MarshalerContext { private final boolean marshalStringNoAllocation; @@ -203,6 +206,10 @@ public void reset() { private static final AtomicInteger KEY_INDEX = new AtomicInteger(); + /** + * This class is internal and is hence not for public use. Its APIs are unstable and can change at + * any time. + */ public static class Key { final int index = KEY_INDEX.getAndIncrement(); } diff --git a/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/KeyValueStatelessMarshaler.java b/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/KeyValueStatelessMarshaler.java index cd7defa9aa6..09607917322 100644 --- a/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/KeyValueStatelessMarshaler.java +++ b/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/KeyValueStatelessMarshaler.java @@ -12,7 +12,12 @@ import io.opentelemetry.exporter.internal.marshal.StatelessMarshalerUtil; import java.io.IOException; -/** A Marshaler of key value pairs. See {@link AnyValueMarshaler}. */ +/** + * A Marshaler of key value pairs. See {@link AnyValueMarshaler}. + * + *

      This class is internal and is hence not for public use. Its APIs are unstable and can change + * at any time. + */ public final class KeyValueStatelessMarshaler implements StatelessMarshaler { public static final KeyValueStatelessMarshaler INSTANCE = new KeyValueStatelessMarshaler(); diff --git a/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/traces/SpanFlags.java b/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/traces/SpanFlags.java index 06c57b90541..571be523492 100644 --- a/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/traces/SpanFlags.java +++ b/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/traces/SpanFlags.java @@ -11,6 +11,9 @@ * Represents the 32 bit span flags as * specified in the proto definition. + * + *

      This class is internal and is hence not for public use. Its APIs are unstable and can change + * at any time. */ public final class SpanFlags { // As defined at: diff --git a/sdk-extensions/autoconfigure-spi/src/main/java/io/opentelemetry/sdk/autoconfigure/spi/internal/AutoConfigureListener.java b/sdk-extensions/autoconfigure-spi/src/main/java/io/opentelemetry/sdk/autoconfigure/spi/internal/AutoConfigureListener.java index af27105cb4f..e181447adb5 100644 --- a/sdk-extensions/autoconfigure-spi/src/main/java/io/opentelemetry/sdk/autoconfigure/spi/internal/AutoConfigureListener.java +++ b/sdk-extensions/autoconfigure-spi/src/main/java/io/opentelemetry/sdk/autoconfigure/spi/internal/AutoConfigureListener.java @@ -13,6 +13,9 @@ * *

      This is not a standalone SPI. Instead, implementations of other SPIs can also implement this * interface to receive a callback with the configured SDK. + * + *

      This class is internal and is hence not for public use. Its APIs are unstable and can change + * at any time. */ public interface AutoConfigureListener { diff --git a/sdk-extensions/autoconfigure-spi/src/main/java/io/opentelemetry/sdk/autoconfigure/spi/internal/ComponentProvider.java b/sdk-extensions/autoconfigure-spi/src/main/java/io/opentelemetry/sdk/autoconfigure/spi/internal/ComponentProvider.java index b7f93b615db..4724a3d1954 100644 --- a/sdk-extensions/autoconfigure-spi/src/main/java/io/opentelemetry/sdk/autoconfigure/spi/internal/ComponentProvider.java +++ b/sdk-extensions/autoconfigure-spi/src/main/java/io/opentelemetry/sdk/autoconfigure/spi/internal/ComponentProvider.java @@ -23,6 +23,9 @@ * used, and {@link #create(StructuredConfigProperties)} is (currently) called with an empty {@link * StructuredConfigProperties}. * + *

      This class is internal and is hence not for public use. Its APIs are unstable and can change + * at any time. + * * @param the type of the SDK extension component. See {@link #getType()}. Supported values * include: {@link SpanExporter}, {@link MetricExporter}, {@link LogRecordExporter}, {@link * SpanProcessor}, {@link LogRecordProcessor}, {@link TextMapPropagator}, {@link Sampler}, diff --git a/sdk-extensions/autoconfigure-spi/src/main/java/io/opentelemetry/sdk/autoconfigure/spi/internal/StructuredConfigProperties.java b/sdk-extensions/autoconfigure-spi/src/main/java/io/opentelemetry/sdk/autoconfigure/spi/internal/StructuredConfigProperties.java index 99eff27f00b..ced88005614 100644 --- a/sdk-extensions/autoconfigure-spi/src/main/java/io/opentelemetry/sdk/autoconfigure/spi/internal/StructuredConfigProperties.java +++ b/sdk-extensions/autoconfigure-spi/src/main/java/io/opentelemetry/sdk/autoconfigure/spi/internal/StructuredConfigProperties.java @@ -21,6 +21,9 @@ * reading scalar properties, {@link #getStructured(String)} for reading children which are * themselves mappings, and {@link #getStructuredList(String)} for reading children which are * sequences of mappings. + * + *

      This class is internal and is hence not for public use. Its APIs are unstable and can change + * at any time. */ public interface StructuredConfigProperties { diff --git a/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/internal/EnvironmentResourceProvider.java b/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/internal/EnvironmentResourceProvider.java index 98af5c0d7e5..ba61f957399 100644 --- a/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/internal/EnvironmentResourceProvider.java +++ b/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/internal/EnvironmentResourceProvider.java @@ -13,6 +13,9 @@ /** * {@link ResourceProvider} for automatically configuring {@link * ResourceConfiguration#createEnvironmentResource(ConfigProperties)}. + * + *

      This class is internal and is hence not for public use. Its APIs are unstable and can change + * at any time. */ public final class EnvironmentResourceProvider implements ResourceProvider { @Override diff --git a/sdk/common/src/main/java/io/opentelemetry/sdk/internal/DynamicPrimitiveLongList.java b/sdk/common/src/main/java/io/opentelemetry/sdk/internal/DynamicPrimitiveLongList.java index e2bd0412391..7dc138ae0b5 100644 --- a/sdk/common/src/main/java/io/opentelemetry/sdk/internal/DynamicPrimitiveLongList.java +++ b/sdk/common/src/main/java/io/opentelemetry/sdk/internal/DynamicPrimitiveLongList.java @@ -43,8 +43,8 @@ * elements to zero. * * - *

      This class is an internal part of the OpenTelemetry SDK and is not intended for public use. - * Its API is unstable and subject to change. + *

      This class is internal and is hence not for public use. Its APIs are unstable and can change + * at any time. * *

      This class is not thread-safe. */ diff --git a/sdk/logs/src/main/java/io/opentelemetry/sdk/logs/internal/LoggerConfig.java b/sdk/logs/src/main/java/io/opentelemetry/sdk/logs/internal/LoggerConfig.java index 39825686c86..8fb0f7dac2e 100644 --- a/sdk/logs/src/main/java/io/opentelemetry/sdk/logs/internal/LoggerConfig.java +++ b/sdk/logs/src/main/java/io/opentelemetry/sdk/logs/internal/LoggerConfig.java @@ -17,6 +17,9 @@ /** * A collection of configuration options which define the behavior of a {@link Logger}. * + *

      This class is internal and is hence not for public use. Its APIs are unstable and can change + * at any time. + * * @see SdkLoggerProviderUtil#setLoggerConfigurator(SdkLoggerProviderBuilder, ScopeConfigurator) * @see SdkLoggerProviderUtil#addLoggerConfiguratorCondition(SdkLoggerProviderBuilder, Predicate, * LoggerConfig) diff --git a/sdk/logs/src/main/java/io/opentelemetry/sdk/logs/internal/SdkEventLoggerProvider.java b/sdk/logs/src/main/java/io/opentelemetry/sdk/logs/internal/SdkEventLoggerProvider.java index 391547201df..7a2972056a3 100644 --- a/sdk/logs/src/main/java/io/opentelemetry/sdk/logs/internal/SdkEventLoggerProvider.java +++ b/sdk/logs/src/main/java/io/opentelemetry/sdk/logs/internal/SdkEventLoggerProvider.java @@ -21,6 +21,9 @@ * *

      Delegates all calls to the configured {@link LoggerProvider}, and its {@link LoggerBuilder}s, * {@link Logger}s. + * + *

      This class is internal and is hence not for public use. Its APIs are unstable and can change + * at any time. */ public final class SdkEventLoggerProvider implements EventLoggerProvider { diff --git a/sdk/metrics/src/jmh/java/io/opentelemetry/sdk/metrics/internal/aggregator/ExponentialHistogramIndexerBenchmark.java b/sdk/metrics/src/jmh/java/io/opentelemetry/sdk/metrics/internal/aggregator/ExponentialHistogramIndexerBenchmark.java index 66c3d579e4f..304087f734f 100644 --- a/sdk/metrics/src/jmh/java/io/opentelemetry/sdk/metrics/internal/aggregator/ExponentialHistogramIndexerBenchmark.java +++ b/sdk/metrics/src/jmh/java/io/opentelemetry/sdk/metrics/internal/aggregator/ExponentialHistogramIndexerBenchmark.java @@ -21,7 +21,12 @@ import org.openjdk.jmh.annotations.State; import org.openjdk.jmh.annotations.Warmup; -/** Measures runtime cost of computing bucket indexes for exponential histograms. */ +/** + * Measures runtime cost of computing bucket indexes for exponential histograms. + * + *

      This class is internal and is hence not for public use. Its APIs are unstable and can change + * at any time. + */ @BenchmarkMode(Mode.AverageTime) @OutputTimeUnit(TimeUnit.NANOSECONDS) @Measurement(iterations = 5, time = 1) diff --git a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/MeterConfig.java b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/MeterConfig.java index 12d2c1df1b1..ededd6acdad 100644 --- a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/MeterConfig.java +++ b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/MeterConfig.java @@ -17,6 +17,9 @@ /** * A collection of configuration options which define the behavior of a {@link Meter}. * + *

      This class is internal and is hence not for public use. Its APIs are unstable and can change + * at any time. + * * @see SdkMeterProviderUtil#setMeterConfigurator(SdkMeterProviderBuilder, ScopeConfigurator) * @see SdkMeterProviderUtil#addMeterConfiguratorCondition(SdkMeterProviderBuilder, Predicate, * MeterConfig) diff --git a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/data/ImmutableSummaryData.java b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/data/ImmutableSummaryData.java index 7f145269341..0c1f4db1bd6 100644 --- a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/data/ImmutableSummaryData.java +++ b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/data/ImmutableSummaryData.java @@ -25,7 +25,7 @@ * instruments. * *

      This class is internal and is hence not for public use. Its APIs are unstable and can change - * at any time + * at any time. */ @Immutable @AutoValue diff --git a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/data/ImmutableSummaryPointData.java b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/data/ImmutableSummaryPointData.java index 447ad45963d..54597c1acb9 100644 --- a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/data/ImmutableSummaryPointData.java +++ b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/data/ImmutableSummaryPointData.java @@ -17,7 +17,7 @@ * A single data point that summarizes the values in a time series of numeric values. * *

      This class is internal and is hence not for public use. Its APIs are unstable and can change - * at any time + * at any time. */ @Immutable @AutoValue diff --git a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/data/ImmutableValueAtQuantile.java b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/data/ImmutableValueAtQuantile.java index 01995b28aa4..d8f31391cb8 100644 --- a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/data/ImmutableValueAtQuantile.java +++ b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/data/ImmutableValueAtQuantile.java @@ -13,7 +13,7 @@ * A summary metric value. * *

      This class is internal and is hence not for public use. Its APIs are unstable and can change - * at any time + * at any time. */ @Immutable @AutoValue diff --git a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/descriptor/Advice.java b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/descriptor/Advice.java index 96302ecfbe4..768b3afc297 100644 --- a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/descriptor/Advice.java +++ b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/descriptor/Advice.java @@ -13,6 +13,10 @@ import javax.annotation.Nullable; import javax.annotation.concurrent.Immutable; +/** + * This class is internal and is hence not for public use. Its APIs are unstable and can change at + * any time. + */ @AutoValue @Immutable public abstract class Advice { @@ -39,6 +43,10 @@ public boolean hasAttributes() { return getAttributes() != null; } + /** + * This class is internal and is hence not for public use. Its APIs are unstable and can change at + * any time. + */ @AutoValue.Builder public abstract static class AdviceBuilder { diff --git a/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/internal/TracerConfig.java b/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/internal/TracerConfig.java index d019055b36a..535760cbfd4 100644 --- a/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/internal/TracerConfig.java +++ b/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/internal/TracerConfig.java @@ -17,6 +17,9 @@ /** * A collection of configuration options which define the behavior of a {@link Tracer}. * + *

      This class is internal and is hence not for public use. Its APIs are unstable and can change + * at any time. + * * @see SdkTracerProviderUtil#setTracerConfigurator(SdkTracerProviderBuilder, ScopeConfigurator) * @see SdkTracerProviderUtil#addTracerConfiguratorCondition(SdkTracerProviderBuilder, Predicate, * TracerConfig) diff --git a/settings.gradle.kts b/settings.gradle.kts index c3542d49948..5952dc4a118 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -29,6 +29,7 @@ include(":api:testing-internal") include(":bom") include(":bom-alpha") include(":context") +include(":custom-checks") include(":dependencyManagement") include(":extensions:kotlin") include(":extensions:trace-propagators") From ef032394dcf63d6b2086c125497c4957271a6dee Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 2 Nov 2024 12:55:51 -0700 Subject: [PATCH 646/901] fix(deps): update dependency checkstyle to v10.20.0 (#6843) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- buildSrc/src/main/kotlin/otel.java-conventions.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/buildSrc/src/main/kotlin/otel.java-conventions.gradle.kts b/buildSrc/src/main/kotlin/otel.java-conventions.gradle.kts index fd3830bc45a..c9f22e8e4fd 100644 --- a/buildSrc/src/main/kotlin/otel.java-conventions.gradle.kts +++ b/buildSrc/src/main/kotlin/otel.java-conventions.gradle.kts @@ -42,7 +42,7 @@ java { checkstyle { configDirectory.set(file("$rootDir/buildscripts/")) - toolVersion = "10.19.0" + toolVersion = "10.20.0" isIgnoreFailures = false configProperties["rootDir"] = rootDir } From fd58d1062893e9c8d5671bc6169624fe6b48678e Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 4 Nov 2024 20:15:18 -0800 Subject: [PATCH 647/901] chore(deps): update plugin com.gradleup.shadow to v8.3.5 (#6847) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- settings.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/settings.gradle.kts b/settings.gradle.kts index 5952dc4a118..4edff174f84 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -1,6 +1,6 @@ pluginManagement { plugins { - id("com.gradleup.shadow") version "8.3.4" + id("com.gradleup.shadow") version "8.3.5" id("com.gradle.develocity") version "3.18.1" id("de.undercouch.download") version "5.6.0" id("org.jsonschema2pojo") version "1.2.2" From 7e4da160ba292a288f08a886853e3818d8686d46 Mon Sep 17 00:00:00 2001 From: jack-berg <34418638+jack-berg@users.noreply.github.com> Date: Tue, 5 Nov 2024 09:00:54 -0600 Subject: [PATCH 648/901] Refactor metrics to remove MeterSharedState (#6845) --- .../sdk/metrics/InstrumentBuilder.java | 39 ++-- .../sdk/metrics/SdkDoubleCounter.java | 22 +- .../sdk/metrics/SdkDoubleGauge.java | 24 +- .../sdk/metrics/SdkDoubleHistogram.java | 23 +- .../sdk/metrics/SdkDoubleUpDownCounter.java | 21 +- .../sdk/metrics/SdkLongCounter.java | 24 +- .../sdk/metrics/SdkLongGauge.java | 22 +- .../sdk/metrics/SdkLongHistogram.java | 22 +- .../sdk/metrics/SdkLongUpDownCounter.java | 23 +- .../opentelemetry/sdk/metrics/SdkMeter.java | 207 ++++++++++++++++-- .../sdk/metrics/SdkObservableInstrument.java | 10 +- .../state/AsynchronousMetricStorage.java | 11 +- .../internal/state/CallbackRegistration.java | 2 +- .../state/MeterProviderSharedState.java | 2 +- .../internal/state/MeterSharedState.java | 199 ----------------- .../internal/state/MetricStorageRegistry.java | 2 +- .../state/MultiWritableMetricStorage.java | 42 ---- .../sdk/metrics/InstrumentBuilderTest.java | 18 +- .../metrics/SdkObservableInstrumentTest.java | 21 +- 19 files changed, 275 insertions(+), 459 deletions(-) delete mode 100644 sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/state/MeterSharedState.java delete mode 100644 sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/state/MultiWritableMetricStorage.java diff --git a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/InstrumentBuilder.java b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/InstrumentBuilder.java index afed0778796..14fd54d7bd1 100644 --- a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/InstrumentBuilder.java +++ b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/InstrumentBuilder.java @@ -11,8 +11,6 @@ import io.opentelemetry.sdk.metrics.internal.descriptor.Advice; import io.opentelemetry.sdk.metrics.internal.descriptor.InstrumentDescriptor; import io.opentelemetry.sdk.metrics.internal.state.CallbackRegistration; -import io.opentelemetry.sdk.metrics.internal.state.MeterProviderSharedState; -import io.opentelemetry.sdk.metrics.internal.state.MeterSharedState; import io.opentelemetry.sdk.metrics.internal.state.SdkObservableMeasurement; import io.opentelemetry.sdk.metrics.internal.state.WriteableMetricStorage; import java.util.Collections; @@ -23,8 +21,7 @@ final class InstrumentBuilder { private final String name; - private final MeterProviderSharedState meterProviderSharedState; - private final MeterSharedState meterSharedState; + private final SdkMeter sdkMeter; private final InstrumentValueType valueType; private InstrumentType type; private Advice.AdviceBuilder adviceBuilder = Advice.builder(); @@ -32,16 +29,11 @@ final class InstrumentBuilder { private String unit = ""; InstrumentBuilder( - String name, - InstrumentType type, - InstrumentValueType valueType, - MeterProviderSharedState meterProviderSharedState, - MeterSharedState meterSharedState) { + String name, InstrumentType type, InstrumentValueType valueType, SdkMeter sdkMeter) { this.name = name; this.type = type; this.valueType = valueType; - this.meterProviderSharedState = meterProviderSharedState; - this.meterSharedState = meterSharedState; + this.sdkMeter = sdkMeter; } InstrumentBuilder setUnit(String unit) { @@ -60,8 +52,7 @@ InstrumentBuilder setDescription(String description) { } T swapBuilder(SwapBuilder swapper) { - return swapper.newBuilder( - meterProviderSharedState, meterSharedState, name, description, unit, adviceBuilder); + return swapper.newBuilder(sdkMeter, name, description, unit, adviceBuilder); } @FunctionalInterface @@ -69,16 +60,15 @@ interface SynchronousInstrumentConstructor { I createInstrument( InstrumentDescriptor instrumentDescriptor, - MeterSharedState meterSharedState, + SdkMeter sdkMeter, WriteableMetricStorage storage); } I buildSynchronousInstrument( SynchronousInstrumentConstructor instrumentFactory) { InstrumentDescriptor descriptor = newDescriptor(); - WriteableMetricStorage storage = - meterSharedState.registerSynchronousMetricStorage(descriptor, meterProviderSharedState); - return instrumentFactory.createInstrument(descriptor, meterSharedState, storage); + WriteableMetricStorage storage = sdkMeter.registerSynchronousMetricStorage(descriptor); + return instrumentFactory.createInstrument(descriptor, sdkMeter, storage); } SdkObservableInstrument buildDoubleAsynchronousInstrument( @@ -87,8 +77,8 @@ SdkObservableInstrument buildDoubleAsynchronousInstrument( Runnable runnable = () -> updater.accept(sdkObservableMeasurement); CallbackRegistration callbackRegistration = CallbackRegistration.create(Collections.singletonList(sdkObservableMeasurement), runnable); - meterSharedState.registerCallback(callbackRegistration); - return new SdkObservableInstrument(meterSharedState, callbackRegistration); + sdkMeter.registerCallback(callbackRegistration); + return new SdkObservableInstrument(sdkMeter, callbackRegistration); } SdkObservableInstrument buildLongAsynchronousInstrument( @@ -97,14 +87,14 @@ SdkObservableInstrument buildLongAsynchronousInstrument( Runnable runnable = () -> updater.accept(sdkObservableMeasurement); CallbackRegistration callbackRegistration = CallbackRegistration.create(Collections.singletonList(sdkObservableMeasurement), runnable); - meterSharedState.registerCallback(callbackRegistration); - return new SdkObservableInstrument(meterSharedState, callbackRegistration); + sdkMeter.registerCallback(callbackRegistration); + return new SdkObservableInstrument(sdkMeter, callbackRegistration); } SdkObservableMeasurement buildObservableMeasurement(InstrumentType type) { this.type = type; InstrumentDescriptor descriptor = newDescriptor(); - return meterSharedState.registerObservableMeasurement(descriptor); + return sdkMeter.registerObservableMeasurement(descriptor); } private InstrumentDescriptor newDescriptor() { @@ -122,10 +112,9 @@ String toStringHelper(String className) { } @FunctionalInterface - protected interface SwapBuilder { + interface SwapBuilder { T newBuilder( - MeterProviderSharedState meterProviderSharedState, - MeterSharedState meterSharedState, + SdkMeter sdkMeter, String name, String description, String unit, diff --git a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkDoubleCounter.java b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkDoubleCounter.java index 5e4eb4a7ef5..de645016076 100644 --- a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkDoubleCounter.java +++ b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkDoubleCounter.java @@ -16,8 +16,6 @@ import io.opentelemetry.sdk.internal.ThrottlingLogger; import io.opentelemetry.sdk.metrics.internal.descriptor.Advice; import io.opentelemetry.sdk.metrics.internal.descriptor.InstrumentDescriptor; -import io.opentelemetry.sdk.metrics.internal.state.MeterProviderSharedState; -import io.opentelemetry.sdk.metrics.internal.state.MeterSharedState; import io.opentelemetry.sdk.metrics.internal.state.WriteableMetricStorage; import java.util.List; import java.util.function.Consumer; @@ -28,15 +26,13 @@ final class SdkDoubleCounter extends AbstractInstrument implements ExtendedDoubl private static final Logger logger = Logger.getLogger(SdkDoubleCounter.class.getName()); private final ThrottlingLogger throttlingLogger = new ThrottlingLogger(logger); - private final MeterSharedState meterSharedState; + private final SdkMeter sdkMeter; private final WriteableMetricStorage storage; private SdkDoubleCounter( - InstrumentDescriptor descriptor, - MeterSharedState meterSharedState, - WriteableMetricStorage storage) { + InstrumentDescriptor descriptor, SdkMeter sdkMeter, WriteableMetricStorage storage) { super(descriptor); - this.meterSharedState = meterSharedState; + this.sdkMeter = sdkMeter; this.storage = storage; } @@ -65,7 +61,7 @@ public void add(double increment) { @Override public boolean isEnabled() { - return meterSharedState.isMeterEnabled() && storage.isEnabled(); + return sdkMeter.isMeterEnabled() && storage.isEnabled(); } static final class SdkDoubleCounterBuilder implements ExtendedDoubleCounterBuilder { @@ -73,19 +69,13 @@ static final class SdkDoubleCounterBuilder implements ExtendedDoubleCounterBuild private final InstrumentBuilder builder; SdkDoubleCounterBuilder( - MeterProviderSharedState meterProviderSharedState, - MeterSharedState sharedState, + SdkMeter sdkMeter, String name, String description, String unit, Advice.AdviceBuilder adviceBuilder) { this.builder = - new InstrumentBuilder( - name, - InstrumentType.COUNTER, - InstrumentValueType.DOUBLE, - meterProviderSharedState, - sharedState) + new InstrumentBuilder(name, InstrumentType.COUNTER, InstrumentValueType.DOUBLE, sdkMeter) .setUnit(unit) .setDescription(description) .setAdviceBuilder(adviceBuilder); diff --git a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkDoubleGauge.java b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkDoubleGauge.java index 8cc9d468257..03b3f43838d 100644 --- a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkDoubleGauge.java +++ b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkDoubleGauge.java @@ -15,23 +15,19 @@ import io.opentelemetry.api.metrics.ObservableDoubleMeasurement; import io.opentelemetry.context.Context; import io.opentelemetry.sdk.metrics.internal.descriptor.InstrumentDescriptor; -import io.opentelemetry.sdk.metrics.internal.state.MeterProviderSharedState; -import io.opentelemetry.sdk.metrics.internal.state.MeterSharedState; import io.opentelemetry.sdk.metrics.internal.state.WriteableMetricStorage; import java.util.List; import java.util.function.Consumer; final class SdkDoubleGauge extends AbstractInstrument implements ExtendedDoubleGauge { - private final MeterSharedState meterSharedState; + private final SdkMeter sdkMeter; private final WriteableMetricStorage storage; private SdkDoubleGauge( - InstrumentDescriptor descriptor, - MeterSharedState meterSharedState, - WriteableMetricStorage storage) { + InstrumentDescriptor descriptor, SdkMeter sdkMeter, WriteableMetricStorage storage) { super(descriptor); - this.meterSharedState = meterSharedState; + this.sdkMeter = sdkMeter; this.storage = storage; } @@ -52,24 +48,16 @@ public void set(double increment) { @Override public boolean isEnabled() { - return meterSharedState.isMeterEnabled() && storage.isEnabled(); + return sdkMeter.isMeterEnabled() && storage.isEnabled(); } static final class SdkDoubleGaugeBuilder implements ExtendedDoubleGaugeBuilder { private final InstrumentBuilder builder; - SdkDoubleGaugeBuilder( - MeterProviderSharedState meterProviderSharedState, - MeterSharedState meterSharedState, - String name) { + SdkDoubleGaugeBuilder(SdkMeter sdkMeter, String name) { builder = - new InstrumentBuilder( - name, - InstrumentType.GAUGE, - InstrumentValueType.DOUBLE, - meterProviderSharedState, - meterSharedState); + new InstrumentBuilder(name, InstrumentType.GAUGE, InstrumentValueType.DOUBLE, sdkMeter); } @Override diff --git a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkDoubleHistogram.java b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkDoubleHistogram.java index 4861a631ab7..5aa8f49de31 100644 --- a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkDoubleHistogram.java +++ b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkDoubleHistogram.java @@ -15,8 +15,6 @@ import io.opentelemetry.sdk.internal.ThrottlingLogger; import io.opentelemetry.sdk.metrics.internal.aggregator.ExplicitBucketHistogramUtils; import io.opentelemetry.sdk.metrics.internal.descriptor.InstrumentDescriptor; -import io.opentelemetry.sdk.metrics.internal.state.MeterProviderSharedState; -import io.opentelemetry.sdk.metrics.internal.state.MeterSharedState; import io.opentelemetry.sdk.metrics.internal.state.WriteableMetricStorage; import java.util.List; import java.util.Objects; @@ -27,15 +25,13 @@ final class SdkDoubleHistogram extends AbstractInstrument implements ExtendedDou private static final Logger logger = Logger.getLogger(SdkDoubleHistogram.class.getName()); private final ThrottlingLogger throttlingLogger = new ThrottlingLogger(logger); - private final MeterSharedState meterSharedState; + private final SdkMeter sdkMeter; private final WriteableMetricStorage storage; private SdkDoubleHistogram( - InstrumentDescriptor descriptor, - MeterSharedState meterSharedState, - WriteableMetricStorage storage) { + InstrumentDescriptor descriptor, SdkMeter sdkMeter, WriteableMetricStorage storage) { super(descriptor); - this.meterSharedState = meterSharedState; + this.sdkMeter = sdkMeter; this.storage = storage; } @@ -64,24 +60,17 @@ public void record(double value) { @Override public boolean isEnabled() { - return meterSharedState.isMeterEnabled() && storage.isEnabled(); + return sdkMeter.isMeterEnabled() && storage.isEnabled(); } static final class SdkDoubleHistogramBuilder implements ExtendedDoubleHistogramBuilder { private final InstrumentBuilder builder; - SdkDoubleHistogramBuilder( - MeterProviderSharedState meterProviderSharedState, - MeterSharedState meterSharedState, - String name) { + SdkDoubleHistogramBuilder(SdkMeter sdkMeter, String name) { builder = new InstrumentBuilder( - name, - InstrumentType.HISTOGRAM, - InstrumentValueType.DOUBLE, - meterProviderSharedState, - meterSharedState); + name, InstrumentType.HISTOGRAM, InstrumentValueType.DOUBLE, sdkMeter); } @Override diff --git a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkDoubleUpDownCounter.java b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkDoubleUpDownCounter.java index da6316d6b77..fe21e295c98 100644 --- a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkDoubleUpDownCounter.java +++ b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkDoubleUpDownCounter.java @@ -16,8 +16,6 @@ import io.opentelemetry.context.Context; import io.opentelemetry.sdk.metrics.internal.descriptor.Advice; import io.opentelemetry.sdk.metrics.internal.descriptor.InstrumentDescriptor; -import io.opentelemetry.sdk.metrics.internal.state.MeterProviderSharedState; -import io.opentelemetry.sdk.metrics.internal.state.MeterSharedState; import io.opentelemetry.sdk.metrics.internal.state.WriteableMetricStorage; import java.util.List; import java.util.function.Consumer; @@ -25,15 +23,13 @@ final class SdkDoubleUpDownCounter extends AbstractInstrument implements ExtendedDoubleUpDownCounter { - private final MeterSharedState meterSharedState; + private final SdkMeter sdkMeter; private final WriteableMetricStorage storage; private SdkDoubleUpDownCounter( - InstrumentDescriptor descriptor, - MeterSharedState meterSharedState, - WriteableMetricStorage storage) { + InstrumentDescriptor descriptor, SdkMeter sdkMeter, WriteableMetricStorage storage) { super(descriptor); - this.meterSharedState = meterSharedState; + this.sdkMeter = sdkMeter; this.storage = storage; } @@ -54,7 +50,7 @@ public void add(double increment) { @Override public boolean isEnabled() { - return meterSharedState.isMeterEnabled() && storage.isEnabled(); + return sdkMeter.isMeterEnabled() && storage.isEnabled(); } static final class SdkDoubleUpDownCounterBuilder implements ExtendedDoubleUpDownCounterBuilder { @@ -62,19 +58,14 @@ static final class SdkDoubleUpDownCounterBuilder implements ExtendedDoubleUpDown private final InstrumentBuilder builder; SdkDoubleUpDownCounterBuilder( - MeterProviderSharedState meterProviderSharedState, - MeterSharedState sharedState, + SdkMeter sdkMeter, String name, String description, String unit, Advice.AdviceBuilder adviceBuilder) { this.builder = new InstrumentBuilder( - name, - InstrumentType.UP_DOWN_COUNTER, - InstrumentValueType.DOUBLE, - meterProviderSharedState, - sharedState) + name, InstrumentType.UP_DOWN_COUNTER, InstrumentValueType.DOUBLE, sdkMeter) .setDescription(description) .setUnit(unit) .setAdviceBuilder(adviceBuilder); diff --git a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkLongCounter.java b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkLongCounter.java index 91b52fee7fd..df2f9b4e660 100644 --- a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkLongCounter.java +++ b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkLongCounter.java @@ -16,8 +16,6 @@ import io.opentelemetry.context.Context; import io.opentelemetry.sdk.internal.ThrottlingLogger; import io.opentelemetry.sdk.metrics.internal.descriptor.InstrumentDescriptor; -import io.opentelemetry.sdk.metrics.internal.state.MeterProviderSharedState; -import io.opentelemetry.sdk.metrics.internal.state.MeterSharedState; import io.opentelemetry.sdk.metrics.internal.state.WriteableMetricStorage; import java.util.List; import java.util.function.Consumer; @@ -29,15 +27,13 @@ final class SdkLongCounter extends AbstractInstrument implements ExtendedLongCou private static final Logger logger = Logger.getLogger(SdkLongCounter.class.getName()); private final ThrottlingLogger throttlingLogger = new ThrottlingLogger(logger); - private final MeterSharedState meterSharedState; + private final SdkMeter sdkMeter; private final WriteableMetricStorage storage; private SdkLongCounter( - InstrumentDescriptor descriptor, - MeterSharedState meterSharedState, - WriteableMetricStorage storage) { + InstrumentDescriptor descriptor, SdkMeter sdkMeter, WriteableMetricStorage storage) { super(descriptor); - this.meterSharedState = meterSharedState; + this.sdkMeter = sdkMeter; this.storage = storage; } @@ -66,24 +62,16 @@ public void add(long increment) { @Override public boolean isEnabled() { - return meterSharedState.isMeterEnabled() && storage.isEnabled(); + return sdkMeter.isMeterEnabled() && storage.isEnabled(); } static final class SdkLongCounterBuilder implements ExtendedLongCounterBuilder { private final InstrumentBuilder builder; - SdkLongCounterBuilder( - MeterProviderSharedState meterProviderSharedState, - MeterSharedState meterSharedState, - String name) { + SdkLongCounterBuilder(SdkMeter sdkMeter, String name) { this.builder = - new InstrumentBuilder( - name, - InstrumentType.COUNTER, - InstrumentValueType.LONG, - meterProviderSharedState, - meterSharedState); + new InstrumentBuilder(name, InstrumentType.COUNTER, InstrumentValueType.LONG, sdkMeter); } @Override diff --git a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkLongGauge.java b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkLongGauge.java index 62ab826df87..499c4a4443a 100644 --- a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkLongGauge.java +++ b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkLongGauge.java @@ -15,23 +15,19 @@ import io.opentelemetry.context.Context; import io.opentelemetry.sdk.metrics.internal.descriptor.Advice; import io.opentelemetry.sdk.metrics.internal.descriptor.InstrumentDescriptor; -import io.opentelemetry.sdk.metrics.internal.state.MeterProviderSharedState; -import io.opentelemetry.sdk.metrics.internal.state.MeterSharedState; import io.opentelemetry.sdk.metrics.internal.state.WriteableMetricStorage; import java.util.List; import java.util.function.Consumer; final class SdkLongGauge extends AbstractInstrument implements ExtendedLongGauge { - private final MeterSharedState meterSharedState; + private final SdkMeter sdkMeter; private final WriteableMetricStorage storage; private SdkLongGauge( - InstrumentDescriptor descriptor, - MeterSharedState meterSharedState, - WriteableMetricStorage storage) { + InstrumentDescriptor descriptor, SdkMeter sdkMeter, WriteableMetricStorage storage) { super(descriptor); - this.meterSharedState = meterSharedState; + this.sdkMeter = sdkMeter; this.storage = storage; } @@ -52,7 +48,7 @@ public void set(long increment) { @Override public boolean isEnabled() { - return meterSharedState.isMeterEnabled() && storage.isEnabled(); + return sdkMeter.isMeterEnabled() && storage.isEnabled(); } static final class SdkLongGaugeBuilder implements ExtendedLongGaugeBuilder { @@ -60,20 +56,14 @@ static final class SdkLongGaugeBuilder implements ExtendedLongGaugeBuilder { private final InstrumentBuilder builder; SdkLongGaugeBuilder( - MeterProviderSharedState meterProviderSharedState, - MeterSharedState sharedState, + SdkMeter sdkMeter, String name, String description, String unit, Advice.AdviceBuilder adviceBuilder) { builder = - new InstrumentBuilder( - name, - InstrumentType.GAUGE, - InstrumentValueType.LONG, - meterProviderSharedState, - sharedState) + new InstrumentBuilder(name, InstrumentType.GAUGE, InstrumentValueType.LONG, sdkMeter) .setDescription(description) .setUnit(unit) .setAdviceBuilder(adviceBuilder); diff --git a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkLongHistogram.java b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkLongHistogram.java index ef8ee31e707..0822b1eff57 100644 --- a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkLongHistogram.java +++ b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkLongHistogram.java @@ -15,8 +15,6 @@ import io.opentelemetry.sdk.metrics.internal.aggregator.ExplicitBucketHistogramUtils; import io.opentelemetry.sdk.metrics.internal.descriptor.Advice; import io.opentelemetry.sdk.metrics.internal.descriptor.InstrumentDescriptor; -import io.opentelemetry.sdk.metrics.internal.state.MeterProviderSharedState; -import io.opentelemetry.sdk.metrics.internal.state.MeterSharedState; import io.opentelemetry.sdk.metrics.internal.state.WriteableMetricStorage; import java.util.List; import java.util.Objects; @@ -28,15 +26,13 @@ final class SdkLongHistogram extends AbstractInstrument implements ExtendedLongH private static final Logger logger = Logger.getLogger(SdkLongHistogram.class.getName()); private final ThrottlingLogger throttlingLogger = new ThrottlingLogger(logger); - private final MeterSharedState meterSharedState; + private final SdkMeter sdkMeter; private final WriteableMetricStorage storage; private SdkLongHistogram( - InstrumentDescriptor descriptor, - MeterSharedState meterSharedState, - WriteableMetricStorage storage) { + InstrumentDescriptor descriptor, SdkMeter sdkMeter, WriteableMetricStorage storage) { super(descriptor); - this.meterSharedState = meterSharedState; + this.sdkMeter = sdkMeter; this.storage = storage; } @@ -65,7 +61,7 @@ public void record(long value) { @Override public boolean isEnabled() { - return meterSharedState.isMeterEnabled() && storage.isEnabled(); + return sdkMeter.isMeterEnabled() && storage.isEnabled(); } static final class SdkLongHistogramBuilder implements ExtendedLongHistogramBuilder { @@ -73,19 +69,13 @@ static final class SdkLongHistogramBuilder implements ExtendedLongHistogramBuild private final InstrumentBuilder builder; SdkLongHistogramBuilder( - MeterProviderSharedState meterProviderSharedState, - MeterSharedState sharedState, + SdkMeter sdkMeter, String name, String description, String unit, Advice.AdviceBuilder adviceBuilder) { builder = - new InstrumentBuilder( - name, - InstrumentType.HISTOGRAM, - InstrumentValueType.LONG, - meterProviderSharedState, - sharedState) + new InstrumentBuilder(name, InstrumentType.HISTOGRAM, InstrumentValueType.LONG, sdkMeter) .setDescription(description) .setUnit(unit) .setAdviceBuilder(adviceBuilder); diff --git a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkLongUpDownCounter.java b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkLongUpDownCounter.java index a74ac786d1a..daf1e2f97a8 100644 --- a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkLongUpDownCounter.java +++ b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkLongUpDownCounter.java @@ -16,23 +16,19 @@ import io.opentelemetry.api.metrics.ObservableLongUpDownCounter; import io.opentelemetry.context.Context; import io.opentelemetry.sdk.metrics.internal.descriptor.InstrumentDescriptor; -import io.opentelemetry.sdk.metrics.internal.state.MeterProviderSharedState; -import io.opentelemetry.sdk.metrics.internal.state.MeterSharedState; import io.opentelemetry.sdk.metrics.internal.state.WriteableMetricStorage; import java.util.List; import java.util.function.Consumer; final class SdkLongUpDownCounter extends AbstractInstrument implements ExtendedLongUpDownCounter { - private final MeterSharedState meterSharedState; + private final SdkMeter sdkMeter; private final WriteableMetricStorage storage; private SdkLongUpDownCounter( - InstrumentDescriptor descriptor, - MeterSharedState meterSharedState, - WriteableMetricStorage storage) { + InstrumentDescriptor descriptor, SdkMeter sdkMeter, WriteableMetricStorage storage) { super(descriptor); - this.meterSharedState = meterSharedState; + this.sdkMeter = sdkMeter; this.storage = storage; } @@ -53,24 +49,17 @@ public void add(long increment) { @Override public boolean isEnabled() { - return meterSharedState.isMeterEnabled() && storage.isEnabled(); + return sdkMeter.isMeterEnabled() && storage.isEnabled(); } static final class SdkLongUpDownCounterBuilder implements ExtendedLongUpDownCounterBuilder { private final InstrumentBuilder builder; - SdkLongUpDownCounterBuilder( - MeterProviderSharedState meterProviderSharedState, - MeterSharedState meterSharedState, - String name) { + SdkLongUpDownCounterBuilder(SdkMeter sdkMeter, String name) { this.builder = new InstrumentBuilder( - name, - InstrumentType.UP_DOWN_COUNTER, - InstrumentValueType.LONG, - meterProviderSharedState, - meterSharedState); + name, InstrumentType.UP_DOWN_COUNTER, InstrumentValueType.LONG, sdkMeter); } @Override diff --git a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkMeter.java b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkMeter.java index da57ef3506c..fe278cba4d6 100644 --- a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkMeter.java +++ b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkMeter.java @@ -5,6 +5,10 @@ package io.opentelemetry.sdk.metrics; +import static java.util.stream.Collectors.toMap; + +import io.opentelemetry.api.common.Attributes; +import io.opentelemetry.api.internal.GuardedBy; import io.opentelemetry.api.metrics.BatchCallback; import io.opentelemetry.api.metrics.DoubleGaugeBuilder; import io.opentelemetry.api.metrics.DoubleHistogramBuilder; @@ -13,20 +17,30 @@ import io.opentelemetry.api.metrics.Meter; import io.opentelemetry.api.metrics.MeterProvider; import io.opentelemetry.api.metrics.ObservableMeasurement; +import io.opentelemetry.context.Context; import io.opentelemetry.sdk.common.InstrumentationScopeInfo; import io.opentelemetry.sdk.metrics.data.MetricData; import io.opentelemetry.sdk.metrics.internal.MeterConfig; +import io.opentelemetry.sdk.metrics.internal.descriptor.InstrumentDescriptor; import io.opentelemetry.sdk.metrics.internal.export.RegisteredReader; +import io.opentelemetry.sdk.metrics.internal.state.AsynchronousMetricStorage; import io.opentelemetry.sdk.metrics.internal.state.CallbackRegistration; import io.opentelemetry.sdk.metrics.internal.state.MeterProviderSharedState; -import io.opentelemetry.sdk.metrics.internal.state.MeterSharedState; +import io.opentelemetry.sdk.metrics.internal.state.MetricStorage; +import io.opentelemetry.sdk.metrics.internal.state.MetricStorageRegistry; import io.opentelemetry.sdk.metrics.internal.state.SdkObservableMeasurement; +import io.opentelemetry.sdk.metrics.internal.state.SynchronousMetricStorage; +import io.opentelemetry.sdk.metrics.internal.state.WriteableMetricStorage; +import io.opentelemetry.sdk.metrics.internal.view.RegisteredView; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.HashSet; import java.util.List; +import java.util.Map; +import java.util.Objects; import java.util.Set; +import java.util.function.Function; import java.util.logging.Level; import java.util.logging.Logger; import java.util.regex.Pattern; @@ -53,9 +67,16 @@ final class SdkMeter implements Meter { private static final Meter NOOP_METER = MeterProvider.noop().get("noop"); private static final String NOOP_INSTRUMENT_NAME = "noop"; - private final InstrumentationScopeInfo instrumentationScopeInfo; + private final Object collectLock = new Object(); + private final Object callbackLock = new Object(); + + @GuardedBy("callbackLock") + private final List callbackRegistrations = new ArrayList<>(); + private final MeterProviderSharedState meterProviderSharedState; - private final MeterSharedState meterSharedState; + private final InstrumentationScopeInfo instrumentationScopeInfo; + private final Map readerStorageRegistries; + private final boolean meterEnabled; SdkMeter( MeterProviderSharedState meterProviderSharedState, @@ -64,8 +85,10 @@ final class SdkMeter implements Meter { MeterConfig meterConfig) { this.instrumentationScopeInfo = instrumentationScopeInfo; this.meterProviderSharedState = meterProviderSharedState; - this.meterSharedState = - MeterSharedState.create(instrumentationScopeInfo, registeredReaders, meterConfig); + this.readerStorageRegistries = + registeredReaders.stream() + .collect(toMap(Function.identity(), unused -> new MetricStorageRegistry())); + this.meterEnabled = meterConfig.isEnabled(); } // Visible for testing @@ -75,41 +98,76 @@ InstrumentationScopeInfo getInstrumentationScopeInfo() { /** Collect all metrics for the meter. */ Collection collectAll(RegisteredReader registeredReader, long epochNanos) { - return meterSharedState.collectAll(registeredReader, meterProviderSharedState, epochNanos); + // Short circuit collection process if meter is disabled + if (!meterEnabled) { + return Collections.emptyList(); + } + List currentRegisteredCallbacks; + synchronized (callbackLock) { + currentRegisteredCallbacks = new ArrayList<>(callbackRegistrations); + } + // Collections across all readers are sequential + synchronized (collectLock) { + for (CallbackRegistration callbackRegistration : currentRegisteredCallbacks) { + callbackRegistration.invokeCallback( + registeredReader, meterProviderSharedState.getStartEpochNanos(), epochNanos); + } + + Collection storages = + Objects.requireNonNull(readerStorageRegistries.get(registeredReader)).getStorages(); + List result = new ArrayList<>(storages.size()); + for (MetricStorage storage : storages) { + MetricData current = + storage.collect( + meterProviderSharedState.getResource(), + getInstrumentationScopeInfo(), + meterProviderSharedState.getStartEpochNanos(), + epochNanos); + // Ignore if the metric data doesn't have any data points, for example when aggregation is + // Aggregation#drop() + if (!current.isEmpty()) { + result.add(current); + } + } + return Collections.unmodifiableList(result); + } } - /** Reset the meter, clearing all registered instruments. */ + /** Reset the meter, clearing all registered callbacks and storages. */ void resetForTest() { - this.meterSharedState.resetForTest(); + synchronized (collectLock) { + synchronized (callbackLock) { + callbackRegistrations.clear(); + } + this.readerStorageRegistries.values().forEach(MetricStorageRegistry::resetForTest); + } } @Override public LongCounterBuilder counterBuilder(String name) { return checkValidInstrumentName(name) - ? new SdkLongCounter.SdkLongCounterBuilder(meterProviderSharedState, meterSharedState, name) + ? new SdkLongCounter.SdkLongCounterBuilder(this, name) : NOOP_METER.counterBuilder(NOOP_INSTRUMENT_NAME); } @Override public LongUpDownCounterBuilder upDownCounterBuilder(String name) { return checkValidInstrumentName(name) - ? new SdkLongUpDownCounter.SdkLongUpDownCounterBuilder( - meterProviderSharedState, meterSharedState, name) + ? new SdkLongUpDownCounter.SdkLongUpDownCounterBuilder(this, name) : NOOP_METER.upDownCounterBuilder(NOOP_INSTRUMENT_NAME); } @Override public DoubleHistogramBuilder histogramBuilder(String name) { return checkValidInstrumentName(name) - ? new SdkDoubleHistogram.SdkDoubleHistogramBuilder( - meterProviderSharedState, meterSharedState, name) + ? new SdkDoubleHistogram.SdkDoubleHistogramBuilder(this, name) : NOOP_METER.histogramBuilder(NOOP_INSTRUMENT_NAME); } @Override public DoubleGaugeBuilder gaugeBuilder(String name) { return checkValidInstrumentName(name) - ? new SdkDoubleGauge.SdkDoubleGaugeBuilder(meterProviderSharedState, meterSharedState, name) + ? new SdkDoubleGauge.SdkDoubleGaugeBuilder(this, name) : NOOP_METER.gaugeBuilder(NOOP_INSTRUMENT_NAME); } @@ -131,9 +189,7 @@ public BatchCallback batchCallback( continue; } SdkObservableMeasurement sdkMeasurement = (SdkObservableMeasurement) measurement; - if (!meterSharedState - .getInstrumentationScopeInfo() - .equals(sdkMeasurement.getInstrumentationScopeInfo())) { + if (!instrumentationScopeInfo.equals(sdkMeasurement.getInstrumentationScopeInfo())) { logger.log( Level.WARNING, "batchCallback called with instruments that belong to a different Meter."); @@ -144,8 +200,89 @@ public BatchCallback batchCallback( CallbackRegistration callbackRegistration = CallbackRegistration.create(sdkMeasurements, callback); - meterSharedState.registerCallback(callbackRegistration); - return new SdkObservableInstrument(meterSharedState, callbackRegistration); + registerCallback(callbackRegistration); + return new SdkObservableInstrument(this, callbackRegistration); + } + + /** + * Unregister the callback. + * + *

      Callbacks are originally registered via {@link #registerCallback(CallbackRegistration)}. + */ + void removeCallback(CallbackRegistration callbackRegistration) { + synchronized (callbackLock) { + this.callbackRegistrations.remove(callbackRegistration); + } + } + + /** + * Register the callback. + * + *

      The callback will be invoked once per collection until unregistered via {@link + * #removeCallback(CallbackRegistration)}. + */ + void registerCallback(CallbackRegistration callbackRegistration) { + synchronized (callbackLock) { + callbackRegistrations.add(callbackRegistration); + } + } + + /** Returns {@code true} if the {@link MeterConfig#enabled()} of the meter is {@code true}. */ + boolean isMeterEnabled() { + return meterEnabled; + } + + /** Registers new synchronous storage associated with a given instrument. */ + WriteableMetricStorage registerSynchronousMetricStorage(InstrumentDescriptor instrument) { + + List registeredStorages = new ArrayList<>(); + for (Map.Entry entry : + readerStorageRegistries.entrySet()) { + RegisteredReader reader = entry.getKey(); + MetricStorageRegistry registry = entry.getValue(); + for (RegisteredView registeredView : + reader.getViewRegistry().findViews(instrument, getInstrumentationScopeInfo())) { + if (Aggregation.drop() == registeredView.getView().getAggregation()) { + continue; + } + registeredStorages.add( + registry.register( + SynchronousMetricStorage.create( + reader, + registeredView, + instrument, + meterProviderSharedState.getExemplarFilter()))); + } + } + + if (registeredStorages.size() == 1) { + return registeredStorages.get(0); + } + + return new MultiWritableMetricStorage(registeredStorages); + } + + /** Register new asynchronous storage associated with a given instrument. */ + SdkObservableMeasurement registerObservableMeasurement( + InstrumentDescriptor instrumentDescriptor) { + List> registeredStorages = new ArrayList<>(); + for (Map.Entry entry : + readerStorageRegistries.entrySet()) { + RegisteredReader reader = entry.getKey(); + MetricStorageRegistry registry = entry.getValue(); + for (RegisteredView registeredView : + reader.getViewRegistry().findViews(instrumentDescriptor, getInstrumentationScopeInfo())) { + if (Aggregation.drop() == registeredView.getView().getAggregation()) { + continue; + } + registeredStorages.add( + registry.register( + AsynchronousMetricStorage.create(reader, registeredView, instrumentDescriptor))); + } + } + + return SdkObservableMeasurement.create( + instrumentationScopeInfo, instrumentDescriptor, registeredStorages); } @Override @@ -170,4 +307,36 @@ static boolean checkValidInstrumentName(String name) { return false; } + + private static class MultiWritableMetricStorage implements WriteableMetricStorage { + private final List storages; + + private MultiWritableMetricStorage(List storages) { + this.storages = storages; + } + + @Override + public void recordLong(long value, Attributes attributes, Context context) { + for (WriteableMetricStorage storage : storages) { + storage.recordLong(value, attributes, context); + } + } + + @Override + public void recordDouble(double value, Attributes attributes, Context context) { + for (WriteableMetricStorage storage : storages) { + storage.recordDouble(value, attributes, context); + } + } + + @Override + public boolean isEnabled() { + for (WriteableMetricStorage storage : storages) { + if (storage.isEnabled()) { + return true; + } + } + return false; + } + } } diff --git a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkObservableInstrument.java b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkObservableInstrument.java index 33c1adbc1e7..5b7731e9d53 100644 --- a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkObservableInstrument.java +++ b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkObservableInstrument.java @@ -14,7 +14,6 @@ import io.opentelemetry.api.metrics.ObservableLongUpDownCounter; import io.opentelemetry.sdk.internal.ThrottlingLogger; import io.opentelemetry.sdk.metrics.internal.state.CallbackRegistration; -import io.opentelemetry.sdk.metrics.internal.state.MeterSharedState; import java.util.concurrent.atomic.AtomicBoolean; import java.util.logging.Level; import java.util.logging.Logger; @@ -31,13 +30,12 @@ class SdkObservableInstrument private static final Logger logger = Logger.getLogger(SdkObservableInstrument.class.getName()); private final ThrottlingLogger throttlingLogger = new ThrottlingLogger(logger); - private final MeterSharedState meterSharedState; + private final SdkMeter sdkMeter; private final CallbackRegistration callbackRegistration; private final AtomicBoolean removed = new AtomicBoolean(false); - SdkObservableInstrument( - MeterSharedState meterSharedState, CallbackRegistration callbackRegistration) { - this.meterSharedState = meterSharedState; + SdkObservableInstrument(SdkMeter sdkMeter, CallbackRegistration callbackRegistration) { + this.sdkMeter = sdkMeter; this.callbackRegistration = callbackRegistration; } @@ -48,7 +46,7 @@ public void close() { Level.WARNING, callbackRegistration + " has called close() multiple times."); return; } - meterSharedState.removeCallback(callbackRegistration); + sdkMeter.removeCallback(callbackRegistration); } @Override diff --git a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/state/AsynchronousMetricStorage.java b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/state/AsynchronousMetricStorage.java index 328710144da..42110e2cb1e 100644 --- a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/state/AsynchronousMetricStorage.java +++ b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/state/AsynchronousMetricStorage.java @@ -41,7 +41,7 @@ *

      This class is internal and is hence not for public use. Its APIs are unstable and can change * at any time. */ -final class AsynchronousMetricStorage +public final class AsynchronousMetricStorage implements MetricStorage { private static final Logger logger = Logger.getLogger(AsynchronousMetricStorage.class.getName()); @@ -101,10 +101,11 @@ private AsynchronousMetricStorage( * Create an asynchronous storage instance for the {@link View} and {@link InstrumentDescriptor}. */ // TODO(anuraaga): The cast to generic type here looks suspicious. - static AsynchronousMetricStorage create( - RegisteredReader registeredReader, - RegisteredView registeredView, - InstrumentDescriptor instrumentDescriptor) { + public static + AsynchronousMetricStorage create( + RegisteredReader registeredReader, + RegisteredView registeredView, + InstrumentDescriptor instrumentDescriptor) { View view = registeredView.getView(); MetricDescriptor metricDescriptor = MetricDescriptor.create(view, registeredView.getViewSourceInfo(), instrumentDescriptor); diff --git a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/state/CallbackRegistration.java b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/state/CallbackRegistration.java index 6634dd728ac..fec792096a2 100644 --- a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/state/CallbackRegistration.java +++ b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/state/CallbackRegistration.java @@ -70,7 +70,7 @@ public String toString() { return "CallbackRegistration{instrumentDescriptors=" + instrumentDescriptors + "}"; } - void invokeCallback(RegisteredReader reader, long startEpochNanos, long epochNanos) { + public void invokeCallback(RegisteredReader reader, long startEpochNanos, long epochNanos) { // Return early if no storages are registered if (!hasStorages) { return; diff --git a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/state/MeterProviderSharedState.java b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/state/MeterProviderSharedState.java index 8f3647c6d46..aaf932d9202 100644 --- a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/state/MeterProviderSharedState.java +++ b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/state/MeterProviderSharedState.java @@ -41,5 +41,5 @@ public static MeterProviderSharedState create( public abstract long getStartEpochNanos(); /** Returns the {@link ExemplarFilter} for remembering synchronous measurements. */ - abstract ExemplarFilter getExemplarFilter(); + public abstract ExemplarFilter getExemplarFilter(); } diff --git a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/state/MeterSharedState.java b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/state/MeterSharedState.java deleted file mode 100644 index 30a3a838c45..00000000000 --- a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/state/MeterSharedState.java +++ /dev/null @@ -1,199 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package io.opentelemetry.sdk.metrics.internal.state; - -import static java.util.stream.Collectors.toMap; - -import io.opentelemetry.api.internal.GuardedBy; -import io.opentelemetry.sdk.common.InstrumentationScopeInfo; -import io.opentelemetry.sdk.metrics.Aggregation; -import io.opentelemetry.sdk.metrics.data.MetricData; -import io.opentelemetry.sdk.metrics.internal.MeterConfig; -import io.opentelemetry.sdk.metrics.internal.descriptor.InstrumentDescriptor; -import io.opentelemetry.sdk.metrics.internal.export.RegisteredReader; -import io.opentelemetry.sdk.metrics.internal.view.RegisteredView; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.List; -import java.util.Map; -import java.util.Objects; -import java.util.function.Function; - -/** - * State for a {@code Meter}. - * - *

      This class is internal and is hence not for public use. Its APIs are unstable and can change - * at any time. - */ -public class MeterSharedState { - - private final Object collectLock = new Object(); - private final Object callbackLock = new Object(); - - @GuardedBy("callbackLock") - private final List callbackRegistrations = new ArrayList<>(); - - private final Map readerStorageRegistries; - private final InstrumentationScopeInfo instrumentationScopeInfo; - private final boolean meterEnabled; - - private MeterSharedState( - InstrumentationScopeInfo instrumentationScopeInfo, - List registeredReaders, - MeterConfig meterConfig) { - this.instrumentationScopeInfo = instrumentationScopeInfo; - this.readerStorageRegistries = - registeredReaders.stream() - .collect(toMap(Function.identity(), unused -> new MetricStorageRegistry())); - this.meterEnabled = meterConfig.isEnabled(); - } - - public static MeterSharedState create( - InstrumentationScopeInfo instrumentationScopeInfo, - List registeredReaders, - MeterConfig meterConfig) { - return new MeterSharedState(instrumentationScopeInfo, registeredReaders, meterConfig); - } - - /** - * Unregister the callback. - * - *

      Callbacks are originally registered via {@link #registerCallback(CallbackRegistration)}. - */ - public void removeCallback(CallbackRegistration callbackRegistration) { - synchronized (callbackLock) { - this.callbackRegistrations.remove(callbackRegistration); - } - } - - /** - * Register the callback. - * - *

      The callback will be invoked once per collection until unregistered via {@link - * #removeCallback(CallbackRegistration)}. - */ - public final void registerCallback(CallbackRegistration callbackRegistration) { - synchronized (callbackLock) { - callbackRegistrations.add(callbackRegistration); - } - } - - // only visible for testing. - /** Returns the {@link InstrumentationScopeInfo} for this {@code Meter}. */ - public InstrumentationScopeInfo getInstrumentationScopeInfo() { - return instrumentationScopeInfo; - } - - /** Returns {@code true} if the {@link MeterConfig#enabled()} of the meter is {@code true}. */ - public boolean isMeterEnabled() { - return meterEnabled; - } - - /** Collects all metrics. */ - public List collectAll( - RegisteredReader registeredReader, - MeterProviderSharedState meterProviderSharedState, - long epochNanos) { - // Short circuit collection process if meter is disabled - if (!meterEnabled) { - return Collections.emptyList(); - } - List currentRegisteredCallbacks; - synchronized (callbackLock) { - currentRegisteredCallbacks = new ArrayList<>(callbackRegistrations); - } - // Collections across all readers are sequential - synchronized (collectLock) { - for (CallbackRegistration callbackRegistration : currentRegisteredCallbacks) { - callbackRegistration.invokeCallback( - registeredReader, meterProviderSharedState.getStartEpochNanos(), epochNanos); - } - - Collection storages = - Objects.requireNonNull(readerStorageRegistries.get(registeredReader)).getStorages(); - List result = new ArrayList<>(storages.size()); - for (MetricStorage storage : storages) { - MetricData current = - storage.collect( - meterProviderSharedState.getResource(), - getInstrumentationScopeInfo(), - meterProviderSharedState.getStartEpochNanos(), - epochNanos); - // Ignore if the metric data doesn't have any data points, for example when aggregation is - // Aggregation#drop() - if (!current.isEmpty()) { - result.add(current); - } - } - return Collections.unmodifiableList(result); - } - } - - /** Reset the meter state, clearing all registered callbacks and storages. */ - public void resetForTest() { - synchronized (collectLock) { - synchronized (callbackLock) { - callbackRegistrations.clear(); - } - this.readerStorageRegistries.values().forEach(MetricStorageRegistry::resetForTest); - } - } - - /** Registers new synchronous storage associated with a given instrument. */ - public final WriteableMetricStorage registerSynchronousMetricStorage( - InstrumentDescriptor instrument, MeterProviderSharedState meterProviderSharedState) { - - List registeredStorages = new ArrayList<>(); - for (Map.Entry entry : - readerStorageRegistries.entrySet()) { - RegisteredReader reader = entry.getKey(); - MetricStorageRegistry registry = entry.getValue(); - for (RegisteredView registeredView : - reader.getViewRegistry().findViews(instrument, getInstrumentationScopeInfo())) { - if (Aggregation.drop() == registeredView.getView().getAggregation()) { - continue; - } - registeredStorages.add( - registry.register( - SynchronousMetricStorage.create( - reader, - registeredView, - instrument, - meterProviderSharedState.getExemplarFilter()))); - } - } - - if (registeredStorages.size() == 1) { - return registeredStorages.get(0); - } - - return new MultiWritableMetricStorage(registeredStorages); - } - - /** Register new asynchronous storage associated with a given instrument. */ - public final SdkObservableMeasurement registerObservableMeasurement( - InstrumentDescriptor instrumentDescriptor) { - List> registeredStorages = new ArrayList<>(); - for (Map.Entry entry : - readerStorageRegistries.entrySet()) { - RegisteredReader reader = entry.getKey(); - MetricStorageRegistry registry = entry.getValue(); - for (RegisteredView registeredView : - reader.getViewRegistry().findViews(instrumentDescriptor, getInstrumentationScopeInfo())) { - if (Aggregation.drop() == registeredView.getView().getAggregation()) { - continue; - } - registeredStorages.add( - registry.register( - AsynchronousMetricStorage.create(reader, registeredView, instrumentDescriptor))); - } - } - - return SdkObservableMeasurement.create( - instrumentationScopeInfo, instrumentDescriptor, registeredStorages); - } -} diff --git a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/state/MetricStorageRegistry.java b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/state/MetricStorageRegistry.java index a070728f06a..34bfd577a86 100644 --- a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/state/MetricStorageRegistry.java +++ b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/state/MetricStorageRegistry.java @@ -88,7 +88,7 @@ public I register(I newStorage) { } /** Reset the storage registry, clearing all storages. */ - void resetForTest() { + public void resetForTest() { synchronized (lock) { registry.clear(); } diff --git a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/state/MultiWritableMetricStorage.java b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/state/MultiWritableMetricStorage.java deleted file mode 100644 index 700fee4c3fb..00000000000 --- a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/state/MultiWritableMetricStorage.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package io.opentelemetry.sdk.metrics.internal.state; - -import io.opentelemetry.api.common.Attributes; -import io.opentelemetry.context.Context; -import java.util.List; - -class MultiWritableMetricStorage implements WriteableMetricStorage { - private final List storages; - - MultiWritableMetricStorage(List storages) { - this.storages = storages; - } - - @Override - public void recordLong(long value, Attributes attributes, Context context) { - for (WriteableMetricStorage storage : storages) { - storage.recordLong(value, attributes, context); - } - } - - @Override - public void recordDouble(double value, Attributes attributes, Context context) { - for (WriteableMetricStorage storage : storages) { - storage.recordDouble(value, attributes, context); - } - } - - @Override - public boolean isEnabled() { - for (WriteableMetricStorage storage : storages) { - if (storage.isEnabled()) { - return true; - } - } - return false; - } -} diff --git a/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/InstrumentBuilderTest.java b/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/InstrumentBuilderTest.java index c6ef1957428..de1a351e619 100644 --- a/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/InstrumentBuilderTest.java +++ b/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/InstrumentBuilderTest.java @@ -12,7 +12,6 @@ import io.opentelemetry.sdk.metrics.internal.descriptor.Advice; import io.opentelemetry.sdk.metrics.internal.exemplar.ExemplarFilter; import io.opentelemetry.sdk.metrics.internal.state.MeterProviderSharedState; -import io.opentelemetry.sdk.metrics.internal.state.MeterSharedState; import io.opentelemetry.sdk.resources.Resource; import io.opentelemetry.sdk.testing.time.TestClock; import java.util.Collections; @@ -24,18 +23,15 @@ class InstrumentBuilderTest { MeterProviderSharedState.create( TestClock.create(), Resource.getDefault(), ExemplarFilter.alwaysOff(), 0); static final InstrumentationScopeInfo SCOPE = InstrumentationScopeInfo.create("scope-name"); - public static final MeterSharedState METER_SHARED_STATE = - MeterSharedState.create(SCOPE, Collections.emptyList(), MeterConfig.defaultConfig()); + public static final SdkMeter SDK_METER = + new SdkMeter( + PROVIDER_SHARED_STATE, SCOPE, Collections.emptyList(), MeterConfig.defaultConfig()); @Test void stringRepresentation() { InstrumentBuilder builder = new InstrumentBuilder( - "instrument-name", - InstrumentType.COUNTER, - InstrumentValueType.LONG, - PROVIDER_SHARED_STATE, - METER_SHARED_STATE) + "instrument-name", InstrumentType.COUNTER, InstrumentValueType.LONG, SDK_METER) .setDescription("instrument-description") .setUnit("instrument-unit") .setAdviceBuilder(Advice.builder()); @@ -57,11 +53,7 @@ void stringRepresentation() { void toStringHelper() { InstrumentBuilder builder = new InstrumentBuilder( - "instrument-name", - InstrumentType.HISTOGRAM, - InstrumentValueType.DOUBLE, - PROVIDER_SHARED_STATE, - METER_SHARED_STATE) + "instrument-name", InstrumentType.HISTOGRAM, InstrumentValueType.DOUBLE, SDK_METER) .setDescription("instrument-description") .setUnit("instrument-unit") .setAdviceBuilder(Advice.builder()); diff --git a/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/SdkObservableInstrumentTest.java b/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/SdkObservableInstrumentTest.java index 03e52331dc7..385e6f65a8c 100644 --- a/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/SdkObservableInstrumentTest.java +++ b/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/SdkObservableInstrumentTest.java @@ -6,18 +6,16 @@ package io.opentelemetry.sdk.metrics; import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; -import static org.mockito.Mockito.spy; import static org.mockito.Mockito.verify; import io.github.netmikey.logunit.api.LogCapturer; import io.opentelemetry.internal.testing.slf4j.SuppressLogger; import io.opentelemetry.sdk.common.InstrumentationScopeInfo; -import io.opentelemetry.sdk.metrics.internal.MeterConfig; import io.opentelemetry.sdk.metrics.internal.descriptor.Advice; import io.opentelemetry.sdk.metrics.internal.descriptor.InstrumentDescriptor; import io.opentelemetry.sdk.metrics.internal.state.CallbackRegistration; -import io.opentelemetry.sdk.metrics.internal.state.MeterSharedState; import io.opentelemetry.sdk.metrics.internal.state.SdkObservableMeasurement; import java.util.Collections; import org.junit.jupiter.api.BeforeEach; @@ -30,18 +28,13 @@ class SdkObservableInstrumentTest { @RegisterExtension LogCapturer logs = LogCapturer.create().captureForType(SdkObservableInstrument.class); - private MeterSharedState meterSharedState; private CallbackRegistration callbackRegistration; + private SdkMeter sdkMeter; private SdkObservableInstrument observableInstrument; @BeforeEach void setup() { - meterSharedState = - spy( - MeterSharedState.create( - InstrumentationScopeInfo.empty(), - Collections.emptyList(), - MeterConfig.defaultConfig())); + sdkMeter = mock(SdkMeter.class); callbackRegistration = CallbackRegistration.create( Collections.singletonList( @@ -57,7 +50,7 @@ void setup() { Collections.emptyList())), () -> {}); - observableInstrument = new SdkObservableInstrument(meterSharedState, callbackRegistration); + observableInstrument = new SdkObservableInstrument(sdkMeter, callbackRegistration); } @Test @@ -65,13 +58,13 @@ void setup() { void close() { // First call to close should trigger remove from meter shared state observableInstrument.close(); - verify(meterSharedState).removeCallback(callbackRegistration); + verify(sdkMeter).removeCallback(callbackRegistration); logs.assertDoesNotContain("has called close() multiple times."); // Close a second time should not trigger remove from meter shared state - Mockito.reset(meterSharedState); + Mockito.reset(sdkMeter); observableInstrument.close(); - verify(meterSharedState, never()).removeCallback(callbackRegistration); + verify(sdkMeter, never()).removeCallback(callbackRegistration); logs.assertContains("has called close() multiple times."); } From 98fa29609823aa3f75661858acd391bdcf66f4a5 Mon Sep 17 00:00:00 2001 From: Jonathan Halliday Date: Tue, 5 Nov 2024 18:36:52 +0000 Subject: [PATCH 649/901] Add ByteBuffer field type marshaling support to exporter. (#6686) --- .../internal/marshal/CodedOutputStream.java | 53 ++++++++++++++++++- .../internal/marshal/JsonSerializer.java | 8 +++ .../internal/marshal/MarshalerUtil.java | 9 ++++ .../internal/marshal/ProtoSerializer.java | 7 +++ .../exporter/internal/marshal/Serializer.java | 15 ++++++ .../profiles/ProfileContainerMarshaler.java | 21 ++++---- 6 files changed, 103 insertions(+), 10 deletions(-) diff --git a/exporters/common/src/main/java/io/opentelemetry/exporter/internal/marshal/CodedOutputStream.java b/exporters/common/src/main/java/io/opentelemetry/exporter/internal/marshal/CodedOutputStream.java index 8cc17a7834b..68311be1845 100644 --- a/exporters/common/src/main/java/io/opentelemetry/exporter/internal/marshal/CodedOutputStream.java +++ b/exporters/common/src/main/java/io/opentelemetry/exporter/internal/marshal/CodedOutputStream.java @@ -44,6 +44,7 @@ import io.opentelemetry.api.internal.ConfigUtil; import java.io.IOException; import java.io.OutputStream; +import java.nio.ByteBuffer; /** * Protobuf wire encoder. @@ -56,7 +57,7 @@ // // Differences // - No support for Message/Lite -// - No support for ByteString or ByteBuffer +// - No support for ByteString // - No support for message set extensions // - No support for Unsafe // - No support for Java String, only UTF-8 bytes @@ -329,6 +330,11 @@ public static int computeByteArraySizeNoTag(final byte[] value) { return computeLengthDelimitedFieldSize(value.length); } + /** Compute the number of bytes that would be needed to encode a {@code bytes} field. */ + public static int computeByteBufferSizeNoTag(final ByteBuffer value) { + return computeLengthDelimitedFieldSize(value.capacity()); + } + static int computeLengthDelimitedFieldSize(int fieldLength) { return computeUInt32SizeNoTag(fieldLength) + fieldLength; } @@ -375,6 +381,8 @@ static long encodeZigZag64(final long n) { abstract void writeByteArrayNoTag(final byte[] value, final int offset, final int length) throws IOException; + abstract void writeByteBufferNoTag(final ByteBuffer value) throws IOException; + // ================================================================= /** Abstract base class for buffered encoders. */ @@ -487,6 +495,49 @@ void writeByteArrayNoTag(final byte[] value, int offset, int length) throws IOEx write(value, offset, length); } + @Override + void writeByteBufferNoTag(final ByteBuffer value) throws IOException { + writeUInt32NoTag(value.capacity()); + if (value.hasArray()) { + write(value.array(), value.arrayOffset(), value.capacity()); + } else { + write((ByteBuffer) value.duplicate().clear()); + } + } + + void write(ByteBuffer value) throws IOException { + int length = value.remaining(); + if (limit - position >= length) { + // We have room in the current buffer. + value.get(buffer, position, length); + position += length; + totalBytesWritten += length; + } else { + // Write extends past current buffer. Fill the rest of this buffer and + // flush. + final int bytesWritten = limit - position; + value.get(buffer, position, bytesWritten); + length -= bytesWritten; + position = limit; + totalBytesWritten += bytesWritten; + doFlush(); + + // Now deal with the rest. + // Since we have an output stream, this is our buffer + // and buffer offset == 0 + while (length > limit) { + // Copy data into the buffer before writing it to OutputStream. + value.get(buffer, 0, limit); + out.write(buffer, 0, limit); + length -= limit; + totalBytesWritten += limit; + } + value.get(buffer, 0, length); + position = length; + totalBytesWritten += length; + } + } + @Override void write(byte value) throws IOException { if (position == limit) { diff --git a/exporters/common/src/main/java/io/opentelemetry/exporter/internal/marshal/JsonSerializer.java b/exporters/common/src/main/java/io/opentelemetry/exporter/internal/marshal/JsonSerializer.java index 7d8ad3aad3f..680220b5e3e 100644 --- a/exporters/common/src/main/java/io/opentelemetry/exporter/internal/marshal/JsonSerializer.java +++ b/exporters/common/src/main/java/io/opentelemetry/exporter/internal/marshal/JsonSerializer.java @@ -9,6 +9,7 @@ import com.fasterxml.jackson.core.JsonGenerator; import java.io.IOException; import java.io.OutputStream; +import java.nio.ByteBuffer; import java.nio.charset.StandardCharsets; import java.util.List; @@ -126,6 +127,13 @@ public void writeBytes(ProtoFieldInfo field, byte[] value) throws IOException { generator.writeBinaryField(field.getJsonName(), value); } + @Override + public void writeByteBuffer(ProtoFieldInfo field, ByteBuffer value) throws IOException { + byte[] data = new byte[value.capacity()]; + ((ByteBuffer) value.duplicate().clear()).get(data); + generator.writeBinaryField(field.getJsonName(), data); + } + @Override protected void writeStartMessage(ProtoFieldInfo field, int protoMessageSize) throws IOException { generator.writeObjectFieldStart(field.getJsonName()); diff --git a/exporters/common/src/main/java/io/opentelemetry/exporter/internal/marshal/MarshalerUtil.java b/exporters/common/src/main/java/io/opentelemetry/exporter/internal/marshal/MarshalerUtil.java index 3fff240704f..d7f6d44c871 100644 --- a/exporters/common/src/main/java/io/opentelemetry/exporter/internal/marshal/MarshalerUtil.java +++ b/exporters/common/src/main/java/io/opentelemetry/exporter/internal/marshal/MarshalerUtil.java @@ -13,6 +13,7 @@ import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.UncheckedIOException; +import java.nio.ByteBuffer; import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.Collection; @@ -346,6 +347,14 @@ public static int sizeBytes(ProtoFieldInfo field, byte[] message) { return field.getTagSize() + CodedOutputStream.computeByteArraySizeNoTag(message); } + /** Returns the size of a bytes field based on the buffer's capacity. */ + public static int sizeByteBuffer(ProtoFieldInfo field, ByteBuffer message) { + if (message.capacity() == 0) { + return 0; + } + return field.getTagSize() + CodedOutputStream.computeByteBufferSizeNoTag(message); + } + /** Returns the size of a enum field. */ // Assumes OTLP always defines the first item in an enum with number 0, which it does and will. public static int sizeEnum(ProtoFieldInfo field, ProtoEnumInfo enumValue) { diff --git a/exporters/common/src/main/java/io/opentelemetry/exporter/internal/marshal/ProtoSerializer.java b/exporters/common/src/main/java/io/opentelemetry/exporter/internal/marshal/ProtoSerializer.java index b71109912b2..62f4a175982 100644 --- a/exporters/common/src/main/java/io/opentelemetry/exporter/internal/marshal/ProtoSerializer.java +++ b/exporters/common/src/main/java/io/opentelemetry/exporter/internal/marshal/ProtoSerializer.java @@ -10,6 +10,7 @@ import io.opentelemetry.api.trace.TraceId; import java.io.IOException; import java.io.OutputStream; +import java.nio.ByteBuffer; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -168,6 +169,12 @@ public void writeBytes(ProtoFieldInfo field, byte[] value) throws IOException { output.writeByteArrayNoTag(value); } + @Override + public void writeByteBuffer(ProtoFieldInfo field, ByteBuffer value) throws IOException { + output.writeUInt32NoTag(field.getTag()); + output.writeByteBufferNoTag(value); + } + @Override protected void writeStartMessage(ProtoFieldInfo field, int protoMessageSize) throws IOException { output.writeUInt32NoTag(field.getTag()); diff --git a/exporters/common/src/main/java/io/opentelemetry/exporter/internal/marshal/Serializer.java b/exporters/common/src/main/java/io/opentelemetry/exporter/internal/marshal/Serializer.java index 205ec192e35..e7970d57491 100644 --- a/exporters/common/src/main/java/io/opentelemetry/exporter/internal/marshal/Serializer.java +++ b/exporters/common/src/main/java/io/opentelemetry/exporter/internal/marshal/Serializer.java @@ -9,6 +9,7 @@ import io.opentelemetry.api.common.Attributes; import io.opentelemetry.sdk.internal.DynamicPrimitiveLongList; import java.io.IOException; +import java.nio.ByteBuffer; import java.util.Collection; import java.util.List; import java.util.Map; @@ -253,8 +254,22 @@ public void serializeBytes(ProtoFieldInfo field, byte[] value) throws IOExceptio writeBytes(field, value); } + /** + * Serializes a protobuf {@code bytes} field. Writes all content of the ByteBuffer regardless of + * the current position and limit. Does not alter the position or limit of the provided + * ByteBuffer. + */ + public void serializeByteBuffer(ProtoFieldInfo field, ByteBuffer value) throws IOException { + if (value.capacity() == 0) { + return; + } + writeByteBuffer(field, value); + } + public abstract void writeBytes(ProtoFieldInfo field, byte[] value) throws IOException; + public abstract void writeByteBuffer(ProtoFieldInfo field, ByteBuffer value) throws IOException; + protected abstract void writeStartMessage(ProtoFieldInfo field, int protoMessageSize) throws IOException; diff --git a/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/ProfileContainerMarshaler.java b/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/ProfileContainerMarshaler.java index 61369962296..984a18c94a9 100644 --- a/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/ProfileContainerMarshaler.java +++ b/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/ProfileContainerMarshaler.java @@ -11,6 +11,7 @@ import io.opentelemetry.exporter.internal.otlp.KeyValueMarshaler; import io.opentelemetry.proto.profiles.v1experimental.internal.ProfileContainer; import java.io.IOException; +import java.nio.ByteBuffer; final class ProfileContainerMarshaler extends MarshalerWithSize { @@ -20,17 +21,19 @@ final class ProfileContainerMarshaler extends MarshalerWithSize { private final KeyValueMarshaler[] attributeMarshalers; private final int droppedAttributesCount; private final byte[] originalPayloadFormatUtf8; - private final byte[] originalPayload; + private final ByteBuffer originalPayload; private final ProfileMarshaler profileMarshaler; static ProfileContainerMarshaler create(ProfileContainerData profileContainerData) { int droppedAttributesCount = profileContainerData.getTotalAttributeCount() - profileContainerData.getAttributes().size(); - // Not ideal, but this will do for now. ByteBuffer support in - // Serialzer/CodedOutputStream/MarshalerUtilwill follow in a separate step. - byte[] originalPayload = new byte[profileContainerData.getOriginalPayload().remaining()]; - profileContainerData.getOriginalPayload().get(originalPayload); + ByteBuffer originalPayload = profileContainerData.getOriginalPayload(); + if (originalPayload == null) { + originalPayload = ByteBuffer.allocate(0); + } else { + originalPayload = originalPayload.duplicate().asReadOnlyBuffer(); + } return new ProfileContainerMarshaler( profileContainerData.getProfileIdBytes(), @@ -50,7 +53,7 @@ private ProfileContainerMarshaler( KeyValueMarshaler[] attributeMarshalers, int droppedAttributesCount, byte[] originalPayloadFormat, - byte[] originalPayload, + ByteBuffer originalPayload, ProfileMarshaler profileMarshaler) { super( calculateSize( @@ -80,7 +83,7 @@ protected void writeTo(Serializer output) throws IOException { output.serializeRepeatedMessage(ProfileContainer.ATTRIBUTES, attributeMarshalers); output.serializeUInt32(ProfileContainer.DROPPED_ATTRIBUTES_COUNT, droppedAttributesCount); output.serializeString(ProfileContainer.ORIGINAL_PAYLOAD_FORMAT, originalPayloadFormatUtf8); - output.serializeBytes(ProfileContainer.ORIGINAL_PAYLOAD, originalPayload); + output.serializeByteBuffer(ProfileContainer.ORIGINAL_PAYLOAD, originalPayload); output.serializeMessage(ProfileContainer.PROFILE, profileMarshaler); } @@ -91,7 +94,7 @@ private static int calculateSize( KeyValueMarshaler[] attributeMarshalers, int droppedAttributesCount, byte[] originalPayloadFormat, - byte[] originalPayload, + ByteBuffer originalPayload, ProfileMarshaler profileMarshaler) { int size; size = 0; @@ -103,7 +106,7 @@ private static int calculateSize( MarshalerUtil.sizeUInt32(ProfileContainer.DROPPED_ATTRIBUTES_COUNT, droppedAttributesCount); size += MarshalerUtil.sizeBytes(ProfileContainer.ORIGINAL_PAYLOAD_FORMAT, originalPayloadFormat); - size += MarshalerUtil.sizeBytes(ProfileContainer.ORIGINAL_PAYLOAD, originalPayload); + size += MarshalerUtil.sizeByteBuffer(ProfileContainer.ORIGINAL_PAYLOAD, originalPayload); size += MarshalerUtil.sizeMessage(ProfileContainer.PROFILE, profileMarshaler); return size; } From a6b33029be2287ea459ed93edbc02298a3515905 Mon Sep 17 00:00:00 2001 From: Gregor Zeitlinger Date: Tue, 5 Nov 2024 19:37:40 +0100 Subject: [PATCH 650/901] bugfix: add newline in stdout exporter (#6848) --- .../exporter/internal/marshal/Marshaler.java | 8 +++++ .../internal/writer/StreamJsonWriter.java | 2 +- .../otlp/AbstractOtlpStdoutExporterTest.java | 30 +++++++++++++++---- .../internal/writer/StreamJsonWriterTest.java | 4 ++- .../PrometheusMetricReaderTest.java | 8 +++-- 5 files changed, 42 insertions(+), 10 deletions(-) diff --git a/exporters/common/src/main/java/io/opentelemetry/exporter/internal/marshal/Marshaler.java b/exporters/common/src/main/java/io/opentelemetry/exporter/internal/marshal/Marshaler.java index 2e6fba4644c..6201481c024 100644 --- a/exporters/common/src/main/java/io/opentelemetry/exporter/internal/marshal/Marshaler.java +++ b/exporters/common/src/main/java/io/opentelemetry/exporter/internal/marshal/Marshaler.java @@ -38,6 +38,14 @@ public final void writeJsonTo(JsonGenerator output) throws IOException { } } + /** Marshals into the {@link JsonGenerator} in proto JSON format and adds a newline. */ + public final void writeJsonWithNewline(JsonGenerator output) throws IOException { + try (JsonSerializer serializer = new JsonSerializer(output)) { + serializer.writeMessageValue(this); + output.writeRaw('\n'); + } + } + /** Returns the number of bytes this Marshaler will write in proto binary format. */ public abstract int getBinarySerializedSize(); diff --git a/exporters/logging-otlp/src/main/java/io/opentelemetry/exporter/logging/otlp/internal/writer/StreamJsonWriter.java b/exporters/logging-otlp/src/main/java/io/opentelemetry/exporter/logging/otlp/internal/writer/StreamJsonWriter.java index 0674810fa5c..0f47ce20e09 100644 --- a/exporters/logging-otlp/src/main/java/io/opentelemetry/exporter/logging/otlp/internal/writer/StreamJsonWriter.java +++ b/exporters/logging-otlp/src/main/java/io/opentelemetry/exporter/logging/otlp/internal/writer/StreamJsonWriter.java @@ -38,7 +38,7 @@ public StreamJsonWriter(OutputStream originalStream, String type) { @Override public CompletableResultCode write(Marshaler exportRequest) { try { - exportRequest.writeJsonTo( + exportRequest.writeJsonWithNewline( JSON_FACTORY .createGenerator(outputStream) .disable(JsonGenerator.Feature.AUTO_CLOSE_TARGET)); diff --git a/exporters/logging-otlp/src/test/java/io/opentelemetry/exporter/logging/otlp/AbstractOtlpStdoutExporterTest.java b/exporters/logging-otlp/src/test/java/io/opentelemetry/exporter/logging/otlp/AbstractOtlpStdoutExporterTest.java index 3988fae332d..54835720d3c 100644 --- a/exporters/logging-otlp/src/test/java/io/opentelemetry/exporter/logging/otlp/AbstractOtlpStdoutExporterTest.java +++ b/exporters/logging-otlp/src/test/java/io/opentelemetry/exporter/logging/otlp/AbstractOtlpStdoutExporterTest.java @@ -34,7 +34,6 @@ import java.util.function.Supplier; import java.util.stream.Stream; import javax.annotation.Nullable; -import org.json.JSONException; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.BeforeEach; @@ -57,6 +56,7 @@ abstract class AbstractOtlpStdoutExporterTest { private static final PrintStream SYSTEM_OUT_PRINT_STREAM = new PrintStream(SYSTEM_OUT_STREAM); @RegisterExtension LogCapturer logs; + private int skipLogs; private final String defaultConfigString; private final TestDataExporter testDataExporter; protected final Class exporterClass; @@ -87,6 +87,7 @@ protected abstract T createExporter( private String output(@Nullable OutputStream outputStream, @Nullable Path file) { if (outputStream == null) { return logs.getEvents().stream() + .skip(skipLogs) .map(LoggingEvent::getMessage) .reduce("", (a, b) -> a + b + "\n") .trim(); @@ -94,14 +95,14 @@ private String output(@Nullable OutputStream outputStream, @Nullable Path file) if (file != null) { try { - return new String(Files.readAllBytes(file), StandardCharsets.UTF_8); + return new String(Files.readAllBytes(file), StandardCharsets.UTF_8).trim(); } catch (IOException e) { throw new RuntimeException(e); } } try { - return SYSTEM_OUT_STREAM.toString(StandardCharsets.UTF_8.name()); + return SYSTEM_OUT_STREAM.toString(StandardCharsets.UTF_8.name()).trim(); } catch (UnsupportedEncodingException e) { throw new RuntimeException(e); } @@ -204,8 +205,7 @@ private static Arguments testCase( @SuppressWarnings("SystemOut") @ParameterizedTest(name = "{0}") @MethodSource("exportTestCases") - void exportWithProgrammaticConfig(String name, TestCase testCase) - throws JSONException, IOException { + void exportWithProgrammaticConfig(String name, TestCase testCase) throws Exception { OutputStream outputStream; Path file = null; switch (testCase.getOutputType()) { @@ -247,6 +247,26 @@ void exportWithProgrammaticConfig(String name, TestCase testCase) if (testCase.isWrapperJsonObject()) { assertThat(output).doesNotContain("\n"); } + + if (file == null) { + // no need to test again for file - and it's not working with files + assertDoubleOutput(exporter, expectedJson, outputStream); + } + } + + private void assertDoubleOutput( + Supplier exporter, String expectedJson, @Nullable OutputStream outputStream) + throws Exception { + SYSTEM_OUT_STREAM.reset(); + skipLogs = logs.getEvents().size(); + testDataExporter.export(exporter.get()); + testDataExporter.export(exporter.get()); + + String[] lines = output(outputStream, null).split("\n"); + assertThat(lines).hasSize(2); + for (String line : lines) { + JSONAssert.assertEquals("Got \n" + line, expectedJson, line, false); + } } @Test diff --git a/exporters/logging-otlp/src/test/java/io/opentelemetry/exporter/logging/otlp/internal/writer/StreamJsonWriterTest.java b/exporters/logging-otlp/src/test/java/io/opentelemetry/exporter/logging/otlp/internal/writer/StreamJsonWriterTest.java index 2245a15e0c0..eabfbc53517 100644 --- a/exporters/logging-otlp/src/test/java/io/opentelemetry/exporter/logging/otlp/internal/writer/StreamJsonWriterTest.java +++ b/exporters/logging-otlp/src/test/java/io/opentelemetry/exporter/logging/otlp/internal/writer/StreamJsonWriterTest.java @@ -46,7 +46,9 @@ void testToString() throws IOException { @Test void errorWriting() throws IOException { Marshaler marshaler = mock(Marshaler.class); - Mockito.doThrow(new IOException("test")).when(marshaler).writeJsonTo(any(JsonGenerator.class)); + Mockito.doThrow(new IOException("test")) + .when(marshaler) + .writeJsonWithNewline(any(JsonGenerator.class)); StreamJsonWriter writer = new StreamJsonWriter(System.out, "type"); writer.write(marshaler); diff --git a/exporters/prometheus/src/test/java/io/opentelemetry/exporter/prometheus/PrometheusMetricReaderTest.java b/exporters/prometheus/src/test/java/io/opentelemetry/exporter/prometheus/PrometheusMetricReaderTest.java index 1a4f9d42889..20076cc9c9d 100644 --- a/exporters/prometheus/src/test/java/io/opentelemetry/exporter/prometheus/PrometheusMetricReaderTest.java +++ b/exporters/prometheus/src/test/java/io/opentelemetry/exporter/prometheus/PrometheusMetricReaderTest.java @@ -616,7 +616,7 @@ private static void assertExponentialHistogramComplete( + " value: 7.0\n" + " timestamp {\n" + " seconds: \n" - + " nanos: \n" + + " \n" + " }\n" + " }\n" + " }\n" @@ -661,7 +661,7 @@ private static void assertExponentialHistogramComplete( + " value: 3.0\n" + " timestamp {\n" + " seconds: \n" - + " nanos: \n" + + " \n" + " }\n" + " }\n" + " }\n" @@ -1115,7 +1115,9 @@ private static void assertMatches(String expected, String actual) { */ private static String toPattern(String expected) { Map replacePatterns = new HashMap<>(); - replacePatterns.put("timestamp", "[0-9]+(\\.[0-9]+)?"); + String timestampPattern = "[0-9]+(\\.[0-9]+)?"; + replacePatterns.put("timestamp", timestampPattern); + replacePatterns.put("maybeNanos", String.format("(nanos: %s)?", timestampPattern)); replacePatterns.put("spanId", "[a-z0-9]*"); replacePatterns.put("traceId", "[a-z0-9]*"); replacePatterns.put("measurement", "[0-9\\.]*"); From bc2487f2741ac287a49fca6d8d327b0b707211f4 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 6 Nov 2024 18:40:08 -0800 Subject: [PATCH 651/901] fix(deps): update dependency nl.jqno.equalsverifier:equalsverifier to v3.17.2 (#6849) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- dependencyManagement/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index 7b6c1d0a55b..f89c83d9c07 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -74,7 +74,7 @@ val DEPENDENCIES = listOf( "io.opentracing:opentracing-noop:0.33.0", "io.prometheus:prometheus-metrics-exporter-httpserver:1.3.2", "junit:junit:4.13.2", - "nl.jqno.equalsverifier:equalsverifier:3.17.1", + "nl.jqno.equalsverifier:equalsverifier:3.17.2", "org.awaitility:awaitility:4.2.2", "org.bouncycastle:bcpkix-jdk15on:1.70", "org.codehaus.mojo:animal-sniffer-annotations:1.24", From 6c3725d91622ef529f16de7d9c41ab55acb6525c Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 7 Nov 2024 09:10:45 -0800 Subject: [PATCH 652/901] fix(deps): update dependency checkstyle to v10.20.1 (#6856) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- buildSrc/src/main/kotlin/otel.java-conventions.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/buildSrc/src/main/kotlin/otel.java-conventions.gradle.kts b/buildSrc/src/main/kotlin/otel.java-conventions.gradle.kts index c9f22e8e4fd..8d75dc8e36b 100644 --- a/buildSrc/src/main/kotlin/otel.java-conventions.gradle.kts +++ b/buildSrc/src/main/kotlin/otel.java-conventions.gradle.kts @@ -42,7 +42,7 @@ java { checkstyle { configDirectory.set(file("$rootDir/buildscripts/")) - toolVersion = "10.20.0" + toolVersion = "10.20.1" isIgnoreFailures = false configProperties["rootDir"] = rootDir } From 2a1c2749ff8e1f263cbea1ba0a9abad0a56ec35c Mon Sep 17 00:00:00 2001 From: Gregor Zeitlinger Date: Fri, 8 Nov 2024 16:15:58 +0100 Subject: [PATCH 653/901] update prom client (#6857) --- dependencyManagement/build.gradle.kts | 2 +- .../prometheus/Otel2PrometheusConverter.java | 27 +++++++++---------- .../prometheus/PrometheusHttpServerTest.java | 2 +- 3 files changed, 14 insertions(+), 17 deletions(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index f89c83d9c07..a55b0fe0a4f 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -72,7 +72,7 @@ val DEPENDENCIES = listOf( "io.opentelemetry.proto:opentelemetry-proto:1.3.2-alpha", "io.opentracing:opentracing-api:0.33.0", "io.opentracing:opentracing-noop:0.33.0", - "io.prometheus:prometheus-metrics-exporter-httpserver:1.3.2", + "io.prometheus:prometheus-metrics-exporter-httpserver:1.3.3", "junit:junit:4.13.2", "nl.jqno.equalsverifier:equalsverifier:3.17.2", "org.awaitility:awaitility:4.2.2", diff --git a/exporters/prometheus/src/main/java/io/opentelemetry/exporter/prometheus/Otel2PrometheusConverter.java b/exporters/prometheus/src/main/java/io/opentelemetry/exporter/prometheus/Otel2PrometheusConverter.java index f3a6eef744e..e1cb84d9766 100644 --- a/exporters/prometheus/src/main/java/io/opentelemetry/exporter/prometheus/Otel2PrometheusConverter.java +++ b/exporters/prometheus/src/main/java/io/opentelemetry/exporter/prometheus/Otel2PrometheusConverter.java @@ -33,7 +33,6 @@ import io.prometheus.metrics.model.snapshots.ClassicHistogramBuckets; import io.prometheus.metrics.model.snapshots.CounterSnapshot; import io.prometheus.metrics.model.snapshots.CounterSnapshot.CounterDataPointSnapshot; -import io.prometheus.metrics.model.snapshots.DataPointSnapshot; import io.prometheus.metrics.model.snapshots.Exemplar; import io.prometheus.metrics.model.snapshots.Exemplars; import io.prometheus.metrics.model.snapshots.GaugeSnapshot; @@ -110,11 +109,11 @@ MetricSnapshots convert(@Nullable Collection metricDataCollection) { if (metricDataCollection == null || metricDataCollection.isEmpty()) { return MetricSnapshots.of(); } - Map> snapshotsByName = new HashMap<>(metricDataCollection.size()); + Map snapshotsByName = new HashMap<>(metricDataCollection.size()); Resource resource = null; Set scopes = new LinkedHashSet<>(); for (MetricData metricData : metricDataCollection) { - MetricSnapshot snapshot = convert(metricData); + MetricSnapshot snapshot = convert(metricData); if (snapshot == null) { continue; } @@ -136,7 +135,7 @@ MetricSnapshots convert(@Nullable Collection metricDataCollection) { } @Nullable - private MetricSnapshot convert(MetricData metricData) { + private MetricSnapshot convert(MetricData metricData) { // Note that AggregationTemporality.DELTA should never happen // because PrometheusMetricReader#getAggregationTemporality returns CUMULATIVE. @@ -549,10 +548,10 @@ private static MetricMetadata convertMetadata(MetricData metricData) { } private static void putOrMerge( - Map> snapshotsByName, MetricSnapshot snapshot) { + Map snapshotsByName, MetricSnapshot snapshot) { String name = snapshot.getMetadata().getPrometheusName(); if (snapshotsByName.containsKey(name)) { - MetricSnapshot merged = merge(snapshotsByName.get(name), snapshot); + MetricSnapshot merged = merge(snapshotsByName.get(name), snapshot); if (merged != null) { snapshotsByName.put(name, merged); } @@ -568,9 +567,7 @@ private static void putOrMerge( * type. If the type differs, we log a message and drop one of them. */ @Nullable - @SuppressWarnings("unchecked") - private static MetricSnapshot merge( - MetricSnapshot a, MetricSnapshot b) { + private static MetricSnapshot merge(MetricSnapshot a, MetricSnapshot b) { MetricMetadata metadata = mergeMetadata(a.getMetadata(), b.getMetadata()); if (metadata == null) { return null; @@ -580,27 +577,27 @@ private static MetricSnapshot merge( List dataPoints = new ArrayList<>(numberOfDataPoints); dataPoints.addAll(((GaugeSnapshot) a).getDataPoints()); dataPoints.addAll(((GaugeSnapshot) b).getDataPoints()); - return (MetricSnapshot) new GaugeSnapshot(metadata, dataPoints); + return new GaugeSnapshot(metadata, dataPoints); } else if (a instanceof CounterSnapshot && b instanceof CounterSnapshot) { List dataPoints = new ArrayList<>(numberOfDataPoints); dataPoints.addAll(((CounterSnapshot) a).getDataPoints()); dataPoints.addAll(((CounterSnapshot) b).getDataPoints()); - return (MetricSnapshot) new CounterSnapshot(metadata, dataPoints); + return new CounterSnapshot(metadata, dataPoints); } else if (a instanceof HistogramSnapshot && b instanceof HistogramSnapshot) { List dataPoints = new ArrayList<>(numberOfDataPoints); dataPoints.addAll(((HistogramSnapshot) a).getDataPoints()); dataPoints.addAll(((HistogramSnapshot) b).getDataPoints()); - return (MetricSnapshot) new HistogramSnapshot(metadata, dataPoints); + return new HistogramSnapshot(metadata, dataPoints); } else if (a instanceof SummarySnapshot && b instanceof SummarySnapshot) { List dataPoints = new ArrayList<>(numberOfDataPoints); dataPoints.addAll(((SummarySnapshot) a).getDataPoints()); dataPoints.addAll(((SummarySnapshot) b).getDataPoints()); - return (MetricSnapshot) new SummarySnapshot(metadata, dataPoints); + return new SummarySnapshot(metadata, dataPoints); } else if (a instanceof InfoSnapshot && b instanceof InfoSnapshot) { List dataPoints = new ArrayList<>(numberOfDataPoints); dataPoints.addAll(((InfoSnapshot) a).getDataPoints()); dataPoints.addAll(((InfoSnapshot) b).getDataPoints()); - return (MetricSnapshot) new InfoSnapshot(metadata, dataPoints); + return new InfoSnapshot(metadata, dataPoints); } else { THROTTLING_LOGGER.log( Level.WARNING, @@ -641,7 +638,7 @@ private static MetricMetadata mergeMetadata(MetricMetadata a, MetricMetadata b) return new MetricMetadata(name, help, unit); } - private static String typeString(MetricSnapshot snapshot) { + private static String typeString(MetricSnapshot snapshot) { // Simple helper for a log message. return snapshot.getClass().getSimpleName().replace("Snapshot", "").toLowerCase(Locale.ENGLISH); } diff --git a/exporters/prometheus/src/test/java/io/opentelemetry/exporter/prometheus/PrometheusHttpServerTest.java b/exporters/prometheus/src/test/java/io/opentelemetry/exporter/prometheus/PrometheusHttpServerTest.java index 8cf1440a023..382e661b5ab 100644 --- a/exporters/prometheus/src/test/java/io/opentelemetry/exporter/prometheus/PrometheusHttpServerTest.java +++ b/exporters/prometheus/src/test/java/io/opentelemetry/exporter/prometheus/PrometheusHttpServerTest.java @@ -44,7 +44,7 @@ import io.prometheus.metrics.exporter.httpserver.MetricsHandler; import io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics; import io.prometheus.metrics.model.registry.PrometheusRegistry; -import io.prometheus.metrics.shaded.com_google_protobuf_4_28_2.TextFormat; +import io.prometheus.metrics.shaded.com_google_protobuf_4_28_3.TextFormat; import java.io.ByteArrayInputStream; import java.io.IOException; import java.net.ServerSocket; From 0a4aa3cbd27bb60e91ea38a0090d23cafef50f89 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 8 Nov 2024 09:16:14 -0600 Subject: [PATCH 654/901] fix(deps): update dependency me.champeau.gradle:japicmp-gradle-plugin to v0.4.5 (#6859) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- buildSrc/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts index a00b575998d..21eb3cecc4b 100644 --- a/buildSrc/build.gradle.kts +++ b/buildSrc/build.gradle.kts @@ -61,7 +61,7 @@ dependencies { implementation("com.squareup.wire:wire-gradle-plugin") implementation("gradle.plugin.com.google.protobuf:protobuf-gradle-plugin:0.8.18") implementation("gradle.plugin.io.morethan.jmhreport:gradle-jmh-report:0.9.6") - implementation("me.champeau.gradle:japicmp-gradle-plugin:0.4.4") + implementation("me.champeau.gradle:japicmp-gradle-plugin:0.4.5") implementation("me.champeau.jmh:jmh-gradle-plugin:0.7.2") implementation("net.ltgt.gradle:gradle-errorprone-plugin:4.1.0") implementation("net.ltgt.gradle:gradle-nullaway-plugin:2.1.0") From 7dcf73f2d8d83763312a6268ddaf71d337cc89b5 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 8 Nov 2024 09:17:44 -0600 Subject: [PATCH 655/901] fix(deps): update dependency com.android.tools:desugar_jdk_libs to v2.1.3 (#6853) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- dependencyManagement/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index a55b0fe0a4f..2516494b3b9 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -82,7 +82,7 @@ val DEPENDENCIES = listOf( "org.junit-pioneer:junit-pioneer:1.9.1", "org.mock-server:mockserver-netty:5.15.0:shaded", "org.skyscreamer:jsonassert:1.5.3", - "com.android.tools:desugar_jdk_libs:2.1.2", + "com.android.tools:desugar_jdk_libs:2.1.3", ) javaPlatform { From b5fab78314ff3322c8724984c76de78afc1452b3 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 8 Nov 2024 09:18:04 -0600 Subject: [PATCH 656/901] fix(deps): update dependency nl.jqno.equalsverifier:equalsverifier to v3.17.3 (#6854) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- dependencyManagement/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index 2516494b3b9..5d89c61c083 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -74,7 +74,7 @@ val DEPENDENCIES = listOf( "io.opentracing:opentracing-noop:0.33.0", "io.prometheus:prometheus-metrics-exporter-httpserver:1.3.3", "junit:junit:4.13.2", - "nl.jqno.equalsverifier:equalsverifier:3.17.2", + "nl.jqno.equalsverifier:equalsverifier:3.17.3", "org.awaitility:awaitility:4.2.2", "org.bouncycastle:bcpkix-jdk15on:1.70", "org.codehaus.mojo:animal-sniffer-annotations:1.24", From e38ebf5dc39565a15699ba104eb8b18e9c3a7596 Mon Sep 17 00:00:00 2001 From: jack-berg <34418638+jack-berg@users.noreply.github.com> Date: Fri, 8 Nov 2024 11:42:51 -0600 Subject: [PATCH 657/901] Prepare 1.44.0 (#6861) --- CHANGELOG.md | 57 +++++++++++++++++++ .../sdk/metrics/SdkMeterProviderBuilder.java | 2 + .../io/opentelemetry/sdk/metrics/View.java | 6 +- .../sdk/metrics/ViewBuilder.java | 1 + .../export/CardinalityLimitSelector.java | 3 +- .../sdk/trace/data/ExceptionEventData.java | 6 +- 6 files changed, 71 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index aa3f1afb9ac..bef5be2c39b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,63 @@ ## Unreleased +### API + +* Fix ConfigUtil#getString ConcurrentModificationException + ([#6841](https://github.com/open-telemetry/opentelemetry-java/pull/6841)) + +### SDK + +#### Traces + +* Stabilize ExceptionEventData + ([#6795](https://github.com/open-telemetry/opentelemetry-java/pull/6795)) + +#### Metrics + +* Stabilize metric cardinality limits + ([#6794](https://github.com/open-telemetry/opentelemetry-java/pull/6794)) +* Refactor metrics internals to remove MeterSharedState + ([#6845](https://github.com/open-telemetry/opentelemetry-java/pull/6845)) + +#### Exporters + +* Add memory mode option to stdout exporters + ([#6774](https://github.com/open-telemetry/opentelemetry-java/pull/6774)) +* Log a warning if OTLP endpoint port is likely incorrect given the protocol + ([#6813](https://github.com/open-telemetry/opentelemetry-java/pull/6813)) +* Fix OTLP gRPC retry mechanism for unsuccessful HTTP responses + ([#6829](https://github.com/open-telemetry/opentelemetry-java/pull/6829)) +* Add ByteBuffer field type marshaling support + ([#6686](https://github.com/open-telemetry/opentelemetry-java/pull/6686)) +* Fix stdout exporter format by adding newline after each export + ([#6848](https://github.com/open-telemetry/opentelemetry-java/pull/6848)) +* Enable `reusuable_data` memory mode by default for `OtlpGrpc{Signal}Exporter`, + `OtlpHttp{Signal}Exporter`, `OtlpStdout{Signal}Exporter`, and `PrometheusHttpServer` + ([#6799](https://github.com/open-telemetry/opentelemetry-java/pull/6799)) + +#### Extension + +* Rebrand file configuration to declarative configuration in documentation + ([#6812](https://github.com/open-telemetry/opentelemetry-java/pull/6812)) +* Fix declarative config `file_format` validation + ([#6786](https://github.com/open-telemetry/opentelemetry-java/pull/6786)) +* Fix declarative config env substitution by disallowing '}' in default value + ([#6793](https://github.com/open-telemetry/opentelemetry-java/pull/6793)) +* Set declarative config default OTLP protocol to http/protobuf + ([#6800](https://github.com/open-telemetry/opentelemetry-java/pull/6800)) +* Stabilize autoconfigure disabling of resource keys via `otel.resource.disabled.keys` + ([#6809](https://github.com/open-telemetry/opentelemetry-java/pull/6809)) + +### Tooling + +* Run tests on Java 23 + ([#6825](https://github.com/open-telemetry/opentelemetry-java/pull/6825)) +* Test Windows in CI + ([#6824](https://github.com/open-telemetry/opentelemetry-java/pull/6824)) +* Add error prone checks for internal javadoc and private constructors + ([#6844](https://github.com/open-telemetry/opentelemetry-java/pull/6844)) + ## Version 1.43.0 (2024-10-11) ### API diff --git a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkMeterProviderBuilder.java b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkMeterProviderBuilder.java index 1a9e5b27a64..90d0c7a8fef 100644 --- a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkMeterProviderBuilder.java +++ b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkMeterProviderBuilder.java @@ -139,6 +139,8 @@ public SdkMeterProviderBuilder registerMetricReader(MetricReader reader) { * *

      If {@link #registerMetricReader(MetricReader)} is used, the {@link * CardinalityLimitSelector#defaultCardinalityLimitSelector()} is used. + * + * @since 1.44.0 */ public SdkMeterProviderBuilder registerMetricReader( MetricReader reader, CardinalityLimitSelector cardinalityLimitSelector) { diff --git a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/View.java b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/View.java index be60974eaed..32f4309b600 100644 --- a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/View.java +++ b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/View.java @@ -60,7 +60,11 @@ static View create( /** Returns the attribute processor used for this view. */ abstract AttributesProcessor getAttributesProcessor(); - /** Returns the cardinality limit for this view. */ + /** + * Returns the cardinality limit for this view. + * + * @since 1.44.0 + */ public abstract int getCardinalityLimit(); @Override diff --git a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/ViewBuilder.java b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/ViewBuilder.java index af591c2ef62..87ce139f81b 100644 --- a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/ViewBuilder.java +++ b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/ViewBuilder.java @@ -114,6 +114,7 @@ ViewBuilder addAttributesProcessor(AttributesProcessor attributesProcessor) { * limit. * * @param cardinalityLimit the maximum number of series for a metric + * @since 1.44.0 */ public ViewBuilder setCardinalityLimit(int cardinalityLimit) { if (cardinalityLimit <= 0) { diff --git a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/export/CardinalityLimitSelector.java b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/export/CardinalityLimitSelector.java index ad0d4e717e2..43318b2ce0b 100644 --- a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/export/CardinalityLimitSelector.java +++ b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/export/CardinalityLimitSelector.java @@ -14,8 +14,7 @@ * function of {@link InstrumentType}. Register via {@link * SdkMeterProviderBuilder#registerMetricReader(MetricReader, CardinalityLimitSelector)}. * - *

      This class is internal and is hence not for public use. Its APIs are unstable and can change - * at any time. + * @since 1.44.0 */ @FunctionalInterface public interface CardinalityLimitSelector { diff --git a/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/data/ExceptionEventData.java b/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/data/ExceptionEventData.java index f717a0aef00..c5170e2485a 100644 --- a/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/data/ExceptionEventData.java +++ b/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/data/ExceptionEventData.java @@ -8,7 +8,11 @@ import io.opentelemetry.api.common.Attributes; import javax.annotation.concurrent.Immutable; -/** Data representation of an event for a recorded exception. */ +/** + * Data representation of an event for a recorded exception. + * + * @since 1.44.0 + */ @Immutable public interface ExceptionEventData extends EventData { From 597eb09de41477f170af5ee6519fe98897a161b9 Mon Sep 17 00:00:00 2001 From: OpenTelemetry Bot <107717825+opentelemetrybot@users.noreply.github.com> Date: Fri, 8 Nov 2024 12:30:04 -0600 Subject: [PATCH 658/901] Update version to 1.45.0 (#6862) --- CHANGELOG.md | 2 ++ version.gradle.kts | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index bef5be2c39b..b84447763f4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,8 @@ ## Unreleased +## Version 1.44.0 (2024-11-08) + ### API * Fix ConfigUtil#getString ConcurrentModificationException diff --git a/version.gradle.kts b/version.gradle.kts index eb508c5fbc1..29d04038d15 100644 --- a/version.gradle.kts +++ b/version.gradle.kts @@ -1,7 +1,7 @@ val snapshot = true allprojects { - var ver = "1.44.0" + var ver = "1.45.0" val release = findProperty("otel.release") if (release != null) { ver += "-" + release From e62d7c69cb373516328c556221abc3f0a8b6400a Mon Sep 17 00:00:00 2001 From: OpenTelemetry Bot <107717825+opentelemetrybot@users.noreply.github.com> Date: Sat, 9 Nov 2024 09:29:43 -0600 Subject: [PATCH 659/901] Post release for version 1.44.0 (#6864) --- README.md | 70 +++++++++---------- .../1.44.0_vs_1.43.0/opentelemetry-api.txt | 2 + .../opentelemetry-context.txt | 2 + .../opentelemetry-exporter-common.txt | 2 + .../opentelemetry-exporter-logging-otlp.txt | 2 + .../opentelemetry-exporter-logging.txt | 2 + .../opentelemetry-exporter-otlp-common.txt | 2 + .../opentelemetry-exporter-otlp.txt | 2 + ...y-exporter-sender-grpc-managed-channel.txt | 2 + .../opentelemetry-exporter-sender-jdk.txt | 2 + .../opentelemetry-exporter-sender-okhttp.txt | 2 + .../opentelemetry-exporter-zipkin.txt | 2 + .../opentelemetry-extension-kotlin.txt | 2 + ...ntelemetry-extension-trace-propagators.txt | 2 + .../opentelemetry-opentracing-shim.txt | 2 + .../opentelemetry-sdk-common.txt | 2 + ...emetry-sdk-extension-autoconfigure-spi.txt | 2 + ...ntelemetry-sdk-extension-autoconfigure.txt | 2 + ...ry-sdk-extension-jaeger-remote-sampler.txt | 2 + .../opentelemetry-sdk-logs.txt | 2 + .../opentelemetry-sdk-metrics.txt | 16 +++++ .../opentelemetry-sdk-testing.txt | 2 + .../opentelemetry-sdk-trace.txt | 7 ++ .../1.44.0_vs_1.43.0/opentelemetry-sdk.txt | 2 + .../current_vs_latest/opentelemetry-api.txt | 2 +- .../opentelemetry-context.txt | 2 +- .../opentelemetry-exporter-common.txt | 2 +- .../opentelemetry-exporter-logging-otlp.txt | 2 +- .../opentelemetry-exporter-logging.txt | 2 +- .../opentelemetry-exporter-otlp-common.txt | 2 +- .../opentelemetry-exporter-otlp.txt | 2 +- ...y-exporter-sender-grpc-managed-channel.txt | 2 +- .../opentelemetry-exporter-sender-jdk.txt | 2 +- .../opentelemetry-exporter-sender-okhttp.txt | 2 +- .../opentelemetry-exporter-zipkin.txt | 2 +- .../opentelemetry-extension-kotlin.txt | 2 +- ...ntelemetry-extension-trace-propagators.txt | 2 +- .../opentelemetry-opentracing-shim.txt | 2 +- .../opentelemetry-sdk-common.txt | 2 +- ...emetry-sdk-extension-autoconfigure-spi.txt | 2 +- ...ntelemetry-sdk-extension-autoconfigure.txt | 2 +- ...ry-sdk-extension-jaeger-remote-sampler.txt | 2 +- .../opentelemetry-sdk-logs.txt | 2 +- .../opentelemetry-sdk-metrics.txt | 18 +---- .../opentelemetry-sdk-testing.txt | 2 +- .../opentelemetry-sdk-trace.txt | 9 +-- .../current_vs_latest/opentelemetry-sdk.txt | 2 +- 47 files changed, 125 insertions(+), 79 deletions(-) create mode 100644 docs/apidiffs/1.44.0_vs_1.43.0/opentelemetry-api.txt create mode 100644 docs/apidiffs/1.44.0_vs_1.43.0/opentelemetry-context.txt create mode 100644 docs/apidiffs/1.44.0_vs_1.43.0/opentelemetry-exporter-common.txt create mode 100644 docs/apidiffs/1.44.0_vs_1.43.0/opentelemetry-exporter-logging-otlp.txt create mode 100644 docs/apidiffs/1.44.0_vs_1.43.0/opentelemetry-exporter-logging.txt create mode 100644 docs/apidiffs/1.44.0_vs_1.43.0/opentelemetry-exporter-otlp-common.txt create mode 100644 docs/apidiffs/1.44.0_vs_1.43.0/opentelemetry-exporter-otlp.txt create mode 100644 docs/apidiffs/1.44.0_vs_1.43.0/opentelemetry-exporter-sender-grpc-managed-channel.txt create mode 100644 docs/apidiffs/1.44.0_vs_1.43.0/opentelemetry-exporter-sender-jdk.txt create mode 100644 docs/apidiffs/1.44.0_vs_1.43.0/opentelemetry-exporter-sender-okhttp.txt create mode 100644 docs/apidiffs/1.44.0_vs_1.43.0/opentelemetry-exporter-zipkin.txt create mode 100644 docs/apidiffs/1.44.0_vs_1.43.0/opentelemetry-extension-kotlin.txt create mode 100644 docs/apidiffs/1.44.0_vs_1.43.0/opentelemetry-extension-trace-propagators.txt create mode 100644 docs/apidiffs/1.44.0_vs_1.43.0/opentelemetry-opentracing-shim.txt create mode 100644 docs/apidiffs/1.44.0_vs_1.43.0/opentelemetry-sdk-common.txt create mode 100644 docs/apidiffs/1.44.0_vs_1.43.0/opentelemetry-sdk-extension-autoconfigure-spi.txt create mode 100644 docs/apidiffs/1.44.0_vs_1.43.0/opentelemetry-sdk-extension-autoconfigure.txt create mode 100644 docs/apidiffs/1.44.0_vs_1.43.0/opentelemetry-sdk-extension-jaeger-remote-sampler.txt create mode 100644 docs/apidiffs/1.44.0_vs_1.43.0/opentelemetry-sdk-logs.txt create mode 100644 docs/apidiffs/1.44.0_vs_1.43.0/opentelemetry-sdk-metrics.txt create mode 100644 docs/apidiffs/1.44.0_vs_1.43.0/opentelemetry-sdk-testing.txt create mode 100644 docs/apidiffs/1.44.0_vs_1.43.0/opentelemetry-sdk-trace.txt create mode 100644 docs/apidiffs/1.44.0_vs_1.43.0/opentelemetry-sdk.txt diff --git a/README.md b/README.md index 3503236b277..8efa1a05ec2 100644 --- a/README.md +++ b/README.md @@ -105,7 +105,7 @@ dependency versions in sync. io.opentelemetry opentelemetry-bom - 1.43.0 + 1.44.0 pom import @@ -124,7 +124,7 @@ dependency versions in sync. ```groovy dependencies { - implementation platform("io.opentelemetry:opentelemetry-bom:1.43.0") + implementation platform("io.opentelemetry:opentelemetry-bom:1.44.0") implementation('io.opentelemetry:opentelemetry-api') } ``` @@ -133,8 +133,8 @@ Note that if you want to use any artifacts that have not fully stabilized yet (s ```groovy dependencies { - implementation platform("io.opentelemetry:opentelemetry-bom:1.43.0") - implementation platform('io.opentelemetry:opentelemetry-bom-alpha:1.43.0-alpha') + implementation platform("io.opentelemetry:opentelemetry-bom:1.44.0") + implementation platform('io.opentelemetry:opentelemetry-bom-alpha:1.44.0-alpha') implementation('io.opentelemetry:opentelemetry-api') implementation('io.opentelemetry:opentelemetry-exporter-prometheus') @@ -162,7 +162,7 @@ We strongly recommend using our published BOM to keep all dependency versions in io.opentelemetry opentelemetry-bom - 1.44.0-SNAPSHOT + 1.45.0-SNAPSHOT pom import @@ -185,7 +185,7 @@ repositories { } dependencies { - implementation platform("io.opentelemetry:opentelemetry-bom:1.44.0-SNAPSHOT") + implementation platform("io.opentelemetry:opentelemetry-bom:1.45.0-SNAPSHOT") implementation('io.opentelemetry:opentelemetry-api') } ``` @@ -230,66 +230,66 @@ dependency as follows, replacing `{{artifact-id}}` with the value from the "Arti | Component | Description | Artifact ID | Version | Javadoc | |----------------------------------------------|----------------------------------------|---------------------------|-------------------------------------------------------------|---------| -| [Bill of Materials (BOM)](./bom) | Bill of materials for stable artifacts | `opentelemetry-bom` | 1.43.0 | N/A | -| [Alpha Bill of Materials (BOM)](./bom-alpha) | Bill of materials for alpha artifacts | `opentelemetry-bom-alpha` | 1.43.0-alpha | N/A | +| [Bill of Materials (BOM)](./bom) | Bill of materials for stable artifacts | `opentelemetry-bom` | 1.44.0 | N/A | +| [Alpha Bill of Materials (BOM)](./bom-alpha) | Bill of materials for alpha artifacts | `opentelemetry-bom-alpha` | 1.44.0-alpha | N/A | ### API | Component | Description | Artifact ID | Version | Javadoc | |-----------------------------------|--------------------------------------------------------------------------------------|-------------------------------|---------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| [API](./api/all) | OpenTelemetry API, including metrics, traces, baggage, context | `opentelemetry-api` | 1.43.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-api.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-api) | -| [API Incubator](./api/incubator) | API incubator, including pass through propagator, and extended tracer, and Event API | `opentelemetry-api-incubator` | 1.43.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-api-incubator.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-api-incubator) | -| [Context API](./context) | OpenTelemetry context API | `opentelemetry-context` | 1.43.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-context.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-context) | +| [API](./api/all) | OpenTelemetry API, including metrics, traces, baggage, context | `opentelemetry-api` | 1.44.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-api.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-api) | +| [API Incubator](./api/incubator) | API incubator, including pass through propagator, and extended tracer, and Event API | `opentelemetry-api-incubator` | 1.44.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-api-incubator.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-api-incubator) | +| [Context API](./context) | OpenTelemetry context API | `opentelemetry-context` | 1.44.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-context.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-context) | ### API Extensions | Component | Description | Artifact ID | Version | Javadoc | |---------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|---------------------------------------------|-------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| [Kotlin Extension](./extensions/kotlin) | Context extension for coroutines | `opentelemetry-extension-kotlin` | 1.43.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-extension-kotlin.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-extension-kotlin) | -| [Trace Propagators Extension](./extensions/trace-propagators) | Trace propagators, including B3, Jaeger, OT Trace | `opentelemetry-extension-trace-propagators` | 1.43.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-extension-trace-propagators.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-extension-trace-propagators) | +| [Kotlin Extension](./extensions/kotlin) | Context extension for coroutines | `opentelemetry-extension-kotlin` | 1.44.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-extension-kotlin.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-extension-kotlin) | +| [Trace Propagators Extension](./extensions/trace-propagators) | Trace propagators, including B3, Jaeger, OT Trace | `opentelemetry-extension-trace-propagators` | 1.44.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-extension-trace-propagators.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-extension-trace-propagators) | ### SDK | Component | Description | Artifact ID | Version | Javadoc | |------------------------------|--------------------------------------------------------|-----------------------------|---------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| [SDK](./sdk/all) | OpenTelemetry SDK, including metrics, traces, and logs | `opentelemetry-sdk` | 1.43.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk) | -| [Metrics SDK](./sdk/metrics) | OpenTelemetry metrics SDK | `opentelemetry-sdk-metrics` | 1.43.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-metrics.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-metrics) | -| [Trace SDK](./sdk/trace) | OpenTelemetry trace SDK | `opentelemetry-sdk-trace` | 1.43.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-trace.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-trace) | -| [Log SDK](./sdk/logs) | OpenTelemetry log SDK | `opentelemetry-sdk-logs` | 1.43.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-logs.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-logs) | -| [SDK Common](./sdk/common) | Shared SDK components | `opentelemetry-sdk-common` | 1.43.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-common.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-common) | -| [SDK Testing](./sdk/testing) | Components for testing OpenTelemetry instrumentation | `opentelemetry-sdk-testing` | 1.43.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-testing.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-testing) | +| [SDK](./sdk/all) | OpenTelemetry SDK, including metrics, traces, and logs | `opentelemetry-sdk` | 1.44.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk) | +| [Metrics SDK](./sdk/metrics) | OpenTelemetry metrics SDK | `opentelemetry-sdk-metrics` | 1.44.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-metrics.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-metrics) | +| [Trace SDK](./sdk/trace) | OpenTelemetry trace SDK | `opentelemetry-sdk-trace` | 1.44.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-trace.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-trace) | +| [Log SDK](./sdk/logs) | OpenTelemetry log SDK | `opentelemetry-sdk-logs` | 1.44.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-logs.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-logs) | +| [SDK Common](./sdk/common) | Shared SDK components | `opentelemetry-sdk-common` | 1.44.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-common.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-common) | +| [SDK Testing](./sdk/testing) | Components for testing OpenTelemetry instrumentation | `opentelemetry-sdk-testing` | 1.44.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-testing.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-testing) | ### SDK Exporters | Component | Description | Artifact ID | Version | Javadoc | |-----------------------------------------------------------------------|------------------------------------------------------------------------------|------------------------------------------------------|-------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| [OTLP Exporters](./exporters/otlp/all) | OTLP gRPC & HTTP exporters, including traces, metrics, and logs | `opentelemetry-exporter-otlp` | 1.43.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-otlp.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-otlp) | -| [OTLP Logging Exporters](./exporters/logging-otlp) | Logging exporters in OTLP JSON encoding, including traces, metrics, and logs | `opentelemetry-exporter-logging-otlp` | 1.43.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-logging-otlp.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-logging-otlp) | -| [OTLP Common](./exporters/otlp/common) | Shared OTLP components (internal) | `opentelemetry-exporter-otlp-common` | 1.43.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-otlp-common.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-otlp-common) | -| [Logging Exporter](./exporters/logging) | Logging exporters, including metrics, traces, and logs | `opentelemetry-exporter-logging` | 1.43.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-logging.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-logging) | -| [Zipkin Exporter](./exporters/zipkin) | Zipkin trace exporter | `opentelemetry-exporter-zipkin` | 1.43.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-zipkin.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-zipkin) | -| [Prometheus Exporter](./exporters/prometheus) | Prometheus metric exporter | `opentelemetry-exporter-prometheus` | 1.43.0-alpha | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-prometheus.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-prometheus) | -| [Exporter Common](./exporters/common) | Shared exporter components (internal) | `opentelemetry-exporter-common` | 1.43.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-common.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-common) | -| [OkHttp Sender](./exporters/sender/okhttp) | OkHttp implementation of HttpSender (internal) | `opentelemetry-exporter-sender-okhttp` | 1.43.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-sender-okhttp.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-sender-okhttp) | -| [JDK Sender](./exporters/sender/jdk) | Java 11+ native HttpClient implementation of HttpSender (internal) | `opentelemetry-exporter-sender-jdk` | 1.43.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-sender-jdk.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-sender-jdk) | | -| [gRPC ManagedChannel Sender](./exporters/sender/grpc-managed-channel) | gRPC ManagedChannel implementation of GrpcSender (internal) | `opentelemetry-exporter-sender-grpc-managed-channel` | 1.43.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-sender-grpc-managed-channel.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-sender-grpc-managed-channel) | | +| [OTLP Exporters](./exporters/otlp/all) | OTLP gRPC & HTTP exporters, including traces, metrics, and logs | `opentelemetry-exporter-otlp` | 1.44.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-otlp.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-otlp) | +| [OTLP Logging Exporters](./exporters/logging-otlp) | Logging exporters in OTLP JSON encoding, including traces, metrics, and logs | `opentelemetry-exporter-logging-otlp` | 1.44.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-logging-otlp.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-logging-otlp) | +| [OTLP Common](./exporters/otlp/common) | Shared OTLP components (internal) | `opentelemetry-exporter-otlp-common` | 1.44.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-otlp-common.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-otlp-common) | +| [Logging Exporter](./exporters/logging) | Logging exporters, including metrics, traces, and logs | `opentelemetry-exporter-logging` | 1.44.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-logging.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-logging) | +| [Zipkin Exporter](./exporters/zipkin) | Zipkin trace exporter | `opentelemetry-exporter-zipkin` | 1.44.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-zipkin.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-zipkin) | +| [Prometheus Exporter](./exporters/prometheus) | Prometheus metric exporter | `opentelemetry-exporter-prometheus` | 1.44.0-alpha | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-prometheus.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-prometheus) | +| [Exporter Common](./exporters/common) | Shared exporter components (internal) | `opentelemetry-exporter-common` | 1.44.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-common.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-common) | +| [OkHttp Sender](./exporters/sender/okhttp) | OkHttp implementation of HttpSender (internal) | `opentelemetry-exporter-sender-okhttp` | 1.44.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-sender-okhttp.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-sender-okhttp) | +| [JDK Sender](./exporters/sender/jdk) | Java 11+ native HttpClient implementation of HttpSender (internal) | `opentelemetry-exporter-sender-jdk` | 1.44.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-sender-jdk.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-sender-jdk) | | +| [gRPC ManagedChannel Sender](./exporters/sender/grpc-managed-channel) | gRPC ManagedChannel implementation of GrpcSender (internal) | `opentelemetry-exporter-sender-grpc-managed-channel` | 1.44.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-sender-grpc-managed-channel.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-sender-grpc-managed-channel) | | ### SDK Extensions | Component | Description | Artifact ID | Version | Javadoc | |-------------------------------------------------------------------------------|------------------------------------------------------------------------------------|-----------------------------------------------------|-------------------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| [SDK Autoconfigure](./sdk-extensions/autoconfigure) | Autoconfigure OpenTelemetry SDK from env vars, system properties, and SPI | `opentelemetry-sdk-extension-autoconfigure` | 1.43.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-extension-autoconfigure.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-extension-autoconfigure) | -| [SDK Autoconfigure SPI](./sdk-extensions/autoconfigure-spi) | Service Provider Interface (SPI) definitions for autoconfigure | `opentelemetry-sdk-extension-autoconfigure-spi` | 1.43.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-extension-autoconfigure-spi.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-extension-autoconfigure-spi) | -| [SDK Jaeger Remote Sampler Extension](./sdk-extensions/jaeger-remote-sampler) | Sampler which obtains sampling configuration from remote Jaeger server | `opentelemetry-sdk-extension-jaeger-remote-sampler` | 1.43.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-extension-jaeger-remote-sampler.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-extension-jaeger-remote-sampler) | -| [SDK Incubator](./sdk-extensions/incubator) | SDK incubator, including YAML based view configuration, LeakDetectingSpanProcessor | `opentelemetry-sdk-extension-incubator` | 1.43.0-alpha | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-extension-incubator.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-extension-incubator) | +| [SDK Autoconfigure](./sdk-extensions/autoconfigure) | Autoconfigure OpenTelemetry SDK from env vars, system properties, and SPI | `opentelemetry-sdk-extension-autoconfigure` | 1.44.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-extension-autoconfigure.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-extension-autoconfigure) | +| [SDK Autoconfigure SPI](./sdk-extensions/autoconfigure-spi) | Service Provider Interface (SPI) definitions for autoconfigure | `opentelemetry-sdk-extension-autoconfigure-spi` | 1.44.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-extension-autoconfigure-spi.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-extension-autoconfigure-spi) | +| [SDK Jaeger Remote Sampler Extension](./sdk-extensions/jaeger-remote-sampler) | Sampler which obtains sampling configuration from remote Jaeger server | `opentelemetry-sdk-extension-jaeger-remote-sampler` | 1.44.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-extension-jaeger-remote-sampler.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-extension-jaeger-remote-sampler) | +| [SDK Incubator](./sdk-extensions/incubator) | SDK incubator, including YAML based view configuration, LeakDetectingSpanProcessor | `opentelemetry-sdk-extension-incubator` | 1.44.0-alpha | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-extension-incubator.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-extension-incubator) | ### Shims | Component | Description | Artifact ID | Version | Javadoc | |----------------------------------------|--------------------------------------------------------------|----------------------------------|-------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| [OpenCensus Shim](./opencensus-shim) | Bridge opencensus metrics into the OpenTelemetry metrics SDK | `opentelemetry-opencensus-shim` | 1.43.0-alpha | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-opencensus-shim.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-opencensus-shim) | -| [OpenTracing Shim](./opentracing-shim) | Bridge opentracing spans into the OpenTelemetry trace API | `opentelemetry-opentracing-shim` | 1.43.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-opentracing-shim.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-opentracing-shim) | +| [OpenCensus Shim](./opencensus-shim) | Bridge opencensus metrics into the OpenTelemetry metrics SDK | `opentelemetry-opencensus-shim` | 1.44.0-alpha | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-opencensus-shim.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-opencensus-shim) | +| [OpenTracing Shim](./opentracing-shim) | Bridge opentracing spans into the OpenTelemetry trace API | `opentelemetry-opentracing-shim` | 1.44.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-opentracing-shim.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-opentracing-shim) | ## Contributing diff --git a/docs/apidiffs/1.44.0_vs_1.43.0/opentelemetry-api.txt b/docs/apidiffs/1.44.0_vs_1.43.0/opentelemetry-api.txt new file mode 100644 index 00000000000..9e70186c29f --- /dev/null +++ b/docs/apidiffs/1.44.0_vs_1.43.0/opentelemetry-api.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of opentelemetry-api-1.44.0.jar against opentelemetry-api-1.43.0.jar +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.44.0_vs_1.43.0/opentelemetry-context.txt b/docs/apidiffs/1.44.0_vs_1.43.0/opentelemetry-context.txt new file mode 100644 index 00000000000..a0b2417ea3d --- /dev/null +++ b/docs/apidiffs/1.44.0_vs_1.43.0/opentelemetry-context.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of opentelemetry-context-1.44.0.jar against opentelemetry-context-1.43.0.jar +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.44.0_vs_1.43.0/opentelemetry-exporter-common.txt b/docs/apidiffs/1.44.0_vs_1.43.0/opentelemetry-exporter-common.txt new file mode 100644 index 00000000000..c33ced08682 --- /dev/null +++ b/docs/apidiffs/1.44.0_vs_1.43.0/opentelemetry-exporter-common.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of opentelemetry-exporter-common-1.44.0.jar against opentelemetry-exporter-common-1.43.0.jar +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.44.0_vs_1.43.0/opentelemetry-exporter-logging-otlp.txt b/docs/apidiffs/1.44.0_vs_1.43.0/opentelemetry-exporter-logging-otlp.txt new file mode 100644 index 00000000000..3384b7a6a8f --- /dev/null +++ b/docs/apidiffs/1.44.0_vs_1.43.0/opentelemetry-exporter-logging-otlp.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of opentelemetry-exporter-logging-otlp-1.44.0.jar against opentelemetry-exporter-logging-otlp-1.43.0.jar +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.44.0_vs_1.43.0/opentelemetry-exporter-logging.txt b/docs/apidiffs/1.44.0_vs_1.43.0/opentelemetry-exporter-logging.txt new file mode 100644 index 00000000000..e0995445a2d --- /dev/null +++ b/docs/apidiffs/1.44.0_vs_1.43.0/opentelemetry-exporter-logging.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of opentelemetry-exporter-logging-1.44.0.jar against opentelemetry-exporter-logging-1.43.0.jar +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.44.0_vs_1.43.0/opentelemetry-exporter-otlp-common.txt b/docs/apidiffs/1.44.0_vs_1.43.0/opentelemetry-exporter-otlp-common.txt new file mode 100644 index 00000000000..d5f44a6ee30 --- /dev/null +++ b/docs/apidiffs/1.44.0_vs_1.43.0/opentelemetry-exporter-otlp-common.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of opentelemetry-exporter-otlp-common-1.44.0.jar against opentelemetry-exporter-otlp-common-1.43.0.jar +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.44.0_vs_1.43.0/opentelemetry-exporter-otlp.txt b/docs/apidiffs/1.44.0_vs_1.43.0/opentelemetry-exporter-otlp.txt new file mode 100644 index 00000000000..6b9b06b34dc --- /dev/null +++ b/docs/apidiffs/1.44.0_vs_1.43.0/opentelemetry-exporter-otlp.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of opentelemetry-exporter-otlp-1.44.0.jar against opentelemetry-exporter-otlp-1.43.0.jar +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.44.0_vs_1.43.0/opentelemetry-exporter-sender-grpc-managed-channel.txt b/docs/apidiffs/1.44.0_vs_1.43.0/opentelemetry-exporter-sender-grpc-managed-channel.txt new file mode 100644 index 00000000000..da2b18615cf --- /dev/null +++ b/docs/apidiffs/1.44.0_vs_1.43.0/opentelemetry-exporter-sender-grpc-managed-channel.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of opentelemetry-exporter-sender-grpc-managed-channel-1.44.0.jar against opentelemetry-exporter-sender-grpc-managed-channel-1.43.0.jar +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.44.0_vs_1.43.0/opentelemetry-exporter-sender-jdk.txt b/docs/apidiffs/1.44.0_vs_1.43.0/opentelemetry-exporter-sender-jdk.txt new file mode 100644 index 00000000000..fcd6cdf22e2 --- /dev/null +++ b/docs/apidiffs/1.44.0_vs_1.43.0/opentelemetry-exporter-sender-jdk.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of opentelemetry-exporter-sender-jdk-1.44.0.jar against opentelemetry-exporter-sender-jdk-1.43.0.jar +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.44.0_vs_1.43.0/opentelemetry-exporter-sender-okhttp.txt b/docs/apidiffs/1.44.0_vs_1.43.0/opentelemetry-exporter-sender-okhttp.txt new file mode 100644 index 00000000000..884e240ae22 --- /dev/null +++ b/docs/apidiffs/1.44.0_vs_1.43.0/opentelemetry-exporter-sender-okhttp.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of opentelemetry-exporter-sender-okhttp-1.44.0.jar against opentelemetry-exporter-sender-okhttp-1.43.0.jar +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.44.0_vs_1.43.0/opentelemetry-exporter-zipkin.txt b/docs/apidiffs/1.44.0_vs_1.43.0/opentelemetry-exporter-zipkin.txt new file mode 100644 index 00000000000..b2241eeb636 --- /dev/null +++ b/docs/apidiffs/1.44.0_vs_1.43.0/opentelemetry-exporter-zipkin.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of opentelemetry-exporter-zipkin-1.44.0.jar against opentelemetry-exporter-zipkin-1.43.0.jar +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.44.0_vs_1.43.0/opentelemetry-extension-kotlin.txt b/docs/apidiffs/1.44.0_vs_1.43.0/opentelemetry-extension-kotlin.txt new file mode 100644 index 00000000000..8044b8f8eec --- /dev/null +++ b/docs/apidiffs/1.44.0_vs_1.43.0/opentelemetry-extension-kotlin.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of opentelemetry-extension-kotlin-1.44.0.jar against opentelemetry-extension-kotlin-1.43.0.jar +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.44.0_vs_1.43.0/opentelemetry-extension-trace-propagators.txt b/docs/apidiffs/1.44.0_vs_1.43.0/opentelemetry-extension-trace-propagators.txt new file mode 100644 index 00000000000..da2fff0fb55 --- /dev/null +++ b/docs/apidiffs/1.44.0_vs_1.43.0/opentelemetry-extension-trace-propagators.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of opentelemetry-extension-trace-propagators-1.44.0.jar against opentelemetry-extension-trace-propagators-1.43.0.jar +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.44.0_vs_1.43.0/opentelemetry-opentracing-shim.txt b/docs/apidiffs/1.44.0_vs_1.43.0/opentelemetry-opentracing-shim.txt new file mode 100644 index 00000000000..5a3e21de838 --- /dev/null +++ b/docs/apidiffs/1.44.0_vs_1.43.0/opentelemetry-opentracing-shim.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of opentelemetry-opentracing-shim-1.44.0.jar against opentelemetry-opentracing-shim-1.43.0.jar +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.44.0_vs_1.43.0/opentelemetry-sdk-common.txt b/docs/apidiffs/1.44.0_vs_1.43.0/opentelemetry-sdk-common.txt new file mode 100644 index 00000000000..5ae9baeb962 --- /dev/null +++ b/docs/apidiffs/1.44.0_vs_1.43.0/opentelemetry-sdk-common.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of opentelemetry-sdk-common-1.44.0.jar against opentelemetry-sdk-common-1.43.0.jar +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.44.0_vs_1.43.0/opentelemetry-sdk-extension-autoconfigure-spi.txt b/docs/apidiffs/1.44.0_vs_1.43.0/opentelemetry-sdk-extension-autoconfigure-spi.txt new file mode 100644 index 00000000000..2a9f6dfbf2b --- /dev/null +++ b/docs/apidiffs/1.44.0_vs_1.43.0/opentelemetry-sdk-extension-autoconfigure-spi.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of opentelemetry-sdk-extension-autoconfigure-spi-1.44.0.jar against opentelemetry-sdk-extension-autoconfigure-spi-1.43.0.jar +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.44.0_vs_1.43.0/opentelemetry-sdk-extension-autoconfigure.txt b/docs/apidiffs/1.44.0_vs_1.43.0/opentelemetry-sdk-extension-autoconfigure.txt new file mode 100644 index 00000000000..227dd95136c --- /dev/null +++ b/docs/apidiffs/1.44.0_vs_1.43.0/opentelemetry-sdk-extension-autoconfigure.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of opentelemetry-sdk-extension-autoconfigure-1.44.0.jar against opentelemetry-sdk-extension-autoconfigure-1.43.0.jar +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.44.0_vs_1.43.0/opentelemetry-sdk-extension-jaeger-remote-sampler.txt b/docs/apidiffs/1.44.0_vs_1.43.0/opentelemetry-sdk-extension-jaeger-remote-sampler.txt new file mode 100644 index 00000000000..a35f25ac548 --- /dev/null +++ b/docs/apidiffs/1.44.0_vs_1.43.0/opentelemetry-sdk-extension-jaeger-remote-sampler.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of opentelemetry-sdk-extension-jaeger-remote-sampler-1.44.0.jar against opentelemetry-sdk-extension-jaeger-remote-sampler-1.43.0.jar +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.44.0_vs_1.43.0/opentelemetry-sdk-logs.txt b/docs/apidiffs/1.44.0_vs_1.43.0/opentelemetry-sdk-logs.txt new file mode 100644 index 00000000000..8605a4468ed --- /dev/null +++ b/docs/apidiffs/1.44.0_vs_1.43.0/opentelemetry-sdk-logs.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of opentelemetry-sdk-logs-1.44.0.jar against opentelemetry-sdk-logs-1.43.0.jar +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.44.0_vs_1.43.0/opentelemetry-sdk-metrics.txt b/docs/apidiffs/1.44.0_vs_1.43.0/opentelemetry-sdk-metrics.txt new file mode 100644 index 00000000000..985d2734842 --- /dev/null +++ b/docs/apidiffs/1.44.0_vs_1.43.0/opentelemetry-sdk-metrics.txt @@ -0,0 +1,16 @@ +Comparing source compatibility of opentelemetry-sdk-metrics-1.44.0.jar against opentelemetry-sdk-metrics-1.43.0.jar ++++ NEW INTERFACE: PUBLIC(+) ABSTRACT(+) io.opentelemetry.sdk.metrics.export.CardinalityLimitSelector (not serializable) + +++ CLASS FILE FORMAT VERSION: 52.0 <- n.a. + +++ NEW SUPERCLASS: java.lang.Object + +++ NEW METHOD: PUBLIC(+) STATIC(+) io.opentelemetry.sdk.metrics.export.CardinalityLimitSelector defaultCardinalityLimitSelector() + +++ NEW METHOD: PUBLIC(+) ABSTRACT(+) int getCardinalityLimit(io.opentelemetry.sdk.metrics.InstrumentType) + +++ NEW ANNOTATION: java.lang.FunctionalInterface +*** MODIFIED CLASS: PUBLIC FINAL io.opentelemetry.sdk.metrics.SdkMeterProviderBuilder (not serializable) + === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 + +++ NEW METHOD: PUBLIC(+) io.opentelemetry.sdk.metrics.SdkMeterProviderBuilder registerMetricReader(io.opentelemetry.sdk.metrics.export.MetricReader, io.opentelemetry.sdk.metrics.export.CardinalityLimitSelector) +*** MODIFIED CLASS: PUBLIC ABSTRACT io.opentelemetry.sdk.metrics.View (not serializable) + === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 + *** MODIFIED METHOD: PUBLIC (<- PACKAGE_PROTECTED) ABSTRACT int getCardinalityLimit() +*** MODIFIED CLASS: PUBLIC FINAL io.opentelemetry.sdk.metrics.ViewBuilder (not serializable) + === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 + *** MODIFIED METHOD: PUBLIC (<- PACKAGE_PROTECTED) io.opentelemetry.sdk.metrics.ViewBuilder setCardinalityLimit(int) diff --git a/docs/apidiffs/1.44.0_vs_1.43.0/opentelemetry-sdk-testing.txt b/docs/apidiffs/1.44.0_vs_1.43.0/opentelemetry-sdk-testing.txt new file mode 100644 index 00000000000..8042c5e1b2d --- /dev/null +++ b/docs/apidiffs/1.44.0_vs_1.43.0/opentelemetry-sdk-testing.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of opentelemetry-sdk-testing-1.44.0.jar against opentelemetry-sdk-testing-1.43.0.jar +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.44.0_vs_1.43.0/opentelemetry-sdk-trace.txt b/docs/apidiffs/1.44.0_vs_1.43.0/opentelemetry-sdk-trace.txt new file mode 100644 index 00000000000..452716a43f3 --- /dev/null +++ b/docs/apidiffs/1.44.0_vs_1.43.0/opentelemetry-sdk-trace.txt @@ -0,0 +1,7 @@ +Comparing source compatibility of opentelemetry-sdk-trace-1.44.0.jar against opentelemetry-sdk-trace-1.43.0.jar ++++ NEW INTERFACE: PUBLIC(+) ABSTRACT(+) io.opentelemetry.sdk.trace.data.ExceptionEventData (not serializable) + +++ CLASS FILE FORMAT VERSION: 52.0 <- n.a. + +++ NEW INTERFACE: io.opentelemetry.sdk.trace.data.EventData + +++ NEW SUPERCLASS: java.lang.Object + +++ NEW METHOD: PUBLIC(+) STATIC(+) io.opentelemetry.sdk.trace.data.ExceptionEventData create(long, java.lang.Throwable, io.opentelemetry.api.common.Attributes, int) + +++ NEW METHOD: PUBLIC(+) ABSTRACT(+) java.lang.Throwable getException() diff --git a/docs/apidiffs/1.44.0_vs_1.43.0/opentelemetry-sdk.txt b/docs/apidiffs/1.44.0_vs_1.43.0/opentelemetry-sdk.txt new file mode 100644 index 00000000000..333f8c4f5b0 --- /dev/null +++ b/docs/apidiffs/1.44.0_vs_1.43.0/opentelemetry-sdk.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of opentelemetry-sdk-1.44.0.jar against opentelemetry-sdk-1.43.0.jar +No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-api.txt b/docs/apidiffs/current_vs_latest/opentelemetry-api.txt index 22b25875a3a..634dc2beb01 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-api.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-api.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of opentelemetry-api-1.44.0-SNAPSHOT.jar against opentelemetry-api-1.43.0.jar +Comparing source compatibility of opentelemetry-api-1.45.0-SNAPSHOT.jar against opentelemetry-api-1.44.0.jar No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-context.txt b/docs/apidiffs/current_vs_latest/opentelemetry-context.txt index cac847ecf2e..4bcd9992fc5 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-context.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-context.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of opentelemetry-context-1.44.0-SNAPSHOT.jar against opentelemetry-context-1.43.0.jar +Comparing source compatibility of opentelemetry-context-1.45.0-SNAPSHOT.jar against opentelemetry-context-1.44.0.jar No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-common.txt b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-common.txt index 27662633e4a..38840d7645b 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-common.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-common.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of opentelemetry-exporter-common-1.44.0-SNAPSHOT.jar against opentelemetry-exporter-common-1.43.0.jar +Comparing source compatibility of opentelemetry-exporter-common-1.45.0-SNAPSHOT.jar against opentelemetry-exporter-common-1.44.0.jar No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-logging-otlp.txt b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-logging-otlp.txt index f4eb50807c8..486aa4adb22 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-logging-otlp.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-logging-otlp.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of opentelemetry-exporter-logging-otlp-1.44.0-SNAPSHOT.jar against opentelemetry-exporter-logging-otlp-1.43.0.jar +Comparing source compatibility of opentelemetry-exporter-logging-otlp-1.45.0-SNAPSHOT.jar against opentelemetry-exporter-logging-otlp-1.44.0.jar No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-logging.txt b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-logging.txt index 19151b77a28..a4743ffe739 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-logging.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-logging.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of opentelemetry-exporter-logging-1.44.0-SNAPSHOT.jar against opentelemetry-exporter-logging-1.43.0.jar +Comparing source compatibility of opentelemetry-exporter-logging-1.45.0-SNAPSHOT.jar against opentelemetry-exporter-logging-1.44.0.jar No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-otlp-common.txt b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-otlp-common.txt index cfc37ac9e71..c196ea9e30d 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-otlp-common.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-otlp-common.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of opentelemetry-exporter-otlp-common-1.44.0-SNAPSHOT.jar against opentelemetry-exporter-otlp-common-1.43.0.jar +Comparing source compatibility of opentelemetry-exporter-otlp-common-1.45.0-SNAPSHOT.jar against opentelemetry-exporter-otlp-common-1.44.0.jar No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-otlp.txt b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-otlp.txt index dff93d3af84..c84f1ddd8e2 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-otlp.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-otlp.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of opentelemetry-exporter-otlp-1.44.0-SNAPSHOT.jar against opentelemetry-exporter-otlp-1.43.0.jar +Comparing source compatibility of opentelemetry-exporter-otlp-1.45.0-SNAPSHOT.jar against opentelemetry-exporter-otlp-1.44.0.jar No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-sender-grpc-managed-channel.txt b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-sender-grpc-managed-channel.txt index 1dd4bb6cf92..0f93b25e61c 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-sender-grpc-managed-channel.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-sender-grpc-managed-channel.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of opentelemetry-exporter-sender-grpc-managed-channel-1.44.0-SNAPSHOT.jar against opentelemetry-exporter-sender-grpc-managed-channel-1.43.0.jar +Comparing source compatibility of opentelemetry-exporter-sender-grpc-managed-channel-1.45.0-SNAPSHOT.jar against opentelemetry-exporter-sender-grpc-managed-channel-1.44.0.jar No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-sender-jdk.txt b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-sender-jdk.txt index 9ec3d17ba48..fbf49c9697e 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-sender-jdk.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-sender-jdk.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of opentelemetry-exporter-sender-jdk-1.44.0-SNAPSHOT.jar against opentelemetry-exporter-sender-jdk-1.43.0.jar +Comparing source compatibility of opentelemetry-exporter-sender-jdk-1.45.0-SNAPSHOT.jar against opentelemetry-exporter-sender-jdk-1.44.0.jar No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-sender-okhttp.txt b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-sender-okhttp.txt index 5569153a8e9..f0003508c3c 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-sender-okhttp.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-sender-okhttp.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of opentelemetry-exporter-sender-okhttp-1.44.0-SNAPSHOT.jar against opentelemetry-exporter-sender-okhttp-1.43.0.jar +Comparing source compatibility of opentelemetry-exporter-sender-okhttp-1.45.0-SNAPSHOT.jar against opentelemetry-exporter-sender-okhttp-1.44.0.jar No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-zipkin.txt b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-zipkin.txt index 692173ab320..72099ccdd1e 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-zipkin.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-zipkin.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of opentelemetry-exporter-zipkin-1.44.0-SNAPSHOT.jar against opentelemetry-exporter-zipkin-1.43.0.jar +Comparing source compatibility of opentelemetry-exporter-zipkin-1.45.0-SNAPSHOT.jar against opentelemetry-exporter-zipkin-1.44.0.jar No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-extension-kotlin.txt b/docs/apidiffs/current_vs_latest/opentelemetry-extension-kotlin.txt index ba6ef24dc0c..bdc24b3966c 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-extension-kotlin.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-extension-kotlin.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of opentelemetry-extension-kotlin-1.44.0-SNAPSHOT.jar against opentelemetry-extension-kotlin-1.43.0.jar +Comparing source compatibility of opentelemetry-extension-kotlin-1.45.0-SNAPSHOT.jar against opentelemetry-extension-kotlin-1.44.0.jar No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-extension-trace-propagators.txt b/docs/apidiffs/current_vs_latest/opentelemetry-extension-trace-propagators.txt index 13c133ff51c..4781ec62f94 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-extension-trace-propagators.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-extension-trace-propagators.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of opentelemetry-extension-trace-propagators-1.44.0-SNAPSHOT.jar against opentelemetry-extension-trace-propagators-1.43.0.jar +Comparing source compatibility of opentelemetry-extension-trace-propagators-1.45.0-SNAPSHOT.jar against opentelemetry-extension-trace-propagators-1.44.0.jar No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-opentracing-shim.txt b/docs/apidiffs/current_vs_latest/opentelemetry-opentracing-shim.txt index f99d150208f..94fd3deb09c 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-opentracing-shim.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-opentracing-shim.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of opentelemetry-opentracing-shim-1.44.0-SNAPSHOT.jar against opentelemetry-opentracing-shim-1.43.0.jar +Comparing source compatibility of opentelemetry-opentracing-shim-1.45.0-SNAPSHOT.jar against opentelemetry-opentracing-shim-1.44.0.jar No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-common.txt b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-common.txt index 7c5dcaabee9..694c4b6d577 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-common.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-common.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of opentelemetry-sdk-common-1.44.0-SNAPSHOT.jar against opentelemetry-sdk-common-1.43.0.jar +Comparing source compatibility of opentelemetry-sdk-common-1.45.0-SNAPSHOT.jar against opentelemetry-sdk-common-1.44.0.jar No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-extension-autoconfigure-spi.txt b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-extension-autoconfigure-spi.txt index 6dc02f3d53f..b38024044a5 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-extension-autoconfigure-spi.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-extension-autoconfigure-spi.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of opentelemetry-sdk-extension-autoconfigure-spi-1.44.0-SNAPSHOT.jar against opentelemetry-sdk-extension-autoconfigure-spi-1.43.0.jar +Comparing source compatibility of opentelemetry-sdk-extension-autoconfigure-spi-1.45.0-SNAPSHOT.jar against opentelemetry-sdk-extension-autoconfigure-spi-1.44.0.jar No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-extension-autoconfigure.txt b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-extension-autoconfigure.txt index b7251779550..9d98cddd1a5 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-extension-autoconfigure.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-extension-autoconfigure.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of opentelemetry-sdk-extension-autoconfigure-1.44.0-SNAPSHOT.jar against opentelemetry-sdk-extension-autoconfigure-1.43.0.jar +Comparing source compatibility of opentelemetry-sdk-extension-autoconfigure-1.45.0-SNAPSHOT.jar against opentelemetry-sdk-extension-autoconfigure-1.44.0.jar No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-extension-jaeger-remote-sampler.txt b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-extension-jaeger-remote-sampler.txt index 2afdbaa513d..0c9837b3701 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-extension-jaeger-remote-sampler.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-extension-jaeger-remote-sampler.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of opentelemetry-sdk-extension-jaeger-remote-sampler-1.44.0-SNAPSHOT.jar against opentelemetry-sdk-extension-jaeger-remote-sampler-1.43.0.jar +Comparing source compatibility of opentelemetry-sdk-extension-jaeger-remote-sampler-1.45.0-SNAPSHOT.jar against opentelemetry-sdk-extension-jaeger-remote-sampler-1.44.0.jar No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-logs.txt b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-logs.txt index 47e56fdd20f..b1ef5ae5a38 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-logs.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-logs.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of opentelemetry-sdk-logs-1.44.0-SNAPSHOT.jar against opentelemetry-sdk-logs-1.43.0.jar +Comparing source compatibility of opentelemetry-sdk-logs-1.45.0-SNAPSHOT.jar against opentelemetry-sdk-logs-1.44.0.jar No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-metrics.txt b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-metrics.txt index aaa00f2eefb..c3e3d2e3256 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-metrics.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-metrics.txt @@ -1,16 +1,2 @@ -Comparing source compatibility of opentelemetry-sdk-metrics-1.44.0-SNAPSHOT.jar against opentelemetry-sdk-metrics-1.43.0.jar -+++ NEW INTERFACE: PUBLIC(+) ABSTRACT(+) io.opentelemetry.sdk.metrics.export.CardinalityLimitSelector (not serializable) - +++ CLASS FILE FORMAT VERSION: 52.0 <- n.a. - +++ NEW SUPERCLASS: java.lang.Object - +++ NEW METHOD: PUBLIC(+) STATIC(+) io.opentelemetry.sdk.metrics.export.CardinalityLimitSelector defaultCardinalityLimitSelector() - +++ NEW METHOD: PUBLIC(+) ABSTRACT(+) int getCardinalityLimit(io.opentelemetry.sdk.metrics.InstrumentType) - +++ NEW ANNOTATION: java.lang.FunctionalInterface -*** MODIFIED CLASS: PUBLIC FINAL io.opentelemetry.sdk.metrics.SdkMeterProviderBuilder (not serializable) - === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 - +++ NEW METHOD: PUBLIC(+) io.opentelemetry.sdk.metrics.SdkMeterProviderBuilder registerMetricReader(io.opentelemetry.sdk.metrics.export.MetricReader, io.opentelemetry.sdk.metrics.export.CardinalityLimitSelector) -*** MODIFIED CLASS: PUBLIC ABSTRACT io.opentelemetry.sdk.metrics.View (not serializable) - === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 - *** MODIFIED METHOD: PUBLIC (<- PACKAGE_PROTECTED) ABSTRACT int getCardinalityLimit() -*** MODIFIED CLASS: PUBLIC FINAL io.opentelemetry.sdk.metrics.ViewBuilder (not serializable) - === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 - *** MODIFIED METHOD: PUBLIC (<- PACKAGE_PROTECTED) io.opentelemetry.sdk.metrics.ViewBuilder setCardinalityLimit(int) +Comparing source compatibility of opentelemetry-sdk-metrics-1.45.0-SNAPSHOT.jar against opentelemetry-sdk-metrics-1.44.0.jar +No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-testing.txt b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-testing.txt index ecf7cf7c9ef..6f89fead97a 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-testing.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-testing.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of opentelemetry-sdk-testing-1.44.0-SNAPSHOT.jar against opentelemetry-sdk-testing-1.43.0.jar +Comparing source compatibility of opentelemetry-sdk-testing-1.45.0-SNAPSHOT.jar against opentelemetry-sdk-testing-1.44.0.jar No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-trace.txt b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-trace.txt index c6fd7e61bcd..8d462811694 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-trace.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-trace.txt @@ -1,7 +1,2 @@ -Comparing source compatibility of opentelemetry-sdk-trace-1.44.0-SNAPSHOT.jar against opentelemetry-sdk-trace-1.43.0.jar -+++ NEW INTERFACE: PUBLIC(+) ABSTRACT(+) io.opentelemetry.sdk.trace.data.ExceptionEventData (not serializable) - +++ CLASS FILE FORMAT VERSION: 52.0 <- n.a. - +++ NEW INTERFACE: io.opentelemetry.sdk.trace.data.EventData - +++ NEW SUPERCLASS: java.lang.Object - +++ NEW METHOD: PUBLIC(+) STATIC(+) io.opentelemetry.sdk.trace.data.ExceptionEventData create(long, java.lang.Throwable, io.opentelemetry.api.common.Attributes, int) - +++ NEW METHOD: PUBLIC(+) ABSTRACT(+) java.lang.Throwable getException() +Comparing source compatibility of opentelemetry-sdk-trace-1.45.0-SNAPSHOT.jar against opentelemetry-sdk-trace-1.44.0.jar +No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-sdk.txt b/docs/apidiffs/current_vs_latest/opentelemetry-sdk.txt index 59adccb88e8..cdc75c8f941 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-sdk.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-sdk.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of opentelemetry-sdk-1.44.0-SNAPSHOT.jar against opentelemetry-sdk-1.43.0.jar +Comparing source compatibility of opentelemetry-sdk-1.45.0-SNAPSHOT.jar against opentelemetry-sdk-1.44.0.jar No changes. \ No newline at end of file From 6c0d140dff4b5fd6e168e6b6a65edf4cf73c7571 Mon Sep 17 00:00:00 2001 From: Trask Stalnaker Date: Sat, 9 Nov 2024 08:04:04 -0800 Subject: [PATCH 660/901] Fix regression in event attributes (#6865) --- .../io/opentelemetry/sdk/trace/SdkSpan.java | 3 +-- .../opentelemetry/sdk/trace/SdkSpanTest.java | 23 +++++++++++++++++++ 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/SdkSpan.java b/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/SdkSpan.java index 0d2c9ab83fd..59eec41179f 100644 --- a/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/SdkSpan.java +++ b/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/SdkSpan.java @@ -445,8 +445,7 @@ public ReadWriteSpan setStatus(StatusCode statusCode, @Nullable String descripti @Override public ReadWriteSpan recordException(Throwable exception) { - Attributes attributes = this.getAttributes(); - recordException(exception, attributes); + recordException(exception, Attributes.empty()); return this; } diff --git a/sdk/trace/src/test/java/io/opentelemetry/sdk/trace/SdkSpanTest.java b/sdk/trace/src/test/java/io/opentelemetry/sdk/trace/SdkSpanTest.java index 7fbd86ef229..4b44607b1d6 100644 --- a/sdk/trace/src/test/java/io/opentelemetry/sdk/trace/SdkSpanTest.java +++ b/sdk/trace/src/test/java/io/opentelemetry/sdk/trace/SdkSpanTest.java @@ -878,6 +878,7 @@ void attributeLength() { assertThat(event.getAttributes().get(stringKey("exception.message"))).isEqualTo(strVal); assertThat(event.getAttributes().get(stringKey("exception.stacktrace")).length()) .isLessThanOrEqualTo(maxLength); + assertThat(event.getAttributes().size()).isEqualTo(3); } finally { span.end(); } @@ -1159,6 +1160,9 @@ void recordException() { testClock.advance(Duration.ofNanos(1000)); long timestamp = testClock.now(); + // make sure that span attributes don't leak down to the exception event + span.setAttribute("spankey", "val"); + span.recordException(exception); List events = span.toSpanData().getEvents(); @@ -1171,6 +1175,7 @@ void recordException() { assertThat(event.getAttributes().get(stringKey("exception.type"))) .isEqualTo(exception.getClass().getName()); assertThat(event.getAttributes().get(stringKey("exception.stacktrace"))).isEqualTo(stacktrace); + assertThat(event.getAttributes().size()).isEqualTo(3); assertThat(event) .isInstanceOfSatisfying( ExceptionEventData.class, @@ -1184,12 +1189,20 @@ void recordException_noMessage() { IllegalStateException exception = new IllegalStateException(); SdkSpan span = createTestRootSpan(); + StringWriter writer = new StringWriter(); + exception.printStackTrace(new PrintWriter(writer)); + String stacktrace = writer.toString(); + span.recordException(exception); List events = span.toSpanData().getEvents(); assertThat(events).hasSize(1); EventData event = events.get(0); assertThat(event.getAttributes().get(stringKey("exception.message"))).isNull(); + assertThat(event.getAttributes().get(stringKey("exception.type"))) + .isEqualTo("java.lang.IllegalStateException"); + assertThat(event.getAttributes().get(stringKey("exception.stacktrace"))).isEqualTo(stacktrace); + assertThat(event.getAttributes().size()).isEqualTo(2); } private static class InnerClassException extends Exception {} @@ -1199,6 +1212,10 @@ void recordException_innerClassException() { InnerClassException exception = new InnerClassException(); SdkSpan span = createTestRootSpan(); + StringWriter writer = new StringWriter(); + exception.printStackTrace(new PrintWriter(writer)); + String stacktrace = writer.toString(); + span.recordException(exception); List events = span.toSpanData().getEvents(); @@ -1206,6 +1223,8 @@ void recordException_innerClassException() { EventData event = events.get(0); assertThat(event.getAttributes().get(stringKey("exception.type"))) .isEqualTo("io.opentelemetry.sdk.trace.SdkSpanTest.InnerClassException"); + assertThat(event.getAttributes().get(stringKey("exception.stacktrace"))).isEqualTo(stacktrace); + assertThat(event.getAttributes().size()).isEqualTo(2); } @Test @@ -1220,6 +1239,9 @@ void recordException_additionalAttributes() { testClock.advance(Duration.ofNanos(1000)); long timestamp = testClock.now(); + // make sure that span attributes don't leak down to the exception event + span.setAttribute("spankey", "val"); + span.recordException( exception, Attributes.of( @@ -1240,6 +1262,7 @@ void recordException_additionalAttributes() { assertThat(event.getAttributes().get(stringKey("exception.type"))) .isEqualTo("java.lang.IllegalStateException"); assertThat(event.getAttributes().get(stringKey("exception.stacktrace"))).isEqualTo(stacktrace); + assertThat(event.getAttributes().size()).isEqualTo(4); assertThat(event) .isInstanceOfSatisfying( From 15669842624cd95b662c90575d5678837d362293 Mon Sep 17 00:00:00 2001 From: OpenTelemetry Bot <107717825+opentelemetrybot@users.noreply.github.com> Date: Sun, 10 Nov 2024 19:45:34 -0600 Subject: [PATCH 661/901] Merge change log updates from release/v1.44.x (#6869) --- CHANGELOG.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index b84447763f4..93709f23f87 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,15 @@ ## Unreleased +## Version 1.44.1 (2024-11-10) + +### SDK + +#### Traces + +* Fix regression in event attributes + ([#6865](https://github.com/open-telemetry/opentelemetry-java/pull/6865)) + ## Version 1.44.0 (2024-11-08) ### API From ca98fc53be592d8634170da04e0db96e206be141 Mon Sep 17 00:00:00 2001 From: jack-berg <34418638+jack-berg@users.noreply.github.com> Date: Fri, 15 Nov 2024 16:27:01 -0600 Subject: [PATCH 662/901] Post release v1.44.1 (#6883) --- README.md | 66 +++++++++---------- .../1.44.1_vs_1.44.0/opentelemetry-api.txt | 2 + .../opentelemetry-context.txt | 2 + .../opentelemetry-exporter-common.txt | 2 + .../opentelemetry-exporter-logging-otlp.txt | 2 + .../opentelemetry-exporter-logging.txt | 2 + .../opentelemetry-exporter-otlp-common.txt | 2 + .../opentelemetry-exporter-otlp.txt | 2 + ...y-exporter-sender-grpc-managed-channel.txt | 2 + .../opentelemetry-exporter-sender-jdk.txt | 2 + .../opentelemetry-exporter-sender-okhttp.txt | 2 + .../opentelemetry-exporter-zipkin.txt | 2 + .../opentelemetry-extension-kotlin.txt | 2 + ...ntelemetry-extension-trace-propagators.txt | 2 + .../opentelemetry-opentracing-shim.txt | 2 + .../opentelemetry-sdk-common.txt | 2 + ...emetry-sdk-extension-autoconfigure-spi.txt | 2 + ...ntelemetry-sdk-extension-autoconfigure.txt | 2 + ...ry-sdk-extension-jaeger-remote-sampler.txt | 2 + .../opentelemetry-sdk-logs.txt | 2 + .../opentelemetry-sdk-metrics.txt | 2 + .../opentelemetry-sdk-testing.txt | 2 + .../opentelemetry-sdk-trace.txt | 2 + .../1.44.1_vs_1.44.0/opentelemetry-sdk.txt | 2 + .../current_vs_latest/opentelemetry-api.txt | 2 +- .../opentelemetry-context.txt | 2 +- .../opentelemetry-exporter-common.txt | 2 +- .../opentelemetry-exporter-logging-otlp.txt | 2 +- .../opentelemetry-exporter-logging.txt | 2 +- .../opentelemetry-exporter-otlp-common.txt | 2 +- .../opentelemetry-exporter-otlp.txt | 2 +- ...y-exporter-sender-grpc-managed-channel.txt | 2 +- .../opentelemetry-exporter-sender-jdk.txt | 2 +- .../opentelemetry-exporter-sender-okhttp.txt | 2 +- .../opentelemetry-exporter-zipkin.txt | 2 +- .../opentelemetry-extension-kotlin.txt | 2 +- ...ntelemetry-extension-trace-propagators.txt | 2 +- .../opentelemetry-opentracing-shim.txt | 2 +- .../opentelemetry-sdk-common.txt | 2 +- ...emetry-sdk-extension-autoconfigure-spi.txt | 2 +- ...ntelemetry-sdk-extension-autoconfigure.txt | 2 +- ...ry-sdk-extension-jaeger-remote-sampler.txt | 2 +- .../opentelemetry-sdk-logs.txt | 2 +- .../opentelemetry-sdk-metrics.txt | 2 +- .../opentelemetry-sdk-testing.txt | 2 +- .../opentelemetry-sdk-trace.txt | 2 +- .../current_vs_latest/opentelemetry-sdk.txt | 2 +- 47 files changed, 102 insertions(+), 56 deletions(-) create mode 100644 docs/apidiffs/1.44.1_vs_1.44.0/opentelemetry-api.txt create mode 100644 docs/apidiffs/1.44.1_vs_1.44.0/opentelemetry-context.txt create mode 100644 docs/apidiffs/1.44.1_vs_1.44.0/opentelemetry-exporter-common.txt create mode 100644 docs/apidiffs/1.44.1_vs_1.44.0/opentelemetry-exporter-logging-otlp.txt create mode 100644 docs/apidiffs/1.44.1_vs_1.44.0/opentelemetry-exporter-logging.txt create mode 100644 docs/apidiffs/1.44.1_vs_1.44.0/opentelemetry-exporter-otlp-common.txt create mode 100644 docs/apidiffs/1.44.1_vs_1.44.0/opentelemetry-exporter-otlp.txt create mode 100644 docs/apidiffs/1.44.1_vs_1.44.0/opentelemetry-exporter-sender-grpc-managed-channel.txt create mode 100644 docs/apidiffs/1.44.1_vs_1.44.0/opentelemetry-exporter-sender-jdk.txt create mode 100644 docs/apidiffs/1.44.1_vs_1.44.0/opentelemetry-exporter-sender-okhttp.txt create mode 100644 docs/apidiffs/1.44.1_vs_1.44.0/opentelemetry-exporter-zipkin.txt create mode 100644 docs/apidiffs/1.44.1_vs_1.44.0/opentelemetry-extension-kotlin.txt create mode 100644 docs/apidiffs/1.44.1_vs_1.44.0/opentelemetry-extension-trace-propagators.txt create mode 100644 docs/apidiffs/1.44.1_vs_1.44.0/opentelemetry-opentracing-shim.txt create mode 100644 docs/apidiffs/1.44.1_vs_1.44.0/opentelemetry-sdk-common.txt create mode 100644 docs/apidiffs/1.44.1_vs_1.44.0/opentelemetry-sdk-extension-autoconfigure-spi.txt create mode 100644 docs/apidiffs/1.44.1_vs_1.44.0/opentelemetry-sdk-extension-autoconfigure.txt create mode 100644 docs/apidiffs/1.44.1_vs_1.44.0/opentelemetry-sdk-extension-jaeger-remote-sampler.txt create mode 100644 docs/apidiffs/1.44.1_vs_1.44.0/opentelemetry-sdk-logs.txt create mode 100644 docs/apidiffs/1.44.1_vs_1.44.0/opentelemetry-sdk-metrics.txt create mode 100644 docs/apidiffs/1.44.1_vs_1.44.0/opentelemetry-sdk-testing.txt create mode 100644 docs/apidiffs/1.44.1_vs_1.44.0/opentelemetry-sdk-trace.txt create mode 100644 docs/apidiffs/1.44.1_vs_1.44.0/opentelemetry-sdk.txt diff --git a/README.md b/README.md index 8efa1a05ec2..52db37f3aa1 100644 --- a/README.md +++ b/README.md @@ -105,7 +105,7 @@ dependency versions in sync. io.opentelemetry opentelemetry-bom - 1.44.0 + 1.44.1 pom import @@ -124,7 +124,7 @@ dependency versions in sync. ```groovy dependencies { - implementation platform("io.opentelemetry:opentelemetry-bom:1.44.0") + implementation platform("io.opentelemetry:opentelemetry-bom:1.44.1") implementation('io.opentelemetry:opentelemetry-api') } ``` @@ -133,8 +133,8 @@ Note that if you want to use any artifacts that have not fully stabilized yet (s ```groovy dependencies { - implementation platform("io.opentelemetry:opentelemetry-bom:1.44.0") - implementation platform('io.opentelemetry:opentelemetry-bom-alpha:1.44.0-alpha') + implementation platform("io.opentelemetry:opentelemetry-bom:1.44.1") + implementation platform('io.opentelemetry:opentelemetry-bom-alpha:1.44.1-alpha') implementation('io.opentelemetry:opentelemetry-api') implementation('io.opentelemetry:opentelemetry-exporter-prometheus') @@ -230,66 +230,66 @@ dependency as follows, replacing `{{artifact-id}}` with the value from the "Arti | Component | Description | Artifact ID | Version | Javadoc | |----------------------------------------------|----------------------------------------|---------------------------|-------------------------------------------------------------|---------| -| [Bill of Materials (BOM)](./bom) | Bill of materials for stable artifacts | `opentelemetry-bom` | 1.44.0 | N/A | -| [Alpha Bill of Materials (BOM)](./bom-alpha) | Bill of materials for alpha artifacts | `opentelemetry-bom-alpha` | 1.44.0-alpha | N/A | +| [Bill of Materials (BOM)](./bom) | Bill of materials for stable artifacts | `opentelemetry-bom` | 1.44.1 | N/A | +| [Alpha Bill of Materials (BOM)](./bom-alpha) | Bill of materials for alpha artifacts | `opentelemetry-bom-alpha` | 1.44.1-alpha | N/A | ### API | Component | Description | Artifact ID | Version | Javadoc | |-----------------------------------|--------------------------------------------------------------------------------------|-------------------------------|---------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| [API](./api/all) | OpenTelemetry API, including metrics, traces, baggage, context | `opentelemetry-api` | 1.44.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-api.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-api) | -| [API Incubator](./api/incubator) | API incubator, including pass through propagator, and extended tracer, and Event API | `opentelemetry-api-incubator` | 1.44.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-api-incubator.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-api-incubator) | -| [Context API](./context) | OpenTelemetry context API | `opentelemetry-context` | 1.44.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-context.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-context) | +| [API](./api/all) | OpenTelemetry API, including metrics, traces, baggage, context | `opentelemetry-api` | 1.44.1 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-api.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-api) | +| [API Incubator](./api/incubator) | API incubator, including pass through propagator, and extended tracer, and Event API | `opentelemetry-api-incubator` | 1.44.1 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-api-incubator.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-api-incubator) | +| [Context API](./context) | OpenTelemetry context API | `opentelemetry-context` | 1.44.1 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-context.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-context) | ### API Extensions | Component | Description | Artifact ID | Version | Javadoc | |---------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|---------------------------------------------|-------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| [Kotlin Extension](./extensions/kotlin) | Context extension for coroutines | `opentelemetry-extension-kotlin` | 1.44.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-extension-kotlin.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-extension-kotlin) | -| [Trace Propagators Extension](./extensions/trace-propagators) | Trace propagators, including B3, Jaeger, OT Trace | `opentelemetry-extension-trace-propagators` | 1.44.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-extension-trace-propagators.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-extension-trace-propagators) | +| [Kotlin Extension](./extensions/kotlin) | Context extension for coroutines | `opentelemetry-extension-kotlin` | 1.44.1 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-extension-kotlin.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-extension-kotlin) | +| [Trace Propagators Extension](./extensions/trace-propagators) | Trace propagators, including B3, Jaeger, OT Trace | `opentelemetry-extension-trace-propagators` | 1.44.1 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-extension-trace-propagators.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-extension-trace-propagators) | ### SDK | Component | Description | Artifact ID | Version | Javadoc | |------------------------------|--------------------------------------------------------|-----------------------------|---------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| [SDK](./sdk/all) | OpenTelemetry SDK, including metrics, traces, and logs | `opentelemetry-sdk` | 1.44.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk) | -| [Metrics SDK](./sdk/metrics) | OpenTelemetry metrics SDK | `opentelemetry-sdk-metrics` | 1.44.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-metrics.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-metrics) | -| [Trace SDK](./sdk/trace) | OpenTelemetry trace SDK | `opentelemetry-sdk-trace` | 1.44.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-trace.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-trace) | -| [Log SDK](./sdk/logs) | OpenTelemetry log SDK | `opentelemetry-sdk-logs` | 1.44.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-logs.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-logs) | -| [SDK Common](./sdk/common) | Shared SDK components | `opentelemetry-sdk-common` | 1.44.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-common.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-common) | -| [SDK Testing](./sdk/testing) | Components for testing OpenTelemetry instrumentation | `opentelemetry-sdk-testing` | 1.44.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-testing.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-testing) | +| [SDK](./sdk/all) | OpenTelemetry SDK, including metrics, traces, and logs | `opentelemetry-sdk` | 1.44.1 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk) | +| [Metrics SDK](./sdk/metrics) | OpenTelemetry metrics SDK | `opentelemetry-sdk-metrics` | 1.44.1 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-metrics.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-metrics) | +| [Trace SDK](./sdk/trace) | OpenTelemetry trace SDK | `opentelemetry-sdk-trace` | 1.44.1 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-trace.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-trace) | +| [Log SDK](./sdk/logs) | OpenTelemetry log SDK | `opentelemetry-sdk-logs` | 1.44.1 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-logs.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-logs) | +| [SDK Common](./sdk/common) | Shared SDK components | `opentelemetry-sdk-common` | 1.44.1 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-common.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-common) | +| [SDK Testing](./sdk/testing) | Components for testing OpenTelemetry instrumentation | `opentelemetry-sdk-testing` | 1.44.1 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-testing.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-testing) | ### SDK Exporters | Component | Description | Artifact ID | Version | Javadoc | |-----------------------------------------------------------------------|------------------------------------------------------------------------------|------------------------------------------------------|-------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| [OTLP Exporters](./exporters/otlp/all) | OTLP gRPC & HTTP exporters, including traces, metrics, and logs | `opentelemetry-exporter-otlp` | 1.44.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-otlp.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-otlp) | -| [OTLP Logging Exporters](./exporters/logging-otlp) | Logging exporters in OTLP JSON encoding, including traces, metrics, and logs | `opentelemetry-exporter-logging-otlp` | 1.44.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-logging-otlp.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-logging-otlp) | -| [OTLP Common](./exporters/otlp/common) | Shared OTLP components (internal) | `opentelemetry-exporter-otlp-common` | 1.44.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-otlp-common.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-otlp-common) | -| [Logging Exporter](./exporters/logging) | Logging exporters, including metrics, traces, and logs | `opentelemetry-exporter-logging` | 1.44.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-logging.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-logging) | -| [Zipkin Exporter](./exporters/zipkin) | Zipkin trace exporter | `opentelemetry-exporter-zipkin` | 1.44.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-zipkin.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-zipkin) | -| [Prometheus Exporter](./exporters/prometheus) | Prometheus metric exporter | `opentelemetry-exporter-prometheus` | 1.44.0-alpha | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-prometheus.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-prometheus) | -| [Exporter Common](./exporters/common) | Shared exporter components (internal) | `opentelemetry-exporter-common` | 1.44.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-common.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-common) | -| [OkHttp Sender](./exporters/sender/okhttp) | OkHttp implementation of HttpSender (internal) | `opentelemetry-exporter-sender-okhttp` | 1.44.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-sender-okhttp.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-sender-okhttp) | -| [JDK Sender](./exporters/sender/jdk) | Java 11+ native HttpClient implementation of HttpSender (internal) | `opentelemetry-exporter-sender-jdk` | 1.44.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-sender-jdk.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-sender-jdk) | | -| [gRPC ManagedChannel Sender](./exporters/sender/grpc-managed-channel) | gRPC ManagedChannel implementation of GrpcSender (internal) | `opentelemetry-exporter-sender-grpc-managed-channel` | 1.44.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-sender-grpc-managed-channel.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-sender-grpc-managed-channel) | | +| [OTLP Exporters](./exporters/otlp/all) | OTLP gRPC & HTTP exporters, including traces, metrics, and logs | `opentelemetry-exporter-otlp` | 1.44.1 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-otlp.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-otlp) | +| [OTLP Logging Exporters](./exporters/logging-otlp) | Logging exporters in OTLP JSON encoding, including traces, metrics, and logs | `opentelemetry-exporter-logging-otlp` | 1.44.1 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-logging-otlp.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-logging-otlp) | +| [OTLP Common](./exporters/otlp/common) | Shared OTLP components (internal) | `opentelemetry-exporter-otlp-common` | 1.44.1 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-otlp-common.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-otlp-common) | +| [Logging Exporter](./exporters/logging) | Logging exporters, including metrics, traces, and logs | `opentelemetry-exporter-logging` | 1.44.1 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-logging.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-logging) | +| [Zipkin Exporter](./exporters/zipkin) | Zipkin trace exporter | `opentelemetry-exporter-zipkin` | 1.44.1 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-zipkin.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-zipkin) | +| [Prometheus Exporter](./exporters/prometheus) | Prometheus metric exporter | `opentelemetry-exporter-prometheus` | 1.44.1-alpha | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-prometheus.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-prometheus) | +| [Exporter Common](./exporters/common) | Shared exporter components (internal) | `opentelemetry-exporter-common` | 1.44.1 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-common.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-common) | +| [OkHttp Sender](./exporters/sender/okhttp) | OkHttp implementation of HttpSender (internal) | `opentelemetry-exporter-sender-okhttp` | 1.44.1 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-sender-okhttp.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-sender-okhttp) | +| [JDK Sender](./exporters/sender/jdk) | Java 11+ native HttpClient implementation of HttpSender (internal) | `opentelemetry-exporter-sender-jdk` | 1.44.1 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-sender-jdk.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-sender-jdk) | | +| [gRPC ManagedChannel Sender](./exporters/sender/grpc-managed-channel) | gRPC ManagedChannel implementation of GrpcSender (internal) | `opentelemetry-exporter-sender-grpc-managed-channel` | 1.44.1 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-sender-grpc-managed-channel.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-sender-grpc-managed-channel) | | ### SDK Extensions | Component | Description | Artifact ID | Version | Javadoc | |-------------------------------------------------------------------------------|------------------------------------------------------------------------------------|-----------------------------------------------------|-------------------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| [SDK Autoconfigure](./sdk-extensions/autoconfigure) | Autoconfigure OpenTelemetry SDK from env vars, system properties, and SPI | `opentelemetry-sdk-extension-autoconfigure` | 1.44.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-extension-autoconfigure.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-extension-autoconfigure) | -| [SDK Autoconfigure SPI](./sdk-extensions/autoconfigure-spi) | Service Provider Interface (SPI) definitions for autoconfigure | `opentelemetry-sdk-extension-autoconfigure-spi` | 1.44.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-extension-autoconfigure-spi.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-extension-autoconfigure-spi) | -| [SDK Jaeger Remote Sampler Extension](./sdk-extensions/jaeger-remote-sampler) | Sampler which obtains sampling configuration from remote Jaeger server | `opentelemetry-sdk-extension-jaeger-remote-sampler` | 1.44.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-extension-jaeger-remote-sampler.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-extension-jaeger-remote-sampler) | -| [SDK Incubator](./sdk-extensions/incubator) | SDK incubator, including YAML based view configuration, LeakDetectingSpanProcessor | `opentelemetry-sdk-extension-incubator` | 1.44.0-alpha | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-extension-incubator.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-extension-incubator) | +| [SDK Autoconfigure](./sdk-extensions/autoconfigure) | Autoconfigure OpenTelemetry SDK from env vars, system properties, and SPI | `opentelemetry-sdk-extension-autoconfigure` | 1.44.1 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-extension-autoconfigure.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-extension-autoconfigure) | +| [SDK Autoconfigure SPI](./sdk-extensions/autoconfigure-spi) | Service Provider Interface (SPI) definitions for autoconfigure | `opentelemetry-sdk-extension-autoconfigure-spi` | 1.44.1 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-extension-autoconfigure-spi.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-extension-autoconfigure-spi) | +| [SDK Jaeger Remote Sampler Extension](./sdk-extensions/jaeger-remote-sampler) | Sampler which obtains sampling configuration from remote Jaeger server | `opentelemetry-sdk-extension-jaeger-remote-sampler` | 1.44.1 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-extension-jaeger-remote-sampler.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-extension-jaeger-remote-sampler) | +| [SDK Incubator](./sdk-extensions/incubator) | SDK incubator, including YAML based view configuration, LeakDetectingSpanProcessor | `opentelemetry-sdk-extension-incubator` | 1.44.1-alpha | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-extension-incubator.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-extension-incubator) | ### Shims | Component | Description | Artifact ID | Version | Javadoc | |----------------------------------------|--------------------------------------------------------------|----------------------------------|-------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| [OpenCensus Shim](./opencensus-shim) | Bridge opencensus metrics into the OpenTelemetry metrics SDK | `opentelemetry-opencensus-shim` | 1.44.0-alpha | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-opencensus-shim.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-opencensus-shim) | -| [OpenTracing Shim](./opentracing-shim) | Bridge opentracing spans into the OpenTelemetry trace API | `opentelemetry-opentracing-shim` | 1.44.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-opentracing-shim.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-opentracing-shim) | +| [OpenCensus Shim](./opencensus-shim) | Bridge opencensus metrics into the OpenTelemetry metrics SDK | `opentelemetry-opencensus-shim` | 1.44.1-alpha | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-opencensus-shim.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-opencensus-shim) | +| [OpenTracing Shim](./opentracing-shim) | Bridge opentracing spans into the OpenTelemetry trace API | `opentelemetry-opentracing-shim` | 1.44.1 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-opentracing-shim.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-opentracing-shim) | ## Contributing diff --git a/docs/apidiffs/1.44.1_vs_1.44.0/opentelemetry-api.txt b/docs/apidiffs/1.44.1_vs_1.44.0/opentelemetry-api.txt new file mode 100644 index 00000000000..227cbe9a7d7 --- /dev/null +++ b/docs/apidiffs/1.44.1_vs_1.44.0/opentelemetry-api.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of opentelemetry-api-1.44.1.jar against opentelemetry-api-1.44.0.jar +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.44.1_vs_1.44.0/opentelemetry-context.txt b/docs/apidiffs/1.44.1_vs_1.44.0/opentelemetry-context.txt new file mode 100644 index 00000000000..1ba6fac89b4 --- /dev/null +++ b/docs/apidiffs/1.44.1_vs_1.44.0/opentelemetry-context.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of opentelemetry-context-1.44.1.jar against opentelemetry-context-1.44.0.jar +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.44.1_vs_1.44.0/opentelemetry-exporter-common.txt b/docs/apidiffs/1.44.1_vs_1.44.0/opentelemetry-exporter-common.txt new file mode 100644 index 00000000000..f17cdd1ef90 --- /dev/null +++ b/docs/apidiffs/1.44.1_vs_1.44.0/opentelemetry-exporter-common.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of opentelemetry-exporter-common-1.44.1.jar against opentelemetry-exporter-common-1.44.0.jar +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.44.1_vs_1.44.0/opentelemetry-exporter-logging-otlp.txt b/docs/apidiffs/1.44.1_vs_1.44.0/opentelemetry-exporter-logging-otlp.txt new file mode 100644 index 00000000000..8b093eaf0aa --- /dev/null +++ b/docs/apidiffs/1.44.1_vs_1.44.0/opentelemetry-exporter-logging-otlp.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of opentelemetry-exporter-logging-otlp-1.44.1.jar against opentelemetry-exporter-logging-otlp-1.44.0.jar +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.44.1_vs_1.44.0/opentelemetry-exporter-logging.txt b/docs/apidiffs/1.44.1_vs_1.44.0/opentelemetry-exporter-logging.txt new file mode 100644 index 00000000000..c60e2be2842 --- /dev/null +++ b/docs/apidiffs/1.44.1_vs_1.44.0/opentelemetry-exporter-logging.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of opentelemetry-exporter-logging-1.44.1.jar against opentelemetry-exporter-logging-1.44.0.jar +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.44.1_vs_1.44.0/opentelemetry-exporter-otlp-common.txt b/docs/apidiffs/1.44.1_vs_1.44.0/opentelemetry-exporter-otlp-common.txt new file mode 100644 index 00000000000..75bc9a388e8 --- /dev/null +++ b/docs/apidiffs/1.44.1_vs_1.44.0/opentelemetry-exporter-otlp-common.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of opentelemetry-exporter-otlp-common-1.44.1.jar against opentelemetry-exporter-otlp-common-1.44.0.jar +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.44.1_vs_1.44.0/opentelemetry-exporter-otlp.txt b/docs/apidiffs/1.44.1_vs_1.44.0/opentelemetry-exporter-otlp.txt new file mode 100644 index 00000000000..c6b8d754b79 --- /dev/null +++ b/docs/apidiffs/1.44.1_vs_1.44.0/opentelemetry-exporter-otlp.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of opentelemetry-exporter-otlp-1.44.1.jar against opentelemetry-exporter-otlp-1.44.0.jar +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.44.1_vs_1.44.0/opentelemetry-exporter-sender-grpc-managed-channel.txt b/docs/apidiffs/1.44.1_vs_1.44.0/opentelemetry-exporter-sender-grpc-managed-channel.txt new file mode 100644 index 00000000000..50b886238aa --- /dev/null +++ b/docs/apidiffs/1.44.1_vs_1.44.0/opentelemetry-exporter-sender-grpc-managed-channel.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of opentelemetry-exporter-sender-grpc-managed-channel-1.44.1.jar against opentelemetry-exporter-sender-grpc-managed-channel-1.44.0.jar +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.44.1_vs_1.44.0/opentelemetry-exporter-sender-jdk.txt b/docs/apidiffs/1.44.1_vs_1.44.0/opentelemetry-exporter-sender-jdk.txt new file mode 100644 index 00000000000..33c42b914c4 --- /dev/null +++ b/docs/apidiffs/1.44.1_vs_1.44.0/opentelemetry-exporter-sender-jdk.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of opentelemetry-exporter-sender-jdk-1.44.1.jar against opentelemetry-exporter-sender-jdk-1.44.0.jar +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.44.1_vs_1.44.0/opentelemetry-exporter-sender-okhttp.txt b/docs/apidiffs/1.44.1_vs_1.44.0/opentelemetry-exporter-sender-okhttp.txt new file mode 100644 index 00000000000..9f2ab4ddafb --- /dev/null +++ b/docs/apidiffs/1.44.1_vs_1.44.0/opentelemetry-exporter-sender-okhttp.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of opentelemetry-exporter-sender-okhttp-1.44.1.jar against opentelemetry-exporter-sender-okhttp-1.44.0.jar +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.44.1_vs_1.44.0/opentelemetry-exporter-zipkin.txt b/docs/apidiffs/1.44.1_vs_1.44.0/opentelemetry-exporter-zipkin.txt new file mode 100644 index 00000000000..29340d90453 --- /dev/null +++ b/docs/apidiffs/1.44.1_vs_1.44.0/opentelemetry-exporter-zipkin.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of opentelemetry-exporter-zipkin-1.44.1.jar against opentelemetry-exporter-zipkin-1.44.0.jar +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.44.1_vs_1.44.0/opentelemetry-extension-kotlin.txt b/docs/apidiffs/1.44.1_vs_1.44.0/opentelemetry-extension-kotlin.txt new file mode 100644 index 00000000000..467a926a409 --- /dev/null +++ b/docs/apidiffs/1.44.1_vs_1.44.0/opentelemetry-extension-kotlin.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of opentelemetry-extension-kotlin-1.44.1.jar against opentelemetry-extension-kotlin-1.44.0.jar +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.44.1_vs_1.44.0/opentelemetry-extension-trace-propagators.txt b/docs/apidiffs/1.44.1_vs_1.44.0/opentelemetry-extension-trace-propagators.txt new file mode 100644 index 00000000000..bfcd1605834 --- /dev/null +++ b/docs/apidiffs/1.44.1_vs_1.44.0/opentelemetry-extension-trace-propagators.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of opentelemetry-extension-trace-propagators-1.44.1.jar against opentelemetry-extension-trace-propagators-1.44.0.jar +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.44.1_vs_1.44.0/opentelemetry-opentracing-shim.txt b/docs/apidiffs/1.44.1_vs_1.44.0/opentelemetry-opentracing-shim.txt new file mode 100644 index 00000000000..c553192aca9 --- /dev/null +++ b/docs/apidiffs/1.44.1_vs_1.44.0/opentelemetry-opentracing-shim.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of opentelemetry-opentracing-shim-1.44.1.jar against opentelemetry-opentracing-shim-1.44.0.jar +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.44.1_vs_1.44.0/opentelemetry-sdk-common.txt b/docs/apidiffs/1.44.1_vs_1.44.0/opentelemetry-sdk-common.txt new file mode 100644 index 00000000000..d07f1dadeb8 --- /dev/null +++ b/docs/apidiffs/1.44.1_vs_1.44.0/opentelemetry-sdk-common.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of opentelemetry-sdk-common-1.44.1.jar against opentelemetry-sdk-common-1.44.0.jar +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.44.1_vs_1.44.0/opentelemetry-sdk-extension-autoconfigure-spi.txt b/docs/apidiffs/1.44.1_vs_1.44.0/opentelemetry-sdk-extension-autoconfigure-spi.txt new file mode 100644 index 00000000000..37aa938da9b --- /dev/null +++ b/docs/apidiffs/1.44.1_vs_1.44.0/opentelemetry-sdk-extension-autoconfigure-spi.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of opentelemetry-sdk-extension-autoconfigure-spi-1.44.1.jar against opentelemetry-sdk-extension-autoconfigure-spi-1.44.0.jar +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.44.1_vs_1.44.0/opentelemetry-sdk-extension-autoconfigure.txt b/docs/apidiffs/1.44.1_vs_1.44.0/opentelemetry-sdk-extension-autoconfigure.txt new file mode 100644 index 00000000000..750b0e2c27f --- /dev/null +++ b/docs/apidiffs/1.44.1_vs_1.44.0/opentelemetry-sdk-extension-autoconfigure.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of opentelemetry-sdk-extension-autoconfigure-1.44.1.jar against opentelemetry-sdk-extension-autoconfigure-1.44.0.jar +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.44.1_vs_1.44.0/opentelemetry-sdk-extension-jaeger-remote-sampler.txt b/docs/apidiffs/1.44.1_vs_1.44.0/opentelemetry-sdk-extension-jaeger-remote-sampler.txt new file mode 100644 index 00000000000..0643d17dfbb --- /dev/null +++ b/docs/apidiffs/1.44.1_vs_1.44.0/opentelemetry-sdk-extension-jaeger-remote-sampler.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of opentelemetry-sdk-extension-jaeger-remote-sampler-1.44.1.jar against opentelemetry-sdk-extension-jaeger-remote-sampler-1.44.0.jar +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.44.1_vs_1.44.0/opentelemetry-sdk-logs.txt b/docs/apidiffs/1.44.1_vs_1.44.0/opentelemetry-sdk-logs.txt new file mode 100644 index 00000000000..26b4f4b3e5f --- /dev/null +++ b/docs/apidiffs/1.44.1_vs_1.44.0/opentelemetry-sdk-logs.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of opentelemetry-sdk-logs-1.44.1.jar against opentelemetry-sdk-logs-1.44.0.jar +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.44.1_vs_1.44.0/opentelemetry-sdk-metrics.txt b/docs/apidiffs/1.44.1_vs_1.44.0/opentelemetry-sdk-metrics.txt new file mode 100644 index 00000000000..5031b75f9f6 --- /dev/null +++ b/docs/apidiffs/1.44.1_vs_1.44.0/opentelemetry-sdk-metrics.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of opentelemetry-sdk-metrics-1.44.1.jar against opentelemetry-sdk-metrics-1.44.0.jar +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.44.1_vs_1.44.0/opentelemetry-sdk-testing.txt b/docs/apidiffs/1.44.1_vs_1.44.0/opentelemetry-sdk-testing.txt new file mode 100644 index 00000000000..b3c59ff77fd --- /dev/null +++ b/docs/apidiffs/1.44.1_vs_1.44.0/opentelemetry-sdk-testing.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of opentelemetry-sdk-testing-1.44.1.jar against opentelemetry-sdk-testing-1.44.0.jar +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.44.1_vs_1.44.0/opentelemetry-sdk-trace.txt b/docs/apidiffs/1.44.1_vs_1.44.0/opentelemetry-sdk-trace.txt new file mode 100644 index 00000000000..2feb43d5d6b --- /dev/null +++ b/docs/apidiffs/1.44.1_vs_1.44.0/opentelemetry-sdk-trace.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of opentelemetry-sdk-trace-1.44.1.jar against opentelemetry-sdk-trace-1.44.0.jar +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.44.1_vs_1.44.0/opentelemetry-sdk.txt b/docs/apidiffs/1.44.1_vs_1.44.0/opentelemetry-sdk.txt new file mode 100644 index 00000000000..37868ac312f --- /dev/null +++ b/docs/apidiffs/1.44.1_vs_1.44.0/opentelemetry-sdk.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of opentelemetry-sdk-1.44.1.jar against opentelemetry-sdk-1.44.0.jar +No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-api.txt b/docs/apidiffs/current_vs_latest/opentelemetry-api.txt index 634dc2beb01..351726df140 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-api.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-api.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of opentelemetry-api-1.45.0-SNAPSHOT.jar against opentelemetry-api-1.44.0.jar +Comparing source compatibility of opentelemetry-api-1.45.0-SNAPSHOT.jar against opentelemetry-api-1.44.1.jar No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-context.txt b/docs/apidiffs/current_vs_latest/opentelemetry-context.txt index 4bcd9992fc5..6dfe94027f0 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-context.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-context.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of opentelemetry-context-1.45.0-SNAPSHOT.jar against opentelemetry-context-1.44.0.jar +Comparing source compatibility of opentelemetry-context-1.45.0-SNAPSHOT.jar against opentelemetry-context-1.44.1.jar No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-common.txt b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-common.txt index 38840d7645b..8692bd40f0d 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-common.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-common.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of opentelemetry-exporter-common-1.45.0-SNAPSHOT.jar against opentelemetry-exporter-common-1.44.0.jar +Comparing source compatibility of opentelemetry-exporter-common-1.45.0-SNAPSHOT.jar against opentelemetry-exporter-common-1.44.1.jar No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-logging-otlp.txt b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-logging-otlp.txt index 486aa4adb22..53e3a232b55 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-logging-otlp.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-logging-otlp.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of opentelemetry-exporter-logging-otlp-1.45.0-SNAPSHOT.jar against opentelemetry-exporter-logging-otlp-1.44.0.jar +Comparing source compatibility of opentelemetry-exporter-logging-otlp-1.45.0-SNAPSHOT.jar against opentelemetry-exporter-logging-otlp-1.44.1.jar No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-logging.txt b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-logging.txt index a4743ffe739..c4c1a7bb9e5 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-logging.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-logging.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of opentelemetry-exporter-logging-1.45.0-SNAPSHOT.jar against opentelemetry-exporter-logging-1.44.0.jar +Comparing source compatibility of opentelemetry-exporter-logging-1.45.0-SNAPSHOT.jar against opentelemetry-exporter-logging-1.44.1.jar No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-otlp-common.txt b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-otlp-common.txt index c196ea9e30d..190cf34e311 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-otlp-common.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-otlp-common.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of opentelemetry-exporter-otlp-common-1.45.0-SNAPSHOT.jar against opentelemetry-exporter-otlp-common-1.44.0.jar +Comparing source compatibility of opentelemetry-exporter-otlp-common-1.45.0-SNAPSHOT.jar against opentelemetry-exporter-otlp-common-1.44.1.jar No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-otlp.txt b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-otlp.txt index c84f1ddd8e2..8f73054e163 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-otlp.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-otlp.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of opentelemetry-exporter-otlp-1.45.0-SNAPSHOT.jar against opentelemetry-exporter-otlp-1.44.0.jar +Comparing source compatibility of opentelemetry-exporter-otlp-1.45.0-SNAPSHOT.jar against opentelemetry-exporter-otlp-1.44.1.jar No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-sender-grpc-managed-channel.txt b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-sender-grpc-managed-channel.txt index 0f93b25e61c..5eefbf7d6c1 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-sender-grpc-managed-channel.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-sender-grpc-managed-channel.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of opentelemetry-exporter-sender-grpc-managed-channel-1.45.0-SNAPSHOT.jar against opentelemetry-exporter-sender-grpc-managed-channel-1.44.0.jar +Comparing source compatibility of opentelemetry-exporter-sender-grpc-managed-channel-1.45.0-SNAPSHOT.jar against opentelemetry-exporter-sender-grpc-managed-channel-1.44.1.jar No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-sender-jdk.txt b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-sender-jdk.txt index fbf49c9697e..34a695b7df2 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-sender-jdk.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-sender-jdk.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of opentelemetry-exporter-sender-jdk-1.45.0-SNAPSHOT.jar against opentelemetry-exporter-sender-jdk-1.44.0.jar +Comparing source compatibility of opentelemetry-exporter-sender-jdk-1.45.0-SNAPSHOT.jar against opentelemetry-exporter-sender-jdk-1.44.1.jar No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-sender-okhttp.txt b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-sender-okhttp.txt index f0003508c3c..89f989f8f99 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-sender-okhttp.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-sender-okhttp.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of opentelemetry-exporter-sender-okhttp-1.45.0-SNAPSHOT.jar against opentelemetry-exporter-sender-okhttp-1.44.0.jar +Comparing source compatibility of opentelemetry-exporter-sender-okhttp-1.45.0-SNAPSHOT.jar against opentelemetry-exporter-sender-okhttp-1.44.1.jar No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-zipkin.txt b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-zipkin.txt index 72099ccdd1e..3a9ad3b76f1 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-zipkin.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-zipkin.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of opentelemetry-exporter-zipkin-1.45.0-SNAPSHOT.jar against opentelemetry-exporter-zipkin-1.44.0.jar +Comparing source compatibility of opentelemetry-exporter-zipkin-1.45.0-SNAPSHOT.jar against opentelemetry-exporter-zipkin-1.44.1.jar No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-extension-kotlin.txt b/docs/apidiffs/current_vs_latest/opentelemetry-extension-kotlin.txt index bdc24b3966c..589f2bff4a7 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-extension-kotlin.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-extension-kotlin.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of opentelemetry-extension-kotlin-1.45.0-SNAPSHOT.jar against opentelemetry-extension-kotlin-1.44.0.jar +Comparing source compatibility of opentelemetry-extension-kotlin-1.45.0-SNAPSHOT.jar against opentelemetry-extension-kotlin-1.44.1.jar No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-extension-trace-propagators.txt b/docs/apidiffs/current_vs_latest/opentelemetry-extension-trace-propagators.txt index 4781ec62f94..4de33099a46 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-extension-trace-propagators.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-extension-trace-propagators.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of opentelemetry-extension-trace-propagators-1.45.0-SNAPSHOT.jar against opentelemetry-extension-trace-propagators-1.44.0.jar +Comparing source compatibility of opentelemetry-extension-trace-propagators-1.45.0-SNAPSHOT.jar against opentelemetry-extension-trace-propagators-1.44.1.jar No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-opentracing-shim.txt b/docs/apidiffs/current_vs_latest/opentelemetry-opentracing-shim.txt index 94fd3deb09c..f45d2f75a1d 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-opentracing-shim.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-opentracing-shim.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of opentelemetry-opentracing-shim-1.45.0-SNAPSHOT.jar against opentelemetry-opentracing-shim-1.44.0.jar +Comparing source compatibility of opentelemetry-opentracing-shim-1.45.0-SNAPSHOT.jar against opentelemetry-opentracing-shim-1.44.1.jar No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-common.txt b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-common.txt index 694c4b6d577..9c5036c7232 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-common.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-common.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of opentelemetry-sdk-common-1.45.0-SNAPSHOT.jar against opentelemetry-sdk-common-1.44.0.jar +Comparing source compatibility of opentelemetry-sdk-common-1.45.0-SNAPSHOT.jar against opentelemetry-sdk-common-1.44.1.jar No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-extension-autoconfigure-spi.txt b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-extension-autoconfigure-spi.txt index b38024044a5..9c9a827fdf4 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-extension-autoconfigure-spi.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-extension-autoconfigure-spi.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of opentelemetry-sdk-extension-autoconfigure-spi-1.45.0-SNAPSHOT.jar against opentelemetry-sdk-extension-autoconfigure-spi-1.44.0.jar +Comparing source compatibility of opentelemetry-sdk-extension-autoconfigure-spi-1.45.0-SNAPSHOT.jar against opentelemetry-sdk-extension-autoconfigure-spi-1.44.1.jar No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-extension-autoconfigure.txt b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-extension-autoconfigure.txt index 9d98cddd1a5..aa2ec5b1d26 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-extension-autoconfigure.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-extension-autoconfigure.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of opentelemetry-sdk-extension-autoconfigure-1.45.0-SNAPSHOT.jar against opentelemetry-sdk-extension-autoconfigure-1.44.0.jar +Comparing source compatibility of opentelemetry-sdk-extension-autoconfigure-1.45.0-SNAPSHOT.jar against opentelemetry-sdk-extension-autoconfigure-1.44.1.jar No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-extension-jaeger-remote-sampler.txt b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-extension-jaeger-remote-sampler.txt index 0c9837b3701..e61102f3a81 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-extension-jaeger-remote-sampler.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-extension-jaeger-remote-sampler.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of opentelemetry-sdk-extension-jaeger-remote-sampler-1.45.0-SNAPSHOT.jar against opentelemetry-sdk-extension-jaeger-remote-sampler-1.44.0.jar +Comparing source compatibility of opentelemetry-sdk-extension-jaeger-remote-sampler-1.45.0-SNAPSHOT.jar against opentelemetry-sdk-extension-jaeger-remote-sampler-1.44.1.jar No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-logs.txt b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-logs.txt index b1ef5ae5a38..3c2b9fb4e3a 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-logs.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-logs.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of opentelemetry-sdk-logs-1.45.0-SNAPSHOT.jar against opentelemetry-sdk-logs-1.44.0.jar +Comparing source compatibility of opentelemetry-sdk-logs-1.45.0-SNAPSHOT.jar against opentelemetry-sdk-logs-1.44.1.jar No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-metrics.txt b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-metrics.txt index c3e3d2e3256..ef08400bb94 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-metrics.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-metrics.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of opentelemetry-sdk-metrics-1.45.0-SNAPSHOT.jar against opentelemetry-sdk-metrics-1.44.0.jar +Comparing source compatibility of opentelemetry-sdk-metrics-1.45.0-SNAPSHOT.jar against opentelemetry-sdk-metrics-1.44.1.jar No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-testing.txt b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-testing.txt index 6f89fead97a..b04bcd8ff85 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-testing.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-testing.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of opentelemetry-sdk-testing-1.45.0-SNAPSHOT.jar against opentelemetry-sdk-testing-1.44.0.jar +Comparing source compatibility of opentelemetry-sdk-testing-1.45.0-SNAPSHOT.jar against opentelemetry-sdk-testing-1.44.1.jar No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-trace.txt b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-trace.txt index 8d462811694..5e83a4987a7 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-trace.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-trace.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of opentelemetry-sdk-trace-1.45.0-SNAPSHOT.jar against opentelemetry-sdk-trace-1.44.0.jar +Comparing source compatibility of opentelemetry-sdk-trace-1.45.0-SNAPSHOT.jar against opentelemetry-sdk-trace-1.44.1.jar No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-sdk.txt b/docs/apidiffs/current_vs_latest/opentelemetry-sdk.txt index cdc75c8f941..8ff004b24a4 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-sdk.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-sdk.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of opentelemetry-sdk-1.45.0-SNAPSHOT.jar against opentelemetry-sdk-1.44.0.jar +Comparing source compatibility of opentelemetry-sdk-1.45.0-SNAPSHOT.jar against opentelemetry-sdk-1.44.1.jar No changes. \ No newline at end of file From 9a0bfb23115a5c4d22f4c36fe4d4df19342d37bb Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sun, 17 Nov 2024 16:25:45 -0800 Subject: [PATCH 663/901] chore(deps): update plugin com.gradle.develocity to v3.18.2 (#6874) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- settings.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/settings.gradle.kts b/settings.gradle.kts index 4edff174f84..c7a176ef057 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -1,7 +1,7 @@ pluginManagement { plugins { id("com.gradleup.shadow") version "8.3.5" - id("com.gradle.develocity") version "3.18.1" + id("com.gradle.develocity") version "3.18.2" id("de.undercouch.download") version "5.6.0" id("org.jsonschema2pojo") version "1.2.2" id("io.github.gradle-nexus.publish-plugin") version "2.0.0" From bd31b457f0e659449c53eb96cf5a3b577c44cb14 Mon Sep 17 00:00:00 2001 From: jack-berg <34418638+jack-berg@users.noreply.github.com> Date: Mon, 18 Nov 2024 09:08:20 -0600 Subject: [PATCH 664/901] Refactor README.md (#6881) --- README.md | 379 +++++++++++++++++++++++------------------------------- 1 file changed, 164 insertions(+), 215 deletions(-) diff --git a/README.md b/README.md index 52db37f3aa1..633be605b34 100644 --- a/README.md +++ b/README.md @@ -4,67 +4,16 @@ [![Maven Central][maven-image]][maven-url] [![Reproducible Builds](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/jvm-repo-rebuild/reproducible-central/master/content/io/opentelemetry/java/badge.json)](https://github.com/jvm-repo-rebuild/reproducible-central/blob/master/content/io/opentelemetry/java/README.md) -## Project Status +`opentelemetry-java` is the home of the Java implementation of the OpenTelemetry API for recording +telemetry, and SDK for managing telemetry recorded by the API. -See [Java status on OpenTelemetry.io][otel-java-status]. +See [opentelemetry.io Java Documentation](https://opentelemetry.io/docs/languages/java/intro/) for: -## Getting Started - -If you are looking for an all-in-one, easy-to-install **auto-instrumentation -javaagent**, see [opentelemetry-java-instrumentation][]. - -If you are looking for **examples** on how to use the OpenTelemetry API to -write your own **manual instrumentation**, or how to set up the OpenTelemetry -Java SDK, see [Manual instrumentation][]. Fully-functional examples -are available in [opentelemetry-java-examples][]. - -If you are looking for generated classes for -the [OpenTelemetry semantic conventions][opentelemetry-semantic-conventions], -see [semantic-conventions-java][opentelemetry-semantic-conventions-java]. - -For a general overview of OpenTelemetry, visit [opentelemetry.io][]. - -Would you like to get involved with the project? Read our [contributing guide](CONTRIBUTING.md). We welcome -contributions! - -## Contacting us - -We hold regular meetings. See details at [community page](https://github.com/open-telemetry/community#java-sdk). - -We use [GitHub Discussions](https://github.com/open-telemetry/opentelemetry-java/discussions) -for support or general questions. Feel free to drop us a line. - -We are also present in the [`#otel-java`](https://cloud-native.slack.com/archives/C014L2KCTE3) channel in the [CNCF slack](https://slack.cncf.io/). -Please join us for more informal discussions. - -To report a bug, or request a new feature, -please [open an issue](https://github.com/open-telemetry/opentelemetry-java/issues/new/choose). - -## Overview - -OpenTelemetry is the merging of OpenCensus and OpenTracing into a single project. - -This project contains the following top level components: - -* [OpenTelemetry API](api/): - * [stable apis](api/all) including `Tracer`, `Span`, `SpanContext`, `Meter`, and `Baggage`. - * [context api](context/) The OpenTelemetry Context implementation. - * [incubating apis](api/incubator) incubating APIs, including `Events`. -* [extensions](extensions/) define additional API extensions not part of the core API, including propagators. -* [sdk](sdk/) defines the implementation of the OpenTelemetry API. -* [exporters](exporters/) trace, metric, and log exporters for the SDK. -* [sdk-extensions](sdk-extensions/) defines additional SDK extensions, which are not part of the core SDK. -* [OpenTracing shim](opentracing-shim/) defines a bridge layer from OpenTracing to the OpenTelemetry API. -* [OpenCensus shim](opencensus-shim/) defines a bridge layer from OpenCensus to the OpenTelemetry API. - -This project publishes a lot of artifacts, listed in [releases](#releases). -[`opentelemetry-bom`](https://mvnrepository.com/artifact/io.opentelemetry/opentelemetry-bom) (BOM = -Bill of Materials) is provided to assist with synchronizing versions of -dependencies. [`opentelemetry-bom-alpha`](https://mvnrepository.com/artifact/io.opentelemetry/opentelemetry-bom-alpha) -provides the same function for unstable artifacts. See [published releases](#published-releases) for -instructions on using the BOMs. - -We would love to hear from the larger community: please provide feedback proactively. +* An overview of the OpenTelemetry Java ecosystem and key repositories +* Detailed documentation on the components published from this repository +* Review of instrumentation ecosystem, including OpenTelemetry Java agent +* End-to-end working code examples +* And more ## Requirements @@ -76,180 +25,63 @@ details. reasons, [library desugaring](https://developer.android.com/studio/write/java8-support#library-desugaring) must be enabled. -See [CONTRIBUTING.md](./CONTRIBUTING.md) for additional instructions for building this project for -development. - -### Note about extensions - -Both API and SDK extensions consist of various additional components which are excluded from the core artifacts -to keep them from growing too large. - -We still aim to provide the same level of quality and guarantee for them as for the core components. -Please don't hesitate to use them if you find them useful. - -## Project setup and contributing - -Please refer to the [contribution guide](CONTRIBUTING.md) on how to set up for development and contribute! - -## Published Releases - -Published releases are available on maven central. We strongly recommend using our published BOM to keep all -dependency versions in sync. - -### Maven - -```xml - - - - - io.opentelemetry - opentelemetry-bom - 1.44.1 - pom - import - - - - - - io.opentelemetry - opentelemetry-api - - - -``` - -### Gradle - -```groovy -dependencies { - implementation platform("io.opentelemetry:opentelemetry-bom:1.44.1") - implementation('io.opentelemetry:opentelemetry-api') -} -``` - -Note that if you want to use any artifacts that have not fully stabilized yet (such as the [prometheus exporter](https://github.com/open-telemetry/opentelemetry-java/tree/main/exporters/prometheus), then you will need to add an entry for the Alpha BOM as well, e.g. - -```groovy -dependencies { - implementation platform("io.opentelemetry:opentelemetry-bom:1.44.1") - implementation platform('io.opentelemetry:opentelemetry-bom-alpha:1.44.1-alpha') - - implementation('io.opentelemetry:opentelemetry-api') - implementation('io.opentelemetry:opentelemetry-exporter-prometheus') - implementation('io.opentelemetry:opentelemetry-sdk-extension-autoconfigure') -} -``` - -## Snapshots - -Snapshots based out the `main` branch are available for `opentelemetry-api`, `opentelemetry-sdk` and the rest of the artifacts. -We strongly recommend using our published BOM to keep all dependency versions in sync. - -### Maven - -```xml - - - - oss.sonatype.org-snapshot - https://oss.sonatype.org/content/repositories/snapshots - - - - - - io.opentelemetry - opentelemetry-bom - 1.45.0-SNAPSHOT - pom - import - - - - - - io.opentelemetry - opentelemetry-api - - - -``` - -### Gradle - -```groovy -repositories { - maven { url 'https://oss.sonatype.org/content/repositories/snapshots' } -} - -dependencies { - implementation platform("io.opentelemetry:opentelemetry-bom:1.45.0-SNAPSHOT") - implementation('io.opentelemetry:opentelemetry-api') -} -``` - -Libraries will usually only need `opentelemetry-api`, while applications -will want to use the `opentelemetry-sdk` module which contains our standard implementation -of the APIs. - -## Gradle composite builds - -For opentelemetry-java developers that need to test the latest source code with another -project, composite builds can be used as an alternative to `publishToMavenLocal`. This -requires some setup which is explained [here](CONTRIBUTING.md#composing-builds). +See [contributing](#contributing) for details on building this project locally. ## Releases -See the [VERSIONING.md](VERSIONING.md) document for our policies for releases and compatibility -guarantees. +Releases are published to maven central. We +publish [minor releases monthly](RELEASING.md#release-cadence) +and [patch releases as needed](RELEASING.md#preparing-a-new-patch-release). -Check out information about the [latest release](https://github.com/open-telemetry/opentelemetry-java/releases). +See [releases](https://github.com/open-telemetry/opentelemetry-java/releases) for a listing of +released versions and notes (see also [changelog](CHANGELOG.md)). -See the project [milestones](https://github.com/open-telemetry/opentelemetry-java/milestones) -for details on upcoming releases. The dates and features described in issues -and milestones are estimates, and subject to change. +## Artifacts -The following tables describe the artifacts published by this project. To take a dependency, follow -the instructions in [Published Released](#published-releases) to include the BOM, and specify the -dependency as follows, replacing `{{artifact-id}}` with the value from the "Artifact ID" column: +The artifacts published by this repository are summarized below in tables, organized in collapsible +sections by topic. -```xml - - io.opentelemetry - {{artifact-id}} - -``` +As discussed in [compatibility](#compatibility), artifact versions must be kept in sync, for which +we strongly recommend [using one of our BOMs][dependencies-and-boms]. -```groovy - implementation('io.opentelemetry:{{artifact-id}}') -``` +

      + Bill of Materials (BOMs) -### Bill of Material +A bill of materials (or BOM) helps sync dependency versions of related artifacts. | Component | Description | Artifact ID | Version | Javadoc | |----------------------------------------------|----------------------------------------|---------------------------|-------------------------------------------------------------|---------| | [Bill of Materials (BOM)](./bom) | Bill of materials for stable artifacts | `opentelemetry-bom` | 1.44.1 | N/A | | [Alpha Bill of Materials (BOM)](./bom-alpha) | Bill of materials for alpha artifacts | `opentelemetry-bom-alpha` | 1.44.1-alpha | N/A | +
      -### API +
      + API +The OpenTelemetry API for recording telemetry. | Component | Description | Artifact ID | Version | Javadoc | |-----------------------------------|--------------------------------------------------------------------------------------|-------------------------------|---------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------| | [API](./api/all) | OpenTelemetry API, including metrics, traces, baggage, context | `opentelemetry-api` | 1.44.1 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-api.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-api) | | [API Incubator](./api/incubator) | API incubator, including pass through propagator, and extended tracer, and Event API | `opentelemetry-api-incubator` | 1.44.1 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-api-incubator.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-api-incubator) | | [Context API](./context) | OpenTelemetry context API | `opentelemetry-context` | 1.44.1 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-context.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-context) | +
      -### API Extensions +
      + API Extensions + +Extensions to the OpenTelemetry API. | Component | Description | Artifact ID | Version | Javadoc | |---------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|---------------------------------------------|-------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| | [Kotlin Extension](./extensions/kotlin) | Context extension for coroutines | `opentelemetry-extension-kotlin` | 1.44.1 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-extension-kotlin.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-extension-kotlin) | | [Trace Propagators Extension](./extensions/trace-propagators) | Trace propagators, including B3, Jaeger, OT Trace | `opentelemetry-extension-trace-propagators` | 1.44.1 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-extension-trace-propagators.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-extension-trace-propagators) | +
      + +
      + SDK -### SDK +The OpenTelemetry SDK for managing telemetry producing by the API. | Component | Description | Artifact ID | Version | Javadoc | |------------------------------|--------------------------------------------------------|-----------------------------|---------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------| @@ -259,8 +91,12 @@ dependency as follows, replacing `{{artifact-id}}` with the value from the "Arti | [Log SDK](./sdk/logs) | OpenTelemetry log SDK | `opentelemetry-sdk-logs` | 1.44.1 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-logs.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-logs) | | [SDK Common](./sdk/common) | Shared SDK components | `opentelemetry-sdk-common` | 1.44.1 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-common.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-common) | | [SDK Testing](./sdk/testing) | Components for testing OpenTelemetry instrumentation | `opentelemetry-sdk-testing` | 1.44.1 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-testing.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-testing) | +
      -### SDK Exporters +
      + SDK Exporters + +SDK exporters for shipping traces, metrics, and logs out of process. | Component | Description | Artifact ID | Version | Javadoc | |-----------------------------------------------------------------------|------------------------------------------------------------------------------|------------------------------------------------------|-------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| @@ -274,8 +110,12 @@ dependency as follows, replacing `{{artifact-id}}` with the value from the "Arti | [OkHttp Sender](./exporters/sender/okhttp) | OkHttp implementation of HttpSender (internal) | `opentelemetry-exporter-sender-okhttp` | 1.44.1 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-sender-okhttp.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-sender-okhttp) | | [JDK Sender](./exporters/sender/jdk) | Java 11+ native HttpClient implementation of HttpSender (internal) | `opentelemetry-exporter-sender-jdk` | 1.44.1 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-sender-jdk.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-sender-jdk) | | | [gRPC ManagedChannel Sender](./exporters/sender/grpc-managed-channel) | gRPC ManagedChannel implementation of GrpcSender (internal) | `opentelemetry-exporter-sender-grpc-managed-channel` | 1.44.1 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-sender-grpc-managed-channel.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-sender-grpc-managed-channel) | | +
      + +
      + SDK Extensions -### SDK Extensions +Extensions to the OpenTelemetry SDK. | Component | Description | Artifact ID | Version | Javadoc | |-------------------------------------------------------------------------------|------------------------------------------------------------------------------------|-----------------------------------------------------|-------------------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| @@ -283,17 +123,132 @@ dependency as follows, replacing `{{artifact-id}}` with the value from the "Arti | [SDK Autoconfigure SPI](./sdk-extensions/autoconfigure-spi) | Service Provider Interface (SPI) definitions for autoconfigure | `opentelemetry-sdk-extension-autoconfigure-spi` | 1.44.1 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-extension-autoconfigure-spi.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-extension-autoconfigure-spi) | | [SDK Jaeger Remote Sampler Extension](./sdk-extensions/jaeger-remote-sampler) | Sampler which obtains sampling configuration from remote Jaeger server | `opentelemetry-sdk-extension-jaeger-remote-sampler` | 1.44.1 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-extension-jaeger-remote-sampler.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-extension-jaeger-remote-sampler) | | [SDK Incubator](./sdk-extensions/incubator) | SDK incubator, including YAML based view configuration, LeakDetectingSpanProcessor | `opentelemetry-sdk-extension-incubator` | 1.44.1-alpha | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-extension-incubator.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-extension-incubator) | +
      -### Shims +
      + Shims + +Shims for bridging data from one observability library to another. | Component | Description | Artifact ID | Version | Javadoc | |----------------------------------------|--------------------------------------------------------------|----------------------------------|-------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------| | [OpenCensus Shim](./opencensus-shim) | Bridge opencensus metrics into the OpenTelemetry metrics SDK | `opentelemetry-opencensus-shim` | 1.44.1-alpha | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-opencensus-shim.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-opencensus-shim) | | [OpenTracing Shim](./opentracing-shim) | Bridge opentracing spans into the OpenTelemetry trace API | `opentelemetry-opentracing-shim` | 1.44.1 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-opentracing-shim.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-opentracing-shim) | +
      + +## Dependencies + +To take a dependency, [include a BOM][dependencies-and-boms] and specify the dependency as follows, +replacing `{{artifact-id}}` with the value from the "Artifact ID" column +from [artifacts](#artifacts): + +
      + Gradle + +```groovy + implementation('io.opentelemetry:{{artifact-id}}') +``` +
      + +
      + Maven + +```xml + + io.opentelemetry + {{artifact-id}} + +``` +
      + +### Snapshots + +Snapshots of the `main` branch are available as follows: + +
      + Gradle + +```groovy +repositories { + maven { url 'https://oss.sonatype.org/content/repositories/snapshots' } +} + +dependencies { + implementation platform("io.opentelemetry:opentelemetry-bom:1.45.0-SNAPSHOT") + implementation('io.opentelemetry:opentelemetry-api') +} +``` +
      + +
      + Maven + +```xml + + + + oss.sonatype.org-snapshot + https://oss.sonatype.org/content/repositories/snapshots + + + + + + io.opentelemetry + opentelemetry-bom + 1.45.0-SNAPSHOT + pom + import + + + + + + io.opentelemetry + opentelemetry-api + + + +``` +
      + +## Compatibility + +Artifacts from this repository follow semantic versioning. + +Stable artifacts (i.e. artifacts without `-alpha` version suffix) come with strong backwards +compatibility guarantees for public APIs. + +Artifacts may depend on other artifacts from this repository, and may depend on internal APIs (i.e. +non-public APIs) which are subject to change across minor versions. Therefore, it's critical to keep +artifact versions in sync in order to avoid possible runtime exceptions. We strongly +recommend [using one of our BOMs][dependencies-and-boms] to assist in keeping artifacts in sync. + +See the [VERSIONING.md](VERSIONING.md) for complete details on compatibility policy. + +## Contacting us + +We hold regular meetings. See details at [community page](https://github.com/open-telemetry/community#java-sdk). + +To report a bug, or request a new feature, +please [open an issue](https://github.com/open-telemetry/opentelemetry-java/issues/new/choose). + +We use [GitHub Discussions](https://github.com/open-telemetry/opentelemetry-java/discussions) +for support or general questions. Feel free to drop us a line. + +We are also present in the [`#otel-java`](https://cloud-native.slack.com/archives/C014L2KCTE3) channel in the [CNCF slack](https://slack.cncf.io/). +Please join us for more informal discussions. ## Contributing -See [CONTRIBUTING.md](CONTRIBUTING.md) +See [CONTRIBUTING.md](CONTRIBUTING.md) for: + +* Details on building locally +* Project scope +* Keys to successful PRs +* Guide to using gradle composite builds + +### Code owners Triagers: @@ -335,12 +290,6 @@ Made with [contrib.rocks](https://contrib.rocks). [ci-url]: https://github.com/open-telemetry/opentelemetry-java/actions?query=workflow%3ABuild+branch%3Amain [codecov-image]: https://codecov.io/gh/open-telemetry/opentelemetry-java/branch/main/graph/badge.svg [codecov-url]: https://app.codecov.io/gh/open-telemetry/opentelemetry-java/branch/main/ -[Manual instrumentation]: https://opentelemetry.io/docs/java/manual_instrumentation/ +[dependencies-and-boms]: https://opentelemetry.io/docs/languages/java/intro/#dependencies-and-boms [maven-image]: https://maven-badges.herokuapp.com/maven-central/io.opentelemetry/opentelemetry-api/badge.svg [maven-url]: https://maven-badges.herokuapp.com/maven-central/io.opentelemetry/opentelemetry-api -[opentelemetry-java-instrumentation]: https://github.com/open-telemetry/opentelemetry-java-instrumentation -[opentelemetry-java-examples]: https://github.com/open-telemetry/opentelemetry-java-examples -[opentelemetry-semantic-conventions]: https://opentelemetry.io/docs/specs/semconv/ -[opentelemetry-semantic-conventions-java]: https://github.com/open-telemetry/semantic-conventions-java -[opentelemetry.io]: https://opentelemetry.io -[otel-java-status]: https://opentelemetry.io/docs/instrumentation/java/#status-and-releases From 78565d813b78f1ccceecdfbe421eb09b384e06e1 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 18 Nov 2024 09:22:20 -0600 Subject: [PATCH 665/901] fix(deps): update dependency com.google.api.grpc:proto-google-common-protos to v2.49.0 (#6879) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- dependencyManagement/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index 5d89c61c083..7c1a3ed8786 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -57,7 +57,7 @@ val DEPENDENCIES = listOf( "io.prometheus:simpleclient_httpserver:${prometheusClientVersion}", "javax.annotation:javax.annotation-api:1.3.2", "com.github.stefanbirkner:system-rules:1.19.0", - "com.google.api.grpc:proto-google-common-protos:2.48.0", + "com.google.api.grpc:proto-google-common-protos:2.49.0", "com.google.code.findbugs:jsr305:3.0.2", "com.google.guava:guava-beta-checker:1.0", "com.sun.net.httpserver:http:20070405", From acde5b62f82d814a5fa2868dbee573ae76ae8fbb Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 18 Nov 2024 09:27:32 -0600 Subject: [PATCH 666/901] chore(deps): update gradle/actions action to v4.2.0 (#6873) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/gradle-wrapper-validation.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/gradle-wrapper-validation.yml b/.github/workflows/gradle-wrapper-validation.yml index a268b37d019..8aea611b2ca 100644 --- a/.github/workflows/gradle-wrapper-validation.yml +++ b/.github/workflows/gradle-wrapper-validation.yml @@ -13,4 +13,4 @@ jobs: steps: - uses: actions/checkout@v4 - - uses: gradle/actions/wrapper-validation@v4.1.0 + - uses: gradle/actions/wrapper-validation@v4.2.0 From fb2a47cf76efdc72e5316dbfd2aa859bbd160a79 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 18 Nov 2024 09:33:04 -0600 Subject: [PATCH 667/901] chore(deps): update codecov/codecov-action action to v5 (#6878) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index a7a4430a67e..d1718c5e67c 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -97,7 +97,7 @@ jobs: exit 1 fi - - uses: codecov/codecov-action@v4 + - uses: codecov/codecov-action@v5 if: ${{ matrix.coverage }} env: CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} From b482e76711b2a445e1fae1faa922f31d3a49be63 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 18 Nov 2024 09:49:54 -0600 Subject: [PATCH 668/901] fix(deps): update dependency io.netty:netty-bom to v4.1.115.final (#6872) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- dependencyManagement/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index 7c1a3ed8786..3b68fb5f9e2 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -15,7 +15,7 @@ val DEPENDENCY_BOMS = listOf( "com.squareup.okhttp3:okhttp-bom:4.12.0", "com.squareup.okio:okio-bom:3.9.1", // applies to transitive dependencies of okhttp "io.grpc:grpc-bom:1.68.1", - "io.netty:netty-bom:4.1.114.Final", + "io.netty:netty-bom:4.1.115.Final", "io.zipkin.brave:brave-bom:6.0.3", "io.zipkin.reporter2:zipkin-reporter-bom:3.4.2", "org.assertj:assertj-bom:3.26.3", From 9084a591278b39faae5508743c7723fd71560759 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 18 Nov 2024 09:57:22 -0600 Subject: [PATCH 669/901] fix(deps): update dependency com.linecorp.armeria:armeria-bom to v1.31.0 (#6877) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Co-authored-by: Jack Berg --- dependencyManagement/build.gradle.kts | 2 +- .../testing/internal/AbstractGrpcTelemetryExporterTest.java | 3 ++- .../testing/internal/AbstractHttpTelemetryExporterTest.java | 3 ++- .../trace/jaeger/sampler/JaegerRemoteSamplerTest.java | 3 ++- 4 files changed, 7 insertions(+), 4 deletions(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index 3b68fb5f9e2..3de7cc18b28 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -11,7 +11,7 @@ val DEPENDENCY_BOMS = listOf( "com.fasterxml.jackson:jackson-bom:2.18.1", "com.google.guava:guava-bom:33.3.1-jre", "com.google.protobuf:protobuf-bom:3.25.5", - "com.linecorp.armeria:armeria-bom:1.30.1", + "com.linecorp.armeria:armeria-bom:1.31.0", "com.squareup.okhttp3:okhttp-bom:4.12.0", "com.squareup.okio:okio-bom:3.9.1", // applies to transitive dependencies of okhttp "io.grpc:grpc-bom:1.68.1", diff --git a/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/AbstractGrpcTelemetryExporterTest.java b/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/AbstractGrpcTelemetryExporterTest.java index 4dcacfb329b..1d7086c1c99 100644 --- a/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/AbstractGrpcTelemetryExporterTest.java +++ b/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/AbstractGrpcTelemetryExporterTest.java @@ -16,6 +16,7 @@ import com.google.protobuf.InvalidProtocolBufferException; import com.google.protobuf.Message; import com.linecorp.armeria.common.HttpRequest; +import com.linecorp.armeria.common.TlsKeyPair; import com.linecorp.armeria.common.grpc.protocol.ArmeriaStatusException; import com.linecorp.armeria.server.ServerBuilder; import com.linecorp.armeria.server.ServiceRequestContext; @@ -137,7 +138,7 @@ protected void configure(ServerBuilder sb) { sb.http(0); sb.https(0); - sb.tls(certificate.certificateFile(), certificate.privateKeyFile()); + sb.tls(TlsKeyPair.of(certificate.privateKey(), certificate.certificate())); sb.tlsCustomizer(ssl -> ssl.trustManager(clientCertificate.certificate())); sb.decorator(LoggingService.newDecorator()); } diff --git a/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/AbstractHttpTelemetryExporterTest.java b/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/AbstractHttpTelemetryExporterTest.java index 7f6bfff04b3..3b68738dbe2 100644 --- a/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/AbstractHttpTelemetryExporterTest.java +++ b/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/AbstractHttpTelemetryExporterTest.java @@ -19,6 +19,7 @@ import com.linecorp.armeria.common.HttpStatus; import com.linecorp.armeria.common.MediaType; import com.linecorp.armeria.common.RequestHeaders; +import com.linecorp.armeria.common.TlsKeyPair; import com.linecorp.armeria.server.HttpService; import com.linecorp.armeria.server.ServerBuilder; import com.linecorp.armeria.server.ServiceRequestContext; @@ -144,7 +145,7 @@ protected void configure(ServerBuilder sb) { sb.http(0); sb.https(0); - sb.tls(certificate.certificateFile(), certificate.privateKeyFile()); + sb.tls(TlsKeyPair.of(certificate.privateKey(), certificate.certificate())); sb.tlsCustomizer(ssl -> ssl.trustManager(clientCertificate.certificate())); sb.decorator(LoggingService.newDecorator()); } diff --git a/sdk-extensions/jaeger-remote-sampler/src/test/java/io/opentelemetry/sdk/extension/trace/jaeger/sampler/JaegerRemoteSamplerTest.java b/sdk-extensions/jaeger-remote-sampler/src/test/java/io/opentelemetry/sdk/extension/trace/jaeger/sampler/JaegerRemoteSamplerTest.java index d1b16920e2e..7f81789c129 100644 --- a/sdk-extensions/jaeger-remote-sampler/src/test/java/io/opentelemetry/sdk/extension/trace/jaeger/sampler/JaegerRemoteSamplerTest.java +++ b/sdk-extensions/jaeger-remote-sampler/src/test/java/io/opentelemetry/sdk/extension/trace/jaeger/sampler/JaegerRemoteSamplerTest.java @@ -12,6 +12,7 @@ import static org.junit.jupiter.api.Named.named; import static org.junit.jupiter.params.provider.Arguments.arguments; +import com.linecorp.armeria.common.TlsKeyPair; import com.linecorp.armeria.common.grpc.protocol.ArmeriaStatusException; import com.linecorp.armeria.server.ServerBuilder; import com.linecorp.armeria.server.ServiceRequestContext; @@ -117,7 +118,7 @@ protected CompletionStage handleMessage( }); sb.http(0); sb.https(0); - sb.tls(certificate.certificateFile(), certificate.privateKeyFile()); + sb.tls(TlsKeyPair.of(certificate.privateKey(), certificate.certificate())); sb.tlsCustomizer( ssl -> { ssl.clientAuth(ClientAuth.OPTIONAL); From dbda01ec07e1395ed65e1c36f9e4249407a5e2eb Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 18 Nov 2024 10:05:00 -0600 Subject: [PATCH 670/901] fix(deps): update dependency ru.vyarus:gradle-animalsniffer-plugin to v1.7.2 (#6889) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- buildSrc/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts index 21eb3cecc4b..0baebc9a3f4 100644 --- a/buildSrc/build.gradle.kts +++ b/buildSrc/build.gradle.kts @@ -67,7 +67,7 @@ dependencies { implementation("net.ltgt.gradle:gradle-nullaway-plugin:2.1.0") implementation("org.jetbrains.kotlin:kotlin-gradle-plugin:2.0.21") implementation("org.owasp:dependency-check-gradle:11.1.0") - implementation("ru.vyarus:gradle-animalsniffer-plugin:1.7.1") + implementation("ru.vyarus:gradle-animalsniffer-plugin:1.7.2") } // We can't apply conventions to this build so include important ones such as the Java compilation From 46b2fcda7d994251b0886aa97b8add79ec00f8e2 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 18 Nov 2024 10:33:09 -0600 Subject: [PATCH 671/901] chore(deps): update dependency gradle to v8.11 (#6871) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Co-authored-by: Jack Berg --- .github/workflows/benchmark-tags.yml | 2 +- .github/workflows/benchmark.yml | 2 +- .github/workflows/build.yml | 2 +- gradle/wrapper/gradle-wrapper.properties | 4 ++-- settings.gradle.kts | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/benchmark-tags.yml b/.github/workflows/benchmark-tags.yml index 9953fef010a..955a4bdcd0a 100644 --- a/.github/workflows/benchmark-tags.yml +++ b/.github/workflows/benchmark-tags.yml @@ -55,7 +55,7 @@ jobs: - name: Run jmh run: ./gradlew jmhJar env: - GRADLE_ENTERPRISE_ACCESS_KEY: ${{ secrets.GRADLE_ENTERPRISE_ACCESS_KEY }} + DEVELOCITY_ACCESS_KEY: ${{ secrets.DEVELOCITY_ACCESS_KEY }} - name: Run Benchmark run: | diff --git a/.github/workflows/benchmark.yml b/.github/workflows/benchmark.yml index 7a8160dbca7..bb47139b039 100644 --- a/.github/workflows/benchmark.yml +++ b/.github/workflows/benchmark.yml @@ -25,7 +25,7 @@ jobs: - name: Run jmh run: ./gradlew jmhJar env: - GRADLE_ENTERPRISE_ACCESS_KEY: ${{ secrets.GRADLE_ENTERPRISE_ACCESS_KEY }} + DEVELOCITY_ACCESS_KEY: ${{ secrets.DEVELOCITY_ACCESS_KEY }} - name: Run Benchmark run: | diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index d1718c5e67c..c600b3539ec 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -75,7 +75,7 @@ jobs: "-Porg.gradle.java.installations.paths=${{ steps.setup-java-test.outputs.path }}" "-Porg.gradle.java.installations.auto-download=false" env: - GRADLE_ENTERPRISE_ACCESS_KEY: ${{ secrets.GRADLE_ENTERPRISE_ACCESS_KEY }} + DEVELOCITY_ACCESS_KEY: ${{ secrets.DEVELOCITY_ACCESS_KEY }} # JMH-based tests run only if this environment variable is set to true RUN_JMH_BASED_TESTS: ${{ matrix.jmh-based-tests }} diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index fb602ee2af0..82dd18b2043 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,7 +1,7 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionSha256Sum=31c55713e40233a8303827ceb42ca48a47267a0ad4bab9177123121e71524c26 -distributionUrl=https\://services.gradle.org/distributions/gradle-8.10.2-bin.zip +distributionSha256Sum=57dafb5c2622c6cc08b993c85b7c06956a2f53536432a30ead46166dbca0f1e9 +distributionUrl=https\://services.gradle.org/distributions/gradle-8.11-bin.zip networkTimeout=10000 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME diff --git a/settings.gradle.kts b/settings.gradle.kts index c7a176ef057..199db38a1f1 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -70,7 +70,7 @@ include(":animal-sniffer-signature") val gradleEnterpriseServer = "https://ge.opentelemetry.io" val isCI = System.getenv("CI") != null -val geAccessKey = System.getenv("GRADLE_ENTERPRISE_ACCESS_KEY") ?: "" +val geAccessKey = System.getenv("DEVELOCITY_ACCESS_KEY") ?: "" // if GE access key is not given and we are in CI, then we publish to scans.gradle.com val useScansGradleCom = isCI && geAccessKey.isEmpty() From 4c30ec48d3d8c99aef60a2608042b2b7b5bffd56 Mon Sep 17 00:00:00 2001 From: Xin Date: Mon, 18 Nov 2024 13:41:17 -0700 Subject: [PATCH 672/901] Add convenience method `setAttribute(Attribute, int)` to SpanBuilder (matching the existing convenience method in Span) (#6884) Co-authored-by: Trask Stalnaker --- .../java/io/opentelemetry/api/trace/SpanBuilder.java | 12 ++++++++++++ .../testing/internal/AbstractDefaultTracerTest.java | 2 ++ .../apidiffs/current_vs_latest/opentelemetry-api.txt | 4 +++- .../opentelemetry/sdk/trace/SdkSpanBuilderTest.java | 8 +++++--- 4 files changed, 22 insertions(+), 4 deletions(-) diff --git a/api/all/src/main/java/io/opentelemetry/api/trace/SpanBuilder.java b/api/all/src/main/java/io/opentelemetry/api/trace/SpanBuilder.java index 3b1726933a8..9f9e5c0ce5e 100644 --- a/api/all/src/main/java/io/opentelemetry/api/trace/SpanBuilder.java +++ b/api/all/src/main/java/io/opentelemetry/api/trace/SpanBuilder.java @@ -238,6 +238,18 @@ public interface SpanBuilder { */ SpanBuilder setAttribute(AttributeKey key, T value); + /** + * Sets an attribute to the newly created {@code Span}. If {@code SpanBuilder} previously + * contained a mapping for the key, the old value is replaced by the specified value. + * + * @param key the key for this attribute. + * @param value the value for this attribute. + * @return this. + */ + default SpanBuilder setAttribute(AttributeKey key, int value) { + return setAttribute(key, (long) value); + } + /** * Sets attributes to the {@link SpanBuilder}. If the {@link SpanBuilder} previously contained a * mapping for any of the keys, the old values are replaced by the specified values. diff --git a/api/testing-internal/src/main/java/io/opentelemetry/api/testing/internal/AbstractDefaultTracerTest.java b/api/testing-internal/src/main/java/io/opentelemetry/api/testing/internal/AbstractDefaultTracerTest.java index c90b7da21d9..c03f877f8a6 100644 --- a/api/testing-internal/src/main/java/io/opentelemetry/api/testing/internal/AbstractDefaultTracerTest.java +++ b/api/testing-internal/src/main/java/io/opentelemetry/api/testing/internal/AbstractDefaultTracerTest.java @@ -5,6 +5,7 @@ package io.opentelemetry.api.testing.internal; +import static io.opentelemetry.api.common.AttributeKey.longKey; import static io.opentelemetry.api.common.AttributeKey.stringKey; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatCode; @@ -155,6 +156,7 @@ void doNotCrash_NoopImplementation() { spanBuilder.setStartTimestamp(12345L, TimeUnit.NANOSECONDS); spanBuilder.setStartTimestamp(Instant.EPOCH); spanBuilder.setStartTimestamp(null); + spanBuilder.setAttribute(longKey("MyLongAttributeKey"), 123); assertThat(spanBuilder.startSpan().getSpanContext().isValid()).isFalse(); }) .doesNotThrowAnyException(); diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-api.txt b/docs/apidiffs/current_vs_latest/opentelemetry-api.txt index 351726df140..4bc9a878f22 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-api.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-api.txt @@ -1,2 +1,4 @@ Comparing source compatibility of opentelemetry-api-1.45.0-SNAPSHOT.jar against opentelemetry-api-1.44.1.jar -No changes. \ No newline at end of file +*** MODIFIED INTERFACE: PUBLIC ABSTRACT io.opentelemetry.api.trace.SpanBuilder (not serializable) + === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 + +++ NEW METHOD: PUBLIC(+) io.opentelemetry.api.trace.SpanBuilder setAttribute(io.opentelemetry.api.common.AttributeKey, int) diff --git a/sdk/trace/src/test/java/io/opentelemetry/sdk/trace/SdkSpanBuilderTest.java b/sdk/trace/src/test/java/io/opentelemetry/sdk/trace/SdkSpanBuilderTest.java index 461ed774cca..9c9ecdc7e9c 100644 --- a/sdk/trace/src/test/java/io/opentelemetry/sdk/trace/SdkSpanBuilderTest.java +++ b/sdk/trace/src/test/java/io/opentelemetry/sdk/trace/SdkSpanBuilderTest.java @@ -246,19 +246,21 @@ void setAttribute() { .setAttribute("long", 12345L) .setAttribute("double", .12345) .setAttribute("boolean", true) - .setAttribute(stringKey("stringAttribute"), "attrvalue"); + .setAttribute(stringKey("stringAttribute"), "attrvalue") + .setAttribute(longKey("longAttribute"), 123); SdkSpan span = (SdkSpan) spanBuilder.startSpan(); try { SpanData spanData = span.toSpanData(); Attributes attrs = spanData.getAttributes(); - assertThat(attrs.size()).isEqualTo(5); + assertThat(attrs.size()).isEqualTo(6); assertThat(attrs.get(stringKey("string"))).isEqualTo("value"); assertThat(attrs.get(longKey("long"))).isEqualTo(12345L); assertThat(attrs.get(doubleKey("double"))).isEqualTo(0.12345); assertThat(attrs.get(booleanKey("boolean"))).isEqualTo(true); assertThat(attrs.get(stringKey("stringAttribute"))).isEqualTo("attrvalue"); - assertThat(spanData.getTotalAttributeCount()).isEqualTo(5); + assertThat(attrs.get(longKey("longAttribute"))).isEqualTo(123); + assertThat(spanData.getTotalAttributeCount()).isEqualTo(6); } finally { span.end(); } From 26f359b3e9a0b9c3c98d7b48aea35db4b5ede90a Mon Sep 17 00:00:00 2001 From: Ravishankar Nagendran Date: Mon, 18 Nov 2024 13:59:28 -0700 Subject: [PATCH 673/901] Add javadoc boilerplate internal comment v2 for experimental classes (#6886) Co-authored-by: Trask Stalnaker --- .../customchecks/OtelInternalJavadoc.java | 17 +++++++++++++---- .../internal/InternalJavadocPositiveCases.java | 6 +++--- .../sdk/logs/internal/LoggerConfig.java | 5 +++-- .../logs/internal/SdkEventLoggerProvider.java | 5 +++-- .../sdk/metrics/internal/MeterConfig.java | 5 +++-- .../metrics/internal/SdkMeterProviderUtil.java | 5 +++-- .../trace/internal/SdkTracerProviderUtil.java | 5 +++-- .../sdk/trace/internal/TracerConfig.java | 5 +++-- 8 files changed, 34 insertions(+), 19 deletions(-) diff --git a/custom-checks/src/main/java/io/opentelemetry/gradle/customchecks/OtelInternalJavadoc.java b/custom-checks/src/main/java/io/opentelemetry/gradle/customchecks/OtelInternalJavadoc.java index 3ac6b964dac..0cc97d45abc 100644 --- a/custom-checks/src/main/java/io/opentelemetry/gradle/customchecks/OtelInternalJavadoc.java +++ b/custom-checks/src/main/java/io/opentelemetry/gradle/customchecks/OtelInternalJavadoc.java @@ -21,8 +21,10 @@ @BugPattern( summary = - "This public internal class doesn't end with the javadoc disclaimer: \"" - + OtelInternalJavadoc.EXPECTED_INTERNAL_COMMENT + "This public internal class doesn't end with any of the applicable javadoc disclaimers: \"" + + OtelInternalJavadoc.EXPECTED_INTERNAL_COMMENT_V1 + + "\", or \"" + + OtelInternalJavadoc.EXPECTED_INTERNAL_COMMENT_V2 + "\"", severity = WARNING) public class OtelInternalJavadoc extends BugChecker implements BugChecker.ClassTreeMatcher { @@ -31,17 +33,24 @@ public class OtelInternalJavadoc extends BugChecker implements BugChecker.ClassT private static final Pattern INTERNAL_PACKAGE_PATTERN = Pattern.compile("\\binternal\\b"); - static final String EXPECTED_INTERNAL_COMMENT = + static final String EXPECTED_INTERNAL_COMMENT_V1 = "This class is internal and is hence not for public use." + " Its APIs are unstable and can change at any time."; + static final String EXPECTED_INTERNAL_COMMENT_V2 = + "This class is internal and experimental. Its APIs are unstable and can change at any time." + + " Its APIs (or a version of them) may be promoted to the public stable API in the" + + " future, but no guarantees are made."; + @Override public Description matchClass(ClassTree tree, VisitorState state) { if (!isPublic(tree) || !isInternal(state) || tree.getSimpleName().toString().endsWith("Test")) { return Description.NO_MATCH; } String javadoc = getJavadoc(state); - if (javadoc != null && javadoc.contains(EXPECTED_INTERNAL_COMMENT)) { + if (javadoc != null + && (javadoc.contains(EXPECTED_INTERNAL_COMMENT_V1) + || javadoc.contains(EXPECTED_INTERNAL_COMMENT_V2))) { return Description.NO_MATCH; } return describeMatch(tree); diff --git a/custom-checks/src/test/resources/io/opentelemetry/gradle/customchecks/internal/InternalJavadocPositiveCases.java b/custom-checks/src/test/resources/io/opentelemetry/gradle/customchecks/internal/InternalJavadocPositiveCases.java index dc36e5ef636..f7a3042e4d6 100644 --- a/custom-checks/src/test/resources/io/opentelemetry/gradle/customchecks/internal/InternalJavadocPositiveCases.java +++ b/custom-checks/src/test/resources/io/opentelemetry/gradle/customchecks/internal/InternalJavadocPositiveCases.java @@ -5,13 +5,13 @@ package io.opentelemetry.gradle.customchecks.internal; -// BUG: Diagnostic contains: doesn't end with the javadoc disclaimer +// BUG: Diagnostic contains: doesn't end with any of the applicable javadoc disclaimers public class InternalJavadocPositiveCases { - // BUG: Diagnostic contains: doesn't end with the javadoc disclaimer + // BUG: Diagnostic contains: doesn't end with any of the applicable javadoc disclaimers public static class One {} /** Doesn't have the disclaimer. */ - // BUG: Diagnostic contains: doesn't end with the javadoc disclaimer + // BUG: Diagnostic contains: doesn't end with any of the applicable javadoc disclaimers public static class Two {} } diff --git a/sdk/logs/src/main/java/io/opentelemetry/sdk/logs/internal/LoggerConfig.java b/sdk/logs/src/main/java/io/opentelemetry/sdk/logs/internal/LoggerConfig.java index 8fb0f7dac2e..00ffdc86b41 100644 --- a/sdk/logs/src/main/java/io/opentelemetry/sdk/logs/internal/LoggerConfig.java +++ b/sdk/logs/src/main/java/io/opentelemetry/sdk/logs/internal/LoggerConfig.java @@ -17,8 +17,9 @@ /** * A collection of configuration options which define the behavior of a {@link Logger}. * - *

      This class is internal and is hence not for public use. Its APIs are unstable and can change - * at any time. + *

      This class is internal and experimental. Its APIs are unstable and can change at any time. Its + * APIs (or a version of them) may be promoted to the public stable API in the future, but no + * guarantees are made. * * @see SdkLoggerProviderUtil#setLoggerConfigurator(SdkLoggerProviderBuilder, ScopeConfigurator) * @see SdkLoggerProviderUtil#addLoggerConfiguratorCondition(SdkLoggerProviderBuilder, Predicate, diff --git a/sdk/logs/src/main/java/io/opentelemetry/sdk/logs/internal/SdkEventLoggerProvider.java b/sdk/logs/src/main/java/io/opentelemetry/sdk/logs/internal/SdkEventLoggerProvider.java index 7a2972056a3..d198675f552 100644 --- a/sdk/logs/src/main/java/io/opentelemetry/sdk/logs/internal/SdkEventLoggerProvider.java +++ b/sdk/logs/src/main/java/io/opentelemetry/sdk/logs/internal/SdkEventLoggerProvider.java @@ -22,8 +22,9 @@ *

      Delegates all calls to the configured {@link LoggerProvider}, and its {@link LoggerBuilder}s, * {@link Logger}s. * - *

      This class is internal and is hence not for public use. Its APIs are unstable and can change - * at any time. + *

      This class is internal and experimental. Its APIs are unstable and can change at any time. Its + * APIs (or a version of them) may be promoted to the public stable API in the future, but no + * guarantees are made. */ public final class SdkEventLoggerProvider implements EventLoggerProvider { diff --git a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/MeterConfig.java b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/MeterConfig.java index ededd6acdad..35981025071 100644 --- a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/MeterConfig.java +++ b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/MeterConfig.java @@ -17,8 +17,9 @@ /** * A collection of configuration options which define the behavior of a {@link Meter}. * - *

      This class is internal and is hence not for public use. Its APIs are unstable and can change - * at any time. + *

      This class is internal and experimental. Its APIs are unstable and can change at any time. Its + * APIs (or a version of them) may be promoted to the public stable API in the future, but no + * guarantees are made. * * @see SdkMeterProviderUtil#setMeterConfigurator(SdkMeterProviderBuilder, ScopeConfigurator) * @see SdkMeterProviderUtil#addMeterConfiguratorCondition(SdkMeterProviderBuilder, Predicate, diff --git a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/SdkMeterProviderUtil.java b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/SdkMeterProviderUtil.java index c559fc4c76f..1b203d9d9a2 100644 --- a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/SdkMeterProviderUtil.java +++ b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/SdkMeterProviderUtil.java @@ -21,8 +21,9 @@ * A collection of methods that allow use of experimental features prior to availability in public * APIs. * - *

      This class is internal and is hence not for public use. Its APIs are unstable and can change - * at any time. + *

      This class is internal and experimental. Its APIs are unstable and can change at any time. Its + * APIs (or a version of them) may be promoted to the public stable API in the future, but no + * guarantees are made. */ public final class SdkMeterProviderUtil { diff --git a/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/internal/SdkTracerProviderUtil.java b/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/internal/SdkTracerProviderUtil.java index 7d00f230dea..76111258a67 100644 --- a/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/internal/SdkTracerProviderUtil.java +++ b/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/internal/SdkTracerProviderUtil.java @@ -16,8 +16,9 @@ * A collection of methods that allow use of experimental features prior to availability in public * APIs. * - *

      This class is internal and is hence not for public use. Its APIs are unstable and can change - * at any time. + *

      This class is internal and experimental. Its APIs are unstable and can change at any time. Its + * APIs (or a version of them) may be promoted to the public stable API in the future, but no + * guarantees are made. */ public final class SdkTracerProviderUtil { diff --git a/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/internal/TracerConfig.java b/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/internal/TracerConfig.java index 535760cbfd4..4fa8c702b1c 100644 --- a/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/internal/TracerConfig.java +++ b/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/internal/TracerConfig.java @@ -17,8 +17,9 @@ /** * A collection of configuration options which define the behavior of a {@link Tracer}. * - *

      This class is internal and is hence not for public use. Its APIs are unstable and can change - * at any time. + *

      This class is internal and experimental. Its APIs are unstable and can change at any time. Its + * APIs (or a version of them) may be promoted to the public stable API in the future, but no + * guarantees are made. * * @see SdkTracerProviderUtil#setTracerConfigurator(SdkTracerProviderBuilder, ScopeConfigurator) * @see SdkTracerProviderUtil#addTracerConfiguratorCondition(SdkTracerProviderBuilder, Predicate, From ec3c55ffebb63add2cc142ec53fa22985a4f1688 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 18 Nov 2024 15:53:37 -0600 Subject: [PATCH 674/901] chore(deps): update gradle/actions action to v4.2.1 (#6890) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/gradle-wrapper-validation.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/gradle-wrapper-validation.yml b/.github/workflows/gradle-wrapper-validation.yml index 8aea611b2ca..9959faf2be1 100644 --- a/.github/workflows/gradle-wrapper-validation.yml +++ b/.github/workflows/gradle-wrapper-validation.yml @@ -13,4 +13,4 @@ jobs: steps: - uses: actions/checkout@v4 - - uses: gradle/actions/wrapper-validation@v4.2.0 + - uses: gradle/actions/wrapper-validation@v4.2.1 From 2a97eaedc55ee4d5edc6f1e998af89d29ddb554d Mon Sep 17 00:00:00 2001 From: Saurabh Lodha Date: Mon, 18 Nov 2024 14:54:40 -0700 Subject: [PATCH 675/901] Add synchronization to SimpleLogRecordProcessor and SimpleSpanProcessor to ensure thread-safe export of logs and spans respectively (#6885) --- .../sdk/logs/export/SimpleLogRecordProcessor.java | 9 ++++++++- .../sdk/trace/export/SimpleSpanProcessor.java | 9 ++++++++- 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/sdk/logs/src/main/java/io/opentelemetry/sdk/logs/export/SimpleLogRecordProcessor.java b/sdk/logs/src/main/java/io/opentelemetry/sdk/logs/export/SimpleLogRecordProcessor.java index 5302212345e..cc75b50ae1f 100644 --- a/sdk/logs/src/main/java/io/opentelemetry/sdk/logs/export/SimpleLogRecordProcessor.java +++ b/sdk/logs/src/main/java/io/opentelemetry/sdk/logs/export/SimpleLogRecordProcessor.java @@ -41,6 +41,8 @@ public final class SimpleLogRecordProcessor implements LogRecordProcessor { Collections.newSetFromMap(new ConcurrentHashMap<>()); private final AtomicBoolean isShutdown = new AtomicBoolean(false); + private final Object exporterLock = new Object(); + /** * Returns a new {@link SimpleLogRecordProcessor} which exports logs to the {@link * LogRecordExporter} synchronously. @@ -64,7 +66,12 @@ private SimpleLogRecordProcessor(LogRecordExporter logRecordExporter) { public void onEmit(Context context, ReadWriteLogRecord logRecord) { try { List logs = Collections.singletonList(logRecord.toLogRecordData()); - CompletableResultCode result = logRecordExporter.export(logs); + CompletableResultCode result; + + synchronized (exporterLock) { + result = logRecordExporter.export(logs); + } + pendingExports.add(result); result.whenComplete( () -> { diff --git a/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/export/SimpleSpanProcessor.java b/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/export/SimpleSpanProcessor.java index 68b197a4b5b..f543e25353e 100644 --- a/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/export/SimpleSpanProcessor.java +++ b/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/export/SimpleSpanProcessor.java @@ -41,6 +41,8 @@ public final class SimpleSpanProcessor implements SpanProcessor { Collections.newSetFromMap(new ConcurrentHashMap<>()); private final AtomicBoolean isShutdown = new AtomicBoolean(false); + private final Object exporterLock = new Object(); + /** * Returns a new {@link SimpleSpanProcessor} which exports spans to the {@link SpanExporter} * synchronously. @@ -86,7 +88,12 @@ public void onEnd(ReadableSpan span) { if (span != null && (exportUnsampledSpans || span.getSpanContext().isSampled())) { try { List spans = Collections.singletonList(span.toSpanData()); - CompletableResultCode result = spanExporter.export(spans); + CompletableResultCode result; + + synchronized (exporterLock) { + result = spanExporter.export(spans); + } + pendingExports.add(result); result.whenComplete( () -> { From cde3d45f0426de18f2a61e99449021c022c89cea Mon Sep 17 00:00:00 2001 From: jack-berg <34418638+jack-berg@users.noreply.github.com> Date: Mon, 18 Nov 2024 15:55:00 -0600 Subject: [PATCH 676/901] Don't require empty objects when referencing custom components (#6891) --- .../fileconfig/FileConfiguration.java | 4 ++++ .../FileConfigurationCreateTest.java | 19 +++++++++++++++++++ 2 files changed, 23 insertions(+) diff --git a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/FileConfiguration.java b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/FileConfiguration.java index e4004516b73..b8af0237188 100644 --- a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/FileConfiguration.java +++ b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/FileConfiguration.java @@ -21,6 +21,7 @@ import java.io.IOException; import java.io.InputStream; import java.util.ArrayList; +import java.util.Collections; import java.util.List; import java.util.Map; import java.util.logging.Logger; @@ -166,6 +167,9 @@ static StructuredConfigProperties toConfigProperties( Object model, ComponentLoader componentLoader) { Map configurationMap = MAPPER.convertValue(model, new TypeReference>() {}); + if (configurationMap == null) { + configurationMap = Collections.emptyMap(); + } return YamlStructuredConfigProperties.create(configurationMap, componentLoader); } diff --git a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/FileConfigurationCreateTest.java b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/FileConfigurationCreateTest.java index 1230ce73832..54f91614df7 100644 --- a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/FileConfigurationCreateTest.java +++ b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/FileConfigurationCreateTest.java @@ -130,4 +130,23 @@ void parseAndCreate_Exception_CleansUpPartials() { "Closing io.opentelemetry.exporter.otlp.http.logs.OtlpHttpLogRecordExporter"); logCapturer.assertContains("Closing io.opentelemetry.sdk.logs.export.BatchLogRecordProcessor"); } + + @Test + void parseAndCreate_EmptyComponentProviderConfig() { + String yaml = + "file_format: \"0.3\"\n" + + "logger_provider:\n" + + " processors:\n" + + " - test:\n" + + "tracer_provider:\n" + + " processors:\n" + + " - test:\n"; + + assertThatCode( + () -> + FileConfiguration.parseAndCreate( + new ByteArrayInputStream(yaml.getBytes(StandardCharsets.UTF_8)))) + .doesNotThrowAnyException(); + ; + } } From e0a6e64fc765cbe95ffe29ee4b90cbcf2e12b4ad Mon Sep 17 00:00:00 2001 From: Eugene Ma Date: Mon, 18 Nov 2024 13:56:03 -0800 Subject: [PATCH 677/901] lazily initialize ReservoirCells (#6851) Co-authored-by: jack-berg <34418638+jack-berg@users.noreply.github.com> --- .../exemplar/FixedSizeExemplarReservoir.java | 28 +++++++++++++++---- 1 file changed, 22 insertions(+), 6 deletions(-) diff --git a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/exemplar/FixedSizeExemplarReservoir.java b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/exemplar/FixedSizeExemplarReservoir.java index 05dfdd1afd3..20254de5991 100644 --- a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/exemplar/FixedSizeExemplarReservoir.java +++ b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/exemplar/FixedSizeExemplarReservoir.java @@ -13,13 +13,16 @@ import java.util.Collections; import java.util.List; import java.util.function.BiFunction; +import javax.annotation.Nullable; /** Base for fixed-size reservoir sampling of Exemplars. */ abstract class FixedSizeExemplarReservoir implements ExemplarReservoir { - private final ReservoirCell[] storage; + @Nullable private ReservoirCell[] storage; private final ReservoirCellSelector reservoirCellSelector; private final BiFunction mapAndResetCell; + private final int size; + private final Clock clock; private volatile boolean hasMeasurements = false; /** Instantiates an exemplar reservoir of fixed size. */ @@ -28,16 +31,18 @@ abstract class FixedSizeExemplarReservoir implements Exe int size, ReservoirCellSelector reservoirCellSelector, BiFunction mapAndResetCell) { - this.storage = new ReservoirCell[size]; - for (int i = 0; i < size; ++i) { - this.storage[i] = new ReservoirCell(clock); - } + this.storage = null; // lazily initialize to avoid allocations + this.size = size; + this.clock = clock; this.reservoirCellSelector = reservoirCellSelector; this.mapAndResetCell = mapAndResetCell; } @Override public void offerLongMeasurement(long value, Attributes attributes, Context context) { + if (storage == null) { + storage = initStorage(); + } int bucket = reservoirCellSelector.reservoirCellIndexFor(storage, value, attributes, context); if (bucket != -1) { this.storage[bucket].recordLongMeasurement(value, attributes, context); @@ -47,6 +52,9 @@ public void offerLongMeasurement(long value, Attributes attributes, Context cont @Override public void offerDoubleMeasurement(double value, Attributes attributes, Context context) { + if (storage == null) { + storage = initStorage(); + } int bucket = reservoirCellSelector.reservoirCellIndexFor(storage, value, attributes, context); if (bucket != -1) { this.storage[bucket].recordDoubleMeasurement(value, attributes, context); @@ -54,9 +62,17 @@ public void offerDoubleMeasurement(double value, Attributes attributes, Context } } + private ReservoirCell[] initStorage() { + ReservoirCell[] storage = new ReservoirCell[this.size]; + for (int i = 0; i < size; ++i) { + storage[i] = new ReservoirCell(this.clock); + } + return storage; + } + @Override public List collectAndReset(Attributes pointAttributes) { - if (!hasMeasurements) { + if (!hasMeasurements || storage == null) { return Collections.emptyList(); } // Note: we are collecting exemplars from buckets piecemeal, but we From 8d6578fbe87c12601405b7d002d6fb2825deaf61 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 19 Nov 2024 14:59:52 -0600 Subject: [PATCH 678/901] fix(deps): update errorproneversion to v2.36.0 (#6894) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- dependencyManagement/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index 3de7cc18b28..4f5b49e3dc4 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -25,7 +25,7 @@ val DEPENDENCY_BOMS = listOf( ) val autoValueVersion = "1.11.0" -val errorProneVersion = "2.35.1" +val errorProneVersion = "2.36.0" val jmhVersion = "1.37" // Mockito 5.x.x requires Java 11 https://github.com/mockito/mockito/releases/tag/v5.0.0 val mockitoVersion = "4.11.0" From 7d74adafdc66615c122a4d06b156eb93366f0986 Mon Sep 17 00:00:00 2001 From: jack-berg <34418638+jack-berg@users.noreply.github.com> Date: Wed, 20 Nov 2024 10:59:08 -0600 Subject: [PATCH 679/901] Rename Marshaler#writeJsonToGenerator to allow jackson runtimeOnly dependency (#6896) --- .../opentelemetry/exporter/internal/marshal/Marshaler.java | 5 ++++- .../logging/otlp/internal/writer/LoggerJsonWriter.java | 2 +- .../logging/otlp/internal/writer/LoggerJsonWriterTest.java | 4 +++- 3 files changed, 8 insertions(+), 3 deletions(-) diff --git a/exporters/common/src/main/java/io/opentelemetry/exporter/internal/marshal/Marshaler.java b/exporters/common/src/main/java/io/opentelemetry/exporter/internal/marshal/Marshaler.java index 6201481c024..e942673da13 100644 --- a/exporters/common/src/main/java/io/opentelemetry/exporter/internal/marshal/Marshaler.java +++ b/exporters/common/src/main/java/io/opentelemetry/exporter/internal/marshal/Marshaler.java @@ -32,7 +32,10 @@ public final void writeJsonTo(OutputStream output) throws IOException { } /** Marshals into the {@link JsonGenerator} in proto JSON format. */ - public final void writeJsonTo(JsonGenerator output) throws IOException { + // Intentionally not overloading writeJsonTo(OutputStream) in order to avoid compilation + // dependency on jackson when using writeJsonTo(OutputStream). See: + // https://github.com/open-telemetry/opentelemetry-java-contrib/pull/1551#discussion_r1849064365 + public final void writeJsonToGenerator(JsonGenerator output) throws IOException { try (JsonSerializer serializer = new JsonSerializer(output)) { serializer.writeMessageValue(this); } diff --git a/exporters/logging-otlp/src/main/java/io/opentelemetry/exporter/logging/otlp/internal/writer/LoggerJsonWriter.java b/exporters/logging-otlp/src/main/java/io/opentelemetry/exporter/logging/otlp/internal/writer/LoggerJsonWriter.java index 1286e116f03..a95c5e0d2c1 100644 --- a/exporters/logging-otlp/src/main/java/io/opentelemetry/exporter/logging/otlp/internal/writer/LoggerJsonWriter.java +++ b/exporters/logging-otlp/src/main/java/io/opentelemetry/exporter/logging/otlp/internal/writer/LoggerJsonWriter.java @@ -33,7 +33,7 @@ public LoggerJsonWriter(Logger logger, String type) { public CompletableResultCode write(Marshaler exportRequest) { SegmentedStringWriter sw = new SegmentedStringWriter(JSON_FACTORY._getBufferRecycler()); try (JsonGenerator gen = JsonUtil.create(sw)) { - exportRequest.writeJsonTo(gen); + exportRequest.writeJsonToGenerator(gen); } catch (IOException e) { logger.log(Level.WARNING, "Unable to write OTLP JSON " + type, e); return CompletableResultCode.ofFailure(); diff --git a/exporters/logging-otlp/src/test/java/io/opentelemetry/exporter/logging/otlp/internal/writer/LoggerJsonWriterTest.java b/exporters/logging-otlp/src/test/java/io/opentelemetry/exporter/logging/otlp/internal/writer/LoggerJsonWriterTest.java index 8cba4ef9707..0810f3c7510 100644 --- a/exporters/logging-otlp/src/test/java/io/opentelemetry/exporter/logging/otlp/internal/writer/LoggerJsonWriterTest.java +++ b/exporters/logging-otlp/src/test/java/io/opentelemetry/exporter/logging/otlp/internal/writer/LoggerJsonWriterTest.java @@ -32,7 +32,9 @@ void testToString() { @Test void error() throws IOException { Marshaler marshaler = mock(Marshaler.class); - Mockito.doThrow(new IOException("test")).when(marshaler).writeJsonTo(any(JsonGenerator.class)); + Mockito.doThrow(new IOException("test")) + .when(marshaler) + .writeJsonToGenerator(any(JsonGenerator.class)); Logger logger = Logger.getLogger(LoggerJsonWriter.class.getName()); From bab9fb9cdb353bbcb27f18c250e61724a4cfc14e Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 21 Nov 2024 10:15:20 -0600 Subject: [PATCH 680/901] chore(deps): update dependency gradle to v8.11.1 (#6897) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- gradle/wrapper/gradle-wrapper.properties | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 82dd18b2043..eb1a55be0e1 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,7 +1,7 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionSha256Sum=57dafb5c2622c6cc08b993c85b7c06956a2f53536432a30ead46166dbca0f1e9 -distributionUrl=https\://services.gradle.org/distributions/gradle-8.11-bin.zip +distributionSha256Sum=f397b287023acdba1e9f6fc5ea72d22dd63669d59ed4a289a29b1a76eee151c6 +distributionUrl=https\://services.gradle.org/distributions/gradle-8.11.1-bin.zip networkTimeout=10000 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME From d2e56b59c6b9896de4dac221a62064ec039a68d7 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 22 Nov 2024 10:13:57 -0600 Subject: [PATCH 681/901] fix(deps): update dependency com.linecorp.armeria:armeria-bom to v1.31.1 (#6902) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- dependencyManagement/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index 4f5b49e3dc4..0d39780a120 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -11,7 +11,7 @@ val DEPENDENCY_BOMS = listOf( "com.fasterxml.jackson:jackson-bom:2.18.1", "com.google.guava:guava-bom:33.3.1-jre", "com.google.protobuf:protobuf-bom:3.25.5", - "com.linecorp.armeria:armeria-bom:1.31.0", + "com.linecorp.armeria:armeria-bom:1.31.1", "com.squareup.okhttp3:okhttp-bom:4.12.0", "com.squareup.okio:okio-bom:3.9.1", // applies to transitive dependencies of okhttp "io.grpc:grpc-bom:1.68.1", From c71bd9dfd5a2fb5d086e5656f0c7115d75622e65 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 22 Nov 2024 10:14:09 -0600 Subject: [PATCH 682/901] fix(deps): update dependency org.testcontainers:testcontainers-bom to v1.20.4 (#6898) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- dependencyManagement/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index 0d39780a120..a5ac0ab369a 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -20,7 +20,7 @@ val DEPENDENCY_BOMS = listOf( "io.zipkin.reporter2:zipkin-reporter-bom:3.4.2", "org.assertj:assertj-bom:3.26.3", "org.junit:junit-bom:5.11.3", - "org.testcontainers:testcontainers-bom:1.20.3", + "org.testcontainers:testcontainers-bom:1.20.4", "org.snakeyaml:snakeyaml-engine:2.8" ) From 6487ac2976a26422836d59c2dfdc63fe2fee8bf3 Mon Sep 17 00:00:00 2001 From: Trask Stalnaker Date: Sun, 24 Nov 2024 10:14:59 -0800 Subject: [PATCH 683/901] Remove outdated commented out code (#6904) --- buildSrc/src/main/kotlin/otel.java-conventions.gradle.kts | 6 ------ 1 file changed, 6 deletions(-) diff --git a/buildSrc/src/main/kotlin/otel.java-conventions.gradle.kts b/buildSrc/src/main/kotlin/otel.java-conventions.gradle.kts index 8d75dc8e36b..b76363f8f12 100644 --- a/buildSrc/src/main/kotlin/otel.java-conventions.gradle.kts +++ b/buildSrc/src/main/kotlin/otel.java-conventions.gradle.kts @@ -134,12 +134,6 @@ tasks { breakIterator(true) addBooleanOption("html5", true) - - // TODO (trask) revisit to see if url is fixed - // currently broken because https://docs.oracle.com/javase/8/docs/api/element-list is missing - // and redirects - // links("https://docs.oracle.com/javase/8/docs/api/") - addBooleanOption("Xdoclint:all,-missing", true) } } From 8a3329be4d6d5e1d164d6c72e5c84f52b8b91b37 Mon Sep 17 00:00:00 2001 From: Josh Suereth Date: Mon, 25 Nov 2024 10:19:35 -0500 Subject: [PATCH 684/901] Fix repeated string serialization for JSON. (#6888) Co-authored-by: Jack Berg --- .../internal/marshal/JsonSerializer.java | 16 ++++++++++++++++ .../internal/marshal/MarshalerUtil.java | 10 ++++++++++ .../internal/marshal/ProtoSerializer.java | 7 +++++++ .../exporter/internal/marshal/Serializer.java | 17 +++++++++++++++++ .../otlp/profiles/ProfileMarshaler.java | 8 ++------ .../profiles/ProfilesRequestMarshalerTest.java | 4 +++- 6 files changed, 55 insertions(+), 7 deletions(-) diff --git a/exporters/common/src/main/java/io/opentelemetry/exporter/internal/marshal/JsonSerializer.java b/exporters/common/src/main/java/io/opentelemetry/exporter/internal/marshal/JsonSerializer.java index 680220b5e3e..6170e1925d2 100644 --- a/exporters/common/src/main/java/io/opentelemetry/exporter/internal/marshal/JsonSerializer.java +++ b/exporters/common/src/main/java/io/opentelemetry/exporter/internal/marshal/JsonSerializer.java @@ -122,6 +122,22 @@ public void writeString( generator.writeString(string); } + @Override + public void writeRepeatedString(ProtoFieldInfo field, byte[][] utf8Bytes) throws IOException { + generator.writeArrayFieldStart(field.getJsonName()); + for (byte[] value : utf8Bytes) { + // Marshalers encoded String into UTF-8 bytes to optimize for binary serialization where + // we are able to avoid the encoding process happening twice, one for size computation and one + // for actual writing. JsonGenerator actually has a writeUTF8String that would be able to + // accept + // this, but it only works when writing to an OutputStream, but not to a String like we do for + // writing to logs. It's wasteful to take a String, convert it to bytes, and convert back to + // the same String but we can see if this can be improved in the future. + generator.writeString(new String(value, StandardCharsets.UTF_8)); + } + generator.writeEndArray(); + } + @Override public void writeBytes(ProtoFieldInfo field, byte[] value) throws IOException { generator.writeBinaryField(field.getJsonName(), value); diff --git a/exporters/common/src/main/java/io/opentelemetry/exporter/internal/marshal/MarshalerUtil.java b/exporters/common/src/main/java/io/opentelemetry/exporter/internal/marshal/MarshalerUtil.java index d7f6d44c871..92db2fa4271 100644 --- a/exporters/common/src/main/java/io/opentelemetry/exporter/internal/marshal/MarshalerUtil.java +++ b/exporters/common/src/main/java/io/opentelemetry/exporter/internal/marshal/MarshalerUtil.java @@ -110,6 +110,16 @@ private static int sizeRepeatedFixed64(ProtoFieldInfo field, int numValues) { return size; } + /** Returns the size of a repeated string field. */ + @SuppressWarnings("AvoidObjectArrays") + public static int sizeRepeatedString(ProtoFieldInfo field, byte[][] utf8Bytes) { + int size = 0; + for (byte[] i : utf8Bytes) { + size += MarshalerUtil.sizeBytes(field, i); + } + return size; + } + /** * Returns the size of a repeated uint64 field. * diff --git a/exporters/common/src/main/java/io/opentelemetry/exporter/internal/marshal/ProtoSerializer.java b/exporters/common/src/main/java/io/opentelemetry/exporter/internal/marshal/ProtoSerializer.java index 62f4a175982..694cec8b2b9 100644 --- a/exporters/common/src/main/java/io/opentelemetry/exporter/internal/marshal/ProtoSerializer.java +++ b/exporters/common/src/main/java/io/opentelemetry/exporter/internal/marshal/ProtoSerializer.java @@ -163,6 +163,13 @@ public void writeString( StatelessMarshalerUtil.writeUtf8(output, string, utf8Length, context); } + @Override + public void writeRepeatedString(ProtoFieldInfo field, byte[][] utf8Bytes) throws IOException { + for (byte[] value : utf8Bytes) { + writeString(field, value); + } + } + @Override public void writeBytes(ProtoFieldInfo field, byte[] value) throws IOException { output.writeUInt32NoTag(field.getTag()); diff --git a/exporters/common/src/main/java/io/opentelemetry/exporter/internal/marshal/Serializer.java b/exporters/common/src/main/java/io/opentelemetry/exporter/internal/marshal/Serializer.java index e7970d57491..069fa3a6b58 100644 --- a/exporters/common/src/main/java/io/opentelemetry/exporter/internal/marshal/Serializer.java +++ b/exporters/common/src/main/java/io/opentelemetry/exporter/internal/marshal/Serializer.java @@ -220,6 +220,18 @@ public void serializeString(ProtoFieldInfo field, byte[] utf8Bytes) throws IOExc writeString(field, utf8Bytes); } + /** + * Serializes a protobuf {@code repeated string} field. {@code utf8Bytes} is the UTF8 encoded + * bytes of the strings to serialize. + */ + @SuppressWarnings("AvoidObjectArrays") + public void serializeRepeatedString(ProtoFieldInfo field, byte[][] utf8Bytes) throws IOException { + if (utf8Bytes.length == 0) { + return; + } + writeRepeatedString(field, utf8Bytes); + } + /** * Serializes a protobuf {@code string} field. {@code string} is the value to be serialized and * {@code utf8Length} is the length of the string after it is encoded in UTF8. This method reads @@ -246,6 +258,11 @@ public abstract void writeString( ProtoFieldInfo field, String string, int utf8Length, MarshalerContext context) throws IOException; + /** Writes a protobuf {@code repeated string} field, even if it matches the default value. */ + @SuppressWarnings("AvoidObjectArrays") + public abstract void writeRepeatedString(ProtoFieldInfo field, byte[][] utf8Bytes) + throws IOException; + /** Serializes a protobuf {@code bytes} field. */ public void serializeBytes(ProtoFieldInfo field, byte[] value) throws IOException { if (value.length == 0) { diff --git a/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/ProfileMarshaler.java b/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/ProfileMarshaler.java index 6553c598c1d..bd6bc7521c8 100644 --- a/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/ProfileMarshaler.java +++ b/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/ProfileMarshaler.java @@ -149,9 +149,7 @@ protected void writeTo(Serializer output) throws IOException { output.serializeRepeatedMessage(Profile.ATTRIBUTE_TABLE, attributeMarshalers); output.serializeRepeatedMessage(Profile.ATTRIBUTE_UNITS, attributeUnitMarshalers); output.serializeRepeatedMessage(Profile.LINK_TABLE, linkMarshalers); - for (byte[] i : stringTable) { - output.serializeString(Profile.STRING_TABLE, i); - } + output.serializeRepeatedString(Profile.STRING_TABLE, stringTable); output.serializeInt64(Profile.DROP_FRAMES, dropFrames); output.serializeInt64(Profile.KEEP_FRAMES, keepFrames); output.serializeInt64(Profile.TIME_NANOS, timeNanos); @@ -192,9 +190,7 @@ private static int calculateSize( size += MarshalerUtil.sizeRepeatedMessage(Profile.ATTRIBUTE_TABLE, attributeMarshalers); size += MarshalerUtil.sizeRepeatedMessage(Profile.ATTRIBUTE_UNITS, attributeUnitMarshalers); size += MarshalerUtil.sizeRepeatedMessage(Profile.LINK_TABLE, linkMarshalers); - for (byte[] i : stringTable) { - size += MarshalerUtil.sizeBytes(Profile.STRING_TABLE, i); - } + size += MarshalerUtil.sizeRepeatedString(Profile.STRING_TABLE, stringTable); size += MarshalerUtil.sizeInt64(Profile.DROP_FRAMES, dropFrames); size += MarshalerUtil.sizeInt64(Profile.KEEP_FRAMES, keepFrames); size += MarshalerUtil.sizeInt64(Profile.TIME_NANOS, timeNanos); diff --git a/exporters/otlp/profiles/src/test/java/io/opentelemetry/exporter/otlp/profiles/ProfilesRequestMarshalerTest.java b/exporters/otlp/profiles/src/test/java/io/opentelemetry/exporter/otlp/profiles/ProfilesRequestMarshalerTest.java index 927c403da17..3d0ca5dda53 100644 --- a/exporters/otlp/profiles/src/test/java/io/opentelemetry/exporter/otlp/profiles/ProfilesRequestMarshalerTest.java +++ b/exporters/otlp/profiles/src/test/java/io/opentelemetry/exporter/otlp/profiles/ProfilesRequestMarshalerTest.java @@ -275,7 +275,7 @@ private static ProfileData sampleProfileData() { Attributes.empty(), Collections.emptyList(), Collections.emptyList(), - Collections.emptyList(), + listOf("foo", "bar"), 3, 4, 5, @@ -304,6 +304,8 @@ private static Profile.Builder sampleProfileBuilder() { .AGGREGATION_TEMPORALITY_CUMULATIVE) .build()) .addAllComment(listOf(8L, 9L)) + .addStringTable("foo") + .addStringTable("bar") .setDefaultSampleType(10); } From 7829f53c247b6741866ff71181bd39e28988a415 Mon Sep 17 00:00:00 2001 From: Trask Stalnaker Date: Mon, 25 Nov 2024 08:34:18 -0800 Subject: [PATCH 685/901] Update develocity configuration (#6903) --- .github/repository-settings.md | 4 --- .github/workflows/benchmark-tags.yml | 2 -- .github/workflows/benchmark.yml | 2 -- .github/workflows/build.yml | 1 - settings.gradle.kts | 41 ++++------------------------ 5 files changed, 5 insertions(+), 45 deletions(-) diff --git a/.github/repository-settings.md b/.github/repository-settings.md index 874eebfab7a..79d583584b1 100644 --- a/.github/repository-settings.md +++ b/.github/repository-settings.md @@ -71,9 +71,5 @@ Same settings as above for `main`, except: * `GPG_PASSWORD` - stored in OpenTelemetry-Java 1Password * `GPG_PRIVATE_KEY` - stored in OpenTelemetry-Java 1Password -* `DEVELOCITY_ACCESS_KEY` - owned by [@jack-berg](https://github.com/jack-berg) - * Generated at https://ge.opentelemetry.io > My settings > Access keys - * format of env var is `ge.opentelemetry.io=`, - see [docs](https://docs.gradle.com/enterprise/gradle-plugin/#via_environment_variable) * `SONATYPE_KEY` - owned by [@jack-berg](https://github.com/jack-berg) * `SONATYPE_USER` - owned by [@jack-berg](https://github.com/jack-berg) diff --git a/.github/workflows/benchmark-tags.yml b/.github/workflows/benchmark-tags.yml index 955a4bdcd0a..5831c0f9819 100644 --- a/.github/workflows/benchmark-tags.yml +++ b/.github/workflows/benchmark-tags.yml @@ -54,8 +54,6 @@ jobs: uses: gradle/actions/setup-gradle@v4 - name: Run jmh run: ./gradlew jmhJar - env: - DEVELOCITY_ACCESS_KEY: ${{ secrets.DEVELOCITY_ACCESS_KEY }} - name: Run Benchmark run: | diff --git a/.github/workflows/benchmark.yml b/.github/workflows/benchmark.yml index bb47139b039..1f026b2c654 100644 --- a/.github/workflows/benchmark.yml +++ b/.github/workflows/benchmark.yml @@ -24,8 +24,6 @@ jobs: uses: gradle/actions/setup-gradle@v4 - name: Run jmh run: ./gradlew jmhJar - env: - DEVELOCITY_ACCESS_KEY: ${{ secrets.DEVELOCITY_ACCESS_KEY }} - name: Run Benchmark run: | diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index c600b3539ec..7244872f30f 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -75,7 +75,6 @@ jobs: "-Porg.gradle.java.installations.paths=${{ steps.setup-java-test.outputs.path }}" "-Porg.gradle.java.installations.auto-download=false" env: - DEVELOCITY_ACCESS_KEY: ${{ secrets.DEVELOCITY_ACCESS_KEY }} # JMH-based tests run only if this environment variable is set to true RUN_JMH_BASED_TESTS: ${{ matrix.jmh-based-tests }} diff --git a/settings.gradle.kts b/settings.gradle.kts index 199db38a1f1..76df07b5606 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -68,41 +68,10 @@ include(":sdk-extensions:jaeger-remote-sampler") include(":testing-internal") include(":animal-sniffer-signature") -val gradleEnterpriseServer = "https://ge.opentelemetry.io" -val isCI = System.getenv("CI") != null -val geAccessKey = System.getenv("DEVELOCITY_ACCESS_KEY") ?: "" - -// if GE access key is not given and we are in CI, then we publish to scans.gradle.com -val useScansGradleCom = isCI && geAccessKey.isEmpty() - -if (useScansGradleCom) { - develocity { - buildScan { - termsOfUseUrl.set("https://gradle.com/terms-of-service") - termsOfUseAgree.set("yes") - uploadInBackground.set(!isCI) - publishing.onlyIf { true } - - capture { - fileFingerprints.set(true) - } - } - } -} else { - develocity { - server = gradleEnterpriseServer - buildScan { - uploadInBackground.set(!isCI) - publishing.onlyIf { - it.isAuthenticated - } - - capture { - fileFingerprints.set(true) - } - - gradle.startParameter.projectProperties["testJavaVersion"]?.let { tag(it) } - gradle.startParameter.projectProperties["testJavaVM"]?.let { tag(it) } - } +develocity { + buildScan { + publishing.onlyIf { System.getenv("CI") != null } + termsOfUseUrl.set("https://gradle.com/help/legal-terms-of-use") + termsOfUseAgree.set("yes") } } From 1cdb04d725c227b96ea550a075faa3639cb9c7a6 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 28 Nov 2024 21:13:36 -0800 Subject: [PATCH 686/901] fix(deps): update dependency org.jetbrains.kotlin:kotlin-gradle-plugin to v2.1.0 (#6909) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- buildSrc/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts index 0baebc9a3f4..ffd73c271c7 100644 --- a/buildSrc/build.gradle.kts +++ b/buildSrc/build.gradle.kts @@ -65,7 +65,7 @@ dependencies { implementation("me.champeau.jmh:jmh-gradle-plugin:0.7.2") implementation("net.ltgt.gradle:gradle-errorprone-plugin:4.1.0") implementation("net.ltgt.gradle:gradle-nullaway-plugin:2.1.0") - implementation("org.jetbrains.kotlin:kotlin-gradle-plugin:2.0.21") + implementation("org.jetbrains.kotlin:kotlin-gradle-plugin:2.1.0") implementation("org.owasp:dependency-check-gradle:11.1.0") implementation("ru.vyarus:gradle-animalsniffer-plugin:1.7.2") } From e78de66e5fe345c9cc2b1aee5d42978c38925ca4 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 28 Nov 2024 21:15:39 -0800 Subject: [PATCH 687/901] fix(deps): update dependency io.grpc:grpc-bom to v1.68.2 (#6911) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- dependencyManagement/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index a5ac0ab369a..3b8fe2d0ff6 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -14,7 +14,7 @@ val DEPENDENCY_BOMS = listOf( "com.linecorp.armeria:armeria-bom:1.31.1", "com.squareup.okhttp3:okhttp-bom:4.12.0", "com.squareup.okio:okio-bom:3.9.1", // applies to transitive dependencies of okhttp - "io.grpc:grpc-bom:1.68.1", + "io.grpc:grpc-bom:1.68.2", "io.netty:netty-bom:4.1.115.Final", "io.zipkin.brave:brave-bom:6.0.3", "io.zipkin.reporter2:zipkin-reporter-bom:3.4.2", From bc482c996e5b213b65f1816f2ab5a38b5761ffbc Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 29 Nov 2024 14:00:01 -0800 Subject: [PATCH 688/901] fix(deps): update dependency com.fasterxml.jackson:jackson-bom to v2.18.2 (#6910) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- dependencyManagement/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index 3b8fe2d0ff6..c91f4cd1b24 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -8,7 +8,7 @@ val dependencyVersions = hashMapOf() rootProject.extra["versions"] = dependencyVersions val DEPENDENCY_BOMS = listOf( - "com.fasterxml.jackson:jackson-bom:2.18.1", + "com.fasterxml.jackson:jackson-bom:2.18.2", "com.google.guava:guava-bom:33.3.1-jre", "com.google.protobuf:protobuf-bom:3.25.5", "com.linecorp.armeria:armeria-bom:1.31.1", From 9b2f6bace99a16f208c2f0d0d0e6b9713cc9ef1a Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 2 Dec 2024 07:42:06 -0800 Subject: [PATCH 689/901] fix(deps): update dependency checkstyle to v10.20.2 (#6914) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- buildSrc/src/main/kotlin/otel.java-conventions.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/buildSrc/src/main/kotlin/otel.java-conventions.gradle.kts b/buildSrc/src/main/kotlin/otel.java-conventions.gradle.kts index b76363f8f12..26a845f5c8a 100644 --- a/buildSrc/src/main/kotlin/otel.java-conventions.gradle.kts +++ b/buildSrc/src/main/kotlin/otel.java-conventions.gradle.kts @@ -42,7 +42,7 @@ java { checkstyle { configDirectory.set(file("$rootDir/buildscripts/")) - toolVersion = "10.20.1" + toolVersion = "10.20.2" isIgnoreFailures = false configProperties["rootDir"] = rootDir } From 3df2068d9f5e036314755d1e6fe9192c4a50a806 Mon Sep 17 00:00:00 2001 From: Jonathan Halliday Date: Mon, 2 Dec 2024 19:08:41 +0000 Subject: [PATCH 690/901] Update opentelementry-proto to 1.4 (#6906) --- .../otel.japicmp-conventions.gradle.kts | 8 +- dependencyManagement/build.gradle.kts | 4 +- .../internal/marshal/MarshalerUtil.java | 33 +++ .../exporter/internal/marshal/Serializer.java | 34 ++- exporters/otlp/common/build.gradle.kts | 2 +- .../data/ImmutableAttributeUnitData.java | 4 +- .../internal/data/ImmutableFunctionData.java | 4 +- .../internal/data/ImmutableLabelData.java | 32 --- .../otlp/internal/data/ImmutableLineData.java | 2 +- .../internal/data/ImmutableLocationData.java | 7 +- .../internal/data/ImmutableMappingData.java | 11 +- .../data/ImmutableProfileContainerData.java | 63 ------ .../internal/data/ImmutableProfileData.java | 51 +++-- .../internal/data/ImmutableSampleData.java | 17 +- .../internal/data/ImmutableValueTypeData.java | 5 +- .../otlp/profiles/AggregationTemporality.java | 4 +- .../otlp/profiles/AttributeUnitData.java | 6 +- .../otlp/profiles/AttributeUnitMarshaler.java | 27 +-- .../exporter/otlp/profiles/BuildIdKind.java | 20 -- .../exporter/otlp/profiles/FunctionData.java | 8 +- .../otlp/profiles/FunctionMarshaler.java | 38 ++-- ...InstrumentationScopeProfilesMarshaler.java | 16 +- .../exporter/otlp/profiles/LabelData.java | 33 --- .../exporter/otlp/profiles/LineData.java | 4 +- .../exporter/otlp/profiles/LineMarshaler.java | 12 +- .../exporter/otlp/profiles/LinkData.java | 2 +- .../exporter/otlp/profiles/LinkMarshaler.java | 2 +- .../exporter/otlp/profiles/LocationData.java | 9 +- .../otlp/profiles/LocationMarshaler.java | 34 ++- .../exporter/otlp/profiles/MappingData.java | 16 +- .../otlp/profiles/MappingMarshaler.java | 51 ++--- .../otlp/profiles/ProfileContainerData.java | 92 -------- .../profiles/ProfileContainerMarshaler.java | 113 ---------- .../exporter/otlp/profiles/ProfileData.java | 86 ++++++-- .../otlp/profiles/ProfileMarshaler.java | 169 +++++++++------ .../profiles/ProfilesRequestMarshaler.java | 12 +- .../profiles/ResourceProfilesMarshaler.java | 22 +- .../exporter/otlp/profiles/SampleData.java | 16 +- .../otlp/profiles/SampleMarshaler.java | 63 +++--- .../exporter/otlp/profiles/ValueTypeData.java | 8 +- .../otlp/profiles/ValueTypeMarshaler.java | 36 ++-- .../ProfilesRequestMarshalerTest.java | 201 ++++++------------ 42 files changed, 524 insertions(+), 853 deletions(-) delete mode 100644 exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/internal/data/ImmutableLabelData.java delete mode 100644 exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/internal/data/ImmutableProfileContainerData.java delete mode 100644 exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/BuildIdKind.java delete mode 100644 exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/LabelData.java delete mode 100644 exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/ProfileContainerData.java delete mode 100644 exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/ProfileContainerMarshaler.java diff --git a/buildSrc/src/main/kotlin/otel.japicmp-conventions.gradle.kts b/buildSrc/src/main/kotlin/otel.japicmp-conventions.gradle.kts index 08dc25cfebc..e9a0ff0b408 100644 --- a/buildSrc/src/main/kotlin/otel.japicmp-conventions.gradle.kts +++ b/buildSrc/src/main/kotlin/otel.japicmp-conventions.gradle.kts @@ -181,7 +181,13 @@ if (!project.hasProperty("otel.release") && !project.name.startsWith("bom")) { // this is needed so that we only consider the current artifact, and not dependencies ignoreMissingClasses.set(true) - packageExcludes.addAll("*.internal", "*.internal.*", "io.opentelemetry.internal.shaded.jctools.*") + packageExcludes.addAll( + "*.internal", + "*.internal.*", + "io.opentelemetry.internal.shaded.jctools.*", + // Temporarily suppress warnings from public generated classes from :sdk-extensions:jaeger-remote-sampler + "io.opentelemetry.sdk.extension.trace.jaeger.proto.api_v2" + ) val baseVersionString = if (apiBaseVersion == null) "latest" else baselineVersion txtOutputFile.set( apiNewVersion?.let { file("$rootDir/docs/apidiffs/${apiNewVersion}_vs_$baselineVersion/${base.archivesName.get()}.txt") } diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index c91f4cd1b24..59cb94d06e6 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -10,7 +10,7 @@ rootProject.extra["versions"] = dependencyVersions val DEPENDENCY_BOMS = listOf( "com.fasterxml.jackson:jackson-bom:2.18.2", "com.google.guava:guava-bom:33.3.1-jre", - "com.google.protobuf:protobuf-bom:3.25.5", + "com.google.protobuf:protobuf-bom:4.28.3", "com.linecorp.armeria:armeria-bom:1.31.1", "com.squareup.okhttp3:okhttp-bom:4.12.0", "com.squareup.okio:okio-bom:3.9.1", // applies to transitive dependencies of okhttp @@ -69,7 +69,7 @@ val DEPENDENCIES = listOf( "io.jaegertracing:jaeger-client:1.8.1", "io.opentelemetry.contrib:opentelemetry-aws-xray-propagator:1.39.0-alpha", "io.opentelemetry.semconv:opentelemetry-semconv-incubating:1.28.0-alpha", - "io.opentelemetry.proto:opentelemetry-proto:1.3.2-alpha", + "io.opentelemetry.proto:opentelemetry-proto:1.4.0-alpha", "io.opentracing:opentracing-api:0.33.0", "io.opentracing:opentracing-noop:0.33.0", "io.prometheus:prometheus-metrics-exporter-httpserver:1.3.3", diff --git a/exporters/common/src/main/java/io/opentelemetry/exporter/internal/marshal/MarshalerUtil.java b/exporters/common/src/main/java/io/opentelemetry/exporter/internal/marshal/MarshalerUtil.java index 92db2fa4271..78e8bf71be1 100644 --- a/exporters/common/src/main/java/io/opentelemetry/exporter/internal/marshal/MarshalerUtil.java +++ b/exporters/common/src/main/java/io/opentelemetry/exporter/internal/marshal/MarshalerUtil.java @@ -225,6 +225,26 @@ public static int sizeRepeatedInt64(ProtoFieldInfo field, List values) { return field.getTagSize() + CodedOutputStream.computeUInt32SizeNoTag(payloadSize) + payloadSize; } + /** + * Returns the size of a repeated int32 field. + * + *

      Packed repeated fields contain the tag, an integer representing the incoming payload size, + * and an actual payload of repeated varints. + */ + public static int sizeRepeatedInt32(ProtoFieldInfo field, List values) { + if (values.isEmpty()) { + return 0; + } + + int payloadSize = 0; + for (int v : values) { + payloadSize += CodedOutputStream.computeInt32SizeNoTag(v); + } + + // tag size + payload indicator size + actual payload size + return field.getTagSize() + CodedOutputStream.computeUInt32SizeNoTag(payloadSize) + payloadSize; + } + /** Returns the size of a repeated double field. */ public static int sizeRepeatedDouble(ProtoFieldInfo field, List values) { // Same as fixed64. @@ -310,6 +330,19 @@ public static int sizeInt32(ProtoFieldInfo field, int message) { return field.getTagSize() + CodedOutputStream.computeInt32SizeNoTag(message); } + /** Returns the size of an optional int32 field. */ + public static int sizeInt32Optional(ProtoFieldInfo field, int message) { + return field.getTagSize() + CodedOutputStream.computeInt32SizeNoTag(message); + } + + /** Returns the size of an optional int32 field. */ + public static int sizeInt32Optional(ProtoFieldInfo field, @Nullable Integer message) { + if (message == null) { + return 0; + } + return sizeInt32Optional(field, (int) message); + } + /** Returns the size of a double field. */ public static int sizeDouble(ProtoFieldInfo field, double value) { if (value == 0D) { diff --git a/exporters/common/src/main/java/io/opentelemetry/exporter/internal/marshal/Serializer.java b/exporters/common/src/main/java/io/opentelemetry/exporter/internal/marshal/Serializer.java index 069fa3a6b58..a19091fa73d 100644 --- a/exporters/common/src/main/java/io/opentelemetry/exporter/internal/marshal/Serializer.java +++ b/exporters/common/src/main/java/io/opentelemetry/exporter/internal/marshal/Serializer.java @@ -122,7 +122,7 @@ public void serializeSInt32(ProtoFieldInfo field, int value) throws IOException protected abstract void writeSInt32(ProtoFieldInfo info, int value) throws IOException; - /** Serializes a protobuf {@code uint32} field. */ + /** Serializes a protobuf {@code int32} field. */ public void serializeInt32(ProtoFieldInfo field, int value) throws IOException { if (value == 0) { return; @@ -130,6 +130,19 @@ public void serializeInt32(ProtoFieldInfo field, int value) throws IOException { writeint32(field, value); } + /** Serializes a protobuf {@code int32} field. */ + public void serializeInt32Optional(ProtoFieldInfo field, int value) throws IOException { + writeint32(field, value); + } + + /** Serializes a protobuf {@code int32} field. */ + public void serializeInt32Optional(ProtoFieldInfo field, @Nullable Integer value) + throws IOException { + if (value != null) { + serializeInt32Optional(field, (int) value); + } + } + protected abstract void writeint32(ProtoFieldInfo field, int value) throws IOException; /** Serializes a protobuf {@code int64} field. */ @@ -340,6 +353,25 @@ protected abstract void writeStartRepeatedVarint(ProtoFieldInfo field, int paylo protected abstract void writeEndRepeatedVarint() throws IOException; + /** Serializes a {@code repeated int32} field. */ + public void serializeRepeatedInt32(ProtoFieldInfo field, List values) + throws IOException { + if (values.isEmpty()) { + return; + } + + int payloadSize = 0; + for (int v : values) { + payloadSize += CodedOutputStream.computeInt32SizeNoTag(v); + } + + writeStartRepeatedVarint(field, payloadSize); + for (int value : values) { + writeUInt64Value(value); + } + writeEndRepeatedVarint(); + } + /** Serializes a {@code repeated fixed64} field. */ public void serializeRepeatedFixed64(ProtoFieldInfo field, List values) throws IOException { if (values.isEmpty()) { diff --git a/exporters/otlp/common/build.gradle.kts b/exporters/otlp/common/build.gradle.kts index 67b3f86aa89..a151c0bb24d 100644 --- a/exporters/otlp/common/build.gradle.kts +++ b/exporters/otlp/common/build.gradle.kts @@ -42,7 +42,7 @@ wire { "opentelemetry.proto.collector.trace.v1.ExportTraceServiceRequest", "opentelemetry.proto.collector.metrics.v1.ExportMetricsServiceRequest", "opentelemetry.proto.collector.logs.v1.ExportLogsServiceRequest", - "opentelemetry.proto.collector.profiles.v1experimental.ExportProfilesServiceRequest" + "opentelemetry.proto.collector.profiles.v1development.ExportProfilesServiceRequest" ) custom { diff --git a/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/internal/data/ImmutableAttributeUnitData.java b/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/internal/data/ImmutableAttributeUnitData.java index 60255827102..ee3e54aa177 100644 --- a/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/internal/data/ImmutableAttributeUnitData.java +++ b/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/internal/data/ImmutableAttributeUnitData.java @@ -25,8 +25,8 @@ public abstract class ImmutableAttributeUnitData implements AttributeUnitData { * * @return a new AttributeUnitData mapping the given key to the given unit. */ - public static AttributeUnitData create(long attributeKey, long unitIndex) { - return new AutoValue_ImmutableAttributeUnitData(attributeKey, unitIndex); + public static AttributeUnitData create(int attributeKeyStringIndex, int unitStringIndex) { + return new AutoValue_ImmutableAttributeUnitData(attributeKeyStringIndex, unitStringIndex); } ImmutableAttributeUnitData() {} diff --git a/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/internal/data/ImmutableFunctionData.java b/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/internal/data/ImmutableFunctionData.java index 30de9f2927c..cd0c12e901c 100644 --- a/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/internal/data/ImmutableFunctionData.java +++ b/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/internal/data/ImmutableFunctionData.java @@ -25,9 +25,9 @@ public abstract class ImmutableFunctionData implements FunctionData { * @return a new FunctionData describing the given function characteristics. */ public static FunctionData create( - long nameIndex, long systemNameIndex, long filenameIndex, long startLine) { + int nameStringIndex, int systemNameStringIndex, int filenameStringIndex, long startLine) { return new AutoValue_ImmutableFunctionData( - nameIndex, systemNameIndex, filenameIndex, startLine); + nameStringIndex, systemNameStringIndex, filenameStringIndex, startLine); } ImmutableFunctionData() {} diff --git a/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/internal/data/ImmutableLabelData.java b/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/internal/data/ImmutableLabelData.java deleted file mode 100644 index 77797fee92c..00000000000 --- a/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/internal/data/ImmutableLabelData.java +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package io.opentelemetry.exporter.otlp.internal.data; - -import com.google.auto.value.AutoValue; -import io.opentelemetry.exporter.otlp.profiles.LabelData; -import javax.annotation.concurrent.Immutable; - -/** - * Auto value implementation of {@link LabelData}, which provides additional context for a sample. - * - *

      This class is internal and is hence not for public use. Its APIs are unstable and can change - * at any time. - */ -@Immutable -@AutoValue -public abstract class ImmutableLabelData implements LabelData { - - /** - * Returns a new LabelData describing the given context for a sample. - * - * @return a new LabelData describing the given context for a sample. - */ - public static LabelData create(long keyIndex, long strIndex, long num, long numUnitIndex) { - return new AutoValue_ImmutableLabelData(keyIndex, strIndex, num, numUnitIndex); - } - - ImmutableLabelData() {} -} diff --git a/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/internal/data/ImmutableLineData.java b/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/internal/data/ImmutableLineData.java index e5c5d673d23..e0eebeaff60 100644 --- a/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/internal/data/ImmutableLineData.java +++ b/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/internal/data/ImmutableLineData.java @@ -25,7 +25,7 @@ public abstract class ImmutableLineData implements LineData { * * @return a new LineData describing the given details a specific line in a source code. */ - public static LineData create(long functionIndex, long line, long column) { + public static LineData create(int functionIndex, long line, long column) { return new AutoValue_ImmutableLineData(functionIndex, line, column); } diff --git a/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/internal/data/ImmutableLocationData.java b/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/internal/data/ImmutableLocationData.java index 13554152dcd..56792a30478 100644 --- a/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/internal/data/ImmutableLocationData.java +++ b/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/internal/data/ImmutableLocationData.java @@ -28,14 +28,13 @@ public abstract class ImmutableLocationData implements LocationData { * @return a new LocationData describing the given function and line table information. */ public static LocationData create( - long mappingIndex, + Integer mappingIndex, long address, List lines, boolean folded, - int typeIndex, - List attributes) { + List attributeIndices) { return new AutoValue_ImmutableLocationData( - mappingIndex, address, lines, folded, typeIndex, attributes); + mappingIndex, address, lines, folded, attributeIndices); } ImmutableLocationData() {} diff --git a/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/internal/data/ImmutableMappingData.java b/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/internal/data/ImmutableMappingData.java index da020967adb..a1f4c07843c 100644 --- a/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/internal/data/ImmutableMappingData.java +++ b/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/internal/data/ImmutableMappingData.java @@ -6,7 +6,6 @@ package io.opentelemetry.exporter.otlp.internal.data; import com.google.auto.value.AutoValue; -import io.opentelemetry.exporter.otlp.profiles.BuildIdKind; import io.opentelemetry.exporter.otlp.profiles.MappingData; import java.util.List; import javax.annotation.concurrent.Immutable; @@ -32,10 +31,8 @@ public static MappingData create( long memoryStart, long memoryLimit, long fileOffset, - long filenameIndex, - long buildIdIndex, - BuildIdKind buildIdKind, - List attributeIndices, + int filenameStringIndex, + List attributeIndices, boolean hasFunctions, boolean hasFilenames, boolean hasLineNumbers, @@ -44,9 +41,7 @@ public static MappingData create( memoryStart, memoryLimit, fileOffset, - filenameIndex, - buildIdIndex, - buildIdKind, + filenameStringIndex, attributeIndices, hasFunctions, hasFilenames, diff --git a/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/internal/data/ImmutableProfileContainerData.java b/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/internal/data/ImmutableProfileContainerData.java deleted file mode 100644 index e6449c88e10..00000000000 --- a/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/internal/data/ImmutableProfileContainerData.java +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package io.opentelemetry.exporter.otlp.internal.data; - -import com.google.auto.value.AutoValue; -import io.opentelemetry.api.common.Attributes; -import io.opentelemetry.exporter.otlp.profiles.ProfileContainerData; -import io.opentelemetry.exporter.otlp.profiles.ProfileData; -import io.opentelemetry.sdk.common.InstrumentationScopeInfo; -import io.opentelemetry.sdk.resources.Resource; -import java.nio.ByteBuffer; -import javax.annotation.Nullable; -import javax.annotation.concurrent.Immutable; - -/** - * Auto value implementation of {@link ProfileContainerData}, which represents a single profile. - * - *

      This class is internal and is hence not for public use. Its APIs are unstable and can change - * at any time. - */ -@Immutable -@AutoValue -public abstract class ImmutableProfileContainerData implements ProfileContainerData { - - /** - * Returns a new ProfileContainerData representing the given profile information. - * - * @return a new ProfileContainerData representing the given profile information. - */ - @SuppressWarnings("TooManyParameters") - public static ProfileContainerData create( - Resource resource, - InstrumentationScopeInfo instrumentationScopeInfo, - String profileId, - long startEpochNanos, - long endEpochNanos, - Attributes attributes, - int totalAttributeCount, - @Nullable String originalPayloadFormat, - ByteBuffer originalPayload, - ProfileData profile) { - return new AutoValue_ImmutableProfileContainerData( - resource, - instrumentationScopeInfo, - profileId, - startEpochNanos, - endEpochNanos, - attributes, - totalAttributeCount, - originalPayloadFormat, - originalPayload, - profile); - } - - ImmutableProfileContainerData() {} - - public ByteBuffer getOriginalPayloadReadOnly() { - return getOriginalPayload().asReadOnlyBuffer(); - } -} diff --git a/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/internal/data/ImmutableProfileData.java b/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/internal/data/ImmutableProfileData.java index 717084d320a..b44b7f67834 100644 --- a/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/internal/data/ImmutableProfileData.java +++ b/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/internal/data/ImmutableProfileData.java @@ -15,6 +15,9 @@ import io.opentelemetry.exporter.otlp.profiles.ProfileData; import io.opentelemetry.exporter.otlp.profiles.SampleData; import io.opentelemetry.exporter.otlp.profiles.ValueTypeData; +import io.opentelemetry.sdk.common.InstrumentationScopeInfo; +import io.opentelemetry.sdk.resources.Resource; +import java.nio.ByteBuffer; import java.util.List; import javax.annotation.concurrent.Immutable; @@ -37,43 +40,53 @@ public abstract class ImmutableProfileData implements ProfileData { */ @SuppressWarnings("TooManyParameters") public static ProfileData create( + Resource resource, + InstrumentationScopeInfo instrumentationScopeInfo, List sampleTypes, List samples, - List mappings, - List locations, - List locationIndices, - List functions, - Attributes attributes, + List mappingTable, + List locationTable, + List locationIndices, + List functionTable, + Attributes attributeTable, List attributeUnits, - List links, + List linkTable, List stringTable, - long dropFrames, - long keepFrames, long timeNanos, long durationNanos, ValueTypeData periodType, long period, - List comment, - long defaultSampleType) { + List commentStrindices, + int defaultSampleTypeStringIndex, + String profileId, + Attributes attributes, + int droppedAttributesCount, + String originalPayloadFormat, + ByteBuffer originalPayload) { return new AutoValue_ImmutableProfileData( + resource, + instrumentationScopeInfo, sampleTypes, samples, - mappings, - locations, + mappingTable, + locationTable, locationIndices, - functions, - attributes, + functionTable, + attributeTable, attributeUnits, - links, + linkTable, stringTable, - dropFrames, - keepFrames, timeNanos, durationNanos, periodType, period, - comment, - defaultSampleType); + commentStrindices, + defaultSampleTypeStringIndex, + profileId, + attributes, + droppedAttributesCount, + originalPayloadFormat, + originalPayload); } ImmutableProfileData() {} diff --git a/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/internal/data/ImmutableSampleData.java b/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/internal/data/ImmutableSampleData.java index 6d121146e52..c0b3deac55b 100644 --- a/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/internal/data/ImmutableSampleData.java +++ b/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/internal/data/ImmutableSampleData.java @@ -27,21 +27,14 @@ public abstract class ImmutableSampleData implements SampleData { * @return a new SampleData representing the given program context. */ public static SampleData create( - long locationsStartIndex, - long locationsLength, - int stacktraceIdIndex, + int locationsStartIndex, + int locationsLength, List values, - List attributes, - long link, + List attributeIndices, + Integer linkIndex, List timestamps) { return new AutoValue_ImmutableSampleData( - locationsStartIndex, - locationsLength, - stacktraceIdIndex, - values, - attributes, - link, - timestamps); + locationsStartIndex, locationsLength, values, attributeIndices, linkIndex, timestamps); } ImmutableSampleData() {} diff --git a/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/internal/data/ImmutableValueTypeData.java b/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/internal/data/ImmutableValueTypeData.java index 3d6ff8c4281..9928403f3a2 100644 --- a/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/internal/data/ImmutableValueTypeData.java +++ b/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/internal/data/ImmutableValueTypeData.java @@ -27,8 +27,9 @@ public abstract class ImmutableValueTypeData implements ValueTypeData { * @return a new ValueTypeData describing the given type and unit characteristics. */ public static ValueTypeData create( - long type, long unit, AggregationTemporality aggregationTemporality) { - return new AutoValue_ImmutableValueTypeData(type, unit, aggregationTemporality); + int typeStringIndex, int unitStringIndex, AggregationTemporality aggregationTemporality) { + return new AutoValue_ImmutableValueTypeData( + typeStringIndex, unitStringIndex, aggregationTemporality); } ImmutableValueTypeData() {} diff --git a/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/AggregationTemporality.java b/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/AggregationTemporality.java index 4586a4652b1..fc3d47196a6 100644 --- a/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/AggregationTemporality.java +++ b/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/AggregationTemporality.java @@ -9,7 +9,7 @@ * Specifies the method of aggregating metric values. * *

      TODO: This is intentionally not the same as metrics/AggregationTemporality. For profiles.proto - * 'v1experimental' version, this class is considered distinct from the pre-exiting + * 'v1development' version, this class is considered distinct from the pre-exiting * AggregationTemporality in metrics.proto. As the profiles.proto stabilises, they may be refactored * into a version in common.proto. Meanwhile the Java class structure reflects the .proto structure * in making distinct entities. @@ -19,7 +19,7 @@ * @see * "https://github.com/open-telemetry/opentelemetry-proto/blob/v1.3.0/opentelemetry/proto/metrics/v1/metrics.proto#L261" * @see - * "https://github.com/open-telemetry/opentelemetry-proto/blob/v1.3.0/opentelemetry/proto/profiles/v1experimental/pprofextended.proto#L147" + * "https://github.com/open-telemetry/opentelemetry-proto/blob/v1.3.0/opentelemetry/proto/profiles/v1development/profiles.proto#L147" * @see "https://github.com/open-telemetry/opentelemetry-proto/issues/547" * @see "https://github.com/open-telemetry/opentelemetry-proto/pull/534#discussion_r1552403726" * @see "profiles.proto::AggregationTemporality" diff --git a/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/AttributeUnitData.java b/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/AttributeUnitData.java index 47f2403cbd4..1b5bbd54c6c 100644 --- a/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/AttributeUnitData.java +++ b/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/AttributeUnitData.java @@ -10,14 +10,14 @@ /** * Represents a mapping between Attribute Keys and Units. * - * @see "pprofextended.proto::AttributeUnit" + * @see "profiles.proto::AttributeUnit" */ @Immutable public interface AttributeUnitData { /** Index into string table. */ - long getAttributeKey(); + int getAttributeKeyStringIndex(); /** Index into string table. */ - long getUnitIndex(); + int getUnitIndexStringIndex(); } diff --git a/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/AttributeUnitMarshaler.java b/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/AttributeUnitMarshaler.java index d3831b78ba5..311a0d1c33d 100644 --- a/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/AttributeUnitMarshaler.java +++ b/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/AttributeUnitMarshaler.java @@ -8,7 +8,7 @@ import io.opentelemetry.exporter.internal.marshal.MarshalerUtil; import io.opentelemetry.exporter.internal.marshal.MarshalerWithSize; import io.opentelemetry.exporter.internal.marshal.Serializer; -import io.opentelemetry.proto.profiles.v1experimental.internal.AttributeUnit; +import io.opentelemetry.proto.profiles.v1development.internal.AttributeUnit; import java.io.IOException; import java.util.List; import java.util.function.Consumer; @@ -17,12 +17,13 @@ final class AttributeUnitMarshaler extends MarshalerWithSize { private static final AttributeUnitMarshaler[] EMPTY_REPEATED = new AttributeUnitMarshaler[0]; - private final long attributeKey; - private final long unitIndex; + private final int attributeKeyStringIndex; + private final int unitStringIndex; static AttributeUnitMarshaler create(AttributeUnitData attributeUnitData) { return new AttributeUnitMarshaler( - attributeUnitData.getAttributeKey(), attributeUnitData.getUnitIndex()); + attributeUnitData.getAttributeKeyStringIndex(), + attributeUnitData.getUnitIndexStringIndex()); } static AttributeUnitMarshaler[] createRepeated(List items) { @@ -44,23 +45,23 @@ public void accept(AttributeUnitData attributeUnitData) { return attributeUnitMarshalers; } - private AttributeUnitMarshaler(long attributeKey, long unitIndex) { - super(calculateSize(attributeKey, unitIndex)); - this.attributeKey = attributeKey; - this.unitIndex = unitIndex; + private AttributeUnitMarshaler(int attributeKeyStringIndex, int unitStringIndex) { + super(calculateSize(attributeKeyStringIndex, unitStringIndex)); + this.attributeKeyStringIndex = attributeKeyStringIndex; + this.unitStringIndex = unitStringIndex; } @Override protected void writeTo(Serializer output) throws IOException { - output.serializeInt64(AttributeUnit.ATTRIBUTE_KEY, attributeKey); - output.serializeInt64(AttributeUnit.UNIT, unitIndex); + output.serializeInt32(AttributeUnit.ATTRIBUTE_KEY_STRINDEX, attributeKeyStringIndex); + output.serializeInt32(AttributeUnit.UNIT_STRINDEX, unitStringIndex); } - private static int calculateSize(long attributeKey, long unitIndex) { + private static int calculateSize(int attributeKeyStringIndex, int unitStringIndex) { int size; size = 0; - size += MarshalerUtil.sizeInt64(AttributeUnit.ATTRIBUTE_KEY, attributeKey); - size += MarshalerUtil.sizeInt64(AttributeUnit.UNIT, unitIndex); + size += MarshalerUtil.sizeInt32(AttributeUnit.ATTRIBUTE_KEY_STRINDEX, attributeKeyStringIndex); + size += MarshalerUtil.sizeInt32(AttributeUnit.UNIT_STRINDEX, unitStringIndex); return size; } } diff --git a/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/BuildIdKind.java b/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/BuildIdKind.java deleted file mode 100644 index 9852b623aed..00000000000 --- a/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/BuildIdKind.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package io.opentelemetry.exporter.otlp.profiles; - -/** - * Indicates the semantics of the build_id field. - * - * @see "pprofextended.proto::BuildIdKind" - */ -public enum BuildIdKind { - - /** Linker-generated build ID, stored in the ELF binary notes. */ - LINKER, - - /** Build ID based on the content hash of the binary. */ - BINARY_HASH; -} diff --git a/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/FunctionData.java b/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/FunctionData.java index 3f246ce4a02..e50ba846907 100644 --- a/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/FunctionData.java +++ b/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/FunctionData.java @@ -10,22 +10,22 @@ /** * Describes a function. * - * @see "pprofextended.proto::Function" + * @see "profiles.proto::Function" */ @Immutable public interface FunctionData { /** Name of the function, in human-readable form if available. Index into string table. */ - long getNameIndex(); + int getNameStringIndex(); /** * Name of the function, as identified by the system. For instance, it can be a C++ mangled name. * Index into string table. */ - long getSystemNameIndex(); + int getSystemNameStringIndex(); /** Source file containing the function. Index into string table. */ - long getFilenameIndex(); + int getFilenameStringIndex(); /** Line number in source file. */ long getStartLine(); diff --git a/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/FunctionMarshaler.java b/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/FunctionMarshaler.java index 7f2a522c95f..aea4071d380 100644 --- a/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/FunctionMarshaler.java +++ b/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/FunctionMarshaler.java @@ -8,7 +8,7 @@ import io.opentelemetry.exporter.internal.marshal.MarshalerUtil; import io.opentelemetry.exporter.internal.marshal.MarshalerWithSize; import io.opentelemetry.exporter.internal.marshal.Serializer; -import io.opentelemetry.proto.profiles.v1experimental.internal.Function; +import io.opentelemetry.proto.profiles.v1development.internal.Function; import java.io.IOException; import java.util.List; import java.util.function.Consumer; @@ -17,16 +17,16 @@ final class FunctionMarshaler extends MarshalerWithSize { private static final FunctionMarshaler[] EMPTY_REPEATED = new FunctionMarshaler[0]; - private final long nameIndex; - private final long systemNameIndex; - private final long filenameIndex; + private final int nameStringIndex; + private final int systemNameStringIndex; + private final int filenameStringIndex; private final long startLine; static FunctionMarshaler create(FunctionData functionData) { return new FunctionMarshaler( - functionData.getNameIndex(), - functionData.getSystemNameIndex(), - functionData.getFilenameIndex(), + functionData.getNameStringIndex(), + functionData.getSystemNameStringIndex(), + functionData.getFilenameStringIndex(), functionData.getStartLine()); } @@ -50,28 +50,28 @@ public void accept(FunctionData functionData) { } private FunctionMarshaler( - long nameIndex, long systemNameIndex, long filenameIndex, long startLine) { - super(calculateSize(nameIndex, systemNameIndex, filenameIndex, startLine)); - this.nameIndex = nameIndex; - this.systemNameIndex = systemNameIndex; - this.filenameIndex = filenameIndex; + int nameStringIndex, int systemNameStringIndex, int filenameStringIndex, long startLine) { + super(calculateSize(nameStringIndex, systemNameStringIndex, filenameStringIndex, startLine)); + this.nameStringIndex = nameStringIndex; + this.systemNameStringIndex = systemNameStringIndex; + this.filenameStringIndex = filenameStringIndex; this.startLine = startLine; } @Override protected void writeTo(Serializer output) throws IOException { - output.serializeInt64(Function.NAME, nameIndex); - output.serializeInt64(Function.SYSTEM_NAME, systemNameIndex); - output.serializeInt64(Function.FILENAME, filenameIndex); + output.serializeInt32(Function.NAME_STRINDEX, nameStringIndex); + output.serializeInt32(Function.SYSTEM_NAME_STRINDEX, systemNameStringIndex); + output.serializeInt32(Function.FILENAME_STRINDEX, filenameStringIndex); output.serializeInt64(Function.START_LINE, startLine); } private static int calculateSize( - long nameIndex, long systemNameIndex, long filenameIndex, long startLine) { + int nameStringIndex, int systemNameStringIndex, int filenameStringIndex, long startLine) { int size = 0; - size += MarshalerUtil.sizeInt64(Function.NAME, nameIndex); - size += MarshalerUtil.sizeInt64(Function.SYSTEM_NAME, systemNameIndex); - size += MarshalerUtil.sizeInt64(Function.FILENAME, filenameIndex); + size += MarshalerUtil.sizeInt32(Function.NAME_STRINDEX, nameStringIndex); + size += MarshalerUtil.sizeInt32(Function.SYSTEM_NAME_STRINDEX, systemNameStringIndex); + size += MarshalerUtil.sizeInt32(Function.FILENAME_STRINDEX, filenameStringIndex); size += MarshalerUtil.sizeInt64(Function.START_LINE, startLine); return size; } diff --git a/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/InstrumentationScopeProfilesMarshaler.java b/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/InstrumentationScopeProfilesMarshaler.java index 63074ba15eb..8f7e2edea44 100644 --- a/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/InstrumentationScopeProfilesMarshaler.java +++ b/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/InstrumentationScopeProfilesMarshaler.java @@ -9,40 +9,40 @@ import io.opentelemetry.exporter.internal.marshal.MarshalerWithSize; import io.opentelemetry.exporter.internal.marshal.Serializer; import io.opentelemetry.exporter.internal.otlp.InstrumentationScopeMarshaler; -import io.opentelemetry.proto.profiles.v1experimental.internal.ScopeProfiles; +import io.opentelemetry.proto.profiles.v1development.internal.ScopeProfiles; import java.io.IOException; import java.util.List; final class InstrumentationScopeProfilesMarshaler extends MarshalerWithSize { private final InstrumentationScopeMarshaler instrumentationScope; - private final List profileContainerMarshalers; + private final List profileMarshalers; private final byte[] schemaUrlUtf8; InstrumentationScopeProfilesMarshaler( InstrumentationScopeMarshaler instrumentationScope, byte[] schemaUrlUtf8, - List profileContainerMarshalers) { - super(calculateSize(instrumentationScope, schemaUrlUtf8, profileContainerMarshalers)); + List profileMarshalers) { + super(calculateSize(instrumentationScope, schemaUrlUtf8, profileMarshalers)); this.instrumentationScope = instrumentationScope; this.schemaUrlUtf8 = schemaUrlUtf8; - this.profileContainerMarshalers = profileContainerMarshalers; + this.profileMarshalers = profileMarshalers; } @Override public void writeTo(Serializer output) throws IOException { output.serializeMessage(ScopeProfiles.SCOPE, instrumentationScope); - output.serializeRepeatedMessage(ScopeProfiles.PROFILES, profileContainerMarshalers); + output.serializeRepeatedMessage(ScopeProfiles.PROFILES, profileMarshalers); output.serializeString(ScopeProfiles.SCHEMA_URL, schemaUrlUtf8); } private static int calculateSize( InstrumentationScopeMarshaler instrumentationScope, byte[] schemaUrlUtf8, - List profileContainerMarshalers) { + List profileMarshalers) { int size = 0; size += MarshalerUtil.sizeMessage(ScopeProfiles.SCOPE, instrumentationScope); - size += MarshalerUtil.sizeRepeatedMessage(ScopeProfiles.PROFILES, profileContainerMarshalers); + size += MarshalerUtil.sizeRepeatedMessage(ScopeProfiles.PROFILES, profileMarshalers); size += MarshalerUtil.sizeBytes(ScopeProfiles.SCHEMA_URL, schemaUrlUtf8); return size; } diff --git a/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/LabelData.java b/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/LabelData.java deleted file mode 100644 index adc8787bae8..00000000000 --- a/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/LabelData.java +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package io.opentelemetry.exporter.otlp.profiles; - -import javax.annotation.concurrent.Immutable; - -/** - * Provides additional context for a sample, such as thread ID or allocation size, with optional - * units. - * - * @see "pprofextended.proto::Label" - */ -@Immutable -public interface LabelData { - - /** Index into string table. */ - long getKeyIndex(); - - /** String value of the label data, if applicable. Index into string table */ - long getStrIndex(); - - /** Numeric value of the label data, if applicable. */ - long getNum(); - - /** - * Specifies the units of num, applicable only if num is present. Use arbitrary string (for - * example, "requests") as a custom count unit. - */ - long getNumUnitIndex(); -} diff --git a/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/LineData.java b/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/LineData.java index b19e53cfa1e..7f5c4738ceb 100644 --- a/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/LineData.java +++ b/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/LineData.java @@ -10,13 +10,13 @@ /** * Details a specific line in a source code, linked to a function. * - * @see "pprofextended.proto::Line" + * @see "profiles.proto::Line" */ @Immutable public interface LineData { /** The index of the corresponding Function for this line. Index into function table. */ - long getFunctionIndex(); + int getFunctionIndex(); /** Line number in source code. */ long getLine(); diff --git a/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/LineMarshaler.java b/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/LineMarshaler.java index d28aedfa5f9..2d3bf83a6c2 100644 --- a/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/LineMarshaler.java +++ b/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/LineMarshaler.java @@ -8,7 +8,7 @@ import io.opentelemetry.exporter.internal.marshal.MarshalerUtil; import io.opentelemetry.exporter.internal.marshal.MarshalerWithSize; import io.opentelemetry.exporter.internal.marshal.Serializer; -import io.opentelemetry.proto.profiles.v1experimental.internal.Line; +import io.opentelemetry.proto.profiles.v1development.internal.Line; import java.io.IOException; import java.util.List; import java.util.function.Consumer; @@ -17,7 +17,7 @@ final class LineMarshaler extends MarshalerWithSize { private static final LineMarshaler[] EMPTY_REPEATED = new LineMarshaler[0]; - private final long functionIndex; + private final int functionIndex; private final long line; private final long column; @@ -44,7 +44,7 @@ public void accept(LineData lineData) { return lineMarshalers; } - private LineMarshaler(long functionIndex, long line, long column) { + private LineMarshaler(int functionIndex, long line, long column) { super(calculateSize(functionIndex, line, column)); this.functionIndex = functionIndex; this.line = line; @@ -53,14 +53,14 @@ private LineMarshaler(long functionIndex, long line, long column) { @Override protected void writeTo(Serializer output) throws IOException { - output.serializeUInt64(Line.FUNCTION_INDEX, functionIndex); + output.serializeInt32(Line.FUNCTION_INDEX, functionIndex); output.serializeInt64(Line.LINE, line); output.serializeInt64(Line.COLUMN, column); } - private static int calculateSize(long functionIndex, long line, long column) { + private static int calculateSize(int functionIndex, long line, long column) { int size = 0; - size += MarshalerUtil.sizeUInt64(Line.FUNCTION_INDEX, functionIndex); + size += MarshalerUtil.sizeInt32(Line.FUNCTION_INDEX, functionIndex); size += MarshalerUtil.sizeInt64(Line.LINE, line); size += MarshalerUtil.sizeInt64(Line.COLUMN, column); return size; diff --git a/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/LinkData.java b/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/LinkData.java index dd76c9283b2..ea3c1e1d7b8 100644 --- a/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/LinkData.java +++ b/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/LinkData.java @@ -10,7 +10,7 @@ /** * A connection from a profile Sample to a trace Span. * - * @see "pprofextended.proto::Link" + * @see "profiles.proto::Link" */ @Immutable public interface LinkData { diff --git a/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/LinkMarshaler.java b/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/LinkMarshaler.java index 13f489b32d7..ae41176a820 100644 --- a/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/LinkMarshaler.java +++ b/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/LinkMarshaler.java @@ -11,7 +11,7 @@ import io.opentelemetry.exporter.internal.marshal.MarshalerUtil; import io.opentelemetry.exporter.internal.marshal.MarshalerWithSize; import io.opentelemetry.exporter.internal.marshal.Serializer; -import io.opentelemetry.proto.profiles.v1experimental.internal.Link; +import io.opentelemetry.proto.profiles.v1development.internal.Link; import java.io.IOException; import java.util.List; import java.util.function.Consumer; diff --git a/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/LocationData.java b/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/LocationData.java index a36280cebd1..056e36c7026 100644 --- a/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/LocationData.java +++ b/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/LocationData.java @@ -11,7 +11,7 @@ /** * Describes function and line table debug information. * - * @see "pprofextended.proto::Location" + * @see "profiles.proto::Location" */ @Immutable public interface LocationData { @@ -20,7 +20,7 @@ public interface LocationData { * The index of the corresponding profile.Mapping for this location. It can be unset if the * mapping is unknown or not applicable for this profile type. */ - long getMappingIndex(); + Integer getMappingIndex(); /** The instruction address for this location, if available. */ long getAddress(); @@ -37,9 +37,6 @@ public interface LocationData { */ boolean isFolded(); - /** Type of frame (e.g. kernel, native, python, hotspot, php). Index into string table. */ - int getTypeIndex(); - /** References to attributes in Profile.attribute_table. */ - List getAttributes(); + List getAttributes(); } diff --git a/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/LocationMarshaler.java b/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/LocationMarshaler.java index 1a62e13fa55..88e1d1a26a4 100644 --- a/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/LocationMarshaler.java +++ b/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/LocationMarshaler.java @@ -8,21 +8,21 @@ import io.opentelemetry.exporter.internal.marshal.MarshalerUtil; import io.opentelemetry.exporter.internal.marshal.MarshalerWithSize; import io.opentelemetry.exporter.internal.marshal.Serializer; -import io.opentelemetry.proto.profiles.v1experimental.internal.Location; +import io.opentelemetry.proto.profiles.v1development.internal.Location; import java.io.IOException; import java.util.List; import java.util.function.Consumer; +import javax.annotation.Nullable; final class LocationMarshaler extends MarshalerWithSize { private static final LocationMarshaler[] EMPTY_REPEATED = new LocationMarshaler[0]; - private final long mappingIndex; + @Nullable private final Integer mappingIndex; private final long address; private final LineMarshaler[] lineMarshalers; private final boolean isFolded; - private final int typeIndex; - private final List attributes; + private final List attributeIndices; static LocationMarshaler create(LocationData locationData) { return new LocationMarshaler( @@ -30,7 +30,6 @@ static LocationMarshaler create(LocationData locationData) { locationData.getAddress(), LineMarshaler.createRepeated(locationData.getLines()), locationData.isFolded(), - locationData.getTypeIndex(), locationData.getAttributes()); } @@ -54,45 +53,40 @@ public void accept(LocationData locationData) { } private LocationMarshaler( - long mappingIndex, + @Nullable Integer mappingIndex, long address, LineMarshaler[] lineMarshalers, boolean isFolded, - int typeIndex, - List attributes) { - super(calculateSize(mappingIndex, address, lineMarshalers, isFolded, typeIndex, attributes)); + List attributeIndices) { + super(calculateSize(mappingIndex, address, lineMarshalers, isFolded, attributeIndices)); this.mappingIndex = mappingIndex; this.address = address; this.lineMarshalers = lineMarshalers; this.isFolded = isFolded; - this.typeIndex = typeIndex; - this.attributes = attributes; + this.attributeIndices = attributeIndices; } @Override protected void writeTo(Serializer output) throws IOException { - output.serializeUInt64(Location.MAPPING_INDEX, mappingIndex); + output.serializeInt32Optional(Location.MAPPING_INDEX, mappingIndex); output.serializeUInt64(Location.ADDRESS, address); output.serializeRepeatedMessage(Location.LINE, lineMarshalers); output.serializeBool(Location.IS_FOLDED, isFolded); - output.serializeUInt32(Location.TYPE_INDEX, typeIndex); - output.serializeRepeatedUInt64(Location.ATTRIBUTES, attributes); + output.serializeRepeatedInt32(Location.ATTRIBUTE_INDICES, attributeIndices); } private static int calculateSize( - long mappingIndex, + @Nullable Integer mappingIndex, long address, LineMarshaler[] lineMarshalers, boolean isFolded, - int typeIndex, - List attributes) { + List attributeIndices) { int size = 0; - size += MarshalerUtil.sizeUInt64(Location.MAPPING_INDEX, mappingIndex); + size += MarshalerUtil.sizeInt32Optional(Location.MAPPING_INDEX, mappingIndex); size += MarshalerUtil.sizeUInt64(Location.ADDRESS, address); size += MarshalerUtil.sizeRepeatedMessage(Location.LINE, lineMarshalers); size += MarshalerUtil.sizeBool(Location.IS_FOLDED, isFolded); - size += MarshalerUtil.sizeUInt32(Location.TYPE_INDEX, typeIndex); - size += MarshalerUtil.sizeRepeatedUInt64(Location.ATTRIBUTES, attributes); + size += MarshalerUtil.sizeRepeatedInt32(Location.ATTRIBUTE_INDICES, attributeIndices); return size; } } diff --git a/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/MappingData.java b/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/MappingData.java index 2b5e14a0c91..1b365bc7ea0 100644 --- a/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/MappingData.java +++ b/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/MappingData.java @@ -11,7 +11,7 @@ /** * Describes the mapping of a binary in memory. * - * @see "pprofextended.proto::Mapping" + * @see "profiles.proto::Mapping" */ @Immutable public interface MappingData { @@ -29,20 +29,10 @@ public interface MappingData { * The object this entry is loaded from. This can be a filename on disk for the main binary and * shared libraries, or virtual abstraction like "[vdso]". Index into the string table. */ - long getFilenameIndex(); - - /** - * Uniquely identifies a particular program version with high probability. e.g., for binaries - * generated by GNU tools, the contents of the .note.gnu.build-id field. Index into the string - * table. - */ - long getBuildIdIndex(); - - /** Specifies the kind of build id. See BuildIdKind enum for more details */ - BuildIdKind getBuildIdKind(); + int getFilenameStringIndex(); /** References to attributes in Profile.attribute_table. */ - List getAttributeIndices(); + List getAttributeIndices(); boolean hasFunctions(); diff --git a/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/MappingMarshaler.java b/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/MappingMarshaler.java index 9b1615137e9..6e39551540f 100644 --- a/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/MappingMarshaler.java +++ b/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/MappingMarshaler.java @@ -7,10 +7,8 @@ import io.opentelemetry.exporter.internal.marshal.MarshalerUtil; import io.opentelemetry.exporter.internal.marshal.MarshalerWithSize; -import io.opentelemetry.exporter.internal.marshal.ProtoEnumInfo; import io.opentelemetry.exporter.internal.marshal.Serializer; -import io.opentelemetry.proto.profiles.v1experimental.internal.BuildIdKind; -import io.opentelemetry.proto.profiles.v1experimental.internal.Mapping; +import io.opentelemetry.proto.profiles.v1development.internal.Mapping; import java.io.IOException; import java.util.List; import java.util.function.Consumer; @@ -22,32 +20,19 @@ final class MappingMarshaler extends MarshalerWithSize { private final long memoryStart; private final long memoryLimit; private final long fileOffset; - private final long filenameIndex; - private final long buildIdIndex; - private final ProtoEnumInfo buildIdKind; - private final List attributeIndices; + private final int filenameIndex; + private final List attributeIndices; private final boolean hasFunctions; private final boolean hasFilenames; private final boolean hasLineNumbers; private final boolean hasInlineFrames; static MappingMarshaler create(MappingData mappingData) { - ProtoEnumInfo buildKind = BuildIdKind.BUILD_ID_LINKER; - switch (mappingData.getBuildIdKind()) { - case LINKER: - buildKind = BuildIdKind.BUILD_ID_LINKER; - break; - case BINARY_HASH: - buildKind = BuildIdKind.BUILD_ID_BINARY_HASH; - break; - } return new MappingMarshaler( mappingData.getMemoryStart(), mappingData.getMemoryLimit(), mappingData.getFileOffset(), - mappingData.getFilenameIndex(), - mappingData.getBuildIdIndex(), - buildKind, + mappingData.getFilenameStringIndex(), mappingData.getAttributeIndices(), mappingData.hasFunctions(), mappingData.hasFilenames(), @@ -78,10 +63,8 @@ private MappingMarshaler( long memoryStart, long memoryLimit, long fileOffset, - long filenameIndex, - long buildIdIndex, - ProtoEnumInfo buildIdKind, - List attributeIndices, + int filenameIndex, + List attributeIndices, boolean hasFunctions, boolean hasFilenames, boolean hasLineNumbers, @@ -92,8 +75,6 @@ private MappingMarshaler( memoryLimit, fileOffset, filenameIndex, - buildIdIndex, - buildIdKind, attributeIndices, hasFunctions, hasFilenames, @@ -103,8 +84,6 @@ private MappingMarshaler( this.memoryLimit = memoryLimit; this.fileOffset = fileOffset; this.filenameIndex = filenameIndex; - this.buildIdIndex = buildIdIndex; - this.buildIdKind = buildIdKind; this.attributeIndices = attributeIndices; this.hasFunctions = hasFunctions; this.hasFilenames = hasFilenames; @@ -117,10 +96,8 @@ protected void writeTo(Serializer output) throws IOException { output.serializeUInt64(Mapping.MEMORY_START, memoryStart); output.serializeUInt64(Mapping.MEMORY_LIMIT, memoryLimit); output.serializeUInt64(Mapping.FILE_OFFSET, fileOffset); - output.serializeInt64(Mapping.FILENAME, filenameIndex); - output.serializeInt64(Mapping.BUILD_ID, buildIdIndex); - output.serializeEnum(Mapping.BUILD_ID_KIND, buildIdKind); - output.serializeRepeatedUInt64(Mapping.ATTRIBUTES, attributeIndices); + output.serializeInt32(Mapping.FILENAME_STRINDEX, filenameIndex); + output.serializeRepeatedInt32(Mapping.ATTRIBUTE_INDICES, attributeIndices); output.serializeBool(Mapping.HAS_FUNCTIONS, hasFunctions); output.serializeBool(Mapping.HAS_FILENAMES, hasFilenames); output.serializeBool(Mapping.HAS_LINE_NUMBERS, hasLineNumbers); @@ -131,10 +108,8 @@ private static int calculateSize( long memoryStart, long memoryLimit, long fileOffset, - long filenameIndex, - long buildIdIndex, - ProtoEnumInfo buildIdKind, - List attributeIndices, + int filenameIndex, + List attributeIndices, boolean hasFunctions, boolean hasFilenames, boolean hasLineNumbers, @@ -143,10 +118,8 @@ private static int calculateSize( size += MarshalerUtil.sizeUInt64(Mapping.MEMORY_START, memoryStart); size += MarshalerUtil.sizeUInt64(Mapping.MEMORY_LIMIT, memoryLimit); size += MarshalerUtil.sizeUInt64(Mapping.FILE_OFFSET, fileOffset); - size += MarshalerUtil.sizeInt64(Mapping.FILENAME, filenameIndex); - size += MarshalerUtil.sizeInt64(Mapping.BUILD_ID, buildIdIndex); - size += MarshalerUtil.sizeEnum(Mapping.BUILD_ID_KIND, buildIdKind); - size += MarshalerUtil.sizeRepeatedUInt64(Mapping.ATTRIBUTES, attributeIndices); + size += MarshalerUtil.sizeInt32(Mapping.FILENAME_STRINDEX, filenameIndex); + size += MarshalerUtil.sizeRepeatedInt32(Mapping.ATTRIBUTE_INDICES, attributeIndices); size += MarshalerUtil.sizeBool(Mapping.HAS_FUNCTIONS, hasFunctions); size += MarshalerUtil.sizeBool(Mapping.HAS_FILENAMES, hasFilenames); size += MarshalerUtil.sizeBool(Mapping.HAS_LINE_NUMBERS, hasLineNumbers); diff --git a/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/ProfileContainerData.java b/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/ProfileContainerData.java deleted file mode 100644 index f7e16f1ba0d..00000000000 --- a/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/ProfileContainerData.java +++ /dev/null @@ -1,92 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package io.opentelemetry.exporter.otlp.profiles; - -import io.opentelemetry.api.common.Attributes; -import io.opentelemetry.api.internal.OtelEncodingUtils; -import io.opentelemetry.sdk.common.InstrumentationScopeInfo; -import io.opentelemetry.sdk.resources.Resource; -import java.nio.ByteBuffer; -import javax.annotation.Nullable; -import javax.annotation.concurrent.Immutable; - -/** - * A ProfileContainer represents a single profile. It wraps pprof profile with OpenTelemetry - * specific metadata. - * - * @see "profiles.proto::ProfileContainer" - */ -@Immutable -public interface ProfileContainerData { - - /** Returns the resource of this profile. */ - Resource getResource(); - - /** Returns the instrumentation scope that generated this profile. */ - InstrumentationScopeInfo getInstrumentationScopeInfo(); - - /** - * Returns a globally unique identifier for a profile, as 32 character lowercase hex String. An ID - * with all zeroes is considered invalid. This field is required. - */ - String getProfileId(); - - /** - * Returns a globally unique identifier for a profile, as a 16 bytes array. An ID with all zeroes - * is considered invalid. This field is required. - */ - default byte[] getProfileIdBytes() { - return OtelEncodingUtils.bytesFromBase16(getProfileId(), 32); - } - - /** - * Returns the start time of the profile. Value is UNIX Epoch time in nanoseconds since 00:00:00 - * UTC on 1 January 1970. This field is semantically required and it is expected that end_time >= - * start_time. - */ - long getStartEpochNanos(); - - /** - * Returns the end time of the profile. Value is UNIX Epoch time in nanoseconds since 00:00:00 UTC - * on 1 January 1970. This field is semantically required and it is expected that end_time >= - * start_time. - */ - long getEndEpochNanos(); - - /** - * Returns profile-wide attributes. Attribute keys MUST be unique (it is not allowed to have more - * than one attribute with the same key). - * - * @see - * "https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/common/README.md#attribute" - */ - Attributes getAttributes(); - - /** - * Returns the total number of attributes that were recorded on this profile container. - * - *

      This number may be larger than the number of attributes that are attached to this profile - * container, if the total number recorded was greater than the configured maximum value. - */ - int getTotalAttributeCount(); - - /** - * Returns the format of the original payload. Common values are defined in semantic conventions. - * [required if original_payload is present] - */ - @Nullable - String getOriginalPayloadFormat(); - - /** - * Returns the original payload, in a profiler-native format e.g. JFR. Optional. Default behavior - * should be to not include the original payload. If the original payload is in pprof format, it - * SHOULD not be included in this field. - */ - ByteBuffer getOriginalPayload(); - - /** Returns an extended pprof profile. Required, even when originalPayload is also present. */ - ProfileData getProfile(); -} diff --git a/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/ProfileContainerMarshaler.java b/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/ProfileContainerMarshaler.java deleted file mode 100644 index 984a18c94a9..00000000000 --- a/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/ProfileContainerMarshaler.java +++ /dev/null @@ -1,113 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package io.opentelemetry.exporter.otlp.profiles; - -import io.opentelemetry.exporter.internal.marshal.MarshalerUtil; -import io.opentelemetry.exporter.internal.marshal.MarshalerWithSize; -import io.opentelemetry.exporter.internal.marshal.Serializer; -import io.opentelemetry.exporter.internal.otlp.KeyValueMarshaler; -import io.opentelemetry.proto.profiles.v1experimental.internal.ProfileContainer; -import java.io.IOException; -import java.nio.ByteBuffer; - -final class ProfileContainerMarshaler extends MarshalerWithSize { - - private final byte[] profileId; - private final long startEpochNanos; - private final long endEpochNanos; - private final KeyValueMarshaler[] attributeMarshalers; - private final int droppedAttributesCount; - private final byte[] originalPayloadFormatUtf8; - private final ByteBuffer originalPayload; - private final ProfileMarshaler profileMarshaler; - - static ProfileContainerMarshaler create(ProfileContainerData profileContainerData) { - int droppedAttributesCount = - profileContainerData.getTotalAttributeCount() - profileContainerData.getAttributes().size(); - - ByteBuffer originalPayload = profileContainerData.getOriginalPayload(); - if (originalPayload == null) { - originalPayload = ByteBuffer.allocate(0); - } else { - originalPayload = originalPayload.duplicate().asReadOnlyBuffer(); - } - - return new ProfileContainerMarshaler( - profileContainerData.getProfileIdBytes(), - profileContainerData.getStartEpochNanos(), - profileContainerData.getEndEpochNanos(), - KeyValueMarshaler.createForAttributes(profileContainerData.getAttributes()), - droppedAttributesCount, - MarshalerUtil.toBytes(profileContainerData.getOriginalPayloadFormat()), - originalPayload, - ProfileMarshaler.create(profileContainerData.getProfile())); - } - - private ProfileContainerMarshaler( - byte[] profileId, - long startEpochNanos, - long endEpochNanos, - KeyValueMarshaler[] attributeMarshalers, - int droppedAttributesCount, - byte[] originalPayloadFormat, - ByteBuffer originalPayload, - ProfileMarshaler profileMarshaler) { - super( - calculateSize( - profileId, - startEpochNanos, - endEpochNanos, - attributeMarshalers, - droppedAttributesCount, - originalPayloadFormat, - originalPayload, - profileMarshaler)); - this.profileId = profileId; - this.startEpochNanos = startEpochNanos; - this.endEpochNanos = endEpochNanos; - this.attributeMarshalers = attributeMarshalers; - this.droppedAttributesCount = droppedAttributesCount; - this.originalPayloadFormatUtf8 = originalPayloadFormat; - this.originalPayload = originalPayload; - this.profileMarshaler = profileMarshaler; - } - - @Override - protected void writeTo(Serializer output) throws IOException { - output.serializeBytes(ProfileContainer.PROFILE_ID, profileId); - output.serializeFixed64(ProfileContainer.START_TIME_UNIX_NANO, startEpochNanos); - output.serializeFixed64(ProfileContainer.END_TIME_UNIX_NANO, endEpochNanos); - output.serializeRepeatedMessage(ProfileContainer.ATTRIBUTES, attributeMarshalers); - output.serializeUInt32(ProfileContainer.DROPPED_ATTRIBUTES_COUNT, droppedAttributesCount); - output.serializeString(ProfileContainer.ORIGINAL_PAYLOAD_FORMAT, originalPayloadFormatUtf8); - output.serializeByteBuffer(ProfileContainer.ORIGINAL_PAYLOAD, originalPayload); - output.serializeMessage(ProfileContainer.PROFILE, profileMarshaler); - } - - private static int calculateSize( - byte[] profileId, - long startEpochNanos, - long endEpochNanos, - KeyValueMarshaler[] attributeMarshalers, - int droppedAttributesCount, - byte[] originalPayloadFormat, - ByteBuffer originalPayload, - ProfileMarshaler profileMarshaler) { - int size; - size = 0; - size += MarshalerUtil.sizeBytes(ProfileContainer.PROFILE_ID, profileId); - size += MarshalerUtil.sizeFixed64(ProfileContainer.START_TIME_UNIX_NANO, startEpochNanos); - size += MarshalerUtil.sizeFixed64(ProfileContainer.END_TIME_UNIX_NANO, endEpochNanos); - size += MarshalerUtil.sizeRepeatedMessage(ProfileContainer.ATTRIBUTES, attributeMarshalers); - size += - MarshalerUtil.sizeUInt32(ProfileContainer.DROPPED_ATTRIBUTES_COUNT, droppedAttributesCount); - size += - MarshalerUtil.sizeBytes(ProfileContainer.ORIGINAL_PAYLOAD_FORMAT, originalPayloadFormat); - size += MarshalerUtil.sizeByteBuffer(ProfileContainer.ORIGINAL_PAYLOAD, originalPayload); - size += MarshalerUtil.sizeMessage(ProfileContainer.PROFILE, profileMarshaler); - return size; - } -} diff --git a/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/ProfileData.java b/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/ProfileData.java index 63b26401de9..d6dd8709ed0 100644 --- a/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/ProfileData.java +++ b/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/ProfileData.java @@ -6,18 +6,29 @@ package io.opentelemetry.exporter.otlp.profiles; import io.opentelemetry.api.common.Attributes; +import io.opentelemetry.api.internal.OtelEncodingUtils; +import io.opentelemetry.sdk.common.InstrumentationScopeInfo; +import io.opentelemetry.sdk.resources.Resource; +import java.nio.ByteBuffer; import java.util.List; +import javax.annotation.Nullable; import javax.annotation.concurrent.Immutable; /** * Represents a complete profile, including sample types, samples, mappings to binaries, locations, * functions, string table, and additional metadata. * - * @see "pprofextended.proto::Profile" + * @see "profiles.proto::Profile" */ @Immutable public interface ProfileData { + /** Returns the resource of this profile. */ + Resource getResource(); + + /** Returns the instrumentation scope that generated this profile. */ + InstrumentationScopeInfo getInstrumentationScopeInfo(); + /** A description of the samples associated with each Sample.value. */ List getSampleTypes(); @@ -28,43 +39,31 @@ public interface ProfileData { * Mapping from address ranges to the image/binary/library mapped into that address range. * mapping[0] will be the main binary. */ - List getMappings(); + List getMappingTable(); /** Locations referenced by samples via location_indices. */ - List getLocations(); + List getLocationTable(); /** Array of locations referenced by samples. */ - List getLocationIndices(); + List getLocationIndices(); /** Functions referenced by locations. */ - List getFunctions(); + List getFunctionTable(); /** Lookup table for attributes. */ - Attributes getAttributes(); + Attributes getAttributeTable(); /** Represents a mapping between Attribute Keys and Units. */ List getAttributeUnits(); /** Lookup table for links. */ - List getLinks(); + List getLinkTable(); /** * A common table for strings referenced by various messages. string_table[0] must always be "". */ List getStringTable(); - /** - * Frames with Function.function_name fully matching the following regexp will be dropped from the - * samples, along with their successors. Index into string table. - */ - long getDropFrames(); - - /** - * Frames with Function.function_name fully matching the following regexp will be kept, even if - * matching drop_frames pattern. Index into string table. - */ - long getKeepFrames(); - /** Time of collection (UTC) represented as nanoseconds past the epoch. */ long getTimeNanos(); @@ -80,8 +79,53 @@ public interface ProfileData { long getPeriod(); /** Free-form text associated with the profile. Indices into string table. */ - List getComment(); + List getCommentStrIndices(); /** Type of the preferred sample. Index into the string table. */ - long getDefaultSampleType(); + int getDefaultSampleTypeStringIndex(); + + /** + * Returns a globally unique identifier for a profile, as 32 character lowercase hex String. An ID + * with all zeroes is considered invalid. This field is required. + */ + String getProfileId(); + + /** + * Returns a globally unique identifier for a profile, as a 16 bytes array. An ID with all zeroes + * is considered invalid. This field is required. + */ + default byte[] getProfileIdBytes() { + return OtelEncodingUtils.bytesFromBase16(getProfileId(), 32); + } + + /** + * Returns profile-wide attributes. Attribute keys MUST be unique (it is not allowed to have more + * than one attribute with the same key). + * + * @see + * "https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/common/README.md#attribute" + */ + Attributes getAttributes(); + + /** + * Returns the total number of attributes that were recorded on this profile. + * + *

      This number may be larger than the number of attributes that are attached to this profile, + * if the total number recorded was greater than the configured maximum value. + */ + int getTotalAttributeCount(); + + /** + * Returns the format of the original payload. Common values are defined in semantic conventions. + * [required if original_payload is present] + */ + @Nullable + String getOriginalPayloadFormat(); + + /** + * Returns the original payload, in a profiler-native format e.g. JFR. Optional. Default behavior + * should be to not include the original payload. If the original payload is in pprof format, it + * SHOULD not be included in this field. + */ + ByteBuffer getOriginalPayload(); } diff --git a/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/ProfileMarshaler.java b/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/ProfileMarshaler.java index bd6bc7521c8..04ea86c3263 100644 --- a/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/ProfileMarshaler.java +++ b/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/ProfileMarshaler.java @@ -9,8 +9,9 @@ import io.opentelemetry.exporter.internal.marshal.MarshalerWithSize; import io.opentelemetry.exporter.internal.marshal.Serializer; import io.opentelemetry.exporter.internal.otlp.KeyValueMarshaler; -import io.opentelemetry.proto.profiles.v1experimental.internal.Profile; +import io.opentelemetry.proto.profiles.v1development.internal.Profile; import java.io.IOException; +import java.nio.ByteBuffer; import java.nio.charset.StandardCharsets; import java.util.List; @@ -18,22 +19,25 @@ final class ProfileMarshaler extends MarshalerWithSize { private final ValueTypeMarshaler[] sampleTypeMarshalers; private final SampleMarshaler[] sampleMarshalers; - private final MappingMarshaler[] mappingMarshalers; - private final LocationMarshaler[] locationMarshalers; - private final List locationIndices; - private final FunctionMarshaler[] functionMarshalers; - private final KeyValueMarshaler[] attributeMarshalers; + private final MappingMarshaler[] mappingTableMarshalers; + private final LocationMarshaler[] locationTableMarshalers; + private final List locationIndices; + private final FunctionMarshaler[] functionTableMarshalers; + private final KeyValueMarshaler[] attributeTableMarshalers; private final AttributeUnitMarshaler[] attributeUnitMarshalers; - private final LinkMarshaler[] linkMarshalers; + private final LinkMarshaler[] linkTableMarshalers; private final byte[][] stringTable; - private final long dropFrames; - private final long keepFrames; private final long timeNanos; private final long durationNanos; private final ValueTypeMarshaler periodTypeMarshaler; private final long period; - private final List comment; - private final long defaultSampleType; + private final List comment; + private final int defaultSampleType; + private final byte[] profileId; + private final KeyValueMarshaler[] attributeMarshalers; + private final int droppedAttributesCount; + private final byte[] originalPayloadFormatUtf8; + private final ByteBuffer originalPayload; static ProfileMarshaler create(ProfileData profileData) { @@ -41,16 +45,16 @@ static ProfileMarshaler create(ProfileData profileData) { ValueTypeMarshaler.createRepeated(profileData.getSampleTypes()); SampleMarshaler[] sampleMarshalers = SampleMarshaler.createRepeated(profileData.getSamples()); MappingMarshaler[] mappingMarshalers = - MappingMarshaler.createRepeated(profileData.getMappings()); + MappingMarshaler.createRepeated(profileData.getMappingTable()); LocationMarshaler[] locationMarshalers = - LocationMarshaler.createRepeated(profileData.getLocations()); + LocationMarshaler.createRepeated(profileData.getLocationTable()); FunctionMarshaler[] functionMarshalers = - FunctionMarshaler.createRepeated(profileData.getFunctions()); + FunctionMarshaler.createRepeated(profileData.getFunctionTable()); KeyValueMarshaler[] attributeMarshalers = KeyValueMarshaler.createForAttributes(profileData.getAttributes()); AttributeUnitMarshaler[] attributeUnitsMarshalers = AttributeUnitMarshaler.createRepeated(profileData.getAttributeUnits()); - LinkMarshaler[] linkMarshalers = LinkMarshaler.createRepeated(profileData.getLinks()); + LinkMarshaler[] linkMarshalers = LinkMarshaler.createRepeated(profileData.getLinkTable()); ValueTypeMarshaler periodTypeMarshaler = ValueTypeMarshaler.create(profileData.getPeriodType()); byte[][] convertedStrings = new byte[profileData.getStringTable().size()][]; @@ -58,6 +62,9 @@ static ProfileMarshaler create(ProfileData profileData) { convertedStrings[i] = profileData.getStringTable().get(i).getBytes(StandardCharsets.UTF_8); } + int droppedAttributesCount = + profileData.getTotalAttributeCount() - profileData.getAttributes().size(); + return new ProfileMarshaler( sampleTypeMarshalers, sampleMarshalers, @@ -69,95 +76,111 @@ static ProfileMarshaler create(ProfileData profileData) { attributeUnitsMarshalers, linkMarshalers, convertedStrings, - profileData.getDropFrames(), - profileData.getKeepFrames(), profileData.getTimeNanos(), profileData.getDurationNanos(), periodTypeMarshaler, profileData.getPeriod(), - profileData.getComment(), - profileData.getDefaultSampleType()); + profileData.getCommentStrIndices(), + profileData.getDefaultSampleTypeStringIndex(), + profileData.getProfileIdBytes(), + KeyValueMarshaler.createForAttributes(profileData.getAttributes()), + droppedAttributesCount, + MarshalerUtil.toBytes(profileData.getOriginalPayloadFormat()), + profileData.getOriginalPayload()); } private ProfileMarshaler( ValueTypeMarshaler[] sampleTypeMarshalers, SampleMarshaler[] sampleMarshalers, - MappingMarshaler[] mappingMarshalers, - LocationMarshaler[] locationMarshalers, - List locationIndices, - FunctionMarshaler[] functionMarshalers, - KeyValueMarshaler[] attributeMarshalers, + MappingMarshaler[] mappingTableMarshalers, + LocationMarshaler[] locationTableMarshalers, + List locationIndices, + FunctionMarshaler[] functionTableMarshalers, + KeyValueMarshaler[] attributeTableMarshalers, AttributeUnitMarshaler[] attributeUnitMarshalers, - LinkMarshaler[] linkMarshalers, + LinkMarshaler[] linkTableMarshalers, byte[][] stringTableUtf8, - long dropFrames, - long keepFrames, long timeNanos, long durationNanos, ValueTypeMarshaler periodTypeMarshaler, long period, - List comment, - long defaultSampleType) { + List comment, + int defaultSampleType, + byte[] profileId, + KeyValueMarshaler[] attributeMarshalers, + int droppedAttributesCount, + byte[] originalPayloadFormat, + ByteBuffer originalPayload) { super( calculateSize( sampleTypeMarshalers, sampleMarshalers, - mappingMarshalers, - locationMarshalers, + mappingTableMarshalers, + locationTableMarshalers, locationIndices, - functionMarshalers, - attributeMarshalers, + functionTableMarshalers, + attributeTableMarshalers, attributeUnitMarshalers, - linkMarshalers, + linkTableMarshalers, stringTableUtf8, - dropFrames, - keepFrames, timeNanos, durationNanos, periodTypeMarshaler, period, comment, - defaultSampleType)); + defaultSampleType, + profileId, + attributeMarshalers, + droppedAttributesCount, + originalPayloadFormat, + originalPayload)); this.sampleTypeMarshalers = sampleTypeMarshalers; this.sampleMarshalers = sampleMarshalers; - this.mappingMarshalers = mappingMarshalers; - this.locationMarshalers = locationMarshalers; + this.mappingTableMarshalers = mappingTableMarshalers; + this.locationTableMarshalers = locationTableMarshalers; this.locationIndices = locationIndices; - this.functionMarshalers = functionMarshalers; - this.attributeMarshalers = attributeMarshalers; + this.functionTableMarshalers = functionTableMarshalers; + this.attributeTableMarshalers = attributeTableMarshalers; this.attributeUnitMarshalers = attributeUnitMarshalers; - this.linkMarshalers = linkMarshalers; + this.linkTableMarshalers = linkTableMarshalers; this.stringTable = stringTableUtf8; - this.dropFrames = dropFrames; - this.keepFrames = keepFrames; this.timeNanos = timeNanos; this.durationNanos = durationNanos; this.periodTypeMarshaler = periodTypeMarshaler; this.period = period; this.comment = comment; this.defaultSampleType = defaultSampleType; + this.profileId = profileId; + this.attributeMarshalers = attributeMarshalers; + this.droppedAttributesCount = droppedAttributesCount; + this.originalPayloadFormatUtf8 = originalPayloadFormat; + this.originalPayload = originalPayload; } @Override protected void writeTo(Serializer output) throws IOException { output.serializeRepeatedMessage(Profile.SAMPLE_TYPE, sampleTypeMarshalers); output.serializeRepeatedMessage(Profile.SAMPLE, sampleMarshalers); - output.serializeRepeatedMessage(Profile.MAPPING, mappingMarshalers); - output.serializeRepeatedMessage(Profile.LOCATION, locationMarshalers); - output.serializeRepeatedInt64(Profile.LOCATION_INDICES, locationIndices); - output.serializeRepeatedMessage(Profile.FUNCTION, functionMarshalers); - output.serializeRepeatedMessage(Profile.ATTRIBUTE_TABLE, attributeMarshalers); + output.serializeRepeatedMessage(Profile.MAPPING_TABLE, mappingTableMarshalers); + output.serializeRepeatedMessage(Profile.LOCATION_TABLE, locationTableMarshalers); + output.serializeRepeatedInt32(Profile.LOCATION_INDICES, locationIndices); + output.serializeRepeatedMessage(Profile.FUNCTION_TABLE, functionTableMarshalers); + output.serializeRepeatedMessage(Profile.ATTRIBUTE_TABLE, attributeTableMarshalers); output.serializeRepeatedMessage(Profile.ATTRIBUTE_UNITS, attributeUnitMarshalers); - output.serializeRepeatedMessage(Profile.LINK_TABLE, linkMarshalers); + output.serializeRepeatedMessage(Profile.LINK_TABLE, linkTableMarshalers); output.serializeRepeatedString(Profile.STRING_TABLE, stringTable); - output.serializeInt64(Profile.DROP_FRAMES, dropFrames); - output.serializeInt64(Profile.KEEP_FRAMES, keepFrames); output.serializeInt64(Profile.TIME_NANOS, timeNanos); output.serializeInt64(Profile.DURATION_NANOS, durationNanos); output.serializeMessage(Profile.PERIOD_TYPE, periodTypeMarshaler); output.serializeInt64(Profile.PERIOD, period); - output.serializeRepeatedInt64(Profile.COMMENT, comment); - output.serializeInt64(Profile.DEFAULT_SAMPLE_TYPE, defaultSampleType); + output.serializeRepeatedInt32(Profile.COMMENT_STRINDICES, comment); + output.serializeInt32(Profile.DEFAULT_SAMPLE_TYPE_STRINDEX, defaultSampleType); + + output.serializeBytes(Profile.PROFILE_ID, profileId); + output.serializeRepeatedMessage(Profile.ATTRIBUTES, attributeMarshalers); + output.serializeUInt32(Profile.DROPPED_ATTRIBUTES_COUNT, droppedAttributesCount); + output.serializeString(Profile.ORIGINAL_PAYLOAD_FORMAT, originalPayloadFormatUtf8); + output.serializeByteBuffer(Profile.ORIGINAL_PAYLOAD, originalPayload); } private static int calculateSize( @@ -165,40 +188,48 @@ private static int calculateSize( SampleMarshaler[] sampleMarshalers, MappingMarshaler[] mappingMarshalers, LocationMarshaler[] locationMarshalers, - List locationIndices, + List locationIndices, FunctionMarshaler[] functionMarshalers, - KeyValueMarshaler[] attributeMarshalers, + KeyValueMarshaler[] attributeTableMarshalers, AttributeUnitMarshaler[] attributeUnitMarshalers, LinkMarshaler[] linkMarshalers, byte[][] stringTable, - long dropFrames, - long keepFrames, long timeNanos, long durationNanos, ValueTypeMarshaler periodTypeMarshaler, long period, - List comment, - long defaultSampleType) { + List comment, + int defaultSampleType, + byte[] profileId, + KeyValueMarshaler[] attributeMarshalers, + int droppedAttributesCount, + byte[] originalPayloadFormat, + ByteBuffer originalPayload) { int size; size = 0; size += MarshalerUtil.sizeRepeatedMessage(Profile.SAMPLE_TYPE, sampleTypeMarshalers); size += MarshalerUtil.sizeRepeatedMessage(Profile.SAMPLE, sampleMarshalers); - size += MarshalerUtil.sizeRepeatedMessage(Profile.MAPPING, mappingMarshalers); - size += MarshalerUtil.sizeRepeatedMessage(Profile.LOCATION, locationMarshalers); - size += MarshalerUtil.sizeRepeatedInt64(Profile.LOCATION_INDICES, locationIndices); - size += MarshalerUtil.sizeRepeatedMessage(Profile.FUNCTION, functionMarshalers); - size += MarshalerUtil.sizeRepeatedMessage(Profile.ATTRIBUTE_TABLE, attributeMarshalers); + size += MarshalerUtil.sizeRepeatedMessage(Profile.MAPPING_TABLE, mappingMarshalers); + size += MarshalerUtil.sizeRepeatedMessage(Profile.LOCATION_TABLE, locationMarshalers); + size += MarshalerUtil.sizeRepeatedInt32(Profile.LOCATION_INDICES, locationIndices); + size += MarshalerUtil.sizeRepeatedMessage(Profile.FUNCTION_TABLE, functionMarshalers); + size += MarshalerUtil.sizeRepeatedMessage(Profile.ATTRIBUTE_TABLE, attributeTableMarshalers); size += MarshalerUtil.sizeRepeatedMessage(Profile.ATTRIBUTE_UNITS, attributeUnitMarshalers); size += MarshalerUtil.sizeRepeatedMessage(Profile.LINK_TABLE, linkMarshalers); size += MarshalerUtil.sizeRepeatedString(Profile.STRING_TABLE, stringTable); - size += MarshalerUtil.sizeInt64(Profile.DROP_FRAMES, dropFrames); - size += MarshalerUtil.sizeInt64(Profile.KEEP_FRAMES, keepFrames); size += MarshalerUtil.sizeInt64(Profile.TIME_NANOS, timeNanos); size += MarshalerUtil.sizeInt64(Profile.DURATION_NANOS, durationNanos); size += MarshalerUtil.sizeMessage(Profile.PERIOD_TYPE, periodTypeMarshaler); size += MarshalerUtil.sizeInt64(Profile.PERIOD, period); - size += MarshalerUtil.sizeRepeatedInt64(Profile.COMMENT, comment); - size += MarshalerUtil.sizeInt64(Profile.DEFAULT_SAMPLE_TYPE, defaultSampleType); + size += MarshalerUtil.sizeRepeatedInt32(Profile.COMMENT_STRINDICES, comment); + size += MarshalerUtil.sizeInt64(Profile.DEFAULT_SAMPLE_TYPE_STRINDEX, defaultSampleType); + + size += MarshalerUtil.sizeBytes(Profile.PROFILE_ID, profileId); + size += MarshalerUtil.sizeRepeatedMessage(Profile.ATTRIBUTES, attributeMarshalers); + size += MarshalerUtil.sizeInt32(Profile.DROPPED_ATTRIBUTES_COUNT, droppedAttributesCount); + size += MarshalerUtil.sizeBytes(Profile.ORIGINAL_PAYLOAD_FORMAT, originalPayloadFormat); + size += MarshalerUtil.sizeByteBuffer(Profile.ORIGINAL_PAYLOAD, originalPayload); + return size; } } diff --git a/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/ProfilesRequestMarshaler.java b/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/ProfilesRequestMarshaler.java index 1d341449a6c..3d57825899a 100644 --- a/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/ProfilesRequestMarshaler.java +++ b/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/ProfilesRequestMarshaler.java @@ -10,13 +10,12 @@ import io.opentelemetry.exporter.internal.marshal.MarshalerWithSize; import io.opentelemetry.exporter.internal.marshal.ProtoFieldInfo; import io.opentelemetry.exporter.internal.marshal.Serializer; -import io.opentelemetry.proto.collector.profiles.v1experimental.internal.ExportProfilesServiceRequest; +import io.opentelemetry.proto.collector.profiles.v1development.internal.ExportProfilesServiceRequest; import java.io.IOException; import java.util.Collection; /** - * {@link Marshaler} to convert SDK {@link ProfileContainerData} to OTLP - * ExportProfilesServiceRequest. + * {@link Marshaler} to convert SDK {@link ProfileData} to OTLP ExportProfilesServiceRequest. * *

      This class is internal and is hence not for public use. Its APIs are unstable and can change * at any time. @@ -30,11 +29,10 @@ public final class ProfilesRequestMarshaler extends MarshalerWithSize { /** * Returns a {@link ProfilesRequestMarshaler} that can be used to convert the provided {@link - * ProfileContainerData} into a serialized OTLP ExportProfilesServiceRequest. + * ProfileData} into a serialized OTLP ExportProfilesServiceRequest. */ - public static ProfilesRequestMarshaler create( - Collection profileContainerList) { - return new ProfilesRequestMarshaler(ResourceProfilesMarshaler.create(profileContainerList)); + public static ProfilesRequestMarshaler create(Collection profileList) { + return new ProfilesRequestMarshaler(ResourceProfilesMarshaler.create(profileList)); } private ProfilesRequestMarshaler(ResourceProfilesMarshaler[] resourceProfilesMarshalers) { diff --git a/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/ResourceProfilesMarshaler.java b/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/ResourceProfilesMarshaler.java index 4000ff5f373..442604cead2 100644 --- a/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/ResourceProfilesMarshaler.java +++ b/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/ResourceProfilesMarshaler.java @@ -10,7 +10,7 @@ import io.opentelemetry.exporter.internal.marshal.Serializer; import io.opentelemetry.exporter.internal.otlp.InstrumentationScopeMarshaler; import io.opentelemetry.exporter.internal.otlp.ResourceMarshaler; -import io.opentelemetry.proto.profiles.v1experimental.internal.ResourceProfiles; +import io.opentelemetry.proto.profiles.v1development.internal.ResourceProfiles; import io.opentelemetry.sdk.common.InstrumentationScopeInfo; import io.opentelemetry.sdk.resources.Resource; import java.io.IOException; @@ -26,20 +26,20 @@ final class ResourceProfilesMarshaler extends MarshalerWithSize { /** Returns Marshalers of ResourceProfiles created by grouping the provided Profiles. */ @SuppressWarnings("AvoidObjectArrays") - static ResourceProfilesMarshaler[] create(Collection profiles) { - Map>> - resourceAndScopeMap = groupByResourceAndScope(profiles); + static ResourceProfilesMarshaler[] create(Collection profiles) { + Map>> resourceAndScopeMap = + groupByResourceAndScope(profiles); ResourceProfilesMarshaler[] resourceProfilesMarshalers = new ResourceProfilesMarshaler[resourceAndScopeMap.size()]; int posResource = 0; - for (Map.Entry>> entry : + for (Map.Entry>> entry : resourceAndScopeMap.entrySet()) { InstrumentationScopeProfilesMarshaler[] instrumentationLibrarySpansMarshalers = new InstrumentationScopeProfilesMarshaler[entry.getValue().size()]; int posInstrumentation = 0; - for (Map.Entry> entryIs : + for (Map.Entry> entryIs : entry.getValue().entrySet()) { instrumentationLibrarySpansMarshalers[posInstrumentation++] = new InstrumentationScopeProfilesMarshaler( @@ -89,12 +89,12 @@ private static int calculateSize( return size; } - private static Map>> - groupByResourceAndScope(Collection profiles) { + private static Map>> + groupByResourceAndScope(Collection profiles) { return MarshalerUtil.groupByResourceAndScope( profiles, - ProfileContainerData::getResource, - ProfileContainerData::getInstrumentationScopeInfo, - ProfileContainerMarshaler::create); + ProfileData::getResource, + ProfileData::getInstrumentationScopeInfo, + ProfileMarshaler::create); } } diff --git a/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/SampleData.java b/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/SampleData.java index f5671511421..ef565b53f86 100644 --- a/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/SampleData.java +++ b/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/SampleData.java @@ -13,7 +13,7 @@ * a stack trace, perhaps augmented with auxiliary information like the thread-id, some indicator of * a higher level request being handled etc. * - * @see "pprofextended.proto::Sample" + * @see "profiles.proto::Sample" */ @Immutable public interface SampleData { @@ -22,19 +22,13 @@ public interface SampleData { * locationsStartIndex along with locationsLength refers to a slice of locations in * Profile.location. Supersedes locationIndices. */ - long getLocationsStartIndex(); + int getLocationsStartIndex(); /** * locationsLength along with locationsStartIndex refers to a slice of locations in * Profile.location. locationIndices. */ - long getLocationsLength(); - - /** - * reference to a 128bit id that uniquely identifies this stacktrace, globally. Index into the - * string table. - */ - int getStacktraceIdIndex(); + int getLocationsLength(); /** * The type and unit of each value is defined by the corresponding entry in Profile.sample_type. @@ -42,10 +36,10 @@ public interface SampleData { List getValues(); /** References to attributes in Profile.attribute_table. */ - List getAttributes(); + List getAttributeIndices(); /** Reference to link in Profile.link_table. */ - long getLink(); + Integer getLinkIndex(); /** * Timestamps associated with Sample represented in ms. These timestamps are expected to fall diff --git a/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/SampleMarshaler.java b/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/SampleMarshaler.java index 0c9cd4ae71e..d6bb2c31c94 100644 --- a/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/SampleMarshaler.java +++ b/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/SampleMarshaler.java @@ -8,21 +8,21 @@ import io.opentelemetry.exporter.internal.marshal.MarshalerUtil; import io.opentelemetry.exporter.internal.marshal.MarshalerWithSize; import io.opentelemetry.exporter.internal.marshal.Serializer; -import io.opentelemetry.proto.profiles.v1experimental.internal.Sample; +import io.opentelemetry.proto.profiles.v1development.internal.Sample; import java.io.IOException; import java.util.List; import java.util.function.Consumer; +import javax.annotation.Nullable; final class SampleMarshaler extends MarshalerWithSize { private static final SampleMarshaler[] EMPTY_REPEATED = new SampleMarshaler[0]; - private final long locationsStartIndex; - private final long locationsLength; - private final int stacktraceIdIndex; + private final int locationsStartIndex; + private final int locationsLength; private final List values; - private final List attributes; - private final long link; + private final List attributesIndices; + @Nullable private final Integer linkIndex; private final List timestamps; static SampleMarshaler create(SampleData sampleData) { @@ -30,10 +30,9 @@ static SampleMarshaler create(SampleData sampleData) { return new SampleMarshaler( sampleData.getLocationsStartIndex(), sampleData.getLocationsLength(), - sampleData.getStacktraceIdIndex(), sampleData.getValues(), - sampleData.getAttributes(), - sampleData.getLink(), + sampleData.getAttributeIndices(), + sampleData.getLinkIndex(), sampleData.getTimestamps()); } @@ -57,58 +56,52 @@ public void accept(SampleData sampleData) { } private SampleMarshaler( - long locationsStartIndex, - long locationsLength, - int stacktraceIdIndex, + int locationsStartIndex, + int locationsLength, List values, - List attributes, - long link, + List attributesIndices, + @Nullable Integer linkIndex, List timestamps) { super( calculateSize( locationsStartIndex, locationsLength, - stacktraceIdIndex, values, - attributes, - link, + attributesIndices, + linkIndex, timestamps)); this.locationsStartIndex = locationsStartIndex; this.locationsLength = locationsLength; - this.stacktraceIdIndex = stacktraceIdIndex; this.values = values; - this.attributes = attributes; - this.link = link; + this.attributesIndices = attributesIndices; + this.linkIndex = linkIndex; this.timestamps = timestamps; } @Override protected void writeTo(Serializer output) throws IOException { - output.serializeUInt64(Sample.LOCATIONS_START_INDEX, locationsStartIndex); - output.serializeUInt64(Sample.LOCATIONS_LENGTH, locationsLength); - output.serializeUInt32(Sample.STACKTRACE_ID_INDEX, stacktraceIdIndex); + output.serializeInt32(Sample.LOCATIONS_START_INDEX, locationsStartIndex); + output.serializeInt32(Sample.LOCATIONS_LENGTH, locationsLength); output.serializeRepeatedInt64(Sample.VALUE, values); - output.serializeRepeatedUInt64(Sample.ATTRIBUTES, attributes); - output.serializeUInt64(Sample.LINK, link); + output.serializeRepeatedInt32(Sample.ATTRIBUTE_INDICES, attributesIndices); + output.serializeInt32Optional(Sample.LINK_INDEX, linkIndex); output.serializeRepeatedUInt64(Sample.TIMESTAMPS_UNIX_NANO, timestamps); } private static int calculateSize( - long locationsStartIndex, - long locationsLength, - int stacktraceIdIndex, + int locationsStartIndex, + int locationsLength, List values, - List attributes, - long link, + List attributesIndices, + @Nullable Integer linkIndex, List timestamps) { int size; size = 0; - size += MarshalerUtil.sizeUInt64(Sample.LOCATIONS_START_INDEX, locationsStartIndex); - size += MarshalerUtil.sizeUInt64(Sample.LOCATIONS_LENGTH, locationsLength); - size += MarshalerUtil.sizeUInt32(Sample.STACKTRACE_ID_INDEX, stacktraceIdIndex); + size += MarshalerUtil.sizeInt32(Sample.LOCATIONS_START_INDEX, locationsStartIndex); + size += MarshalerUtil.sizeInt32(Sample.LOCATIONS_LENGTH, locationsLength); size += MarshalerUtil.sizeRepeatedInt64(Sample.VALUE, values); - size += MarshalerUtil.sizeRepeatedUInt64(Sample.ATTRIBUTES, attributes); - size += MarshalerUtil.sizeUInt64(Sample.LINK, link); + size += MarshalerUtil.sizeRepeatedInt32(Sample.ATTRIBUTE_INDICES, attributesIndices); + size += MarshalerUtil.sizeInt32Optional(Sample.LINK_INDEX, linkIndex); size += MarshalerUtil.sizeRepeatedUInt64(Sample.TIMESTAMPS_UNIX_NANO, timestamps); return size; } diff --git a/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/ValueTypeData.java b/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/ValueTypeData.java index 22c18787b32..10aac94b71a 100644 --- a/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/ValueTypeData.java +++ b/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/ValueTypeData.java @@ -11,17 +11,17 @@ /** * ValueType describes the type and units of a value, with an optional aggregation temporality. * - * @see "pprofextended.proto::ValueType" + * @see "profiles.proto::ValueType" */ @Immutable public interface ValueTypeData { /** Index into string table. */ - long type(); + int getTypeStringIndex(); /** Index into string table. */ - long unit(); + int getUnitStringIndex(); @Nullable - AggregationTemporality aggregationTemporality(); + AggregationTemporality getAggregationTemporality(); } diff --git a/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/ValueTypeMarshaler.java b/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/ValueTypeMarshaler.java index e880b3dded9..a52621b119c 100644 --- a/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/ValueTypeMarshaler.java +++ b/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/ValueTypeMarshaler.java @@ -9,8 +9,8 @@ import io.opentelemetry.exporter.internal.marshal.MarshalerWithSize; import io.opentelemetry.exporter.internal.marshal.ProtoEnumInfo; import io.opentelemetry.exporter.internal.marshal.Serializer; -import io.opentelemetry.proto.profiles.v1experimental.internal.AggregationTemporality; -import io.opentelemetry.proto.profiles.v1experimental.internal.ValueType; +import io.opentelemetry.proto.profiles.v1development.internal.AggregationTemporality; +import io.opentelemetry.proto.profiles.v1development.internal.ValueType; import java.io.IOException; import java.util.List; import java.util.function.Consumer; @@ -19,15 +19,15 @@ final class ValueTypeMarshaler extends MarshalerWithSize { private static final ValueTypeMarshaler[] EMPTY_REPEATED = new ValueTypeMarshaler[0]; - private final long type; - private final long unit; + private final int typeStringIndex; + private final int unitStringIndex; private final ProtoEnumInfo aggregationTemporality; static ValueTypeMarshaler create(ValueTypeData valueTypeData) { ProtoEnumInfo aggregationTemporality = AggregationTemporality.AGGREGATION_TEMPORALITY_UNSPECIFIED; - if (valueTypeData.aggregationTemporality() != null) { - switch (valueTypeData.aggregationTemporality()) { + if (valueTypeData.getAggregationTemporality() != null) { + switch (valueTypeData.getAggregationTemporality()) { case DELTA: aggregationTemporality = AggregationTemporality.AGGREGATION_TEMPORALITY_DELTA; break; @@ -37,7 +37,9 @@ static ValueTypeMarshaler create(ValueTypeData valueTypeData) { } } return new ValueTypeMarshaler( - valueTypeData.type(), valueTypeData.unit(), aggregationTemporality); + valueTypeData.getTypeStringIndex(), + valueTypeData.getUnitStringIndex(), + aggregationTemporality); } static ValueTypeMarshaler[] createRepeated(List items) { @@ -59,25 +61,27 @@ public void accept(ValueTypeData valueTypeData) { return valueTypeMarshalers; } - private ValueTypeMarshaler(long type, long unit, ProtoEnumInfo aggregationTemporality) { - super(calculateSize(type, unit, aggregationTemporality)); - this.type = type; - this.unit = unit; + private ValueTypeMarshaler( + int typeStringIndex, int unitStringIndex, ProtoEnumInfo aggregationTemporality) { + super(calculateSize(typeStringIndex, unitStringIndex, aggregationTemporality)); + this.typeStringIndex = typeStringIndex; + this.unitStringIndex = unitStringIndex; this.aggregationTemporality = aggregationTemporality; } @Override protected void writeTo(Serializer output) throws IOException { - output.serializeInt64(ValueType.TYPE, type); - output.serializeInt64(ValueType.UNIT, unit); + output.serializeInt64(ValueType.TYPE_STRINDEX, typeStringIndex); + output.serializeInt64(ValueType.UNIT_STRINDEX, unitStringIndex); output.serializeEnum(ValueType.AGGREGATION_TEMPORALITY, aggregationTemporality); } - private static int calculateSize(long type, long unit, ProtoEnumInfo aggregationTemporality) { + private static int calculateSize( + int typeStringIndex, int unitStringIndex, ProtoEnumInfo aggregationTemporality) { int size; size = 0; - size += MarshalerUtil.sizeInt64(ValueType.TYPE, type); - size += MarshalerUtil.sizeInt64(ValueType.UNIT, unit); + size += MarshalerUtil.sizeInt32(ValueType.TYPE_STRINDEX, typeStringIndex); + size += MarshalerUtil.sizeInt32(ValueType.UNIT_STRINDEX, unitStringIndex); size += MarshalerUtil.sizeEnum(ValueType.AGGREGATION_TEMPORALITY, aggregationTemporality); return size; } diff --git a/exporters/otlp/profiles/src/test/java/io/opentelemetry/exporter/otlp/profiles/ProfilesRequestMarshalerTest.java b/exporters/otlp/profiles/src/test/java/io/opentelemetry/exporter/otlp/profiles/ProfilesRequestMarshalerTest.java index 3d0ca5dda53..1046caeb557 100644 --- a/exporters/otlp/profiles/src/test/java/io/opentelemetry/exporter/otlp/profiles/ProfilesRequestMarshalerTest.java +++ b/exporters/otlp/profiles/src/test/java/io/opentelemetry/exporter/otlp/profiles/ProfilesRequestMarshalerTest.java @@ -19,23 +19,21 @@ import io.opentelemetry.exporter.otlp.internal.data.ImmutableLinkData; import io.opentelemetry.exporter.otlp.internal.data.ImmutableLocationData; import io.opentelemetry.exporter.otlp.internal.data.ImmutableMappingData; -import io.opentelemetry.exporter.otlp.internal.data.ImmutableProfileContainerData; import io.opentelemetry.exporter.otlp.internal.data.ImmutableProfileData; import io.opentelemetry.exporter.otlp.internal.data.ImmutableSampleData; import io.opentelemetry.exporter.otlp.internal.data.ImmutableValueTypeData; import io.opentelemetry.proto.common.v1.InstrumentationScope; -import io.opentelemetry.proto.profiles.v1experimental.AttributeUnit; -import io.opentelemetry.proto.profiles.v1experimental.Function; -import io.opentelemetry.proto.profiles.v1experimental.Line; -import io.opentelemetry.proto.profiles.v1experimental.Link; -import io.opentelemetry.proto.profiles.v1experimental.Location; -import io.opentelemetry.proto.profiles.v1experimental.Mapping; -import io.opentelemetry.proto.profiles.v1experimental.Profile; -import io.opentelemetry.proto.profiles.v1experimental.ProfileContainer; -import io.opentelemetry.proto.profiles.v1experimental.ResourceProfiles; -import io.opentelemetry.proto.profiles.v1experimental.Sample; -import io.opentelemetry.proto.profiles.v1experimental.ScopeProfiles; -import io.opentelemetry.proto.profiles.v1experimental.ValueType; +import io.opentelemetry.proto.profiles.v1development.AttributeUnit; +import io.opentelemetry.proto.profiles.v1development.Function; +import io.opentelemetry.proto.profiles.v1development.Line; +import io.opentelemetry.proto.profiles.v1development.Link; +import io.opentelemetry.proto.profiles.v1development.Location; +import io.opentelemetry.proto.profiles.v1development.Mapping; +import io.opentelemetry.proto.profiles.v1development.Profile; +import io.opentelemetry.proto.profiles.v1development.ResourceProfiles; +import io.opentelemetry.proto.profiles.v1development.Sample; +import io.opentelemetry.proto.profiles.v1development.ScopeProfiles; +import io.opentelemetry.proto.profiles.v1development.ValueType; import io.opentelemetry.sdk.common.InstrumentationScopeInfo; import io.opentelemetry.sdk.resources.Resource; import java.io.ByteArrayOutputStream; @@ -50,11 +48,11 @@ import org.junit.jupiter.api.Test; public class ProfilesRequestMarshalerTest { - @Test void compareAttributeUnitMarshaling() { AttributeUnitData input = ImmutableAttributeUnitData.create(1, 2); - AttributeUnit builderResult = AttributeUnit.newBuilder().setAttributeKey(1).setUnit(2).build(); + AttributeUnit builderResult = + AttributeUnit.newBuilder().setAttributeKeyStrindex(1).setUnitStrindex(2).build(); AttributeUnit roundTripResult = parse(AttributeUnit.getDefaultInstance(), AttributeUnitMarshaler.create(input)); @@ -65,7 +63,12 @@ void compareAttributeUnitMarshaling() { void compareFunctionMarshaling() { FunctionData input = ImmutableFunctionData.create(1, 2, 3, 4); Function builderResult = - Function.newBuilder().setName(1).setSystemName(2).setFilename(3).setStartLine(4).build(); + Function.newBuilder() + .setNameStrindex(1) + .setSystemNameStrindex(2) + .setFilenameStrindex(3) + .setStartLine(4) + .build(); Function roundTripResult = parse(Function.getDefaultInstance(), FunctionMarshaler.create(input)); @@ -99,14 +102,13 @@ void compareLinkMarshaling() { @Test void compareLocationMarshaling() { LocationData input = - ImmutableLocationData.create(1, 2, Collections.emptyList(), true, 3, listOf(5L, 6L)); + ImmutableLocationData.create(1, 2, Collections.emptyList(), true, listOf(4, 5)); Location builderResult = Location.newBuilder() .setMappingIndex(1) .setAddress(2) .setIsFolded(true) - .setTypeIndex(3) - .addAllAttributes(listOf(5L, 6L)) + .addAllAttributeIndices(listOf(4, 5)) .build(); Location roundTripResult = @@ -117,18 +119,14 @@ void compareLocationMarshaling() { @Test void compareMappingMarshaling() { MappingData input = - ImmutableMappingData.create( - 1, 2, 3, 4, 5, BuildIdKind.LINKER, listOf(6L, 7L), true, true, true, true); + ImmutableMappingData.create(1, 2, 3, 4, listOf(5, 6), true, true, true, true); Mapping builderResult = Mapping.newBuilder() .setMemoryStart(1) .setMemoryLimit(2) .setFileOffset(3) - .setFilename(4) - .setBuildId(5) - .setBuildIdKind( - io.opentelemetry.proto.profiles.v1experimental.BuildIdKind.BUILD_ID_LINKER) - .addAllAttributes(listOf(6L, 7L)) + .setFilenameStrindex(4) + .addAllAttributeIndices(listOf(5, 6)) .setHasFunctions(true) .setHasFilenames(true) .setHasLineNumbers(true) @@ -139,67 +137,58 @@ void compareMappingMarshaling() { assertThat(roundTripResult).isEqualTo(builderResult); } - @Test - void compareProfileContainerMarshaling() { - String profileId = "0123456789abcdef0123456789abcdef"; - ProfileContainerData input = - ImmutableProfileContainerData.create( - Resource.getDefault(), - InstrumentationScopeInfo.empty(), - profileId, - 1, - 2, - Attributes.empty(), - 3, - "format", - ByteBuffer.wrap(new byte[] {4, 5}), - sampleProfileData()); - - ProfileContainer builderResult = - ProfileContainer.newBuilder() - .setProfileId(ByteString.fromHex(profileId)) - .setStartTimeUnixNano(1) - .setEndTimeUnixNano(2) - .setDroppedAttributesCount(3) - .setOriginalPayloadFormat("format") - .setOriginalPayload(ByteString.copyFrom(new byte[] {4, 5})) - .setProfile(sampleProfileBuilder().build()) - .build(); - - ProfileContainer roundTripResult = - parse(ProfileContainer.getDefaultInstance(), ProfileContainerMarshaler.create(input)); - assertThat(roundTripResult).isEqualTo(builderResult); - } - @Test void compareResourceProfilesMarshaling() { String profileId = "0123456789abcdef0123456789abcdef"; - ProfileContainerData profileContainerData = - ImmutableProfileContainerData.create( + ProfileData profileContainerData = + ImmutableProfileData.create( Resource.create(Attributes.empty()), InstrumentationScopeInfo.create("testscope"), + Collections.emptyList(), + Collections.emptyList(), + Collections.emptyList(), + Collections.emptyList(), + listOf(1, 2), + Collections.emptyList(), + Attributes.empty(), + Collections.emptyList(), + Collections.emptyList(), + Collections.emptyList(), + 5L, + 6L, + ImmutableValueTypeData.create(1, 2, AggregationTemporality.CUMULATIVE), + 7L, + listOf(8, 9), + 0, profileId, - 1, - 2, Attributes.empty(), 3, "format", - ByteBuffer.wrap(new byte[] {4, 5}), - sampleProfileData()); + ByteBuffer.wrap(new byte[] {4, 5})); - Collection input = new ArrayList<>(); + Collection input = new ArrayList<>(); input.add(profileContainerData); - ProfileContainer profileContainer = - ProfileContainer.newBuilder() + Profile profileContainer = + Profile.newBuilder() .setProfileId(ByteString.fromHex(profileId)) - .setStartTimeUnixNano(1) - .setEndTimeUnixNano(2) .setDroppedAttributesCount(3) .setOriginalPayloadFormat("format") .setOriginalPayload(ByteString.copyFrom(new byte[] {4, 5})) - .setProfile(sampleProfileBuilder().build()) + .addAllLocationIndices(listOf(1, 2)) + .setTimeNanos(5) + .setDurationNanos(6) + .setPeriod(7) + .setPeriodType( + ValueType.newBuilder() + .setTypeStrindex(1) + .setUnitStrindex(2) + .setAggregationTemporality( + io.opentelemetry.proto.profiles.v1development.AggregationTemporality + .AGGREGATION_TEMPORALITY_CUMULATIVE) + .build()) + .addAllCommentStrindices(listOf(8, 9)) .build(); ResourceProfiles builderResult = @@ -216,30 +205,20 @@ void compareResourceProfilesMarshaling() { assertThat(marshalers.length).isEqualTo(1); ResourceProfiles roundTripResult = parse(ResourceProfiles.getDefaultInstance(), marshalers[0]); assertThat(roundTripResult).isEqualTo(builderResult); - // TODO - } - - @Test - void compareProfileMarshaling() { - ProfileData input = sampleProfileData(); - Profile builderResult = sampleProfileBuilder().build(); - Profile roundTripResult = parse(Profile.getDefaultInstance(), ProfileMarshaler.create(input)); - assertThat(roundTripResult).isEqualTo(builderResult); } @Test void compareSampleMarshaling() { SampleData input = - ImmutableSampleData.create(1, 2, 3, listOf(4L, 5L), listOf(6L, 7L), 8L, listOf(9L, 10L)); + ImmutableSampleData.create(1, 2, listOf(3L, 4L), listOf(5, 6), 7, listOf(8L, 9L)); Sample builderResult = Sample.newBuilder() .setLocationsStartIndex(1) .setLocationsLength(2) - .setStacktraceIdIndex(3) - .addAllValue(listOf(4L, 5L)) - .addAllAttributes(listOf(6L, 7L)) - .setLink(8) - .addAllTimestampsUnixNano(listOf(9L, 10L)) + .addAllValue(listOf(3L, 4L)) + .addAllAttributeIndices(listOf(5, 6)) + .setLinkIndex(7) + .addAllTimestampsUnixNano(listOf(8L, 9L)) .build(); Sample roundTripResult = parse(Sample.getDefaultInstance(), SampleMarshaler.create(input)); @@ -251,10 +230,10 @@ void compareValueTypeMarshaling() { ValueTypeData input = ImmutableValueTypeData.create(1, 2, AggregationTemporality.CUMULATIVE); ValueType builderResult = ValueType.newBuilder() - .setType(1) - .setUnit(2) + .setTypeStrindex(1) + .setUnitStrindex(2) .setAggregationTemporality( - io.opentelemetry.proto.profiles.v1experimental.AggregationTemporality + io.opentelemetry.proto.profiles.v1development.AggregationTemporality .AGGREGATION_TEMPORALITY_CUMULATIVE) .build(); @@ -263,52 +242,6 @@ void compareValueTypeMarshaling() { assertThat(roundTripResult).isEqualTo(builderResult); } - // twin of sampleProfileBuilder - private static ProfileData sampleProfileData() { - return ImmutableProfileData.create( - Collections.emptyList(), - Collections.emptyList(), - Collections.emptyList(), - Collections.emptyList(), - listOf(1L, 2L), - Collections.emptyList(), - Attributes.empty(), - Collections.emptyList(), - Collections.emptyList(), - listOf("foo", "bar"), - 3, - 4, - 5, - 6, - ImmutableValueTypeData.create(1, 2, AggregationTemporality.CUMULATIVE), - 7, - listOf(8L, 9L), - 10); - } - - // twin of sampleProfileData - private static Profile.Builder sampleProfileBuilder() { - return Profile.newBuilder() - .addAllLocationIndices(listOf(1L, 2L)) - .setDropFrames(3) - .setKeepFrames(4) - .setTimeNanos(5) - .setDurationNanos(6) - .setPeriod(7) - .setPeriodType( - ValueType.newBuilder() - .setType(1) - .setUnit(2) - .setAggregationTemporality( - io.opentelemetry.proto.profiles.v1experimental.AggregationTemporality - .AGGREGATION_TEMPORALITY_CUMULATIVE) - .build()) - .addAllComment(listOf(8L, 9L)) - .addStringTable("foo") - .addStringTable("bar") - .setDefaultSampleType(10); - } - private static List listOf(T a, T b) { ArrayList list = new ArrayList<>(); list.add(a); From d61a5c3b37cf149ab87d1a1e2ec05dc44af20998 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 2 Dec 2024 15:00:17 -0600 Subject: [PATCH 691/901] fix(deps): update dependency com.google.protobuf:protobuf-bom to v4.29.0 (#6917) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Co-authored-by: Jack Berg --- dependencyManagement/build.gradle.kts | 2 +- exporters/otlp/common/build.gradle.kts | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index 59cb94d06e6..35a660d4bb6 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -10,7 +10,7 @@ rootProject.extra["versions"] = dependencyVersions val DEPENDENCY_BOMS = listOf( "com.fasterxml.jackson:jackson-bom:2.18.2", "com.google.guava:guava-bom:33.3.1-jre", - "com.google.protobuf:protobuf-bom:4.28.3", + "com.google.protobuf:protobuf-bom:4.29.0", "com.linecorp.armeria:armeria-bom:1.31.1", "com.squareup.okhttp3:okhttp-bom:4.12.0", "com.squareup.okio:okio-bom:3.9.1", // applies to transitive dependencies of okhttp diff --git a/exporters/otlp/common/build.gradle.kts b/exporters/otlp/common/build.gradle.kts index a151c0bb24d..99b054f3d5e 100644 --- a/exporters/otlp/common/build.gradle.kts +++ b/exporters/otlp/common/build.gradle.kts @@ -29,6 +29,7 @@ dependencies { testImplementation("com.fasterxml.jackson.core:jackson-databind") testImplementation("com.google.protobuf:protobuf-java-util") + testImplementation("com.google.guava:guava") testImplementation("io.opentelemetry.proto:opentelemetry-proto") jmhImplementation(project(":sdk:testing")) From 0ef86fae7d1c568c3f2dabe6c7b536c54000a2d3 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 3 Dec 2024 09:18:10 -0600 Subject: [PATCH 692/901] fix(deps): update dependency io.prometheus:prometheus-metrics-exporter-httpserver to v1.3.4 (#6907) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Co-authored-by: Jack Berg --- dependencyManagement/build.gradle.kts | 4 +++- exporters/prometheus/build.gradle.kts | 1 + .../exporter/prometheus/PrometheusHttpServerTest.java | 2 +- 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index 35a660d4bb6..1b2849175db 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -32,6 +32,7 @@ val mockitoVersion = "4.11.0" val slf4jVersion = "2.0.16" val opencensusVersion = "0.31.1" val prometheusClientVersion = "0.16.0" +val prometheusServerVersion = "1.3.4" val DEPENDENCIES = listOf( "com.google.auto.value:auto-value:${autoValueVersion}", @@ -52,6 +53,8 @@ val DEPENDENCIES = listOf( "org.slf4j:slf4j-simple:${slf4jVersion}", "org.slf4j:jul-to-slf4j:${slf4jVersion}", "io.prometheus:prometheus-metrics-shaded-protobuf:1.3.1", + "io.prometheus:prometheus-metrics-exporter-httpserver:${prometheusServerVersion}", + "io.prometheus:prometheus-metrics-exposition-formats:${prometheusServerVersion}", "io.prometheus:simpleclient:${prometheusClientVersion}", "io.prometheus:simpleclient_common:${prometheusClientVersion}", "io.prometheus:simpleclient_httpserver:${prometheusClientVersion}", @@ -72,7 +75,6 @@ val DEPENDENCIES = listOf( "io.opentelemetry.proto:opentelemetry-proto:1.4.0-alpha", "io.opentracing:opentracing-api:0.33.0", "io.opentracing:opentracing-noop:0.33.0", - "io.prometheus:prometheus-metrics-exporter-httpserver:1.3.3", "junit:junit:4.13.2", "nl.jqno.equalsverifier:equalsverifier:3.17.3", "org.awaitility:awaitility:4.2.2", diff --git a/exporters/prometheus/build.gradle.kts b/exporters/prometheus/build.gradle.kts index 8fe244b3f3d..3b44fad2c56 100644 --- a/exporters/prometheus/build.gradle.kts +++ b/exporters/prometheus/build.gradle.kts @@ -20,6 +20,7 @@ dependencies { testImplementation(project(":sdk:testing")) testImplementation("io.opentelemetry.proto:opentelemetry-proto") testImplementation("io.prometheus:prometheus-metrics-shaded-protobuf") + testImplementation("io.prometheus:prometheus-metrics-exposition-formats") testImplementation("com.sun.net.httpserver:http") testImplementation("com.google.guava:guava") testImplementation("com.linecorp.armeria:armeria") diff --git a/exporters/prometheus/src/test/java/io/opentelemetry/exporter/prometheus/PrometheusHttpServerTest.java b/exporters/prometheus/src/test/java/io/opentelemetry/exporter/prometheus/PrometheusHttpServerTest.java index 382e661b5ab..7115ff8a2b3 100644 --- a/exporters/prometheus/src/test/java/io/opentelemetry/exporter/prometheus/PrometheusHttpServerTest.java +++ b/exporters/prometheus/src/test/java/io/opentelemetry/exporter/prometheus/PrometheusHttpServerTest.java @@ -42,7 +42,7 @@ import io.opentelemetry.sdk.resources.Resource; import io.prometheus.metrics.exporter.httpserver.HTTPServer; import io.prometheus.metrics.exporter.httpserver.MetricsHandler; -import io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics; +import io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics; import io.prometheus.metrics.model.registry.PrometheusRegistry; import io.prometheus.metrics.shaded.com_google_protobuf_4_28_3.TextFormat; import java.io.ByteArrayInputStream; From d2a0299587e3c9a6c7f49b3c002fa9cec1283975 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 3 Dec 2024 16:59:01 -0600 Subject: [PATCH 693/901] fix(deps): update dependency com.linecorp.armeria:armeria-bom to v1.31.2 (#6918) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- dependencyManagement/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index 1b2849175db..d8c72de3664 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -11,7 +11,7 @@ val DEPENDENCY_BOMS = listOf( "com.fasterxml.jackson:jackson-bom:2.18.2", "com.google.guava:guava-bom:33.3.1-jre", "com.google.protobuf:protobuf-bom:4.29.0", - "com.linecorp.armeria:armeria-bom:1.31.1", + "com.linecorp.armeria:armeria-bom:1.31.2", "com.squareup.okhttp3:okhttp-bom:4.12.0", "com.squareup.okio:okio-bom:3.9.1", // applies to transitive dependencies of okhttp "io.grpc:grpc-bom:1.68.2", From 59b49cf741d96e2056d746987338a09acd06236e Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 4 Dec 2024 20:47:13 -0800 Subject: [PATCH 694/901] chore(deps): update plugin org.graalvm.buildtools.native to v0.10.4 (#6919) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- settings.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/settings.gradle.kts b/settings.gradle.kts index 76df07b5606..4075a604a57 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -5,7 +5,7 @@ pluginManagement { id("de.undercouch.download") version "5.6.0" id("org.jsonschema2pojo") version "1.2.2" id("io.github.gradle-nexus.publish-plugin") version "2.0.0" - id("org.graalvm.buildtools.native") version "0.10.3" + id("org.graalvm.buildtools.native") version "0.10.4" } } From 6d62e8b742658381fa39f23503d796b2f242aac4 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 4 Dec 2024 20:51:37 -0800 Subject: [PATCH 695/901] fix(deps): update dependency com.google.protobuf:protobuf-bom to v4.29.1 (#6922) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- dependencyManagement/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index d8c72de3664..984ffb3aa9f 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -10,7 +10,7 @@ rootProject.extra["versions"] = dependencyVersions val DEPENDENCY_BOMS = listOf( "com.fasterxml.jackson:jackson-bom:2.18.2", "com.google.guava:guava-bom:33.3.1-jre", - "com.google.protobuf:protobuf-bom:4.29.0", + "com.google.protobuf:protobuf-bom:4.29.1", "com.linecorp.armeria:armeria-bom:1.31.2", "com.squareup.okhttp3:okhttp-bom:4.12.0", "com.squareup.okio:okio-bom:3.9.1", // applies to transitive dependencies of okhttp From 3a5222f808eefea5d92d7586a22cda9b2b0c1479 Mon Sep 17 00:00:00 2001 From: Lauri Tulmin Date: Thu, 5 Dec 2024 17:55:29 +0200 Subject: [PATCH 696/901] Fix missing unsafe available check (#6920) --- exporters/common/build.gradle.kts | 3 + .../internal/marshal/UnsafeString.java | 3 +- .../marshal/StatelessMarshalerUtilTest.java | 101 ++++++++++++++++++ 3 files changed, 106 insertions(+), 1 deletion(-) create mode 100644 exporters/common/src/testWithoutUnsafe/java/io/opentelemetry/exporter/internal/marshal/StatelessMarshalerUtilTest.java diff --git a/exporters/common/build.gradle.kts b/exporters/common/build.gradle.kts index f311510f83d..bbca8bc416a 100644 --- a/exporters/common/build.gradle.kts +++ b/exporters/common/build.gradle.kts @@ -67,6 +67,9 @@ testing { } } } + suites { + register("testWithoutUnsafe") {} + } } tasks { diff --git a/exporters/common/src/main/java/io/opentelemetry/exporter/internal/marshal/UnsafeString.java b/exporters/common/src/main/java/io/opentelemetry/exporter/internal/marshal/UnsafeString.java index c581e7525fb..309b005fd49 100644 --- a/exporters/common/src/main/java/io/opentelemetry/exporter/internal/marshal/UnsafeString.java +++ b/exporters/common/src/main/java/io/opentelemetry/exporter/internal/marshal/UnsafeString.java @@ -10,7 +10,8 @@ class UnsafeString { private static final long valueOffset = getStringFieldOffset("value", byte[].class); private static final long coderOffset = getStringFieldOffset("coder", byte.class); - private static final int byteArrayBaseOffset = UnsafeAccess.arrayBaseOffset(byte[].class); + private static final int byteArrayBaseOffset = + UnsafeAccess.isAvailable() ? UnsafeAccess.arrayBaseOffset(byte[].class) : -1; private static final boolean available = valueOffset != -1 && coderOffset != -1; static boolean isAvailable() { diff --git a/exporters/common/src/testWithoutUnsafe/java/io/opentelemetry/exporter/internal/marshal/StatelessMarshalerUtilTest.java b/exporters/common/src/testWithoutUnsafe/java/io/opentelemetry/exporter/internal/marshal/StatelessMarshalerUtilTest.java new file mode 100644 index 00000000000..8ff3ec2e04d --- /dev/null +++ b/exporters/common/src/testWithoutUnsafe/java/io/opentelemetry/exporter/internal/marshal/StatelessMarshalerUtilTest.java @@ -0,0 +1,101 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.exporter.internal.marshal; + +import static io.opentelemetry.exporter.internal.marshal.StatelessMarshalerUtil.getUtf8Size; +import static io.opentelemetry.exporter.internal.marshal.StatelessMarshalerUtil.writeUtf8; +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.nio.charset.StandardCharsets; +import org.junit.jupiter.api.Test; + +class StatelessMarshalerUtilTest { + + // Simulate running in an environment without sun.misc.Unsafe e.g. when running a modular + // application. To use sun.misc.Unsafe in modular application user would need to add dependency to + // jdk.unsupported module or use --add-modules jdk.unsupported. Here we use a custom child first + // class loader that does not delegate loading sun.misc classes to make sun.misc.Unsafe + // unavailable. + @Test + void encodeUtf8WithoutUnsafe() throws Exception { + ClassLoader testClassLoader = + new ClassLoader(this.getClass().getClassLoader()) { + @Override + protected Class loadClass(String name, boolean resolve) throws ClassNotFoundException { + // don't allow loading sun.misc classes + if (name.startsWith("sun.misc")) { + throw new ClassNotFoundException(name); + } + // load io.opentelemetry in the custom loader + if (name.startsWith("io.opentelemetry")) { + synchronized (this) { + Class clazz = findLoadedClass(name); + if (clazz != null) { + return clazz; + } + try (InputStream inputStream = + getParent().getResourceAsStream(name.replace(".", "/") + ".class")) { + if (inputStream != null) { + byte[] bytes = readBytes(inputStream); + // we don't bother to define packages or provide protection domain + return defineClass(name, bytes, 0, bytes.length); + } + } catch (IOException exception) { + throw new ClassNotFoundException(name, exception); + } + } + } + return super.loadClass(name, resolve); + } + }; + + // load test class in the custom loader and run the test + Class testClass = testClassLoader.loadClass(this.getClass().getName() + "$TestClass"); + assertThat(testClass.getClassLoader()).isEqualTo(testClassLoader); + Runnable test = (Runnable) testClass.getConstructor().newInstance(); + test.run(); + } + + private static byte[] readBytes(InputStream inputStream) throws IOException { + ByteArrayOutputStream out = new ByteArrayOutputStream(); + byte[] buffer = new byte[1024]; + + int readCount; + while ((readCount = inputStream.read(buffer, 0, buffer.length)) != -1) { + out.write(buffer, 0, readCount); + } + return out.toByteArray(); + } + + @SuppressWarnings("unused") + public static class TestClass implements Runnable { + + @Override + public void run() { + // verify that unsafe can't be found + assertThatThrownBy(() -> Class.forName("sun.misc.Unsafe")) + .isInstanceOf(ClassNotFoundException.class); + // test the methods that use unsafe + assertThat(getUtf8Size("a", true)).isEqualTo(1); + assertThat(testUtf8("a", 0)).isEqualTo("a"); + } + + static String testUtf8(String string, int utf8Length) { + try (ByteArrayOutputStream outputStream = new ByteArrayOutputStream()) { + CodedOutputStream codedOutputStream = CodedOutputStream.newInstance(outputStream); + writeUtf8(codedOutputStream, string, utf8Length, true); + codedOutputStream.flush(); + return new String(outputStream.toByteArray(), StandardCharsets.UTF_8); + } catch (Exception exception) { + throw new IllegalArgumentException(exception); + } + } + } +} From 236e119f662824f83b3b0810fec2592551bd2d11 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 5 Dec 2024 11:50:35 -0600 Subject: [PATCH 697/901] fix(deps): update dependency org.owasp:dependency-check-gradle to v11.1.1 (#6921) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- buildSrc/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts index ffd73c271c7..3d90314dceb 100644 --- a/buildSrc/build.gradle.kts +++ b/buildSrc/build.gradle.kts @@ -66,7 +66,7 @@ dependencies { implementation("net.ltgt.gradle:gradle-errorprone-plugin:4.1.0") implementation("net.ltgt.gradle:gradle-nullaway-plugin:2.1.0") implementation("org.jetbrains.kotlin:kotlin-gradle-plugin:2.1.0") - implementation("org.owasp:dependency-check-gradle:11.1.0") + implementation("org.owasp:dependency-check-gradle:11.1.1") implementation("ru.vyarus:gradle-animalsniffer-plugin:1.7.2") } From ee8d735de13ce196d3f2fcef146beb981cfba341 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 5 Dec 2024 13:11:11 -0600 Subject: [PATCH 698/901] fix(deps): update dependency nl.jqno.equalsverifier:equalsverifier to v3.17.4 (#6912) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Co-authored-by: Jack Berg --- buildSrc/src/main/kotlin/otel.java-conventions.gradle.kts | 1 + dependencyManagement/build.gradle.kts | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/buildSrc/src/main/kotlin/otel.java-conventions.gradle.kts b/buildSrc/src/main/kotlin/otel.java-conventions.gradle.kts index 26a845f5c8a..3fbc9cb1daa 100644 --- a/buildSrc/src/main/kotlin/otel.java-conventions.gradle.kts +++ b/buildSrc/src/main/kotlin/otel.java-conventions.gradle.kts @@ -237,6 +237,7 @@ testing { compileOnly("com.google.auto.value:auto-value-annotations") compileOnly("com.google.errorprone:error_prone_annotations") compileOnly("com.google.code.findbugs:jsr305") + compileOnly("com.google.code.findbugs:annotations") implementation("org.junit.jupiter:junit-jupiter-api") implementation("org.junit.jupiter:junit-jupiter-params") diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index 984ffb3aa9f..11e38dffdfc 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -61,6 +61,7 @@ val DEPENDENCIES = listOf( "javax.annotation:javax.annotation-api:1.3.2", "com.github.stefanbirkner:system-rules:1.19.0", "com.google.api.grpc:proto-google-common-protos:2.49.0", + "com.google.code.findbugs:annotations:3.0.1", "com.google.code.findbugs:jsr305:3.0.2", "com.google.guava:guava-beta-checker:1.0", "com.sun.net.httpserver:http:20070405", @@ -76,7 +77,7 @@ val DEPENDENCIES = listOf( "io.opentracing:opentracing-api:0.33.0", "io.opentracing:opentracing-noop:0.33.0", "junit:junit:4.13.2", - "nl.jqno.equalsverifier:equalsverifier:3.17.3", + "nl.jqno.equalsverifier:equalsverifier:3.17.4", "org.awaitility:awaitility:4.2.2", "org.bouncycastle:bcpkix-jdk15on:1.70", "org.codehaus.mojo:animal-sniffer-annotations:1.24", From b07dab31cd572e063896027d0d52cda46195c104 Mon Sep 17 00:00:00 2001 From: James Moessis Date: Fri, 6 Dec 2024 06:26:56 +1100 Subject: [PATCH 699/901] Extends TextMapGetter with GetAll() method, implement usage in W3CBaggagePropagator (#6852) Co-authored-by: Jack Berg --- .../propagation/W3CBaggagePropagator.java | 37 ++++++ .../propagation/W3CBaggagePropagatorTest.java | 121 ++++++++++++++++++ .../internal/ExtendedTextMapGetter.java | 44 +++++++ .../internal/ExtendedTextMapGetterTest.java | 70 ++++++++++ 4 files changed, 272 insertions(+) create mode 100644 context/src/main/java/io/opentelemetry/context/propagation/internal/ExtendedTextMapGetter.java create mode 100644 context/src/test/java/io/opentelemetry/context/propagation/internal/ExtendedTextMapGetterTest.java diff --git a/api/all/src/main/java/io/opentelemetry/api/baggage/propagation/W3CBaggagePropagator.java b/api/all/src/main/java/io/opentelemetry/api/baggage/propagation/W3CBaggagePropagator.java index 150be6e4fdd..e03f8e9078f 100644 --- a/api/all/src/main/java/io/opentelemetry/api/baggage/propagation/W3CBaggagePropagator.java +++ b/api/all/src/main/java/io/opentelemetry/api/baggage/propagation/W3CBaggagePropagator.java @@ -16,7 +16,9 @@ import io.opentelemetry.context.propagation.TextMapGetter; import io.opentelemetry.context.propagation.TextMapPropagator; import io.opentelemetry.context.propagation.TextMapSetter; +import io.opentelemetry.context.propagation.internal.ExtendedTextMapGetter; import java.util.Collection; +import java.util.Iterator; import java.util.List; import javax.annotation.Nullable; @@ -95,6 +97,14 @@ public Context extract(Context context, @Nullable C carrier, TextMapGetter) getter); + } + return extractSingle(context, carrier, getter); + } + + private static Context extractSingle( + Context context, @Nullable C carrier, TextMapGetter getter) { String baggageHeader = getter.get(carrier, FIELD); if (baggageHeader == null) { return context; @@ -112,6 +122,33 @@ public Context extract(Context context, @Nullable C carrier, TextMapGetter Context extractMulti( + Context context, @Nullable C carrier, ExtendedTextMapGetter getter) { + Iterator baggageHeaders = getter.getAll(carrier, FIELD); + if (baggageHeaders == null) { + return context; + } + + boolean extracted = false; + BaggageBuilder baggageBuilder = Baggage.builder(); + + while (baggageHeaders.hasNext()) { + String header = baggageHeaders.next(); + if (header.isEmpty()) { + continue; + } + + try { + extractEntries(header, baggageBuilder); + extracted = true; + } catch (RuntimeException expected) { + // invalid baggage header, continue + } + } + + return extracted ? context.with(baggageBuilder.build()) : context; + } + private static void extractEntries(String baggageHeader, BaggageBuilder baggageBuilder) { new Parser(baggageHeader).parseInto(baggageBuilder); } diff --git a/api/all/src/test/java/io/opentelemetry/api/baggage/propagation/W3CBaggagePropagatorTest.java b/api/all/src/test/java/io/opentelemetry/api/baggage/propagation/W3CBaggagePropagatorTest.java index e775ed04f1e..fb0c342affc 100644 --- a/api/all/src/test/java/io/opentelemetry/api/baggage/propagation/W3CBaggagePropagatorTest.java +++ b/api/all/src/test/java/io/opentelemetry/api/baggage/propagation/W3CBaggagePropagatorTest.java @@ -8,14 +8,18 @@ import static java.util.Collections.singletonMap; import static org.assertj.core.api.Assertions.assertThat; +import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; import io.opentelemetry.api.baggage.Baggage; import io.opentelemetry.api.baggage.BaggageEntryMetadata; import io.opentelemetry.context.Context; import io.opentelemetry.context.propagation.TextMapGetter; +import io.opentelemetry.context.propagation.internal.ExtendedTextMapGetter; import java.util.Collections; import java.util.HashMap; +import java.util.Iterator; import java.util.LinkedHashMap; +import java.util.List; import java.util.Map; import javax.annotation.Nullable; import org.junit.jupiter.api.Test; @@ -36,6 +40,28 @@ public String get(Map carrier, String key) { } }; + private static final ExtendedTextMapGetter>> multiGetter = + new ExtendedTextMapGetter>>() { + @Override + public Iterable keys(Map> carrier) { + return carrier.keySet(); + } + + @Nullable + @Override + public String get(Map> carrier, String key) { + return carrier.getOrDefault(key, Collections.emptyList()).stream() + .findFirst() + .orElse(null); + } + + @Override + public Iterator getAll(Map> carrier, String key) { + List values = carrier.get(key); + return values == null ? Collections.emptyIterator() : values.iterator(); + } + }; + @Test void fields() { assertThat(W3CBaggagePropagator.getInstance().fields()).containsExactly("baggage"); @@ -421,6 +447,101 @@ void extract_nullGetter() { .isSameAs(context); } + @Test + void extract_multiple_headers() { + W3CBaggagePropagator propagator = W3CBaggagePropagator.getInstance(); + + Context result = + propagator.extract( + Context.root(), + ImmutableMap.of("baggage", ImmutableList.of("k1=v1", "k2=v2")), + multiGetter); + + Baggage expectedBaggage = Baggage.builder().put("k1", "v1").put("k2", "v2").build(); + assertThat(Baggage.fromContext(result)).isEqualTo(expectedBaggage); + } + + @Test + void extract_multiple_headers_duplicate_key() { + W3CBaggagePropagator propagator = W3CBaggagePropagator.getInstance(); + + Context result = + propagator.extract( + Context.root(), + ImmutableMap.of("baggage", ImmutableList.of("k1=v1", "k1=v2")), + multiGetter); + + Baggage expectedBaggage = Baggage.builder().put("k1", "v2").build(); + assertThat(Baggage.fromContext(result)).isEqualTo(expectedBaggage); + } + + @Test + void extract_multiple_headers_mixed_duplicates_non_duplicates() { + W3CBaggagePropagator propagator = W3CBaggagePropagator.getInstance(); + + Context result = + propagator.extract( + Context.root(), + ImmutableMap.of("baggage", ImmutableList.of("k1=v1,k2=v0", "k2=v2,k3=v3")), + multiGetter); + + Baggage expectedBaggage = + Baggage.builder().put("k1", "v1").put("k2", "v2").put("k3", "v3").build(); + assertThat(Baggage.fromContext(result)).isEqualTo(expectedBaggage); + } + + @Test + void extract_multiple_headers_all_empty() { + W3CBaggagePropagator propagator = W3CBaggagePropagator.getInstance(); + + Context result = + propagator.extract( + Context.root(), ImmutableMap.of("baggage", ImmutableList.of("", "")), multiGetter); + + Baggage expectedBaggage = Baggage.builder().build(); + assertThat(Baggage.fromContext(result)).isEqualTo(expectedBaggage); + } + + @Test + void extract_multiple_headers_some_empty() { + W3CBaggagePropagator propagator = W3CBaggagePropagator.getInstance(); + + Context result = + propagator.extract( + Context.root(), ImmutableMap.of("baggage", ImmutableList.of("", "k=v")), multiGetter); + + Baggage expectedBaggage = Baggage.builder().put("k", "v").build(); + assertThat(Baggage.fromContext(result)).isEqualTo(expectedBaggage); + } + + @Test + void extract_multiple_headers_all_invalid() { + W3CBaggagePropagator propagator = W3CBaggagePropagator.getInstance(); + + Context result = + propagator.extract( + Context.root(), + ImmutableMap.of("baggage", ImmutableList.of("!@#$%^", "key=va%lue")), + multiGetter); + + Baggage expectedBaggage = Baggage.builder().build(); + assertThat(Baggage.fromContext(result)).isEqualTo(expectedBaggage); + } + + @Test + void extract_multiple_headers_some_invalid() { + W3CBaggagePropagator propagator = W3CBaggagePropagator.getInstance(); + + Context result = + propagator.extract( + Context.root(), + ImmutableMap.of("baggage", ImmutableList.of("k1=v1", "key=va%lue", "k2=v2")), + multiGetter); + + Baggage expectedBaggage = Baggage.builder().put("k1", "v1").put("k2", "v2").build(); + assertThat(Baggage.fromContext(result)).isEqualTo(expectedBaggage); + } + @Test void inject_noBaggage() { W3CBaggagePropagator propagator = W3CBaggagePropagator.getInstance(); diff --git a/context/src/main/java/io/opentelemetry/context/propagation/internal/ExtendedTextMapGetter.java b/context/src/main/java/io/opentelemetry/context/propagation/internal/ExtendedTextMapGetter.java new file mode 100644 index 00000000000..d64604757db --- /dev/null +++ b/context/src/main/java/io/opentelemetry/context/propagation/internal/ExtendedTextMapGetter.java @@ -0,0 +1,44 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.context.propagation.internal; + +import io.opentelemetry.context.propagation.TextMapGetter; +import java.util.Collections; +import java.util.Iterator; +import javax.annotation.Nullable; + +/** + * Extends {@link TextMapGetter} to return possibly multiple values for a given key. + * + *

      This class is internal and experimental. Its APIs are unstable and can change at any time. Its + * APIs (or a version of them) may be promoted to the public stable API in the future, but no + * guarantees are made. + * + * @param carrier of propagation fields, such as an http request. + */ +public interface ExtendedTextMapGetter extends TextMapGetter { + /** + * If implemented, returns all values for a given {@code key} in order, or returns an empty list. + * + *

      The default method returns the first value of the given propagation {@code key} as a + * singleton list, or returns an empty list. + * + *

      This class is internal and is hence not for public use. Its APIs are unstable and can change + * at any time. + * + * @param carrier carrier of propagation fields, such as an http request. + * @param key the key of the field. + * @return all values for a given {@code key} in order, or returns an empty list. Default method + * wraps {@code get()} as an {@link Iterator}. + */ + default Iterator getAll(@Nullable C carrier, String key) { + String first = get(carrier, key); + if (first == null) { + return Collections.emptyIterator(); + } + return Collections.singleton(first).iterator(); + } +} diff --git a/context/src/test/java/io/opentelemetry/context/propagation/internal/ExtendedTextMapGetterTest.java b/context/src/test/java/io/opentelemetry/context/propagation/internal/ExtendedTextMapGetterTest.java new file mode 100644 index 00000000000..f8c35ea2ed9 --- /dev/null +++ b/context/src/test/java/io/opentelemetry/context/propagation/internal/ExtendedTextMapGetterTest.java @@ -0,0 +1,70 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.context.propagation.internal; + +import static org.assertj.core.api.AssertionsForClassTypes.assertThat; + +import com.google.common.collect.ImmutableList; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Iterator; +import java.util.List; +import javax.annotation.Nullable; +import org.junit.jupiter.api.Test; + +class ExtendedTextMapGetterTest { + + final ExtendedTextMapGetter nullGet = + new ExtendedTextMapGetter() { + @Override + public Iterable keys(Void carrier) { + return ImmutableList.of("key"); + } + + @Nullable + @Override + public String get(@Nullable Void carrier, String key) { + return null; + } + }; + + final ExtendedTextMapGetter nonNullGet = + new ExtendedTextMapGetter() { + @Override + public Iterable keys(Void carrier) { + return ImmutableList.of("key"); + } + + @Override + public String get(@Nullable Void carrier, String key) { + return "123"; + } + }; + + @Test + void extendedTextMapGetterdefaultMethod_returnsEmpty() { + Iterator result = nullGet.getAll(null, "key"); + assertThat(result).isNotNull(); + List values = iterToList(result); + assertThat(values).isEqualTo(Collections.emptyList()); + } + + @Test + void extendedTextMapGetterdefaultMethod_returnsSingleVal() { + Iterator result = nonNullGet.getAll(null, "key"); + assertThat(result).isNotNull(); + List values = iterToList(result); + assertThat(values).isEqualTo(Collections.singletonList("123")); + } + + private static List iterToList(Iterator iter) { + List list = new ArrayList<>(); + while (iter.hasNext()) { + list.add(iter.next()); + } + return list; + } +} From 541ef89e6a64bc208f5003ab9285613e4f867d99 Mon Sep 17 00:00:00 2001 From: jack-berg <34418638+jack-berg@users.noreply.github.com> Date: Fri, 6 Dec 2024 13:03:13 -0600 Subject: [PATCH 700/901] Prepare for 1.45.0 release (#6923) Co-authored-by: Trask Stalnaker --- CHANGELOG.md | 48 +++++++++++++++++++ .../opentelemetry/api/trace/SpanBuilder.java | 1 + 2 files changed, 49 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 93709f23f87..7db6ad9b77c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,54 @@ ## Unreleased +### API + +* Add convenience method `setAttribute(Attribute, int)` to SpanBuilder (matching the existing + convenience method in Span) + ([#6884](https://github.com/open-telemetry/opentelemetry-java/pull/6884)) +* Extends TextMapGetter with experimental GetAll() method, implement usage in W3CBaggagePropagator + ([#6852](https://github.com/open-telemetry/opentelemetry-java/pull/6852)) + +### SDK + +#### Traces + +* Add synchronization to SimpleSpanProcessor to ensure thread-safe export of spans + ([#6885](https://github.com/open-telemetry/opentelemetry-java/pull/6885)) + +#### Metrics + +* Lazily initialize ReservoirCells + ([#6851](https://github.com/open-telemetry/opentelemetry-java/pull/6851)) + +#### Logs + +* Add synchronization to SimpleLogRecordProcessor to ensure thread-safe export of logs + ([#6885](https://github.com/open-telemetry/opentelemetry-java/pull/6885)) + +#### Exporters + +* OTLP: Update opentelementry-proto to 1.4 + ([#6906](https://github.com/open-telemetry/opentelemetry-java/pull/6906)) +* OTLP: Rename internal Marshaler#writeJsonToGenerator method to allow jackson runtimeOnly dependency + ([#6896](https://github.com/open-telemetry/opentelemetry-java/pull/6896)) +* OTLP: Fix repeated string serialization for JSON. + ([#6888](https://github.com/open-telemetry/opentelemetry-java/pull/6888)) +* OTLP: Fix missing unsafe available check + ([#6920](https://github.com/open-telemetry/opentelemetry-java/pull/6920)) + +#### Extensions + +* Declarative config: Don't require empty objects when referencing custom components + ([#6891](https://github.com/open-telemetry/opentelemetry-java/pull/6891)) + +### Tooling + +* Add javadoc boilerplate internal comment v2 for experimental classes + ([#6886](https://github.com/open-telemetry/opentelemetry-java/pull/6886)) +* Update develocity configuration + ([#6903](https://github.com/open-telemetry/opentelemetry-java/pull/6903)) + ## Version 1.44.1 (2024-11-10) ### SDK diff --git a/api/all/src/main/java/io/opentelemetry/api/trace/SpanBuilder.java b/api/all/src/main/java/io/opentelemetry/api/trace/SpanBuilder.java index 9f9e5c0ce5e..c8727dd8471 100644 --- a/api/all/src/main/java/io/opentelemetry/api/trace/SpanBuilder.java +++ b/api/all/src/main/java/io/opentelemetry/api/trace/SpanBuilder.java @@ -245,6 +245,7 @@ public interface SpanBuilder { * @param key the key for this attribute. * @param value the value for this attribute. * @return this. + * @since 1.45.0 */ default SpanBuilder setAttribute(AttributeKey key, int value) { return setAttribute(key, (long) value); From bd8c008c3dbfe3d24e84aff64ebb50edb8ba4407 Mon Sep 17 00:00:00 2001 From: OpenTelemetry Bot <107717825+opentelemetrybot@users.noreply.github.com> Date: Fri, 6 Dec 2024 13:46:07 -0600 Subject: [PATCH 701/901] Update version to 1.46.0 (#6927) --- CHANGELOG.md | 2 ++ version.gradle.kts | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7db6ad9b77c..b4fddc06a87 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,8 @@ ## Unreleased +## Version 1.45.0 (2024-12-06) + ### API * Add convenience method `setAttribute(Attribute, int)` to SpanBuilder (matching the existing diff --git a/version.gradle.kts b/version.gradle.kts index 29d04038d15..61fc4af26df 100644 --- a/version.gradle.kts +++ b/version.gradle.kts @@ -1,7 +1,7 @@ val snapshot = true allprojects { - var ver = "1.45.0" + var ver = "1.46.0" val release = findProperty("otel.release") if (release != null) { ver += "-" + release From 23780762b0df50b893e7ef38f80330ecd442eede Mon Sep 17 00:00:00 2001 From: OpenTelemetry Bot <107717825+opentelemetrybot@users.noreply.github.com> Date: Fri, 6 Dec 2024 15:01:55 -0600 Subject: [PATCH 702/901] Post release for version 1.45.0 (#6929) --- README.md | 62 +++++++++---------- .../1.45.0_vs_1.44.0/opentelemetry-api.txt | 4 ++ .../opentelemetry-context.txt | 2 + .../opentelemetry-exporter-common.txt | 2 + .../opentelemetry-exporter-logging-otlp.txt | 2 + .../opentelemetry-exporter-logging.txt | 2 + .../opentelemetry-exporter-otlp-common.txt | 2 + .../opentelemetry-exporter-otlp.txt | 2 + ...y-exporter-sender-grpc-managed-channel.txt | 2 + .../opentelemetry-exporter-sender-jdk.txt | 2 + .../opentelemetry-exporter-sender-okhttp.txt | 2 + .../opentelemetry-exporter-zipkin.txt | 2 + .../opentelemetry-extension-kotlin.txt | 2 + ...ntelemetry-extension-trace-propagators.txt | 2 + .../opentelemetry-opentracing-shim.txt | 2 + .../opentelemetry-sdk-common.txt | 2 + ...emetry-sdk-extension-autoconfigure-spi.txt | 2 + ...ntelemetry-sdk-extension-autoconfigure.txt | 2 + ...ry-sdk-extension-jaeger-remote-sampler.txt | 2 + .../opentelemetry-sdk-logs.txt | 2 + .../opentelemetry-sdk-metrics.txt | 2 + .../opentelemetry-sdk-testing.txt | 2 + .../opentelemetry-sdk-trace.txt | 2 + .../1.45.0_vs_1.44.0/opentelemetry-sdk.txt | 2 + .../current_vs_latest/opentelemetry-api.txt | 6 +- .../opentelemetry-context.txt | 2 +- .../opentelemetry-exporter-common.txt | 2 +- .../opentelemetry-exporter-logging-otlp.txt | 2 +- .../opentelemetry-exporter-logging.txt | 2 +- .../opentelemetry-exporter-otlp-common.txt | 2 +- .../opentelemetry-exporter-otlp.txt | 2 +- ...y-exporter-sender-grpc-managed-channel.txt | 2 +- .../opentelemetry-exporter-sender-jdk.txt | 2 +- .../opentelemetry-exporter-sender-okhttp.txt | 2 +- .../opentelemetry-exporter-zipkin.txt | 2 +- .../opentelemetry-extension-kotlin.txt | 2 +- ...ntelemetry-extension-trace-propagators.txt | 2 +- .../opentelemetry-opentracing-shim.txt | 2 +- .../opentelemetry-sdk-common.txt | 2 +- ...emetry-sdk-extension-autoconfigure-spi.txt | 2 +- ...ntelemetry-sdk-extension-autoconfigure.txt | 2 +- ...ry-sdk-extension-jaeger-remote-sampler.txt | 2 +- .../opentelemetry-sdk-logs.txt | 2 +- .../opentelemetry-sdk-metrics.txt | 2 +- .../opentelemetry-sdk-testing.txt | 2 +- .../opentelemetry-sdk-trace.txt | 2 +- .../current_vs_latest/opentelemetry-sdk.txt | 2 +- 47 files changed, 103 insertions(+), 57 deletions(-) create mode 100644 docs/apidiffs/1.45.0_vs_1.44.0/opentelemetry-api.txt create mode 100644 docs/apidiffs/1.45.0_vs_1.44.0/opentelemetry-context.txt create mode 100644 docs/apidiffs/1.45.0_vs_1.44.0/opentelemetry-exporter-common.txt create mode 100644 docs/apidiffs/1.45.0_vs_1.44.0/opentelemetry-exporter-logging-otlp.txt create mode 100644 docs/apidiffs/1.45.0_vs_1.44.0/opentelemetry-exporter-logging.txt create mode 100644 docs/apidiffs/1.45.0_vs_1.44.0/opentelemetry-exporter-otlp-common.txt create mode 100644 docs/apidiffs/1.45.0_vs_1.44.0/opentelemetry-exporter-otlp.txt create mode 100644 docs/apidiffs/1.45.0_vs_1.44.0/opentelemetry-exporter-sender-grpc-managed-channel.txt create mode 100644 docs/apidiffs/1.45.0_vs_1.44.0/opentelemetry-exporter-sender-jdk.txt create mode 100644 docs/apidiffs/1.45.0_vs_1.44.0/opentelemetry-exporter-sender-okhttp.txt create mode 100644 docs/apidiffs/1.45.0_vs_1.44.0/opentelemetry-exporter-zipkin.txt create mode 100644 docs/apidiffs/1.45.0_vs_1.44.0/opentelemetry-extension-kotlin.txt create mode 100644 docs/apidiffs/1.45.0_vs_1.44.0/opentelemetry-extension-trace-propagators.txt create mode 100644 docs/apidiffs/1.45.0_vs_1.44.0/opentelemetry-opentracing-shim.txt create mode 100644 docs/apidiffs/1.45.0_vs_1.44.0/opentelemetry-sdk-common.txt create mode 100644 docs/apidiffs/1.45.0_vs_1.44.0/opentelemetry-sdk-extension-autoconfigure-spi.txt create mode 100644 docs/apidiffs/1.45.0_vs_1.44.0/opentelemetry-sdk-extension-autoconfigure.txt create mode 100644 docs/apidiffs/1.45.0_vs_1.44.0/opentelemetry-sdk-extension-jaeger-remote-sampler.txt create mode 100644 docs/apidiffs/1.45.0_vs_1.44.0/opentelemetry-sdk-logs.txt create mode 100644 docs/apidiffs/1.45.0_vs_1.44.0/opentelemetry-sdk-metrics.txt create mode 100644 docs/apidiffs/1.45.0_vs_1.44.0/opentelemetry-sdk-testing.txt create mode 100644 docs/apidiffs/1.45.0_vs_1.44.0/opentelemetry-sdk-trace.txt create mode 100644 docs/apidiffs/1.45.0_vs_1.44.0/opentelemetry-sdk.txt diff --git a/README.md b/README.md index 633be605b34..ee6157962b3 100644 --- a/README.md +++ b/README.md @@ -51,8 +51,8 @@ A bill of materials (or BOM) helps sync dependency versions of related artifacts | Component | Description | Artifact ID | Version | Javadoc | |----------------------------------------------|----------------------------------------|---------------------------|-------------------------------------------------------------|---------| -| [Bill of Materials (BOM)](./bom) | Bill of materials for stable artifacts | `opentelemetry-bom` | 1.44.1 | N/A | -| [Alpha Bill of Materials (BOM)](./bom-alpha) | Bill of materials for alpha artifacts | `opentelemetry-bom-alpha` | 1.44.1-alpha | N/A | +| [Bill of Materials (BOM)](./bom) | Bill of materials for stable artifacts | `opentelemetry-bom` | 1.45.0 | N/A | +| [Alpha Bill of Materials (BOM)](./bom-alpha) | Bill of materials for alpha artifacts | `opentelemetry-bom-alpha` | 1.45.0-alpha | N/A |

      @@ -62,9 +62,9 @@ The OpenTelemetry API for recording telemetry. | Component | Description | Artifact ID | Version | Javadoc | |-----------------------------------|--------------------------------------------------------------------------------------|-------------------------------|---------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| [API](./api/all) | OpenTelemetry API, including metrics, traces, baggage, context | `opentelemetry-api` | 1.44.1 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-api.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-api) | -| [API Incubator](./api/incubator) | API incubator, including pass through propagator, and extended tracer, and Event API | `opentelemetry-api-incubator` | 1.44.1 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-api-incubator.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-api-incubator) | -| [Context API](./context) | OpenTelemetry context API | `opentelemetry-context` | 1.44.1 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-context.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-context) | +| [API](./api/all) | OpenTelemetry API, including metrics, traces, baggage, context | `opentelemetry-api` | 1.45.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-api.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-api) | +| [API Incubator](./api/incubator) | API incubator, including pass through propagator, and extended tracer, and Event API | `opentelemetry-api-incubator` | 1.45.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-api-incubator.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-api-incubator) | +| [Context API](./context) | OpenTelemetry context API | `opentelemetry-context` | 1.45.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-context.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-context) |
      @@ -74,8 +74,8 @@ Extensions to the OpenTelemetry API. | Component | Description | Artifact ID | Version | Javadoc | |---------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|---------------------------------------------|-------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| [Kotlin Extension](./extensions/kotlin) | Context extension for coroutines | `opentelemetry-extension-kotlin` | 1.44.1 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-extension-kotlin.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-extension-kotlin) | -| [Trace Propagators Extension](./extensions/trace-propagators) | Trace propagators, including B3, Jaeger, OT Trace | `opentelemetry-extension-trace-propagators` | 1.44.1 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-extension-trace-propagators.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-extension-trace-propagators) | +| [Kotlin Extension](./extensions/kotlin) | Context extension for coroutines | `opentelemetry-extension-kotlin` | 1.45.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-extension-kotlin.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-extension-kotlin) | +| [Trace Propagators Extension](./extensions/trace-propagators) | Trace propagators, including B3, Jaeger, OT Trace | `opentelemetry-extension-trace-propagators` | 1.45.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-extension-trace-propagators.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-extension-trace-propagators) |
      @@ -85,12 +85,12 @@ The OpenTelemetry SDK for managing telemetry producing by the API. | Component | Description | Artifact ID | Version | Javadoc | |------------------------------|--------------------------------------------------------|-----------------------------|---------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| [SDK](./sdk/all) | OpenTelemetry SDK, including metrics, traces, and logs | `opentelemetry-sdk` | 1.44.1 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk) | -| [Metrics SDK](./sdk/metrics) | OpenTelemetry metrics SDK | `opentelemetry-sdk-metrics` | 1.44.1 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-metrics.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-metrics) | -| [Trace SDK](./sdk/trace) | OpenTelemetry trace SDK | `opentelemetry-sdk-trace` | 1.44.1 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-trace.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-trace) | -| [Log SDK](./sdk/logs) | OpenTelemetry log SDK | `opentelemetry-sdk-logs` | 1.44.1 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-logs.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-logs) | -| [SDK Common](./sdk/common) | Shared SDK components | `opentelemetry-sdk-common` | 1.44.1 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-common.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-common) | -| [SDK Testing](./sdk/testing) | Components for testing OpenTelemetry instrumentation | `opentelemetry-sdk-testing` | 1.44.1 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-testing.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-testing) | +| [SDK](./sdk/all) | OpenTelemetry SDK, including metrics, traces, and logs | `opentelemetry-sdk` | 1.45.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk) | +| [Metrics SDK](./sdk/metrics) | OpenTelemetry metrics SDK | `opentelemetry-sdk-metrics` | 1.45.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-metrics.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-metrics) | +| [Trace SDK](./sdk/trace) | OpenTelemetry trace SDK | `opentelemetry-sdk-trace` | 1.45.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-trace.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-trace) | +| [Log SDK](./sdk/logs) | OpenTelemetry log SDK | `opentelemetry-sdk-logs` | 1.45.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-logs.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-logs) | +| [SDK Common](./sdk/common) | Shared SDK components | `opentelemetry-sdk-common` | 1.45.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-common.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-common) | +| [SDK Testing](./sdk/testing) | Components for testing OpenTelemetry instrumentation | `opentelemetry-sdk-testing` | 1.45.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-testing.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-testing) |
      @@ -100,16 +100,16 @@ SDK exporters for shipping traces, metrics, and logs out of process. | Component | Description | Artifact ID | Version | Javadoc | |-----------------------------------------------------------------------|------------------------------------------------------------------------------|------------------------------------------------------|-------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| [OTLP Exporters](./exporters/otlp/all) | OTLP gRPC & HTTP exporters, including traces, metrics, and logs | `opentelemetry-exporter-otlp` | 1.44.1 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-otlp.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-otlp) | -| [OTLP Logging Exporters](./exporters/logging-otlp) | Logging exporters in OTLP JSON encoding, including traces, metrics, and logs | `opentelemetry-exporter-logging-otlp` | 1.44.1 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-logging-otlp.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-logging-otlp) | -| [OTLP Common](./exporters/otlp/common) | Shared OTLP components (internal) | `opentelemetry-exporter-otlp-common` | 1.44.1 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-otlp-common.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-otlp-common) | -| [Logging Exporter](./exporters/logging) | Logging exporters, including metrics, traces, and logs | `opentelemetry-exporter-logging` | 1.44.1 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-logging.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-logging) | -| [Zipkin Exporter](./exporters/zipkin) | Zipkin trace exporter | `opentelemetry-exporter-zipkin` | 1.44.1 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-zipkin.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-zipkin) | -| [Prometheus Exporter](./exporters/prometheus) | Prometheus metric exporter | `opentelemetry-exporter-prometheus` | 1.44.1-alpha | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-prometheus.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-prometheus) | -| [Exporter Common](./exporters/common) | Shared exporter components (internal) | `opentelemetry-exporter-common` | 1.44.1 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-common.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-common) | -| [OkHttp Sender](./exporters/sender/okhttp) | OkHttp implementation of HttpSender (internal) | `opentelemetry-exporter-sender-okhttp` | 1.44.1 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-sender-okhttp.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-sender-okhttp) | -| [JDK Sender](./exporters/sender/jdk) | Java 11+ native HttpClient implementation of HttpSender (internal) | `opentelemetry-exporter-sender-jdk` | 1.44.1 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-sender-jdk.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-sender-jdk) | | -| [gRPC ManagedChannel Sender](./exporters/sender/grpc-managed-channel) | gRPC ManagedChannel implementation of GrpcSender (internal) | `opentelemetry-exporter-sender-grpc-managed-channel` | 1.44.1 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-sender-grpc-managed-channel.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-sender-grpc-managed-channel) | | +| [OTLP Exporters](./exporters/otlp/all) | OTLP gRPC & HTTP exporters, including traces, metrics, and logs | `opentelemetry-exporter-otlp` | 1.45.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-otlp.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-otlp) | +| [OTLP Logging Exporters](./exporters/logging-otlp) | Logging exporters in OTLP JSON encoding, including traces, metrics, and logs | `opentelemetry-exporter-logging-otlp` | 1.45.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-logging-otlp.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-logging-otlp) | +| [OTLP Common](./exporters/otlp/common) | Shared OTLP components (internal) | `opentelemetry-exporter-otlp-common` | 1.45.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-otlp-common.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-otlp-common) | +| [Logging Exporter](./exporters/logging) | Logging exporters, including metrics, traces, and logs | `opentelemetry-exporter-logging` | 1.45.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-logging.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-logging) | +| [Zipkin Exporter](./exporters/zipkin) | Zipkin trace exporter | `opentelemetry-exporter-zipkin` | 1.45.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-zipkin.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-zipkin) | +| [Prometheus Exporter](./exporters/prometheus) | Prometheus metric exporter | `opentelemetry-exporter-prometheus` | 1.45.0-alpha | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-prometheus.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-prometheus) | +| [Exporter Common](./exporters/common) | Shared exporter components (internal) | `opentelemetry-exporter-common` | 1.45.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-common.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-common) | +| [OkHttp Sender](./exporters/sender/okhttp) | OkHttp implementation of HttpSender (internal) | `opentelemetry-exporter-sender-okhttp` | 1.45.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-sender-okhttp.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-sender-okhttp) | +| [JDK Sender](./exporters/sender/jdk) | Java 11+ native HttpClient implementation of HttpSender (internal) | `opentelemetry-exporter-sender-jdk` | 1.45.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-sender-jdk.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-sender-jdk) | | +| [gRPC ManagedChannel Sender](./exporters/sender/grpc-managed-channel) | gRPC ManagedChannel implementation of GrpcSender (internal) | `opentelemetry-exporter-sender-grpc-managed-channel` | 1.45.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-sender-grpc-managed-channel.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-sender-grpc-managed-channel) | |
      @@ -119,10 +119,10 @@ Extensions to the OpenTelemetry SDK. | Component | Description | Artifact ID | Version | Javadoc | |-------------------------------------------------------------------------------|------------------------------------------------------------------------------------|-----------------------------------------------------|-------------------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| [SDK Autoconfigure](./sdk-extensions/autoconfigure) | Autoconfigure OpenTelemetry SDK from env vars, system properties, and SPI | `opentelemetry-sdk-extension-autoconfigure` | 1.44.1 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-extension-autoconfigure.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-extension-autoconfigure) | -| [SDK Autoconfigure SPI](./sdk-extensions/autoconfigure-spi) | Service Provider Interface (SPI) definitions for autoconfigure | `opentelemetry-sdk-extension-autoconfigure-spi` | 1.44.1 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-extension-autoconfigure-spi.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-extension-autoconfigure-spi) | -| [SDK Jaeger Remote Sampler Extension](./sdk-extensions/jaeger-remote-sampler) | Sampler which obtains sampling configuration from remote Jaeger server | `opentelemetry-sdk-extension-jaeger-remote-sampler` | 1.44.1 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-extension-jaeger-remote-sampler.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-extension-jaeger-remote-sampler) | -| [SDK Incubator](./sdk-extensions/incubator) | SDK incubator, including YAML based view configuration, LeakDetectingSpanProcessor | `opentelemetry-sdk-extension-incubator` | 1.44.1-alpha | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-extension-incubator.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-extension-incubator) | +| [SDK Autoconfigure](./sdk-extensions/autoconfigure) | Autoconfigure OpenTelemetry SDK from env vars, system properties, and SPI | `opentelemetry-sdk-extension-autoconfigure` | 1.45.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-extension-autoconfigure.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-extension-autoconfigure) | +| [SDK Autoconfigure SPI](./sdk-extensions/autoconfigure-spi) | Service Provider Interface (SPI) definitions for autoconfigure | `opentelemetry-sdk-extension-autoconfigure-spi` | 1.45.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-extension-autoconfigure-spi.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-extension-autoconfigure-spi) | +| [SDK Jaeger Remote Sampler Extension](./sdk-extensions/jaeger-remote-sampler) | Sampler which obtains sampling configuration from remote Jaeger server | `opentelemetry-sdk-extension-jaeger-remote-sampler` | 1.45.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-extension-jaeger-remote-sampler.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-extension-jaeger-remote-sampler) | +| [SDK Incubator](./sdk-extensions/incubator) | SDK incubator, including YAML based view configuration, LeakDetectingSpanProcessor | `opentelemetry-sdk-extension-incubator` | 1.45.0-alpha | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-extension-incubator.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-extension-incubator) |
      @@ -132,8 +132,8 @@ Shims for bridging data from one observability library to another. | Component | Description | Artifact ID | Version | Javadoc | |----------------------------------------|--------------------------------------------------------------|----------------------------------|-------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| [OpenCensus Shim](./opencensus-shim) | Bridge opencensus metrics into the OpenTelemetry metrics SDK | `opentelemetry-opencensus-shim` | 1.44.1-alpha | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-opencensus-shim.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-opencensus-shim) | -| [OpenTracing Shim](./opentracing-shim) | Bridge opentracing spans into the OpenTelemetry trace API | `opentelemetry-opentracing-shim` | 1.44.1 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-opentracing-shim.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-opentracing-shim) | +| [OpenCensus Shim](./opencensus-shim) | Bridge opencensus metrics into the OpenTelemetry metrics SDK | `opentelemetry-opencensus-shim` | 1.45.0-alpha | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-opencensus-shim.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-opencensus-shim) | +| [OpenTracing Shim](./opentracing-shim) | Bridge opentracing spans into the OpenTelemetry trace API | `opentelemetry-opentracing-shim` | 1.45.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-opentracing-shim.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-opentracing-shim) |
      ## Dependencies @@ -174,7 +174,7 @@ repositories { } dependencies { - implementation platform("io.opentelemetry:opentelemetry-bom:1.45.0-SNAPSHOT") + implementation platform("io.opentelemetry:opentelemetry-bom:1.46.0-SNAPSHOT") implementation('io.opentelemetry:opentelemetry-api') } ``` @@ -196,7 +196,7 @@ dependencies { io.opentelemetry opentelemetry-bom - 1.45.0-SNAPSHOT + 1.46.0-SNAPSHOT pom import diff --git a/docs/apidiffs/1.45.0_vs_1.44.0/opentelemetry-api.txt b/docs/apidiffs/1.45.0_vs_1.44.0/opentelemetry-api.txt new file mode 100644 index 00000000000..bf2bd952ea2 --- /dev/null +++ b/docs/apidiffs/1.45.0_vs_1.44.0/opentelemetry-api.txt @@ -0,0 +1,4 @@ +Comparing source compatibility of opentelemetry-api-1.45.0.jar against opentelemetry-api-1.44.0.jar +*** MODIFIED INTERFACE: PUBLIC ABSTRACT io.opentelemetry.api.trace.SpanBuilder (not serializable) + === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 + +++ NEW METHOD: PUBLIC(+) io.opentelemetry.api.trace.SpanBuilder setAttribute(io.opentelemetry.api.common.AttributeKey, int) diff --git a/docs/apidiffs/1.45.0_vs_1.44.0/opentelemetry-context.txt b/docs/apidiffs/1.45.0_vs_1.44.0/opentelemetry-context.txt new file mode 100644 index 00000000000..2b2bd88aabf --- /dev/null +++ b/docs/apidiffs/1.45.0_vs_1.44.0/opentelemetry-context.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of opentelemetry-context-1.45.0.jar against opentelemetry-context-1.44.0.jar +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.45.0_vs_1.44.0/opentelemetry-exporter-common.txt b/docs/apidiffs/1.45.0_vs_1.44.0/opentelemetry-exporter-common.txt new file mode 100644 index 00000000000..d17a671090b --- /dev/null +++ b/docs/apidiffs/1.45.0_vs_1.44.0/opentelemetry-exporter-common.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of opentelemetry-exporter-common-1.45.0.jar against opentelemetry-exporter-common-1.44.0.jar +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.45.0_vs_1.44.0/opentelemetry-exporter-logging-otlp.txt b/docs/apidiffs/1.45.0_vs_1.44.0/opentelemetry-exporter-logging-otlp.txt new file mode 100644 index 00000000000..eacd4d7b06d --- /dev/null +++ b/docs/apidiffs/1.45.0_vs_1.44.0/opentelemetry-exporter-logging-otlp.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of opentelemetry-exporter-logging-otlp-1.45.0.jar against opentelemetry-exporter-logging-otlp-1.44.0.jar +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.45.0_vs_1.44.0/opentelemetry-exporter-logging.txt b/docs/apidiffs/1.45.0_vs_1.44.0/opentelemetry-exporter-logging.txt new file mode 100644 index 00000000000..9a73557f2c7 --- /dev/null +++ b/docs/apidiffs/1.45.0_vs_1.44.0/opentelemetry-exporter-logging.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of opentelemetry-exporter-logging-1.45.0.jar against opentelemetry-exporter-logging-1.44.0.jar +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.45.0_vs_1.44.0/opentelemetry-exporter-otlp-common.txt b/docs/apidiffs/1.45.0_vs_1.44.0/opentelemetry-exporter-otlp-common.txt new file mode 100644 index 00000000000..26804e02640 --- /dev/null +++ b/docs/apidiffs/1.45.0_vs_1.44.0/opentelemetry-exporter-otlp-common.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of opentelemetry-exporter-otlp-common-1.45.0.jar against opentelemetry-exporter-otlp-common-1.44.0.jar +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.45.0_vs_1.44.0/opentelemetry-exporter-otlp.txt b/docs/apidiffs/1.45.0_vs_1.44.0/opentelemetry-exporter-otlp.txt new file mode 100644 index 00000000000..22aba4564a1 --- /dev/null +++ b/docs/apidiffs/1.45.0_vs_1.44.0/opentelemetry-exporter-otlp.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of opentelemetry-exporter-otlp-1.45.0.jar against opentelemetry-exporter-otlp-1.44.0.jar +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.45.0_vs_1.44.0/opentelemetry-exporter-sender-grpc-managed-channel.txt b/docs/apidiffs/1.45.0_vs_1.44.0/opentelemetry-exporter-sender-grpc-managed-channel.txt new file mode 100644 index 00000000000..198cbb3e26a --- /dev/null +++ b/docs/apidiffs/1.45.0_vs_1.44.0/opentelemetry-exporter-sender-grpc-managed-channel.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of opentelemetry-exporter-sender-grpc-managed-channel-1.45.0.jar against opentelemetry-exporter-sender-grpc-managed-channel-1.44.0.jar +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.45.0_vs_1.44.0/opentelemetry-exporter-sender-jdk.txt b/docs/apidiffs/1.45.0_vs_1.44.0/opentelemetry-exporter-sender-jdk.txt new file mode 100644 index 00000000000..4dc968493c8 --- /dev/null +++ b/docs/apidiffs/1.45.0_vs_1.44.0/opentelemetry-exporter-sender-jdk.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of opentelemetry-exporter-sender-jdk-1.45.0.jar against opentelemetry-exporter-sender-jdk-1.44.0.jar +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.45.0_vs_1.44.0/opentelemetry-exporter-sender-okhttp.txt b/docs/apidiffs/1.45.0_vs_1.44.0/opentelemetry-exporter-sender-okhttp.txt new file mode 100644 index 00000000000..6c13a1dedff --- /dev/null +++ b/docs/apidiffs/1.45.0_vs_1.44.0/opentelemetry-exporter-sender-okhttp.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of opentelemetry-exporter-sender-okhttp-1.45.0.jar against opentelemetry-exporter-sender-okhttp-1.44.0.jar +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.45.0_vs_1.44.0/opentelemetry-exporter-zipkin.txt b/docs/apidiffs/1.45.0_vs_1.44.0/opentelemetry-exporter-zipkin.txt new file mode 100644 index 00000000000..fd6e10c1e2c --- /dev/null +++ b/docs/apidiffs/1.45.0_vs_1.44.0/opentelemetry-exporter-zipkin.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of opentelemetry-exporter-zipkin-1.45.0.jar against opentelemetry-exporter-zipkin-1.44.0.jar +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.45.0_vs_1.44.0/opentelemetry-extension-kotlin.txt b/docs/apidiffs/1.45.0_vs_1.44.0/opentelemetry-extension-kotlin.txt new file mode 100644 index 00000000000..ab527cf1319 --- /dev/null +++ b/docs/apidiffs/1.45.0_vs_1.44.0/opentelemetry-extension-kotlin.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of opentelemetry-extension-kotlin-1.45.0.jar against opentelemetry-extension-kotlin-1.44.0.jar +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.45.0_vs_1.44.0/opentelemetry-extension-trace-propagators.txt b/docs/apidiffs/1.45.0_vs_1.44.0/opentelemetry-extension-trace-propagators.txt new file mode 100644 index 00000000000..03fda39decf --- /dev/null +++ b/docs/apidiffs/1.45.0_vs_1.44.0/opentelemetry-extension-trace-propagators.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of opentelemetry-extension-trace-propagators-1.45.0.jar against opentelemetry-extension-trace-propagators-1.44.0.jar +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.45.0_vs_1.44.0/opentelemetry-opentracing-shim.txt b/docs/apidiffs/1.45.0_vs_1.44.0/opentelemetry-opentracing-shim.txt new file mode 100644 index 00000000000..2b7bfb4bd1c --- /dev/null +++ b/docs/apidiffs/1.45.0_vs_1.44.0/opentelemetry-opentracing-shim.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of opentelemetry-opentracing-shim-1.45.0.jar against opentelemetry-opentracing-shim-1.44.0.jar +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.45.0_vs_1.44.0/opentelemetry-sdk-common.txt b/docs/apidiffs/1.45.0_vs_1.44.0/opentelemetry-sdk-common.txt new file mode 100644 index 00000000000..50d8efb7a82 --- /dev/null +++ b/docs/apidiffs/1.45.0_vs_1.44.0/opentelemetry-sdk-common.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of opentelemetry-sdk-common-1.45.0.jar against opentelemetry-sdk-common-1.44.0.jar +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.45.0_vs_1.44.0/opentelemetry-sdk-extension-autoconfigure-spi.txt b/docs/apidiffs/1.45.0_vs_1.44.0/opentelemetry-sdk-extension-autoconfigure-spi.txt new file mode 100644 index 00000000000..39174b4c385 --- /dev/null +++ b/docs/apidiffs/1.45.0_vs_1.44.0/opentelemetry-sdk-extension-autoconfigure-spi.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of opentelemetry-sdk-extension-autoconfigure-spi-1.45.0.jar against opentelemetry-sdk-extension-autoconfigure-spi-1.44.0.jar +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.45.0_vs_1.44.0/opentelemetry-sdk-extension-autoconfigure.txt b/docs/apidiffs/1.45.0_vs_1.44.0/opentelemetry-sdk-extension-autoconfigure.txt new file mode 100644 index 00000000000..fe749f6f68c --- /dev/null +++ b/docs/apidiffs/1.45.0_vs_1.44.0/opentelemetry-sdk-extension-autoconfigure.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of opentelemetry-sdk-extension-autoconfigure-1.45.0.jar against opentelemetry-sdk-extension-autoconfigure-1.44.0.jar +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.45.0_vs_1.44.0/opentelemetry-sdk-extension-jaeger-remote-sampler.txt b/docs/apidiffs/1.45.0_vs_1.44.0/opentelemetry-sdk-extension-jaeger-remote-sampler.txt new file mode 100644 index 00000000000..c48ad9ea5c8 --- /dev/null +++ b/docs/apidiffs/1.45.0_vs_1.44.0/opentelemetry-sdk-extension-jaeger-remote-sampler.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of opentelemetry-sdk-extension-jaeger-remote-sampler-1.45.0.jar against opentelemetry-sdk-extension-jaeger-remote-sampler-1.44.0.jar +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.45.0_vs_1.44.0/opentelemetry-sdk-logs.txt b/docs/apidiffs/1.45.0_vs_1.44.0/opentelemetry-sdk-logs.txt new file mode 100644 index 00000000000..b037e09c771 --- /dev/null +++ b/docs/apidiffs/1.45.0_vs_1.44.0/opentelemetry-sdk-logs.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of opentelemetry-sdk-logs-1.45.0.jar against opentelemetry-sdk-logs-1.44.0.jar +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.45.0_vs_1.44.0/opentelemetry-sdk-metrics.txt b/docs/apidiffs/1.45.0_vs_1.44.0/opentelemetry-sdk-metrics.txt new file mode 100644 index 00000000000..80ba32106db --- /dev/null +++ b/docs/apidiffs/1.45.0_vs_1.44.0/opentelemetry-sdk-metrics.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of opentelemetry-sdk-metrics-1.45.0.jar against opentelemetry-sdk-metrics-1.44.0.jar +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.45.0_vs_1.44.0/opentelemetry-sdk-testing.txt b/docs/apidiffs/1.45.0_vs_1.44.0/opentelemetry-sdk-testing.txt new file mode 100644 index 00000000000..257565b8a2b --- /dev/null +++ b/docs/apidiffs/1.45.0_vs_1.44.0/opentelemetry-sdk-testing.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of opentelemetry-sdk-testing-1.45.0.jar against opentelemetry-sdk-testing-1.44.0.jar +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.45.0_vs_1.44.0/opentelemetry-sdk-trace.txt b/docs/apidiffs/1.45.0_vs_1.44.0/opentelemetry-sdk-trace.txt new file mode 100644 index 00000000000..6f3a3c4eb05 --- /dev/null +++ b/docs/apidiffs/1.45.0_vs_1.44.0/opentelemetry-sdk-trace.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of opentelemetry-sdk-trace-1.45.0.jar against opentelemetry-sdk-trace-1.44.0.jar +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.45.0_vs_1.44.0/opentelemetry-sdk.txt b/docs/apidiffs/1.45.0_vs_1.44.0/opentelemetry-sdk.txt new file mode 100644 index 00000000000..cb527f8bc36 --- /dev/null +++ b/docs/apidiffs/1.45.0_vs_1.44.0/opentelemetry-sdk.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of opentelemetry-sdk-1.45.0.jar against opentelemetry-sdk-1.44.0.jar +No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-api.txt b/docs/apidiffs/current_vs_latest/opentelemetry-api.txt index 4bc9a878f22..e557956558f 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-api.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-api.txt @@ -1,4 +1,2 @@ -Comparing source compatibility of opentelemetry-api-1.45.0-SNAPSHOT.jar against opentelemetry-api-1.44.1.jar -*** MODIFIED INTERFACE: PUBLIC ABSTRACT io.opentelemetry.api.trace.SpanBuilder (not serializable) - === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 - +++ NEW METHOD: PUBLIC(+) io.opentelemetry.api.trace.SpanBuilder setAttribute(io.opentelemetry.api.common.AttributeKey, int) +Comparing source compatibility of opentelemetry-api-1.46.0-SNAPSHOT.jar against opentelemetry-api-1.45.0.jar +No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-context.txt b/docs/apidiffs/current_vs_latest/opentelemetry-context.txt index 6dfe94027f0..e9f4fd71d81 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-context.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-context.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of opentelemetry-context-1.45.0-SNAPSHOT.jar against opentelemetry-context-1.44.1.jar +Comparing source compatibility of opentelemetry-context-1.46.0-SNAPSHOT.jar against opentelemetry-context-1.45.0.jar No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-common.txt b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-common.txt index 8692bd40f0d..b1838c92c1a 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-common.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-common.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of opentelemetry-exporter-common-1.45.0-SNAPSHOT.jar against opentelemetry-exporter-common-1.44.1.jar +Comparing source compatibility of opentelemetry-exporter-common-1.46.0-SNAPSHOT.jar against opentelemetry-exporter-common-1.45.0.jar No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-logging-otlp.txt b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-logging-otlp.txt index 53e3a232b55..f4ee97ae586 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-logging-otlp.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-logging-otlp.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of opentelemetry-exporter-logging-otlp-1.45.0-SNAPSHOT.jar against opentelemetry-exporter-logging-otlp-1.44.1.jar +Comparing source compatibility of opentelemetry-exporter-logging-otlp-1.46.0-SNAPSHOT.jar against opentelemetry-exporter-logging-otlp-1.45.0.jar No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-logging.txt b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-logging.txt index c4c1a7bb9e5..ad52df00ff8 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-logging.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-logging.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of opentelemetry-exporter-logging-1.45.0-SNAPSHOT.jar against opentelemetry-exporter-logging-1.44.1.jar +Comparing source compatibility of opentelemetry-exporter-logging-1.46.0-SNAPSHOT.jar against opentelemetry-exporter-logging-1.45.0.jar No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-otlp-common.txt b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-otlp-common.txt index 190cf34e311..2fc47a297b6 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-otlp-common.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-otlp-common.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of opentelemetry-exporter-otlp-common-1.45.0-SNAPSHOT.jar against opentelemetry-exporter-otlp-common-1.44.1.jar +Comparing source compatibility of opentelemetry-exporter-otlp-common-1.46.0-SNAPSHOT.jar against opentelemetry-exporter-otlp-common-1.45.0.jar No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-otlp.txt b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-otlp.txt index 8f73054e163..5a2acbb88a6 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-otlp.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-otlp.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of opentelemetry-exporter-otlp-1.45.0-SNAPSHOT.jar against opentelemetry-exporter-otlp-1.44.1.jar +Comparing source compatibility of opentelemetry-exporter-otlp-1.46.0-SNAPSHOT.jar against opentelemetry-exporter-otlp-1.45.0.jar No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-sender-grpc-managed-channel.txt b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-sender-grpc-managed-channel.txt index 5eefbf7d6c1..943b658de9a 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-sender-grpc-managed-channel.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-sender-grpc-managed-channel.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of opentelemetry-exporter-sender-grpc-managed-channel-1.45.0-SNAPSHOT.jar against opentelemetry-exporter-sender-grpc-managed-channel-1.44.1.jar +Comparing source compatibility of opentelemetry-exporter-sender-grpc-managed-channel-1.46.0-SNAPSHOT.jar against opentelemetry-exporter-sender-grpc-managed-channel-1.45.0.jar No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-sender-jdk.txt b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-sender-jdk.txt index 34a695b7df2..a18ec60fc0c 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-sender-jdk.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-sender-jdk.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of opentelemetry-exporter-sender-jdk-1.45.0-SNAPSHOT.jar against opentelemetry-exporter-sender-jdk-1.44.1.jar +Comparing source compatibility of opentelemetry-exporter-sender-jdk-1.46.0-SNAPSHOT.jar against opentelemetry-exporter-sender-jdk-1.45.0.jar No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-sender-okhttp.txt b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-sender-okhttp.txt index 89f989f8f99..4de0d949877 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-sender-okhttp.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-sender-okhttp.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of opentelemetry-exporter-sender-okhttp-1.45.0-SNAPSHOT.jar against opentelemetry-exporter-sender-okhttp-1.44.1.jar +Comparing source compatibility of opentelemetry-exporter-sender-okhttp-1.46.0-SNAPSHOT.jar against opentelemetry-exporter-sender-okhttp-1.45.0.jar No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-zipkin.txt b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-zipkin.txt index 3a9ad3b76f1..6eee24ad477 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-zipkin.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-zipkin.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of opentelemetry-exporter-zipkin-1.45.0-SNAPSHOT.jar against opentelemetry-exporter-zipkin-1.44.1.jar +Comparing source compatibility of opentelemetry-exporter-zipkin-1.46.0-SNAPSHOT.jar against opentelemetry-exporter-zipkin-1.45.0.jar No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-extension-kotlin.txt b/docs/apidiffs/current_vs_latest/opentelemetry-extension-kotlin.txt index 589f2bff4a7..da836c4e761 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-extension-kotlin.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-extension-kotlin.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of opentelemetry-extension-kotlin-1.45.0-SNAPSHOT.jar against opentelemetry-extension-kotlin-1.44.1.jar +Comparing source compatibility of opentelemetry-extension-kotlin-1.46.0-SNAPSHOT.jar against opentelemetry-extension-kotlin-1.45.0.jar No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-extension-trace-propagators.txt b/docs/apidiffs/current_vs_latest/opentelemetry-extension-trace-propagators.txt index 4de33099a46..d03771ed7dd 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-extension-trace-propagators.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-extension-trace-propagators.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of opentelemetry-extension-trace-propagators-1.45.0-SNAPSHOT.jar against opentelemetry-extension-trace-propagators-1.44.1.jar +Comparing source compatibility of opentelemetry-extension-trace-propagators-1.46.0-SNAPSHOT.jar against opentelemetry-extension-trace-propagators-1.45.0.jar No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-opentracing-shim.txt b/docs/apidiffs/current_vs_latest/opentelemetry-opentracing-shim.txt index f45d2f75a1d..46f5bdf7e78 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-opentracing-shim.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-opentracing-shim.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of opentelemetry-opentracing-shim-1.45.0-SNAPSHOT.jar against opentelemetry-opentracing-shim-1.44.1.jar +Comparing source compatibility of opentelemetry-opentracing-shim-1.46.0-SNAPSHOT.jar against opentelemetry-opentracing-shim-1.45.0.jar No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-common.txt b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-common.txt index 9c5036c7232..573574f361f 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-common.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-common.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of opentelemetry-sdk-common-1.45.0-SNAPSHOT.jar against opentelemetry-sdk-common-1.44.1.jar +Comparing source compatibility of opentelemetry-sdk-common-1.46.0-SNAPSHOT.jar against opentelemetry-sdk-common-1.45.0.jar No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-extension-autoconfigure-spi.txt b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-extension-autoconfigure-spi.txt index 9c9a827fdf4..5d0125c6605 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-extension-autoconfigure-spi.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-extension-autoconfigure-spi.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of opentelemetry-sdk-extension-autoconfigure-spi-1.45.0-SNAPSHOT.jar against opentelemetry-sdk-extension-autoconfigure-spi-1.44.1.jar +Comparing source compatibility of opentelemetry-sdk-extension-autoconfigure-spi-1.46.0-SNAPSHOT.jar against opentelemetry-sdk-extension-autoconfigure-spi-1.45.0.jar No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-extension-autoconfigure.txt b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-extension-autoconfigure.txt index aa2ec5b1d26..f1b7db454cf 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-extension-autoconfigure.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-extension-autoconfigure.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of opentelemetry-sdk-extension-autoconfigure-1.45.0-SNAPSHOT.jar against opentelemetry-sdk-extension-autoconfigure-1.44.1.jar +Comparing source compatibility of opentelemetry-sdk-extension-autoconfigure-1.46.0-SNAPSHOT.jar against opentelemetry-sdk-extension-autoconfigure-1.45.0.jar No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-extension-jaeger-remote-sampler.txt b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-extension-jaeger-remote-sampler.txt index e61102f3a81..34e24ebfff6 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-extension-jaeger-remote-sampler.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-extension-jaeger-remote-sampler.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of opentelemetry-sdk-extension-jaeger-remote-sampler-1.45.0-SNAPSHOT.jar against opentelemetry-sdk-extension-jaeger-remote-sampler-1.44.1.jar +Comparing source compatibility of opentelemetry-sdk-extension-jaeger-remote-sampler-1.46.0-SNAPSHOT.jar against opentelemetry-sdk-extension-jaeger-remote-sampler-1.45.0.jar No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-logs.txt b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-logs.txt index 3c2b9fb4e3a..3cee338a2c6 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-logs.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-logs.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of opentelemetry-sdk-logs-1.45.0-SNAPSHOT.jar against opentelemetry-sdk-logs-1.44.1.jar +Comparing source compatibility of opentelemetry-sdk-logs-1.46.0-SNAPSHOT.jar against opentelemetry-sdk-logs-1.45.0.jar No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-metrics.txt b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-metrics.txt index ef08400bb94..37d013e9fb8 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-metrics.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-metrics.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of opentelemetry-sdk-metrics-1.45.0-SNAPSHOT.jar against opentelemetry-sdk-metrics-1.44.1.jar +Comparing source compatibility of opentelemetry-sdk-metrics-1.46.0-SNAPSHOT.jar against opentelemetry-sdk-metrics-1.45.0.jar No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-testing.txt b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-testing.txt index b04bcd8ff85..705e94ae4c0 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-testing.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-testing.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of opentelemetry-sdk-testing-1.45.0-SNAPSHOT.jar against opentelemetry-sdk-testing-1.44.1.jar +Comparing source compatibility of opentelemetry-sdk-testing-1.46.0-SNAPSHOT.jar against opentelemetry-sdk-testing-1.45.0.jar No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-trace.txt b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-trace.txt index 5e83a4987a7..50cf7470b99 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-trace.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-trace.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of opentelemetry-sdk-trace-1.45.0-SNAPSHOT.jar against opentelemetry-sdk-trace-1.44.1.jar +Comparing source compatibility of opentelemetry-sdk-trace-1.46.0-SNAPSHOT.jar against opentelemetry-sdk-trace-1.45.0.jar No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-sdk.txt b/docs/apidiffs/current_vs_latest/opentelemetry-sdk.txt index 8ff004b24a4..190ad7d42ad 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-sdk.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-sdk.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of opentelemetry-sdk-1.45.0-SNAPSHOT.jar against opentelemetry-sdk-1.44.1.jar +Comparing source compatibility of opentelemetry-sdk-1.46.0-SNAPSHOT.jar against opentelemetry-sdk-1.45.0.jar No changes. \ No newline at end of file From af1e1d57ee4dd69883d544f6bb39e9145a9972fc Mon Sep 17 00:00:00 2001 From: jack-berg <34418638+jack-berg@users.noreply.github.com> Date: Fri, 6 Dec 2024 17:21:52 -0600 Subject: [PATCH 703/901] Remove japicmp special case (#6933) --- .../otel.japicmp-conventions.gradle.kts | 47 ------------------- 1 file changed, 47 deletions(-) diff --git a/buildSrc/src/main/kotlin/otel.japicmp-conventions.gradle.kts b/buildSrc/src/main/kotlin/otel.japicmp-conventions.gradle.kts index e9a0ff0b408..b59be80dd9b 100644 --- a/buildSrc/src/main/kotlin/otel.japicmp-conventions.gradle.kts +++ b/buildSrc/src/main/kotlin/otel.japicmp-conventions.gradle.kts @@ -47,55 +47,8 @@ class AllowNewAbstractMethodOnAutovalueClasses : AbstractRecordingSeenMembers() } class SourceIncompatibleRule : AbstractRecordingSeenMembers() { - - fun ignoreAddLogRecordProcessorCustomizerReturnTypeChange(member: JApiCompatibility): Violation? { - if (member is JApiClass && - member.newClass.get().name.equals("io.opentelemetry.sdk.autoconfigure.AutoConfiguredOpenTelemetrySdkBuilder") && - member.isChangeCausedByClassElement - ) { - // member.isChangeCausedByClassElement check above - // limits source of changes to fields, methods and constructors - - for (method in member.methods) { - if (!method.isSourceCompatible()) { - // addLogRecordProcessorCustomizer method had a return type change from base to impl class, - // japicmp (correctly) doesn't consider it as a METHOD_RETURN_TYPE_CHANGED - // compatibility issue. But still thinks that something wrong. - // Since it thinks that method did not change, it reports it as class-level violation, - // and we need to suppress it, but keep other checks on. - if (method.name.equals("addLogRecordProcessorCustomizer") && - method.compatibilityChanges.isEmpty() && - method.changeStatus == JApiChangeStatus.UNCHANGED) { - return null; - } - return Violation.error(method, "Method is not source compatible: $method") - } - } - - for (field in member.fields) { - if (!field.isSourceCompatible()) { - return Violation.error(field, "Field is not source compatible: $field") - } - } - - for (constructor in member.constructors) { - if (!constructor.isSourceCompatible()) { - return Violation.error(constructor, "Constructor is not source compatible: $constructor") - } - } - } - - return Violation.error(member, "Not source compatible: $member") - } - override fun maybeAddViolation(member: JApiCompatibility): Violation? { if (!member.isSourceCompatible()) { - // TODO: remove after 1.36.0 is released, see https://github.com/open-telemetry/opentelemetry-java/pull/6248 - if (member.compatibilityChanges.isEmpty()) { - return ignoreAddLogRecordProcessorCustomizerReturnTypeChange(member) - } - // end of suppression - return Violation.error(member, "Not source compatible: $member") } return null From e61e19ae23756c5574e4a4e8565f5da4a203247a Mon Sep 17 00:00:00 2001 From: jack-berg <34418638+jack-berg@users.noreply.github.com> Date: Fri, 6 Dec 2024 17:22:02 -0600 Subject: [PATCH 704/901] Remove outdated TODOs (#6932) --- .../src/main/java/io/opentelemetry/api/baggage/package-info.java | 1 - .../src/main/java/io/opentelemetry/api/trace/package-info.java | 1 - 2 files changed, 2 deletions(-) diff --git a/api/all/src/main/java/io/opentelemetry/api/baggage/package-info.java b/api/all/src/main/java/io/opentelemetry/api/baggage/package-info.java index 7cf942a9129..d119efa9a03 100644 --- a/api/all/src/main/java/io/opentelemetry/api/baggage/package-info.java +++ b/api/all/src/main/java/io/opentelemetry/api/baggage/package-info.java @@ -13,7 +13,6 @@ *

      Note that entries are independent of the tracing data that is propagated in the {@link * io.opentelemetry.context.Context}, such as trace ID. */ -// TODO: Add code examples. @ParametersAreNonnullByDefault package io.opentelemetry.api.baggage; diff --git a/api/all/src/main/java/io/opentelemetry/api/trace/package-info.java b/api/all/src/main/java/io/opentelemetry/api/trace/package-info.java index 2970a7eeadf..1a6e4789fb7 100644 --- a/api/all/src/main/java/io/opentelemetry/api/trace/package-info.java +++ b/api/all/src/main/java/io/opentelemetry/api/trace/package-info.java @@ -18,7 +18,6 @@ * io.opentelemetry.context.Context} and between process using one of the wire propagation formats * supported in the {@code opentelemetry.trace.propagation} package. */ -// TODO: Add code examples. @ParametersAreNonnullByDefault package io.opentelemetry.api.trace; From 1f8ee517bfbec147ca5a7c45b2f82d05c4c9f48b Mon Sep 17 00:00:00 2001 From: jack-berg <34418638+jack-berg@users.noreply.github.com> Date: Fri, 6 Dec 2024 17:22:12 -0600 Subject: [PATCH 705/901] Remove support for deprecated otel.experimental.resource.disabled.keys (#6931) --- .../autoconfigure/ResourceConfiguration.java | 13 ------------ .../ResourceConfigurationTest.java | 21 ------------------- 2 files changed, 34 deletions(-) diff --git a/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/ResourceConfiguration.java b/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/ResourceConfiguration.java index 21026fe75aa..5e94f966a39 100644 --- a/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/ResourceConfiguration.java +++ b/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/ResourceConfiguration.java @@ -25,7 +25,6 @@ import java.util.Map; import java.util.Set; import java.util.function.BiFunction; -import java.util.logging.Logger; /** * Auto-configuration for the OpenTelemetry {@link Resource}. @@ -34,15 +33,11 @@ */ public final class ResourceConfiguration { - private static final Logger logger = Logger.getLogger(ResourceConfiguration.class.getName()); - private static final AttributeKey SERVICE_NAME = AttributeKey.stringKey("service.name"); // Visible for testing static final String ATTRIBUTE_PROPERTY = "otel.resource.attributes"; static final String SERVICE_NAME_PROPERTY = "otel.service.name"; - static final String EXPERIMENTAL_DISABLED_ATTRIBUTE_KEYS = - "otel.experimental.resource.disabled.keys"; static final String DISABLED_ATTRIBUTE_KEYS = "otel.resource.disabled.keys"; /** @@ -120,14 +115,6 @@ static Resource configureResource( // visible for testing static Resource filterAttributes(Resource resource, ConfigProperties configProperties) { List disabledAttibuteKeys = configProperties.getList(DISABLED_ATTRIBUTE_KEYS); - // TODO: Remove this once the deprecated property is removed. - if (disabledAttibuteKeys.isEmpty()) { - disabledAttibuteKeys = configProperties.getList(EXPERIMENTAL_DISABLED_ATTRIBUTE_KEYS); - if (!disabledAttibuteKeys.isEmpty()) { - logger.warning( - "otel.experimental.resource.disabled.keys is deprecated and will be removed after 1.45.0 release. Please use otel.resource.disabled.keys instead."); - } - } Set disabledKeys = new HashSet<>(disabledAttibuteKeys); ResourceBuilder builder = diff --git a/sdk-extensions/autoconfigure/src/test/java/io/opentelemetry/sdk/autoconfigure/ResourceConfigurationTest.java b/sdk-extensions/autoconfigure/src/test/java/io/opentelemetry/sdk/autoconfigure/ResourceConfigurationTest.java index 8e6a42d3af6..e2c94a68aa8 100644 --- a/sdk-extensions/autoconfigure/src/test/java/io/opentelemetry/sdk/autoconfigure/ResourceConfigurationTest.java +++ b/sdk-extensions/autoconfigure/src/test/java/io/opentelemetry/sdk/autoconfigure/ResourceConfigurationTest.java @@ -46,27 +46,6 @@ void customConfigResourceWithDisabledKeys() { .build()); } - @Test - void customConfigResourceWithExperimentalDisabledKeys() { - Map props = new HashMap<>(); - props.put("otel.service.name", "test-service"); - props.put( - "otel.resource.attributes", "food=cheesecake,drink=juice,animal= ,color=,shape=square"); - props.put("otel.experimental.resource.disabled-keys", "drink"); - - assertThat( - ResourceConfiguration.configureResource( - DefaultConfigProperties.create(props), - SpiHelper.create(ResourceConfigurationTest.class.getClassLoader()), - (r, c) -> r)) - .isEqualTo( - Resource.getDefault().toBuilder() - .put(stringKey("service.name"), "test-service") - .put("food", "cheesecake") - .put("shape", "square") - .build()); - } - @Test void createEnvironmentResource_Empty() { Attributes attributes = ResourceConfiguration.createEnvironmentResource().getAttributes(); From 3928febd2dd377e74708235c8591d0b6fc58224c Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 6 Dec 2024 17:55:35 -0800 Subject: [PATCH 706/901] fix(deps): update dependency nl.jqno.equalsverifier:equalsverifier to v3.17.5 (#6926) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Co-authored-by: Jack Berg --- buildSrc/src/main/kotlin/otel.java-conventions.gradle.kts | 1 - dependencyManagement/build.gradle.kts | 3 +-- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/buildSrc/src/main/kotlin/otel.java-conventions.gradle.kts b/buildSrc/src/main/kotlin/otel.java-conventions.gradle.kts index 3fbc9cb1daa..26a845f5c8a 100644 --- a/buildSrc/src/main/kotlin/otel.java-conventions.gradle.kts +++ b/buildSrc/src/main/kotlin/otel.java-conventions.gradle.kts @@ -237,7 +237,6 @@ testing { compileOnly("com.google.auto.value:auto-value-annotations") compileOnly("com.google.errorprone:error_prone_annotations") compileOnly("com.google.code.findbugs:jsr305") - compileOnly("com.google.code.findbugs:annotations") implementation("org.junit.jupiter:junit-jupiter-api") implementation("org.junit.jupiter:junit-jupiter-params") diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index 11e38dffdfc..4e4237fd6e0 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -61,7 +61,6 @@ val DEPENDENCIES = listOf( "javax.annotation:javax.annotation-api:1.3.2", "com.github.stefanbirkner:system-rules:1.19.0", "com.google.api.grpc:proto-google-common-protos:2.49.0", - "com.google.code.findbugs:annotations:3.0.1", "com.google.code.findbugs:jsr305:3.0.2", "com.google.guava:guava-beta-checker:1.0", "com.sun.net.httpserver:http:20070405", @@ -77,7 +76,7 @@ val DEPENDENCIES = listOf( "io.opentracing:opentracing-api:0.33.0", "io.opentracing:opentracing-noop:0.33.0", "junit:junit:4.13.2", - "nl.jqno.equalsverifier:equalsverifier:3.17.4", + "nl.jqno.equalsverifier:equalsverifier:3.17.5", "org.awaitility:awaitility:4.2.2", "org.bouncycastle:bcpkix-jdk15on:1.70", "org.codehaus.mojo:animal-sniffer-annotations:1.24", From aca4ee35cbacb0aa0dc14bfff74554cffe9ce7f2 Mon Sep 17 00:00:00 2001 From: jack-berg <34418638+jack-berg@users.noreply.github.com> Date: Fri, 6 Dec 2024 20:12:04 -0600 Subject: [PATCH 707/901] Declarative config: more qualified imports (#6930) --- .../fileconfig/AggregationFactory.java | 21 +++++++++---------- .../fileconfig/AttributeListFactory.java | 8 +++---- .../fileconfig/FileConfiguration.java | 4 ++-- .../fileconfig/LogRecordProcessorFactory.java | 5 +++-- .../fileconfig/MeterProviderFactory.java | 3 ++- .../fileconfig/MetricReaderFactory.java | 7 ++++--- .../incubator/fileconfig/ResourceFactory.java | 11 +++------- .../fileconfig/SpanLimitsFactory.java | 8 +++---- .../fileconfig/SpanProcessorFactory.java | 5 +++-- 9 files changed, 35 insertions(+), 37 deletions(-) diff --git a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/AggregationFactory.java b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/AggregationFactory.java index 6e35ecbdbfb..5626d27c212 100644 --- a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/AggregationFactory.java +++ b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/AggregationFactory.java @@ -10,11 +10,11 @@ import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.AggregationModel; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.Base2ExponentialBucketHistogramModel; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.ExplicitBucketHistogramModel; +import io.opentelemetry.sdk.metrics.Aggregation; import java.io.Closeable; import java.util.List; -final class AggregationFactory - implements Factory { +final class AggregationFactory implements Factory { private static final AggregationFactory INSTANCE = new AggregationFactory(); @@ -25,16 +25,16 @@ static AggregationFactory getInstance() { } @Override - public io.opentelemetry.sdk.metrics.Aggregation create( + public Aggregation create( AggregationModel model, SpiHelper spiHelper, List closeables) { if (model.getDrop() != null) { - return io.opentelemetry.sdk.metrics.Aggregation.drop(); + return Aggregation.drop(); } if (model.getSum() != null) { - return io.opentelemetry.sdk.metrics.Aggregation.sum(); + return Aggregation.sum(); } if (model.getLastValue() != null) { - return io.opentelemetry.sdk.metrics.Aggregation.lastValue(); + return Aggregation.lastValue(); } Base2ExponentialBucketHistogramModel exponentialBucketHistogram = model.getBase2ExponentialBucketHistogram(); @@ -48,8 +48,7 @@ public io.opentelemetry.sdk.metrics.Aggregation create( maxSize = 160; } try { - return io.opentelemetry.sdk.metrics.Aggregation.base2ExponentialBucketHistogram( - maxSize, maxScale); + return Aggregation.base2ExponentialBucketHistogram(maxSize, maxScale); } catch (IllegalArgumentException e) { throw new ConfigurationException("Invalid exponential bucket histogram", e); } @@ -58,15 +57,15 @@ public io.opentelemetry.sdk.metrics.Aggregation create( if (explicitBucketHistogram != null) { List boundaries = explicitBucketHistogram.getBoundaries(); if (boundaries == null) { - return io.opentelemetry.sdk.metrics.Aggregation.explicitBucketHistogram(); + return Aggregation.explicitBucketHistogram(); } try { - return io.opentelemetry.sdk.metrics.Aggregation.explicitBucketHistogram(boundaries); + return Aggregation.explicitBucketHistogram(boundaries); } catch (IllegalArgumentException e) { throw new ConfigurationException("Invalid explicit bucket histogram", e); } } - return io.opentelemetry.sdk.metrics.Aggregation.defaultAggregation(); + return Aggregation.defaultAggregation(); } } diff --git a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/AttributeListFactory.java b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/AttributeListFactory.java index c3bba8925b3..23d08e7fae7 100644 --- a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/AttributeListFactory.java +++ b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/AttributeListFactory.java @@ -8,6 +8,7 @@ import static java.util.stream.Collectors.toList; import io.opentelemetry.api.common.AttributeKey; +import io.opentelemetry.api.common.Attributes; import io.opentelemetry.api.common.AttributesBuilder; import io.opentelemetry.sdk.autoconfigure.internal.SpiHelper; import io.opentelemetry.sdk.autoconfigure.spi.ConfigurationException; @@ -16,8 +17,7 @@ import java.util.List; import javax.annotation.Nullable; -final class AttributeListFactory - implements Factory, io.opentelemetry.api.common.Attributes> { +final class AttributeListFactory implements Factory, Attributes> { private static final AttributeListFactory INSTANCE = new AttributeListFactory(); @@ -28,9 +28,9 @@ static AttributeListFactory getInstance() { } @Override - public io.opentelemetry.api.common.Attributes create( + public Attributes create( List model, SpiHelper spiHelper, List closeables) { - AttributesBuilder builder = io.opentelemetry.api.common.Attributes.builder(); + AttributesBuilder builder = Attributes.builder(); for (AttributeNameValueModel nameValueModel : model) { addToBuilder(nameValueModel, builder); diff --git a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/FileConfiguration.java b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/FileConfiguration.java index b8af0237188..7e5e98344d6 100644 --- a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/FileConfiguration.java +++ b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/FileConfiguration.java @@ -17,6 +17,7 @@ import io.opentelemetry.sdk.autoconfigure.spi.internal.StructuredConfigProperties; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.OpenTelemetryConfigurationModel; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.SamplerModel; +import io.opentelemetry.sdk.trace.samplers.Sampler; import java.io.Closeable; import java.io.IOException; import java.io.InputStream; @@ -183,8 +184,7 @@ static StructuredConfigProperties toConfigProperties( */ // TODO(jack-berg): add create methods for all SDK extension components supported by // ComponentProvider - public static io.opentelemetry.sdk.trace.samplers.Sampler createSampler( - StructuredConfigProperties genericSamplerModel) { + public static Sampler createSampler(StructuredConfigProperties genericSamplerModel) { YamlStructuredConfigProperties yamlStructuredConfigProperties = requireYamlStructuredConfigProperties(genericSamplerModel); SamplerModel samplerModel = convertToModel(yamlStructuredConfigProperties, SamplerModel.class); diff --git a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/LogRecordProcessorFactory.java b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/LogRecordProcessorFactory.java index a9cec70455a..3861617ad84 100644 --- a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/LogRecordProcessorFactory.java +++ b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/LogRecordProcessorFactory.java @@ -16,6 +16,7 @@ import io.opentelemetry.sdk.logs.LogRecordProcessor; import io.opentelemetry.sdk.logs.export.BatchLogRecordProcessor; import io.opentelemetry.sdk.logs.export.BatchLogRecordProcessorBuilder; +import io.opentelemetry.sdk.logs.export.LogRecordExporter; import io.opentelemetry.sdk.logs.export.SimpleLogRecordProcessor; import java.io.Closeable; import java.time.Duration; @@ -42,7 +43,7 @@ public LogRecordProcessor create( FileConfigUtil.requireNonNull( batchModel.getExporter(), "batch log record processor exporter"); - io.opentelemetry.sdk.logs.export.LogRecordExporter logRecordExporter = + LogRecordExporter logRecordExporter = LogRecordExporterFactory.getInstance().create(exporterModel, spiHelper, closeables); BatchLogRecordProcessorBuilder builder = BatchLogRecordProcessor.builder(logRecordExporter); if (batchModel.getExportTimeout() != null) { @@ -65,7 +66,7 @@ public LogRecordProcessor create( LogRecordExporterModel exporterModel = FileConfigUtil.requireNonNull( simpleModel.getExporter(), "simple log record processor exporter"); - io.opentelemetry.sdk.logs.export.LogRecordExporter logRecordExporter = + LogRecordExporter logRecordExporter = LogRecordExporterFactory.getInstance().create(exporterModel, spiHelper, closeables); return FileConfigUtil.addAndReturn( closeables, SimpleLogRecordProcessor.create(logRecordExporter)); diff --git a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/MeterProviderFactory.java b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/MeterProviderFactory.java index dd400eeeb1e..864277b8398 100644 --- a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/MeterProviderFactory.java +++ b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/MeterProviderFactory.java @@ -15,6 +15,7 @@ import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.ViewModel; import io.opentelemetry.sdk.metrics.SdkMeterProvider; import io.opentelemetry.sdk.metrics.SdkMeterProviderBuilder; +import io.opentelemetry.sdk.metrics.export.MetricReader; import java.io.Closeable; import java.util.List; @@ -37,7 +38,7 @@ public SdkMeterProviderBuilder create( if (readerModels != null) { readerModels.forEach( readerModel -> { - io.opentelemetry.sdk.metrics.export.MetricReader metricReader = + MetricReader metricReader = MetricReaderFactory.getInstance().create(readerModel, spiHelper, closeables); if (metricReader != null) { builder.registerMetricReader(metricReader); diff --git a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/MetricReaderFactory.java b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/MetricReaderFactory.java index c30ac774b60..fe7bd8bbf1a 100644 --- a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/MetricReaderFactory.java +++ b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/MetricReaderFactory.java @@ -15,7 +15,9 @@ import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.PullMetricExporterModel; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.PullMetricReaderModel; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.PushMetricExporterModel; +import io.opentelemetry.sdk.metrics.export.MetricExporter; import io.opentelemetry.sdk.metrics.export.MetricReader; +import io.opentelemetry.sdk.metrics.export.PeriodicMetricReader; import io.opentelemetry.sdk.metrics.export.PeriodicMetricReaderBuilder; import java.io.Closeable; import java.time.Duration; @@ -38,11 +40,10 @@ public MetricReader create( if (periodicModel != null) { PushMetricExporterModel exporterModel = requireNonNull(periodicModel.getExporter(), "periodic metric reader exporter"); - io.opentelemetry.sdk.metrics.export.MetricExporter metricExporter = + MetricExporter metricExporter = MetricExporterFactory.getInstance().create(exporterModel, spiHelper, closeables); PeriodicMetricReaderBuilder builder = - io.opentelemetry.sdk.metrics.export.PeriodicMetricReader.builder( - FileConfigUtil.addAndReturn(closeables, metricExporter)); + PeriodicMetricReader.builder(FileConfigUtil.addAndReturn(closeables, metricExporter)); if (periodicModel.getInterval() != null) { builder.setInterval(Duration.ofMillis(periodicModel.getInterval())); } diff --git a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/ResourceFactory.java b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/ResourceFactory.java index 0f3a8164c9f..6e40822a6b4 100644 --- a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/ResourceFactory.java +++ b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/ResourceFactory.java @@ -17,6 +17,7 @@ import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.AttributeNameValueModel; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.DetectorAttributesModel; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.DetectorsModel; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.ResourceModel; import io.opentelemetry.sdk.resources.Resource; import io.opentelemetry.sdk.resources.ResourceBuilder; import java.io.Closeable; @@ -28,10 +29,7 @@ import java.util.stream.Collectors; import javax.annotation.Nullable; -final class ResourceFactory - implements Factory< - io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.ResourceModel, - Resource> { +final class ResourceFactory implements Factory { private static final StructuredConfigProperties EMPTY_CONFIG = FileConfiguration.toConfigProperties( @@ -46,10 +44,7 @@ static ResourceFactory getInstance() { } @Override - public Resource create( - io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.ResourceModel model, - SpiHelper spiHelper, - List closeables) { + public Resource create(ResourceModel model, SpiHelper spiHelper, List closeables) { ResourceBuilder builder = Resource.getDefault().toBuilder(); ResourceBuilder detectedResourceBuilder = Resource.builder(); diff --git a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/SpanLimitsFactory.java b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/SpanLimitsFactory.java index b669c99bf06..c10c4bfd7a8 100644 --- a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/SpanLimitsFactory.java +++ b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/SpanLimitsFactory.java @@ -8,12 +8,12 @@ import io.opentelemetry.sdk.autoconfigure.internal.SpiHelper; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.AttributeLimitsModel; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.SpanLimitsModel; +import io.opentelemetry.sdk.trace.SpanLimits; import io.opentelemetry.sdk.trace.SpanLimitsBuilder; import java.io.Closeable; import java.util.List; -final class SpanLimitsFactory - implements Factory { +final class SpanLimitsFactory implements Factory { private static final SpanLimitsFactory INSTANCE = new SpanLimitsFactory(); @@ -24,9 +24,9 @@ static SpanLimitsFactory getInstance() { } @Override - public io.opentelemetry.sdk.trace.SpanLimits create( + public SpanLimits create( SpanLimitsAndAttributeLimits model, SpiHelper spiHelper, List closeables) { - SpanLimitsBuilder builder = io.opentelemetry.sdk.trace.SpanLimits.builder(); + SpanLimitsBuilder builder = SpanLimits.builder(); AttributeLimitsModel attributeLimitsModel = model.getAttributeLimits(); if (attributeLimitsModel != null) { diff --git a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/SpanProcessorFactory.java b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/SpanProcessorFactory.java index 04a5a144303..4a174e201f4 100644 --- a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/SpanProcessorFactory.java +++ b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/SpanProcessorFactory.java @@ -17,6 +17,7 @@ import io.opentelemetry.sdk.trace.export.BatchSpanProcessor; import io.opentelemetry.sdk.trace.export.BatchSpanProcessorBuilder; import io.opentelemetry.sdk.trace.export.SimpleSpanProcessor; +import io.opentelemetry.sdk.trace.export.SpanExporter; import java.io.Closeable; import java.time.Duration; import java.util.List; @@ -39,7 +40,7 @@ public SpanProcessor create( if (batchModel != null) { SpanExporterModel exporterModel = FileConfigUtil.requireNonNull(batchModel.getExporter(), "batch span processor exporter"); - io.opentelemetry.sdk.trace.export.SpanExporter spanExporter = + SpanExporter spanExporter = SpanExporterFactory.getInstance().create(exporterModel, spiHelper, closeables); BatchSpanProcessorBuilder builder = BatchSpanProcessor.builder(spanExporter); if (batchModel.getExportTimeout() != null) { @@ -62,7 +63,7 @@ public SpanProcessor create( SpanExporterModel exporterModel = FileConfigUtil.requireNonNull( simpleModel.getExporter(), "simple span processor exporter"); - io.opentelemetry.sdk.trace.export.SpanExporter spanExporter = + SpanExporter spanExporter = SpanExporterFactory.getInstance().create(exporterModel, spiHelper, closeables); return FileConfigUtil.addAndReturn(closeables, SimpleSpanProcessor.create(spanExporter)); } From efdacc1c184b17433b49a18f56b9dab01a97eb82 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 9 Dec 2024 07:42:47 -0800 Subject: [PATCH 708/901] fix(deps): update dependency io.zipkin.reporter2:zipkin-reporter-bom to v3.4.3 (#6934) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- dependencyManagement/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index 4e4237fd6e0..daad7f6f0fe 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -17,7 +17,7 @@ val DEPENDENCY_BOMS = listOf( "io.grpc:grpc-bom:1.68.2", "io.netty:netty-bom:4.1.115.Final", "io.zipkin.brave:brave-bom:6.0.3", - "io.zipkin.reporter2:zipkin-reporter-bom:3.4.2", + "io.zipkin.reporter2:zipkin-reporter-bom:3.4.3", "org.assertj:assertj-bom:3.26.3", "org.junit:junit-bom:5.11.3", "org.testcontainers:testcontainers-bom:1.20.4", From e3cfedee7d8e198b9092cd2b8408d1f2508e8cca Mon Sep 17 00:00:00 2001 From: jack-berg <34418638+jack-berg@users.noreply.github.com> Date: Wed, 11 Dec 2024 15:12:06 -0600 Subject: [PATCH 709/901] Fix -alpha status of opentelemetry-api-incubator (#6945) --- README.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index ee6157962b3..65b7e2c5c8e 100644 --- a/README.md +++ b/README.md @@ -60,11 +60,11 @@ A bill of materials (or BOM) helps sync dependency versions of related artifacts The OpenTelemetry API for recording telemetry. -| Component | Description | Artifact ID | Version | Javadoc | -|-----------------------------------|--------------------------------------------------------------------------------------|-------------------------------|---------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| [API](./api/all) | OpenTelemetry API, including metrics, traces, baggage, context | `opentelemetry-api` | 1.45.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-api.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-api) | -| [API Incubator](./api/incubator) | API incubator, including pass through propagator, and extended tracer, and Event API | `opentelemetry-api-incubator` | 1.45.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-api-incubator.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-api-incubator) | -| [Context API](./context) | OpenTelemetry context API | `opentelemetry-context` | 1.45.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-context.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-context) | +| Component | Description | Artifact ID | Version | Javadoc | +|-----------------------------------|--------------------------------------------------------------------------------------|-------------------------------|-------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| [API](./api/all) | OpenTelemetry API, including metrics, traces, baggage, context | `opentelemetry-api` | 1.45.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-api.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-api) | +| [API Incubator](./api/incubator) | API incubator, including pass through propagator, and extended tracer, and Event API | `opentelemetry-api-incubator` | 1.45.0-alpha | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-api-incubator.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-api-incubator) | +| [Context API](./context) | OpenTelemetry context API | `opentelemetry-context` | 1.45.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-context.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-context) |

      From 62f060ed9a4719213451cfc24203b208c4af318f Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 11 Dec 2024 17:10:43 -0800 Subject: [PATCH 710/901] fix(deps): update dependency io.grpc:grpc-bom to v1.69.0 (#6938) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Co-authored-by: Jason Plumb --- dependencyManagement/build.gradle.kts | 2 +- .../grpc/managedchannel/internal/UpstreamGrpcSender.java | 4 ++-- .../extension/trace/jaeger/sampler/UpstreamGrpcService.java | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index daad7f6f0fe..362c42ab59a 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -14,7 +14,7 @@ val DEPENDENCY_BOMS = listOf( "com.linecorp.armeria:armeria-bom:1.31.2", "com.squareup.okhttp3:okhttp-bom:4.12.0", "com.squareup.okio:okio-bom:3.9.1", // applies to transitive dependencies of okhttp - "io.grpc:grpc-bom:1.68.2", + "io.grpc:grpc-bom:1.69.0", "io.netty:netty-bom:4.1.115.Final", "io.zipkin.brave:brave-bom:6.0.3", "io.zipkin.reporter2:zipkin-reporter-bom:3.4.3", diff --git a/exporters/sender/grpc-managed-channel/src/main/java/io/opentelemetry/exporter/sender/grpc/managedchannel/internal/UpstreamGrpcSender.java b/exporters/sender/grpc-managed-channel/src/main/java/io/opentelemetry/exporter/sender/grpc/managedchannel/internal/UpstreamGrpcSender.java index 2c250399bb1..1f1ae5e4d28 100644 --- a/exporters/sender/grpc-managed-channel/src/main/java/io/opentelemetry/exporter/sender/grpc/managedchannel/internal/UpstreamGrpcSender.java +++ b/exporters/sender/grpc-managed-channel/src/main/java/io/opentelemetry/exporter/sender/grpc/managedchannel/internal/UpstreamGrpcSender.java @@ -19,9 +19,9 @@ import io.opentelemetry.exporter.internal.grpc.MarshalerServiceStub; import io.opentelemetry.exporter.internal.marshal.Marshaler; import io.opentelemetry.sdk.common.CompletableResultCode; +import java.time.Duration; import java.util.List; import java.util.Map; -import java.util.concurrent.TimeUnit; import java.util.function.Consumer; import java.util.function.Supplier; import javax.annotation.Nullable; @@ -55,7 +55,7 @@ public UpstreamGrpcSender( public void send(T request, Consumer onResponse, Consumer onError) { MarshalerServiceStub stub = this.stub; if (timeoutNanos > 0) { - stub = stub.withDeadlineAfter(timeoutNanos, TimeUnit.NANOSECONDS); + stub = stub.withDeadlineAfter(Duration.ofNanos(timeoutNanos)); } Map> headers = headersSupplier.get(); if (headers != null) { diff --git a/sdk-extensions/jaeger-remote-sampler/src/main/java/io/opentelemetry/sdk/extension/trace/jaeger/sampler/UpstreamGrpcService.java b/sdk-extensions/jaeger-remote-sampler/src/main/java/io/opentelemetry/sdk/extension/trace/jaeger/sampler/UpstreamGrpcService.java index 32b19e4c0bc..49551df496f 100644 --- a/sdk-extensions/jaeger-remote-sampler/src/main/java/io/opentelemetry/sdk/extension/trace/jaeger/sampler/UpstreamGrpcService.java +++ b/sdk-extensions/jaeger-remote-sampler/src/main/java/io/opentelemetry/sdk/extension/trace/jaeger/sampler/UpstreamGrpcService.java @@ -11,7 +11,7 @@ import io.opentelemetry.exporter.internal.grpc.ManagedChannelUtil; import io.opentelemetry.exporter.internal.grpc.MarshalerServiceStub; import io.opentelemetry.sdk.common.CompletableResultCode; -import java.util.concurrent.TimeUnit; +import java.time.Duration; import java.util.logging.Level; import java.util.logging.Logger; @@ -48,7 +48,7 @@ public SamplingStrategyResponseUnMarshaler execute( SamplingStrategyParametersMarshaler, SamplingStrategyResponseUnMarshaler, ?> stub = this.stub; if (timeoutNanos > 0) { - stub = stub.withDeadlineAfter(timeoutNanos, TimeUnit.NANOSECONDS); + stub = stub.withDeadlineAfter(Duration.ofNanos(timeoutNanos)); } try { From f68ba65d6bd608ffa167cf901ac1bb33f8fcb0f3 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 11 Dec 2024 17:15:54 -0800 Subject: [PATCH 711/901] fix(deps): update dependency com.linecorp.armeria:armeria-bom to v1.31.3 (#6941) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- dependencyManagement/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index 362c42ab59a..fc611fe309d 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -11,7 +11,7 @@ val DEPENDENCY_BOMS = listOf( "com.fasterxml.jackson:jackson-bom:2.18.2", "com.google.guava:guava-bom:33.3.1-jre", "com.google.protobuf:protobuf-bom:4.29.1", - "com.linecorp.armeria:armeria-bom:1.31.2", + "com.linecorp.armeria:armeria-bom:1.31.3", "com.squareup.okhttp3:okhttp-bom:4.12.0", "com.squareup.okio:okio-bom:3.9.1", // applies to transitive dependencies of okhttp "io.grpc:grpc-bom:1.69.0", From b32f64420c84bd2af7e60261baad01a198162639 Mon Sep 17 00:00:00 2001 From: jack-berg <34418638+jack-berg@users.noreply.github.com> Date: Thu, 12 Dec 2024 11:03:11 -0600 Subject: [PATCH 712/901] Remove unused dependencies, cleanup code after stability (#6948) --- exporters/otlp/common/build.gradle.kts | 2 +- .../io/opentelemetry/sdk/logs/ValueBodyTest.java | 16 +++++++--------- .../sdk/metrics/SdkDoubleHistogram.java | 3 +-- .../sdk/metrics/SdkLongHistogram.java | 3 +-- .../opentelemetry/sdk/metrics/IdentityTest.java | 9 ++++++--- sdk/testing/build.gradle.kts | 3 ++- 6 files changed, 18 insertions(+), 18 deletions(-) diff --git a/exporters/otlp/common/build.gradle.kts b/exporters/otlp/common/build.gradle.kts index 99b054f3d5e..0e74e8829a7 100644 --- a/exporters/otlp/common/build.gradle.kts +++ b/exporters/otlp/common/build.gradle.kts @@ -16,7 +16,6 @@ dependencies { protoSource("io.opentelemetry.proto:opentelemetry-proto:${versions["io.opentelemetry.proto"]}") api(project(":exporters:common")) - implementation(project(":api:incubator")) compileOnly(project(":sdk:metrics")) compileOnly(project(":sdk:trace")) @@ -32,6 +31,7 @@ dependencies { testImplementation("com.google.guava:guava") testImplementation("io.opentelemetry.proto:opentelemetry-proto") + jmhImplementation(project(":api:incubator")) jmhImplementation(project(":sdk:testing")) jmhImplementation("com.fasterxml.jackson.core:jackson-core") jmhImplementation("io.opentelemetry.proto:opentelemetry-proto") diff --git a/sdk/logs/src/test/java/io/opentelemetry/sdk/logs/ValueBodyTest.java b/sdk/logs/src/test/java/io/opentelemetry/sdk/logs/ValueBodyTest.java index cd5820bb974..954ba6bdb63 100644 --- a/sdk/logs/src/test/java/io/opentelemetry/sdk/logs/ValueBodyTest.java +++ b/sdk/logs/src/test/java/io/opentelemetry/sdk/logs/ValueBodyTest.java @@ -10,7 +10,6 @@ import io.opentelemetry.api.common.KeyValue; import io.opentelemetry.api.common.Value; import io.opentelemetry.api.common.ValueType; -import io.opentelemetry.api.incubator.logs.ExtendedLogRecordBuilder; import io.opentelemetry.api.logs.Logger; import io.opentelemetry.sdk.logs.export.SimpleLogRecordProcessor; import io.opentelemetry.sdk.testing.exporter.InMemoryLogRecordExporter; @@ -32,7 +31,7 @@ void valueBody() { Logger logger = provider.get(ValueBodyTest.class.getName()); // Value can be a primitive type, like a string, long, double, boolean - extendedLogRecordBuilder(logger).setBody(Value.of(1)).emit(); + logger.logRecordBuilder().setBody(Value.of(1)).emit(); assertThat(exporter.getFinishedLogRecordItems()) .hasSize(1) .satisfiesExactly( @@ -48,7 +47,8 @@ void valueBody() { exporter.reset(); // ...or a byte array of raw data - extendedLogRecordBuilder(logger) + logger + .logRecordBuilder() .setBody(Value.of("hello world".getBytes(StandardCharsets.UTF_8))) .emit(); assertThat(exporter.getFinishedLogRecordItems()) @@ -68,7 +68,8 @@ void valueBody() { exporter.reset(); // But most commonly it will be used to represent complex structured like a map - extendedLogRecordBuilder(logger) + logger + .logRecordBuilder() .setBody( // The protocol data structure uses a repeated KeyValue to represent a map: // https://github.com/open-telemetry/opentelemetry-proto/blob/ac3242b03157295e4ee9e616af53b81517b06559/opentelemetry/proto/common/v1/common.proto#L59 @@ -145,7 +146,8 @@ void valueBody() { exporter.reset(); // ..or an array (optionally with heterogeneous types) - extendedLogRecordBuilder(logger) + logger + .logRecordBuilder() .setBody(Value.of(Value.of("entry1"), Value.of("entry2"), Value.of(3))) .emit(); assertThat(exporter.getFinishedLogRecordItems()) @@ -164,8 +166,4 @@ void valueBody() { }); exporter.reset(); } - - ExtendedLogRecordBuilder extendedLogRecordBuilder(Logger logger) { - return (ExtendedLogRecordBuilder) logger.logRecordBuilder(); - } } diff --git a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkDoubleHistogram.java b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkDoubleHistogram.java index 5aa8f49de31..d155a7d7975 100644 --- a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkDoubleHistogram.java +++ b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkDoubleHistogram.java @@ -96,8 +96,7 @@ public LongHistogramBuilder ofLongs() { } @Override - public ExtendedDoubleHistogramBuilder setExplicitBucketBoundariesAdvice( - List bucketBoundaries) { + public DoubleHistogramBuilder setExplicitBucketBoundariesAdvice(List bucketBoundaries) { try { Objects.requireNonNull(bucketBoundaries, "bucketBoundaries must not be null"); ExplicitBucketHistogramUtils.validateBucketBoundaries(bucketBoundaries); diff --git a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkLongHistogram.java b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkLongHistogram.java index 0822b1eff57..5e96bfb2e61 100644 --- a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkLongHistogram.java +++ b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkLongHistogram.java @@ -99,8 +99,7 @@ public SdkLongHistogram build() { } @Override - public ExtendedLongHistogramBuilder setExplicitBucketBoundariesAdvice( - List bucketBoundaries) { + public LongHistogramBuilder setExplicitBucketBoundariesAdvice(List bucketBoundaries) { List boundaries; try { Objects.requireNonNull(bucketBoundaries, "bucketBoundaries must not be null"); diff --git a/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/IdentityTest.java b/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/IdentityTest.java index 981d84dcd82..195c8730e45 100644 --- a/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/IdentityTest.java +++ b/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/IdentityTest.java @@ -8,7 +8,6 @@ import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.assertThat; import io.github.netmikey.logunit.api.LogCapturer; -import io.opentelemetry.api.incubator.metrics.ExtendedDoubleHistogramBuilder; import io.opentelemetry.internal.testing.slf4j.SuppressLogger; import io.opentelemetry.sdk.common.InstrumentationScopeInfo; import io.opentelemetry.sdk.metrics.internal.state.MetricStorageRegistry; @@ -222,13 +221,17 @@ void sameMeterSameInstrumentNameDifferentNonIdentifyingFieldsNoViews() { // Register histogram1, with and without advice. First registration without advice wins. meterProvider.get("meter1").histogramBuilder("histogram1").build().record(8); - ((ExtendedDoubleHistogramBuilder) meterProvider.get("meter1").histogramBuilder("histogram1")) + meterProvider + .get("meter1") + .histogramBuilder("histogram1") .setExplicitBucketBoundariesAdvice(Arrays.asList(10.0, 20.0, 30.0)) .build() .record(8); // Register histogram2, with and without advice. First registration with advice wins. - ((ExtendedDoubleHistogramBuilder) meterProvider.get("meter1").histogramBuilder("histogram2")) + meterProvider + .get("meter1") + .histogramBuilder("histogram2") .setExplicitBucketBoundariesAdvice(Arrays.asList(10.0, 20.0, 30.0)) .build() .record(8); diff --git a/sdk/testing/build.gradle.kts b/sdk/testing/build.gradle.kts index 4d3f3aa4ec8..e6a095179d5 100644 --- a/sdk/testing/build.gradle.kts +++ b/sdk/testing/build.gradle.kts @@ -8,7 +8,6 @@ otelJava.moduleName.set("io.opentelemetry.sdk.testing") dependencies { api(project(":api:all")) - api(project(":api:incubator")) api(project(":sdk:all")) compileOnly("org.assertj:assertj-core") @@ -17,6 +16,8 @@ dependencies { annotationProcessor("com.google.auto.value:auto-value") + testImplementation(project(":api:incubator")) + testImplementation("junit:junit") testImplementation("org.junit.vintage:junit-vintage-engine") } From 09b8db6563986ddba5883c048328a8e53c456065 Mon Sep 17 00:00:00 2001 From: Steve Rao Date: Sat, 14 Dec 2024 12:27:12 +0800 Subject: [PATCH 713/901] Update VERSIONING.md (#6942) Co-authored-by: Trask Stalnaker --- VERSIONING.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSIONING.md b/VERSIONING.md index ad599963e02..d7566cacff4 100644 --- a/VERSIONING.md +++ b/VERSIONING.md @@ -18,7 +18,7 @@ changes are: reordering parameters, adding a method to an interface or abstract class without adding a default implementation. -- ABI changes that could require code using the artifact to be recompiled, but not changed, e.g., +- [ABI](https://wikipedia.org/wiki/Application_binary_interface) changes that could require code using the artifact to be recompiled, but not changed, e.g., changing the return type of a method from `void` to non-`void`, changing a `class` to an `interface`. The [JLS](https://docs.oracle.com/javase/specs/jls/se7/html/jls-13.html) has more information on what constitutes compatible changes. From e80506a92f4f4cdd77e572f1939010724113a0ed Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 14 Dec 2024 09:07:21 -0800 Subject: [PATCH 714/901] chore(deps): update plugin com.gradle.develocity to v3.19 (#6947) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- settings.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/settings.gradle.kts b/settings.gradle.kts index 4075a604a57..ae259612d85 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -1,7 +1,7 @@ pluginManagement { plugins { id("com.gradleup.shadow") version "8.3.5" - id("com.gradle.develocity") version "3.18.2" + id("com.gradle.develocity") version "3.19" id("de.undercouch.download") version "5.6.0" id("org.jsonschema2pojo") version "1.2.2" id("io.github.gradle-nexus.publish-plugin") version "2.0.0" From 1fcbed8d81cfd05f19fe7f4f811dcef65ecd1730 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 14 Dec 2024 17:02:22 -0800 Subject: [PATCH 715/901] fix(deps): update dependency checkstyle to v10.21.0 (#6951) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- buildSrc/src/main/kotlin/otel.java-conventions.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/buildSrc/src/main/kotlin/otel.java-conventions.gradle.kts b/buildSrc/src/main/kotlin/otel.java-conventions.gradle.kts index 26a845f5c8a..71a119f9b3b 100644 --- a/buildSrc/src/main/kotlin/otel.java-conventions.gradle.kts +++ b/buildSrc/src/main/kotlin/otel.java-conventions.gradle.kts @@ -42,7 +42,7 @@ java { checkstyle { configDirectory.set(file("$rootDir/buildscripts/")) - toolVersion = "10.20.2" + toolVersion = "10.21.0" isIgnoreFailures = false configProperties["rootDir"] = rootDir } From c80845dfe4a494c4cdb6a29edf99a4754255f468 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 17 Dec 2024 07:51:28 -0800 Subject: [PATCH 716/901] fix(deps): update dependency com.uber.nullaway:nullaway to v0.12.2 (#6956) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- dependencyManagement/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index fc611fe309d..d0fcd80927a 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -65,7 +65,7 @@ val DEPENDENCIES = listOf( "com.google.guava:guava-beta-checker:1.0", "com.sun.net.httpserver:http:20070405", "com.tngtech.archunit:archunit-junit5:1.3.0", - "com.uber.nullaway:nullaway:0.12.1", + "com.uber.nullaway:nullaway:0.12.2", "edu.berkeley.cs.jqf:jqf-fuzz:1.7", // jqf-fuzz version 1.8+ requires Java 11+ "eu.rekawek.toxiproxy:toxiproxy-java:2.1.7", "io.github.netmikey.logunit:logunit-jul:2.0.0", From 77b1f64252bc926bb03b8e5c4d8d92f5c13f5576 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 18 Dec 2024 07:40:30 -0800 Subject: [PATCH 717/901] fix(deps): update dependency org.junit:junit-bom to v5.11.4 (#6961) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- dependencyManagement/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index d0fcd80927a..53ded19bb88 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -19,7 +19,7 @@ val DEPENDENCY_BOMS = listOf( "io.zipkin.brave:brave-bom:6.0.3", "io.zipkin.reporter2:zipkin-reporter-bom:3.4.3", "org.assertj:assertj-bom:3.26.3", - "org.junit:junit-bom:5.11.3", + "org.junit:junit-bom:5.11.4", "org.testcontainers:testcontainers-bom:1.20.4", "org.snakeyaml:snakeyaml-engine:2.8" ) From e454311bd575f1309648ad0d8512195e15d94f44 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 18 Dec 2024 19:49:55 -0800 Subject: [PATCH 718/901] fix(deps): update dependency com.google.api.grpc:proto-google-common-protos to v2.50.0 (#6949) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- dependencyManagement/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index 53ded19bb88..f9e892dc6c3 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -60,7 +60,7 @@ val DEPENDENCIES = listOf( "io.prometheus:simpleclient_httpserver:${prometheusClientVersion}", "javax.annotation:javax.annotation-api:1.3.2", "com.github.stefanbirkner:system-rules:1.19.0", - "com.google.api.grpc:proto-google-common-protos:2.49.0", + "com.google.api.grpc:proto-google-common-protos:2.50.0", "com.google.code.findbugs:jsr305:3.0.2", "com.google.guava:guava-beta-checker:1.0", "com.sun.net.httpserver:http:20070405", From a7a2c061459a8a57fe560ebb0410948f545f8293 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 19 Dec 2024 07:42:00 -0800 Subject: [PATCH 719/901] fix(deps): update dependency com.google.guava:guava to v33.4.0-jre (#6964) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- buildSrc/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts index 3d90314dceb..fb8352ed2f3 100644 --- a/buildSrc/build.gradle.kts +++ b/buildSrc/build.gradle.kts @@ -55,7 +55,7 @@ dependencies { // When updating, update above in plugins too implementation("com.diffplug.spotless:spotless-plugin-gradle:6.25.0") // Needed for japicmp but not automatically brought in for some reason. - implementation("com.google.guava:guava:33.3.1-jre") + implementation("com.google.guava:guava:33.4.0-jre") implementation("com.squareup:javapoet:1.13.0") implementation("com.squareup.wire:wire-compiler") implementation("com.squareup.wire:wire-gradle-plugin") From d95c4ea4840571f19a6a9fdec50ab2eb813eea41 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 19 Dec 2024 08:43:11 -0800 Subject: [PATCH 720/901] fix(deps): update dependency com.google.guava:guava-bom to v33.4.0-jre (#6965) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- dependencyManagement/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index f9e892dc6c3..36a31b6f4bb 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -9,7 +9,7 @@ rootProject.extra["versions"] = dependencyVersions val DEPENDENCY_BOMS = listOf( "com.fasterxml.jackson:jackson-bom:2.18.2", - "com.google.guava:guava-bom:33.3.1-jre", + "com.google.guava:guava-bom:33.4.0-jre", "com.google.protobuf:protobuf-bom:4.29.1", "com.linecorp.armeria:armeria-bom:1.31.3", "com.squareup.okhttp3:okhttp-bom:4.12.0", From 0e6af66d10247e9952aa2a76967f49ef8e76627d Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 19 Dec 2024 11:29:01 -0800 Subject: [PATCH 721/901] fix(deps): update dependency io.netty:netty-bom to v4.1.116.final (#6966) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- dependencyManagement/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index 36a31b6f4bb..73776aa89c3 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -15,7 +15,7 @@ val DEPENDENCY_BOMS = listOf( "com.squareup.okhttp3:okhttp-bom:4.12.0", "com.squareup.okio:okio-bom:3.9.1", // applies to transitive dependencies of okhttp "io.grpc:grpc-bom:1.69.0", - "io.netty:netty-bom:4.1.115.Final", + "io.netty:netty-bom:4.1.116.Final", "io.zipkin.brave:brave-bom:6.0.3", "io.zipkin.reporter2:zipkin-reporter-bom:3.4.3", "org.assertj:assertj-bom:3.26.3", From 21529fa3397334cca6acdd85be093f2211d3cde5 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 19 Dec 2024 15:56:38 -0600 Subject: [PATCH 722/901] fix(deps): update prometheusserverversion to v1.3.5 (#6957) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Co-authored-by: Jack Berg --- dependencyManagement/build.gradle.kts | 2 +- .../exporter/prometheus/PrometheusHttpServerTest.java | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index 73776aa89c3..f3818aab7aa 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -32,7 +32,7 @@ val mockitoVersion = "4.11.0" val slf4jVersion = "2.0.16" val opencensusVersion = "0.31.1" val prometheusClientVersion = "0.16.0" -val prometheusServerVersion = "1.3.4" +val prometheusServerVersion = "1.3.5" val DEPENDENCIES = listOf( "com.google.auto.value:auto-value:${autoValueVersion}", diff --git a/exporters/prometheus/src/test/java/io/opentelemetry/exporter/prometheus/PrometheusHttpServerTest.java b/exporters/prometheus/src/test/java/io/opentelemetry/exporter/prometheus/PrometheusHttpServerTest.java index 7115ff8a2b3..4f69f2069be 100644 --- a/exporters/prometheus/src/test/java/io/opentelemetry/exporter/prometheus/PrometheusHttpServerTest.java +++ b/exporters/prometheus/src/test/java/io/opentelemetry/exporter/prometheus/PrometheusHttpServerTest.java @@ -42,9 +42,9 @@ import io.opentelemetry.sdk.resources.Resource; import io.prometheus.metrics.exporter.httpserver.HTTPServer; import io.prometheus.metrics.exporter.httpserver.MetricsHandler; -import io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics; +import io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics; import io.prometheus.metrics.model.registry.PrometheusRegistry; -import io.prometheus.metrics.shaded.com_google_protobuf_4_28_3.TextFormat; +import io.prometheus.metrics.shaded.com_google_protobuf_4_29_1.TextFormat; import java.io.ByteArrayInputStream; import java.io.IOException; import java.net.ServerSocket; From 40b74b05e1c4f839caaaa95e9a5d9a33b042edee Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 19 Dec 2024 15:56:53 -0600 Subject: [PATCH 723/901] fix(deps): update dependency com.google.protobuf:protobuf-bom to v4.29.2 (#6968) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- dependencyManagement/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index f3818aab7aa..08b8d69fa86 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -10,7 +10,7 @@ rootProject.extra["versions"] = dependencyVersions val DEPENDENCY_BOMS = listOf( "com.fasterxml.jackson:jackson-bom:2.18.2", "com.google.guava:guava-bom:33.4.0-jre", - "com.google.protobuf:protobuf-bom:4.29.1", + "com.google.protobuf:protobuf-bom:4.29.2", "com.linecorp.armeria:armeria-bom:1.31.3", "com.squareup.okhttp3:okhttp-bom:4.12.0", "com.squareup.okio:okio-bom:3.9.1", // applies to transitive dependencies of okhttp From c1b9ec789cabe10f18acbbcc8b395d6784e9e1e8 Mon Sep 17 00:00:00 2001 From: jason plumb <75337021+breedx-splk@users.noreply.github.com> Date: Thu, 19 Dec 2024 13:57:17 -0800 Subject: [PATCH 724/901] Explicitly allow null into CompletableResultCode.failExceptionally() (#6963) --- .../opentelemetry/sdk/common/CompletableResultCode.java | 6 ++++-- .../sdk/common/CompletableResultCodeTest.java | 9 +++++++++ 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/sdk/common/src/main/java/io/opentelemetry/sdk/common/CompletableResultCode.java b/sdk/common/src/main/java/io/opentelemetry/sdk/common/CompletableResultCode.java index 4a52effcd90..600ec73a48e 100644 --- a/sdk/common/src/main/java/io/opentelemetry/sdk/common/CompletableResultCode.java +++ b/sdk/common/src/main/java/io/opentelemetry/sdk/common/CompletableResultCode.java @@ -123,9 +123,10 @@ public CompletableResultCode fail() { * Completes this {@link CompletableResultCode} unsuccessfully if it is not already completed, * setting the {@link #getFailureThrowable() failure throwable} to {@code throwable}. * + * @param throwable the {@code Throwable} that caused the failure, or {@code null} * @since 1.41.0 */ - public CompletableResultCode failExceptionally(Throwable throwable) { + public CompletableResultCode failExceptionally(@Nullable Throwable throwable) { return failInternal(throwable); } @@ -160,7 +161,8 @@ public boolean isSuccess() { * via the {@link #whenComplete(Runnable)} method. * * @return the throwable if failed exceptionally, or null if: {@link #fail() failed without - * exception}, {@link #succeed() succeeded}, or not complete.g + * exception}, {@link #succeed() succeeded}, {@link #failExceptionally(Throwable)} with a null + * {@code throwable}, or not complete. * @since 1.41.0 */ @Nullable diff --git a/sdk/common/src/test/java/io/opentelemetry/sdk/common/CompletableResultCodeTest.java b/sdk/common/src/test/java/io/opentelemetry/sdk/common/CompletableResultCodeTest.java index 3964fdd7f73..b83e3e03ec7 100644 --- a/sdk/common/src/test/java/io/opentelemetry/sdk/common/CompletableResultCodeTest.java +++ b/sdk/common/src/test/java/io/opentelemetry/sdk/common/CompletableResultCodeTest.java @@ -79,6 +79,15 @@ void fail() throws InterruptedException { assertThat(resultCode.isSuccess()).isFalse(); } + @Test + void failExceptionallyWithNull() { + CompletableResultCode resultCode = new CompletableResultCode(); + CompletableResultCode result = resultCode.failExceptionally(null); + assertThat(result.isDone()).isTrue(); + assertThat(result.isSuccess()).isFalse(); + assertThat(result.getFailureThrowable()).isNull(); + } + @Test void whenDoublyCompleteSuccessfully() throws InterruptedException { CompletableResultCode resultCode = new CompletableResultCode(); From b934a0a3d49371802b4fdc2db119fb8ce6d9aec3 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 19 Dec 2024 15:57:53 -0600 Subject: [PATCH 725/901] fix(deps): update dependency io.opentelemetry.semconv:opentelemetry-semconv-incubating to v1.29.0-alpha (#6971) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- dependencyManagement/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index 08b8d69fa86..6033d20b1bd 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -71,7 +71,7 @@ val DEPENDENCIES = listOf( "io.github.netmikey.logunit:logunit-jul:2.0.0", "io.jaegertracing:jaeger-client:1.8.1", "io.opentelemetry.contrib:opentelemetry-aws-xray-propagator:1.39.0-alpha", - "io.opentelemetry.semconv:opentelemetry-semconv-incubating:1.28.0-alpha", + "io.opentelemetry.semconv:opentelemetry-semconv-incubating:1.29.0-alpha", "io.opentelemetry.proto:opentelemetry-proto:1.4.0-alpha", "io.opentracing:opentracing-api:0.33.0", "io.opentracing:opentracing-noop:0.33.0", From a084b3ae0ad9b0379611c8dec3ba0f6368134b00 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 19 Dec 2024 15:58:42 -0600 Subject: [PATCH 726/901] chore(deps): update gradle/actions action to v4.2.2 (#6967) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/gradle-wrapper-validation.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/gradle-wrapper-validation.yml b/.github/workflows/gradle-wrapper-validation.yml index 9959faf2be1..f33287100b4 100644 --- a/.github/workflows/gradle-wrapper-validation.yml +++ b/.github/workflows/gradle-wrapper-validation.yml @@ -13,4 +13,4 @@ jobs: steps: - uses: actions/checkout@v4 - - uses: gradle/actions/wrapper-validation@v4.2.1 + - uses: gradle/actions/wrapper-validation@v4.2.2 From d294a42afb64edcd06d5e2bbee0cd53a7dc606d8 Mon Sep 17 00:00:00 2001 From: jason plumb <75337021+breedx-splk@users.noreply.github.com> Date: Thu, 19 Dec 2024 14:01:13 -0800 Subject: [PATCH 727/901] Add getters/accessors for readable fields in ReadWriteLogRecord. (#6924) --- .../opentelemetry-sdk-logs.txt | 16 +++++- .../sdk/logs/ReadWriteLogRecord.java | 56 ++++++++++++++++++- .../sdk/logs/SdkReadWriteLogRecord.java | 53 ++++++++++++++++++ .../sdk/logs/ReadWriteLogRecordTest.java | 10 ++-- 4 files changed, 127 insertions(+), 8 deletions(-) diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-logs.txt b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-logs.txt index 3cee338a2c6..dca61614aaf 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-logs.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-logs.txt @@ -1,2 +1,16 @@ Comparing source compatibility of opentelemetry-sdk-logs-1.46.0-SNAPSHOT.jar against opentelemetry-sdk-logs-1.45.0.jar -No changes. \ No newline at end of file +*** MODIFIED INTERFACE: PUBLIC ABSTRACT io.opentelemetry.sdk.logs.ReadWriteLogRecord (not serializable) + === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 + +++ NEW METHOD: PUBLIC(+) java.lang.Object getAttribute(io.opentelemetry.api.common.AttributeKey) + +++ NEW ANNOTATION: javax.annotation.Nullable + GENERIC TEMPLATES: +++ T:java.lang.Object + +++ NEW METHOD: PUBLIC(+) io.opentelemetry.api.common.Attributes getAttributes() + +++ NEW METHOD: PUBLIC(+) io.opentelemetry.api.common.Value getBodyValue() + +++ NEW ANNOTATION: javax.annotation.Nullable + +++ NEW METHOD: PUBLIC(+) io.opentelemetry.sdk.common.InstrumentationScopeInfo getInstrumentationScopeInfo() + +++ NEW METHOD: PUBLIC(+) long getObservedTimestampEpochNanos() + +++ NEW METHOD: PUBLIC(+) io.opentelemetry.api.logs.Severity getSeverity() + +++ NEW METHOD: PUBLIC(+) java.lang.String getSeverityText() + +++ NEW ANNOTATION: javax.annotation.Nullable + +++ NEW METHOD: PUBLIC(+) io.opentelemetry.api.trace.SpanContext getSpanContext() + +++ NEW METHOD: PUBLIC(+) long getTimestampEpochNanos() diff --git a/sdk/logs/src/main/java/io/opentelemetry/sdk/logs/ReadWriteLogRecord.java b/sdk/logs/src/main/java/io/opentelemetry/sdk/logs/ReadWriteLogRecord.java index d99267d9acd..6ad913c1029 100644 --- a/sdk/logs/src/main/java/io/opentelemetry/sdk/logs/ReadWriteLogRecord.java +++ b/sdk/logs/src/main/java/io/opentelemetry/sdk/logs/ReadWriteLogRecord.java @@ -7,7 +7,12 @@ import io.opentelemetry.api.common.AttributeKey; import io.opentelemetry.api.common.Attributes; +import io.opentelemetry.api.common.Value; +import io.opentelemetry.api.logs.Severity; +import io.opentelemetry.api.trace.SpanContext; +import io.opentelemetry.sdk.common.InstrumentationScopeInfo; import io.opentelemetry.sdk.logs.data.LogRecordData; +import javax.annotation.Nullable; /** * A log record that can be read from and written to. @@ -47,7 +52,54 @@ default ReadWriteLogRecord setAllAttributes(Attributes attributes) { /** Return an immutable {@link LogRecordData} instance representing this log record. */ LogRecordData toLogRecordData(); - // TODO: add additional log record accessors. Currently, all fields can be accessed indirectly via - // #toLogRecordData() at the expense of additional allocations. + /** + * Returns the value of a given attribute if it exists. This is the equivalent of calling + * getAttributes().get(key) + */ + @Nullable + default T getAttribute(AttributeKey key) { + return toLogRecordData().getAttributes().get(key); + } + + /** Returns the instrumentation scope that generated this log. */ + default InstrumentationScopeInfo getInstrumentationScopeInfo() { + return toLogRecordData().getInstrumentationScopeInfo(); + } + + /** Returns the timestamp at which the log record occurred, in epoch nanos. */ + default long getTimestampEpochNanos() { + return toLogRecordData().getTimestampEpochNanos(); + } + + /** Returns the timestamp at which the log record was observed, in epoch nanos. */ + default long getObservedTimestampEpochNanos() { + return toLogRecordData().getTimestampEpochNanos(); + } + /** Return the span context for this log, or {@link SpanContext#getInvalid()} if unset. */ + default SpanContext getSpanContext() { + return toLogRecordData().getSpanContext(); + } + + /** Returns the severity for this log, or {@link Severity#UNDEFINED_SEVERITY_NUMBER} if unset. */ + default Severity getSeverity() { + return toLogRecordData().getSeverity(); + } + + /** Returns the severity text for this log, or null if unset. */ + @Nullable + default String getSeverityText() { + return toLogRecordData().getSeverityText(); + } + + /** Returns the {@link Value} representation of the log body, of null if unset. */ + @Nullable + default Value getBodyValue() { + return toLogRecordData().getBodyValue(); + } + + /** Returns the attributes for this log, or {@link Attributes#empty()} if unset. */ + default Attributes getAttributes() { + return toLogRecordData().getAttributes(); + } } diff --git a/sdk/logs/src/main/java/io/opentelemetry/sdk/logs/SdkReadWriteLogRecord.java b/sdk/logs/src/main/java/io/opentelemetry/sdk/logs/SdkReadWriteLogRecord.java index 881f1d124ee..e6c68ce6ec4 100644 --- a/sdk/logs/src/main/java/io/opentelemetry/sdk/logs/SdkReadWriteLogRecord.java +++ b/sdk/logs/src/main/java/io/opentelemetry/sdk/logs/SdkReadWriteLogRecord.java @@ -125,4 +125,57 @@ public LogRecordData toLogRecordData() { attributes == null ? 0 : attributes.getTotalAddedValues()); } } + + @Override + public InstrumentationScopeInfo getInstrumentationScopeInfo() { + return instrumentationScopeInfo; + } + + @Override + public long getTimestampEpochNanos() { + return timestampEpochNanos; + } + + @Override + public long getObservedTimestampEpochNanos() { + return observedTimestampEpochNanos; + } + + @Override + public SpanContext getSpanContext() { + return spanContext; + } + + @Override + public Severity getSeverity() { + return severity; + } + + @Nullable + @Override + public String getSeverityText() { + return severityText; + } + + @Nullable + @Override + public Value getBodyValue() { + return body; + } + + @Override + public Attributes getAttributes() { + return getImmutableAttributes(); + } + + @Nullable + @Override + public T getAttribute(AttributeKey key) { + synchronized (lock) { + if (attributes == null || attributes.isEmpty()) { + return null; + } + return attributes.get(key); + } + } } diff --git a/sdk/logs/src/test/java/io/opentelemetry/sdk/logs/ReadWriteLogRecordTest.java b/sdk/logs/src/test/java/io/opentelemetry/sdk/logs/ReadWriteLogRecordTest.java index e671372c515..7a444817d40 100644 --- a/sdk/logs/src/test/java/io/opentelemetry/sdk/logs/ReadWriteLogRecordTest.java +++ b/sdk/logs/src/test/java/io/opentelemetry/sdk/logs/ReadWriteLogRecordTest.java @@ -26,7 +26,7 @@ void addAllAttributes() { logRecord.setAllAttributes(newAttributes); - Attributes result = logRecord.toLogRecordData().getAttributes(); + Attributes result = logRecord.getAttributes(); assertThat(result.get(stringKey("foo"))).isEqualTo("bar"); assertThat(result.get(stringKey("bar"))).isEqualTo("buzz"); assertThat(result.get(stringKey("untouched"))).isEqualTo("yes"); @@ -35,17 +35,17 @@ void addAllAttributes() { @Test void addAllHandlesNull() { SdkReadWriteLogRecord logRecord = buildLogRecord(); - Attributes originalAttributes = logRecord.toLogRecordData().getAttributes(); + Attributes originalAttributes = logRecord.getAttributes(); ReadWriteLogRecord result = logRecord.setAllAttributes(null); - assertThat(result.toLogRecordData().getAttributes()).isEqualTo(originalAttributes); + assertThat(result.getAttributes()).isEqualTo(originalAttributes); } @Test void allHandlesEmpty() { SdkReadWriteLogRecord logRecord = buildLogRecord(); - Attributes originalAttributes = logRecord.toLogRecordData().getAttributes(); + Attributes originalAttributes = logRecord.getAttributes(); ReadWriteLogRecord result = logRecord.setAllAttributes(Attributes.empty()); - assertThat(result.toLogRecordData().getAttributes()).isEqualTo(originalAttributes); + assertThat(result.getAttributes()).isEqualTo(originalAttributes); } SdkReadWriteLogRecord buildLogRecord() { From a3d807b70f4523e7ed498aeba983335716a214ca Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 19 Dec 2024 16:01:46 -0600 Subject: [PATCH 728/901] fix(deps): update dependency org.assertj:assertj-bom to v3.27.0 (#6974) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- dependencyManagement/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index 6033d20b1bd..5d6fdfd91a3 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -18,7 +18,7 @@ val DEPENDENCY_BOMS = listOf( "io.netty:netty-bom:4.1.116.Final", "io.zipkin.brave:brave-bom:6.0.3", "io.zipkin.reporter2:zipkin-reporter-bom:3.4.3", - "org.assertj:assertj-bom:3.26.3", + "org.assertj:assertj-bom:3.27.0", "org.junit:junit-bom:5.11.4", "org.testcontainers:testcontainers-bom:1.20.4", "org.snakeyaml:snakeyaml-engine:2.8" From ee05c5cb0881dc1bd409bfe04bbbad72c5288a36 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 21 Dec 2024 10:44:17 -0800 Subject: [PATCH 729/901] fix(deps): update dependency com.android.tools:desugar_jdk_libs to v2.1.4 (#6976) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- dependencyManagement/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index 5d6fdfd91a3..be50c8e5b62 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -84,7 +84,7 @@ val DEPENDENCIES = listOf( "org.junit-pioneer:junit-pioneer:1.9.1", "org.mock-server:mockserver-netty:5.15.0:shaded", "org.skyscreamer:jsonassert:1.5.3", - "com.android.tools:desugar_jdk_libs:2.1.3", + "com.android.tools:desugar_jdk_libs:2.1.4", ) javaPlatform { From 717d8b00320d4e0dadc15d96f9c48559bd2b2e20 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 21 Dec 2024 11:51:53 -0800 Subject: [PATCH 730/901] chore(deps): update dependency gradle to v8.12 (#6977) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- gradle/wrapper/gradle-wrapper.properties | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index eb1a55be0e1..e1b837a19c2 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,7 +1,7 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionSha256Sum=f397b287023acdba1e9f6fc5ea72d22dd63669d59ed4a289a29b1a76eee151c6 -distributionUrl=https\://services.gradle.org/distributions/gradle-8.11.1-bin.zip +distributionSha256Sum=7a00d51fb93147819aab76024feece20b6b84e420694101f276be952e08bef03 +distributionUrl=https\://services.gradle.org/distributions/gradle-8.12-bin.zip networkTimeout=10000 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME From abdbf07dfda5b43cab9bcf9dd9e8291f329508a3 Mon Sep 17 00:00:00 2001 From: Trask Stalnaker Date: Mon, 23 Dec 2024 16:30:15 -0800 Subject: [PATCH 731/901] Switch link checker to lychee (#6972) --- .../config/markdown-link-check-config.json | 7 ------- .../scripts/markdown-link-check-with-retry.sh | 17 ---------------- .../reusable-markdown-link-check.yml | 20 +++++++++---------- CHANGELOG.md | 18 ++++++++--------- 4 files changed, 19 insertions(+), 43 deletions(-) delete mode 100644 .github/config/markdown-link-check-config.json delete mode 100755 .github/scripts/markdown-link-check-with-retry.sh diff --git a/.github/config/markdown-link-check-config.json b/.github/config/markdown-link-check-config.json deleted file mode 100644 index a458029d5d9..00000000000 --- a/.github/config/markdown-link-check-config.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "retryOn429": true, - "aliveStatusCodes": [ - 200, - 403 - ] -} diff --git a/.github/scripts/markdown-link-check-with-retry.sh b/.github/scripts/markdown-link-check-with-retry.sh deleted file mode 100755 index 9a81e8df95b..00000000000 --- a/.github/scripts/markdown-link-check-with-retry.sh +++ /dev/null @@ -1,17 +0,0 @@ -#!/bin/bash -e - -# this script helps to reduce sporadic link check failures by retrying at a file-by-file level - -retry_count=3 - -for file in "$@"; do - for i in $(seq 1 $retry_count); do - if markdown-link-check --config "$(dirname "$0")/../config/markdown-link-check-config.json" \ - "$file"; then - break - elif [[ $i -eq $retry_count ]]; then - exit 1 - fi - sleep 5 - done -done diff --git a/.github/workflows/reusable-markdown-link-check.yml b/.github/workflows/reusable-markdown-link-check.yml index 4e7ad15c423..93e42a98ad1 100644 --- a/.github/workflows/reusable-markdown-link-check.yml +++ b/.github/workflows/reusable-markdown-link-check.yml @@ -9,13 +9,13 @@ jobs: steps: - uses: actions/checkout@v4 - - name: Install markdown-link-check - # TODO(jack-berg): use latest when config file reading bug is fixed: https://github.com/tcort/markdown-link-check/issues/246 - run: npm install -g markdown-link-check@3.10.3 - - - name: Run markdown-link-check - run: | - find . -type f \ - -name '*.md' \ - -not -path './CHANGELOG.md' \ - | xargs .github/scripts/markdown-link-check-with-retry.sh + - uses: lycheeverse/lychee-action@v2 + with: + # remove version after next release of lychee-action + lycheeVersion: latest + # excluding links to pull requests and issues is done for performance + args: > + --include-fragments + --exclude "^https://github.com/open-telemetry/opentelemetry-java/(issue|pull)/\\d+$" + --max-retries 6 + . diff --git a/CHANGELOG.md b/CHANGELOG.md index b4fddc06a87..561033dfa81 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -521,7 +521,7 @@ have stopped being published. Jaeger has [native support for OTLP](https://opentelemetry.io/blog/2022/jaeger-native-otlp/), and users should export to jaeger -using [OTLP](https://opentelemetry.io/docs/instrumentation/java/exporters/#otlp-dependencies) +using OTLP instead. ### API @@ -605,7 +605,7 @@ instead. and `opentelemetry-exporter-jaeger-thift`. Jaeger has [native support for OTLP](https://opentelemetry.io/blog/2022/jaeger-native-otlp/), and users should export to jaeger -using [OTLP](https://opentelemetry.io/docs/instrumentation/java/exporters/#otlp-dependencies) +using OTLP instead. ### API @@ -1042,7 +1042,7 @@ The log bridge API / SDK are now stable! Some important notes: of `otel.logs.exporter` from `none` to `otlp`. NOTE: reminder that -the [Logs Bridge API](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/logs/bridge-api.md) +the [Logs Bridge API](https://github.com/open-telemetry/opentelemetry-specification/blob/v1.21.0/specification/logs/bridge-api.md) is _not_ meant for end users. Log appenders use the API to bridge logs from existing log frameworks (e.g. JUL, Log4j, SLf4J, Logback) into OpenTelemetry. Users configure the Log SDK to dictate how logs are processed and exported. @@ -1110,7 +1110,7 @@ merged into `opentelemetry-exporter-otlp`, `opentelemetry-sdk-logs-testing` will into `opentelemetry-sdk-testing`, `opentelemetry-sdk-extension-autoconfigure` will enable `otlp` log exporter by default (i.e. `otel.logs.exporter=otlp`). For more details, see tracking issue [#5340](https://github.com/open-telemetry/opentelemetry-java/issues/5340). NOTE: reminder that -the [Logs Bridge API](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/logs/bridge-api.md) +the [Logs Bridge API](https://github.com/open-telemetry/opentelemetry-specification/blob/v1.21.0/specification/logs/bridge-api.md) is _not_ meant for end users. Log appenders use the API to bridge logs from existing log frameworks (e.g. JUL, Log4j, SLf4J, Logback) into OpenTelemetry. Users configure the Log SDK to dictate how logs are processed and exported. @@ -1672,8 +1672,8 @@ log API component has been added for emitting events and for writing log appende API is not a substitute for traditional log frameworks like Log4j, JUL, SLF4J, or Logback. While the event portion of the API is intended for instrumentation authors and end users, the API for emitting LogRecords is not. -See [LoggerProvider](./api/logs/src/main/java/io/opentelemetry/api/logs/LoggerProvider.java) -and [Logger](./api/logs/src/main/java/io/opentelemetry/api/logs/Logger.java) javadoc for more +See [LoggerProvider](./api/all/src/main/java/io/opentelemetry/api/logs/LoggerProvider.java) +and [Logger](./api/all/src/main/java/io/opentelemetry/api/logs/Logger.java) javadoc for more details. ### General @@ -1959,7 +1959,7 @@ details. stable `opentelemetry-sdk-extension-autoconfigure-spi`. * Autoconfigure now supports multiple values for `otel.metrics.exporter`. * Autoconfigure now - supports [general attribute limits](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/sdk-environment-variables.md#attribute-limits), + supports [general attribute limits](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/configuration/sdk-environment-variables.md#attribute-limits), applicable to span attributes, span event attributes, span link attributes, and log attributes. * Autoconfigure now supports an experimental option to disable the SDK. If `otel.experimental.sdk.enabled=true`, `AutoConfiguredOpenTelemetrySdk#getOpenTelemetrySdk()` @@ -3519,7 +3519,7 @@ See the `opentelemetry-extension-kotlin` module for details. #### Breaking changes -- There have been many updates to the semantic conventions constants. The constants are now auto-generated from the YAML specification files, so the names will now be consistent across languages. For more information, see the [YAML Model for Semantic Conventions](https://github.com/open-telemetry/opentelemetry-specification/tree/master/semantic_conventions). +- There have been many updates to the semantic conventions constants. The constants are now auto-generated from the YAML specification files, so the names will now be consistent across languages. For more information, see the [YAML Model for Semantic Conventions](https://github.com/open-telemetry/semantic-conventions/tree/main/model#yaml-model-for-semantic-conventions). - All API classes have been moved into the `io.opentelemetry.api.` prefix to support JPMS users. - The API no longer uses the `grpc-context` as the context implementation. It now uses `io.opentelemetry.context.Context`. This is published in the `opentelemetry-context` artifact. Interactions with the context were mostly moved to static methods in the `Span` and `Baggage` interfaces. - The Baggage API has been reworked to more closely match the specification. This includes the removal of the `BaggageManager`. Baggage is fully functional within the API, without needing to install an SDK. @@ -3550,7 +3550,7 @@ See the `opentelemetry-extension-kotlin` module for details. #### Breaking changes -- `TraceConfig` configuration option names (environment variables and system properties) were renamed to match the OpenTelemetery Specification. For more information, see [TraceConfig](./QUICKSTART.md#TraceConfig). +- `TraceConfig` configuration option names (environment variables and system properties) were renamed to match the OpenTelemetery Specification. - The Jaeger gRPC exporter was updated to match the OpenTelemetry Specification. The `message` log entry attribute has been renamed to `event` and a new `dropped attributes count` attribute was added. For more information, see the [Overview](https://github.com/open-telemetry/opentelemetry-specification/blob/master/specification/overview.md). - The `SpanData.getHasRemoteParent()` and `SpanData.getHasEnded()` methods were renamed to `hasRemoteParent()` and `hasEnded()`, respectively. - The `IdsGenerator` interface has been renamed to `IdGenerator`, and all implementations and relevant factory methods were similarly renamed. From fe810e73d3ab0fe22fef9e9b17eeafb47521de8d Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 24 Dec 2024 10:31:18 -0800 Subject: [PATCH 732/901] fix(deps): update dependency nl.jqno.equalsverifier:equalsverifier to v3.18 (#6980) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- dependencyManagement/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index be50c8e5b62..647addc2223 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -76,7 +76,7 @@ val DEPENDENCIES = listOf( "io.opentracing:opentracing-api:0.33.0", "io.opentracing:opentracing-noop:0.33.0", "junit:junit:4.13.2", - "nl.jqno.equalsverifier:equalsverifier:3.17.5", + "nl.jqno.equalsverifier:equalsverifier:3.18", "org.awaitility:awaitility:4.2.2", "org.bouncycastle:bcpkix-jdk15on:1.70", "org.codehaus.mojo:animal-sniffer-annotations:1.24", From 98c3fc1b8511ba5a0feeed5cb95038abd459b0a7 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 28 Dec 2024 19:19:41 -0800 Subject: [PATCH 733/901] fix(deps): update dependency checkstyle to v10.21.1 (#6982) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- buildSrc/src/main/kotlin/otel.java-conventions.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/buildSrc/src/main/kotlin/otel.java-conventions.gradle.kts b/buildSrc/src/main/kotlin/otel.java-conventions.gradle.kts index 71a119f9b3b..ff17e6dcaa2 100644 --- a/buildSrc/src/main/kotlin/otel.java-conventions.gradle.kts +++ b/buildSrc/src/main/kotlin/otel.java-conventions.gradle.kts @@ -42,7 +42,7 @@ java { checkstyle { configDirectory.set(file("$rootDir/buildscripts/")) - toolVersion = "10.21.0" + toolVersion = "10.21.1" isIgnoreFailures = false configProperties["rootDir"] = rootDir } From 986dbaa26e975bc65344a601badfaeeb3a2fee6f Mon Sep 17 00:00:00 2001 From: jack-berg <34418638+jack-berg@users.noreply.github.com> Date: Thu, 2 Jan 2025 14:53:42 -0600 Subject: [PATCH 734/901] Ensure Serializer runtime exceptions are rethrown as IOException (#6969) --- .../exporter/internal/marshal/Serializer.java | 23 +++- .../internal/marshal/MarshalerTest.java | 127 ++++++++++++++++++ 2 files changed, 145 insertions(+), 5 deletions(-) diff --git a/exporters/common/src/main/java/io/opentelemetry/exporter/internal/marshal/Serializer.java b/exporters/common/src/main/java/io/opentelemetry/exporter/internal/marshal/Serializer.java index a19091fa73d..100506fb3dc 100644 --- a/exporters/common/src/main/java/io/opentelemetry/exporter/internal/marshal/Serializer.java +++ b/exporters/common/src/main/java/io/opentelemetry/exporter/internal/marshal/Serializer.java @@ -9,6 +9,7 @@ import io.opentelemetry.api.common.Attributes; import io.opentelemetry.sdk.internal.DynamicPrimitiveLongList; import java.io.IOException; +import java.io.UncheckedIOException; import java.nio.ByteBuffer; import java.util.Collection; import java.util.List; @@ -535,7 +536,11 @@ public void serializeRepeatedMessageWithContext( if (!messages.isEmpty()) { RepeatedElementWriter writer = context.getInstance(key, RepeatedElementWriter::new); writer.initialize(field, this, marshaler, context); - messages.forEach(writer); + try { + messages.forEach(writer); + } catch (UncheckedIOException e) { + throw e.getCause(); + } } writeEndRepeated(); @@ -559,7 +564,11 @@ public void serializeRepeatedMessageWithContext( RepeatedElementPairWriter writer = context.getInstance(key, RepeatedElementPairWriter::new); writer.initialize(field, this, marshaler, context); - messages.forEach(writer); + try { + messages.forEach(writer); + } catch (UncheckedIOException e) { + throw e.getCause(); + } } writeEndRepeated(); @@ -582,7 +591,11 @@ public void serializeRepeatedMessageWithContext( RepeatedElementPairWriter, Object> writer = context.getInstance(ATTRIBUTES_WRITER_KEY, RepeatedElementPairWriter::new); writer.initialize(field, this, marshaler, context); - attributes.forEach(writer); + try { + attributes.forEach(writer); + } catch (UncheckedIOException e) { + throw e.getCause(); + } } writeEndRepeated(); @@ -619,7 +632,7 @@ public void accept(T element) { marshaler.writeTo(output, element, context); output.writeEndRepeatedElement(); } catch (IOException e) { - throw new IllegalStateException(e); + throw new UncheckedIOException(e); } } } @@ -655,7 +668,7 @@ public void accept(K key, V value) { marshaler.writeTo(output, key, value, context); output.writeEndRepeatedElement(); } catch (IOException e) { - throw new IllegalStateException(e); + throw new UncheckedIOException(e); } } } diff --git a/exporters/common/src/test/java/io/opentelemetry/exporter/internal/marshal/MarshalerTest.java b/exporters/common/src/test/java/io/opentelemetry/exporter/internal/marshal/MarshalerTest.java index eff401a2800..a89ea217cc1 100644 --- a/exporters/common/src/test/java/io/opentelemetry/exporter/internal/marshal/MarshalerTest.java +++ b/exporters/common/src/test/java/io/opentelemetry/exporter/internal/marshal/MarshalerTest.java @@ -11,9 +11,17 @@ import static org.mockito.Mockito.doThrow; import static org.mockito.Mockito.mock; +import io.opentelemetry.api.common.AttributeKey; +import io.opentelemetry.api.common.Attributes; +import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.OutputStream; +import java.util.Collections; +import java.util.stream.Stream; import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; class MarshalerTest { @@ -47,4 +55,123 @@ protected void writeTo(Serializer output) throws IOException { assertThatThrownBy(() -> marshaler.writeBinaryTo(os)).isInstanceOf(IOException.class); assertThatThrownBy(() -> marshaler.writeJsonTo(os)).isInstanceOf(IOException.class); } + + /** + * This test ensures that instances where serializer produces runtime exceptions are properly + * converted back to checked {@link IOException}. + * + *

      At various points in {@link Serializer}, we use {@code .forEach}-style methods which accept + * {@link java.util.function.Consumer} and {@link java.util.function.BiConsumer}. These consumers + * that any checked exceptions are caught and rethrown as runtime exceptions. Its essential that + * these runtime exceptions are re-converted back to checked {@link IOException} because calling + * code's error handling is built on top of {@link IOException}. Failure to convert to {@link + * IOException} leads to issues like this: #6946. + */ + @ParameterizedTest + @MethodSource("writeToArgs") + void writeTo_NoRuntimeExceptions(Writer writer) throws IOException { + Marshaler marshaler = + new Marshaler() { + @Override + public int getBinarySerializedSize() { + return 0; + } + + @Override + protected void writeTo(Serializer output) throws IOException { + writer.writeTo(output); + } + }; + + try (ByteArrayOutputStream baos = new ByteArrayOutputStream()) { + assertThatThrownBy(() -> marshaler.writeBinaryTo(baos)).isInstanceOf(IOException.class); + } + } + + private static Stream writeToArgs() { + ProtoFieldInfo fieldInfo = ProtoFieldInfo.create(0, 0, "name"); + MarshalerContext context = new MarshalerContext(); + ThrowingMarshaler throwingMarshaler = new ThrowingMarshaler<>(new IOException("error")); + ThrowingMarshaler2 throwingMarshaler2 = + new ThrowingMarshaler2<>(new IOException("error")); + ThrowingMarshaler2, Object> throwingMarshaler2Attributes = + new ThrowingMarshaler2<>(new IOException("error")); + + return Stream.of( + Arguments.of( + asWriter( + output -> + output.serializeRepeatedMessageWithContext( + fieldInfo, + Collections.singleton("value"), + throwingMarshaler, + context, + MarshalerContext.key()))), + Arguments.of( + asWriter( + output -> + output.serializeRepeatedMessageWithContext( + fieldInfo, + Collections.singletonMap("key", "value"), + throwingMarshaler2, + context, + MarshalerContext.key()))), + Arguments.of( + asWriter( + output -> + output.serializeRepeatedMessageWithContext( + fieldInfo, + Attributes.builder().put("key", "value").build(), + throwingMarshaler2Attributes, + context)))); + } + + private static Writer asWriter(Writer writer) { + return writer; + } + + @FunctionalInterface + private interface Writer { + void writeTo(Serializer output) throws IOException; + } + + private static class ThrowingMarshaler implements StatelessMarshaler { + + private final IOException exception; + + private ThrowingMarshaler(IOException exception) { + this.exception = exception; + } + + @Override + public int getBinarySerializedSize(T value, MarshalerContext context) { + return 0; + } + + @Override + public void writeTo(Serializer output, T value, MarshalerContext context) throws IOException { + throw exception; + } + } + + private static class ThrowingMarshaler2 implements StatelessMarshaler2 { + + private final IOException exception; + + private ThrowingMarshaler2(IOException exception) { + this.exception = exception; + } + + @Override + public int getBinarySerializedSize(K key, V value, MarshalerContext context) { + return 0; + } + + @Override + public void writeTo(Serializer output, K key, V value, MarshalerContext context) + throws IOException { + throw exception; + } + } } From ddc9c9162be669aa9e953275e8162fd73aa1b5ab Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 2 Jan 2025 15:24:41 -0800 Subject: [PATCH 735/901] fix(deps): update dependency org.assertj:assertj-bom to v3.27.1 (#6985) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- dependencyManagement/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index 647addc2223..ddb57ece77c 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -18,7 +18,7 @@ val DEPENDENCY_BOMS = listOf( "io.netty:netty-bom:4.1.116.Final", "io.zipkin.brave:brave-bom:6.0.3", "io.zipkin.reporter2:zipkin-reporter-bom:3.4.3", - "org.assertj:assertj-bom:3.27.0", + "org.assertj:assertj-bom:3.27.1", "org.junit:junit-bom:5.11.4", "org.testcontainers:testcontainers-bom:1.20.4", "org.snakeyaml:snakeyaml-engine:2.8" From aa5c74c9e07e0aa6169c60665435b319c440159e Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 4 Jan 2025 14:03:17 -0800 Subject: [PATCH 736/901] fix(deps): update dependency org.assertj:assertj-bom to v3.27.2 (#6987) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- dependencyManagement/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index ddb57ece77c..7614816701e 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -18,7 +18,7 @@ val DEPENDENCY_BOMS = listOf( "io.netty:netty-bom:4.1.116.Final", "io.zipkin.brave:brave-bom:6.0.3", "io.zipkin.reporter2:zipkin-reporter-bom:3.4.3", - "org.assertj:assertj-bom:3.27.1", + "org.assertj:assertj-bom:3.27.2", "org.junit:junit-bom:5.11.4", "org.testcontainers:testcontainers-bom:1.20.4", "org.snakeyaml:snakeyaml-engine:2.8" From 8369d7f57e8c74beacbc2b8a388d29282cc28140 Mon Sep 17 00:00:00 2001 From: jack-berg <34418638+jack-berg@users.noreply.github.com> Date: Mon, 6 Jan 2025 11:29:26 -0600 Subject: [PATCH 737/901] Delete OTLP authenticator concept (#6984) --- .../exporter/internal/auth/Authenticator.java | 55 ------------ .../exporter/internal/auth/package-info.java | 10 --- .../internal/http/HttpExporterBuilder.java | 10 --- .../internal/http/HttpSenderProvider.java | 2 - .../internal/auth/AuthenticatorTest.java | 75 ----------------- ...tlpHttpLogRecordExporterJdkSenderTest.java | 5 -- .../OtlpHttpMetricExporterJdkSenderTest.java | 5 -- .../OtlpHttpSpanExporterJdkSenderTest.java | 5 -- .../AbstractHttpTelemetryExporterTest.java | 36 -------- .../GrpcLogRecordExporterBuilderWrapper.java | 6 -- .../GrpcMetricExporterBuilderWrapper.java | 6 -- .../GrpcSpanExporterBuilderWrapper.java | 6 -- .../HttpLogRecordExporterBuilderWrapper.java | 7 -- .../HttpMetricExporterBuilderWrapper.java | 7 -- .../HttpSpanExporterBuilderWrapper.java | 7 -- ...anagedChannelTelemetryExporterBuilder.java | 7 -- .../internal/TelemetryExporterBuilder.java | 3 - .../jdk/internal/JdkHttpSenderProvider.java | 2 - .../okhttp/internal/OkHttpHttpSender.java | 13 --- .../internal/OkHttpHttpSenderProvider.java | 3 - .../internal/AuthenticatingExporterTest.java | 84 ------------------- .../internal/OkHttpHttpSuppressionTest.java | 1 - 22 files changed, 355 deletions(-) delete mode 100644 exporters/common/src/main/java/io/opentelemetry/exporter/internal/auth/Authenticator.java delete mode 100644 exporters/common/src/main/java/io/opentelemetry/exporter/internal/auth/package-info.java delete mode 100644 exporters/common/src/test/java/io/opentelemetry/exporter/internal/auth/AuthenticatorTest.java delete mode 100644 exporters/sender/okhttp/src/test/java/io/opentelemetry/exporter/sender/okhttp/internal/AuthenticatingExporterTest.java diff --git a/exporters/common/src/main/java/io/opentelemetry/exporter/internal/auth/Authenticator.java b/exporters/common/src/main/java/io/opentelemetry/exporter/internal/auth/Authenticator.java deleted file mode 100644 index 7ad2547ee20..00000000000 --- a/exporters/common/src/main/java/io/opentelemetry/exporter/internal/auth/Authenticator.java +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package io.opentelemetry.exporter.internal.auth; - -import io.opentelemetry.exporter.internal.grpc.GrpcExporterBuilder; -import io.opentelemetry.exporter.internal.http.HttpExporterBuilder; -import java.lang.reflect.Field; -import java.util.Map; - -/** - * This class is internal and is hence not for public use. Its APIs are unstable and can change at - * any time. - * - *

      Allow users of OTLP-OkHttp exporters to add support for authentication. - */ -public interface Authenticator { - - /** - * Method called by the exporter to get headers to be used on a request that requires - * authentication. - * - * @return Headers to add to the request - */ - Map getHeaders(); - - /** - * Reflectively access a {@link GrpcExporterBuilder}, or {@link HttpExporterBuilder} instance in - * field called "delegate" of the instance, and set the {@link Authenticator}. - * - * @param builder export builder to modify - * @param authenticator authenticator to set on builder - * @throws IllegalArgumentException if the instance does not contain a field called "delegate" of - * a supported type. - */ - static void setAuthenticatorOnDelegate(Object builder, Authenticator authenticator) { - try { - Field field = builder.getClass().getDeclaredField("delegate"); - field.setAccessible(true); - Object value = field.get(builder); - if (value instanceof GrpcExporterBuilder) { - throw new IllegalArgumentException("GrpcExporterBuilder not supported yet."); - } else if (value instanceof HttpExporterBuilder) { - ((HttpExporterBuilder) value).setAuthenticator(authenticator); - } else { - throw new IllegalArgumentException( - "Delegate field is not type DefaultGrpcExporterBuilder or OkHttpGrpcExporterBuilder."); - } - } catch (NoSuchFieldException | IllegalAccessException e) { - throw new IllegalArgumentException("Unable to access delegate reflectively.", e); - } - } -} diff --git a/exporters/common/src/main/java/io/opentelemetry/exporter/internal/auth/package-info.java b/exporters/common/src/main/java/io/opentelemetry/exporter/internal/auth/package-info.java deleted file mode 100644 index 1d79565d574..00000000000 --- a/exporters/common/src/main/java/io/opentelemetry/exporter/internal/auth/package-info.java +++ /dev/null @@ -1,10 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -/** Utilities for exporter authentication. */ -@ParametersAreNonnullByDefault -package io.opentelemetry.exporter.internal.auth; - -import javax.annotation.ParametersAreNonnullByDefault; diff --git a/exporters/common/src/main/java/io/opentelemetry/exporter/internal/http/HttpExporterBuilder.java b/exporters/common/src/main/java/io/opentelemetry/exporter/internal/http/HttpExporterBuilder.java index 4d23d39ea85..e88533ab8aa 100644 --- a/exporters/common/src/main/java/io/opentelemetry/exporter/internal/http/HttpExporterBuilder.java +++ b/exporters/common/src/main/java/io/opentelemetry/exporter/internal/http/HttpExporterBuilder.java @@ -10,7 +10,6 @@ import io.opentelemetry.api.metrics.MeterProvider; import io.opentelemetry.exporter.internal.ExporterBuilderUtil; import io.opentelemetry.exporter.internal.TlsConfigHelper; -import io.opentelemetry.exporter.internal.auth.Authenticator; import io.opentelemetry.exporter.internal.compression.Compressor; import io.opentelemetry.exporter.internal.marshal.Marshaler; import io.opentelemetry.sdk.common.export.ProxyOptions; @@ -61,7 +60,6 @@ public final class HttpExporterBuilder { private TlsConfigHelper tlsConfigHelper = new TlsConfigHelper(); @Nullable private RetryPolicy retryPolicy = RetryPolicy.getDefault(); private Supplier meterProviderSupplier = GlobalOpenTelemetry::getMeterProvider; - @Nullable private Authenticator authenticator; public HttpExporterBuilder(String exporterName, String type, String defaultEndpoint) { this.exporterName = exporterName; @@ -101,11 +99,6 @@ public HttpExporterBuilder setHeadersSupplier(Supplier> h return this; } - public HttpExporterBuilder setAuthenticator(Authenticator authenticator) { - this.authenticator = authenticator; - return this; - } - public HttpExporterBuilder setTrustManagerFromCerts(byte[] trustedCertificatesPem) { tlsConfigHelper.setTrustManagerFromCerts(trustedCertificatesPem); return this; @@ -158,7 +151,6 @@ public HttpExporterBuilder copy() { copy.retryPolicy = retryPolicy.toBuilder().build(); } copy.meterProviderSupplier = meterProviderSupplier; - copy.authenticator = authenticator; copy.proxyOptions = proxyOptions; return copy; } @@ -197,7 +189,6 @@ public HttpExporter build() { connectTimeoutNanos, headerSupplier, proxyOptions, - authenticator, retryPolicy, isPlainHttp ? null : tlsConfigHelper.getSslContext(), isPlainHttp ? null : tlsConfigHelper.getTrustManager()); @@ -233,7 +224,6 @@ public String toString(boolean includePrefixAndSuffix) { } // Note: omit tlsConfigHelper because we can't log the configuration in any readable way // Note: omit meterProviderSupplier because we can't log the configuration in any readable way - // Note: omit authenticator because we can't log the configuration in any readable way return joiner.toString(); } diff --git a/exporters/common/src/main/java/io/opentelemetry/exporter/internal/http/HttpSenderProvider.java b/exporters/common/src/main/java/io/opentelemetry/exporter/internal/http/HttpSenderProvider.java index b308511eba3..651343beaed 100644 --- a/exporters/common/src/main/java/io/opentelemetry/exporter/internal/http/HttpSenderProvider.java +++ b/exporters/common/src/main/java/io/opentelemetry/exporter/internal/http/HttpSenderProvider.java @@ -5,7 +5,6 @@ package io.opentelemetry.exporter.internal.http; -import io.opentelemetry.exporter.internal.auth.Authenticator; import io.opentelemetry.exporter.internal.compression.Compressor; import io.opentelemetry.sdk.common.export.ProxyOptions; import io.opentelemetry.sdk.common.export.RetryPolicy; @@ -36,7 +35,6 @@ HttpSender createSender( long connectTimeout, Supplier>> headerSupplier, @Nullable ProxyOptions proxyOptions, - @Nullable Authenticator authenticator, @Nullable RetryPolicy retryPolicy, @Nullable SSLContext sslContext, @Nullable X509TrustManager trustManager); diff --git a/exporters/common/src/test/java/io/opentelemetry/exporter/internal/auth/AuthenticatorTest.java b/exporters/common/src/test/java/io/opentelemetry/exporter/internal/auth/AuthenticatorTest.java deleted file mode 100644 index 93e07e12d41..00000000000 --- a/exporters/common/src/test/java/io/opentelemetry/exporter/internal/auth/AuthenticatorTest.java +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package io.opentelemetry.exporter.internal.auth; - -import static org.assertj.core.api.Assertions.as; -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatThrownBy; - -import io.opentelemetry.exporter.internal.grpc.GrpcExporter; -import io.opentelemetry.exporter.internal.http.HttpExporterBuilder; -import java.util.Collections; -import java.util.HashMap; -import java.util.Map; -import org.assertj.core.api.InstanceOfAssertFactories; -import org.junit.jupiter.api.Test; - -class AuthenticatorTest { - - @Test - void getHeaders() { - Map input = new HashMap<>(); - input.put("key1", "value1"); - input.put("key2", "value2"); - - Authenticator authenticator = () -> new HashMap<>(input); - assertThat(authenticator.getHeaders()).isEqualTo(input); - } - - @Test - void setAuthenticatorOnDelegate_Success() { - HttpExporterBuilder builder = - new HttpExporterBuilder<>("otlp", "test", "http://localhost:4318/test"); - - assertThat(builder).extracting("authenticator").isNull(); - - Authenticator authenticator = Collections::emptyMap; - - Authenticator.setAuthenticatorOnDelegate(new WithDelegate(builder), authenticator); - - assertThat(builder) - .extracting("authenticator", as(InstanceOfAssertFactories.type(Authenticator.class))) - .isSameAs(authenticator); - } - - @Test - void setAuthenticatorOnDelegate_Fail() { - Authenticator authenticator = Collections::emptyMap; - - assertThatThrownBy(() -> Authenticator.setAuthenticatorOnDelegate(new Object(), authenticator)) - .isInstanceOf(IllegalArgumentException.class); - assertThatThrownBy( - () -> - Authenticator.setAuthenticatorOnDelegate( - new WithDelegate(new Object()), authenticator)) - .isInstanceOf(IllegalArgumentException.class); - assertThatThrownBy( - () -> - Authenticator.setAuthenticatorOnDelegate( - new WithDelegate(new GrpcExporter<>(null, null, null, null)), authenticator)) - .isInstanceOf(IllegalArgumentException.class); - } - - @SuppressWarnings({"UnusedVariable", "FieldCanBeLocal"}) - private static class WithDelegate { - - private final Object delegate; - - private WithDelegate(Object delegate) { - this.delegate = delegate; - } - } -} diff --git a/exporters/otlp/all/src/testJdkHttpSender/java/io/opentelemetry/exporter/otlp/http/logs/OtlpHttpLogRecordExporterJdkSenderTest.java b/exporters/otlp/all/src/testJdkHttpSender/java/io/opentelemetry/exporter/otlp/http/logs/OtlpHttpLogRecordExporterJdkSenderTest.java index 25b99077948..9c1d92972d8 100644 --- a/exporters/otlp/all/src/testJdkHttpSender/java/io/opentelemetry/exporter/otlp/http/logs/OtlpHttpLogRecordExporterJdkSenderTest.java +++ b/exporters/otlp/all/src/testJdkHttpSender/java/io/opentelemetry/exporter/otlp/http/logs/OtlpHttpLogRecordExporterJdkSenderTest.java @@ -23,11 +23,6 @@ protected OtlpHttpLogRecordExporterJdkSenderTest() { super("log", "/v1/logs", ResourceLogs.getDefaultInstance()); } - @Override - protected boolean hasAuthenticatorSupport() { - return false; - } - @Override protected TelemetryExporterBuilder exporterBuilder() { return new HttpLogRecordExporterBuilderWrapper(OtlpHttpLogRecordExporter.builder()); diff --git a/exporters/otlp/all/src/testJdkHttpSender/java/io/opentelemetry/exporter/otlp/http/metrics/OtlpHttpMetricExporterJdkSenderTest.java b/exporters/otlp/all/src/testJdkHttpSender/java/io/opentelemetry/exporter/otlp/http/metrics/OtlpHttpMetricExporterJdkSenderTest.java index 4c1ad15e856..88f7b6cdfe3 100644 --- a/exporters/otlp/all/src/testJdkHttpSender/java/io/opentelemetry/exporter/otlp/http/metrics/OtlpHttpMetricExporterJdkSenderTest.java +++ b/exporters/otlp/all/src/testJdkHttpSender/java/io/opentelemetry/exporter/otlp/http/metrics/OtlpHttpMetricExporterJdkSenderTest.java @@ -108,11 +108,6 @@ void stringRepresentation() { } } - @Override - protected boolean hasAuthenticatorSupport() { - return false; - } - @Override protected TelemetryExporterBuilder exporterBuilder() { return new HttpMetricExporterBuilderWrapper(OtlpHttpMetricExporter.builder()); diff --git a/exporters/otlp/all/src/testJdkHttpSender/java/io/opentelemetry/exporter/otlp/http/trace/OtlpHttpSpanExporterJdkSenderTest.java b/exporters/otlp/all/src/testJdkHttpSender/java/io/opentelemetry/exporter/otlp/http/trace/OtlpHttpSpanExporterJdkSenderTest.java index 28a451addb4..4b546d1d796 100644 --- a/exporters/otlp/all/src/testJdkHttpSender/java/io/opentelemetry/exporter/otlp/http/trace/OtlpHttpSpanExporterJdkSenderTest.java +++ b/exporters/otlp/all/src/testJdkHttpSender/java/io/opentelemetry/exporter/otlp/http/trace/OtlpHttpSpanExporterJdkSenderTest.java @@ -27,11 +27,6 @@ protected OtlpHttpSpanExporterJdkSenderTest() { super("span", "/v1/traces", ResourceSpans.getDefaultInstance()); } - @Override - protected boolean hasAuthenticatorSupport() { - return false; - } - @Override protected TelemetryExporterBuilder exporterBuilder() { return new HttpSpanExporterBuilderWrapper(OtlpHttpSpanExporter.builder()); diff --git a/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/AbstractHttpTelemetryExporterTest.java b/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/AbstractHttpTelemetryExporterTest.java index 3b68738dbe2..28e54dab222 100644 --- a/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/AbstractHttpTelemetryExporterTest.java +++ b/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/AbstractHttpTelemetryExporterTest.java @@ -8,7 +8,6 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatCode; import static org.assertj.core.api.Assertions.assertThatThrownBy; -import static org.assertj.core.api.Assumptions.assumeThat; import static org.junit.jupiter.api.Named.named; import static org.junit.jupiter.params.provider.Arguments.arguments; @@ -402,36 +401,6 @@ void withHeaders() { } } - @Test - void withAuthenticator() { - assumeThat(hasAuthenticatorSupport()).isTrue(); - - TelemetryExporter exporter = - exporterBuilder() - .setEndpoint(server.httpUri() + path) - .setAuthenticator(() -> Collections.singletonMap("key", "value")) - .build(); - - addHttpError(401); - - try { - assertThat( - exporter - .export(Collections.singletonList(generateFakeTelemetry())) - .join(10, TimeUnit.SECONDS) - .isSuccess()) - .isTrue(); - assertThat(httpRequests) - .element(0) - .satisfies(req -> assertThat(req.headers().get("key")).isNull()); - assertThat(httpRequests) - .element(1) - .satisfies(req -> assertThat(req.headers().get("key")).isEqualTo("value")); - } finally { - exporter.shutdown(); - } - } - @Test void tls() throws Exception { TelemetryExporter exporter = @@ -951,11 +920,6 @@ void stringRepresentation() throws IOException, CertificateEncodingException { protected abstract Marshaler[] toMarshalers(List telemetry); - // TODO: remove once JdkHttpSender supports authenticator - protected boolean hasAuthenticatorSupport() { - return true; - } - private List toProto(List telemetry) { return Arrays.stream(toMarshalers(telemetry)) .map( diff --git a/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/GrpcLogRecordExporterBuilderWrapper.java b/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/GrpcLogRecordExporterBuilderWrapper.java index 99fabd1ecb8..259be25632f 100644 --- a/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/GrpcLogRecordExporterBuilderWrapper.java +++ b/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/GrpcLogRecordExporterBuilderWrapper.java @@ -6,7 +6,6 @@ package io.opentelemetry.exporter.otlp.testing.internal; import io.grpc.ManagedChannel; -import io.opentelemetry.exporter.internal.auth.Authenticator; import io.opentelemetry.exporter.otlp.logs.OtlpGrpcLogRecordExporterBuilder; import io.opentelemetry.sdk.common.export.ProxyOptions; import io.opentelemetry.sdk.common.export.RetryPolicy; @@ -75,11 +74,6 @@ public TelemetryExporterBuilder setHeaders( return this; } - @Override - public TelemetryExporterBuilder setAuthenticator(Authenticator authenticator) { - return this; - } - @Override public TelemetryExporterBuilder setTrustedCertificates(byte[] certificates) { builder.setTrustedCertificates(certificates); diff --git a/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/GrpcMetricExporterBuilderWrapper.java b/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/GrpcMetricExporterBuilderWrapper.java index 07d5f39dd15..afe3a7eeb56 100644 --- a/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/GrpcMetricExporterBuilderWrapper.java +++ b/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/GrpcMetricExporterBuilderWrapper.java @@ -6,7 +6,6 @@ package io.opentelemetry.exporter.otlp.testing.internal; import io.grpc.ManagedChannel; -import io.opentelemetry.exporter.internal.auth.Authenticator; import io.opentelemetry.exporter.otlp.metrics.OtlpGrpcMetricExporterBuilder; import io.opentelemetry.sdk.common.export.ProxyOptions; import io.opentelemetry.sdk.common.export.RetryPolicy; @@ -75,11 +74,6 @@ public TelemetryExporterBuilder setHeaders( return this; } - @Override - public TelemetryExporterBuilder setAuthenticator(Authenticator authenticator) { - return this; - } - @Override public TelemetryExporterBuilder setTrustedCertificates(byte[] certificates) { builder.setTrustedCertificates(certificates); diff --git a/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/GrpcSpanExporterBuilderWrapper.java b/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/GrpcSpanExporterBuilderWrapper.java index 4f728111b6b..40e0c94f797 100644 --- a/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/GrpcSpanExporterBuilderWrapper.java +++ b/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/GrpcSpanExporterBuilderWrapper.java @@ -6,7 +6,6 @@ package io.opentelemetry.exporter.otlp.testing.internal; import io.grpc.ManagedChannel; -import io.opentelemetry.exporter.internal.auth.Authenticator; import io.opentelemetry.exporter.otlp.trace.OtlpGrpcSpanExporterBuilder; import io.opentelemetry.sdk.common.export.ProxyOptions; import io.opentelemetry.sdk.common.export.RetryPolicy; @@ -76,11 +75,6 @@ public TelemetryExporterBuilder setHeaders( return this; } - @Override - public TelemetryExporterBuilder setAuthenticator(Authenticator authenticator) { - return this; - } - @Override public TelemetryExporterBuilder setTrustedCertificates(byte[] certificates) { builder.setTrustedCertificates(certificates); diff --git a/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/HttpLogRecordExporterBuilderWrapper.java b/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/HttpLogRecordExporterBuilderWrapper.java index 0d9997f4644..359cec9e016 100644 --- a/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/HttpLogRecordExporterBuilderWrapper.java +++ b/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/HttpLogRecordExporterBuilderWrapper.java @@ -5,7 +5,6 @@ package io.opentelemetry.exporter.otlp.testing.internal; -import io.opentelemetry.exporter.internal.auth.Authenticator; import io.opentelemetry.exporter.otlp.http.logs.OtlpHttpLogRecordExporterBuilder; import io.opentelemetry.sdk.common.export.ProxyOptions; import io.opentelemetry.sdk.common.export.RetryPolicy; @@ -76,12 +75,6 @@ public TelemetryExporterBuilder setHeaders( return this; } - @Override - public TelemetryExporterBuilder setAuthenticator(Authenticator authenticator) { - Authenticator.setAuthenticatorOnDelegate(builder, authenticator); - return this; - } - @Override public TelemetryExporterBuilder setTrustedCertificates(byte[] certificates) { builder.setTrustedCertificates(certificates); diff --git a/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/HttpMetricExporterBuilderWrapper.java b/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/HttpMetricExporterBuilderWrapper.java index a553acc5f18..0058f51a760 100644 --- a/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/HttpMetricExporterBuilderWrapper.java +++ b/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/HttpMetricExporterBuilderWrapper.java @@ -5,7 +5,6 @@ package io.opentelemetry.exporter.otlp.testing.internal; -import io.opentelemetry.exporter.internal.auth.Authenticator; import io.opentelemetry.exporter.otlp.http.metrics.OtlpHttpMetricExporterBuilder; import io.opentelemetry.sdk.common.export.ProxyOptions; import io.opentelemetry.sdk.common.export.RetryPolicy; @@ -75,12 +74,6 @@ public TelemetryExporterBuilder setHeaders( return this; } - @Override - public TelemetryExporterBuilder setAuthenticator(Authenticator authenticator) { - Authenticator.setAuthenticatorOnDelegate(builder, authenticator); - return this; - } - @Override public TelemetryExporterBuilder setTrustedCertificates(byte[] certificates) { builder.setTrustedCertificates(certificates); diff --git a/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/HttpSpanExporterBuilderWrapper.java b/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/HttpSpanExporterBuilderWrapper.java index 1efcf301813..993abe5d2bb 100644 --- a/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/HttpSpanExporterBuilderWrapper.java +++ b/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/HttpSpanExporterBuilderWrapper.java @@ -5,7 +5,6 @@ package io.opentelemetry.exporter.otlp.testing.internal; -import io.opentelemetry.exporter.internal.auth.Authenticator; import io.opentelemetry.exporter.otlp.http.trace.OtlpHttpSpanExporterBuilder; import io.opentelemetry.sdk.common.export.ProxyOptions; import io.opentelemetry.sdk.common.export.RetryPolicy; @@ -75,12 +74,6 @@ public TelemetryExporterBuilder setHeaders( return this; } - @Override - public TelemetryExporterBuilder setAuthenticator(Authenticator authenticator) { - Authenticator.setAuthenticatorOnDelegate(builder, authenticator); - return this; - } - @Override public TelemetryExporterBuilder setTrustedCertificates(byte[] certificates) { builder.setTrustedCertificates(certificates); diff --git a/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/ManagedChannelTelemetryExporterBuilder.java b/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/ManagedChannelTelemetryExporterBuilder.java index d9fc98d0f8c..941a30359b1 100644 --- a/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/ManagedChannelTelemetryExporterBuilder.java +++ b/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/ManagedChannelTelemetryExporterBuilder.java @@ -13,7 +13,6 @@ import io.grpc.netty.NettyChannelBuilder; import io.netty.handler.ssl.SslContext; import io.opentelemetry.exporter.internal.TlsConfigHelper; -import io.opentelemetry.exporter.internal.auth.Authenticator; import io.opentelemetry.exporter.internal.grpc.ManagedChannelUtil; import io.opentelemetry.exporter.otlp.internal.OtlpUserAgent; import io.opentelemetry.sdk.common.CompletableResultCode; @@ -109,12 +108,6 @@ public TelemetryExporterBuilder setHeaders(Supplier> head return this; } - @Override - public TelemetryExporterBuilder setAuthenticator(Authenticator authenticator) { - delegate.setAuthenticator(authenticator); - return this; - } - // When a user provides a Channel, we are not in control of TLS or retry config and reimplement it // here for use in tests. Technically we don't have to test them since they are out of the SDK's // control, but it's probably worth verifying the baseline functionality anyways. diff --git a/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/TelemetryExporterBuilder.java b/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/TelemetryExporterBuilder.java index 2b4b8d94d18..4e71e81132f 100644 --- a/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/TelemetryExporterBuilder.java +++ b/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/TelemetryExporterBuilder.java @@ -5,7 +5,6 @@ package io.opentelemetry.exporter.otlp.testing.internal; -import io.opentelemetry.exporter.internal.auth.Authenticator; import io.opentelemetry.exporter.otlp.logs.OtlpGrpcLogRecordExporterBuilder; import io.opentelemetry.exporter.otlp.metrics.OtlpGrpcMetricExporterBuilder; import io.opentelemetry.exporter.otlp.trace.OtlpGrpcSpanExporterBuilder; @@ -52,8 +51,6 @@ static TelemetryExporterBuilder wrap(OtlpGrpcLogRecordExporterBui TelemetryExporterBuilder setHeaders(Supplier> headerSupplier); - TelemetryExporterBuilder setAuthenticator(Authenticator authenticator); - TelemetryExporterBuilder setTrustedCertificates(byte[] certificates); TelemetryExporterBuilder setClientTls(byte[] privateKeyPem, byte[] certificatePem); diff --git a/exporters/sender/jdk/src/main/java/io/opentelemetry/exporter/sender/jdk/internal/JdkHttpSenderProvider.java b/exporters/sender/jdk/src/main/java/io/opentelemetry/exporter/sender/jdk/internal/JdkHttpSenderProvider.java index 8c2b44cddcb..f5905599183 100644 --- a/exporters/sender/jdk/src/main/java/io/opentelemetry/exporter/sender/jdk/internal/JdkHttpSenderProvider.java +++ b/exporters/sender/jdk/src/main/java/io/opentelemetry/exporter/sender/jdk/internal/JdkHttpSenderProvider.java @@ -5,7 +5,6 @@ package io.opentelemetry.exporter.sender.jdk.internal; -import io.opentelemetry.exporter.internal.auth.Authenticator; import io.opentelemetry.exporter.internal.compression.Compressor; import io.opentelemetry.exporter.internal.http.HttpSender; import io.opentelemetry.exporter.internal.http.HttpSenderProvider; @@ -36,7 +35,6 @@ public HttpSender createSender( long connectTimeout, Supplier>> headerSupplier, @Nullable ProxyOptions proxyOptions, - @Nullable Authenticator authenticator, @Nullable RetryPolicy retryPolicy, @Nullable SSLContext sslContext, @Nullable X509TrustManager trustManager) { diff --git a/exporters/sender/okhttp/src/main/java/io/opentelemetry/exporter/sender/okhttp/internal/OkHttpHttpSender.java b/exporters/sender/okhttp/src/main/java/io/opentelemetry/exporter/sender/okhttp/internal/OkHttpHttpSender.java index 20af7127451..53d06120e2e 100644 --- a/exporters/sender/okhttp/src/main/java/io/opentelemetry/exporter/sender/okhttp/internal/OkHttpHttpSender.java +++ b/exporters/sender/okhttp/src/main/java/io/opentelemetry/exporter/sender/okhttp/internal/OkHttpHttpSender.java @@ -7,7 +7,6 @@ import io.opentelemetry.api.internal.InstrumentationUtil; import io.opentelemetry.exporter.internal.RetryUtil; -import io.opentelemetry.exporter.internal.auth.Authenticator; import io.opentelemetry.exporter.internal.compression.Compressor; import io.opentelemetry.exporter.internal.http.HttpSender; import io.opentelemetry.exporter.internal.marshal.Marshaler; @@ -62,7 +61,6 @@ public OkHttpHttpSender( long connectionTimeoutNanos, Supplier>> headerSupplier, @Nullable ProxyOptions proxyOptions, - @Nullable Authenticator authenticator, @Nullable RetryPolicy retryPolicy, @Nullable SSLContext sslContext, @Nullable X509TrustManager trustManager) { @@ -76,17 +74,6 @@ public OkHttpHttpSender( builder.proxySelector(proxyOptions.getProxySelector()); } - if (authenticator != null) { - Authenticator finalAuthenticator = authenticator; - // Generate and attach OkHttp Authenticator implementation - builder.authenticator( - (route, response) -> { - Request.Builder requestBuilder = response.request().newBuilder(); - finalAuthenticator.getHeaders().forEach(requestBuilder::header); - return requestBuilder.build(); - }); - } - if (retryPolicy != null) { builder.addInterceptor(new RetryInterceptor(retryPolicy, OkHttpHttpSender::isRetryable)); } diff --git a/exporters/sender/okhttp/src/main/java/io/opentelemetry/exporter/sender/okhttp/internal/OkHttpHttpSenderProvider.java b/exporters/sender/okhttp/src/main/java/io/opentelemetry/exporter/sender/okhttp/internal/OkHttpHttpSenderProvider.java index fc91030fb5c..f5036a21271 100644 --- a/exporters/sender/okhttp/src/main/java/io/opentelemetry/exporter/sender/okhttp/internal/OkHttpHttpSenderProvider.java +++ b/exporters/sender/okhttp/src/main/java/io/opentelemetry/exporter/sender/okhttp/internal/OkHttpHttpSenderProvider.java @@ -5,7 +5,6 @@ package io.opentelemetry.exporter.sender.okhttp.internal; -import io.opentelemetry.exporter.internal.auth.Authenticator; import io.opentelemetry.exporter.internal.compression.Compressor; import io.opentelemetry.exporter.internal.http.HttpSender; import io.opentelemetry.exporter.internal.http.HttpSenderProvider; @@ -36,7 +35,6 @@ public HttpSender createSender( long connectTimeout, Supplier>> headerSupplier, @Nullable ProxyOptions proxyOptions, - @Nullable Authenticator authenticator, @Nullable RetryPolicy retryPolicy, @Nullable SSLContext sslContext, @Nullable X509TrustManager trustManager) { @@ -49,7 +47,6 @@ public HttpSender createSender( connectTimeout, headerSupplier, proxyOptions, - authenticator, retryPolicy, sslContext, trustManager); diff --git a/exporters/sender/okhttp/src/test/java/io/opentelemetry/exporter/sender/okhttp/internal/AuthenticatingExporterTest.java b/exporters/sender/okhttp/src/test/java/io/opentelemetry/exporter/sender/okhttp/internal/AuthenticatingExporterTest.java deleted file mode 100644 index a028d9c085b..00000000000 --- a/exporters/sender/okhttp/src/test/java/io/opentelemetry/exporter/sender/okhttp/internal/AuthenticatingExporterTest.java +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package io.opentelemetry.exporter.sender.okhttp.internal; - -import static org.assertj.core.api.Assertions.assertThat; - -import com.linecorp.armeria.common.HttpResponse; -import com.linecorp.armeria.common.HttpStatus; -import com.linecorp.armeria.testing.junit5.server.mock.MockWebServerExtension; -import io.opentelemetry.exporter.internal.http.HttpExporter; -import io.opentelemetry.exporter.internal.http.HttpExporterBuilder; -import io.opentelemetry.exporter.internal.marshal.Marshaler; -import io.opentelemetry.exporter.internal.marshal.Serializer; -import io.opentelemetry.internal.testing.slf4j.SuppressLogger; -import io.opentelemetry.sdk.common.CompletableResultCode; -import java.util.Collections; -import java.util.HashMap; -import java.util.Map; -import java.util.concurrent.TimeUnit; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.junit.jupiter.api.extension.RegisterExtension; -import org.mockito.junit.jupiter.MockitoExtension; - -/** Test Authentication in an exporter. */ -@ExtendWith(MockitoExtension.class) -class AuthenticatingExporterTest { - - @RegisterExtension static final MockWebServerExtension server = new MockWebServerExtension(); - private final Marshaler marshaler = - new Marshaler() { - @Override - public int getBinarySerializedSize() { - return 0; - } - - @Override - protected void writeTo(Serializer output) {} - }; - - @Test - void export() { - HttpExporter exporter = - new HttpExporterBuilder<>("otlp", "test", server.httpUri().toASCIIString()) - .setAuthenticator( - () -> { - Map headers = new HashMap<>(); - headers.put("Authorization", "auth"); - return headers; - }) - .build(); - - server.enqueue(HttpResponse.of(HttpStatus.UNAUTHORIZED)); - server.enqueue(HttpResponse.of(HttpStatus.OK)); - - CompletableResultCode result = exporter.export(marshaler, 0); - - assertThat(server.takeRequest().request().headers().get("Authorization")).isNull(); - assertThat(server.takeRequest().request().headers().get("Authorization")).isEqualTo("auth"); - - result.join(1, TimeUnit.MINUTES); - assertThat(result.isSuccess()).isTrue(); - } - - /** Ensure that exporter gives up if a request is always considered UNAUTHORIZED. */ - @Test - @SuppressLogger(HttpExporter.class) - void export_giveup() { - HttpExporter exporter = - new HttpExporterBuilder<>("otlp", "test", server.httpUri().toASCIIString()) - .setAuthenticator( - () -> { - server.enqueue(HttpResponse.of(HttpStatus.UNAUTHORIZED)); - return Collections.emptyMap(); - }) - .exportAsJson() - .build(); - server.enqueue(HttpResponse.of(HttpStatus.UNAUTHORIZED)); - assertThat(exporter.export(marshaler, 0).join(1, TimeUnit.MINUTES).isSuccess()).isFalse(); - } -} diff --git a/exporters/sender/okhttp/src/test/java/io/opentelemetry/exporter/sender/okhttp/internal/OkHttpHttpSuppressionTest.java b/exporters/sender/okhttp/src/test/java/io/opentelemetry/exporter/sender/okhttp/internal/OkHttpHttpSuppressionTest.java index 38686c36526..046dbee521a 100644 --- a/exporters/sender/okhttp/src/test/java/io/opentelemetry/exporter/sender/okhttp/internal/OkHttpHttpSuppressionTest.java +++ b/exporters/sender/okhttp/src/test/java/io/opentelemetry/exporter/sender/okhttp/internal/OkHttpHttpSuppressionTest.java @@ -46,7 +46,6 @@ OkHttpHttpSender createSender(String endpoint) { null, null, null, - null, null); } } From 2367ae53128ca04214b098e1f6005d2978f83277 Mon Sep 17 00:00:00 2001 From: jack-berg <34418638+jack-berg@users.noreply.github.com> Date: Mon, 6 Jan 2025 12:58:54 -0600 Subject: [PATCH 738/901] Add help wanted banner to readme (#6615) --- README.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/README.md b/README.md index 65b7e2c5c8e..771ad45f407 100644 --- a/README.md +++ b/README.md @@ -15,6 +15,9 @@ See [opentelemetry.io Java Documentation](https://opentelemetry.io/docs/language * End-to-end working code examples * And more +> [!IMPORTANT] +> We are currently seeking additional contributors! See [help wanted](#help-wanted) for details. + ## Requirements Unless otherwise noted, all published artifacts support Java 8 or higher. @@ -278,6 +281,15 @@ Emeritus: *Find more about the maintainer role in [community repository](https://github.com/open-telemetry/community/blob/main/guides/contributor/membership.md#maintainer).* +### Help wanted + +We are currently resource constrained and are actively seeking new contributors interested in working towards [approver](https://github.com/open-telemetry/community/blob/main/guides/contributor/membership.md#approver) / [maintainer](https://github.com/open-telemetry/community/blob/main/guides/contributor/membership.md#maintainer) roles. In addition to the documentation for approver / maintainer roles and the [contributing](./CONTRIBUTING.md) guide, here are some additional notes on engaging: + +- [Pull request](https://github.com/open-telemetry/opentelemetry-java/pulls) reviews are equally or more helpful than code contributions. Comments and approvals are valuable with or without a formal project role. They're also a great forcing function to explore a fairly complex codebase. +- Attending the [Java: SDK + Automatic Instrumentation](https://github.com/open-telemetry/community?tab=readme-ov-file#implementation-sigs) Special Interest Group (SIG) is a great way to get to know community members and learn about project priorities. +- Issues labeled [help wanted](https://github.com/open-telemetry/opentelemetry-java/issues?q=is%3Aopen+is%3Aissue+label%3A%22help+wanted%22) are project priorities. Code contributions (or pull request reviews when a PR is linked) for these issues are particularly important. +- Triaging / responding to new issues and discussions is a great way to engage with the project. + ### Thanks to all the people who have contributed From e36e185c6a806fe4a8ce149470f236ddf807c8d1 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 6 Jan 2025 13:29:33 -0600 Subject: [PATCH 739/901] fix(deps): update dependency com.uber.nullaway:nullaway to v0.12.3 (#6989) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- dependencyManagement/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index 7614816701e..b9596cfb29e 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -65,7 +65,7 @@ val DEPENDENCIES = listOf( "com.google.guava:guava-beta-checker:1.0", "com.sun.net.httpserver:http:20070405", "com.tngtech.archunit:archunit-junit5:1.3.0", - "com.uber.nullaway:nullaway:0.12.2", + "com.uber.nullaway:nullaway:0.12.3", "edu.berkeley.cs.jqf:jqf-fuzz:1.7", // jqf-fuzz version 1.8+ requires Java 11+ "eu.rekawek.toxiproxy:toxiproxy-java:2.1.7", "io.github.netmikey.logunit:logunit-jul:2.0.0", From ccccd1b0a523e249a6a75fd0b817f5391dc23f54 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 6 Jan 2025 13:30:39 -0600 Subject: [PATCH 740/901] fix(deps): update dependency com.squareup.wire:wire-bom to v5.2.0 (#6988) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- buildSrc/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts index fb8352ed2f3..d0b85233918 100644 --- a/buildSrc/build.gradle.kts +++ b/buildSrc/build.gradle.kts @@ -50,7 +50,7 @@ repositories { } dependencies { - implementation(enforcedPlatform("com.squareup.wire:wire-bom:5.1.0")) + implementation(enforcedPlatform("com.squareup.wire:wire-bom:5.2.0")) implementation("com.google.auto.value:auto-value-annotations:1.11.0") // When updating, update above in plugins too implementation("com.diffplug.spotless:spotless-plugin-gradle:6.25.0") From 1a84cbd00f6f5875129cfd170a07a32260138ac3 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 7 Jan 2025 13:03:51 -0600 Subject: [PATCH 741/901] fix(deps): update spotless packages to v7 (major) (#6993) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Co-authored-by: Jack Berg --- buildSrc/build.gradle.kts | 4 ++-- .../src/main/kotlin/otel.spotless-conventions.gradle.kts | 2 +- .../opentelemetry/extension/kotlin/ContextExtensions.kt | 8 ++------ .../DoubleRandomFixedSizeExemplarReservoirTest.java | 2 +- .../LongRandomFixedSizeExemplarReservoirTest.java | 2 +- 5 files changed, 7 insertions(+), 11 deletions(-) diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts index d0b85233918..e353de7c702 100644 --- a/buildSrc/build.gradle.kts +++ b/buildSrc/build.gradle.kts @@ -2,7 +2,7 @@ plugins { `kotlin-dsl` // When updating, update below in dependencies too - id("com.diffplug.spotless") version "6.25.0" + id("com.diffplug.spotless") version "7.0.0" } if (!hasLauncherForJavaVersion(17)) { @@ -53,7 +53,7 @@ dependencies { implementation(enforcedPlatform("com.squareup.wire:wire-bom:5.2.0")) implementation("com.google.auto.value:auto-value-annotations:1.11.0") // When updating, update above in plugins too - implementation("com.diffplug.spotless:spotless-plugin-gradle:6.25.0") + implementation("com.diffplug.spotless:spotless-plugin-gradle:7.0.0") // Needed for japicmp but not automatically brought in for some reason. implementation("com.google.guava:guava:33.4.0-jre") implementation("com.squareup:javapoet:1.13.0") diff --git a/buildSrc/src/main/kotlin/otel.spotless-conventions.gradle.kts b/buildSrc/src/main/kotlin/otel.spotless-conventions.gradle.kts index 5aec55a0407..b1c39dcd0db 100644 --- a/buildSrc/src/main/kotlin/otel.spotless-conventions.gradle.kts +++ b/buildSrc/src/main/kotlin/otel.spotless-conventions.gradle.kts @@ -70,7 +70,7 @@ spotless { "*.sh", "src/**/*.properties", ) - indentWithSpaces() + leadingTabsToSpaces() trimTrailingWhitespace() endWithNewline() } diff --git a/extensions/kotlin/src/main/kotlin/io/opentelemetry/extension/kotlin/ContextExtensions.kt b/extensions/kotlin/src/main/kotlin/io/opentelemetry/extension/kotlin/ContextExtensions.kt index 78f5a43e3f7..21e44222cac 100644 --- a/extensions/kotlin/src/main/kotlin/io/opentelemetry/extension/kotlin/ContextExtensions.kt +++ b/extensions/kotlin/src/main/kotlin/io/opentelemetry/extension/kotlin/ContextExtensions.kt @@ -13,17 +13,13 @@ import kotlin.coroutines.CoroutineContext * Returns a [CoroutineContext] which will make this [Context] current when resuming a coroutine * and restores the previous [Context] on suspension. */ -fun Context.asContextElement(): CoroutineContext { - return KotlinContextElement(this) -} +fun Context.asContextElement(): CoroutineContext = KotlinContextElement(this) /** * Returns a [CoroutineContext] which will make this [ImplicitContextKeyed] current when resuming a * coroutine and restores the previous [Context] on suspension. */ -fun ImplicitContextKeyed.asContextElement(): CoroutineContext { - return KotlinContextElement(Context.current().with(this)) -} +fun ImplicitContextKeyed.asContextElement(): CoroutineContext = KotlinContextElement(Context.current().with(this)) /** * Returns the [Context] in this [CoroutineContext] if present, or the root otherwise. diff --git a/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/internal/exemplar/DoubleRandomFixedSizeExemplarReservoirTest.java b/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/internal/exemplar/DoubleRandomFixedSizeExemplarReservoirTest.java index 769c2e2b5ce..85a53fbeb0d 100644 --- a/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/internal/exemplar/DoubleRandomFixedSizeExemplarReservoirTest.java +++ b/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/internal/exemplar/DoubleRandomFixedSizeExemplarReservoirTest.java @@ -114,7 +114,7 @@ public void multiMeasurements_preservesLatestSamples() { @Override public int nextInt(int max) { switch (max) { - // Force one sample in bucket 1 and two in bucket 0. + // Force one sample in bucket 1 and two in bucket 0. case 2: return 1; default: diff --git a/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/internal/exemplar/LongRandomFixedSizeExemplarReservoirTest.java b/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/internal/exemplar/LongRandomFixedSizeExemplarReservoirTest.java index ed9f1ea759e..fc754576401 100644 --- a/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/internal/exemplar/LongRandomFixedSizeExemplarReservoirTest.java +++ b/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/internal/exemplar/LongRandomFixedSizeExemplarReservoirTest.java @@ -114,7 +114,7 @@ public void multiMeasurements_preservesLatestSamples() { @Override public int nextInt(int max) { switch (max) { - // Force one sample in bucket 1 and two in bucket 0. + // Force one sample in bucket 1 and two in bucket 0. case 2: return 1; default: From cf95056770af860bd99cc7ffd6324d64c7c6d64f Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 7 Jan 2025 13:04:06 -0600 Subject: [PATCH 742/901] fix(deps): update dependency com.squareup.wire:wire-bom to v5.2.1 (#6996) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- buildSrc/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts index e353de7c702..7345320dbd3 100644 --- a/buildSrc/build.gradle.kts +++ b/buildSrc/build.gradle.kts @@ -50,7 +50,7 @@ repositories { } dependencies { - implementation(enforcedPlatform("com.squareup.wire:wire-bom:5.2.0")) + implementation(enforcedPlatform("com.squareup.wire:wire-bom:5.2.1")) implementation("com.google.auto.value:auto-value-annotations:1.11.0") // When updating, update above in plugins too implementation("com.diffplug.spotless:spotless-plugin-gradle:7.0.0") From d3e38077e73321ffcd0b996870a8c325a2db5fbf Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 7 Jan 2025 13:04:20 -0600 Subject: [PATCH 743/901] fix(deps): update dependency com.squareup.okio:okio-bom to v3.10.1 (#6997) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- dependencyManagement/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index b9596cfb29e..36073d361f9 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -13,7 +13,7 @@ val DEPENDENCY_BOMS = listOf( "com.google.protobuf:protobuf-bom:4.29.2", "com.linecorp.armeria:armeria-bom:1.31.3", "com.squareup.okhttp3:okhttp-bom:4.12.0", - "com.squareup.okio:okio-bom:3.9.1", // applies to transitive dependencies of okhttp + "com.squareup.okio:okio-bom:3.10.1", // applies to transitive dependencies of okhttp "io.grpc:grpc-bom:1.69.0", "io.netty:netty-bom:4.1.116.Final", "io.zipkin.brave:brave-bom:6.0.3", From 5f90b0352ed91fad01e7c33c0a3b6853d318f029 Mon Sep 17 00:00:00 2001 From: jack-berg <34418638+jack-berg@users.noreply.github.com> Date: Tue, 7 Jan 2025 13:04:44 -0600 Subject: [PATCH 744/901] Fix span setStatus (#6990) --- .../io/opentelemetry/sdk/trace/SdkSpan.java | 18 ++++- .../opentelemetry/sdk/trace/SdkSpanTest.java | 67 ++++++++++++++++--- 2 files changed, 76 insertions(+), 9 deletions(-) diff --git a/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/SdkSpan.java b/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/SdkSpan.java index 59eec41179f..f3821c55540 100644 --- a/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/SdkSpan.java +++ b/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/SdkSpan.java @@ -434,10 +434,26 @@ public ReadWriteSpan setStatus(StatusCode statusCode, @Nullable String descripti if (!isModifiableByCurrentThread()) { logger.log(Level.FINE, "Calling setStatus() on an ended Span."); return this; - } else if (this.status.getStatusCode() == StatusCode.OK) { + } + + // If current status is OK, ignore further attempts to change it + if (this.status.getStatusCode() == StatusCode.OK) { logger.log(Level.FINE, "Calling setStatus() on a Span that is already set to OK."); return this; } + + // Ignore attempts to set status to UNSET + if (statusCode == StatusCode.UNSET) { + logger.log(Level.FINE, "Ignoring call to setStatus() with status UNSET."); + return this; + } + + // Ignore description when status is not ERROR + if (description != null && statusCode != StatusCode.ERROR) { + logger.log(Level.FINE, "Ignoring setStatus() description since status is not ERROR."); + description = null; + } + this.status = StatusData.create(statusCode, description); } return this; diff --git a/sdk/trace/src/test/java/io/opentelemetry/sdk/trace/SdkSpanTest.java b/sdk/trace/src/test/java/io/opentelemetry/sdk/trace/SdkSpanTest.java index 4b44607b1d6..180fd377b0c 100644 --- a/sdk/trace/src/test/java/io/opentelemetry/sdk/trace/SdkSpanTest.java +++ b/sdk/trace/src/test/java/io/opentelemetry/sdk/trace/SdkSpanTest.java @@ -63,11 +63,16 @@ import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicLong; +import java.util.function.Consumer; import java.util.stream.IntStream; +import java.util.stream.Stream; import javax.annotation.Nullable; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; import org.mockito.Mock; import org.mockito.Mockito; import org.mockito.junit.jupiter.MockitoExtension; @@ -1336,15 +1341,61 @@ void onStartOnEndNotRequired() { verify(spanProcessor, never()).onEnd(any()); } - @Test - void setStatusCannotOverrideStatusOK() { + @ParameterizedTest + @MethodSource("setStatusArgs") + void setStatus(Consumer spanConsumer, StatusData expectedSpanData) { SdkSpan testSpan = createTestRootSpan(); - testSpan.setStatus(StatusCode.OK); - assertThat(testSpan.toSpanData().getStatus().getStatusCode()).isEqualTo(StatusCode.OK); - testSpan.setStatus(StatusCode.ERROR); - assertThat(testSpan.toSpanData().getStatus().getStatusCode()).isEqualTo(StatusCode.OK); - testSpan.setStatus(StatusCode.UNSET); - assertThat(testSpan.toSpanData().getStatus().getStatusCode()).isEqualTo(StatusCode.OK); + spanConsumer.accept(testSpan); + assertThat(testSpan.toSpanData().getStatus()).isEqualTo(expectedSpanData); + } + + private static Stream setStatusArgs() { + return Stream.of( + // Default status is UNSET + Arguments.of(spanConsumer(span -> {}), StatusData.unset()), + // Simple cases + Arguments.of(spanConsumer(span -> span.setStatus(StatusCode.OK)), StatusData.ok()), + Arguments.of(spanConsumer(span -> span.setStatus(StatusCode.ERROR)), StatusData.error()), + // UNSET is ignored + Arguments.of( + spanConsumer(span -> span.setStatus(StatusCode.OK).setStatus(StatusCode.UNSET)), + StatusData.ok()), + Arguments.of( + spanConsumer(span -> span.setStatus(StatusCode.ERROR).setStatus(StatusCode.UNSET)), + StatusData.error()), + // Description is ignored unless status is ERROR + Arguments.of( + spanConsumer(span -> span.setStatus(StatusCode.UNSET, "description")), + StatusData.unset()), + Arguments.of( + spanConsumer(span -> span.setStatus(StatusCode.OK, "description")), StatusData.ok()), + Arguments.of( + spanConsumer(span -> span.setStatus(StatusCode.ERROR, "description")), + StatusData.create(StatusCode.ERROR, "description")), + // ERROR is ignored if status is OK + Arguments.of( + spanConsumer( + span -> span.setStatus(StatusCode.OK).setStatus(StatusCode.ERROR, "description")), + StatusData.ok()), + // setStatus ignored after span is ended + Arguments.of( + spanConsumer( + span -> { + span.end(); + span.setStatus(StatusCode.OK); + }), + StatusData.unset()), + Arguments.of( + spanConsumer( + span -> { + span.end(); + span.setStatus(StatusCode.ERROR); + }), + StatusData.unset())); + } + + private static Consumer spanConsumer(Consumer spanConsumer) { + return spanConsumer; } private SdkSpan createTestSpanWithAttributes(Map attributes) { From 6f8d4915b90c0d17d5fe2cd812d5bc086d49b161 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 7 Jan 2025 13:33:05 -0600 Subject: [PATCH 745/901] fix(deps): update spotless packages to v7.0.1 (#6998) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- buildSrc/build.gradle.kts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts index 7345320dbd3..df259de52f6 100644 --- a/buildSrc/build.gradle.kts +++ b/buildSrc/build.gradle.kts @@ -2,7 +2,7 @@ plugins { `kotlin-dsl` // When updating, update below in dependencies too - id("com.diffplug.spotless") version "7.0.0" + id("com.diffplug.spotless") version "7.0.1" } if (!hasLauncherForJavaVersion(17)) { @@ -53,7 +53,7 @@ dependencies { implementation(enforcedPlatform("com.squareup.wire:wire-bom:5.2.1")) implementation("com.google.auto.value:auto-value-annotations:1.11.0") // When updating, update above in plugins too - implementation("com.diffplug.spotless:spotless-plugin-gradle:7.0.0") + implementation("com.diffplug.spotless:spotless-plugin-gradle:7.0.1") // Needed for japicmp but not automatically brought in for some reason. implementation("com.google.guava:guava:33.4.0-jre") implementation("com.squareup:javapoet:1.13.0") From 330881a1d1849f6b82e439abfc263f97038f4cd9 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 8 Jan 2025 14:20:56 -0600 Subject: [PATCH 746/901] fix(deps): update dependency com.google.api.grpc:proto-google-common-protos to v2.50.1 (#7000) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- dependencyManagement/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index 36073d361f9..64bf205be37 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -60,7 +60,7 @@ val DEPENDENCIES = listOf( "io.prometheus:simpleclient_httpserver:${prometheusClientVersion}", "javax.annotation:javax.annotation-api:1.3.2", "com.github.stefanbirkner:system-rules:1.19.0", - "com.google.api.grpc:proto-google-common-protos:2.50.0", + "com.google.api.grpc:proto-google-common-protos:2.50.1", "com.google.code.findbugs:jsr305:3.0.2", "com.google.guava:guava-beta-checker:1.0", "com.sun.net.httpserver:http:20070405", From 43b38e276ce10c00324f63d6c90a214b7d08c92e Mon Sep 17 00:00:00 2001 From: Jonathan Halliday Date: Fri, 10 Jan 2025 15:32:45 +0000 Subject: [PATCH 747/901] Update profiling exporters for proto 1.5 (#6999) --- dependencyManagement/build.gradle.kts | 2 +- .../internal/data/ImmutableProfileData.java | 8 +++---- .../exporter/otlp/profiles/ProfileData.java | 6 ++--- .../otlp/profiles/ProfileMarshaler.java | 24 +++++++++---------- .../otlp/profiles/SampleMarshaler.java | 19 ++++++--------- .../ProfilesRequestMarshalerTest.java | 2 +- 6 files changed, 28 insertions(+), 33 deletions(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index 64bf205be37..f97c3f58b88 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -72,7 +72,7 @@ val DEPENDENCIES = listOf( "io.jaegertracing:jaeger-client:1.8.1", "io.opentelemetry.contrib:opentelemetry-aws-xray-propagator:1.39.0-alpha", "io.opentelemetry.semconv:opentelemetry-semconv-incubating:1.29.0-alpha", - "io.opentelemetry.proto:opentelemetry-proto:1.4.0-alpha", + "io.opentelemetry.proto:opentelemetry-proto:1.5.0-alpha", "io.opentracing:opentracing-api:0.33.0", "io.opentracing:opentracing-noop:0.33.0", "junit:junit:4.13.2", diff --git a/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/internal/data/ImmutableProfileData.java b/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/internal/data/ImmutableProfileData.java index b44b7f67834..c9b4a642ad3 100644 --- a/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/internal/data/ImmutableProfileData.java +++ b/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/internal/data/ImmutableProfileData.java @@ -56,10 +56,10 @@ public static ProfileData create( long durationNanos, ValueTypeData periodType, long period, - List commentStrindices, + List commentStrIndices, int defaultSampleTypeStringIndex, String profileId, - Attributes attributes, + List attributeIndices, int droppedAttributesCount, String originalPayloadFormat, ByteBuffer originalPayload) { @@ -80,10 +80,10 @@ public static ProfileData create( durationNanos, periodType, period, - commentStrindices, + commentStrIndices, defaultSampleTypeStringIndex, profileId, - attributes, + attributeIndices, droppedAttributesCount, originalPayloadFormat, originalPayload); diff --git a/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/ProfileData.java b/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/ProfileData.java index d6dd8709ed0..d37e901206b 100644 --- a/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/ProfileData.java +++ b/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/ProfileData.java @@ -99,13 +99,13 @@ default byte[] getProfileIdBytes() { } /** - * Returns profile-wide attributes. Attribute keys MUST be unique (it is not allowed to have more - * than one attribute with the same key). + * Returns indexes of profile-wide attributes, referencing to Profile.attribute_table. Attribute + * keys MUST be unique (it is not allowed to have more than one attribute with the same key). * * @see * "https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/common/README.md#attribute" */ - Attributes getAttributes(); + List getAttributeIndices(); /** * Returns the total number of attributes that were recorded on this profile. diff --git a/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/ProfileMarshaler.java b/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/ProfileMarshaler.java index 04ea86c3263..be4215c8b9f 100644 --- a/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/ProfileMarshaler.java +++ b/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/ProfileMarshaler.java @@ -34,7 +34,7 @@ final class ProfileMarshaler extends MarshalerWithSize { private final List comment; private final int defaultSampleType; private final byte[] profileId; - private final KeyValueMarshaler[] attributeMarshalers; + private final List attributeIndices; private final int droppedAttributesCount; private final byte[] originalPayloadFormatUtf8; private final ByteBuffer originalPayload; @@ -50,8 +50,8 @@ static ProfileMarshaler create(ProfileData profileData) { LocationMarshaler.createRepeated(profileData.getLocationTable()); FunctionMarshaler[] functionMarshalers = FunctionMarshaler.createRepeated(profileData.getFunctionTable()); - KeyValueMarshaler[] attributeMarshalers = - KeyValueMarshaler.createForAttributes(profileData.getAttributes()); + KeyValueMarshaler[] attributeTableMarshalers = + KeyValueMarshaler.createForAttributes(profileData.getAttributeTable()); AttributeUnitMarshaler[] attributeUnitsMarshalers = AttributeUnitMarshaler.createRepeated(profileData.getAttributeUnits()); LinkMarshaler[] linkMarshalers = LinkMarshaler.createRepeated(profileData.getLinkTable()); @@ -63,7 +63,7 @@ static ProfileMarshaler create(ProfileData profileData) { } int droppedAttributesCount = - profileData.getTotalAttributeCount() - profileData.getAttributes().size(); + profileData.getTotalAttributeCount() - profileData.getAttributeIndices().size(); return new ProfileMarshaler( sampleTypeMarshalers, @@ -72,7 +72,7 @@ static ProfileMarshaler create(ProfileData profileData) { locationMarshalers, profileData.getLocationIndices(), functionMarshalers, - attributeMarshalers, + attributeTableMarshalers, attributeUnitsMarshalers, linkMarshalers, convertedStrings, @@ -83,7 +83,7 @@ static ProfileMarshaler create(ProfileData profileData) { profileData.getCommentStrIndices(), profileData.getDefaultSampleTypeStringIndex(), profileData.getProfileIdBytes(), - KeyValueMarshaler.createForAttributes(profileData.getAttributes()), + profileData.getAttributeIndices(), droppedAttributesCount, MarshalerUtil.toBytes(profileData.getOriginalPayloadFormat()), profileData.getOriginalPayload()); @@ -107,7 +107,7 @@ private ProfileMarshaler( List comment, int defaultSampleType, byte[] profileId, - KeyValueMarshaler[] attributeMarshalers, + List attributeIndices, int droppedAttributesCount, byte[] originalPayloadFormat, ByteBuffer originalPayload) { @@ -130,7 +130,7 @@ private ProfileMarshaler( comment, defaultSampleType, profileId, - attributeMarshalers, + attributeIndices, droppedAttributesCount, originalPayloadFormat, originalPayload)); @@ -151,7 +151,7 @@ private ProfileMarshaler( this.comment = comment; this.defaultSampleType = defaultSampleType; this.profileId = profileId; - this.attributeMarshalers = attributeMarshalers; + this.attributeIndices = attributeIndices; this.droppedAttributesCount = droppedAttributesCount; this.originalPayloadFormatUtf8 = originalPayloadFormat; this.originalPayload = originalPayload; @@ -177,7 +177,7 @@ protected void writeTo(Serializer output) throws IOException { output.serializeInt32(Profile.DEFAULT_SAMPLE_TYPE_STRINDEX, defaultSampleType); output.serializeBytes(Profile.PROFILE_ID, profileId); - output.serializeRepeatedMessage(Profile.ATTRIBUTES, attributeMarshalers); + output.serializeRepeatedInt32(Profile.ATTRIBUTE_INDICES, attributeIndices); output.serializeUInt32(Profile.DROPPED_ATTRIBUTES_COUNT, droppedAttributesCount); output.serializeString(Profile.ORIGINAL_PAYLOAD_FORMAT, originalPayloadFormatUtf8); output.serializeByteBuffer(Profile.ORIGINAL_PAYLOAD, originalPayload); @@ -201,7 +201,7 @@ private static int calculateSize( List comment, int defaultSampleType, byte[] profileId, - KeyValueMarshaler[] attributeMarshalers, + List attributeIndices, int droppedAttributesCount, byte[] originalPayloadFormat, ByteBuffer originalPayload) { @@ -225,7 +225,7 @@ private static int calculateSize( size += MarshalerUtil.sizeInt64(Profile.DEFAULT_SAMPLE_TYPE_STRINDEX, defaultSampleType); size += MarshalerUtil.sizeBytes(Profile.PROFILE_ID, profileId); - size += MarshalerUtil.sizeRepeatedMessage(Profile.ATTRIBUTES, attributeMarshalers); + size += MarshalerUtil.sizeRepeatedInt32(Profile.ATTRIBUTE_INDICES, attributeIndices); size += MarshalerUtil.sizeInt32(Profile.DROPPED_ATTRIBUTES_COUNT, droppedAttributesCount); size += MarshalerUtil.sizeBytes(Profile.ORIGINAL_PAYLOAD_FORMAT, originalPayloadFormat); size += MarshalerUtil.sizeByteBuffer(Profile.ORIGINAL_PAYLOAD, originalPayload); diff --git a/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/SampleMarshaler.java b/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/SampleMarshaler.java index d6bb2c31c94..5a1517ccf06 100644 --- a/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/SampleMarshaler.java +++ b/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/SampleMarshaler.java @@ -21,7 +21,7 @@ final class SampleMarshaler extends MarshalerWithSize { private final int locationsStartIndex; private final int locationsLength; private final List values; - private final List attributesIndices; + private final List attributeIndices; @Nullable private final Integer linkIndex; private final List timestamps; @@ -59,21 +59,16 @@ private SampleMarshaler( int locationsStartIndex, int locationsLength, List values, - List attributesIndices, + List attributeIndices, @Nullable Integer linkIndex, List timestamps) { super( calculateSize( - locationsStartIndex, - locationsLength, - values, - attributesIndices, - linkIndex, - timestamps)); + locationsStartIndex, locationsLength, values, attributeIndices, linkIndex, timestamps)); this.locationsStartIndex = locationsStartIndex; this.locationsLength = locationsLength; this.values = values; - this.attributesIndices = attributesIndices; + this.attributeIndices = attributeIndices; this.linkIndex = linkIndex; this.timestamps = timestamps; } @@ -83,7 +78,7 @@ protected void writeTo(Serializer output) throws IOException { output.serializeInt32(Sample.LOCATIONS_START_INDEX, locationsStartIndex); output.serializeInt32(Sample.LOCATIONS_LENGTH, locationsLength); output.serializeRepeatedInt64(Sample.VALUE, values); - output.serializeRepeatedInt32(Sample.ATTRIBUTE_INDICES, attributesIndices); + output.serializeRepeatedInt32(Sample.ATTRIBUTE_INDICES, attributeIndices); output.serializeInt32Optional(Sample.LINK_INDEX, linkIndex); output.serializeRepeatedUInt64(Sample.TIMESTAMPS_UNIX_NANO, timestamps); } @@ -92,7 +87,7 @@ private static int calculateSize( int locationsStartIndex, int locationsLength, List values, - List attributesIndices, + List attributeIndices, @Nullable Integer linkIndex, List timestamps) { int size; @@ -100,7 +95,7 @@ private static int calculateSize( size += MarshalerUtil.sizeInt32(Sample.LOCATIONS_START_INDEX, locationsStartIndex); size += MarshalerUtil.sizeInt32(Sample.LOCATIONS_LENGTH, locationsLength); size += MarshalerUtil.sizeRepeatedInt64(Sample.VALUE, values); - size += MarshalerUtil.sizeRepeatedInt32(Sample.ATTRIBUTE_INDICES, attributesIndices); + size += MarshalerUtil.sizeRepeatedInt32(Sample.ATTRIBUTE_INDICES, attributeIndices); size += MarshalerUtil.sizeInt32Optional(Sample.LINK_INDEX, linkIndex); size += MarshalerUtil.sizeRepeatedUInt64(Sample.TIMESTAMPS_UNIX_NANO, timestamps); return size; diff --git a/exporters/otlp/profiles/src/test/java/io/opentelemetry/exporter/otlp/profiles/ProfilesRequestMarshalerTest.java b/exporters/otlp/profiles/src/test/java/io/opentelemetry/exporter/otlp/profiles/ProfilesRequestMarshalerTest.java index 1046caeb557..c7c2deec381 100644 --- a/exporters/otlp/profiles/src/test/java/io/opentelemetry/exporter/otlp/profiles/ProfilesRequestMarshalerTest.java +++ b/exporters/otlp/profiles/src/test/java/io/opentelemetry/exporter/otlp/profiles/ProfilesRequestMarshalerTest.java @@ -162,7 +162,7 @@ void compareResourceProfilesMarshaling() { listOf(8, 9), 0, profileId, - Attributes.empty(), + Collections.emptyList(), 3, "format", ByteBuffer.wrap(new byte[] {4, 5})); From ccb6346e32ab5fb01e56da87cb9263b1805612b9 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 10 Jan 2025 09:38:29 -0600 Subject: [PATCH 748/901] fix(deps): update dependency nl.jqno.equalsverifier:equalsverifier to v3.18.1 (#7005) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- dependencyManagement/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index f97c3f58b88..1c36a351435 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -76,7 +76,7 @@ val DEPENDENCIES = listOf( "io.opentracing:opentracing-api:0.33.0", "io.opentracing:opentracing-noop:0.33.0", "junit:junit:4.13.2", - "nl.jqno.equalsverifier:equalsverifier:3.18", + "nl.jqno.equalsverifier:equalsverifier:3.18.1", "org.awaitility:awaitility:4.2.2", "org.bouncycastle:bcpkix-jdk15on:1.70", "org.codehaus.mojo:animal-sniffer-annotations:1.24", From d74e277ecbb06274ed2266f350b5e186637ca2c8 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 10 Jan 2025 09:38:42 -0600 Subject: [PATCH 749/901] fix(deps): update dependency com.squareup.okio:okio-bom to v3.10.2 (#7001) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- dependencyManagement/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index 1c36a351435..f0bcdac3116 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -13,7 +13,7 @@ val DEPENDENCY_BOMS = listOf( "com.google.protobuf:protobuf-bom:4.29.2", "com.linecorp.armeria:armeria-bom:1.31.3", "com.squareup.okhttp3:okhttp-bom:4.12.0", - "com.squareup.okio:okio-bom:3.10.1", // applies to transitive dependencies of okhttp + "com.squareup.okio:okio-bom:3.10.2", // applies to transitive dependencies of okhttp "io.grpc:grpc-bom:1.69.0", "io.netty:netty-bom:4.1.116.Final", "io.zipkin.brave:brave-bom:6.0.3", From 2e0b315ce66b0f6f24253b902050c6ebd0176e49 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 10 Jan 2025 09:47:05 -0600 Subject: [PATCH 750/901] fix(deps): update dependency com.google.protobuf:protobuf-bom to v4.29.3 (#7003) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- dependencyManagement/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index f0bcdac3116..6d4ffa90d17 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -10,7 +10,7 @@ rootProject.extra["versions"] = dependencyVersions val DEPENDENCY_BOMS = listOf( "com.fasterxml.jackson:jackson-bom:2.18.2", "com.google.guava:guava-bom:33.4.0-jre", - "com.google.protobuf:protobuf-bom:4.29.2", + "com.google.protobuf:protobuf-bom:4.29.3", "com.linecorp.armeria:armeria-bom:1.31.3", "com.squareup.okhttp3:okhttp-bom:4.12.0", "com.squareup.okio:okio-bom:3.10.2", // applies to transitive dependencies of okhttp From 0920d11aeca99af46e05bc82ec98582ed883ca1a Mon Sep 17 00:00:00 2001 From: jack-berg <34418638+jack-berg@users.noreply.github.com> Date: Fri, 10 Jan 2025 10:41:51 -0600 Subject: [PATCH 751/901] Prepare 1.46.0 (#7007) --- CHANGELOG.md | 33 ++++++++++++ .../sdk/logs/ReadWriteLogRecord.java | 54 +++++++++++++++---- 2 files changed, 77 insertions(+), 10 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 561033dfa81..a442a129c57 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,39 @@ ## Unreleased +### SDK + +* Remove unused dependencies, cleanup code after stabilizing Value + ([#6948](https://github.com/open-telemetry/opentelemetry-java/pull/6948)) +* Explicitly allow null into CompletableResultCode.failExceptionally() + ([#6963](https://github.com/open-telemetry/opentelemetry-java/pull/6963)) + +#### Traces + +* Fix span setStatus + ([#6990](https://github.com/open-telemetry/opentelemetry-java/pull/6990)) + +#### Logs + +* Add getters/accessors for readable fields in ReadWriteLogRecord. + ([#6924](https://github.com/open-telemetry/opentelemetry-java/pull/6924)) + +#### Exporters + +* OTLP: Update to opentelemetry-proto 1.5 + ([#6999](https://github.com/open-telemetry/opentelemetry-java/pull/6999)) +* Bugfix - OTLP: Ensure Serializer runtime exceptions are rethrown as IOException + ([#6969](https://github.com/open-telemetry/opentelemetry-java/pull/6969)) +* BREAKING - OTLP: Delete experimental OTLP authenticator concept. + See [OTLP authentication docs](https://opentelemetry.io/docs/languages/java/sdk/#authentication) + for supported solutions. + ([#6984](https://github.com/open-telemetry/opentelemetry-java/pull/6984)) + +#### Extensions + +* BREAKING - Autoconfigure: Remove support for deprecated otel.experimental.resource.disabled.keys + ([#6931](https://github.com/open-telemetry/opentelemetry-java/pull/6931)) + ## Version 1.45.0 (2024-12-06) ### API diff --git a/sdk/logs/src/main/java/io/opentelemetry/sdk/logs/ReadWriteLogRecord.java b/sdk/logs/src/main/java/io/opentelemetry/sdk/logs/ReadWriteLogRecord.java index 6ad913c1029..03639e31e9f 100644 --- a/sdk/logs/src/main/java/io/opentelemetry/sdk/logs/ReadWriteLogRecord.java +++ b/sdk/logs/src/main/java/io/opentelemetry/sdk/logs/ReadWriteLogRecord.java @@ -53,52 +53,86 @@ default ReadWriteLogRecord setAllAttributes(Attributes attributes) { LogRecordData toLogRecordData(); /** - * Returns the value of a given attribute if it exists. This is the equivalent of calling - * getAttributes().get(key) + * Returns the value of a given attribute if it exists. This is the equivalent of calling {@code + * getAttributes().get(key)}. + * + * @since 1.46.0 */ @Nullable default T getAttribute(AttributeKey key) { return toLogRecordData().getAttributes().get(key); } - /** Returns the instrumentation scope that generated this log. */ + /** + * Returns the instrumentation scope that generated this log. + * + * @since 1.46.0 + */ default InstrumentationScopeInfo getInstrumentationScopeInfo() { return toLogRecordData().getInstrumentationScopeInfo(); } - /** Returns the timestamp at which the log record occurred, in epoch nanos. */ + /** + * Returns the timestamp at which the log record occurred, in epoch nanos. + * + * @since 1.46.0 + */ default long getTimestampEpochNanos() { return toLogRecordData().getTimestampEpochNanos(); } - /** Returns the timestamp at which the log record was observed, in epoch nanos. */ + /** + * Returns the timestamp at which the log record was observed, in epoch nanos. + * + * @since 1.46.0 + */ default long getObservedTimestampEpochNanos() { return toLogRecordData().getTimestampEpochNanos(); } - /** Return the span context for this log, or {@link SpanContext#getInvalid()} if unset. */ + /** + * Return the span context for this log, or {@link SpanContext#getInvalid()} if unset. + * + * @since 1.46.0 + */ default SpanContext getSpanContext() { return toLogRecordData().getSpanContext(); } - /** Returns the severity for this log, or {@link Severity#UNDEFINED_SEVERITY_NUMBER} if unset. */ + /** + * Returns the severity for this log, or {@link Severity#UNDEFINED_SEVERITY_NUMBER} if unset. + * + * @since 1.46.0 + */ default Severity getSeverity() { return toLogRecordData().getSeverity(); } - /** Returns the severity text for this log, or null if unset. */ + /** + * Returns the severity text for this log, or null if unset. + * + * @since 1.46.0 + */ @Nullable default String getSeverityText() { return toLogRecordData().getSeverityText(); } - /** Returns the {@link Value} representation of the log body, of null if unset. */ + /** + * Returns the {@link Value} representation of the log body, of null if unset. + * + * @since 1.46.0 + */ @Nullable default Value getBodyValue() { return toLogRecordData().getBodyValue(); } - /** Returns the attributes for this log, or {@link Attributes#empty()} if unset. */ + /** + * Returns the attributes for this log, or {@link Attributes#empty()} if unset. + * + * @since 1.46.0 + */ default Attributes getAttributes() { return toLogRecordData().getAttributes(); } From d13fd38df1ef418dac4bf30be6514d7a56e6ba03 Mon Sep 17 00:00:00 2001 From: OpenTelemetry Bot <107717825+opentelemetrybot@users.noreply.github.com> Date: Fri, 10 Jan 2025 11:47:27 -0600 Subject: [PATCH 752/901] Update version to 1.47.0 (#7009) --- CHANGELOG.md | 2 ++ version.gradle.kts | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a442a129c57..69386e397b2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,8 @@ ## Unreleased +## Version 1.46.0 (2025-01-10) + ### SDK * Remove unused dependencies, cleanup code after stabilizing Value diff --git a/version.gradle.kts b/version.gradle.kts index 61fc4af26df..215d9f5a3be 100644 --- a/version.gradle.kts +++ b/version.gradle.kts @@ -1,7 +1,7 @@ val snapshot = true allprojects { - var ver = "1.46.0" + var ver = "1.47.0" val release = findProperty("otel.release") if (release != null) { ver += "-" + release From 492b94f2b0b94bdd8866320cdfc053f063cbc2f8 Mon Sep 17 00:00:00 2001 From: OpenTelemetry Bot <107717825+opentelemetrybot@users.noreply.github.com> Date: Mon, 13 Jan 2025 14:55:23 -0600 Subject: [PATCH 753/901] Post release for version 1.46.0 (#7015) --- README.md | 62 +++++++++---------- .../1.46.0_vs_1.45.0/opentelemetry-api.txt | 2 + .../opentelemetry-context.txt | 2 + .../opentelemetry-exporter-common.txt | 2 + .../opentelemetry-exporter-logging-otlp.txt | 2 + .../opentelemetry-exporter-logging.txt | 2 + .../opentelemetry-exporter-otlp-common.txt | 2 + .../opentelemetry-exporter-otlp.txt | 2 + ...y-exporter-sender-grpc-managed-channel.txt | 2 + .../opentelemetry-exporter-sender-jdk.txt | 2 + .../opentelemetry-exporter-sender-okhttp.txt | 2 + .../opentelemetry-exporter-zipkin.txt | 2 + .../opentelemetry-extension-kotlin.txt | 2 + ...ntelemetry-extension-trace-propagators.txt | 2 + .../opentelemetry-opentracing-shim.txt | 2 + .../opentelemetry-sdk-common.txt | 2 + ...emetry-sdk-extension-autoconfigure-spi.txt | 2 + ...ntelemetry-sdk-extension-autoconfigure.txt | 2 + ...ry-sdk-extension-jaeger-remote-sampler.txt | 2 + .../opentelemetry-sdk-logs.txt | 16 +++++ .../opentelemetry-sdk-metrics.txt | 2 + .../opentelemetry-sdk-testing.txt | 2 + .../opentelemetry-sdk-trace.txt | 2 + .../1.46.0_vs_1.45.0/opentelemetry-sdk.txt | 2 + .../current_vs_latest/opentelemetry-api.txt | 2 +- .../opentelemetry-context.txt | 2 +- .../opentelemetry-exporter-common.txt | 2 +- .../opentelemetry-exporter-logging-otlp.txt | 2 +- .../opentelemetry-exporter-logging.txt | 2 +- .../opentelemetry-exporter-otlp-common.txt | 2 +- .../opentelemetry-exporter-otlp.txt | 2 +- ...y-exporter-sender-grpc-managed-channel.txt | 2 +- .../opentelemetry-exporter-sender-jdk.txt | 2 +- .../opentelemetry-exporter-sender-okhttp.txt | 2 +- .../opentelemetry-exporter-zipkin.txt | 2 +- .../opentelemetry-extension-kotlin.txt | 2 +- ...ntelemetry-extension-trace-propagators.txt | 2 +- .../opentelemetry-opentracing-shim.txt | 2 +- .../opentelemetry-sdk-common.txt | 2 +- ...emetry-sdk-extension-autoconfigure-spi.txt | 2 +- ...ntelemetry-sdk-extension-autoconfigure.txt | 2 +- ...ry-sdk-extension-jaeger-remote-sampler.txt | 2 +- .../opentelemetry-sdk-logs.txt | 18 +----- .../opentelemetry-sdk-metrics.txt | 2 +- .../opentelemetry-sdk-testing.txt | 2 +- .../opentelemetry-sdk-trace.txt | 2 +- .../current_vs_latest/opentelemetry-sdk.txt | 2 +- 47 files changed, 115 insertions(+), 69 deletions(-) create mode 100644 docs/apidiffs/1.46.0_vs_1.45.0/opentelemetry-api.txt create mode 100644 docs/apidiffs/1.46.0_vs_1.45.0/opentelemetry-context.txt create mode 100644 docs/apidiffs/1.46.0_vs_1.45.0/opentelemetry-exporter-common.txt create mode 100644 docs/apidiffs/1.46.0_vs_1.45.0/opentelemetry-exporter-logging-otlp.txt create mode 100644 docs/apidiffs/1.46.0_vs_1.45.0/opentelemetry-exporter-logging.txt create mode 100644 docs/apidiffs/1.46.0_vs_1.45.0/opentelemetry-exporter-otlp-common.txt create mode 100644 docs/apidiffs/1.46.0_vs_1.45.0/opentelemetry-exporter-otlp.txt create mode 100644 docs/apidiffs/1.46.0_vs_1.45.0/opentelemetry-exporter-sender-grpc-managed-channel.txt create mode 100644 docs/apidiffs/1.46.0_vs_1.45.0/opentelemetry-exporter-sender-jdk.txt create mode 100644 docs/apidiffs/1.46.0_vs_1.45.0/opentelemetry-exporter-sender-okhttp.txt create mode 100644 docs/apidiffs/1.46.0_vs_1.45.0/opentelemetry-exporter-zipkin.txt create mode 100644 docs/apidiffs/1.46.0_vs_1.45.0/opentelemetry-extension-kotlin.txt create mode 100644 docs/apidiffs/1.46.0_vs_1.45.0/opentelemetry-extension-trace-propagators.txt create mode 100644 docs/apidiffs/1.46.0_vs_1.45.0/opentelemetry-opentracing-shim.txt create mode 100644 docs/apidiffs/1.46.0_vs_1.45.0/opentelemetry-sdk-common.txt create mode 100644 docs/apidiffs/1.46.0_vs_1.45.0/opentelemetry-sdk-extension-autoconfigure-spi.txt create mode 100644 docs/apidiffs/1.46.0_vs_1.45.0/opentelemetry-sdk-extension-autoconfigure.txt create mode 100644 docs/apidiffs/1.46.0_vs_1.45.0/opentelemetry-sdk-extension-jaeger-remote-sampler.txt create mode 100644 docs/apidiffs/1.46.0_vs_1.45.0/opentelemetry-sdk-logs.txt create mode 100644 docs/apidiffs/1.46.0_vs_1.45.0/opentelemetry-sdk-metrics.txt create mode 100644 docs/apidiffs/1.46.0_vs_1.45.0/opentelemetry-sdk-testing.txt create mode 100644 docs/apidiffs/1.46.0_vs_1.45.0/opentelemetry-sdk-trace.txt create mode 100644 docs/apidiffs/1.46.0_vs_1.45.0/opentelemetry-sdk.txt diff --git a/README.md b/README.md index 771ad45f407..7706ba81e9d 100644 --- a/README.md +++ b/README.md @@ -54,8 +54,8 @@ A bill of materials (or BOM) helps sync dependency versions of related artifacts | Component | Description | Artifact ID | Version | Javadoc | |----------------------------------------------|----------------------------------------|---------------------------|-------------------------------------------------------------|---------| -| [Bill of Materials (BOM)](./bom) | Bill of materials for stable artifacts | `opentelemetry-bom` | 1.45.0 | N/A | -| [Alpha Bill of Materials (BOM)](./bom-alpha) | Bill of materials for alpha artifacts | `opentelemetry-bom-alpha` | 1.45.0-alpha | N/A | +| [Bill of Materials (BOM)](./bom) | Bill of materials for stable artifacts | `opentelemetry-bom` | 1.46.0 | N/A | +| [Alpha Bill of Materials (BOM)](./bom-alpha) | Bill of materials for alpha artifacts | `opentelemetry-bom-alpha` | 1.46.0-alpha | N/A |

      @@ -65,9 +65,9 @@ The OpenTelemetry API for recording telemetry. | Component | Description | Artifact ID | Version | Javadoc | |-----------------------------------|--------------------------------------------------------------------------------------|-------------------------------|-------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| [API](./api/all) | OpenTelemetry API, including metrics, traces, baggage, context | `opentelemetry-api` | 1.45.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-api.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-api) | -| [API Incubator](./api/incubator) | API incubator, including pass through propagator, and extended tracer, and Event API | `opentelemetry-api-incubator` | 1.45.0-alpha | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-api-incubator.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-api-incubator) | -| [Context API](./context) | OpenTelemetry context API | `opentelemetry-context` | 1.45.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-context.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-context) | +| [API](./api/all) | OpenTelemetry API, including metrics, traces, baggage, context | `opentelemetry-api` | 1.46.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-api.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-api) | +| [API Incubator](./api/incubator) | API incubator, including pass through propagator, and extended tracer, and Event API | `opentelemetry-api-incubator` | 1.46.0-alpha | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-api-incubator.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-api-incubator) | +| [Context API](./context) | OpenTelemetry context API | `opentelemetry-context` | 1.46.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-context.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-context) |
      @@ -77,8 +77,8 @@ Extensions to the OpenTelemetry API. | Component | Description | Artifact ID | Version | Javadoc | |---------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|---------------------------------------------|-------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| [Kotlin Extension](./extensions/kotlin) | Context extension for coroutines | `opentelemetry-extension-kotlin` | 1.45.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-extension-kotlin.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-extension-kotlin) | -| [Trace Propagators Extension](./extensions/trace-propagators) | Trace propagators, including B3, Jaeger, OT Trace | `opentelemetry-extension-trace-propagators` | 1.45.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-extension-trace-propagators.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-extension-trace-propagators) | +| [Kotlin Extension](./extensions/kotlin) | Context extension for coroutines | `opentelemetry-extension-kotlin` | 1.46.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-extension-kotlin.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-extension-kotlin) | +| [Trace Propagators Extension](./extensions/trace-propagators) | Trace propagators, including B3, Jaeger, OT Trace | `opentelemetry-extension-trace-propagators` | 1.46.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-extension-trace-propagators.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-extension-trace-propagators) |
      @@ -88,12 +88,12 @@ The OpenTelemetry SDK for managing telemetry producing by the API. | Component | Description | Artifact ID | Version | Javadoc | |------------------------------|--------------------------------------------------------|-----------------------------|---------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| [SDK](./sdk/all) | OpenTelemetry SDK, including metrics, traces, and logs | `opentelemetry-sdk` | 1.45.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk) | -| [Metrics SDK](./sdk/metrics) | OpenTelemetry metrics SDK | `opentelemetry-sdk-metrics` | 1.45.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-metrics.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-metrics) | -| [Trace SDK](./sdk/trace) | OpenTelemetry trace SDK | `opentelemetry-sdk-trace` | 1.45.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-trace.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-trace) | -| [Log SDK](./sdk/logs) | OpenTelemetry log SDK | `opentelemetry-sdk-logs` | 1.45.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-logs.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-logs) | -| [SDK Common](./sdk/common) | Shared SDK components | `opentelemetry-sdk-common` | 1.45.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-common.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-common) | -| [SDK Testing](./sdk/testing) | Components for testing OpenTelemetry instrumentation | `opentelemetry-sdk-testing` | 1.45.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-testing.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-testing) | +| [SDK](./sdk/all) | OpenTelemetry SDK, including metrics, traces, and logs | `opentelemetry-sdk` | 1.46.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk) | +| [Metrics SDK](./sdk/metrics) | OpenTelemetry metrics SDK | `opentelemetry-sdk-metrics` | 1.46.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-metrics.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-metrics) | +| [Trace SDK](./sdk/trace) | OpenTelemetry trace SDK | `opentelemetry-sdk-trace` | 1.46.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-trace.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-trace) | +| [Log SDK](./sdk/logs) | OpenTelemetry log SDK | `opentelemetry-sdk-logs` | 1.46.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-logs.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-logs) | +| [SDK Common](./sdk/common) | Shared SDK components | `opentelemetry-sdk-common` | 1.46.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-common.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-common) | +| [SDK Testing](./sdk/testing) | Components for testing OpenTelemetry instrumentation | `opentelemetry-sdk-testing` | 1.46.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-testing.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-testing) |
      @@ -103,16 +103,16 @@ SDK exporters for shipping traces, metrics, and logs out of process. | Component | Description | Artifact ID | Version | Javadoc | |-----------------------------------------------------------------------|------------------------------------------------------------------------------|------------------------------------------------------|-------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| [OTLP Exporters](./exporters/otlp/all) | OTLP gRPC & HTTP exporters, including traces, metrics, and logs | `opentelemetry-exporter-otlp` | 1.45.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-otlp.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-otlp) | -| [OTLP Logging Exporters](./exporters/logging-otlp) | Logging exporters in OTLP JSON encoding, including traces, metrics, and logs | `opentelemetry-exporter-logging-otlp` | 1.45.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-logging-otlp.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-logging-otlp) | -| [OTLP Common](./exporters/otlp/common) | Shared OTLP components (internal) | `opentelemetry-exporter-otlp-common` | 1.45.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-otlp-common.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-otlp-common) | -| [Logging Exporter](./exporters/logging) | Logging exporters, including metrics, traces, and logs | `opentelemetry-exporter-logging` | 1.45.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-logging.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-logging) | -| [Zipkin Exporter](./exporters/zipkin) | Zipkin trace exporter | `opentelemetry-exporter-zipkin` | 1.45.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-zipkin.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-zipkin) | -| [Prometheus Exporter](./exporters/prometheus) | Prometheus metric exporter | `opentelemetry-exporter-prometheus` | 1.45.0-alpha | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-prometheus.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-prometheus) | -| [Exporter Common](./exporters/common) | Shared exporter components (internal) | `opentelemetry-exporter-common` | 1.45.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-common.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-common) | -| [OkHttp Sender](./exporters/sender/okhttp) | OkHttp implementation of HttpSender (internal) | `opentelemetry-exporter-sender-okhttp` | 1.45.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-sender-okhttp.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-sender-okhttp) | -| [JDK Sender](./exporters/sender/jdk) | Java 11+ native HttpClient implementation of HttpSender (internal) | `opentelemetry-exporter-sender-jdk` | 1.45.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-sender-jdk.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-sender-jdk) | | -| [gRPC ManagedChannel Sender](./exporters/sender/grpc-managed-channel) | gRPC ManagedChannel implementation of GrpcSender (internal) | `opentelemetry-exporter-sender-grpc-managed-channel` | 1.45.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-sender-grpc-managed-channel.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-sender-grpc-managed-channel) | | +| [OTLP Exporters](./exporters/otlp/all) | OTLP gRPC & HTTP exporters, including traces, metrics, and logs | `opentelemetry-exporter-otlp` | 1.46.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-otlp.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-otlp) | +| [OTLP Logging Exporters](./exporters/logging-otlp) | Logging exporters in OTLP JSON encoding, including traces, metrics, and logs | `opentelemetry-exporter-logging-otlp` | 1.46.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-logging-otlp.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-logging-otlp) | +| [OTLP Common](./exporters/otlp/common) | Shared OTLP components (internal) | `opentelemetry-exporter-otlp-common` | 1.46.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-otlp-common.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-otlp-common) | +| [Logging Exporter](./exporters/logging) | Logging exporters, including metrics, traces, and logs | `opentelemetry-exporter-logging` | 1.46.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-logging.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-logging) | +| [Zipkin Exporter](./exporters/zipkin) | Zipkin trace exporter | `opentelemetry-exporter-zipkin` | 1.46.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-zipkin.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-zipkin) | +| [Prometheus Exporter](./exporters/prometheus) | Prometheus metric exporter | `opentelemetry-exporter-prometheus` | 1.46.0-alpha | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-prometheus.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-prometheus) | +| [Exporter Common](./exporters/common) | Shared exporter components (internal) | `opentelemetry-exporter-common` | 1.46.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-common.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-common) | +| [OkHttp Sender](./exporters/sender/okhttp) | OkHttp implementation of HttpSender (internal) | `opentelemetry-exporter-sender-okhttp` | 1.46.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-sender-okhttp.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-sender-okhttp) | +| [JDK Sender](./exporters/sender/jdk) | Java 11+ native HttpClient implementation of HttpSender (internal) | `opentelemetry-exporter-sender-jdk` | 1.46.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-sender-jdk.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-sender-jdk) | | +| [gRPC ManagedChannel Sender](./exporters/sender/grpc-managed-channel) | gRPC ManagedChannel implementation of GrpcSender (internal) | `opentelemetry-exporter-sender-grpc-managed-channel` | 1.46.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-sender-grpc-managed-channel.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-sender-grpc-managed-channel) | |
      @@ -122,10 +122,10 @@ Extensions to the OpenTelemetry SDK. | Component | Description | Artifact ID | Version | Javadoc | |-------------------------------------------------------------------------------|------------------------------------------------------------------------------------|-----------------------------------------------------|-------------------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| [SDK Autoconfigure](./sdk-extensions/autoconfigure) | Autoconfigure OpenTelemetry SDK from env vars, system properties, and SPI | `opentelemetry-sdk-extension-autoconfigure` | 1.45.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-extension-autoconfigure.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-extension-autoconfigure) | -| [SDK Autoconfigure SPI](./sdk-extensions/autoconfigure-spi) | Service Provider Interface (SPI) definitions for autoconfigure | `opentelemetry-sdk-extension-autoconfigure-spi` | 1.45.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-extension-autoconfigure-spi.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-extension-autoconfigure-spi) | -| [SDK Jaeger Remote Sampler Extension](./sdk-extensions/jaeger-remote-sampler) | Sampler which obtains sampling configuration from remote Jaeger server | `opentelemetry-sdk-extension-jaeger-remote-sampler` | 1.45.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-extension-jaeger-remote-sampler.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-extension-jaeger-remote-sampler) | -| [SDK Incubator](./sdk-extensions/incubator) | SDK incubator, including YAML based view configuration, LeakDetectingSpanProcessor | `opentelemetry-sdk-extension-incubator` | 1.45.0-alpha | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-extension-incubator.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-extension-incubator) | +| [SDK Autoconfigure](./sdk-extensions/autoconfigure) | Autoconfigure OpenTelemetry SDK from env vars, system properties, and SPI | `opentelemetry-sdk-extension-autoconfigure` | 1.46.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-extension-autoconfigure.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-extension-autoconfigure) | +| [SDK Autoconfigure SPI](./sdk-extensions/autoconfigure-spi) | Service Provider Interface (SPI) definitions for autoconfigure | `opentelemetry-sdk-extension-autoconfigure-spi` | 1.46.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-extension-autoconfigure-spi.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-extension-autoconfigure-spi) | +| [SDK Jaeger Remote Sampler Extension](./sdk-extensions/jaeger-remote-sampler) | Sampler which obtains sampling configuration from remote Jaeger server | `opentelemetry-sdk-extension-jaeger-remote-sampler` | 1.46.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-extension-jaeger-remote-sampler.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-extension-jaeger-remote-sampler) | +| [SDK Incubator](./sdk-extensions/incubator) | SDK incubator, including YAML based view configuration, LeakDetectingSpanProcessor | `opentelemetry-sdk-extension-incubator` | 1.46.0-alpha | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-extension-incubator.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-extension-incubator) |
      @@ -135,8 +135,8 @@ Shims for bridging data from one observability library to another. | Component | Description | Artifact ID | Version | Javadoc | |----------------------------------------|--------------------------------------------------------------|----------------------------------|-------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| [OpenCensus Shim](./opencensus-shim) | Bridge opencensus metrics into the OpenTelemetry metrics SDK | `opentelemetry-opencensus-shim` | 1.45.0-alpha | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-opencensus-shim.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-opencensus-shim) | -| [OpenTracing Shim](./opentracing-shim) | Bridge opentracing spans into the OpenTelemetry trace API | `opentelemetry-opentracing-shim` | 1.45.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-opentracing-shim.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-opentracing-shim) | +| [OpenCensus Shim](./opencensus-shim) | Bridge opencensus metrics into the OpenTelemetry metrics SDK | `opentelemetry-opencensus-shim` | 1.46.0-alpha | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-opencensus-shim.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-opencensus-shim) | +| [OpenTracing Shim](./opentracing-shim) | Bridge opentracing spans into the OpenTelemetry trace API | `opentelemetry-opentracing-shim` | 1.46.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-opentracing-shim.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-opentracing-shim) |
      ## Dependencies @@ -177,7 +177,7 @@ repositories { } dependencies { - implementation platform("io.opentelemetry:opentelemetry-bom:1.46.0-SNAPSHOT") + implementation platform("io.opentelemetry:opentelemetry-bom:1.47.0-SNAPSHOT") implementation('io.opentelemetry:opentelemetry-api') } ``` @@ -199,7 +199,7 @@ dependencies { io.opentelemetry opentelemetry-bom - 1.46.0-SNAPSHOT + 1.47.0-SNAPSHOT pom import diff --git a/docs/apidiffs/1.46.0_vs_1.45.0/opentelemetry-api.txt b/docs/apidiffs/1.46.0_vs_1.45.0/opentelemetry-api.txt new file mode 100644 index 00000000000..7a52ca19294 --- /dev/null +++ b/docs/apidiffs/1.46.0_vs_1.45.0/opentelemetry-api.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of opentelemetry-api-1.46.0.jar against opentelemetry-api-1.45.0.jar +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.46.0_vs_1.45.0/opentelemetry-context.txt b/docs/apidiffs/1.46.0_vs_1.45.0/opentelemetry-context.txt new file mode 100644 index 00000000000..e92b7d7e324 --- /dev/null +++ b/docs/apidiffs/1.46.0_vs_1.45.0/opentelemetry-context.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of opentelemetry-context-1.46.0.jar against opentelemetry-context-1.45.0.jar +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.46.0_vs_1.45.0/opentelemetry-exporter-common.txt b/docs/apidiffs/1.46.0_vs_1.45.0/opentelemetry-exporter-common.txt new file mode 100644 index 00000000000..81783a03446 --- /dev/null +++ b/docs/apidiffs/1.46.0_vs_1.45.0/opentelemetry-exporter-common.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of opentelemetry-exporter-common-1.46.0.jar against opentelemetry-exporter-common-1.45.0.jar +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.46.0_vs_1.45.0/opentelemetry-exporter-logging-otlp.txt b/docs/apidiffs/1.46.0_vs_1.45.0/opentelemetry-exporter-logging-otlp.txt new file mode 100644 index 00000000000..df84177a6df --- /dev/null +++ b/docs/apidiffs/1.46.0_vs_1.45.0/opentelemetry-exporter-logging-otlp.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of opentelemetry-exporter-logging-otlp-1.46.0.jar against opentelemetry-exporter-logging-otlp-1.45.0.jar +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.46.0_vs_1.45.0/opentelemetry-exporter-logging.txt b/docs/apidiffs/1.46.0_vs_1.45.0/opentelemetry-exporter-logging.txt new file mode 100644 index 00000000000..58252a79e9f --- /dev/null +++ b/docs/apidiffs/1.46.0_vs_1.45.0/opentelemetry-exporter-logging.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of opentelemetry-exporter-logging-1.46.0.jar against opentelemetry-exporter-logging-1.45.0.jar +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.46.0_vs_1.45.0/opentelemetry-exporter-otlp-common.txt b/docs/apidiffs/1.46.0_vs_1.45.0/opentelemetry-exporter-otlp-common.txt new file mode 100644 index 00000000000..42f4bf2f0b7 --- /dev/null +++ b/docs/apidiffs/1.46.0_vs_1.45.0/opentelemetry-exporter-otlp-common.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of opentelemetry-exporter-otlp-common-1.46.0.jar against opentelemetry-exporter-otlp-common-1.45.0.jar +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.46.0_vs_1.45.0/opentelemetry-exporter-otlp.txt b/docs/apidiffs/1.46.0_vs_1.45.0/opentelemetry-exporter-otlp.txt new file mode 100644 index 00000000000..91523f25014 --- /dev/null +++ b/docs/apidiffs/1.46.0_vs_1.45.0/opentelemetry-exporter-otlp.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of opentelemetry-exporter-otlp-1.46.0.jar against opentelemetry-exporter-otlp-1.45.0.jar +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.46.0_vs_1.45.0/opentelemetry-exporter-sender-grpc-managed-channel.txt b/docs/apidiffs/1.46.0_vs_1.45.0/opentelemetry-exporter-sender-grpc-managed-channel.txt new file mode 100644 index 00000000000..18e90db15ab --- /dev/null +++ b/docs/apidiffs/1.46.0_vs_1.45.0/opentelemetry-exporter-sender-grpc-managed-channel.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of opentelemetry-exporter-sender-grpc-managed-channel-1.46.0.jar against opentelemetry-exporter-sender-grpc-managed-channel-1.45.0.jar +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.46.0_vs_1.45.0/opentelemetry-exporter-sender-jdk.txt b/docs/apidiffs/1.46.0_vs_1.45.0/opentelemetry-exporter-sender-jdk.txt new file mode 100644 index 00000000000..02b60f67e05 --- /dev/null +++ b/docs/apidiffs/1.46.0_vs_1.45.0/opentelemetry-exporter-sender-jdk.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of opentelemetry-exporter-sender-jdk-1.46.0.jar against opentelemetry-exporter-sender-jdk-1.45.0.jar +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.46.0_vs_1.45.0/opentelemetry-exporter-sender-okhttp.txt b/docs/apidiffs/1.46.0_vs_1.45.0/opentelemetry-exporter-sender-okhttp.txt new file mode 100644 index 00000000000..6b276e92b7a --- /dev/null +++ b/docs/apidiffs/1.46.0_vs_1.45.0/opentelemetry-exporter-sender-okhttp.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of opentelemetry-exporter-sender-okhttp-1.46.0.jar against opentelemetry-exporter-sender-okhttp-1.45.0.jar +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.46.0_vs_1.45.0/opentelemetry-exporter-zipkin.txt b/docs/apidiffs/1.46.0_vs_1.45.0/opentelemetry-exporter-zipkin.txt new file mode 100644 index 00000000000..5ae6fbf884c --- /dev/null +++ b/docs/apidiffs/1.46.0_vs_1.45.0/opentelemetry-exporter-zipkin.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of opentelemetry-exporter-zipkin-1.46.0.jar against opentelemetry-exporter-zipkin-1.45.0.jar +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.46.0_vs_1.45.0/opentelemetry-extension-kotlin.txt b/docs/apidiffs/1.46.0_vs_1.45.0/opentelemetry-extension-kotlin.txt new file mode 100644 index 00000000000..b19719fe068 --- /dev/null +++ b/docs/apidiffs/1.46.0_vs_1.45.0/opentelemetry-extension-kotlin.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of opentelemetry-extension-kotlin-1.46.0.jar against opentelemetry-extension-kotlin-1.45.0.jar +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.46.0_vs_1.45.0/opentelemetry-extension-trace-propagators.txt b/docs/apidiffs/1.46.0_vs_1.45.0/opentelemetry-extension-trace-propagators.txt new file mode 100644 index 00000000000..45e93a6e2f2 --- /dev/null +++ b/docs/apidiffs/1.46.0_vs_1.45.0/opentelemetry-extension-trace-propagators.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of opentelemetry-extension-trace-propagators-1.46.0.jar against opentelemetry-extension-trace-propagators-1.45.0.jar +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.46.0_vs_1.45.0/opentelemetry-opentracing-shim.txt b/docs/apidiffs/1.46.0_vs_1.45.0/opentelemetry-opentracing-shim.txt new file mode 100644 index 00000000000..69f685420e4 --- /dev/null +++ b/docs/apidiffs/1.46.0_vs_1.45.0/opentelemetry-opentracing-shim.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of opentelemetry-opentracing-shim-1.46.0.jar against opentelemetry-opentracing-shim-1.45.0.jar +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.46.0_vs_1.45.0/opentelemetry-sdk-common.txt b/docs/apidiffs/1.46.0_vs_1.45.0/opentelemetry-sdk-common.txt new file mode 100644 index 00000000000..c9019153006 --- /dev/null +++ b/docs/apidiffs/1.46.0_vs_1.45.0/opentelemetry-sdk-common.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of opentelemetry-sdk-common-1.46.0.jar against opentelemetry-sdk-common-1.45.0.jar +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.46.0_vs_1.45.0/opentelemetry-sdk-extension-autoconfigure-spi.txt b/docs/apidiffs/1.46.0_vs_1.45.0/opentelemetry-sdk-extension-autoconfigure-spi.txt new file mode 100644 index 00000000000..9afe3d165d4 --- /dev/null +++ b/docs/apidiffs/1.46.0_vs_1.45.0/opentelemetry-sdk-extension-autoconfigure-spi.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of opentelemetry-sdk-extension-autoconfigure-spi-1.46.0.jar against opentelemetry-sdk-extension-autoconfigure-spi-1.45.0.jar +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.46.0_vs_1.45.0/opentelemetry-sdk-extension-autoconfigure.txt b/docs/apidiffs/1.46.0_vs_1.45.0/opentelemetry-sdk-extension-autoconfigure.txt new file mode 100644 index 00000000000..ba7aa6c29f7 --- /dev/null +++ b/docs/apidiffs/1.46.0_vs_1.45.0/opentelemetry-sdk-extension-autoconfigure.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of opentelemetry-sdk-extension-autoconfigure-1.46.0.jar against opentelemetry-sdk-extension-autoconfigure-1.45.0.jar +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.46.0_vs_1.45.0/opentelemetry-sdk-extension-jaeger-remote-sampler.txt b/docs/apidiffs/1.46.0_vs_1.45.0/opentelemetry-sdk-extension-jaeger-remote-sampler.txt new file mode 100644 index 00000000000..ca4395b27eb --- /dev/null +++ b/docs/apidiffs/1.46.0_vs_1.45.0/opentelemetry-sdk-extension-jaeger-remote-sampler.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of opentelemetry-sdk-extension-jaeger-remote-sampler-1.46.0.jar against opentelemetry-sdk-extension-jaeger-remote-sampler-1.45.0.jar +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.46.0_vs_1.45.0/opentelemetry-sdk-logs.txt b/docs/apidiffs/1.46.0_vs_1.45.0/opentelemetry-sdk-logs.txt new file mode 100644 index 00000000000..20a7acf6688 --- /dev/null +++ b/docs/apidiffs/1.46.0_vs_1.45.0/opentelemetry-sdk-logs.txt @@ -0,0 +1,16 @@ +Comparing source compatibility of opentelemetry-sdk-logs-1.46.0.jar against opentelemetry-sdk-logs-1.45.0.jar +*** MODIFIED INTERFACE: PUBLIC ABSTRACT io.opentelemetry.sdk.logs.ReadWriteLogRecord (not serializable) + === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 + +++ NEW METHOD: PUBLIC(+) java.lang.Object getAttribute(io.opentelemetry.api.common.AttributeKey) + +++ NEW ANNOTATION: javax.annotation.Nullable + GENERIC TEMPLATES: +++ T:java.lang.Object + +++ NEW METHOD: PUBLIC(+) io.opentelemetry.api.common.Attributes getAttributes() + +++ NEW METHOD: PUBLIC(+) io.opentelemetry.api.common.Value getBodyValue() + +++ NEW ANNOTATION: javax.annotation.Nullable + +++ NEW METHOD: PUBLIC(+) io.opentelemetry.sdk.common.InstrumentationScopeInfo getInstrumentationScopeInfo() + +++ NEW METHOD: PUBLIC(+) long getObservedTimestampEpochNanos() + +++ NEW METHOD: PUBLIC(+) io.opentelemetry.api.logs.Severity getSeverity() + +++ NEW METHOD: PUBLIC(+) java.lang.String getSeverityText() + +++ NEW ANNOTATION: javax.annotation.Nullable + +++ NEW METHOD: PUBLIC(+) io.opentelemetry.api.trace.SpanContext getSpanContext() + +++ NEW METHOD: PUBLIC(+) long getTimestampEpochNanos() diff --git a/docs/apidiffs/1.46.0_vs_1.45.0/opentelemetry-sdk-metrics.txt b/docs/apidiffs/1.46.0_vs_1.45.0/opentelemetry-sdk-metrics.txt new file mode 100644 index 00000000000..471c8ad65a8 --- /dev/null +++ b/docs/apidiffs/1.46.0_vs_1.45.0/opentelemetry-sdk-metrics.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of opentelemetry-sdk-metrics-1.46.0.jar against opentelemetry-sdk-metrics-1.45.0.jar +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.46.0_vs_1.45.0/opentelemetry-sdk-testing.txt b/docs/apidiffs/1.46.0_vs_1.45.0/opentelemetry-sdk-testing.txt new file mode 100644 index 00000000000..549c10ad82a --- /dev/null +++ b/docs/apidiffs/1.46.0_vs_1.45.0/opentelemetry-sdk-testing.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of opentelemetry-sdk-testing-1.46.0.jar against opentelemetry-sdk-testing-1.45.0.jar +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.46.0_vs_1.45.0/opentelemetry-sdk-trace.txt b/docs/apidiffs/1.46.0_vs_1.45.0/opentelemetry-sdk-trace.txt new file mode 100644 index 00000000000..f90c6b4f672 --- /dev/null +++ b/docs/apidiffs/1.46.0_vs_1.45.0/opentelemetry-sdk-trace.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of opentelemetry-sdk-trace-1.46.0.jar against opentelemetry-sdk-trace-1.45.0.jar +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.46.0_vs_1.45.0/opentelemetry-sdk.txt b/docs/apidiffs/1.46.0_vs_1.45.0/opentelemetry-sdk.txt new file mode 100644 index 00000000000..e405062aabf --- /dev/null +++ b/docs/apidiffs/1.46.0_vs_1.45.0/opentelemetry-sdk.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of opentelemetry-sdk-1.46.0.jar against opentelemetry-sdk-1.45.0.jar +No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-api.txt b/docs/apidiffs/current_vs_latest/opentelemetry-api.txt index e557956558f..58b43aee602 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-api.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-api.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of opentelemetry-api-1.46.0-SNAPSHOT.jar against opentelemetry-api-1.45.0.jar +Comparing source compatibility of opentelemetry-api-1.47.0-SNAPSHOT.jar against opentelemetry-api-1.46.0.jar No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-context.txt b/docs/apidiffs/current_vs_latest/opentelemetry-context.txt index e9f4fd71d81..3e2bde1a9e0 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-context.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-context.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of opentelemetry-context-1.46.0-SNAPSHOT.jar against opentelemetry-context-1.45.0.jar +Comparing source compatibility of opentelemetry-context-1.47.0-SNAPSHOT.jar against opentelemetry-context-1.46.0.jar No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-common.txt b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-common.txt index b1838c92c1a..6f7d58ae7e3 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-common.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-common.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of opentelemetry-exporter-common-1.46.0-SNAPSHOT.jar against opentelemetry-exporter-common-1.45.0.jar +Comparing source compatibility of opentelemetry-exporter-common-1.47.0-SNAPSHOT.jar against opentelemetry-exporter-common-1.46.0.jar No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-logging-otlp.txt b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-logging-otlp.txt index f4ee97ae586..7bf18cc7e8b 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-logging-otlp.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-logging-otlp.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of opentelemetry-exporter-logging-otlp-1.46.0-SNAPSHOT.jar against opentelemetry-exporter-logging-otlp-1.45.0.jar +Comparing source compatibility of opentelemetry-exporter-logging-otlp-1.47.0-SNAPSHOT.jar against opentelemetry-exporter-logging-otlp-1.46.0.jar No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-logging.txt b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-logging.txt index ad52df00ff8..c6ab761791a 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-logging.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-logging.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of opentelemetry-exporter-logging-1.46.0-SNAPSHOT.jar against opentelemetry-exporter-logging-1.45.0.jar +Comparing source compatibility of opentelemetry-exporter-logging-1.47.0-SNAPSHOT.jar against opentelemetry-exporter-logging-1.46.0.jar No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-otlp-common.txt b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-otlp-common.txt index 2fc47a297b6..429d75ec41b 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-otlp-common.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-otlp-common.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of opentelemetry-exporter-otlp-common-1.46.0-SNAPSHOT.jar against opentelemetry-exporter-otlp-common-1.45.0.jar +Comparing source compatibility of opentelemetry-exporter-otlp-common-1.47.0-SNAPSHOT.jar against opentelemetry-exporter-otlp-common-1.46.0.jar No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-otlp.txt b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-otlp.txt index 5a2acbb88a6..c56b64745c4 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-otlp.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-otlp.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of opentelemetry-exporter-otlp-1.46.0-SNAPSHOT.jar against opentelemetry-exporter-otlp-1.45.0.jar +Comparing source compatibility of opentelemetry-exporter-otlp-1.47.0-SNAPSHOT.jar against opentelemetry-exporter-otlp-1.46.0.jar No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-sender-grpc-managed-channel.txt b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-sender-grpc-managed-channel.txt index 943b658de9a..f61af313c46 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-sender-grpc-managed-channel.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-sender-grpc-managed-channel.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of opentelemetry-exporter-sender-grpc-managed-channel-1.46.0-SNAPSHOT.jar against opentelemetry-exporter-sender-grpc-managed-channel-1.45.0.jar +Comparing source compatibility of opentelemetry-exporter-sender-grpc-managed-channel-1.47.0-SNAPSHOT.jar against opentelemetry-exporter-sender-grpc-managed-channel-1.46.0.jar No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-sender-jdk.txt b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-sender-jdk.txt index a18ec60fc0c..49be6b8165d 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-sender-jdk.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-sender-jdk.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of opentelemetry-exporter-sender-jdk-1.46.0-SNAPSHOT.jar against opentelemetry-exporter-sender-jdk-1.45.0.jar +Comparing source compatibility of opentelemetry-exporter-sender-jdk-1.47.0-SNAPSHOT.jar against opentelemetry-exporter-sender-jdk-1.46.0.jar No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-sender-okhttp.txt b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-sender-okhttp.txt index 4de0d949877..79e4a63d947 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-sender-okhttp.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-sender-okhttp.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of opentelemetry-exporter-sender-okhttp-1.46.0-SNAPSHOT.jar against opentelemetry-exporter-sender-okhttp-1.45.0.jar +Comparing source compatibility of opentelemetry-exporter-sender-okhttp-1.47.0-SNAPSHOT.jar against opentelemetry-exporter-sender-okhttp-1.46.0.jar No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-zipkin.txt b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-zipkin.txt index 6eee24ad477..5ab882bda63 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-zipkin.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-zipkin.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of opentelemetry-exporter-zipkin-1.46.0-SNAPSHOT.jar against opentelemetry-exporter-zipkin-1.45.0.jar +Comparing source compatibility of opentelemetry-exporter-zipkin-1.47.0-SNAPSHOT.jar against opentelemetry-exporter-zipkin-1.46.0.jar No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-extension-kotlin.txt b/docs/apidiffs/current_vs_latest/opentelemetry-extension-kotlin.txt index da836c4e761..3efd311fda2 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-extension-kotlin.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-extension-kotlin.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of opentelemetry-extension-kotlin-1.46.0-SNAPSHOT.jar against opentelemetry-extension-kotlin-1.45.0.jar +Comparing source compatibility of opentelemetry-extension-kotlin-1.47.0-SNAPSHOT.jar against opentelemetry-extension-kotlin-1.46.0.jar No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-extension-trace-propagators.txt b/docs/apidiffs/current_vs_latest/opentelemetry-extension-trace-propagators.txt index d03771ed7dd..e6caaa018b9 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-extension-trace-propagators.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-extension-trace-propagators.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of opentelemetry-extension-trace-propagators-1.46.0-SNAPSHOT.jar against opentelemetry-extension-trace-propagators-1.45.0.jar +Comparing source compatibility of opentelemetry-extension-trace-propagators-1.47.0-SNAPSHOT.jar against opentelemetry-extension-trace-propagators-1.46.0.jar No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-opentracing-shim.txt b/docs/apidiffs/current_vs_latest/opentelemetry-opentracing-shim.txt index 46f5bdf7e78..320013d7fc6 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-opentracing-shim.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-opentracing-shim.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of opentelemetry-opentracing-shim-1.46.0-SNAPSHOT.jar against opentelemetry-opentracing-shim-1.45.0.jar +Comparing source compatibility of opentelemetry-opentracing-shim-1.47.0-SNAPSHOT.jar against opentelemetry-opentracing-shim-1.46.0.jar No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-common.txt b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-common.txt index 573574f361f..83355f6883d 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-common.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-common.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of opentelemetry-sdk-common-1.46.0-SNAPSHOT.jar against opentelemetry-sdk-common-1.45.0.jar +Comparing source compatibility of opentelemetry-sdk-common-1.47.0-SNAPSHOT.jar against opentelemetry-sdk-common-1.46.0.jar No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-extension-autoconfigure-spi.txt b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-extension-autoconfigure-spi.txt index 5d0125c6605..56525b7393e 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-extension-autoconfigure-spi.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-extension-autoconfigure-spi.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of opentelemetry-sdk-extension-autoconfigure-spi-1.46.0-SNAPSHOT.jar against opentelemetry-sdk-extension-autoconfigure-spi-1.45.0.jar +Comparing source compatibility of opentelemetry-sdk-extension-autoconfigure-spi-1.47.0-SNAPSHOT.jar against opentelemetry-sdk-extension-autoconfigure-spi-1.46.0.jar No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-extension-autoconfigure.txt b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-extension-autoconfigure.txt index f1b7db454cf..4303d8e57e3 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-extension-autoconfigure.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-extension-autoconfigure.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of opentelemetry-sdk-extension-autoconfigure-1.46.0-SNAPSHOT.jar against opentelemetry-sdk-extension-autoconfigure-1.45.0.jar +Comparing source compatibility of opentelemetry-sdk-extension-autoconfigure-1.47.0-SNAPSHOT.jar against opentelemetry-sdk-extension-autoconfigure-1.46.0.jar No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-extension-jaeger-remote-sampler.txt b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-extension-jaeger-remote-sampler.txt index 34e24ebfff6..71b9918c230 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-extension-jaeger-remote-sampler.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-extension-jaeger-remote-sampler.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of opentelemetry-sdk-extension-jaeger-remote-sampler-1.46.0-SNAPSHOT.jar against opentelemetry-sdk-extension-jaeger-remote-sampler-1.45.0.jar +Comparing source compatibility of opentelemetry-sdk-extension-jaeger-remote-sampler-1.47.0-SNAPSHOT.jar against opentelemetry-sdk-extension-jaeger-remote-sampler-1.46.0.jar No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-logs.txt b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-logs.txt index dca61614aaf..aa0ae633c34 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-logs.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-logs.txt @@ -1,16 +1,2 @@ -Comparing source compatibility of opentelemetry-sdk-logs-1.46.0-SNAPSHOT.jar against opentelemetry-sdk-logs-1.45.0.jar -*** MODIFIED INTERFACE: PUBLIC ABSTRACT io.opentelemetry.sdk.logs.ReadWriteLogRecord (not serializable) - === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 - +++ NEW METHOD: PUBLIC(+) java.lang.Object getAttribute(io.opentelemetry.api.common.AttributeKey) - +++ NEW ANNOTATION: javax.annotation.Nullable - GENERIC TEMPLATES: +++ T:java.lang.Object - +++ NEW METHOD: PUBLIC(+) io.opentelemetry.api.common.Attributes getAttributes() - +++ NEW METHOD: PUBLIC(+) io.opentelemetry.api.common.Value getBodyValue() - +++ NEW ANNOTATION: javax.annotation.Nullable - +++ NEW METHOD: PUBLIC(+) io.opentelemetry.sdk.common.InstrumentationScopeInfo getInstrumentationScopeInfo() - +++ NEW METHOD: PUBLIC(+) long getObservedTimestampEpochNanos() - +++ NEW METHOD: PUBLIC(+) io.opentelemetry.api.logs.Severity getSeverity() - +++ NEW METHOD: PUBLIC(+) java.lang.String getSeverityText() - +++ NEW ANNOTATION: javax.annotation.Nullable - +++ NEW METHOD: PUBLIC(+) io.opentelemetry.api.trace.SpanContext getSpanContext() - +++ NEW METHOD: PUBLIC(+) long getTimestampEpochNanos() +Comparing source compatibility of opentelemetry-sdk-logs-1.47.0-SNAPSHOT.jar against opentelemetry-sdk-logs-1.46.0.jar +No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-metrics.txt b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-metrics.txt index 37d013e9fb8..b512a547045 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-metrics.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-metrics.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of opentelemetry-sdk-metrics-1.46.0-SNAPSHOT.jar against opentelemetry-sdk-metrics-1.45.0.jar +Comparing source compatibility of opentelemetry-sdk-metrics-1.47.0-SNAPSHOT.jar against opentelemetry-sdk-metrics-1.46.0.jar No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-testing.txt b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-testing.txt index 705e94ae4c0..07403164be2 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-testing.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-testing.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of opentelemetry-sdk-testing-1.46.0-SNAPSHOT.jar against opentelemetry-sdk-testing-1.45.0.jar +Comparing source compatibility of opentelemetry-sdk-testing-1.47.0-SNAPSHOT.jar against opentelemetry-sdk-testing-1.46.0.jar No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-trace.txt b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-trace.txt index 50cf7470b99..4ce59781d9c 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-trace.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-trace.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of opentelemetry-sdk-trace-1.46.0-SNAPSHOT.jar against opentelemetry-sdk-trace-1.45.0.jar +Comparing source compatibility of opentelemetry-sdk-trace-1.47.0-SNAPSHOT.jar against opentelemetry-sdk-trace-1.46.0.jar No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-sdk.txt b/docs/apidiffs/current_vs_latest/opentelemetry-sdk.txt index 190ad7d42ad..a9d84bd5ebe 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-sdk.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-sdk.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of opentelemetry-sdk-1.46.0-SNAPSHOT.jar against opentelemetry-sdk-1.45.0.jar +Comparing source compatibility of opentelemetry-sdk-1.47.0-SNAPSHOT.jar against opentelemetry-sdk-1.46.0.jar No changes. \ No newline at end of file From d56bdf57234c5dda9ce89f892cd54a7f6b6a8923 Mon Sep 17 00:00:00 2001 From: jack-berg <34418638+jack-berg@users.noreply.github.com> Date: Mon, 13 Jan 2025 16:01:14 -0600 Subject: [PATCH 754/901] Remove -alpha artifacts from runtime classpath of stable components (#6944) --- .../graal-incubating/build.gradle.kts | 1 + .../graal/IncubatingApiTests.java | 78 +++++++++ sdk-extensions/autoconfigure/build.gradle.kts | 7 +- ...AutoConfiguredOpenTelemetrySdkBuilder.java | 20 ++- .../sdk/autoconfigure/IncubatingUtil.java | 24 +++ .../AutoConfiguredOpenTelemetrySdkTest.java | 8 - ...onfigureGlobalEventLoggerProviderTest.java | 62 +++++++ sdk/logs/build.gradle.kts | 20 ++- .../sdk/logs/ExtendedSdkLogRecordBuilder.java | 85 ++++++++++ .../sdk/logs/ExtendedSdkLogger.java | 29 ++++ .../sdk/logs/IncubatingUtil.java | 31 ++++ .../sdk/logs/SdkLogRecordBuilder.java | 3 +- .../io/opentelemetry/sdk/logs/SdkLogger.java | 34 +++- .../sdk/logs/SdkLoggerProvider.java | 2 +- .../sdk/logs/LoggerConfigTest.java | 0 .../logs/internal/SdkEventBuilderTest.java | 0 .../internal/SdkEventLoggerProviderTest.java | 0 sdk/metrics/build.gradle.kts | 9 +- .../sdk/metrics/ExtendedSdkDoubleCounter.java | 51 ++++++ .../sdk/metrics/ExtendedSdkDoubleGauge.java | 50 ++++++ .../metrics/ExtendedSdkDoubleHistogram.java | 52 ++++++ .../ExtendedSdkDoubleUpDownCounter.java | 53 ++++++ .../sdk/metrics/ExtendedSdkLongCounter.java | 51 ++++++ .../sdk/metrics/ExtendedSdkLongGauge.java | 51 ++++++ .../sdk/metrics/ExtendedSdkLongHistogram.java | 51 ++++++ .../metrics/ExtendedSdkLongUpDownCounter.java | 53 ++++++ .../sdk/metrics/IncubatingUtil.java | 39 +++++ .../sdk/metrics/SdkDoubleCounter.java | 28 +-- .../sdk/metrics/SdkDoubleGauge.java | 29 +--- .../sdk/metrics/SdkDoubleHistogram.java | 27 +-- .../sdk/metrics/SdkDoubleUpDownCounter.java | 29 +--- .../sdk/metrics/SdkLongCounter.java | 28 +-- .../sdk/metrics/SdkLongGauge.java | 30 +--- .../sdk/metrics/SdkLongHistogram.java | 27 +-- .../sdk/metrics/SdkLongUpDownCounter.java | 27 +-- .../opentelemetry/sdk/metrics/SdkMeter.java | 48 ++++-- .../sdk/metrics/AttributesAdviceTest.java | 0 .../sdk/metrics/MeterConfigTest.java | 0 sdk/trace/build.gradle.kts | 20 ++- .../sdk/trace/ExtendedSdkSpanBuilder.java | 159 ++++++++++++++++++ .../sdk/trace/ExtendedSdkTracer.java | 30 ++++ .../sdk/trace/IncubatingUtil.java | 35 ++++ .../sdk/trace/SdkSpanBuilder.java | 89 ++-------- .../io/opentelemetry/sdk/trace/SdkTracer.java | 36 +++- .../sdk/trace/SdkTracerProvider.java | 2 +- .../sdk/trace/TracerConfigTest.java | 0 46 files changed, 1210 insertions(+), 298 deletions(-) create mode 100644 sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/IncubatingUtil.java create mode 100644 sdk-extensions/autoconfigure/src/testIncubating/java/io/opentelemetry/sdk/autoconfigure/AutoconfigureGlobalEventLoggerProviderTest.java create mode 100644 sdk/logs/src/main/java/io/opentelemetry/sdk/logs/ExtendedSdkLogRecordBuilder.java create mode 100644 sdk/logs/src/main/java/io/opentelemetry/sdk/logs/ExtendedSdkLogger.java create mode 100644 sdk/logs/src/main/java/io/opentelemetry/sdk/logs/IncubatingUtil.java rename sdk/logs/src/{test => testIncubating}/java/io/opentelemetry/sdk/logs/LoggerConfigTest.java (100%) rename sdk/logs/src/{test => testIncubating}/java/io/opentelemetry/sdk/logs/internal/SdkEventBuilderTest.java (100%) rename sdk/logs/src/{test => testIncubating}/java/io/opentelemetry/sdk/logs/internal/SdkEventLoggerProviderTest.java (100%) create mode 100644 sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/ExtendedSdkDoubleCounter.java create mode 100644 sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/ExtendedSdkDoubleGauge.java create mode 100644 sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/ExtendedSdkDoubleHistogram.java create mode 100644 sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/ExtendedSdkDoubleUpDownCounter.java create mode 100644 sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/ExtendedSdkLongCounter.java create mode 100644 sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/ExtendedSdkLongGauge.java create mode 100644 sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/ExtendedSdkLongHistogram.java create mode 100644 sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/ExtendedSdkLongUpDownCounter.java create mode 100644 sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/IncubatingUtil.java rename sdk/metrics/src/{test => testIncubating}/java/io/opentelemetry/sdk/metrics/AttributesAdviceTest.java (100%) rename sdk/metrics/src/{test => testIncubating}/java/io/opentelemetry/sdk/metrics/MeterConfigTest.java (100%) create mode 100644 sdk/trace/src/main/java/io/opentelemetry/sdk/trace/ExtendedSdkSpanBuilder.java create mode 100644 sdk/trace/src/main/java/io/opentelemetry/sdk/trace/ExtendedSdkTracer.java create mode 100644 sdk/trace/src/main/java/io/opentelemetry/sdk/trace/IncubatingUtil.java rename sdk/trace/src/{test => testIncubating}/java/io/opentelemetry/sdk/trace/TracerConfigTest.java (100%) diff --git a/integration-tests/graal-incubating/build.gradle.kts b/integration-tests/graal-incubating/build.gradle.kts index d050e01dee8..7ad93ffb947 100644 --- a/integration-tests/graal-incubating/build.gradle.kts +++ b/integration-tests/graal-incubating/build.gradle.kts @@ -18,6 +18,7 @@ sourceSets { dependencies { implementation(project(":sdk:all")) implementation(project(":sdk:trace-shaded-deps")) + implementation(project(":sdk:testing")) implementation(project(":exporters:otlp:all")) implementation(project(":api:incubator")) } diff --git a/integration-tests/graal-incubating/src/test/java/io/opentelemetry/integrationtests/graal/IncubatingApiTests.java b/integration-tests/graal-incubating/src/test/java/io/opentelemetry/integrationtests/graal/IncubatingApiTests.java index 8d705419452..06ddcd006e1 100644 --- a/integration-tests/graal-incubating/src/test/java/io/opentelemetry/integrationtests/graal/IncubatingApiTests.java +++ b/integration-tests/graal-incubating/src/test/java/io/opentelemetry/integrationtests/graal/IncubatingApiTests.java @@ -7,12 +7,31 @@ import static org.assertj.core.api.Assertions.assertThat; +import io.opentelemetry.api.incubator.logs.ExtendedLogRecordBuilder; import io.opentelemetry.api.incubator.logs.ExtendedLogger; +import io.opentelemetry.api.incubator.metrics.ExtendedDoubleCounter; +import io.opentelemetry.api.incubator.metrics.ExtendedDoubleGauge; +import io.opentelemetry.api.incubator.metrics.ExtendedDoubleHistogram; +import io.opentelemetry.api.incubator.metrics.ExtendedDoubleUpDownCounter; +import io.opentelemetry.api.incubator.metrics.ExtendedLongCounter; import io.opentelemetry.api.incubator.metrics.ExtendedLongCounterBuilder; +import io.opentelemetry.api.incubator.metrics.ExtendedLongGauge; +import io.opentelemetry.api.incubator.metrics.ExtendedLongHistogram; +import io.opentelemetry.api.incubator.metrics.ExtendedLongUpDownCounter; +import io.opentelemetry.api.incubator.trace.ExtendedSpanBuilder; import io.opentelemetry.api.incubator.trace.ExtendedTracer; import io.opentelemetry.api.logs.LoggerProvider; +import io.opentelemetry.api.metrics.Meter; import io.opentelemetry.api.metrics.MeterProvider; import io.opentelemetry.api.trace.TracerProvider; +import io.opentelemetry.sdk.logs.SdkLoggerProvider; +import io.opentelemetry.sdk.logs.export.SimpleLogRecordProcessor; +import io.opentelemetry.sdk.metrics.SdkMeterProvider; +import io.opentelemetry.sdk.testing.exporter.InMemoryLogRecordExporter; +import io.opentelemetry.sdk.testing.exporter.InMemoryMetricReader; +import io.opentelemetry.sdk.testing.exporter.InMemorySpanExporter; +import io.opentelemetry.sdk.trace.SdkTracerProvider; +import io.opentelemetry.sdk.trace.export.SimpleSpanProcessor; import org.junit.jupiter.api.Test; class IncubatingApiTests { @@ -23,4 +42,63 @@ void incubatingApiIsLoadedViaReflection() { assertThat(MeterProvider.noop().get("test").counterBuilder("test")) .isInstanceOf(ExtendedLongCounterBuilder.class); } + + @Test + void incubatingLogSdk() { + InMemoryLogRecordExporter exporter = InMemoryLogRecordExporter.create(); + SdkLoggerProvider loggerProvider = + SdkLoggerProvider.builder() + .addLogRecordProcessor(SimpleLogRecordProcessor.create(exporter)) + .build(); + + ExtendedLogger logger = (ExtendedLogger) loggerProvider.get("logger"); + logger.isEnabled(); + ((ExtendedLogRecordBuilder) logger.logRecordBuilder()).setBody("message").emit(); + } + + @Test + void incubatingTraceSdk() { + InMemorySpanExporter exporter = InMemorySpanExporter.create(); + SdkTracerProvider tracerProvider = + SdkTracerProvider.builder().addSpanProcessor(SimpleSpanProcessor.create(exporter)).build(); + + ExtendedTracer tracer = (ExtendedTracer) tracerProvider.get("tracer"); + tracer.isEnabled(); + ((ExtendedSpanBuilder) tracer.spanBuilder("span")).startAndRun(() -> {}); + } + + @Test + void incubatingMetricSdk() { + InMemoryMetricReader reader = InMemoryMetricReader.create(); + SdkMeterProvider meterProvider = + SdkMeterProvider.builder().registerMetricReader(reader).build(); + + Meter meter = meterProvider.get("meter"); + + ExtendedLongCounter longCounter = + (ExtendedLongCounter) meter.counterBuilder("longCounter").build(); + longCounter.isEnabled(); + ExtendedDoubleCounter doubleCounter = + (ExtendedDoubleCounter) meter.counterBuilder("doubleCounter").ofDoubles().build(); + doubleCounter.isEnabled(); + ExtendedLongUpDownCounter longUpDownCounter = + (ExtendedLongUpDownCounter) meter.upDownCounterBuilder("longUpDownCounter").build(); + longUpDownCounter.isEnabled(); + ExtendedDoubleUpDownCounter doubleUpDownCounter = + (ExtendedDoubleUpDownCounter) + meter.upDownCounterBuilder("doubleUpDownCounter").ofDoubles().build(); + doubleUpDownCounter.isEnabled(); + ExtendedDoubleHistogram doubleHistogram = + (ExtendedDoubleHistogram) meter.histogramBuilder("doubleHistogram").build(); + doubleHistogram.isEnabled(); + ExtendedLongHistogram longHistogram = + (ExtendedLongHistogram) meter.histogramBuilder("longHistogram").ofLongs().build(); + longHistogram.isEnabled(); + ExtendedDoubleGauge doubleGauge = + (ExtendedDoubleGauge) meter.gaugeBuilder("doubleGauge").build(); + doubleGauge.isEnabled(); + ExtendedLongGauge longGauge = + (ExtendedLongGauge) meter.gaugeBuilder("longGauge").ofLongs().build(); + longGauge.isEnabled(); + } } diff --git a/sdk-extensions/autoconfigure/build.gradle.kts b/sdk-extensions/autoconfigure/build.gradle.kts index fb73bdaa6b6..7f0077178e5 100644 --- a/sdk-extensions/autoconfigure/build.gradle.kts +++ b/sdk-extensions/autoconfigure/build.gradle.kts @@ -10,7 +10,7 @@ dependencies { api(project(":sdk:all")) api(project(":sdk-extensions:autoconfigure-spi")) - implementation(project(":api:incubator")) + compileOnly(project(":api:incubator")) annotationProcessor("com.google.auto.value:auto-value") @@ -23,6 +23,11 @@ dependencies { testing { suites { + register("testIncubating") { + dependencies { + implementation(project(":api:incubator")) + } + } register("testAutoConfigureOrder") { targets { all { diff --git a/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/AutoConfiguredOpenTelemetrySdkBuilder.java b/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/AutoConfiguredOpenTelemetrySdkBuilder.java index 1c293a002cd..f6ddd6c6f85 100644 --- a/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/AutoConfiguredOpenTelemetrySdkBuilder.java +++ b/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/AutoConfiguredOpenTelemetrySdkBuilder.java @@ -8,7 +8,6 @@ import static java.util.Objects.requireNonNull; import io.opentelemetry.api.GlobalOpenTelemetry; -import io.opentelemetry.api.incubator.events.GlobalEventLoggerProvider; import io.opentelemetry.context.propagation.ContextPropagators; import io.opentelemetry.context.propagation.TextMapPropagator; import io.opentelemetry.sdk.OpenTelemetrySdk; @@ -26,7 +25,6 @@ import io.opentelemetry.sdk.logs.SdkLoggerProvider; import io.opentelemetry.sdk.logs.SdkLoggerProviderBuilder; import io.opentelemetry.sdk.logs.export.LogRecordExporter; -import io.opentelemetry.sdk.logs.internal.SdkEventLoggerProvider; import io.opentelemetry.sdk.metrics.SdkMeterProvider; import io.opentelemetry.sdk.metrics.SdkMeterProviderBuilder; import io.opentelemetry.sdk.metrics.export.MetricExporter; @@ -65,6 +63,19 @@ */ public final class AutoConfiguredOpenTelemetrySdkBuilder implements AutoConfigurationCustomizer { + private static final boolean INCUBATOR_AVAILABLE; + + static { + boolean incubatorAvailable = false; + try { + Class.forName("io.opentelemetry.api.incubator.events.GlobalEventLoggerProvider"); + incubatorAvailable = true; + } catch (ClassNotFoundException e) { + // Not available + } + INCUBATOR_AVAILABLE = incubatorAvailable; + } + private static final Logger logger = Logger.getLogger(AutoConfiguredOpenTelemetrySdkBuilder.class.getName()); @@ -592,8 +603,9 @@ private void maybeSetAsGlobal(OpenTelemetrySdk openTelemetrySdk) { return; } GlobalOpenTelemetry.set(openTelemetrySdk); - GlobalEventLoggerProvider.set( - SdkEventLoggerProvider.create(openTelemetrySdk.getSdkLoggerProvider())); + if (INCUBATOR_AVAILABLE) { + IncubatingUtil.setGlobalEventLoggerProvider(openTelemetrySdk.getSdkLoggerProvider()); + } logger.log( Level.FINE, "Global OpenTelemetry set to {0} by autoconfiguration", openTelemetrySdk); } diff --git a/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/IncubatingUtil.java b/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/IncubatingUtil.java new file mode 100644 index 00000000000..f66e007cf34 --- /dev/null +++ b/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/IncubatingUtil.java @@ -0,0 +1,24 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.sdk.autoconfigure; + +import io.opentelemetry.api.incubator.events.GlobalEventLoggerProvider; +import io.opentelemetry.sdk.logs.SdkLoggerProvider; +import io.opentelemetry.sdk.logs.internal.SdkEventLoggerProvider; + +/** + * Utilities for interacting with {@code io.opentelemetry:opentelemetry-api-incubator}, which is not + * guaranteed to be present on the classpath. For all methods, callers MUST first separately + * reflectively confirm that the incubator is available on the classpath. + */ +final class IncubatingUtil { + + private IncubatingUtil() {} + + static void setGlobalEventLoggerProvider(SdkLoggerProvider sdkLoggerProvider) { + GlobalEventLoggerProvider.set(SdkEventLoggerProvider.create(sdkLoggerProvider)); + } +} diff --git a/sdk-extensions/autoconfigure/src/test/java/io/opentelemetry/sdk/autoconfigure/AutoConfiguredOpenTelemetrySdkTest.java b/sdk-extensions/autoconfigure/src/test/java/io/opentelemetry/sdk/autoconfigure/AutoConfiguredOpenTelemetrySdkTest.java index f74b248c04d..b42c1936130 100644 --- a/sdk-extensions/autoconfigure/src/test/java/io/opentelemetry/sdk/autoconfigure/AutoConfiguredOpenTelemetrySdkTest.java +++ b/sdk-extensions/autoconfigure/src/test/java/io/opentelemetry/sdk/autoconfigure/AutoConfiguredOpenTelemetrySdkTest.java @@ -26,7 +26,6 @@ import io.github.netmikey.logunit.api.LogCapturer; import io.opentelemetry.api.GlobalOpenTelemetry; import io.opentelemetry.api.OpenTelemetry; -import io.opentelemetry.api.incubator.events.GlobalEventLoggerProvider; import io.opentelemetry.api.trace.Span; import io.opentelemetry.api.trace.SpanId; import io.opentelemetry.api.trace.TraceId; @@ -49,7 +48,6 @@ import io.opentelemetry.sdk.logs.LogRecordProcessor; import io.opentelemetry.sdk.logs.SdkLoggerProvider; import io.opentelemetry.sdk.logs.SdkLoggerProviderBuilder; -import io.opentelemetry.sdk.logs.internal.SdkEventLoggerProvider; import io.opentelemetry.sdk.metrics.SdkMeterProvider; import io.opentelemetry.sdk.metrics.SdkMeterProviderBuilder; import io.opentelemetry.sdk.metrics.export.MetricReader; @@ -156,7 +154,6 @@ public SdkLoggerProviderBuilder apply( @BeforeEach void resetGlobal() { GlobalOpenTelemetry.resetForTest(); - GlobalEventLoggerProvider.resetForTest(); builder = AutoConfiguredOpenTelemetrySdk.builder() .addPropertiesSupplier(disableExportPropertySupplier()); @@ -456,7 +453,6 @@ void builder_setResultAsGlobalFalse() { OpenTelemetrySdk openTelemetry = builder.build().getOpenTelemetrySdk(); assertThat(GlobalOpenTelemetry.get()).extracting("delegate").isNotSameAs(openTelemetry); - assertThat(GlobalEventLoggerProvider.get()).isNotSameAs(openTelemetry.getSdkLoggerProvider()); } @Test @@ -464,10 +460,6 @@ void builder_setResultAsGlobalTrue() { OpenTelemetrySdk openTelemetry = builder.setResultAsGlobal().build().getOpenTelemetrySdk(); assertThat(GlobalOpenTelemetry.get()).extracting("delegate").isSameAs(openTelemetry); - assertThat(GlobalEventLoggerProvider.get()) - .isInstanceOf(SdkEventLoggerProvider.class) - .extracting("delegateLoggerProvider") - .isSameAs(openTelemetry.getSdkLoggerProvider()); } @Test diff --git a/sdk-extensions/autoconfigure/src/testIncubating/java/io/opentelemetry/sdk/autoconfigure/AutoconfigureGlobalEventLoggerProviderTest.java b/sdk-extensions/autoconfigure/src/testIncubating/java/io/opentelemetry/sdk/autoconfigure/AutoconfigureGlobalEventLoggerProviderTest.java new file mode 100644 index 00000000000..8ca85372ada --- /dev/null +++ b/sdk-extensions/autoconfigure/src/testIncubating/java/io/opentelemetry/sdk/autoconfigure/AutoconfigureGlobalEventLoggerProviderTest.java @@ -0,0 +1,62 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.sdk.autoconfigure; + +import static org.assertj.core.api.Assertions.assertThat; + +import io.opentelemetry.api.GlobalOpenTelemetry; +import io.opentelemetry.api.OpenTelemetry; +import io.opentelemetry.api.incubator.events.GlobalEventLoggerProvider; +import io.opentelemetry.sdk.OpenTelemetrySdk; +import io.opentelemetry.sdk.logs.internal.SdkEventLoggerProvider; +import java.util.HashMap; +import java.util.Map; +import java.util.function.Supplier; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +class AutoconfigureGlobalEventLoggerProviderTest { + + private AutoConfiguredOpenTelemetrySdkBuilder builder; + + @BeforeEach + void resetGlobal() { + GlobalOpenTelemetry.resetForTest(); + GlobalEventLoggerProvider.resetForTest(); + builder = + AutoConfiguredOpenTelemetrySdk.builder() + .addPropertiesSupplier(disableExportPropertySupplier()); + } + + @Test + void builder_setResultAsGlobalFalse() { + GlobalOpenTelemetry.set(OpenTelemetry.noop()); + + OpenTelemetrySdk openTelemetry = builder.build().getOpenTelemetrySdk(); + + assertThat(GlobalOpenTelemetry.get()).extracting("delegate").isNotSameAs(openTelemetry); + assertThat(GlobalEventLoggerProvider.get()).isNotSameAs(openTelemetry.getSdkLoggerProvider()); + } + + @Test + void builder_setResultAsGlobalTrue() { + OpenTelemetrySdk openTelemetry = builder.setResultAsGlobal().build().getOpenTelemetrySdk(); + + assertThat(GlobalOpenTelemetry.get()).extracting("delegate").isSameAs(openTelemetry); + assertThat(GlobalEventLoggerProvider.get()) + .isInstanceOf(SdkEventLoggerProvider.class) + .extracting("delegateLoggerProvider") + .isSameAs(openTelemetry.getSdkLoggerProvider()); + } + + private static Supplier> disableExportPropertySupplier() { + Map props = new HashMap<>(); + props.put("otel.metrics.exporter", "none"); + props.put("otel.traces.exporter", "none"); + props.put("otel.logs.exporter", "none"); + return () -> props; + } +} diff --git a/sdk/logs/build.gradle.kts b/sdk/logs/build.gradle.kts index 7c8c020d6a2..c0c740d3743 100644 --- a/sdk/logs/build.gradle.kts +++ b/sdk/logs/build.gradle.kts @@ -12,7 +12,7 @@ otelJava.moduleName.set("io.opentelemetry.sdk.logs") dependencies { api(project(":api:all")) api(project(":sdk:common")) - implementation(project(":api:incubator")) + compileOnly(project(":api:incubator")) annotationProcessor("com.google.auto.value:auto-value") @@ -21,3 +21,21 @@ dependencies { testImplementation("org.awaitility:awaitility") testImplementation("com.google.guava:guava") } + +testing { + suites { + register("testIncubating") { + dependencies { + implementation(project(":sdk:testing")) + implementation(project(":api:incubator")) + implementation("com.google.guava:guava") + } + } + } +} + +tasks { + check { + dependsOn(testing.suites) + } +} diff --git a/sdk/logs/src/main/java/io/opentelemetry/sdk/logs/ExtendedSdkLogRecordBuilder.java b/sdk/logs/src/main/java/io/opentelemetry/sdk/logs/ExtendedSdkLogRecordBuilder.java new file mode 100644 index 00000000000..ba1d0e6cfd2 --- /dev/null +++ b/sdk/logs/src/main/java/io/opentelemetry/sdk/logs/ExtendedSdkLogRecordBuilder.java @@ -0,0 +1,85 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.sdk.logs; + +import io.opentelemetry.api.common.AttributeKey; +import io.opentelemetry.api.common.Value; +import io.opentelemetry.api.incubator.logs.ExtendedLogRecordBuilder; +import io.opentelemetry.api.logs.Severity; +import io.opentelemetry.context.Context; +import io.opentelemetry.sdk.common.InstrumentationScopeInfo; +import java.time.Instant; +import java.util.concurrent.TimeUnit; + +/** SDK implementation of {@link ExtendedLogRecordBuilder}. */ +final class ExtendedSdkLogRecordBuilder extends SdkLogRecordBuilder + implements ExtendedLogRecordBuilder { + + ExtendedSdkLogRecordBuilder( + LoggerSharedState loggerSharedState, InstrumentationScopeInfo instrumentationScopeInfo) { + super(loggerSharedState, instrumentationScopeInfo); + } + + @Override + public ExtendedSdkLogRecordBuilder setTimestamp(long timestamp, TimeUnit unit) { + super.setTimestamp(timestamp, unit); + return this; + } + + @Override + public ExtendedSdkLogRecordBuilder setTimestamp(Instant instant) { + super.setTimestamp(instant); + return this; + } + + @Override + public ExtendedSdkLogRecordBuilder setObservedTimestamp(long timestamp, TimeUnit unit) { + super.setObservedTimestamp(timestamp, unit); + return this; + } + + @Override + public ExtendedSdkLogRecordBuilder setObservedTimestamp(Instant instant) { + super.setObservedTimestamp(instant); + return this; + } + + @Override + public ExtendedSdkLogRecordBuilder setContext(Context context) { + super.setContext(context); + return this; + } + + @Override + public ExtendedSdkLogRecordBuilder setSeverity(Severity severity) { + super.setSeverity(severity); + return this; + } + + @Override + public ExtendedSdkLogRecordBuilder setSeverityText(String severityText) { + super.setSeverityText(severityText); + return this; + } + + @Override + public ExtendedSdkLogRecordBuilder setBody(String body) { + super.setBody(body); + return this; + } + + @Override + public ExtendedSdkLogRecordBuilder setBody(Value value) { + super.setBody(value); + return this; + } + + @Override + public ExtendedSdkLogRecordBuilder setAttribute(AttributeKey key, T value) { + super.setAttribute(key, value); + return this; + } +} diff --git a/sdk/logs/src/main/java/io/opentelemetry/sdk/logs/ExtendedSdkLogger.java b/sdk/logs/src/main/java/io/opentelemetry/sdk/logs/ExtendedSdkLogger.java new file mode 100644 index 00000000000..67813bb933d --- /dev/null +++ b/sdk/logs/src/main/java/io/opentelemetry/sdk/logs/ExtendedSdkLogger.java @@ -0,0 +1,29 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.sdk.logs; + +import io.opentelemetry.api.incubator.logs.ExtendedLogger; +import io.opentelemetry.sdk.common.InstrumentationScopeInfo; +import io.opentelemetry.sdk.logs.internal.LoggerConfig; + +/** SDK implementation of {@link ExtendedLogger}. */ +final class ExtendedSdkLogger extends SdkLogger implements ExtendedLogger { + + private final boolean loggerEnabled; + + ExtendedSdkLogger( + LoggerSharedState loggerSharedState, + InstrumentationScopeInfo instrumentationScopeInfo, + LoggerConfig loggerConfig) { + super(loggerSharedState, instrumentationScopeInfo, loggerConfig); + this.loggerEnabled = loggerConfig.isEnabled(); + } + + @Override + public boolean isEnabled() { + return loggerEnabled; + } +} diff --git a/sdk/logs/src/main/java/io/opentelemetry/sdk/logs/IncubatingUtil.java b/sdk/logs/src/main/java/io/opentelemetry/sdk/logs/IncubatingUtil.java new file mode 100644 index 00000000000..fd7582644be --- /dev/null +++ b/sdk/logs/src/main/java/io/opentelemetry/sdk/logs/IncubatingUtil.java @@ -0,0 +1,31 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.sdk.logs; + +import io.opentelemetry.sdk.common.InstrumentationScopeInfo; +import io.opentelemetry.sdk.logs.internal.LoggerConfig; + +/** + * Utilities for interacting with {@code io.opentelemetry:opentelemetry-api-incubator}, which is not + * guaranteed to be present on the classpath. For all methods, callers MUST first separately + * reflectively confirm that the incubator is available on the classpath. + */ +final class IncubatingUtil { + + private IncubatingUtil() {} + + static SdkLogger createExtendedLogger( + LoggerSharedState sharedState, + InstrumentationScopeInfo instrumentationScopeInfo, + LoggerConfig tracerConfig) { + return new ExtendedSdkLogger(sharedState, instrumentationScopeInfo, tracerConfig); + } + + static SdkLogRecordBuilder createExtendedLogRecordBuilder( + LoggerSharedState loggerSharedState, InstrumentationScopeInfo instrumentationScopeInfo) { + return new ExtendedSdkLogRecordBuilder(loggerSharedState, instrumentationScopeInfo); + } +} diff --git a/sdk/logs/src/main/java/io/opentelemetry/sdk/logs/SdkLogRecordBuilder.java b/sdk/logs/src/main/java/io/opentelemetry/sdk/logs/SdkLogRecordBuilder.java index ce77d076730..ce43bc8d2c6 100644 --- a/sdk/logs/src/main/java/io/opentelemetry/sdk/logs/SdkLogRecordBuilder.java +++ b/sdk/logs/src/main/java/io/opentelemetry/sdk/logs/SdkLogRecordBuilder.java @@ -7,7 +7,6 @@ import io.opentelemetry.api.common.AttributeKey; import io.opentelemetry.api.common.Value; -import io.opentelemetry.api.incubator.logs.ExtendedLogRecordBuilder; import io.opentelemetry.api.logs.LogRecordBuilder; import io.opentelemetry.api.logs.Severity; import io.opentelemetry.api.trace.Span; @@ -19,7 +18,7 @@ import javax.annotation.Nullable; /** SDK implementation of {@link LogRecordBuilder}. */ -final class SdkLogRecordBuilder implements ExtendedLogRecordBuilder { +class SdkLogRecordBuilder implements LogRecordBuilder { private final LoggerSharedState loggerSharedState; private final LogLimits logLimits; diff --git a/sdk/logs/src/main/java/io/opentelemetry/sdk/logs/SdkLogger.java b/sdk/logs/src/main/java/io/opentelemetry/sdk/logs/SdkLogger.java index 72fb9f0b356..8ac51603073 100644 --- a/sdk/logs/src/main/java/io/opentelemetry/sdk/logs/SdkLogger.java +++ b/sdk/logs/src/main/java/io/opentelemetry/sdk/logs/SdkLogger.java @@ -5,7 +5,6 @@ package io.opentelemetry.sdk.logs; -import io.opentelemetry.api.incubator.logs.ExtendedLogger; import io.opentelemetry.api.logs.LogRecordBuilder; import io.opentelemetry.api.logs.Logger; import io.opentelemetry.api.logs.LoggerProvider; @@ -13,9 +12,21 @@ import io.opentelemetry.sdk.logs.internal.LoggerConfig; /** SDK implementation of {@link Logger}. */ -final class SdkLogger implements ExtendedLogger { +class SdkLogger implements Logger { private static final Logger NOOP_LOGGER = LoggerProvider.noop().get("noop"); + private static final boolean INCUBATOR_AVAILABLE; + + static { + boolean incubatorAvailable = false; + try { + Class.forName("io.opentelemetry.api.incubator.logs.ExtendedDefaultLoggerProvider"); + incubatorAvailable = true; + } catch (ClassNotFoundException e) { + // Not available + } + INCUBATOR_AVAILABLE = incubatorAvailable; + } private final LoggerSharedState loggerSharedState; private final InstrumentationScopeInfo instrumentationScopeInfo; @@ -30,10 +41,22 @@ final class SdkLogger implements ExtendedLogger { this.loggerEnabled = loggerConfig.isEnabled(); } + static SdkLogger create( + LoggerSharedState sharedState, + InstrumentationScopeInfo instrumentationScopeInfo, + LoggerConfig loggerConfig) { + return INCUBATOR_AVAILABLE + ? IncubatingUtil.createExtendedLogger(sharedState, instrumentationScopeInfo, loggerConfig) + : new SdkLogger(sharedState, instrumentationScopeInfo, loggerConfig); + } + @Override public LogRecordBuilder logRecordBuilder() { if (loggerEnabled) { - return new SdkLogRecordBuilder(loggerSharedState, instrumentationScopeInfo); + return INCUBATOR_AVAILABLE + ? IncubatingUtil.createExtendedLogRecordBuilder( + loggerSharedState, instrumentationScopeInfo) + : new SdkLogRecordBuilder(loggerSharedState, instrumentationScopeInfo); } return NOOP_LOGGER.logRecordBuilder(); } @@ -42,9 +65,4 @@ public LogRecordBuilder logRecordBuilder() { InstrumentationScopeInfo getInstrumentationScopeInfo() { return instrumentationScopeInfo; } - - @Override - public boolean isEnabled() { - return loggerEnabled; - } } diff --git a/sdk/logs/src/main/java/io/opentelemetry/sdk/logs/SdkLoggerProvider.java b/sdk/logs/src/main/java/io/opentelemetry/sdk/logs/SdkLoggerProvider.java index 2d7b87e6b47..ea68a6c2a5c 100644 --- a/sdk/logs/src/main/java/io/opentelemetry/sdk/logs/SdkLoggerProvider.java +++ b/sdk/logs/src/main/java/io/opentelemetry/sdk/logs/SdkLoggerProvider.java @@ -60,7 +60,7 @@ public static SdkLoggerProviderBuilder builder() { this.loggerComponentRegistry = new ComponentRegistry<>( instrumentationScopeInfo -> - new SdkLogger( + SdkLogger.create( sharedState, instrumentationScopeInfo, getLoggerConfig(instrumentationScopeInfo))); diff --git a/sdk/logs/src/test/java/io/opentelemetry/sdk/logs/LoggerConfigTest.java b/sdk/logs/src/testIncubating/java/io/opentelemetry/sdk/logs/LoggerConfigTest.java similarity index 100% rename from sdk/logs/src/test/java/io/opentelemetry/sdk/logs/LoggerConfigTest.java rename to sdk/logs/src/testIncubating/java/io/opentelemetry/sdk/logs/LoggerConfigTest.java diff --git a/sdk/logs/src/test/java/io/opentelemetry/sdk/logs/internal/SdkEventBuilderTest.java b/sdk/logs/src/testIncubating/java/io/opentelemetry/sdk/logs/internal/SdkEventBuilderTest.java similarity index 100% rename from sdk/logs/src/test/java/io/opentelemetry/sdk/logs/internal/SdkEventBuilderTest.java rename to sdk/logs/src/testIncubating/java/io/opentelemetry/sdk/logs/internal/SdkEventBuilderTest.java diff --git a/sdk/logs/src/test/java/io/opentelemetry/sdk/logs/internal/SdkEventLoggerProviderTest.java b/sdk/logs/src/testIncubating/java/io/opentelemetry/sdk/logs/internal/SdkEventLoggerProviderTest.java similarity index 100% rename from sdk/logs/src/test/java/io/opentelemetry/sdk/logs/internal/SdkEventLoggerProviderTest.java rename to sdk/logs/src/testIncubating/java/io/opentelemetry/sdk/logs/internal/SdkEventLoggerProviderTest.java diff --git a/sdk/metrics/build.gradle.kts b/sdk/metrics/build.gradle.kts index 0fffd03457e..a0b667943c8 100644 --- a/sdk/metrics/build.gradle.kts +++ b/sdk/metrics/build.gradle.kts @@ -15,7 +15,7 @@ otelJava.moduleName.set("io.opentelemetry.sdk.metrics") dependencies { api(project(":api:all")) api(project(":sdk:common")) - implementation(project(":api:incubator")) + compileOnly(project(":api:incubator")) compileOnly("org.codehaus.mojo:animal-sniffer-annotations") @@ -37,6 +37,13 @@ dependencyCheck { testing { suites { + register("testIncubating") { + dependencies { + implementation(project(":sdk:testing")) + implementation(project(":api:incubator")) + implementation("com.google.guava:guava") + } + } register("debugEnabledTest") { targets { all { diff --git a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/ExtendedSdkDoubleCounter.java b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/ExtendedSdkDoubleCounter.java new file mode 100644 index 00000000000..050429f8f52 --- /dev/null +++ b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/ExtendedSdkDoubleCounter.java @@ -0,0 +1,51 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.sdk.metrics; + +import io.opentelemetry.api.common.AttributeKey; +import io.opentelemetry.api.incubator.metrics.ExtendedDoubleCounter; +import io.opentelemetry.api.incubator.metrics.ExtendedDoubleCounterBuilder; +import io.opentelemetry.sdk.metrics.internal.descriptor.Advice; +import io.opentelemetry.sdk.metrics.internal.descriptor.InstrumentDescriptor; +import io.opentelemetry.sdk.metrics.internal.state.WriteableMetricStorage; +import java.util.List; + +final class ExtendedSdkDoubleCounter extends SdkDoubleCounter implements ExtendedDoubleCounter { + + private ExtendedSdkDoubleCounter( + InstrumentDescriptor descriptor, SdkMeter sdkMeter, WriteableMetricStorage storage) { + super(descriptor, sdkMeter, storage); + } + + @Override + public boolean isEnabled() { + return sdkMeter.isMeterEnabled() && storage.isEnabled(); + } + + static final class ExtendedSdkDoubleCounterBuilder extends SdkDoubleCounterBuilder + implements ExtendedDoubleCounterBuilder { + + ExtendedSdkDoubleCounterBuilder( + SdkMeter sdkMeter, + String name, + String description, + String unit, + Advice.AdviceBuilder adviceBuilder) { + super(sdkMeter, name, description, unit, adviceBuilder); + } + + @Override + public ExtendedSdkDoubleCounter build() { + return builder.buildSynchronousInstrument(ExtendedSdkDoubleCounter::new); + } + + @Override + public ExtendedDoubleCounterBuilder setAttributesAdvice(List> attributes) { + builder.setAdviceAttributes(attributes); + return this; + } + } +} diff --git a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/ExtendedSdkDoubleGauge.java b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/ExtendedSdkDoubleGauge.java new file mode 100644 index 00000000000..def79d8bb65 --- /dev/null +++ b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/ExtendedSdkDoubleGauge.java @@ -0,0 +1,50 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.sdk.metrics; + +import io.opentelemetry.api.common.AttributeKey; +import io.opentelemetry.api.incubator.metrics.ExtendedDoubleGauge; +import io.opentelemetry.api.incubator.metrics.ExtendedDoubleGaugeBuilder; +import io.opentelemetry.api.incubator.metrics.ExtendedLongGaugeBuilder; +import io.opentelemetry.sdk.metrics.internal.descriptor.InstrumentDescriptor; +import io.opentelemetry.sdk.metrics.internal.state.WriteableMetricStorage; +import java.util.List; + +final class ExtendedSdkDoubleGauge extends SdkDoubleGauge implements ExtendedDoubleGauge { + + private ExtendedSdkDoubleGauge( + InstrumentDescriptor descriptor, SdkMeter sdkMeter, WriteableMetricStorage storage) { + super(descriptor, sdkMeter, storage); + } + + @Override + public boolean isEnabled() { + return sdkMeter.isMeterEnabled() && storage.isEnabled(); + } + + static final class ExtendedSdkDoubleGaugeBuilder extends SdkDoubleGaugeBuilder + implements ExtendedDoubleGaugeBuilder { + ExtendedSdkDoubleGaugeBuilder(SdkMeter sdkMeter, String name) { + super(sdkMeter, name); + } + + @Override + public ExtendedSdkDoubleGauge build() { + return builder.buildSynchronousInstrument(ExtendedSdkDoubleGauge::new); + } + + @Override + public ExtendedDoubleGaugeBuilder setAttributesAdvice(List> attributes) { + builder.setAdviceAttributes(attributes); + return this; + } + + @Override + public ExtendedLongGaugeBuilder ofLongs() { + return builder.swapBuilder(ExtendedSdkLongGauge.ExtendedSdkLongGaugeBuilder::new); + } + } +} diff --git a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/ExtendedSdkDoubleHistogram.java b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/ExtendedSdkDoubleHistogram.java new file mode 100644 index 00000000000..76afb84214f --- /dev/null +++ b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/ExtendedSdkDoubleHistogram.java @@ -0,0 +1,52 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.sdk.metrics; + +import io.opentelemetry.api.common.AttributeKey; +import io.opentelemetry.api.incubator.metrics.ExtendedDoubleHistogram; +import io.opentelemetry.api.incubator.metrics.ExtendedDoubleHistogramBuilder; +import io.opentelemetry.api.incubator.metrics.ExtendedLongHistogramBuilder; +import io.opentelemetry.sdk.metrics.internal.descriptor.InstrumentDescriptor; +import io.opentelemetry.sdk.metrics.internal.state.WriteableMetricStorage; +import java.util.List; + +final class ExtendedSdkDoubleHistogram extends SdkDoubleHistogram + implements ExtendedDoubleHistogram { + + ExtendedSdkDoubleHistogram( + InstrumentDescriptor descriptor, SdkMeter sdkMeter, WriteableMetricStorage storage) { + super(descriptor, sdkMeter, storage); + } + + @Override + public boolean isEnabled() { + return sdkMeter.isMeterEnabled() && storage.isEnabled(); + } + + static final class ExtendedSdkDoubleHistogramBuilder extends SdkDoubleHistogramBuilder + implements ExtendedDoubleHistogramBuilder { + + ExtendedSdkDoubleHistogramBuilder(SdkMeter sdkMeter, String name) { + super(sdkMeter, name); + } + + @Override + public ExtendedSdkDoubleHistogram build() { + return builder.buildSynchronousInstrument(ExtendedSdkDoubleHistogram::new); + } + + @Override + public ExtendedLongHistogramBuilder ofLongs() { + return builder.swapBuilder(ExtendedSdkLongHistogram.ExtendedSdkLongHistogramBuilder::new); + } + + @Override + public ExtendedDoubleHistogramBuilder setAttributesAdvice(List> attributes) { + builder.setAdviceAttributes(attributes); + return this; + } + } +} diff --git a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/ExtendedSdkDoubleUpDownCounter.java b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/ExtendedSdkDoubleUpDownCounter.java new file mode 100644 index 00000000000..3e7ae4bdb11 --- /dev/null +++ b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/ExtendedSdkDoubleUpDownCounter.java @@ -0,0 +1,53 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.sdk.metrics; + +import io.opentelemetry.api.common.AttributeKey; +import io.opentelemetry.api.incubator.metrics.ExtendedDoubleUpDownCounter; +import io.opentelemetry.api.incubator.metrics.ExtendedDoubleUpDownCounterBuilder; +import io.opentelemetry.sdk.metrics.internal.descriptor.Advice; +import io.opentelemetry.sdk.metrics.internal.descriptor.InstrumentDescriptor; +import io.opentelemetry.sdk.metrics.internal.state.WriteableMetricStorage; +import java.util.List; + +final class ExtendedSdkDoubleUpDownCounter extends SdkDoubleUpDownCounter + implements ExtendedDoubleUpDownCounter { + + private ExtendedSdkDoubleUpDownCounter( + InstrumentDescriptor descriptor, SdkMeter sdkMeter, WriteableMetricStorage storage) { + super(descriptor, sdkMeter, storage); + } + + @Override + public boolean isEnabled() { + return sdkMeter.isMeterEnabled() && storage.isEnabled(); + } + + static final class ExtendedSdkDoubleUpDownCounterBuilder extends SdkDoubleUpDownCounterBuilder + implements ExtendedDoubleUpDownCounterBuilder { + + ExtendedSdkDoubleUpDownCounterBuilder( + SdkMeter sdkMeter, + String name, + String description, + String unit, + Advice.AdviceBuilder adviceBuilder) { + super(sdkMeter, name, description, unit, adviceBuilder); + } + + @Override + public ExtendedDoubleUpDownCounter build() { + return builder.buildSynchronousInstrument(ExtendedSdkDoubleUpDownCounter::new); + } + + @Override + public ExtendedDoubleUpDownCounterBuilder setAttributesAdvice( + List> attributes) { + builder.setAdviceAttributes(attributes); + return this; + } + } +} diff --git a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/ExtendedSdkLongCounter.java b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/ExtendedSdkLongCounter.java new file mode 100644 index 00000000000..f87e3407184 --- /dev/null +++ b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/ExtendedSdkLongCounter.java @@ -0,0 +1,51 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.sdk.metrics; + +import io.opentelemetry.api.common.AttributeKey; +import io.opentelemetry.api.incubator.metrics.ExtendedDoubleCounterBuilder; +import io.opentelemetry.api.incubator.metrics.ExtendedLongCounter; +import io.opentelemetry.api.incubator.metrics.ExtendedLongCounterBuilder; +import io.opentelemetry.sdk.metrics.internal.descriptor.InstrumentDescriptor; +import io.opentelemetry.sdk.metrics.internal.state.WriteableMetricStorage; +import java.util.List; + +final class ExtendedSdkLongCounter extends SdkLongCounter implements ExtendedLongCounter { + + private ExtendedSdkLongCounter( + InstrumentDescriptor descriptor, SdkMeter sdkMeter, WriteableMetricStorage storage) { + super(descriptor, sdkMeter, storage); + } + + @Override + public boolean isEnabled() { + return sdkMeter.isMeterEnabled() && storage.isEnabled(); + } + + static final class ExtendedSdkLongCounterBuilder extends SdkLongCounterBuilder + implements ExtendedLongCounterBuilder { + + ExtendedSdkLongCounterBuilder(SdkMeter sdkMeter, String name) { + super(sdkMeter, name); + } + + @Override + public ExtendedSdkLongCounter build() { + return builder.buildSynchronousInstrument(ExtendedSdkLongCounter::new); + } + + @Override + public ExtendedDoubleCounterBuilder ofDoubles() { + return builder.swapBuilder(ExtendedSdkDoubleCounter.ExtendedSdkDoubleCounterBuilder::new); + } + + @Override + public ExtendedLongCounterBuilder setAttributesAdvice(List> attributes) { + builder.setAdviceAttributes(attributes); + return this; + } + } +} diff --git a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/ExtendedSdkLongGauge.java b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/ExtendedSdkLongGauge.java new file mode 100644 index 00000000000..94845f4bef5 --- /dev/null +++ b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/ExtendedSdkLongGauge.java @@ -0,0 +1,51 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.sdk.metrics; + +import io.opentelemetry.api.common.AttributeKey; +import io.opentelemetry.api.incubator.metrics.ExtendedLongGauge; +import io.opentelemetry.api.incubator.metrics.ExtendedLongGaugeBuilder; +import io.opentelemetry.sdk.metrics.internal.descriptor.Advice; +import io.opentelemetry.sdk.metrics.internal.descriptor.InstrumentDescriptor; +import io.opentelemetry.sdk.metrics.internal.state.WriteableMetricStorage; +import java.util.List; + +final class ExtendedSdkLongGauge extends SdkLongGauge implements ExtendedLongGauge { + + private ExtendedSdkLongGauge( + InstrumentDescriptor descriptor, SdkMeter sdkMeter, WriteableMetricStorage storage) { + super(descriptor, sdkMeter, storage); + } + + @Override + public boolean isEnabled() { + return sdkMeter.isMeterEnabled() && storage.isEnabled(); + } + + static final class ExtendedSdkLongGaugeBuilder extends SdkLongGaugeBuilder + implements ExtendedLongGaugeBuilder { + + ExtendedSdkLongGaugeBuilder( + SdkMeter sdkMeter, + String name, + String description, + String unit, + Advice.AdviceBuilder adviceBuilder) { + super(sdkMeter, name, description, unit, adviceBuilder); + } + + @Override + public ExtendedSdkLongGauge build() { + return builder.buildSynchronousInstrument(ExtendedSdkLongGauge::new); + } + + @Override + public ExtendedLongGaugeBuilder setAttributesAdvice(List> attributes) { + builder.setAdviceAttributes(attributes); + return this; + } + } +} diff --git a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/ExtendedSdkLongHistogram.java b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/ExtendedSdkLongHistogram.java new file mode 100644 index 00000000000..e10851efd54 --- /dev/null +++ b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/ExtendedSdkLongHistogram.java @@ -0,0 +1,51 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.sdk.metrics; + +import io.opentelemetry.api.common.AttributeKey; +import io.opentelemetry.api.incubator.metrics.ExtendedLongHistogram; +import io.opentelemetry.api.incubator.metrics.ExtendedLongHistogramBuilder; +import io.opentelemetry.sdk.metrics.internal.descriptor.Advice; +import io.opentelemetry.sdk.metrics.internal.descriptor.InstrumentDescriptor; +import io.opentelemetry.sdk.metrics.internal.state.WriteableMetricStorage; +import java.util.List; + +final class ExtendedSdkLongHistogram extends SdkLongHistogram implements ExtendedLongHistogram { + + private ExtendedSdkLongHistogram( + InstrumentDescriptor descriptor, SdkMeter sdkMeter, WriteableMetricStorage storage) { + super(descriptor, sdkMeter, storage); + } + + @Override + public boolean isEnabled() { + return sdkMeter.isMeterEnabled() && storage.isEnabled(); + } + + static final class ExtendedSdkLongHistogramBuilder extends SdkLongHistogramBuilder + implements ExtendedLongHistogramBuilder { + + ExtendedSdkLongHistogramBuilder( + SdkMeter sdkMeter, + String name, + String description, + String unit, + Advice.AdviceBuilder adviceBuilder) { + super(sdkMeter, name, description, unit, adviceBuilder); + } + + @Override + public ExtendedSdkLongHistogram build() { + return builder.buildSynchronousInstrument(ExtendedSdkLongHistogram::new); + } + + @Override + public ExtendedLongHistogramBuilder setAttributesAdvice(List> attributes) { + builder.setAdviceAttributes(attributes); + return this; + } + } +} diff --git a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/ExtendedSdkLongUpDownCounter.java b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/ExtendedSdkLongUpDownCounter.java new file mode 100644 index 00000000000..53be08fed63 --- /dev/null +++ b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/ExtendedSdkLongUpDownCounter.java @@ -0,0 +1,53 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.sdk.metrics; + +import io.opentelemetry.api.common.AttributeKey; +import io.opentelemetry.api.incubator.metrics.ExtendedDoubleUpDownCounterBuilder; +import io.opentelemetry.api.incubator.metrics.ExtendedLongUpDownCounter; +import io.opentelemetry.api.incubator.metrics.ExtendedLongUpDownCounterBuilder; +import io.opentelemetry.sdk.metrics.internal.descriptor.InstrumentDescriptor; +import io.opentelemetry.sdk.metrics.internal.state.WriteableMetricStorage; +import java.util.List; + +final class ExtendedSdkLongUpDownCounter extends SdkLongUpDownCounter + implements ExtendedLongUpDownCounter { + + private ExtendedSdkLongUpDownCounter( + InstrumentDescriptor descriptor, SdkMeter sdkMeter, WriteableMetricStorage storage) { + super(descriptor, sdkMeter, storage); + } + + @Override + public boolean isEnabled() { + return sdkMeter.isMeterEnabled() && storage.isEnabled(); + } + + static final class ExtendedSdkLongUpDownCounterBuilder extends SdkLongUpDownCounterBuilder + implements ExtendedLongUpDownCounterBuilder { + + ExtendedSdkLongUpDownCounterBuilder(SdkMeter sdkMeter, String name) { + super(sdkMeter, name); + } + + @Override + public ExtendedLongUpDownCounter build() { + return builder.buildSynchronousInstrument(ExtendedSdkLongUpDownCounter::new); + } + + @Override + public ExtendedDoubleUpDownCounterBuilder ofDoubles() { + return builder.swapBuilder( + ExtendedSdkDoubleUpDownCounter.ExtendedSdkDoubleUpDownCounterBuilder::new); + } + + @Override + public ExtendedLongUpDownCounterBuilder setAttributesAdvice(List> attributes) { + builder.setAdviceAttributes(attributes); + return this; + } + } +} diff --git a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/IncubatingUtil.java b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/IncubatingUtil.java new file mode 100644 index 00000000000..03a88bb9382 --- /dev/null +++ b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/IncubatingUtil.java @@ -0,0 +1,39 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.sdk.metrics; + +import io.opentelemetry.api.metrics.DoubleGaugeBuilder; +import io.opentelemetry.api.metrics.DoubleHistogramBuilder; +import io.opentelemetry.api.metrics.LongCounterBuilder; +import io.opentelemetry.api.metrics.LongUpDownCounterBuilder; + +/** + * Utilities for interacting with {@code io.opentelemetry:opentelemetry-api-incubator}, which is not + * guaranteed to be present on the classpath. For all methods, callers MUST first separately + * reflectively confirm that the incubator is available on the classpath. + */ +final class IncubatingUtil { + + private IncubatingUtil() {} + + static LongCounterBuilder createExtendedLongCounterBuilder(SdkMeter sdkMeter, String name) { + return new ExtendedSdkLongCounter.ExtendedSdkLongCounterBuilder(sdkMeter, name); + } + + static LongUpDownCounterBuilder createExtendedLongUpDownCounterBuilder( + SdkMeter sdkMeter, String name) { + return new ExtendedSdkLongUpDownCounter.ExtendedSdkLongUpDownCounterBuilder(sdkMeter, name); + } + + static DoubleHistogramBuilder createExtendedDoubleHistogramBuilder( + SdkMeter sdkMeter, String name) { + return new ExtendedSdkDoubleHistogram.ExtendedSdkDoubleHistogramBuilder(sdkMeter, name); + } + + static DoubleGaugeBuilder createExtendedDoubleGaugeBuilder(SdkMeter sdkMeter, String name) { + return new ExtendedSdkDoubleGauge.ExtendedSdkDoubleGaugeBuilder(sdkMeter, name); + } +} diff --git a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkDoubleCounter.java b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkDoubleCounter.java index de645016076..7fd6e435556 100644 --- a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkDoubleCounter.java +++ b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkDoubleCounter.java @@ -5,10 +5,8 @@ package io.opentelemetry.sdk.metrics; -import io.opentelemetry.api.common.AttributeKey; import io.opentelemetry.api.common.Attributes; -import io.opentelemetry.api.incubator.metrics.ExtendedDoubleCounter; -import io.opentelemetry.api.incubator.metrics.ExtendedDoubleCounterBuilder; +import io.opentelemetry.api.metrics.DoubleCounter; import io.opentelemetry.api.metrics.DoubleCounterBuilder; import io.opentelemetry.api.metrics.ObservableDoubleCounter; import io.opentelemetry.api.metrics.ObservableDoubleMeasurement; @@ -17,19 +15,18 @@ import io.opentelemetry.sdk.metrics.internal.descriptor.Advice; import io.opentelemetry.sdk.metrics.internal.descriptor.InstrumentDescriptor; import io.opentelemetry.sdk.metrics.internal.state.WriteableMetricStorage; -import java.util.List; import java.util.function.Consumer; import java.util.logging.Level; import java.util.logging.Logger; -final class SdkDoubleCounter extends AbstractInstrument implements ExtendedDoubleCounter { +class SdkDoubleCounter extends AbstractInstrument implements DoubleCounter { private static final Logger logger = Logger.getLogger(SdkDoubleCounter.class.getName()); private final ThrottlingLogger throttlingLogger = new ThrottlingLogger(logger); - private final SdkMeter sdkMeter; - private final WriteableMetricStorage storage; + final SdkMeter sdkMeter; + final WriteableMetricStorage storage; - private SdkDoubleCounter( + SdkDoubleCounter( InstrumentDescriptor descriptor, SdkMeter sdkMeter, WriteableMetricStorage storage) { super(descriptor); this.sdkMeter = sdkMeter; @@ -59,14 +56,9 @@ public void add(double increment) { add(increment, Attributes.empty()); } - @Override - public boolean isEnabled() { - return sdkMeter.isMeterEnabled() && storage.isEnabled(); - } + static class SdkDoubleCounterBuilder implements DoubleCounterBuilder { - static final class SdkDoubleCounterBuilder implements ExtendedDoubleCounterBuilder { - - private final InstrumentBuilder builder; + final InstrumentBuilder builder; SdkDoubleCounterBuilder( SdkMeter sdkMeter, @@ -109,12 +101,6 @@ public ObservableDoubleMeasurement buildObserver() { return builder.buildObservableMeasurement(InstrumentType.OBSERVABLE_COUNTER); } - @Override - public ExtendedDoubleCounterBuilder setAttributesAdvice(List> attributes) { - builder.setAdviceAttributes(attributes); - return this; - } - @Override public String toString() { return builder.toStringHelper(getClass().getSimpleName()); diff --git a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkDoubleGauge.java b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkDoubleGauge.java index 03b3f43838d..97076603bb5 100644 --- a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkDoubleGauge.java +++ b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkDoubleGauge.java @@ -5,10 +5,8 @@ package io.opentelemetry.sdk.metrics; -import io.opentelemetry.api.common.AttributeKey; import io.opentelemetry.api.common.Attributes; -import io.opentelemetry.api.incubator.metrics.ExtendedDoubleGauge; -import io.opentelemetry.api.incubator.metrics.ExtendedDoubleGaugeBuilder; +import io.opentelemetry.api.metrics.DoubleGauge; import io.opentelemetry.api.metrics.DoubleGaugeBuilder; import io.opentelemetry.api.metrics.LongGaugeBuilder; import io.opentelemetry.api.metrics.ObservableDoubleGauge; @@ -16,15 +14,14 @@ import io.opentelemetry.context.Context; import io.opentelemetry.sdk.metrics.internal.descriptor.InstrumentDescriptor; import io.opentelemetry.sdk.metrics.internal.state.WriteableMetricStorage; -import java.util.List; import java.util.function.Consumer; -final class SdkDoubleGauge extends AbstractInstrument implements ExtendedDoubleGauge { +class SdkDoubleGauge extends AbstractInstrument implements DoubleGauge { - private final SdkMeter sdkMeter; - private final WriteableMetricStorage storage; + final SdkMeter sdkMeter; + final WriteableMetricStorage storage; - private SdkDoubleGauge( + SdkDoubleGauge( InstrumentDescriptor descriptor, SdkMeter sdkMeter, WriteableMetricStorage storage) { super(descriptor); this.sdkMeter = sdkMeter; @@ -46,16 +43,10 @@ public void set(double increment) { set(increment, Attributes.empty()); } - @Override - public boolean isEnabled() { - return sdkMeter.isMeterEnabled() && storage.isEnabled(); - } - - static final class SdkDoubleGaugeBuilder implements ExtendedDoubleGaugeBuilder { - private final InstrumentBuilder builder; + static class SdkDoubleGaugeBuilder implements DoubleGaugeBuilder { + final InstrumentBuilder builder; SdkDoubleGaugeBuilder(SdkMeter sdkMeter, String name) { - builder = new InstrumentBuilder(name, InstrumentType.GAUGE, InstrumentValueType.DOUBLE, sdkMeter); } @@ -77,12 +68,6 @@ public SdkDoubleGauge build() { return builder.buildSynchronousInstrument(SdkDoubleGauge::new); } - @Override - public ExtendedDoubleGaugeBuilder setAttributesAdvice(List> attributes) { - builder.setAdviceAttributes(attributes); - return this; - } - @Override public LongGaugeBuilder ofLongs() { return builder.swapBuilder(SdkLongGauge.SdkLongGaugeBuilder::new); diff --git a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkDoubleHistogram.java b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkDoubleHistogram.java index d155a7d7975..de4473ace2e 100644 --- a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkDoubleHistogram.java +++ b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkDoubleHistogram.java @@ -5,10 +5,8 @@ package io.opentelemetry.sdk.metrics; -import io.opentelemetry.api.common.AttributeKey; import io.opentelemetry.api.common.Attributes; -import io.opentelemetry.api.incubator.metrics.ExtendedDoubleHistogram; -import io.opentelemetry.api.incubator.metrics.ExtendedDoubleHistogramBuilder; +import io.opentelemetry.api.metrics.DoubleHistogram; import io.opentelemetry.api.metrics.DoubleHistogramBuilder; import io.opentelemetry.api.metrics.LongHistogramBuilder; import io.opentelemetry.context.Context; @@ -21,14 +19,14 @@ import java.util.logging.Level; import java.util.logging.Logger; -final class SdkDoubleHistogram extends AbstractInstrument implements ExtendedDoubleHistogram { +class SdkDoubleHistogram extends AbstractInstrument implements DoubleHistogram { private static final Logger logger = Logger.getLogger(SdkDoubleHistogram.class.getName()); private final ThrottlingLogger throttlingLogger = new ThrottlingLogger(logger); - private final SdkMeter sdkMeter; - private final WriteableMetricStorage storage; + final SdkMeter sdkMeter; + final WriteableMetricStorage storage; - private SdkDoubleHistogram( + SdkDoubleHistogram( InstrumentDescriptor descriptor, SdkMeter sdkMeter, WriteableMetricStorage storage) { super(descriptor); this.sdkMeter = sdkMeter; @@ -58,14 +56,9 @@ public void record(double value) { record(value, Attributes.empty()); } - @Override - public boolean isEnabled() { - return sdkMeter.isMeterEnabled() && storage.isEnabled(); - } + static class SdkDoubleHistogramBuilder implements DoubleHistogramBuilder { - static final class SdkDoubleHistogramBuilder implements ExtendedDoubleHistogramBuilder { - - private final InstrumentBuilder builder; + final InstrumentBuilder builder; SdkDoubleHistogramBuilder(SdkMeter sdkMeter, String name) { builder = @@ -108,12 +101,6 @@ public DoubleHistogramBuilder setExplicitBucketBoundariesAdvice(List buc return this; } - @Override - public ExtendedDoubleHistogramBuilder setAttributesAdvice(List> attributes) { - builder.setAdviceAttributes(attributes); - return this; - } - @Override public String toString() { return builder.toStringHelper(getClass().getSimpleName()); diff --git a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkDoubleUpDownCounter.java b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkDoubleUpDownCounter.java index fe21e295c98..4231f58fdc0 100644 --- a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkDoubleUpDownCounter.java +++ b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkDoubleUpDownCounter.java @@ -5,10 +5,7 @@ package io.opentelemetry.sdk.metrics; -import io.opentelemetry.api.common.AttributeKey; import io.opentelemetry.api.common.Attributes; -import io.opentelemetry.api.incubator.metrics.ExtendedDoubleUpDownCounter; -import io.opentelemetry.api.incubator.metrics.ExtendedDoubleUpDownCounterBuilder; import io.opentelemetry.api.metrics.DoubleUpDownCounter; import io.opentelemetry.api.metrics.DoubleUpDownCounterBuilder; import io.opentelemetry.api.metrics.ObservableDoubleMeasurement; @@ -17,16 +14,14 @@ import io.opentelemetry.sdk.metrics.internal.descriptor.Advice; import io.opentelemetry.sdk.metrics.internal.descriptor.InstrumentDescriptor; import io.opentelemetry.sdk.metrics.internal.state.WriteableMetricStorage; -import java.util.List; import java.util.function.Consumer; -final class SdkDoubleUpDownCounter extends AbstractInstrument - implements ExtendedDoubleUpDownCounter { +class SdkDoubleUpDownCounter extends AbstractInstrument implements DoubleUpDownCounter { - private final SdkMeter sdkMeter; - private final WriteableMetricStorage storage; + final SdkMeter sdkMeter; + final WriteableMetricStorage storage; - private SdkDoubleUpDownCounter( + SdkDoubleUpDownCounter( InstrumentDescriptor descriptor, SdkMeter sdkMeter, WriteableMetricStorage storage) { super(descriptor); this.sdkMeter = sdkMeter; @@ -48,14 +43,9 @@ public void add(double increment) { add(increment, Attributes.empty()); } - @Override - public boolean isEnabled() { - return sdkMeter.isMeterEnabled() && storage.isEnabled(); - } + static class SdkDoubleUpDownCounterBuilder implements DoubleUpDownCounterBuilder { - static final class SdkDoubleUpDownCounterBuilder implements ExtendedDoubleUpDownCounterBuilder { - - private final InstrumentBuilder builder; + final InstrumentBuilder builder; SdkDoubleUpDownCounterBuilder( SdkMeter sdkMeter, @@ -100,13 +90,6 @@ public ObservableDoubleMeasurement buildObserver() { return builder.buildObservableMeasurement(InstrumentType.OBSERVABLE_UP_DOWN_COUNTER); } - @Override - public ExtendedDoubleUpDownCounterBuilder setAttributesAdvice( - List> attributes) { - builder.setAdviceAttributes(attributes); - return this; - } - @Override public String toString() { return builder.toStringHelper(getClass().getSimpleName()); diff --git a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkLongCounter.java b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkLongCounter.java index df2f9b4e660..0de901060f5 100644 --- a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkLongCounter.java +++ b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkLongCounter.java @@ -5,11 +5,9 @@ package io.opentelemetry.sdk.metrics; -import io.opentelemetry.api.common.AttributeKey; import io.opentelemetry.api.common.Attributes; -import io.opentelemetry.api.incubator.metrics.ExtendedLongCounter; -import io.opentelemetry.api.incubator.metrics.ExtendedLongCounterBuilder; import io.opentelemetry.api.metrics.DoubleCounterBuilder; +import io.opentelemetry.api.metrics.LongCounter; import io.opentelemetry.api.metrics.LongCounterBuilder; import io.opentelemetry.api.metrics.ObservableLongCounter; import io.opentelemetry.api.metrics.ObservableLongMeasurement; @@ -17,20 +15,19 @@ import io.opentelemetry.sdk.internal.ThrottlingLogger; import io.opentelemetry.sdk.metrics.internal.descriptor.InstrumentDescriptor; import io.opentelemetry.sdk.metrics.internal.state.WriteableMetricStorage; -import java.util.List; import java.util.function.Consumer; import java.util.logging.Level; import java.util.logging.Logger; -final class SdkLongCounter extends AbstractInstrument implements ExtendedLongCounter { +class SdkLongCounter extends AbstractInstrument implements LongCounter { private static final Logger logger = Logger.getLogger(SdkLongCounter.class.getName()); private final ThrottlingLogger throttlingLogger = new ThrottlingLogger(logger); - private final SdkMeter sdkMeter; - private final WriteableMetricStorage storage; + final SdkMeter sdkMeter; + final WriteableMetricStorage storage; - private SdkLongCounter( + SdkLongCounter( InstrumentDescriptor descriptor, SdkMeter sdkMeter, WriteableMetricStorage storage) { super(descriptor); this.sdkMeter = sdkMeter; @@ -60,14 +57,9 @@ public void add(long increment) { add(increment, Attributes.empty()); } - @Override - public boolean isEnabled() { - return sdkMeter.isMeterEnabled() && storage.isEnabled(); - } + static class SdkLongCounterBuilder implements LongCounterBuilder { - static final class SdkLongCounterBuilder implements ExtendedLongCounterBuilder { - - private final InstrumentBuilder builder; + final InstrumentBuilder builder; SdkLongCounterBuilder(SdkMeter sdkMeter, String name) { this.builder = @@ -106,12 +98,6 @@ public ObservableLongMeasurement buildObserver() { return builder.buildObservableMeasurement(InstrumentType.OBSERVABLE_COUNTER); } - @Override - public ExtendedLongCounterBuilder setAttributesAdvice(List> attributes) { - builder.setAdviceAttributes(attributes); - return this; - } - @Override public String toString() { return builder.toStringHelper(getClass().getSimpleName()); diff --git a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkLongGauge.java b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkLongGauge.java index 499c4a4443a..5c6aafbb9ef 100644 --- a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkLongGauge.java +++ b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkLongGauge.java @@ -5,10 +5,8 @@ package io.opentelemetry.sdk.metrics; -import io.opentelemetry.api.common.AttributeKey; import io.opentelemetry.api.common.Attributes; -import io.opentelemetry.api.incubator.metrics.ExtendedLongGauge; -import io.opentelemetry.api.incubator.metrics.ExtendedLongGaugeBuilder; +import io.opentelemetry.api.metrics.LongGauge; import io.opentelemetry.api.metrics.LongGaugeBuilder; import io.opentelemetry.api.metrics.ObservableLongGauge; import io.opentelemetry.api.metrics.ObservableLongMeasurement; @@ -16,16 +14,14 @@ import io.opentelemetry.sdk.metrics.internal.descriptor.Advice; import io.opentelemetry.sdk.metrics.internal.descriptor.InstrumentDescriptor; import io.opentelemetry.sdk.metrics.internal.state.WriteableMetricStorage; -import java.util.List; import java.util.function.Consumer; -final class SdkLongGauge extends AbstractInstrument implements ExtendedLongGauge { +class SdkLongGauge extends AbstractInstrument implements LongGauge { - private final SdkMeter sdkMeter; - private final WriteableMetricStorage storage; + final SdkMeter sdkMeter; + final WriteableMetricStorage storage; - private SdkLongGauge( - InstrumentDescriptor descriptor, SdkMeter sdkMeter, WriteableMetricStorage storage) { + SdkLongGauge(InstrumentDescriptor descriptor, SdkMeter sdkMeter, WriteableMetricStorage storage) { super(descriptor); this.sdkMeter = sdkMeter; this.storage = storage; @@ -46,14 +42,9 @@ public void set(long increment) { set(increment, Attributes.empty()); } - @Override - public boolean isEnabled() { - return sdkMeter.isMeterEnabled() && storage.isEnabled(); - } + static class SdkLongGaugeBuilder implements LongGaugeBuilder { - static final class SdkLongGaugeBuilder implements ExtendedLongGaugeBuilder { - - private final InstrumentBuilder builder; + final InstrumentBuilder builder; SdkLongGaugeBuilder( SdkMeter sdkMeter, @@ -61,7 +52,6 @@ static final class SdkLongGaugeBuilder implements ExtendedLongGaugeBuilder { String description, String unit, Advice.AdviceBuilder adviceBuilder) { - builder = new InstrumentBuilder(name, InstrumentType.GAUGE, InstrumentValueType.LONG, sdkMeter) .setDescription(description) @@ -86,12 +76,6 @@ public SdkLongGauge build() { return builder.buildSynchronousInstrument(SdkLongGauge::new); } - @Override - public ExtendedLongGaugeBuilder setAttributesAdvice(List> attributes) { - builder.setAdviceAttributes(attributes); - return this; - } - @Override public ObservableLongGauge buildWithCallback(Consumer callback) { return builder.buildLongAsynchronousInstrument(InstrumentType.OBSERVABLE_GAUGE, callback); diff --git a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkLongHistogram.java b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkLongHistogram.java index 5e96bfb2e61..b777ad34e59 100644 --- a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkLongHistogram.java +++ b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkLongHistogram.java @@ -5,10 +5,8 @@ package io.opentelemetry.sdk.metrics; -import io.opentelemetry.api.common.AttributeKey; import io.opentelemetry.api.common.Attributes; -import io.opentelemetry.api.incubator.metrics.ExtendedLongHistogram; -import io.opentelemetry.api.incubator.metrics.ExtendedLongHistogramBuilder; +import io.opentelemetry.api.metrics.LongHistogram; import io.opentelemetry.api.metrics.LongHistogramBuilder; import io.opentelemetry.context.Context; import io.opentelemetry.sdk.internal.ThrottlingLogger; @@ -22,14 +20,14 @@ import java.util.logging.Logger; import java.util.stream.Collectors; -final class SdkLongHistogram extends AbstractInstrument implements ExtendedLongHistogram { +class SdkLongHistogram extends AbstractInstrument implements LongHistogram { private static final Logger logger = Logger.getLogger(SdkLongHistogram.class.getName()); private final ThrottlingLogger throttlingLogger = new ThrottlingLogger(logger); - private final SdkMeter sdkMeter; - private final WriteableMetricStorage storage; + final SdkMeter sdkMeter; + final WriteableMetricStorage storage; - private SdkLongHistogram( + SdkLongHistogram( InstrumentDescriptor descriptor, SdkMeter sdkMeter, WriteableMetricStorage storage) { super(descriptor); this.sdkMeter = sdkMeter; @@ -59,14 +57,9 @@ public void record(long value) { record(value, Attributes.empty()); } - @Override - public boolean isEnabled() { - return sdkMeter.isMeterEnabled() && storage.isEnabled(); - } + static class SdkLongHistogramBuilder implements LongHistogramBuilder { - static final class SdkLongHistogramBuilder implements ExtendedLongHistogramBuilder { - - private final InstrumentBuilder builder; + final InstrumentBuilder builder; SdkLongHistogramBuilder( SdkMeter sdkMeter, @@ -113,12 +106,6 @@ public LongHistogramBuilder setExplicitBucketBoundariesAdvice(List bucketB return this; } - @Override - public ExtendedLongHistogramBuilder setAttributesAdvice(List> attributes) { - builder.setAdviceAttributes(attributes); - return this; - } - @Override public String toString() { return builder.toStringHelper(getClass().getSimpleName()); diff --git a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkLongUpDownCounter.java b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkLongUpDownCounter.java index daf1e2f97a8..dece771f4b6 100644 --- a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkLongUpDownCounter.java +++ b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkLongUpDownCounter.java @@ -5,10 +5,7 @@ package io.opentelemetry.sdk.metrics; -import io.opentelemetry.api.common.AttributeKey; import io.opentelemetry.api.common.Attributes; -import io.opentelemetry.api.incubator.metrics.ExtendedLongUpDownCounter; -import io.opentelemetry.api.incubator.metrics.ExtendedLongUpDownCounterBuilder; import io.opentelemetry.api.metrics.DoubleUpDownCounterBuilder; import io.opentelemetry.api.metrics.LongUpDownCounter; import io.opentelemetry.api.metrics.LongUpDownCounterBuilder; @@ -17,15 +14,14 @@ import io.opentelemetry.context.Context; import io.opentelemetry.sdk.metrics.internal.descriptor.InstrumentDescriptor; import io.opentelemetry.sdk.metrics.internal.state.WriteableMetricStorage; -import java.util.List; import java.util.function.Consumer; -final class SdkLongUpDownCounter extends AbstractInstrument implements ExtendedLongUpDownCounter { +class SdkLongUpDownCounter extends AbstractInstrument implements LongUpDownCounter { - private final SdkMeter sdkMeter; - private final WriteableMetricStorage storage; + final SdkMeter sdkMeter; + final WriteableMetricStorage storage; - private SdkLongUpDownCounter( + SdkLongUpDownCounter( InstrumentDescriptor descriptor, SdkMeter sdkMeter, WriteableMetricStorage storage) { super(descriptor); this.sdkMeter = sdkMeter; @@ -47,14 +43,9 @@ public void add(long increment) { add(increment, Attributes.empty()); } - @Override - public boolean isEnabled() { - return sdkMeter.isMeterEnabled() && storage.isEnabled(); - } + static class SdkLongUpDownCounterBuilder implements LongUpDownCounterBuilder { - static final class SdkLongUpDownCounterBuilder implements ExtendedLongUpDownCounterBuilder { - - private final InstrumentBuilder builder; + final InstrumentBuilder builder; SdkLongUpDownCounterBuilder(SdkMeter sdkMeter, String name) { this.builder = @@ -96,12 +87,6 @@ public ObservableLongMeasurement buildObserver() { return builder.buildObservableMeasurement(InstrumentType.OBSERVABLE_UP_DOWN_COUNTER); } - @Override - public ExtendedLongUpDownCounterBuilder setAttributesAdvice(List> attributes) { - builder.setAdviceAttributes(attributes); - return this; - } - @Override public String toString() { return builder.toStringHelper(getClass().getSimpleName()); diff --git a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkMeter.java b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkMeter.java index fe278cba4d6..c0f1476077a 100644 --- a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkMeter.java +++ b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkMeter.java @@ -49,6 +49,18 @@ final class SdkMeter implements Meter { private static final Logger logger = Logger.getLogger(SdkMeter.class.getName()); + private static final boolean INCUBATOR_AVAILABLE; + + static { + boolean incubatorAvailable = false; + try { + Class.forName("io.opentelemetry.api.incubator.metrics.ExtendedDefaultMeterProvider"); + incubatorAvailable = true; + } catch (ClassNotFoundException e) { + // Not available + } + INCUBATOR_AVAILABLE = incubatorAvailable; + } /** * Instrument names MUST conform to the following syntax. @@ -145,30 +157,42 @@ void resetForTest() { @Override public LongCounterBuilder counterBuilder(String name) { - return checkValidInstrumentName(name) - ? new SdkLongCounter.SdkLongCounterBuilder(this, name) - : NOOP_METER.counterBuilder(NOOP_INSTRUMENT_NAME); + if (!checkValidInstrumentName(name)) { + return NOOP_METER.counterBuilder(NOOP_INSTRUMENT_NAME); + } + return INCUBATOR_AVAILABLE + ? IncubatingUtil.createExtendedLongCounterBuilder(this, name) + : new SdkLongCounter.SdkLongCounterBuilder(this, name); } @Override public LongUpDownCounterBuilder upDownCounterBuilder(String name) { - return checkValidInstrumentName(name) - ? new SdkLongUpDownCounter.SdkLongUpDownCounterBuilder(this, name) - : NOOP_METER.upDownCounterBuilder(NOOP_INSTRUMENT_NAME); + if (!checkValidInstrumentName(name)) { + return NOOP_METER.upDownCounterBuilder(NOOP_INSTRUMENT_NAME); + } + return INCUBATOR_AVAILABLE + ? IncubatingUtil.createExtendedLongUpDownCounterBuilder(this, name) + : new SdkLongUpDownCounter.SdkLongUpDownCounterBuilder(this, name); } @Override public DoubleHistogramBuilder histogramBuilder(String name) { - return checkValidInstrumentName(name) - ? new SdkDoubleHistogram.SdkDoubleHistogramBuilder(this, name) - : NOOP_METER.histogramBuilder(NOOP_INSTRUMENT_NAME); + if (!checkValidInstrumentName(name)) { + return NOOP_METER.histogramBuilder(NOOP_INSTRUMENT_NAME); + } + return INCUBATOR_AVAILABLE + ? IncubatingUtil.createExtendedDoubleHistogramBuilder(this, name) + : new SdkDoubleHistogram.SdkDoubleHistogramBuilder(this, name); } @Override public DoubleGaugeBuilder gaugeBuilder(String name) { - return checkValidInstrumentName(name) - ? new SdkDoubleGauge.SdkDoubleGaugeBuilder(this, name) - : NOOP_METER.gaugeBuilder(NOOP_INSTRUMENT_NAME); + if (!checkValidInstrumentName(name)) { + return NOOP_METER.gaugeBuilder(NOOP_INSTRUMENT_NAME); + } + return INCUBATOR_AVAILABLE + ? IncubatingUtil.createExtendedDoubleGaugeBuilder(this, name) + : new SdkDoubleGauge.SdkDoubleGaugeBuilder(this, name); } @Override diff --git a/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/AttributesAdviceTest.java b/sdk/metrics/src/testIncubating/java/io/opentelemetry/sdk/metrics/AttributesAdviceTest.java similarity index 100% rename from sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/AttributesAdviceTest.java rename to sdk/metrics/src/testIncubating/java/io/opentelemetry/sdk/metrics/AttributesAdviceTest.java diff --git a/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/MeterConfigTest.java b/sdk/metrics/src/testIncubating/java/io/opentelemetry/sdk/metrics/MeterConfigTest.java similarity index 100% rename from sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/MeterConfigTest.java rename to sdk/metrics/src/testIncubating/java/io/opentelemetry/sdk/metrics/MeterConfigTest.java diff --git a/sdk/trace/build.gradle.kts b/sdk/trace/build.gradle.kts index 2dc5c769508..35d30c8513b 100644 --- a/sdk/trace/build.gradle.kts +++ b/sdk/trace/build.gradle.kts @@ -22,8 +22,7 @@ dependencies { api(project(":api:all")) api(project(":sdk:common")) - implementation(project(":api:incubator")) - + compileOnly(project(":api:incubator")) compileOnly(project(":sdk:trace-shaded-deps")) annotationProcessor("com.google.auto.value:auto-value") @@ -65,6 +64,23 @@ dependencies { jmh("org.testcontainers:testcontainers") // testContainer for OTLP collector } +testing { + suites { + register("testIncubating") { + dependencies { + implementation(project(":sdk:testing")) + implementation(project(":api:incubator")) + } + } + } +} + +tasks { + check { + dependsOn(testing.suites) + } +} + tasks { withType().configureEach { // We catch NoClassDefFoundError to fallback to non-jctools queues. diff --git a/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/ExtendedSdkSpanBuilder.java b/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/ExtendedSdkSpanBuilder.java new file mode 100644 index 00000000000..b68030202ce --- /dev/null +++ b/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/ExtendedSdkSpanBuilder.java @@ -0,0 +1,159 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.sdk.trace; + +import io.opentelemetry.api.common.AttributeKey; +import io.opentelemetry.api.common.Attributes; +import io.opentelemetry.api.incubator.propagation.ExtendedContextPropagators; +import io.opentelemetry.api.incubator.trace.ExtendedSpanBuilder; +import io.opentelemetry.api.incubator.trace.SpanCallable; +import io.opentelemetry.api.incubator.trace.SpanRunnable; +import io.opentelemetry.api.trace.Span; +import io.opentelemetry.api.trace.SpanContext; +import io.opentelemetry.api.trace.SpanKind; +import io.opentelemetry.api.trace.StatusCode; +import io.opentelemetry.context.Context; +import io.opentelemetry.context.Scope; +import io.opentelemetry.context.propagation.ContextPropagators; +import io.opentelemetry.sdk.common.InstrumentationScopeInfo; +import java.util.Map; +import java.util.concurrent.TimeUnit; +import java.util.function.BiConsumer; + +/** {@link ExtendedSdkSpanBuilder} is SDK implementation of {@link ExtendedSpanBuilder}. */ +final class ExtendedSdkSpanBuilder extends SdkSpanBuilder implements ExtendedSpanBuilder { + + ExtendedSdkSpanBuilder( + String spanName, + InstrumentationScopeInfo instrumentationScopeInfo, + TracerSharedState tracerSharedState, + SpanLimits spanLimits) { + super(spanName, instrumentationScopeInfo, tracerSharedState, spanLimits); + } + + @Override + public ExtendedSpanBuilder setParent(Context context) { + super.setParent(context); + return this; + } + + @Override + public ExtendedSpanBuilder setNoParent() { + super.setNoParent(); + return this; + } + + @Override + public ExtendedSpanBuilder setSpanKind(SpanKind spanKind) { + super.setSpanKind(spanKind); + return this; + } + + @Override + public ExtendedSpanBuilder addLink(SpanContext spanContext) { + super.addLink(spanContext); + return this; + } + + @Override + public ExtendedSpanBuilder addLink(SpanContext spanContext, Attributes attributes) { + super.addLink(spanContext, attributes); + return this; + } + + @Override + public ExtendedSpanBuilder setAttribute(String key, String value) { + super.setAttribute(key, value); + return this; + } + + @Override + public ExtendedSpanBuilder setAttribute(String key, long value) { + super.setAttribute(key, value); + return this; + } + + @Override + public ExtendedSpanBuilder setAttribute(String key, double value) { + super.setAttribute(key, value); + return this; + } + + @Override + public ExtendedSpanBuilder setAttribute(String key, boolean value) { + super.setAttribute(key, value); + return this; + } + + @Override + public ExtendedSpanBuilder setAttribute(AttributeKey key, T value) { + super.setAttribute(key, value); + return this; + } + + @Override + public ExtendedSpanBuilder setStartTimestamp(long startTimestamp, TimeUnit unit) { + super.setStartTimestamp(startTimestamp, unit); + return this; + } + + @Override + public ExtendedSpanBuilder setParentFrom( + ContextPropagators propagators, Map carrier) { + super.setParent( + ExtendedContextPropagators.extractTextMapPropagationContext(carrier, propagators)); + return this; + } + + @Override + public T startAndCall(SpanCallable spanCallable) throws E { + return startAndCall(spanCallable, ExtendedSdkSpanBuilder::setSpanError); + } + + @Override + public T startAndCall( + SpanCallable spanCallable, BiConsumer handleException) throws E { + Span span = startSpan(); + + //noinspection unused + try (Scope unused = span.makeCurrent()) { + return spanCallable.callInSpan(); + } catch (Throwable e) { + handleException.accept(span, e); + throw e; + } finally { + span.end(); + } + } + + @Override + public void startAndRun(SpanRunnable runnable) throws E { + startAndRun(runnable, ExtendedSdkSpanBuilder::setSpanError); + } + + @SuppressWarnings("NullAway") + @Override + public void startAndRun( + SpanRunnable runnable, BiConsumer handleException) throws E { + startAndCall( + () -> { + runnable.runInSpan(); + return null; + }, + handleException); + } + + /** + * Marks a span as error. This is the default exception handler. + * + * @param span the span + * @param exception the exception that caused the error + */ + private static void setSpanError(Span span, Throwable exception) { + span.setStatus(StatusCode.ERROR); + span.recordException(exception); + } +} diff --git a/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/ExtendedSdkTracer.java b/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/ExtendedSdkTracer.java new file mode 100644 index 00000000000..7e339fd9a19 --- /dev/null +++ b/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/ExtendedSdkTracer.java @@ -0,0 +1,30 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.sdk.trace; + +import io.opentelemetry.api.incubator.trace.ExtendedTracer; +import io.opentelemetry.sdk.common.InstrumentationScopeInfo; +import io.opentelemetry.sdk.trace.internal.TracerConfig; + +/** {@link ExtendedSdkTracer} is SDK implementation of {@link ExtendedTracer}. */ +final class ExtendedSdkTracer extends SdkTracer implements ExtendedTracer { + // TODO: add dedicated API for updating scope config. + @SuppressWarnings("FieldCanBeFinal") // For now, allow updating reflectively. + private boolean tracerEnabled; + + ExtendedSdkTracer( + TracerSharedState sharedState, + InstrumentationScopeInfo instrumentationScopeInfo, + TracerConfig tracerConfig) { + super(sharedState, instrumentationScopeInfo, tracerConfig); + this.tracerEnabled = tracerConfig.isEnabled(); + } + + @Override + public boolean isEnabled() { + return tracerEnabled; + } +} diff --git a/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/IncubatingUtil.java b/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/IncubatingUtil.java new file mode 100644 index 00000000000..c7ab15e9c2e --- /dev/null +++ b/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/IncubatingUtil.java @@ -0,0 +1,35 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.sdk.trace; + +import io.opentelemetry.sdk.common.InstrumentationScopeInfo; +import io.opentelemetry.sdk.trace.internal.TracerConfig; + +/** + * Utilities for interacting with {@code io.opentelemetry:opentelemetry-api-incubator}, which is not + * guaranteed to be present on the classpath. For all methods, callers MUST first separately + * reflectively confirm that the incubator is available on the classpath. + */ +final class IncubatingUtil { + + private IncubatingUtil() {} + + static SdkTracer createExtendedTracer( + TracerSharedState sharedState, + InstrumentationScopeInfo instrumentationScopeInfo, + TracerConfig tracerConfig) { + return new ExtendedSdkTracer(sharedState, instrumentationScopeInfo, tracerConfig); + } + + static SdkSpanBuilder createExtendedSpanBuilder( + String spanName, + InstrumentationScopeInfo instrumentationScopeInfo, + TracerSharedState tracerSharedState, + SpanLimits spanLimits) { + return new ExtendedSdkSpanBuilder( + spanName, instrumentationScopeInfo, tracerSharedState, spanLimits); + } +} diff --git a/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/SdkSpanBuilder.java b/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/SdkSpanBuilder.java index d637caa60da..b12107c7d43 100644 --- a/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/SdkSpanBuilder.java +++ b/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/SdkSpanBuilder.java @@ -12,21 +12,14 @@ import io.opentelemetry.api.common.AttributeKey; import io.opentelemetry.api.common.Attributes; -import io.opentelemetry.api.incubator.propagation.ExtendedContextPropagators; -import io.opentelemetry.api.incubator.trace.ExtendedSpanBuilder; -import io.opentelemetry.api.incubator.trace.SpanCallable; -import io.opentelemetry.api.incubator.trace.SpanRunnable; import io.opentelemetry.api.internal.ImmutableSpanContext; import io.opentelemetry.api.trace.Span; import io.opentelemetry.api.trace.SpanBuilder; import io.opentelemetry.api.trace.SpanContext; import io.opentelemetry.api.trace.SpanKind; -import io.opentelemetry.api.trace.StatusCode; import io.opentelemetry.api.trace.TraceFlags; import io.opentelemetry.api.trace.TraceState; import io.opentelemetry.context.Context; -import io.opentelemetry.context.Scope; -import io.opentelemetry.context.propagation.ContextPropagators; import io.opentelemetry.sdk.common.InstrumentationScopeInfo; import io.opentelemetry.sdk.internal.AttributeUtil; import io.opentelemetry.sdk.internal.AttributesMap; @@ -36,13 +29,11 @@ import java.util.ArrayList; import java.util.Collections; import java.util.List; -import java.util.Map; import java.util.concurrent.TimeUnit; -import java.util.function.BiConsumer; import javax.annotation.Nullable; /** {@link SdkSpanBuilder} is SDK implementation of {@link SpanBuilder}. */ -final class SdkSpanBuilder implements ExtendedSpanBuilder { +class SdkSpanBuilder implements SpanBuilder { private final String spanName; private final InstrumentationScopeInfo instrumentationScopeInfo; @@ -68,7 +59,7 @@ final class SdkSpanBuilder implements ExtendedSpanBuilder { } @Override - public ExtendedSpanBuilder setParent(Context context) { + public SpanBuilder setParent(Context context) { if (context == null) { return this; } @@ -77,13 +68,13 @@ public ExtendedSpanBuilder setParent(Context context) { } @Override - public ExtendedSpanBuilder setNoParent() { + public SpanBuilder setNoParent() { this.parent = Context.root(); return this; } @Override - public ExtendedSpanBuilder setSpanKind(SpanKind spanKind) { + public SpanBuilder setSpanKind(SpanKind spanKind) { if (spanKind == null) { return this; } @@ -92,7 +83,7 @@ public ExtendedSpanBuilder setSpanKind(SpanKind spanKind) { } @Override - public ExtendedSpanBuilder addLink(SpanContext spanContext) { + public SpanBuilder addLink(SpanContext spanContext) { if (spanContext == null || !spanContext.isValid()) { return this; } @@ -101,7 +92,7 @@ public ExtendedSpanBuilder addLink(SpanContext spanContext) { } @Override - public ExtendedSpanBuilder addLink(SpanContext spanContext, Attributes attributes) { + public SpanBuilder addLink(SpanContext spanContext, Attributes attributes) { if (spanContext == null || !spanContext.isValid()) { return this; } @@ -135,27 +126,27 @@ private void addLink(LinkData link) { } @Override - public ExtendedSpanBuilder setAttribute(String key, String value) { + public SpanBuilder setAttribute(String key, String value) { return setAttribute(stringKey(key), value); } @Override - public ExtendedSpanBuilder setAttribute(String key, long value) { + public SpanBuilder setAttribute(String key, long value) { return setAttribute(longKey(key), value); } @Override - public ExtendedSpanBuilder setAttribute(String key, double value) { + public SpanBuilder setAttribute(String key, double value) { return setAttribute(doubleKey(key), value); } @Override - public ExtendedSpanBuilder setAttribute(String key, boolean value) { + public SpanBuilder setAttribute(String key, boolean value) { return setAttribute(booleanKey(key), value); } @Override - public ExtendedSpanBuilder setAttribute(AttributeKey key, T value) { + public SpanBuilder setAttribute(AttributeKey key, T value) { if (key == null || key.getKey().isEmpty() || value == null) { return this; } @@ -164,7 +155,7 @@ public ExtendedSpanBuilder setAttribute(AttributeKey key, T value) { } @Override - public ExtendedSpanBuilder setStartTimestamp(long startTimestamp, TimeUnit unit) { + public SpanBuilder setStartTimestamp(long startTimestamp, TimeUnit unit) { if (startTimestamp < 0 || unit == null) { return this; } @@ -172,13 +163,6 @@ public ExtendedSpanBuilder setStartTimestamp(long startTimestamp, TimeUnit unit) return this; } - @Override - public ExtendedSpanBuilder setParentFrom( - ContextPropagators propagators, Map carrier) { - setParent(ExtendedContextPropagators.extractTextMapPropagationContext(carrier, propagators)); - return this; - } - @Override @SuppressWarnings({"unchecked", "rawtypes"}) public Span startSpan() { @@ -250,44 +234,6 @@ public Span startSpan() { startEpochNanos); } - @Override - public T startAndCall(SpanCallable spanCallable) throws E { - return startAndCall(spanCallable, SdkSpanBuilder::setSpanError); - } - - @Override - public T startAndCall( - SpanCallable spanCallable, BiConsumer handleException) throws E { - Span span = startSpan(); - - //noinspection unused - try (Scope unused = span.makeCurrent()) { - return spanCallable.callInSpan(); - } catch (Throwable e) { - handleException.accept(span, e); - throw e; - } finally { - span.end(); - } - } - - @Override - public void startAndRun(SpanRunnable runnable) throws E { - startAndRun(runnable, SdkSpanBuilder::setSpanError); - } - - @SuppressWarnings("NullAway") - @Override - public void startAndRun( - SpanRunnable runnable, BiConsumer handleException) throws E { - startAndCall( - () -> { - runnable.runInSpan(); - return null; - }, - handleException); - } - private AttributesMap attributes() { AttributesMap attributes = this.attributes; if (attributes == null) { @@ -309,15 +255,4 @@ static boolean isRecording(SamplingDecision decision) { static boolean isSampled(SamplingDecision decision) { return SamplingDecision.RECORD_AND_SAMPLE.equals(decision); } - - /** - * Marks a span as error. This is the default exception handler. - * - * @param span the span - * @param exception the exception that caused the error - */ - private static void setSpanError(Span span, Throwable exception) { - span.setStatus(StatusCode.ERROR); - span.recordException(exception); - } } diff --git a/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/SdkTracer.java b/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/SdkTracer.java index 7b74c035e82..42210e56b28 100644 --- a/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/SdkTracer.java +++ b/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/SdkTracer.java @@ -5,7 +5,6 @@ package io.opentelemetry.sdk.trace; -import io.opentelemetry.api.incubator.trace.ExtendedTracer; import io.opentelemetry.api.trace.SpanBuilder; import io.opentelemetry.api.trace.Tracer; import io.opentelemetry.api.trace.TracerProvider; @@ -13,9 +12,21 @@ import io.opentelemetry.sdk.trace.internal.TracerConfig; /** {@link SdkTracer} is SDK implementation of {@link Tracer}. */ -final class SdkTracer implements ExtendedTracer { +class SdkTracer implements Tracer { static final String FALLBACK_SPAN_NAME = ""; private static final Tracer NOOP_TRACER = TracerProvider.noop().get("noop"); + private static final boolean INCUBATOR_AVAILABLE; + + static { + boolean incubatorAvailable = false; + try { + Class.forName("io.opentelemetry.api.incubator.trace.ExtendedDefaultTracerProvider"); + incubatorAvailable = true; + } catch (ClassNotFoundException e) { + // Not available + } + INCUBATOR_AVAILABLE = incubatorAvailable; + } private final TracerSharedState sharedState; private final InstrumentationScopeInfo instrumentationScopeInfo; @@ -33,6 +44,15 @@ final class SdkTracer implements ExtendedTracer { this.tracerEnabled = tracerConfig.isEnabled(); } + static SdkTracer create( + TracerSharedState sharedState, + InstrumentationScopeInfo instrumentationScopeInfo, + TracerConfig tracerConfig) { + return INCUBATOR_AVAILABLE + ? IncubatingUtil.createExtendedTracer(sharedState, instrumentationScopeInfo, tracerConfig) + : new SdkTracer(sharedState, instrumentationScopeInfo, tracerConfig); + } + @Override public SpanBuilder spanBuilder(String spanName) { if (!tracerEnabled) { @@ -45,17 +65,15 @@ public SpanBuilder spanBuilder(String spanName) { Tracer tracer = TracerProvider.noop().get(instrumentationScopeInfo.getName()); return tracer.spanBuilder(spanName); } - return new SdkSpanBuilder( - spanName, instrumentationScopeInfo, sharedState, sharedState.getSpanLimits()); + return INCUBATOR_AVAILABLE + ? IncubatingUtil.createExtendedSpanBuilder( + spanName, instrumentationScopeInfo, sharedState, sharedState.getSpanLimits()) + : new SdkSpanBuilder( + spanName, instrumentationScopeInfo, sharedState, sharedState.getSpanLimits()); } // Visible for testing InstrumentationScopeInfo getInstrumentationScopeInfo() { return instrumentationScopeInfo; } - - @Override - public boolean isEnabled() { - return tracerEnabled; - } } diff --git a/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/SdkTracerProvider.java b/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/SdkTracerProvider.java index 036e812c5ab..14ccc37c41f 100644 --- a/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/SdkTracerProvider.java +++ b/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/SdkTracerProvider.java @@ -56,7 +56,7 @@ public static SdkTracerProviderBuilder builder() { this.tracerSdkComponentRegistry = new ComponentRegistry<>( instrumentationScopeInfo -> - new SdkTracer( + SdkTracer.create( sharedState, instrumentationScopeInfo, getTracerConfig(instrumentationScopeInfo))); diff --git a/sdk/trace/src/test/java/io/opentelemetry/sdk/trace/TracerConfigTest.java b/sdk/trace/src/testIncubating/java/io/opentelemetry/sdk/trace/TracerConfigTest.java similarity index 100% rename from sdk/trace/src/test/java/io/opentelemetry/sdk/trace/TracerConfigTest.java rename to sdk/trace/src/testIncubating/java/io/opentelemetry/sdk/trace/TracerConfigTest.java From d71db3a2f0b44a0296a01a8cc805f0d9dce480bd Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 13 Jan 2025 16:48:29 -0600 Subject: [PATCH 755/901] fix(deps): update dependency net.ltgt.gradle:gradle-nullaway-plugin to v2.2.0 (#7014) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- buildSrc/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts index df259de52f6..6854f70ace0 100644 --- a/buildSrc/build.gradle.kts +++ b/buildSrc/build.gradle.kts @@ -64,7 +64,7 @@ dependencies { implementation("me.champeau.gradle:japicmp-gradle-plugin:0.4.5") implementation("me.champeau.jmh:jmh-gradle-plugin:0.7.2") implementation("net.ltgt.gradle:gradle-errorprone-plugin:4.1.0") - implementation("net.ltgt.gradle:gradle-nullaway-plugin:2.1.0") + implementation("net.ltgt.gradle:gradle-nullaway-plugin:2.2.0") implementation("org.jetbrains.kotlin:kotlin-gradle-plugin:2.1.0") implementation("org.owasp:dependency-check-gradle:11.1.1") implementation("ru.vyarus:gradle-animalsniffer-plugin:1.7.2") From 4b3cedda0d65e4bdd0d6f7dd8cb93f421ee054a0 Mon Sep 17 00:00:00 2001 From: Gregor Zeitlinger Date: Tue, 14 Jan 2025 18:14:47 +0100 Subject: [PATCH 756/901] make extended tracer easier to use (#6943) Co-authored-by: Jack Berg --- .../trace/ExtendedDefaultTracer.java | 3 +- .../api/incubator/trace/ExtendedTracer.java | 3 + .../trace/ExtendedTraceApiUsageTest.java | 17 +++-- .../graal/IncubatingApiTests.java | 6 +- .../sdk/trace/ExtendedSdkTracer.java | 6 ++ .../io/opentelemetry/sdk/trace/SdkTracer.java | 7 +- .../sdk/trace/ExtendedTracerTest.java | 71 +++++++++++++++++++ 7 files changed, 100 insertions(+), 13 deletions(-) create mode 100644 sdk/trace/src/testIncubating/java/io/opentelemetry/sdk/trace/ExtendedTracerTest.java diff --git a/api/incubator/src/main/java/io/opentelemetry/api/incubator/trace/ExtendedDefaultTracer.java b/api/incubator/src/main/java/io/opentelemetry/api/incubator/trace/ExtendedDefaultTracer.java index 948f17e9996..45346099a5d 100644 --- a/api/incubator/src/main/java/io/opentelemetry/api/incubator/trace/ExtendedDefaultTracer.java +++ b/api/incubator/src/main/java/io/opentelemetry/api/incubator/trace/ExtendedDefaultTracer.java @@ -10,7 +10,6 @@ import io.opentelemetry.api.incubator.propagation.ExtendedContextPropagators; import io.opentelemetry.api.internal.ApiUsageLogger; import io.opentelemetry.api.trace.Span; -import io.opentelemetry.api.trace.SpanBuilder; import io.opentelemetry.api.trace.SpanContext; import io.opentelemetry.api.trace.SpanKind; import io.opentelemetry.api.trace.Tracer; @@ -33,7 +32,7 @@ static Tracer getNoop() { } @Override - public SpanBuilder spanBuilder(String spanName) { + public ExtendedSpanBuilder spanBuilder(String spanName) { return NoopSpanBuilder.create(); } diff --git a/api/incubator/src/main/java/io/opentelemetry/api/incubator/trace/ExtendedTracer.java b/api/incubator/src/main/java/io/opentelemetry/api/incubator/trace/ExtendedTracer.java index cb2cae27c24..c37ba913eb1 100644 --- a/api/incubator/src/main/java/io/opentelemetry/api/incubator/trace/ExtendedTracer.java +++ b/api/incubator/src/main/java/io/opentelemetry/api/incubator/trace/ExtendedTracer.java @@ -20,4 +20,7 @@ public interface ExtendedTracer extends Tracer { default boolean isEnabled() { return true; } + + @Override + ExtendedSpanBuilder spanBuilder(String spanName); } diff --git a/api/incubator/src/test/java/io/opentelemetry/api/incubator/trace/ExtendedTraceApiUsageTest.java b/api/incubator/src/test/java/io/opentelemetry/api/incubator/trace/ExtendedTraceApiUsageTest.java index 40bf10454de..752cd279650 100644 --- a/api/incubator/src/test/java/io/opentelemetry/api/incubator/trace/ExtendedTraceApiUsageTest.java +++ b/api/incubator/src/test/java/io/opentelemetry/api/incubator/trace/ExtendedTraceApiUsageTest.java @@ -166,6 +166,7 @@ void startAndCallOrRun() { // Get a Tracer for a scope Tracer tracer = tracerProvider.get("org.foo.my-scope"); + ExtendedTracer extendedTracer = (ExtendedTracer) tracer; // Wrap the resetCheckout method in a span String cartId = @@ -173,20 +174,24 @@ void startAndCallOrRun() { .setAttribute("key123", "val456") .startAndCall(() -> resetCheckoutAndReturn("abc123", /* throwException= */ false)); assertThat(cartId).isEqualTo("abc123"); + // ...or use ExtendedTracer instance // ...or runnable variation - ((ExtendedSpanBuilder) tracer.spanBuilder("reset_checkout")) + extendedTracer + .spanBuilder("reset_checkout") .startAndRun(() -> resetCheckout("abc123", /* throwException= */ false)); // Wrap the resetCheckout method in a span; resetCheckout throws an exception try { - ((ExtendedSpanBuilder) tracer.spanBuilder("reset_checkout_and_return")) + extendedTracer + .spanBuilder("reset_checkout_and_return") .startAndCall(() -> resetCheckoutAndReturn("def456", /* throwException= */ true)); } catch (Throwable e) { // Ignore expected exception } // ...or runnable variation try { - ((ExtendedSpanBuilder) tracer.spanBuilder("reset_checkout")) + extendedTracer + .spanBuilder("reset_checkout") .startAndRun(() -> resetCheckout("def456", /* throwException= */ true)); } catch (Throwable e) { // Ignore expected exception @@ -195,7 +200,8 @@ void startAndCallOrRun() { // Wrap the resetCheckout method in a span; resetCheckout throws an exception; use custom error // handler try { - ((ExtendedSpanBuilder) tracer.spanBuilder("reset_checkout_and_return")) + extendedTracer + .spanBuilder("reset_checkout_and_return") .startAndCall( () -> resetCheckoutAndReturn("ghi789", /* throwException= */ true), (span, throwable) -> span.setAttribute("my-attribute", "error")); @@ -204,7 +210,8 @@ void startAndCallOrRun() { } // ...or runnable variation try { - ((ExtendedSpanBuilder) tracer.spanBuilder("reset_checkout")) + extendedTracer + .spanBuilder("reset_checkout") .startAndRun( () -> resetCheckout("ghi789", /* throwException= */ true), (span, throwable) -> span.setAttribute("my-attribute", "error")); diff --git a/integration-tests/graal-incubating/src/test/java/io/opentelemetry/integrationtests/graal/IncubatingApiTests.java b/integration-tests/graal-incubating/src/test/java/io/opentelemetry/integrationtests/graal/IncubatingApiTests.java index 06ddcd006e1..fd3d0162dab 100644 --- a/integration-tests/graal-incubating/src/test/java/io/opentelemetry/integrationtests/graal/IncubatingApiTests.java +++ b/integration-tests/graal-incubating/src/test/java/io/opentelemetry/integrationtests/graal/IncubatingApiTests.java @@ -7,7 +7,6 @@ import static org.assertj.core.api.Assertions.assertThat; -import io.opentelemetry.api.incubator.logs.ExtendedLogRecordBuilder; import io.opentelemetry.api.incubator.logs.ExtendedLogger; import io.opentelemetry.api.incubator.metrics.ExtendedDoubleCounter; import io.opentelemetry.api.incubator.metrics.ExtendedDoubleGauge; @@ -18,7 +17,6 @@ import io.opentelemetry.api.incubator.metrics.ExtendedLongGauge; import io.opentelemetry.api.incubator.metrics.ExtendedLongHistogram; import io.opentelemetry.api.incubator.metrics.ExtendedLongUpDownCounter; -import io.opentelemetry.api.incubator.trace.ExtendedSpanBuilder; import io.opentelemetry.api.incubator.trace.ExtendedTracer; import io.opentelemetry.api.logs.LoggerProvider; import io.opentelemetry.api.metrics.Meter; @@ -53,7 +51,7 @@ void incubatingLogSdk() { ExtendedLogger logger = (ExtendedLogger) loggerProvider.get("logger"); logger.isEnabled(); - ((ExtendedLogRecordBuilder) logger.logRecordBuilder()).setBody("message").emit(); + logger.logRecordBuilder().setBody("message").emit(); } @Test @@ -64,7 +62,7 @@ void incubatingTraceSdk() { ExtendedTracer tracer = (ExtendedTracer) tracerProvider.get("tracer"); tracer.isEnabled(); - ((ExtendedSpanBuilder) tracer.spanBuilder("span")).startAndRun(() -> {}); + tracer.spanBuilder("span").startAndRun(() -> {}); } @Test diff --git a/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/ExtendedSdkTracer.java b/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/ExtendedSdkTracer.java index 7e339fd9a19..25de43faf88 100644 --- a/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/ExtendedSdkTracer.java +++ b/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/ExtendedSdkTracer.java @@ -5,6 +5,7 @@ package io.opentelemetry.sdk.trace; +import io.opentelemetry.api.incubator.trace.ExtendedSpanBuilder; import io.opentelemetry.api.incubator.trace.ExtendedTracer; import io.opentelemetry.sdk.common.InstrumentationScopeInfo; import io.opentelemetry.sdk.trace.internal.TracerConfig; @@ -27,4 +28,9 @@ final class ExtendedSdkTracer extends SdkTracer implements ExtendedTracer { public boolean isEnabled() { return tracerEnabled; } + + @Override + public ExtendedSpanBuilder spanBuilder(String spanName) { + return (ExtendedSpanBuilder) super.spanBuilder(spanName); + } } diff --git a/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/SdkTracer.java b/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/SdkTracer.java index 42210e56b28..0238d897907 100644 --- a/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/SdkTracer.java +++ b/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/SdkTracer.java @@ -53,6 +53,10 @@ static SdkTracer create( : new SdkTracer(sharedState, instrumentationScopeInfo, tracerConfig); } + /** + * Note that {@link ExtendedSdkTracer#spanBuilder(String)} calls this and depends on it returning + * {@link ExtendedSdkTracer} in all cases when the incubator is present. + */ @Override public SpanBuilder spanBuilder(String spanName) { if (!tracerEnabled) { @@ -62,8 +66,7 @@ public SpanBuilder spanBuilder(String spanName) { spanName = FALLBACK_SPAN_NAME; } if (sharedState.hasBeenShutdown()) { - Tracer tracer = TracerProvider.noop().get(instrumentationScopeInfo.getName()); - return tracer.spanBuilder(spanName); + return NOOP_TRACER.spanBuilder(spanName); } return INCUBATOR_AVAILABLE ? IncubatingUtil.createExtendedSpanBuilder( diff --git a/sdk/trace/src/testIncubating/java/io/opentelemetry/sdk/trace/ExtendedTracerTest.java b/sdk/trace/src/testIncubating/java/io/opentelemetry/sdk/trace/ExtendedTracerTest.java new file mode 100644 index 00000000000..c093b6da245 --- /dev/null +++ b/sdk/trace/src/testIncubating/java/io/opentelemetry/sdk/trace/ExtendedTracerTest.java @@ -0,0 +1,71 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.sdk.trace; + +import static io.opentelemetry.sdk.internal.ScopeConfiguratorBuilder.nameEquals; +import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.assertThat; +import static io.opentelemetry.sdk.trace.internal.TracerConfig.disabled; + +import io.opentelemetry.api.incubator.trace.ExtendedSpanBuilder; +import io.opentelemetry.api.incubator.trace.ExtendedTracer; +import io.opentelemetry.sdk.testing.exporter.InMemorySpanExporter; +import io.opentelemetry.sdk.trace.export.SimpleSpanProcessor; +import java.util.function.Supplier; +import java.util.stream.Stream; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; + +class ExtendedTracerTest { + + /** + * {@link ExtendedTracer#spanBuilder(String)} delegates to {@link SdkTracer#spanBuilder(String)} + * and casts the result to {@link ExtendedSpanBuilder}. Therefore, we need to confirm that {@link + * SdkTracer#spanBuilder(String)} correctly returns {@link ExtendedSpanBuilder} and not {@link + * io.opentelemetry.api.trace.SpanBuilder} in all cases, else the user will get {@link + * ClassCastException}. + */ + @ParameterizedTest + @MethodSource("spanBuilderArgs") + void spanBuilder(Supplier spanBuilderSupplier) { + ExtendedSpanBuilder spanBuilder = spanBuilderSupplier.get(); + assertThat(spanBuilder).isInstanceOf(ExtendedSpanBuilder.class); + } + + private static Stream spanBuilderArgs() { + SdkTracerProvider tracerProvider = + SdkTracerProvider.builder() + .addSpanProcessor(SimpleSpanProcessor.create(InMemorySpanExporter.create())) + .addTracerConfiguratorCondition(nameEquals("tracerB"), disabled()) + .build(); + + ExtendedTracer tracerA = (ExtendedTracer) tracerProvider.get("tracerA"); + ExtendedTracer tracerB = (ExtendedTracer) tracerProvider.get("tracerB"); + + SdkTracerProvider tracerProvider2 = + SdkTracerProvider.builder() + .addSpanProcessor(SimpleSpanProcessor.create(InMemorySpanExporter.create())) + .build(); + ExtendedTracer tracerC = (ExtendedTracer) tracerProvider.get("tracerC"); + tracerProvider2.shutdown(); + + return Stream.of( + // Simple case + Arguments.of(spanBuilderSupplier(() -> tracerA.spanBuilder("span"))), + // Disabled tracer + Arguments.of(spanBuilderSupplier(() -> tracerB.spanBuilder("span"))), + // Invalid span name + Arguments.of(spanBuilderSupplier(() -> tracerB.spanBuilder(null))), + Arguments.of(spanBuilderSupplier(() -> tracerB.spanBuilder(" "))), + // Shutdown tracer provider + Arguments.of(spanBuilderSupplier(() -> tracerC.spanBuilder("span")))); + } + + private static Supplier spanBuilderSupplier( + Supplier spanBuilderSupplier) { + return spanBuilderSupplier; + } +} From bfd87cad4ee30c55667d0924062fbf83616637bf Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 14 Jan 2025 11:15:00 -0800 Subject: [PATCH 757/901] fix(deps): update dependency org.owasp:dependency-check-gradle to v12 (#7011) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- buildSrc/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts index 6854f70ace0..f59e21d7b22 100644 --- a/buildSrc/build.gradle.kts +++ b/buildSrc/build.gradle.kts @@ -66,7 +66,7 @@ dependencies { implementation("net.ltgt.gradle:gradle-errorprone-plugin:4.1.0") implementation("net.ltgt.gradle:gradle-nullaway-plugin:2.2.0") implementation("org.jetbrains.kotlin:kotlin-gradle-plugin:2.1.0") - implementation("org.owasp:dependency-check-gradle:11.1.1") + implementation("org.owasp:dependency-check-gradle:12.0.0") implementation("ru.vyarus:gradle-animalsniffer-plugin:1.7.2") } From c8da0201abce6e78dfc3bad36fb2fd034da33a4d Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 14 Jan 2025 12:16:32 -0800 Subject: [PATCH 758/901] fix(deps): update dependency io.netty:netty-bom to v4.1.117.final (#7016) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- dependencyManagement/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index 6d4ffa90d17..e82a7112253 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -15,7 +15,7 @@ val DEPENDENCY_BOMS = listOf( "com.squareup.okhttp3:okhttp-bom:4.12.0", "com.squareup.okio:okio-bom:3.10.2", // applies to transitive dependencies of okhttp "io.grpc:grpc-bom:1.69.0", - "io.netty:netty-bom:4.1.116.Final", + "io.netty:netty-bom:4.1.117.Final", "io.zipkin.brave:brave-bom:6.0.3", "io.zipkin.reporter2:zipkin-reporter-bom:3.4.3", "org.assertj:assertj-bom:3.27.2", From 2fb3ebad3d1b75de8089c508eca89c536a31edaa Mon Sep 17 00:00:00 2001 From: Jonathan Halliday Date: Thu, 16 Jan 2025 20:28:05 +0000 Subject: [PATCH 759/901] Add AttributeKeyValue abstraction to common otlp exporters (#7026) --- exporters/otlp/common/build.gradle.kts | 2 + .../internal/otlp/AttributeKeyValue.java | 50 +++++++++++++++++++ .../internal/otlp/AttributeKeyValueImpl.java | 19 +++++++ .../internal/otlp/KeyValueMarshaler.java | 23 +++++++++ .../internal/otlp/AttributeKeyValueTest.java | 49 ++++++++++++++++++ 5 files changed, 143 insertions(+) create mode 100644 exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/AttributeKeyValue.java create mode 100644 exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/AttributeKeyValueImpl.java create mode 100644 exporters/otlp/common/src/test/java/io/opentelemetry/exporter/internal/otlp/AttributeKeyValueTest.java diff --git a/exporters/otlp/common/build.gradle.kts b/exporters/otlp/common/build.gradle.kts index 0e74e8829a7..94d50e46fd0 100644 --- a/exporters/otlp/common/build.gradle.kts +++ b/exporters/otlp/common/build.gradle.kts @@ -15,6 +15,8 @@ val versions: Map by project dependencies { protoSource("io.opentelemetry.proto:opentelemetry-proto:${versions["io.opentelemetry.proto"]}") + annotationProcessor("com.google.auto.value:auto-value") + api(project(":exporters:common")) compileOnly(project(":sdk:metrics")) diff --git a/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/AttributeKeyValue.java b/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/AttributeKeyValue.java new file mode 100644 index 00000000000..2b3cc82519e --- /dev/null +++ b/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/AttributeKeyValue.java @@ -0,0 +1,50 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.exporter.internal.otlp; + +import io.opentelemetry.api.common.AttributeKey; +import io.opentelemetry.api.common.Attributes; +import io.opentelemetry.api.common.KeyValue; +import java.util.ArrayList; +import java.util.List; + +/** + * Key-value pair of {@link AttributeKey} key and its corresponding value. + * + *

      Conceptually if {@link Attributes} is a Map, then this is a Map.Entry. Note that whilst {@link + * KeyValue} is similar, this class holds type information on the Key rather than the value. + * + *

      NOTE: This class is only used in the profiling signal, and exists in this module and package + * because its a common dependency of the modules that use it. Long term, it probably makes more + * sense to live in {@code opentelemetry-sdk-profiles} once such a module exists. + * + *

      This class is internal and is hence not for public use. Its APIs are unstable and can change + * at any time. + */ +public interface AttributeKeyValue { + + /** Returns a {@link AttributeKeyValue} for the given {@link AttributeKey} and {@code value}. */ + static AttributeKeyValue of(AttributeKey attributeKey, T value) { + return AttributeKeyValueImpl.create(attributeKey, value); + } + + /** Returns a List corresponding to the provided Map. This is a copy, not a view. */ + @SuppressWarnings("unchecked") + static List> of(Attributes attributes) { + List> result = new ArrayList<>(attributes.size()); + attributes.forEach( + (key, value) -> { + result.add(of((AttributeKey) key, (T) value)); + }); + return result; + } + + /** Returns the key. */ + AttributeKey getAttributeKey(); + + /** Returns the value. */ + T getValue(); +} diff --git a/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/AttributeKeyValueImpl.java b/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/AttributeKeyValueImpl.java new file mode 100644 index 00000000000..c4f6cdf89ca --- /dev/null +++ b/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/AttributeKeyValueImpl.java @@ -0,0 +1,19 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.exporter.internal.otlp; + +import com.google.auto.value.AutoValue; +import io.opentelemetry.api.common.AttributeKey; + +@AutoValue +abstract class AttributeKeyValueImpl implements AttributeKeyValue { + + AttributeKeyValueImpl() {} + + static AttributeKeyValueImpl create(AttributeKey attributeKey, T value) { + return new AutoValue_AttributeKeyValueImpl(attributeKey, value); + } +} diff --git a/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/KeyValueMarshaler.java b/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/KeyValueMarshaler.java index 47a0a32a759..08b9699291d 100644 --- a/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/KeyValueMarshaler.java +++ b/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/KeyValueMarshaler.java @@ -17,6 +17,7 @@ import java.nio.charset.StandardCharsets; import java.util.List; import java.util.function.BiConsumer; +import java.util.function.Consumer; /** * A Marshaler of key value pairs. @@ -65,6 +66,28 @@ public void accept(AttributeKey attributeKey, Object o) { return marshalers; } + @SuppressWarnings("AvoidObjectArrays") + public static KeyValueMarshaler[] createRepeated(List> items) { + if (items.isEmpty()) { + return EMPTY_REPEATED; + } + + KeyValueMarshaler[] keyValueMarshalers = new KeyValueMarshaler[items.size()]; + items.forEach( + item -> + new Consumer>() { + int index = 0; + + @Override + public void accept(AttributeKeyValue attributeKeyValue) { + keyValueMarshalers[index++] = + KeyValueMarshaler.create( + attributeKeyValue.getAttributeKey(), attributeKeyValue.getValue()); + } + }); + return keyValueMarshalers; + } + @SuppressWarnings("unchecked") private static KeyValueMarshaler create(AttributeKey attributeKey, Object value) { byte[] keyUtf8; diff --git a/exporters/otlp/common/src/test/java/io/opentelemetry/exporter/internal/otlp/AttributeKeyValueTest.java b/exporters/otlp/common/src/test/java/io/opentelemetry/exporter/internal/otlp/AttributeKeyValueTest.java new file mode 100644 index 00000000000..220b3845352 --- /dev/null +++ b/exporters/otlp/common/src/test/java/io/opentelemetry/exporter/internal/otlp/AttributeKeyValueTest.java @@ -0,0 +1,49 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.exporter.internal.otlp; + +import static org.assertj.core.api.Assertions.assertThat; + +import io.opentelemetry.api.common.AttributeKey; +import io.opentelemetry.api.common.AttributeType; +import io.opentelemetry.api.common.Attributes; +import java.util.Collections; +import java.util.List; +import nl.jqno.equalsverifier.EqualsVerifier; +import org.assertj.core.api.Assertions; +import org.junit.jupiter.api.Test; + +class AttributeKeyValueTest { + + @Test + void equalsVerifier() { + EqualsVerifier.forClass(AttributeKeyValue.class).verify(); + } + + @Test + void ofEmpty() { + assertThat(AttributeKeyValue.of(Attributes.empty())).isEmpty(); + } + + @Test + void ofOne() { + AttributeKeyValue input = AttributeKeyValue.of(AttributeKey.stringKey("foo"), "bar"); + Attributes attributes = Attributes.of(input.getAttributeKey(), input.getValue()); + List> list = AttributeKeyValue.of(attributes); + Assertions.assertThat(list).hasSize(1); + assertThat(list.get(0)).isEqualTo(input); + } + + @Test + void ofList() { + AttributeKeyValue> input = + AttributeKeyValue.of(AttributeKey.longArrayKey("foo"), Collections.emptyList()); + Attributes attributes = Attributes.of(input.getAttributeKey(), input.getValue()); + List> list = AttributeKeyValue.of(attributes); + Assertions.assertThat(list).hasSize(1); + assertThat(list.get(0).getAttributeKey().getType()).isEqualTo(AttributeType.LONG_ARRAY); + } +} From 97410cb24a581e888a6795c38391babce224d78f Mon Sep 17 00:00:00 2001 From: Trask Stalnaker Date: Thu, 16 Jan 2025 13:02:41 -0800 Subject: [PATCH 760/901] Add event name as an incubating feature (#7012) Co-authored-by: jack-berg <34418638+jack-berg@users.noreply.github.com> --- .../incubator/logs/ExtendedDefaultLogger.java | 14 +- .../logs/ExtendedLogRecordBuilder.java | 9 +- .../api/incubator/logs/ExtendedLogger.java | 3 + .../internal/AbstractDefaultLoggerTest.java | 2 + .../logging/otlp/TestDataExporter.java | 4 +- .../test/resources/expected-logs-wrapper.json | 1 + .../src/test/resources/expected-logs.json | 1 + .../internal/otlp/logs/LogMarshaler.java | 22 +- .../otlp/logs/LogStatelessMarshaler.java | 11 + .../otlp/logs/LogsRequestMarshalerTest.java | 12 +- .../LowAllocationLogRequestMarshalerTest.java | 6 +- .../OtlpExporterIntegrationTest.java | 4 +- .../sdk/logs/ExtendedSdkLogRecordBuilder.java | 6 + .../sdk/logs/ExtendedSdkLogger.java | 6 + .../sdk/logs/ReadWriteLogRecord.java | 2 + .../sdk/logs/SdkLogRecordBuilder.java | 8 + .../sdk/logs/SdkLogRecordData.java | 12 +- .../sdk/logs/SdkReadWriteLogRecord.java | 6 + .../data/internal/ExtendedLogRecordData.java | 20 ++ .../sdk/logs/ReadWriteLogRecordTest.java | 1 + .../sdk/logs/SdkLogRecordBuilderTest.java | 4 + .../sdk/logs/SdkLoggerProviderTest.java | 4 + .../testing/assertj/LogRecordDataAssert.java | 2 + .../internal/TestExtendedLogRecordData.java | 191 ++++++++++++++++++ .../testing/assertj/LogAssertionsTest.java | 7 +- 25 files changed, 336 insertions(+), 22 deletions(-) create mode 100644 sdk/logs/src/main/java/io/opentelemetry/sdk/logs/data/internal/ExtendedLogRecordData.java create mode 100644 sdk/testing/src/main/java/io/opentelemetry/sdk/testing/logs/internal/TestExtendedLogRecordData.java diff --git a/api/incubator/src/main/java/io/opentelemetry/api/incubator/logs/ExtendedDefaultLogger.java b/api/incubator/src/main/java/io/opentelemetry/api/incubator/logs/ExtendedDefaultLogger.java index 3e8dce08e74..378af1c6b00 100644 --- a/api/incubator/src/main/java/io/opentelemetry/api/incubator/logs/ExtendedDefaultLogger.java +++ b/api/incubator/src/main/java/io/opentelemetry/api/incubator/logs/ExtendedDefaultLogger.java @@ -17,7 +17,8 @@ class ExtendedDefaultLogger implements ExtendedLogger { private static final Logger INSTANCE = new ExtendedDefaultLogger(); - private static final LogRecordBuilder NOOP_LOG_RECORD_BUILDER = new NoopLogRecordBuilder(); + private static final ExtendedLogRecordBuilder NOOP_LOG_RECORD_BUILDER = + new NoopExtendedLogRecordBuilder(); private ExtendedDefaultLogger() {} @@ -26,13 +27,18 @@ static Logger getNoop() { } @Override - public LogRecordBuilder logRecordBuilder() { + public ExtendedLogRecordBuilder logRecordBuilder() { return NOOP_LOG_RECORD_BUILDER; } - private static final class NoopLogRecordBuilder implements ExtendedLogRecordBuilder { + private static final class NoopExtendedLogRecordBuilder implements ExtendedLogRecordBuilder { - private NoopLogRecordBuilder() {} + private NoopExtendedLogRecordBuilder() {} + + @Override + public ExtendedLogRecordBuilder setEventName(String eventName) { + return this; + } @Override public LogRecordBuilder setTimestamp(long timestamp, TimeUnit unit) { diff --git a/api/incubator/src/main/java/io/opentelemetry/api/incubator/logs/ExtendedLogRecordBuilder.java b/api/incubator/src/main/java/io/opentelemetry/api/incubator/logs/ExtendedLogRecordBuilder.java index 4e8af8eee70..4a18baa07ed 100644 --- a/api/incubator/src/main/java/io/opentelemetry/api/incubator/logs/ExtendedLogRecordBuilder.java +++ b/api/incubator/src/main/java/io/opentelemetry/api/incubator/logs/ExtendedLogRecordBuilder.java @@ -10,6 +10,13 @@ /** Extended {@link LogRecordBuilder} with experimental APIs. */ public interface ExtendedLogRecordBuilder extends LogRecordBuilder { - // Nothing at the moment, but experimental methods may be added in the future. + // keep this class even if it is empty, since experimental methods may be added in the future. + /** + * Sets the event name, which identifies the class / type of the Event. + * + *

      This name should uniquely identify the event structure (both attributes and body). A log + * record with a non-empty event name is an Event. + */ + ExtendedLogRecordBuilder setEventName(String eventName); } diff --git a/api/incubator/src/main/java/io/opentelemetry/api/incubator/logs/ExtendedLogger.java b/api/incubator/src/main/java/io/opentelemetry/api/incubator/logs/ExtendedLogger.java index db5e2a3b029..de159406c0e 100644 --- a/api/incubator/src/main/java/io/opentelemetry/api/incubator/logs/ExtendedLogger.java +++ b/api/incubator/src/main/java/io/opentelemetry/api/incubator/logs/ExtendedLogger.java @@ -20,4 +20,7 @@ public interface ExtendedLogger extends Logger { default boolean isEnabled() { return true; } + + @Override + ExtendedLogRecordBuilder logRecordBuilder(); } diff --git a/api/testing-internal/src/main/java/io/opentelemetry/api/testing/internal/AbstractDefaultLoggerTest.java b/api/testing-internal/src/main/java/io/opentelemetry/api/testing/internal/AbstractDefaultLoggerTest.java index 82d9f0b1f67..4b38e6fab19 100644 --- a/api/testing-internal/src/main/java/io/opentelemetry/api/testing/internal/AbstractDefaultLoggerTest.java +++ b/api/testing-internal/src/main/java/io/opentelemetry/api/testing/internal/AbstractDefaultLoggerTest.java @@ -51,6 +51,8 @@ void buildAndEmit() { () -> getLogger() .logRecordBuilder() + // TODO (trask) once event name stabilizes + // .setEventName("event name") .setTimestamp(100, TimeUnit.SECONDS) .setTimestamp(Instant.now()) .setObservedTimestamp(100, TimeUnit.SECONDS) diff --git a/exporters/logging-otlp/src/test/java/io/opentelemetry/exporter/logging/otlp/TestDataExporter.java b/exporters/logging-otlp/src/test/java/io/opentelemetry/exporter/logging/otlp/TestDataExporter.java index 54032fca3e0..63040a9beb1 100644 --- a/exporters/logging-otlp/src/test/java/io/opentelemetry/exporter/logging/otlp/TestDataExporter.java +++ b/exporters/logging-otlp/src/test/java/io/opentelemetry/exporter/logging/otlp/TestDataExporter.java @@ -28,6 +28,7 @@ import io.opentelemetry.sdk.metrics.internal.data.ImmutableSumData; import io.opentelemetry.sdk.resources.Resource; import io.opentelemetry.sdk.testing.logs.TestLogRecordData; +import io.opentelemetry.sdk.testing.logs.internal.TestExtendedLogRecordData; import io.opentelemetry.sdk.testing.trace.TestSpanData; import io.opentelemetry.sdk.trace.data.EventData; import io.opentelemetry.sdk.trace.data.SpanData; @@ -47,13 +48,14 @@ abstract class TestDataExporter { Resource.create(Attributes.builder().put("key", "value").build()); private static final LogRecordData LOG1 = - TestLogRecordData.builder() + TestExtendedLogRecordData.builder() .setResource(RESOURCE) .setInstrumentationScopeInfo( InstrumentationScopeInfo.builder("instrumentation") .setVersion("1") .setAttributes(Attributes.builder().put("key", "value").build()) .build()) + .setEventName("event name") .setBody("body1") .setSeverity(Severity.INFO) .setSeverityText("INFO") diff --git a/exporters/logging-otlp/src/test/resources/expected-logs-wrapper.json b/exporters/logging-otlp/src/test/resources/expected-logs-wrapper.json index 887fdb13d4b..c298d824182 100644 --- a/exporters/logging-otlp/src/test/resources/expected-logs-wrapper.json +++ b/exporters/logging-otlp/src/test/resources/expected-logs-wrapper.json @@ -27,6 +27,7 @@ }, "logRecords": [ { + "eventName": "event name", "timeUnixNano": "100", "observedTimeUnixNano": "200", "severityNumber": 9, diff --git a/exporters/logging-otlp/src/test/resources/expected-logs.json b/exporters/logging-otlp/src/test/resources/expected-logs.json index fe84d67c4ef..6eae7f28ad3 100644 --- a/exporters/logging-otlp/src/test/resources/expected-logs.json +++ b/exporters/logging-otlp/src/test/resources/expected-logs.json @@ -25,6 +25,7 @@ }, "logRecords": [ { + "eventName": "event name", "timeUnixNano": "100", "observedTimeUnixNano": "200", "severityNumber": 9, diff --git a/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/logs/LogMarshaler.java b/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/logs/LogMarshaler.java index 530e38dbe05..0ad265e9655 100644 --- a/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/logs/LogMarshaler.java +++ b/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/logs/LogMarshaler.java @@ -19,12 +19,14 @@ import io.opentelemetry.proto.logs.v1.internal.LogRecord; import io.opentelemetry.proto.logs.v1.internal.SeverityNumber; import io.opentelemetry.sdk.logs.data.LogRecordData; +import io.opentelemetry.sdk.logs.data.internal.ExtendedLogRecordData; import java.io.IOException; import javax.annotation.Nullable; final class LogMarshaler extends MarshalerWithSize { private static final String INVALID_TRACE_ID = TraceId.getInvalid(); private static final String INVALID_SPAN_ID = SpanId.getInvalid(); + private static final byte[] EMPTY_BYTES = new byte[0]; private final long timeUnixNano; private final long observedTimeUnixNano; @@ -36,6 +38,7 @@ final class LogMarshaler extends MarshalerWithSize { private final TraceFlags traceFlags; @Nullable private final String traceId; @Nullable private final String spanId; + private final byte[] eventName; static LogMarshaler create(LogRecordData logRecordData) { KeyValueMarshaler[] attributeMarshalers = @@ -57,7 +60,10 @@ static LogMarshaler create(LogRecordData logRecordData) { logRecordData.getTotalAttributeCount() - logRecordData.getAttributes().size(), spanContext.getTraceFlags(), spanContext.getTraceId().equals(INVALID_TRACE_ID) ? null : spanContext.getTraceId(), - spanContext.getSpanId().equals(INVALID_SPAN_ID) ? null : spanContext.getSpanId()); + spanContext.getSpanId().equals(INVALID_SPAN_ID) ? null : spanContext.getSpanId(), + logRecordData instanceof ExtendedLogRecordData + ? MarshalerUtil.toBytes(((ExtendedLogRecordData) logRecordData).getEventName()) + : EMPTY_BYTES); } private LogMarshaler( @@ -70,7 +76,8 @@ private LogMarshaler( int droppedAttributesCount, TraceFlags traceFlags, @Nullable String traceId, - @Nullable String spanId) { + @Nullable String spanId, + byte[] eventName) { super( calculateSize( timeUnixNano, @@ -82,7 +89,8 @@ private LogMarshaler( droppedAttributesCount, traceFlags, traceId, - spanId)); + spanId, + eventName)); this.timeUnixNano = timeUnixNano; this.observedTimeUnixNano = observedTimeUnixNano; this.traceId = traceId; @@ -93,6 +101,7 @@ private LogMarshaler( this.anyValueMarshaler = anyValueMarshaler; this.attributeMarshalers = attributeMarshalers; this.droppedAttributesCount = droppedAttributesCount; + this.eventName = eventName; } @Override @@ -115,6 +124,8 @@ protected void writeTo(Serializer output) throws IOException { output.serializeByteAsFixed32(LogRecord.FLAGS, traceFlags.asByte()); output.serializeTraceId(LogRecord.TRACE_ID, traceId); output.serializeSpanId(LogRecord.SPAN_ID, spanId); + + output.serializeString(LogRecord.EVENT_NAME, eventName); } private static int calculateSize( @@ -127,7 +138,8 @@ private static int calculateSize( int droppedAttributesCount, TraceFlags traceFlags, @Nullable String traceId, - @Nullable String spanId) { + @Nullable String spanId, + byte[] eventName) { int size = 0; size += MarshalerUtil.sizeFixed64(LogRecord.TIME_UNIX_NANO, timeUnixNano); @@ -147,6 +159,8 @@ private static int calculateSize( size += MarshalerUtil.sizeByteAsFixed32(LogRecord.FLAGS, traceFlags.asByte()); size += MarshalerUtil.sizeTraceId(LogRecord.TRACE_ID, traceId); size += MarshalerUtil.sizeSpanId(LogRecord.SPAN_ID, spanId); + + size += MarshalerUtil.sizeBytes(LogRecord.EVENT_NAME, eventName); return size; } diff --git a/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/logs/LogStatelessMarshaler.java b/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/logs/LogStatelessMarshaler.java index 1f16ebbe41c..1477af88ce6 100644 --- a/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/logs/LogStatelessMarshaler.java +++ b/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/logs/LogStatelessMarshaler.java @@ -19,6 +19,7 @@ import io.opentelemetry.exporter.internal.otlp.AttributeKeyValueStatelessMarshaler; import io.opentelemetry.proto.logs.v1.internal.LogRecord; import io.opentelemetry.sdk.logs.data.LogRecordData; +import io.opentelemetry.sdk.logs.data.internal.ExtendedLogRecordData; import java.io.IOException; /** See {@link LogMarshaler}. */ @@ -55,6 +56,10 @@ public void writeTo(Serializer output, LogRecordData log, MarshalerContext conte if (!spanContext.getSpanId().equals(INVALID_SPAN_ID)) { output.serializeSpanId(LogRecord.SPAN_ID, spanContext.getSpanId(), context); } + if (log instanceof ExtendedLogRecordData) { + output.serializeStringWithContext( + LogRecord.EVENT_NAME, ((ExtendedLogRecordData) log).getEventName(), context); + } } @Override @@ -93,6 +98,12 @@ public int getBinarySerializedSize(LogRecordData log, MarshalerContext context) size += MarshalerUtil.sizeSpanId(LogRecord.SPAN_ID, spanContext.getSpanId()); } + if (log instanceof ExtendedLogRecordData) { + size += + StatelessMarshalerUtil.sizeStringWithContext( + LogRecord.EVENT_NAME, ((ExtendedLogRecordData) log).getEventName(), context); + } + return size; } } diff --git a/exporters/otlp/common/src/test/java/io/opentelemetry/exporter/internal/otlp/logs/LogsRequestMarshalerTest.java b/exporters/otlp/common/src/test/java/io/opentelemetry/exporter/internal/otlp/logs/LogsRequestMarshalerTest.java index 9c01ddc7aed..0e54a10f0e2 100644 --- a/exporters/otlp/common/src/test/java/io/opentelemetry/exporter/internal/otlp/logs/LogsRequestMarshalerTest.java +++ b/exporters/otlp/common/src/test/java/io/opentelemetry/exporter/internal/otlp/logs/LogsRequestMarshalerTest.java @@ -33,7 +33,7 @@ import io.opentelemetry.sdk.common.InstrumentationScopeInfo; import io.opentelemetry.sdk.logs.data.LogRecordData; import io.opentelemetry.sdk.resources.Resource; -import io.opentelemetry.sdk.testing.logs.TestLogRecordData; +import io.opentelemetry.sdk.testing.logs.internal.TestExtendedLogRecordData; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.UncheckedIOException; @@ -52,6 +52,7 @@ class LogsRequestMarshalerTest { private static final String TRACE_ID = TraceId.fromBytes(TRACE_ID_BYTES); private static final byte[] SPAN_ID_BYTES = new byte[] {0, 0, 0, 0, 4, 3, 2, 1}; private static final String SPAN_ID = SpanId.fromBytes(SPAN_ID_BYTES); + private static final String EVENT_NAME = "hello"; private static final String BODY = "Hello world from this log..."; @Test @@ -59,7 +60,7 @@ void toProtoResourceLogs() { ResourceLogsMarshaler[] resourceLogsMarshalers = ResourceLogsMarshaler.create( Collections.singleton( - TestLogRecordData.builder() + TestExtendedLogRecordData.builder() .setResource( Resource.builder().put("one", 1).setSchemaUrl("http://url").build()) .setInstrumentationScopeInfo( @@ -68,6 +69,7 @@ void toProtoResourceLogs() { .setSchemaUrl("http://url") .setAttributes(Attributes.builder().put("key", "value").build()) .build()) + .setEventName(EVENT_NAME) .setBody(BODY) .setSeverity(Severity.INFO) .setSeverityText("INFO") @@ -108,11 +110,12 @@ void toProtoLogRecord(MarshalerSource marshalerSource) { parse( LogRecord.getDefaultInstance(), marshalerSource.create( - TestLogRecordData.builder() + TestExtendedLogRecordData.builder() .setResource( Resource.create(Attributes.builder().put("testKey", "testValue").build())) .setInstrumentationScopeInfo( InstrumentationScopeInfo.builder("instrumentation").setVersion("1").build()) + .setEventName(EVENT_NAME) .setBody(BODY) .setSeverity(Severity.INFO) .setSeverityText("INFO") @@ -128,6 +131,7 @@ void toProtoLogRecord(MarshalerSource marshalerSource) { assertThat(logRecord.getTraceId().toByteArray()).isEqualTo(TRACE_ID_BYTES); assertThat(logRecord.getSpanId().toByteArray()).isEqualTo(SPAN_ID_BYTES); assertThat(logRecord.getSeverityText()).isEqualTo("INFO"); + assertThat(logRecord.getEventName()).isEqualTo(EVENT_NAME); assertThat(logRecord.getBody()).isEqualTo(AnyValue.newBuilder().setStringValue(BODY).build()); assertThat(logRecord.getAttributesList()) .containsExactly( @@ -147,7 +151,7 @@ void toProtoLogRecord_MinimalFields(MarshalerSource marshalerSource) { parse( LogRecord.getDefaultInstance(), marshalerSource.create( - TestLogRecordData.builder() + TestExtendedLogRecordData.builder() .setResource( Resource.create(Attributes.builder().put("testKey", "testValue").build())) .setInstrumentationScopeInfo( diff --git a/exporters/otlp/common/src/test/java/io/opentelemetry/exporter/internal/otlp/logs/LowAllocationLogRequestMarshalerTest.java b/exporters/otlp/common/src/test/java/io/opentelemetry/exporter/internal/otlp/logs/LowAllocationLogRequestMarshalerTest.java index 4890e02dd66..2d8d61e207d 100644 --- a/exporters/otlp/common/src/test/java/io/opentelemetry/exporter/internal/otlp/logs/LowAllocationLogRequestMarshalerTest.java +++ b/exporters/otlp/common/src/test/java/io/opentelemetry/exporter/internal/otlp/logs/LowAllocationLogRequestMarshalerTest.java @@ -16,7 +16,7 @@ import io.opentelemetry.sdk.common.InstrumentationScopeInfo; import io.opentelemetry.sdk.logs.data.LogRecordData; import io.opentelemetry.sdk.resources.Resource; -import io.opentelemetry.sdk.testing.logs.TestLogRecordData; +import io.opentelemetry.sdk.testing.logs.internal.TestExtendedLogRecordData; import java.io.ByteArrayOutputStream; import java.nio.charset.StandardCharsets; import java.util.ArrayList; @@ -39,6 +39,7 @@ class LowAllocationLogRequestMarshalerTest { AttributeKey.doubleArrayKey("key_double_array"); private static final AttributeKey> KEY_BOOLEAN_ARRAY = AttributeKey.booleanArrayKey("key_boolean_array"); + private static final String EVENT_NAME = "hello"; private static final String BODY = "Hello world from this log..."; private static final Resource RESOURCE = @@ -72,9 +73,10 @@ private static List createLogRecordDataList() { } private static LogRecordData createLogRecordData() { - return TestLogRecordData.builder() + return TestExtendedLogRecordData.builder() .setResource(RESOURCE) .setInstrumentationScopeInfo(INSTRUMENTATION_SCOPE_INFO) + .setEventName(EVENT_NAME) .setBody(BODY) .setSeverity(Severity.INFO) .setSeverityText("INFO") diff --git a/integration-tests/otlp/src/main/java/io/opentelemetry/integrationtest/OtlpExporterIntegrationTest.java b/integration-tests/otlp/src/main/java/io/opentelemetry/integrationtest/OtlpExporterIntegrationTest.java index 9a0ffec76c6..578bb57eca5 100644 --- a/integration-tests/otlp/src/main/java/io/opentelemetry/integrationtest/OtlpExporterIntegrationTest.java +++ b/integration-tests/otlp/src/main/java/io/opentelemetry/integrationtest/OtlpExporterIntegrationTest.java @@ -648,8 +648,9 @@ private static void testLogRecordExporter(LogRecordExporter logRecordExporter) { TraceFlags.getDefault(), TraceState.getDefault()); - try (Scope unused = Span.wrap(spanContext).makeCurrent()) { + try (Scope ignored = Span.wrap(spanContext).makeCurrent()) { ((ExtendedLogRecordBuilder) logger.logRecordBuilder()) + .setEventName("event name") .setBody( of( KeyValue.of("str_key", of("value")), @@ -699,6 +700,7 @@ private static void testLogRecordExporter(LogRecordExporter logRecordExporter) { // LogRecord via Logger.logRecordBuilder()...emit() io.opentelemetry.proto.logs.v1.LogRecord protoLog1 = ilLogs.getLogRecords(0); + assertThat(protoLog1.getEventName()).isEqualTo("event name"); assertThat(protoLog1.getBody()) .isEqualTo( AnyValue.newBuilder() diff --git a/sdk/logs/src/main/java/io/opentelemetry/sdk/logs/ExtendedSdkLogRecordBuilder.java b/sdk/logs/src/main/java/io/opentelemetry/sdk/logs/ExtendedSdkLogRecordBuilder.java index ba1d0e6cfd2..9f874d1f4b3 100644 --- a/sdk/logs/src/main/java/io/opentelemetry/sdk/logs/ExtendedSdkLogRecordBuilder.java +++ b/sdk/logs/src/main/java/io/opentelemetry/sdk/logs/ExtendedSdkLogRecordBuilder.java @@ -23,6 +23,12 @@ final class ExtendedSdkLogRecordBuilder extends SdkLogRecordBuilder super(loggerSharedState, instrumentationScopeInfo); } + @Override + public ExtendedSdkLogRecordBuilder setEventName(String eventName) { + super.setEventName(eventName); + return this; + } + @Override public ExtendedSdkLogRecordBuilder setTimestamp(long timestamp, TimeUnit unit) { super.setTimestamp(timestamp, unit); diff --git a/sdk/logs/src/main/java/io/opentelemetry/sdk/logs/ExtendedSdkLogger.java b/sdk/logs/src/main/java/io/opentelemetry/sdk/logs/ExtendedSdkLogger.java index 67813bb933d..e3ab57a9711 100644 --- a/sdk/logs/src/main/java/io/opentelemetry/sdk/logs/ExtendedSdkLogger.java +++ b/sdk/logs/src/main/java/io/opentelemetry/sdk/logs/ExtendedSdkLogger.java @@ -5,6 +5,7 @@ package io.opentelemetry.sdk.logs; +import io.opentelemetry.api.incubator.logs.ExtendedLogRecordBuilder; import io.opentelemetry.api.incubator.logs.ExtendedLogger; import io.opentelemetry.sdk.common.InstrumentationScopeInfo; import io.opentelemetry.sdk.logs.internal.LoggerConfig; @@ -26,4 +27,9 @@ final class ExtendedSdkLogger extends SdkLogger implements ExtendedLogger { public boolean isEnabled() { return loggerEnabled; } + + @Override + public ExtendedLogRecordBuilder logRecordBuilder() { + return (ExtendedLogRecordBuilder) super.logRecordBuilder(); + } } diff --git a/sdk/logs/src/main/java/io/opentelemetry/sdk/logs/ReadWriteLogRecord.java b/sdk/logs/src/main/java/io/opentelemetry/sdk/logs/ReadWriteLogRecord.java index 03639e31e9f..8b69483d2a8 100644 --- a/sdk/logs/src/main/java/io/opentelemetry/sdk/logs/ReadWriteLogRecord.java +++ b/sdk/logs/src/main/java/io/opentelemetry/sdk/logs/ReadWriteLogRecord.java @@ -52,6 +52,8 @@ default ReadWriteLogRecord setAllAttributes(Attributes attributes) { /** Return an immutable {@link LogRecordData} instance representing this log record. */ LogRecordData toLogRecordData(); + // TODO (trask) once event name stabilizes, add getEventName() + /** * Returns the value of a given attribute if it exists. This is the equivalent of calling {@code * getAttributes().get(key)}. diff --git a/sdk/logs/src/main/java/io/opentelemetry/sdk/logs/SdkLogRecordBuilder.java b/sdk/logs/src/main/java/io/opentelemetry/sdk/logs/SdkLogRecordBuilder.java index ce43bc8d2c6..da7e1f45e7e 100644 --- a/sdk/logs/src/main/java/io/opentelemetry/sdk/logs/SdkLogRecordBuilder.java +++ b/sdk/logs/src/main/java/io/opentelemetry/sdk/logs/SdkLogRecordBuilder.java @@ -24,6 +24,7 @@ class SdkLogRecordBuilder implements LogRecordBuilder { private final LogLimits logLimits; private final InstrumentationScopeInfo instrumentationScopeInfo; + @Nullable private String eventName; private long timestampEpochNanos; private long observedTimestampEpochNanos; @Nullable private Context context; @@ -39,6 +40,12 @@ class SdkLogRecordBuilder implements LogRecordBuilder { this.instrumentationScopeInfo = instrumentationScopeInfo; } + // accessible via ExtendedSdkLogRecordBuilder + SdkLogRecordBuilder setEventName(String eventName) { + this.eventName = eventName; + return this; + } + @Override public SdkLogRecordBuilder setTimestamp(long timestamp, TimeUnit unit) { this.timestampEpochNanos = unit.toNanos(timestamp); @@ -126,6 +133,7 @@ public void emit() { loggerSharedState.getLogLimits(), loggerSharedState.getResource(), instrumentationScopeInfo, + eventName, timestampEpochNanos, observedTimestampEpochNanos, Span.fromContext(context).getSpanContext(), diff --git a/sdk/logs/src/main/java/io/opentelemetry/sdk/logs/SdkLogRecordData.java b/sdk/logs/src/main/java/io/opentelemetry/sdk/logs/SdkLogRecordData.java index 1927a0ec572..eb8e966a7fd 100644 --- a/sdk/logs/src/main/java/io/opentelemetry/sdk/logs/SdkLogRecordData.java +++ b/sdk/logs/src/main/java/io/opentelemetry/sdk/logs/SdkLogRecordData.java @@ -11,7 +11,7 @@ import io.opentelemetry.api.logs.Severity; import io.opentelemetry.api.trace.SpanContext; import io.opentelemetry.sdk.common.InstrumentationScopeInfo; -import io.opentelemetry.sdk.logs.data.LogRecordData; +import io.opentelemetry.sdk.logs.data.internal.ExtendedLogRecordData; import io.opentelemetry.sdk.resources.Resource; import javax.annotation.Nullable; import javax.annotation.concurrent.Immutable; @@ -19,13 +19,14 @@ @AutoValue @AutoValue.CopyAnnotations @Immutable -abstract class SdkLogRecordData implements LogRecordData { +abstract class SdkLogRecordData implements ExtendedLogRecordData { SdkLogRecordData() {} static SdkLogRecordData create( Resource resource, InstrumentationScopeInfo instrumentationScopeInfo, + @Nullable String eventName, long epochNanos, long observedEpochNanos, SpanContext spanContext, @@ -44,13 +45,18 @@ static SdkLogRecordData create( severityText, attributes, totalAttributeCount, - body); + body, + eventName); } @Override @Nullable public abstract Value getBodyValue(); + @Override + @Nullable + public abstract String getEventName(); + @Override @SuppressWarnings("deprecation") // Implementation of deprecated method public io.opentelemetry.sdk.logs.data.Body getBody() { diff --git a/sdk/logs/src/main/java/io/opentelemetry/sdk/logs/SdkReadWriteLogRecord.java b/sdk/logs/src/main/java/io/opentelemetry/sdk/logs/SdkReadWriteLogRecord.java index e6c68ce6ec4..ad6197d8cf3 100644 --- a/sdk/logs/src/main/java/io/opentelemetry/sdk/logs/SdkReadWriteLogRecord.java +++ b/sdk/logs/src/main/java/io/opentelemetry/sdk/logs/SdkReadWriteLogRecord.java @@ -24,6 +24,7 @@ class SdkReadWriteLogRecord implements ReadWriteLogRecord { private final LogLimits logLimits; private final Resource resource; private final InstrumentationScopeInfo instrumentationScopeInfo; + @Nullable private final String eventName; private final long timestampEpochNanos; private final long observedTimestampEpochNanos; private final SpanContext spanContext; @@ -40,6 +41,7 @@ private SdkReadWriteLogRecord( LogLimits logLimits, Resource resource, InstrumentationScopeInfo instrumentationScopeInfo, + @Nullable String eventName, long timestampEpochNanos, long observedTimestampEpochNanos, SpanContext spanContext, @@ -50,6 +52,7 @@ private SdkReadWriteLogRecord( this.logLimits = logLimits; this.resource = resource; this.instrumentationScopeInfo = instrumentationScopeInfo; + this.eventName = eventName; this.timestampEpochNanos = timestampEpochNanos; this.observedTimestampEpochNanos = observedTimestampEpochNanos; this.spanContext = spanContext; @@ -64,6 +67,7 @@ static SdkReadWriteLogRecord create( LogLimits logLimits, Resource resource, InstrumentationScopeInfo instrumentationScopeInfo, + @Nullable String eventName, long timestampEpochNanos, long observedTimestampEpochNanos, SpanContext spanContext, @@ -75,6 +79,7 @@ static SdkReadWriteLogRecord create( logLimits, resource, instrumentationScopeInfo, + eventName, timestampEpochNanos, observedTimestampEpochNanos, spanContext, @@ -115,6 +120,7 @@ public LogRecordData toLogRecordData() { return SdkLogRecordData.create( resource, instrumentationScopeInfo, + eventName, timestampEpochNanos, observedTimestampEpochNanos, spanContext, diff --git a/sdk/logs/src/main/java/io/opentelemetry/sdk/logs/data/internal/ExtendedLogRecordData.java b/sdk/logs/src/main/java/io/opentelemetry/sdk/logs/data/internal/ExtendedLogRecordData.java new file mode 100644 index 00000000000..61e48eb7821 --- /dev/null +++ b/sdk/logs/src/main/java/io/opentelemetry/sdk/logs/data/internal/ExtendedLogRecordData.java @@ -0,0 +1,20 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.sdk.logs.data.internal; + +import io.opentelemetry.sdk.logs.data.LogRecordData; +import javax.annotation.Nullable; + +/** + * This class is internal and experimental. Its APIs are unstable and can change at any time. Its + * APIs (or a version of them) may be promoted to the public stable API in the future, but no + * guarantees are made. + */ +public interface ExtendedLogRecordData extends LogRecordData { + + @Nullable + String getEventName(); +} diff --git a/sdk/logs/src/test/java/io/opentelemetry/sdk/logs/ReadWriteLogRecordTest.java b/sdk/logs/src/test/java/io/opentelemetry/sdk/logs/ReadWriteLogRecordTest.java index 7a444817d40..95215ee57db 100644 --- a/sdk/logs/src/test/java/io/opentelemetry/sdk/logs/ReadWriteLogRecordTest.java +++ b/sdk/logs/src/test/java/io/opentelemetry/sdk/logs/ReadWriteLogRecordTest.java @@ -62,6 +62,7 @@ SdkReadWriteLogRecord buildLogRecord() { limits, resource, scope, + "event name", 0L, 0L, spanContext, diff --git a/sdk/logs/src/test/java/io/opentelemetry/sdk/logs/SdkLogRecordBuilderTest.java b/sdk/logs/src/test/java/io/opentelemetry/sdk/logs/SdkLogRecordBuilderTest.java index 3c5743e673d..0be11e67b31 100644 --- a/sdk/logs/src/test/java/io/opentelemetry/sdk/logs/SdkLogRecordBuilderTest.java +++ b/sdk/logs/src/test/java/io/opentelemetry/sdk/logs/SdkLogRecordBuilderTest.java @@ -60,6 +60,7 @@ void emit_AllFields() { Instant timestamp = Instant.now(); Instant observedTimestamp = Instant.now().plusNanos(100); + String eventName = "event name"; String bodyStr = "body"; String sevText = "sevText"; Severity severity = Severity.DEBUG3; @@ -70,6 +71,7 @@ void emit_AllFields() { TraceFlags.getSampled(), TraceState.getDefault()); + builder.setEventName(eventName); builder.setBody(bodyStr); builder.setTimestamp(123, TimeUnit.SECONDS); builder.setTimestamp(timestamp); @@ -85,6 +87,8 @@ void emit_AllFields() { assertThat(emittedLog.get().toLogRecordData()) .hasResource(RESOURCE) .hasInstrumentationScope(SCOPE_INFO) + // TODO (trask) once event name stabilizes + // .hasEventName(eventName) .hasBody(bodyStr) .hasTimestamp(TimeUnit.SECONDS.toNanos(timestamp.getEpochSecond()) + timestamp.getNano()) .hasObservedTimestamp( diff --git a/sdk/logs/src/test/java/io/opentelemetry/sdk/logs/SdkLoggerProviderTest.java b/sdk/logs/src/test/java/io/opentelemetry/sdk/logs/SdkLoggerProviderTest.java index 05da79ee3eb..63063731ac4 100644 --- a/sdk/logs/src/test/java/io/opentelemetry/sdk/logs/SdkLoggerProviderTest.java +++ b/sdk/logs/src/test/java/io/opentelemetry/sdk/logs/SdkLoggerProviderTest.java @@ -246,6 +246,8 @@ void loggerBuilder_WithLogRecordProcessor() { sdkLoggerProvider .get("test") .logRecordBuilder() + // TODO (trask) once event name stabilizes + // .setEventName("event name") .setTimestamp(100, TimeUnit.NANOSECONDS) .setContext(Span.wrap(spanContext).storeInContext(Context.root())) .setSeverity(Severity.DEBUG) @@ -258,6 +260,8 @@ void loggerBuilder_WithLogRecordProcessor() { assertThat(logRecordData.get()) .hasResource(resource) .hasInstrumentationScope(InstrumentationScopeInfo.create("test")) + // TODO (trask) once event name stabilizes + // .hasEventName("event name") .hasTimestamp(100) .hasSpanContext(spanContext) .hasSeverity(Severity.DEBUG) diff --git a/sdk/testing/src/main/java/io/opentelemetry/sdk/testing/assertj/LogRecordDataAssert.java b/sdk/testing/src/main/java/io/opentelemetry/sdk/testing/assertj/LogRecordDataAssert.java index e2256dcbbef..323e5b7813d 100644 --- a/sdk/testing/src/main/java/io/opentelemetry/sdk/testing/assertj/LogRecordDataAssert.java +++ b/sdk/testing/src/main/java/io/opentelemetry/sdk/testing/assertj/LogRecordDataAssert.java @@ -84,6 +84,8 @@ public LogRecordDataAssert hasInstrumentationScope( return this; } + // TODO (trask) once event name stabilizes, add hasEventName(String) + /** Asserts the log has the given epoch {@code timestamp}. */ public LogRecordDataAssert hasTimestamp(long timestampEpochNanos) { isNotNull(); diff --git a/sdk/testing/src/main/java/io/opentelemetry/sdk/testing/logs/internal/TestExtendedLogRecordData.java b/sdk/testing/src/main/java/io/opentelemetry/sdk/testing/logs/internal/TestExtendedLogRecordData.java new file mode 100644 index 00000000000..750344bf748 --- /dev/null +++ b/sdk/testing/src/main/java/io/opentelemetry/sdk/testing/logs/internal/TestExtendedLogRecordData.java @@ -0,0 +1,191 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.sdk.testing.logs.internal; + +import com.google.auto.value.AutoValue; +import io.opentelemetry.api.common.Attributes; +import io.opentelemetry.api.common.Value; +import io.opentelemetry.api.logs.Severity; +import io.opentelemetry.api.trace.SpanContext; +import io.opentelemetry.sdk.common.InstrumentationScopeInfo; +import io.opentelemetry.sdk.logs.data.LogRecordData; +import io.opentelemetry.sdk.logs.data.internal.ExtendedLogRecordData; +import io.opentelemetry.sdk.resources.Resource; +import java.time.Instant; +import java.util.concurrent.TimeUnit; +import javax.annotation.Nullable; +import javax.annotation.concurrent.Immutable; + +/** + * Immutable representation of {@link LogRecordData}. + * + *

      This class is internal and experimental. Its APIs are unstable and can change at any time. Its + * APIs (or a version of them) may be promoted to the public stable API in the future, but no + * guarantees are made. + * + * @since 1.27.0 + */ +// TODO (trask) delete this class once event name stabilizes +@Immutable +@AutoValue +@AutoValue.CopyAnnotations +// Carry suppression for Body to AutoValue implementation via @AutoValue.CopyAnnotations +@SuppressWarnings("deprecation") +public abstract class TestExtendedLogRecordData implements ExtendedLogRecordData { + + /** Creates a new Builder for creating an {@link LogRecordData} instance. */ + public static Builder builder() { + return new AutoValue_TestExtendedLogRecordData.Builder() + .setResource(Resource.empty()) + .setInstrumentationScopeInfo(InstrumentationScopeInfo.empty()) + .setTimestamp(0, TimeUnit.NANOSECONDS) + .setObservedTimestamp(0, TimeUnit.NANOSECONDS) + .setSpanContext(SpanContext.getInvalid()) + .setSeverity(Severity.UNDEFINED_SEVERITY_NUMBER) + .setAttributes(Attributes.empty()) + .setTotalAttributeCount(0); + } + + @Deprecated + public io.opentelemetry.sdk.logs.data.Body getBody() { + Value valueBody = getBodyValue(); + return valueBody == null + ? io.opentelemetry.sdk.logs.data.Body.empty() + : io.opentelemetry.sdk.logs.data.Body.string(valueBody.asString()); + } + + /** + * {@inheritDoc} + * + * @since 1.42.0 + */ + @Override + @Nullable + public abstract Value getBodyValue(); + + TestExtendedLogRecordData() {} + + /** + * A {@code Builder} class for {@link TestExtendedLogRecordData}. + * + *

      This class is internal and experimental. Its APIs are unstable and can change at any time. + * Its APIs (or a version of them) may be promoted to the public stable API in the future, but no + * guarantees are made. + */ + @AutoValue.Builder + public abstract static class Builder { + + abstract TestExtendedLogRecordData autoBuild(); + + /** Create a new {@link LogRecordData} instance from the data in this. */ + public TestExtendedLogRecordData build() { + return autoBuild(); + } + + /** Set the {@link Resource}. */ + public abstract Builder setResource(Resource resource); + + /** Sets the {@link InstrumentationScopeInfo}. */ + public abstract Builder setInstrumentationScopeInfo( + InstrumentationScopeInfo instrumentationScopeInfo); + + public abstract Builder setEventName(String eventName); + + /** + * Set the epoch {@code timestamp}, using the instant. + * + *

      The {@code timestamp} is the time at which the log record occurred. + */ + public Builder setTimestamp(Instant instant) { + return setTimestampEpochNanos( + TimeUnit.SECONDS.toNanos(instant.getEpochSecond()) + instant.getNano()); + } + + /** + * Set the epoch {@code timestamp}, using the timestamp and unit. + * + *

      The {@code timestamp} is the time at which the log record occurred. + */ + public Builder setTimestamp(long timestamp, TimeUnit unit) { + return setTimestampEpochNanos(unit.toNanos(timestamp)); + } + + /** + * Set the epoch {@code timestamp}. + * + *

      The {@code timestamp} is the time at which the log record occurred. + */ + abstract Builder setTimestampEpochNanos(long epochNanos); + + /** + * Set the {@code observedTimestamp}, using the instant. + * + *

      The {@code observedTimestamp} is the time at which the log record was observed. + */ + public Builder setObservedTimestamp(Instant instant) { + return setObservedTimestampEpochNanos( + TimeUnit.SECONDS.toNanos(instant.getEpochSecond()) + instant.getNano()); + } + + /** + * Set the epoch {@code observedTimestamp}, using the timestamp and unit. + * + *

      The {@code observedTimestamp} is the time at which the log record was observed. + */ + public Builder setObservedTimestamp(long timestamp, TimeUnit unit) { + return setObservedTimestampEpochNanos(unit.toNanos(timestamp)); + } + + /** + * Set the epoch {@code observedTimestamp}. + * + *

      The {@code observedTimestamp} is the time at which the log record was observed. + */ + abstract Builder setObservedTimestampEpochNanos(long epochNanos); + + /** Set the span context. */ + public abstract Builder setSpanContext(SpanContext spanContext); + + /** Set the severity. */ + public abstract Builder setSeverity(Severity severity); + + /** Set the severity text. */ + public abstract Builder setSeverityText(String severityText); + + /** Set the body string. */ + public Builder setBody(String body) { + return setBodyValue(Value.of(body)); + } + + /** + * Set the body. + * + * @deprecated Use {@link #setBodyValue(Value)}. + */ + @Deprecated + public Builder setBody(io.opentelemetry.sdk.logs.data.Body body) { + if (body.getType() == io.opentelemetry.sdk.logs.data.Body.Type.STRING) { + setBodyValue(Value.of(body.asString())); + } else if (body.getType() == io.opentelemetry.sdk.logs.data.Body.Type.EMPTY) { + setBodyValue(null); + } + return this; + } + + /** + * Set the body. + * + * @since 1.42.0 + */ + public abstract Builder setBodyValue(@Nullable Value body); + + /** Set the attributes. */ + public abstract Builder setAttributes(Attributes attributes); + + /** Set the total attribute count. */ + public abstract Builder setTotalAttributeCount(int totalAttributeCount); + } +} diff --git a/sdk/testing/src/test/java/io/opentelemetry/sdk/testing/assertj/LogAssertionsTest.java b/sdk/testing/src/test/java/io/opentelemetry/sdk/testing/assertj/LogAssertionsTest.java index 849ba25b90f..e30210eb9d6 100644 --- a/sdk/testing/src/test/java/io/opentelemetry/sdk/testing/assertj/LogAssertionsTest.java +++ b/sdk/testing/src/test/java/io/opentelemetry/sdk/testing/assertj/LogAssertionsTest.java @@ -34,7 +34,7 @@ import io.opentelemetry.sdk.logs.internal.SdkEventLoggerProvider; import io.opentelemetry.sdk.resources.Resource; import io.opentelemetry.sdk.testing.exporter.InMemoryLogRecordExporter; -import io.opentelemetry.sdk.testing.logs.TestLogRecordData; +import io.opentelemetry.sdk.testing.logs.internal.TestExtendedLogRecordData; import java.util.Arrays; import java.util.List; import java.util.concurrent.TimeUnit; @@ -62,9 +62,10 @@ public class LogAssertionsTest { .build(); private static final LogRecordData LOG_DATA = - TestLogRecordData.builder() + TestExtendedLogRecordData.builder() .setResource(RESOURCE) .setInstrumentationScopeInfo(INSTRUMENTATION_SCOPE_INFO) + .setEventName("event name") .setTimestamp(100, TimeUnit.NANOSECONDS) .setObservedTimestamp(200, TimeUnit.NANOSECONDS) .setSpanContext( @@ -112,6 +113,8 @@ void passing() { satisfies(DOG, val -> val.startsWith("bar")), satisfies(AttributeKey.booleanKey("dog is cute"), val -> val.isTrue()))) .hasInstrumentationScope(INSTRUMENTATION_SCOPE_INFO) + // TODO (trask) once event name stabilizes + // .hasEventName("event name") .hasTimestamp(100) .hasObservedTimestamp(200) .hasSpanContext( From a1c0d0bd64d39ab2f05b4a534527cf12920ba438 Mon Sep 17 00:00:00 2001 From: jack-berg <34418638+jack-berg@users.noreply.github.com> Date: Thu, 16 Jan 2025 15:25:33 -0600 Subject: [PATCH 761/901] Consistent application of exporter customizers when otel.{signal}.exporter=none (#7017) --- sdk-extensions/autoconfigure/build.gradle.kts | 1 - .../LogRecordExporterConfiguration.java | 8 +- .../SpanExporterConfiguration.java | 8 +- .../AutoConfiguredOpenTelemetrySdkTest.java | 84 ------------ .../sdk/autoconfigure/FullConfigTest.java | 124 ++++++++---------- .../provider/LogRecordCustomizer.java | 78 +++++++++++ .../provider/LogRecordExporterCustomizer.java | 47 ------- .../provider/MetricCustomizer.java | 1 + .../provider/SpanCustomizer.java | 102 ++++++++++++++ .../provider/SpanExporterCustomizer.java | 52 -------- ...re.spi.AutoConfigurationCustomizerProvider | 4 +- 11 files changed, 240 insertions(+), 269 deletions(-) create mode 100644 sdk-extensions/autoconfigure/src/testFullConfig/java/io/opentelemetry/sdk/autoconfigure/provider/LogRecordCustomizer.java delete mode 100644 sdk-extensions/autoconfigure/src/testFullConfig/java/io/opentelemetry/sdk/autoconfigure/provider/LogRecordExporterCustomizer.java create mode 100644 sdk-extensions/autoconfigure/src/testFullConfig/java/io/opentelemetry/sdk/autoconfigure/provider/SpanCustomizer.java delete mode 100644 sdk-extensions/autoconfigure/src/testFullConfig/java/io/opentelemetry/sdk/autoconfigure/provider/SpanExporterCustomizer.java diff --git a/sdk-extensions/autoconfigure/build.gradle.kts b/sdk-extensions/autoconfigure/build.gradle.kts index 7f0077178e5..df01e3d34d7 100644 --- a/sdk-extensions/autoconfigure/build.gradle.kts +++ b/sdk-extensions/autoconfigure/build.gradle.kts @@ -78,7 +78,6 @@ testing { environment("OTEL_PROPAGATORS", "tracecontext,baggage,b3,b3multi,jaeger,ottrace,test") environment("OTEL_EXPORTER_OTLP_HEADERS", "cat=meow,dog=bark") environment("OTEL_EXPORTER_OTLP_TIMEOUT", "5000") - environment("OTEL_SPAN_ATTRIBUTE_COUNT_LIMIT", "2") environment("OTEL_TEST_CONFIGURED", "true") environment("OTEL_TEST_WRAPPED", "1") } diff --git a/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/LogRecordExporterConfiguration.java b/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/LogRecordExporterConfiguration.java index ff70fa4d114..db0589ee183 100644 --- a/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/LogRecordExporterConfiguration.java +++ b/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/LogRecordExporterConfiguration.java @@ -48,13 +48,7 @@ static Map configureLogRecordExporters( throw new ConfigurationException( "otel.logs.exporter contains " + EXPORTER_NONE + " along with other exporters"); } - LogRecordExporter noop = LogRecordExporter.composite(); - LogRecordExporter customized = logRecordExporterCustomizer.apply(noop, config); - if (customized == noop) { - return Collections.emptyMap(); - } - closeables.add(customized); - return Collections.singletonMap(EXPORTER_NONE, customized); + return Collections.emptyMap(); } if (exporterNames.isEmpty()) { diff --git a/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/SpanExporterConfiguration.java b/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/SpanExporterConfiguration.java index 581ce575b81..74e6457125c 100644 --- a/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/SpanExporterConfiguration.java +++ b/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/SpanExporterConfiguration.java @@ -48,13 +48,7 @@ static Map configureSpanExporters( throw new ConfigurationException( "otel.traces.exporter contains " + EXPORTER_NONE + " along with other exporters"); } - SpanExporter noop = SpanExporter.composite(); - SpanExporter customized = spanExporterCustomizer.apply(noop, config); - if (customized == noop) { - return Collections.emptyMap(); - } - closeables.add(customized); - return Collections.singletonMap(EXPORTER_NONE, customized); + return Collections.emptyMap(); } if (exporterNames.isEmpty()) { diff --git a/sdk-extensions/autoconfigure/src/test/java/io/opentelemetry/sdk/autoconfigure/AutoConfiguredOpenTelemetrySdkTest.java b/sdk-extensions/autoconfigure/src/test/java/io/opentelemetry/sdk/autoconfigure/AutoConfiguredOpenTelemetrySdkTest.java index b42c1936130..ed2c94a7108 100644 --- a/sdk-extensions/autoconfigure/src/test/java/io/opentelemetry/sdk/autoconfigure/AutoConfiguredOpenTelemetrySdkTest.java +++ b/sdk-extensions/autoconfigure/src/test/java/io/opentelemetry/sdk/autoconfigure/AutoConfiguredOpenTelemetrySdkTest.java @@ -11,7 +11,6 @@ import static org.assertj.core.api.Assertions.assertThatCode; import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.same; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.doThrow; import static org.mockito.Mockito.mock; @@ -19,7 +18,6 @@ import static org.mockito.Mockito.spy; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.verifyNoInteractions; import static org.mockito.Mockito.verifyNoMoreInteractions; import static org.mockito.Mockito.when; @@ -54,14 +52,10 @@ import io.opentelemetry.sdk.resources.Resource; import io.opentelemetry.sdk.testing.exporter.InMemorySpanExporter; import io.opentelemetry.sdk.trace.IdGenerator; -import io.opentelemetry.sdk.trace.ReadWriteSpan; -import io.opentelemetry.sdk.trace.ReadableSpan; import io.opentelemetry.sdk.trace.SdkTracerProvider; import io.opentelemetry.sdk.trace.SdkTracerProviderBuilder; -import io.opentelemetry.sdk.trace.SpanProcessor; import io.opentelemetry.sdk.trace.data.SpanData; import io.opentelemetry.sdk.trace.export.SimpleSpanProcessor; -import io.opentelemetry.sdk.trace.export.SpanExporter; import io.opentelemetry.sdk.trace.samplers.Sampler; import java.io.IOException; import java.math.BigDecimal; @@ -98,8 +92,6 @@ class AutoConfiguredOpenTelemetrySdkTest { @Mock private TextMapGetter> getter; @Mock private Sampler sampler1; @Mock private Sampler sampler2; - @Mock private SpanExporter spanExporter1; - @Mock private SpanExporter spanExporter2; @Mock private MetricReader metricReader; @Mock private LogRecordProcessor logRecordProcessor; @@ -247,76 +239,6 @@ void builder_addSamplerCustomizer() { .isEqualTo(sampler2); } - @Test - void builder_addSpanExporterCustomizer() { - Mockito.lenient().when(spanExporter2.shutdown()).thenReturn(CompletableResultCode.ofSuccess()); - - SdkTracerProvider sdkTracerProvider = - builder - .addSpanExporterCustomizer( - (previous, config) -> { - assertThat(previous).isSameAs(SpanExporter.composite()); - return spanExporter1; - }) - .addSpanExporterCustomizer( - (previous, config) -> { - assertThat(previous).isSameAs(spanExporter1); - return spanExporter2; - }) - .build() - .getOpenTelemetrySdk() - .getSdkTracerProvider(); - - assertThat(sdkTracerProvider) - .extracting("sharedState") - .extracting("activeSpanProcessor") - .extracting("worker") - .extracting("spanExporter") - .isEqualTo(spanExporter2); - } - - @Test - void builder_addSpanProcessorCustomizer() { - SpanProcessor mockProcessor1 = Mockito.mock(SpanProcessor.class); - SpanProcessor mockProcessor2 = Mockito.mock(SpanProcessor.class); - when(mockProcessor2.isStartRequired()).thenReturn(true); - when(mockProcessor2.isEndRequired()).thenReturn(true); - Mockito.lenient().doReturn(CompletableResultCode.ofSuccess()).when(mockProcessor2).shutdown(); - Mockito.lenient().when(spanExporter1.shutdown()).thenReturn(CompletableResultCode.ofSuccess()); - - SdkTracerProvider sdkTracerProvider = - builder - .addSpanExporterCustomizer((prev, config) -> spanExporter1) - .addSpanProcessorCustomizer( - (previous, config) -> { - assertThat(previous).isNotSameAs(mockProcessor2); - return mockProcessor1; - }) - .addSpanProcessorCustomizer( - (previous, config) -> { - assertThat(previous).isSameAs(mockProcessor1); - return mockProcessor2; - }) - .build() - .getOpenTelemetrySdk() - .getSdkTracerProvider(); - - assertThat(sdkTracerProvider) - .extracting("sharedState") - .extracting("activeSpanProcessor") - .isSameAs(mockProcessor2); - - Span span = sdkTracerProvider.get("dummy-scope").spanBuilder("dummy-span").startSpan(); - - verify(mockProcessor2).onStart(any(), same((ReadWriteSpan) span)); - - span.end(); - verify(mockProcessor2).onEnd(same((ReadableSpan) span)); - - verifyNoInteractions(mockProcessor1); - verifyNoInteractions(spanExporter1); - } - @Test void builder_addAutoConfigurationCustomizerProviderUsingComponentLoader() { AutoConfigurationCustomizerProvider customizerProvider = @@ -420,8 +342,6 @@ void builder_addMeterProviderCustomizer() { verify(metricReader).forceFlush(); } - // TODO: add test for addMetricExporterCustomizer once OTLP export is enabled by default - @Test void builder_addLoggerProviderCustomizer() { Mockito.lenient() @@ -442,10 +362,6 @@ void builder_addLoggerProviderCustomizer() { verify(logRecordProcessor).forceFlush(); } - // TODO: add test for addLogRecordExporterCustomizer once OTLP export is enabled by default - - // TODO: add test for addLogRecordProcessorCustomizer once OTLP export is enabled by default - @Test void builder_setResultAsGlobalFalse() { GlobalOpenTelemetry.set(OpenTelemetry.noop()); diff --git a/sdk-extensions/autoconfigure/src/testFullConfig/java/io/opentelemetry/sdk/autoconfigure/FullConfigTest.java b/sdk-extensions/autoconfigure/src/testFullConfig/java/io/opentelemetry/sdk/autoconfigure/FullConfigTest.java index e4ac7963ea8..96fd7e3eb61 100644 --- a/sdk-extensions/autoconfigure/src/testFullConfig/java/io/opentelemetry/sdk/autoconfigure/FullConfigTest.java +++ b/sdk-extensions/autoconfigure/src/testFullConfig/java/io/opentelemetry/sdk/autoconfigure/FullConfigTest.java @@ -53,7 +53,7 @@ import org.junit.jupiter.api.extension.RegisterExtension; @SuppressWarnings("InterruptedExceptionSwallowed") -class FullConfigTest { +public class FullConfigTest { private static final BlockingQueue otlpTraceRequests = new LinkedBlockingDeque<>(); @@ -193,7 +193,6 @@ void configures() throws Exception { .spanBuilder("test") .startSpan() .setAttribute("cat", "meow") - .setAttribute("dog", "bark") .end(); Meter meter = GlobalOpenTelemetry.get().getMeter("test"); @@ -209,7 +208,6 @@ void configures() throws Exception { EventLogger eventLogger = GlobalEventLoggerProvider.get().eventLoggerBuilder("test").build(); eventLogger.builder("namespace.test-name").put("cow", "moo").emit(); - ; openTelemetrySdk.getSdkTracerProvider().forceFlush().join(10, TimeUnit.SECONDS); openTelemetrySdk.getSdkLoggerProvider().forceFlush().join(10, TimeUnit.SECONDS); @@ -218,37 +216,19 @@ void configures() throws Exception { await().untilAsserted(() -> assertThat(otlpTraceRequests).hasSize(1)); ExportTraceServiceRequest traceRequest = otlpTraceRequests.take(); - assertThat(traceRequest.getResourceSpans(0).getResource().getAttributesList()) - .contains( - KeyValue.newBuilder() - .setKey("service.name") - .setValue(AnyValue.newBuilder().setStringValue("test").build()) - .build(), - KeyValue.newBuilder() - .setKey("cat") - .setValue(AnyValue.newBuilder().setStringValue("meow").build()) - .build()); + List spanResourceAttributes = + traceRequest.getResourceSpans(0).getResource().getAttributesList(); + assertHasKeyValue(spanResourceAttributes, "service.name", "test"); + assertHasKeyValue(spanResourceAttributes, "cat", "meow"); io.opentelemetry.proto.trace.v1.Span span = traceRequest.getResourceSpans(0).getScopeSpans(0).getSpans(0); - // Dog dropped by attribute limit. - assertThat(span.getAttributesList()) - .containsExactlyInAnyOrder( - KeyValue.newBuilder() - .setKey("configured") - .setValue(AnyValue.newBuilder().setBoolValue(true).build()) - .build(), - KeyValue.newBuilder() - .setKey("wrapped") - .setValue(AnyValue.newBuilder().setIntValue(1).build()) - .build(), - KeyValue.newBuilder() - .setKey("cat") - .setValue(AnyValue.newBuilder().setStringValue("meow").build()) - .build()); + assertHasKeyValue(span.getAttributesList(), "configured", true); + assertHasKeyValue(span.getAttributesList(), "wrapped", 1); + assertHasKeyValue(span.getAttributesList(), "cat", "meow"); + assertHasKeyValue(span.getAttributesList(), "extra-key", "extra-value"); // await on assertions since metrics may come in different order for BatchSpanProcessor, - // exporter, or the ones we - // created in the test. + // exporter, or the ones we created in the test. await() .untilAsserted( () -> { @@ -257,16 +237,10 @@ void configures() throws Exception { assertThat(metricRequest.getResourceMetricsList()) .satisfiesExactly( resourceMetrics -> { - assertThat(resourceMetrics.getResource().getAttributesList()) - .contains( - KeyValue.newBuilder() - .setKey("service.name") - .setValue(AnyValue.newBuilder().setStringValue("test").build()) - .build(), - KeyValue.newBuilder() - .setKey("cat") - .setValue(AnyValue.newBuilder().setStringValue("meow").build()) - .build()); + List metricResourceAttributes = + resourceMetrics.getResource().getAttributesList(); + assertHasKeyValue(metricResourceAttributes, "service.name", "test"); + assertHasKeyValue(metricResourceAttributes, "cat", "meow"); assertThat(resourceMetrics.getScopeMetricsList()) .anySatisfy( scopeMetrics -> { @@ -277,18 +251,10 @@ void configures() throws Exception { // SPI was loaded assertThat(metric.getName()).isEqualTo("my-metric"); // TestMeterProviderConfigurer configures a view that - // only passes on attribute - // named allowed + // only passes an attribute named "allowed" // configured-test - assertThat(getFirstDataPointLabels(metric)) - .contains( - KeyValue.newBuilder() - .setKey("allowed") - .setValue( - AnyValue.newBuilder() - .setStringValue("bear") - .build()) - .build()); + assertHasKeyValue( + getFirstDataPointLabels(metric), "allowed", "bear"); }); }) // This verifies that AutoConfigureListener was invoked and the OTLP @@ -312,21 +278,20 @@ void configures() throws Exception { await().untilAsserted(() -> assertThat(otlpLogsRequests).hasSize(1)); ExportLogsServiceRequest logRequest = otlpLogsRequests.take(); - assertThat(logRequest.getResourceLogs(0).getResource().getAttributesList()) - .contains( - KeyValue.newBuilder() - .setKey("service.name") - .setValue(AnyValue.newBuilder().setStringValue("test").build()) - .build(), - KeyValue.newBuilder() - .setKey("cat") - .setValue(AnyValue.newBuilder().setStringValue("meow").build()) - .build()); + List logResourceAttributes = + logRequest.getResourceLogs(0).getResource().getAttributesList(); + assertHasKeyValue(logResourceAttributes, "service.name", "test"); + assertHasKeyValue(logResourceAttributes, "cat", "meow"); assertThat(logRequest.getResourceLogs(0).getScopeLogs(0).getLogRecordsList()) + // LogRecordCustomizer customizes BatchLogProcessor to add an extra attribute on every log + // record + .allSatisfy( + logRecord -> + assertHasKeyValue(logRecord.getAttributesList(), "extra-key", "extra-value")) .satisfiesExactlyInAnyOrder( logRecord -> { - // LogRecordExporterCustomizer filters logs not whose level is less than Severity.INFO + // LogRecordCustomizer filters logs not whose level is less than Severity.INFO assertThat(logRecord.getBody().getStringValue()).isEqualTo("info log message"); assertThat(logRecord.getSeverityNumberValue()) .isEqualTo(Severity.INFO.getSeverityNumber()); @@ -340,16 +305,37 @@ void configures() throws Exception { .build()); assertThat(logRecord.getSeverityNumber()) .isEqualTo(SeverityNumber.SEVERITY_NUMBER_INFO); - assertThat(logRecord.getAttributesList()) - .containsExactlyInAnyOrder( - KeyValue.newBuilder() - .setKey("event.name") - .setValue( - AnyValue.newBuilder().setStringValue("namespace.test-name").build()) - .build()); + assertHasKeyValue(logRecord.getAttributesList(), "event.name", "namespace.test-name"); }); } + private static void assertHasKeyValue(List keyValues, String key, boolean value) { + assertThat(keyValues) + .contains( + KeyValue.newBuilder() + .setKey(key) + .setValue(AnyValue.newBuilder().setBoolValue(value)) + .build()); + } + + private static void assertHasKeyValue(List keyValues, String key, long value) { + assertThat(keyValues) + .contains( + KeyValue.newBuilder() + .setKey(key) + .setValue(AnyValue.newBuilder().setIntValue(value)) + .build()); + } + + private static void assertHasKeyValue(List keyValues, String key, String value) { + assertThat(keyValues) + .contains( + KeyValue.newBuilder() + .setKey(key) + .setValue(AnyValue.newBuilder().setStringValue(value)) + .build()); + } + private static List getFirstDataPointLabels(Metric metric) { switch (metric.getDataCase()) { case GAUGE: diff --git a/sdk-extensions/autoconfigure/src/testFullConfig/java/io/opentelemetry/sdk/autoconfigure/provider/LogRecordCustomizer.java b/sdk-extensions/autoconfigure/src/testFullConfig/java/io/opentelemetry/sdk/autoconfigure/provider/LogRecordCustomizer.java new file mode 100644 index 00000000000..78c21104ff2 --- /dev/null +++ b/sdk-extensions/autoconfigure/src/testFullConfig/java/io/opentelemetry/sdk/autoconfigure/provider/LogRecordCustomizer.java @@ -0,0 +1,78 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.sdk.autoconfigure.provider; + +import io.opentelemetry.api.common.AttributeKey; +import io.opentelemetry.api.logs.Severity; +import io.opentelemetry.context.Context; +import io.opentelemetry.sdk.autoconfigure.spi.AutoConfigurationCustomizer; +import io.opentelemetry.sdk.autoconfigure.spi.AutoConfigurationCustomizerProvider; +import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties; +import io.opentelemetry.sdk.common.CompletableResultCode; +import io.opentelemetry.sdk.logs.LogRecordProcessor; +import io.opentelemetry.sdk.logs.ReadWriteLogRecord; +import io.opentelemetry.sdk.logs.data.LogRecordData; +import io.opentelemetry.sdk.logs.export.LogRecordExporter; +import java.util.Collection; +import java.util.stream.Collectors; + +/** Behavior asserted in {@link io.opentelemetry.sdk.autoconfigure.FullConfigTest}. */ +public class LogRecordCustomizer implements AutoConfigurationCustomizerProvider { + @Override + public void customize(AutoConfigurationCustomizer autoConfiguration) { + autoConfiguration.addLogRecordProcessorCustomizer(LogRecordCustomizer::processorCustomizer); + autoConfiguration.addLogRecordExporterCustomizer(LogRecordCustomizer::exporterCustomizer); + } + + private static LogRecordProcessor processorCustomizer( + LogRecordProcessor delegate, ConfigProperties config) { + return new LogRecordProcessor() { + @Override + public void onEmit(Context context, ReadWriteLogRecord logRecord) { + logRecord.setAttribute(AttributeKey.stringKey("extra-key"), "extra-value"); + delegate.onEmit(context, logRecord); + } + + @Override + public CompletableResultCode shutdown() { + return delegate.shutdown(); + } + + @Override + public CompletableResultCode forceFlush() { + return delegate.forceFlush(); + } + }; + } + + private static LogRecordExporter exporterCustomizer( + LogRecordExporter delegate, ConfigProperties config) { + return new LogRecordExporter() { + @Override + public CompletableResultCode export(Collection logs) { + Collection filtered = + logs.stream() + .filter( + log -> + log.getSeverity() == Severity.UNDEFINED_SEVERITY_NUMBER + || log.getSeverity().getSeverityNumber() + >= Severity.INFO.getSeverityNumber()) + .collect(Collectors.toList()); + return delegate.export(filtered); + } + + @Override + public CompletableResultCode flush() { + return delegate.flush(); + } + + @Override + public CompletableResultCode shutdown() { + return delegate.shutdown(); + } + }; + } +} diff --git a/sdk-extensions/autoconfigure/src/testFullConfig/java/io/opentelemetry/sdk/autoconfigure/provider/LogRecordExporterCustomizer.java b/sdk-extensions/autoconfigure/src/testFullConfig/java/io/opentelemetry/sdk/autoconfigure/provider/LogRecordExporterCustomizer.java deleted file mode 100644 index fe6c2930b7e..00000000000 --- a/sdk-extensions/autoconfigure/src/testFullConfig/java/io/opentelemetry/sdk/autoconfigure/provider/LogRecordExporterCustomizer.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package io.opentelemetry.sdk.autoconfigure.provider; - -import io.opentelemetry.api.logs.Severity; -import io.opentelemetry.sdk.autoconfigure.spi.AutoConfigurationCustomizer; -import io.opentelemetry.sdk.autoconfigure.spi.AutoConfigurationCustomizerProvider; -import io.opentelemetry.sdk.common.CompletableResultCode; -import io.opentelemetry.sdk.logs.data.LogRecordData; -import io.opentelemetry.sdk.logs.export.LogRecordExporter; -import java.util.Collection; -import java.util.stream.Collectors; - -public class LogRecordExporterCustomizer implements AutoConfigurationCustomizerProvider { - @Override - public void customize(AutoConfigurationCustomizer autoConfiguration) { - autoConfiguration.addLogRecordExporterCustomizer( - (delegate, config) -> - new LogRecordExporter() { - @Override - public CompletableResultCode export(Collection logs) { - Collection filtered = - logs.stream() - .filter( - log -> - log.getSeverity() == Severity.UNDEFINED_SEVERITY_NUMBER - || log.getSeverity().getSeverityNumber() - >= Severity.INFO.getSeverityNumber()) - .collect(Collectors.toList()); - return delegate.export(filtered); - } - - @Override - public CompletableResultCode flush() { - return delegate.flush(); - } - - @Override - public CompletableResultCode shutdown() { - return delegate.shutdown(); - } - }); - } -} diff --git a/sdk-extensions/autoconfigure/src/testFullConfig/java/io/opentelemetry/sdk/autoconfigure/provider/MetricCustomizer.java b/sdk-extensions/autoconfigure/src/testFullConfig/java/io/opentelemetry/sdk/autoconfigure/provider/MetricCustomizer.java index d4a34a57d82..c65434cf908 100644 --- a/sdk-extensions/autoconfigure/src/testFullConfig/java/io/opentelemetry/sdk/autoconfigure/provider/MetricCustomizer.java +++ b/sdk-extensions/autoconfigure/src/testFullConfig/java/io/opentelemetry/sdk/autoconfigure/provider/MetricCustomizer.java @@ -19,6 +19,7 @@ import java.util.Collection; import java.util.stream.Collectors; +/** Behavior asserted in {@link io.opentelemetry.sdk.autoconfigure.FullConfigTest}. */ public class MetricCustomizer implements AutoConfigurationCustomizerProvider { @Override public void customize(AutoConfigurationCustomizer autoConfiguration) { diff --git a/sdk-extensions/autoconfigure/src/testFullConfig/java/io/opentelemetry/sdk/autoconfigure/provider/SpanCustomizer.java b/sdk-extensions/autoconfigure/src/testFullConfig/java/io/opentelemetry/sdk/autoconfigure/provider/SpanCustomizer.java new file mode 100644 index 00000000000..5fa8c41b3ca --- /dev/null +++ b/sdk-extensions/autoconfigure/src/testFullConfig/java/io/opentelemetry/sdk/autoconfigure/provider/SpanCustomizer.java @@ -0,0 +1,102 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.sdk.autoconfigure.provider; + +import io.opentelemetry.api.common.AttributeKey; +import io.opentelemetry.api.common.Attributes; +import io.opentelemetry.context.Context; +import io.opentelemetry.sdk.autoconfigure.spi.AutoConfigurationCustomizer; +import io.opentelemetry.sdk.autoconfigure.spi.AutoConfigurationCustomizerProvider; +import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties; +import io.opentelemetry.sdk.common.CompletableResultCode; +import io.opentelemetry.sdk.trace.ReadWriteSpan; +import io.opentelemetry.sdk.trace.ReadableSpan; +import io.opentelemetry.sdk.trace.SpanProcessor; +import io.opentelemetry.sdk.trace.data.DelegatingSpanData; +import io.opentelemetry.sdk.trace.data.SpanData; +import io.opentelemetry.sdk.trace.export.SpanExporter; +import java.util.Collection; +import java.util.stream.Collectors; + +/** Behavior asserted in {@link io.opentelemetry.sdk.autoconfigure.FullConfigTest}. */ +public class SpanCustomizer implements AutoConfigurationCustomizerProvider { + @Override + public void customize(AutoConfigurationCustomizer autoConfiguration) { + autoConfiguration.addSpanProcessorCustomizer(SpanCustomizer::processorCustomizer); + autoConfiguration.addSpanExporterCustomizer(SpanCustomizer::exporterCustomizer); + } + + private static SpanProcessor processorCustomizer( + SpanProcessor delegate, ConfigProperties config) { + return new SpanProcessor() { + @Override + public void onStart(Context parentContext, ReadWriteSpan span) { + span.setAttribute(AttributeKey.stringKey("extra-key"), "extra-value"); + if (delegate.isStartRequired()) { + delegate.onStart(parentContext, span); + } + } + + @Override + public boolean isStartRequired() { + return true; + } + + @Override + public void onEnd(ReadableSpan span) { + if (delegate.isEndRequired()) { + delegate.onEnd(span); + } + } + + @Override + public boolean isEndRequired() { + return delegate.isEndRequired(); + } + + @Override + public CompletableResultCode shutdown() { + return delegate.shutdown(); + } + + @Override + public CompletableResultCode forceFlush() { + return delegate.forceFlush(); + } + }; + } + + private static SpanExporter exporterCustomizer(SpanExporter delegate, ConfigProperties config) { + return new SpanExporter() { + @Override + public CompletableResultCode export(Collection spans) { + return delegate.export( + spans.stream() + .map( + span -> + new DelegatingSpanData(span) { + @Override + public Attributes getAttributes() { + return span.getAttributes().toBuilder() + .put("wrapped", config.getInt("otel.test.wrapped")) + .build(); + } + }) + .collect(Collectors.toList())); + } + + @Override + public CompletableResultCode flush() { + return delegate.flush(); + } + + @Override + public CompletableResultCode shutdown() { + return delegate.shutdown(); + } + }; + } +} diff --git a/sdk-extensions/autoconfigure/src/testFullConfig/java/io/opentelemetry/sdk/autoconfigure/provider/SpanExporterCustomizer.java b/sdk-extensions/autoconfigure/src/testFullConfig/java/io/opentelemetry/sdk/autoconfigure/provider/SpanExporterCustomizer.java deleted file mode 100644 index 50f8210ecde..00000000000 --- a/sdk-extensions/autoconfigure/src/testFullConfig/java/io/opentelemetry/sdk/autoconfigure/provider/SpanExporterCustomizer.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package io.opentelemetry.sdk.autoconfigure.provider; - -import io.opentelemetry.api.common.Attributes; -import io.opentelemetry.sdk.autoconfigure.spi.AutoConfigurationCustomizer; -import io.opentelemetry.sdk.autoconfigure.spi.AutoConfigurationCustomizerProvider; -import io.opentelemetry.sdk.common.CompletableResultCode; -import io.opentelemetry.sdk.trace.data.DelegatingSpanData; -import io.opentelemetry.sdk.trace.data.SpanData; -import io.opentelemetry.sdk.trace.export.SpanExporter; -import java.util.Collection; -import java.util.stream.Collectors; - -public class SpanExporterCustomizer implements AutoConfigurationCustomizerProvider { - @Override - public void customize(AutoConfigurationCustomizer autoConfiguration) { - autoConfiguration.addSpanExporterCustomizer( - (delegate, config) -> - new SpanExporter() { - @Override - public CompletableResultCode export(Collection spans) { - return delegate.export( - spans.stream() - .map( - span -> - new DelegatingSpanData(span) { - @Override - public Attributes getAttributes() { - return span.getAttributes().toBuilder() - .put("wrapped", config.getInt("otel.test.wrapped")) - .build(); - } - }) - .collect(Collectors.toList())); - } - - @Override - public CompletableResultCode flush() { - return delegate.flush(); - } - - @Override - public CompletableResultCode shutdown() { - return delegate.shutdown(); - } - }); - } -} diff --git a/sdk-extensions/autoconfigure/src/testFullConfig/resources/META-INF/services/io.opentelemetry.sdk.autoconfigure.spi.AutoConfigurationCustomizerProvider b/sdk-extensions/autoconfigure/src/testFullConfig/resources/META-INF/services/io.opentelemetry.sdk.autoconfigure.spi.AutoConfigurationCustomizerProvider index 3103a136000..38b64bf91d3 100644 --- a/sdk-extensions/autoconfigure/src/testFullConfig/resources/META-INF/services/io.opentelemetry.sdk.autoconfigure.spi.AutoConfigurationCustomizerProvider +++ b/sdk-extensions/autoconfigure/src/testFullConfig/resources/META-INF/services/io.opentelemetry.sdk.autoconfigure.spi.AutoConfigurationCustomizerProvider @@ -1,3 +1,3 @@ -io.opentelemetry.sdk.autoconfigure.provider.SpanExporterCustomizer +io.opentelemetry.sdk.autoconfigure.provider.SpanCustomizer io.opentelemetry.sdk.autoconfigure.provider.MetricCustomizer -io.opentelemetry.sdk.autoconfigure.provider.LogRecordExporterCustomizer \ No newline at end of file +io.opentelemetry.sdk.autoconfigure.provider.LogRecordCustomizer From 4eeef335245297becb1f33a7a49c41a666b377a4 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 16 Jan 2025 15:25:50 -0600 Subject: [PATCH 762/901] fix(deps): update spotless packages to v7.0.2 (#7018) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- buildSrc/build.gradle.kts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts index f59e21d7b22..67ff29ca05e 100644 --- a/buildSrc/build.gradle.kts +++ b/buildSrc/build.gradle.kts @@ -2,7 +2,7 @@ plugins { `kotlin-dsl` // When updating, update below in dependencies too - id("com.diffplug.spotless") version "7.0.1" + id("com.diffplug.spotless") version "7.0.2" } if (!hasLauncherForJavaVersion(17)) { @@ -53,7 +53,7 @@ dependencies { implementation(enforcedPlatform("com.squareup.wire:wire-bom:5.2.1")) implementation("com.google.auto.value:auto-value-annotations:1.11.0") // When updating, update above in plugins too - implementation("com.diffplug.spotless:spotless-plugin-gradle:7.0.1") + implementation("com.diffplug.spotless:spotless-plugin-gradle:7.0.2") // Needed for japicmp but not automatically brought in for some reason. implementation("com.google.guava:guava:33.4.0-jre") implementation("com.squareup:javapoet:1.13.0") From 31869a3fc694d58a9ba22603811002eff9c17999 Mon Sep 17 00:00:00 2001 From: jack-berg <34418638+jack-berg@users.noreply.github.com> Date: Thu, 16 Jan 2025 18:02:31 -0600 Subject: [PATCH 763/901] Interpret timeout zero value as no limit (#7023) --- .../internal/grpc/GrpcExporterBuilder.java | 4 +- .../internal/http/HttpExporterBuilder.java | 4 +- .../AbstractGrpcTelemetryExporterTest.java | 58 +++++++++++++++++-- .../AbstractHttpTelemetryExporterTest.java | 49 +++++++++++++--- .../okhttp/internal/OkHttpGrpcSender.java | 8 ++- .../okhttp/internal/OkHttpHttpSender.java | 8 ++- .../zipkin/ZipkinSpanExporterBuilder.java | 7 ++- .../zipkin/ZipkinSpanExporterTest.java | 15 +++++ .../BatchLogRecordProcessorBuilder.java | 2 +- .../export/BatchSpanProcessorBuilder.java | 2 +- 10 files changed, 131 insertions(+), 26 deletions(-) diff --git a/exporters/common/src/main/java/io/opentelemetry/exporter/internal/grpc/GrpcExporterBuilder.java b/exporters/common/src/main/java/io/opentelemetry/exporter/internal/grpc/GrpcExporterBuilder.java index c5b04fd8db8..3ddf45c03e4 100644 --- a/exporters/common/src/main/java/io/opentelemetry/exporter/internal/grpc/GrpcExporterBuilder.java +++ b/exporters/common/src/main/java/io/opentelemetry/exporter/internal/grpc/GrpcExporterBuilder.java @@ -87,7 +87,7 @@ public GrpcExporterBuilder setChannel(ManagedChannel channel) { } public GrpcExporterBuilder setTimeout(long timeout, TimeUnit unit) { - timeoutNanos = unit.toNanos(timeout); + timeoutNanos = timeout == 0 ? Long.MAX_VALUE : unit.toNanos(timeout); return this; } @@ -96,7 +96,7 @@ public GrpcExporterBuilder setTimeout(Duration timeout) { } public GrpcExporterBuilder setConnectTimeout(long timeout, TimeUnit unit) { - connectTimeoutNanos = unit.toNanos(timeout); + connectTimeoutNanos = timeout == 0 ? Long.MAX_VALUE : unit.toNanos(timeout); return this; } diff --git a/exporters/common/src/main/java/io/opentelemetry/exporter/internal/http/HttpExporterBuilder.java b/exporters/common/src/main/java/io/opentelemetry/exporter/internal/http/HttpExporterBuilder.java index e88533ab8aa..a82da5afc9a 100644 --- a/exporters/common/src/main/java/io/opentelemetry/exporter/internal/http/HttpExporterBuilder.java +++ b/exporters/common/src/main/java/io/opentelemetry/exporter/internal/http/HttpExporterBuilder.java @@ -69,12 +69,12 @@ public HttpExporterBuilder(String exporterName, String type, String defaultEndpo } public HttpExporterBuilder setTimeout(long timeout, TimeUnit unit) { - timeoutNanos = unit.toNanos(timeout); + timeoutNanos = timeout == 0 ? Long.MAX_VALUE : unit.toNanos(timeout); return this; } public HttpExporterBuilder setConnectTimeout(long timeout, TimeUnit unit) { - connectTimeoutNanos = unit.toNanos(timeout); + connectTimeoutNanos = timeout == 0 ? Long.MAX_VALUE : unit.toNanos(timeout); return this; } diff --git a/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/AbstractGrpcTelemetryExporterTest.java b/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/AbstractGrpcTelemetryExporterTest.java index 1d7086c1c99..5aca2a4588e 100644 --- a/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/AbstractGrpcTelemetryExporterTest.java +++ b/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/AbstractGrpcTelemetryExporterTest.java @@ -815,13 +815,39 @@ void overrideHost() { @Test @SuppressWarnings("PreferJavaTimeOverload") void validConfig() { - assertThatCode(() -> exporterBuilder().setTimeout(0, TimeUnit.MILLISECONDS)) + // We must build exporters to test timeout settings, which intersect with underlying client + // implementations and may convert between Duration, int, and long, which may be susceptible to + // overflow exceptions. + assertThatCode(() -> buildAndShutdown(exporterBuilder().setTimeout(0, TimeUnit.MILLISECONDS))) .doesNotThrowAnyException(); - assertThatCode(() -> exporterBuilder().setTimeout(Duration.ofMillis(0))) + assertThatCode(() -> buildAndShutdown(exporterBuilder().setTimeout(Duration.ofMillis(0)))) .doesNotThrowAnyException(); - assertThatCode(() -> exporterBuilder().setTimeout(10, TimeUnit.MILLISECONDS)) + assertThatCode( + () -> + buildAndShutdown( + exporterBuilder().setTimeout(Long.MAX_VALUE, TimeUnit.NANOSECONDS))) + .doesNotThrowAnyException(); + assertThatCode( + () -> buildAndShutdown(exporterBuilder().setTimeout(Duration.ofNanos(Long.MAX_VALUE)))) + .doesNotThrowAnyException(); + assertThatCode( + () -> buildAndShutdown(exporterBuilder().setTimeout(Long.MAX_VALUE, TimeUnit.SECONDS))) + .doesNotThrowAnyException(); + assertThatCode(() -> buildAndShutdown(exporterBuilder().setTimeout(10, TimeUnit.MILLISECONDS))) + .doesNotThrowAnyException(); + assertThatCode(() -> buildAndShutdown(exporterBuilder().setTimeout(Duration.ofMillis(10)))) + .doesNotThrowAnyException(); + assertThatCode( + () -> buildAndShutdown(exporterBuilder().setConnectTimeout(0, TimeUnit.MILLISECONDS))) + .doesNotThrowAnyException(); + assertThatCode( + () -> buildAndShutdown(exporterBuilder().setConnectTimeout(Duration.ofMillis(0)))) + .doesNotThrowAnyException(); + assertThatCode( + () -> buildAndShutdown(exporterBuilder().setConnectTimeout(10, TimeUnit.MILLISECONDS))) .doesNotThrowAnyException(); - assertThatCode(() -> exporterBuilder().setTimeout(Duration.ofMillis(10))) + assertThatCode( + () -> buildAndShutdown(exporterBuilder().setConnectTimeout(Duration.ofMillis(10)))) .doesNotThrowAnyException(); assertThatCode(() -> exporterBuilder().setEndpoint("http://localhost:4317")) @@ -846,6 +872,11 @@ void validConfig() { .doesNotThrowAnyException(); } + private void buildAndShutdown(TelemetryExporterBuilder builder) { + TelemetryExporter build = builder.build(); + build.shutdown().join(10, TimeUnit.MILLISECONDS); + } + @Test @SuppressWarnings({"PreferJavaTimeOverload", "NullAway"}) void invalidConfig() { @@ -858,6 +889,25 @@ void invalidConfig() { assertThatThrownBy(() -> exporterBuilder().setTimeout(null)) .isInstanceOf(NullPointerException.class) .hasMessage("timeout"); + assertThatThrownBy( + () -> + buildAndShutdown(exporterBuilder().setTimeout(Duration.ofSeconds(Long.MAX_VALUE)))) + .isInstanceOf(ArithmeticException.class); + + assertThatThrownBy(() -> exporterBuilder().setConnectTimeout(-1, TimeUnit.MILLISECONDS)) + .isInstanceOf(IllegalArgumentException.class) + .hasMessage("timeout must be non-negative"); + assertThatThrownBy(() -> exporterBuilder().setConnectTimeout(1, null)) + .isInstanceOf(NullPointerException.class) + .hasMessage("unit"); + assertThatThrownBy(() -> exporterBuilder().setConnectTimeout(null)) + .isInstanceOf(NullPointerException.class) + .hasMessage("timeout"); + assertThatThrownBy( + () -> + buildAndShutdown( + exporterBuilder().setConnectTimeout(Duration.ofSeconds(Long.MAX_VALUE)))) + .isInstanceOf(ArithmeticException.class); assertThatThrownBy(() -> exporterBuilder().setEndpoint(null)) .isInstanceOf(NullPointerException.class) diff --git a/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/AbstractHttpTelemetryExporterTest.java b/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/AbstractHttpTelemetryExporterTest.java index 28e54dab222..6f622a6e70c 100644 --- a/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/AbstractHttpTelemetryExporterTest.java +++ b/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/AbstractHttpTelemetryExporterTest.java @@ -698,22 +698,39 @@ void proxy() { @Test @SuppressWarnings("PreferJavaTimeOverload") void validConfig() { - assertThatCode(() -> exporterBuilder().setTimeout(0, TimeUnit.MILLISECONDS)) + // We must build exporters to test timeout settings, which intersect with underlying client + // implementations and may convert between Duration, int, and long, which may be susceptible to + // overflow exceptions. + assertThatCode(() -> buildAndShutdown(exporterBuilder().setTimeout(0, TimeUnit.MILLISECONDS))) .doesNotThrowAnyException(); - assertThatCode(() -> exporterBuilder().setTimeout(Duration.ofMillis(0))) + assertThatCode(() -> buildAndShutdown(exporterBuilder().setTimeout(Duration.ofMillis(0)))) .doesNotThrowAnyException(); - assertThatCode(() -> exporterBuilder().setTimeout(10, TimeUnit.MILLISECONDS)) + assertThatCode( + () -> + buildAndShutdown( + exporterBuilder().setTimeout(Long.MAX_VALUE, TimeUnit.NANOSECONDS))) .doesNotThrowAnyException(); - assertThatCode(() -> exporterBuilder().setTimeout(Duration.ofMillis(10))) + assertThatCode( + () -> buildAndShutdown(exporterBuilder().setTimeout(Duration.ofNanos(Long.MAX_VALUE)))) .doesNotThrowAnyException(); - - assertThatCode(() -> exporterBuilder().setConnectTimeout(0, TimeUnit.MILLISECONDS)) + assertThatCode( + () -> buildAndShutdown(exporterBuilder().setTimeout(Long.MAX_VALUE, TimeUnit.SECONDS))) + .doesNotThrowAnyException(); + assertThatCode(() -> buildAndShutdown(exporterBuilder().setTimeout(10, TimeUnit.MILLISECONDS))) + .doesNotThrowAnyException(); + assertThatCode(() -> buildAndShutdown(exporterBuilder().setTimeout(Duration.ofMillis(10)))) + .doesNotThrowAnyException(); + assertThatCode( + () -> buildAndShutdown(exporterBuilder().setConnectTimeout(0, TimeUnit.MILLISECONDS))) .doesNotThrowAnyException(); - assertThatCode(() -> exporterBuilder().setConnectTimeout(Duration.ofMillis(0))) + assertThatCode( + () -> buildAndShutdown(exporterBuilder().setConnectTimeout(Duration.ofMillis(0)))) .doesNotThrowAnyException(); - assertThatCode(() -> exporterBuilder().setConnectTimeout(10, TimeUnit.MILLISECONDS)) + assertThatCode( + () -> buildAndShutdown(exporterBuilder().setConnectTimeout(10, TimeUnit.MILLISECONDS))) .doesNotThrowAnyException(); - assertThatCode(() -> exporterBuilder().setConnectTimeout(Duration.ofMillis(10))) + assertThatCode( + () -> buildAndShutdown(exporterBuilder().setConnectTimeout(Duration.ofMillis(10)))) .doesNotThrowAnyException(); assertThatCode(() -> exporterBuilder().setEndpoint("http://localhost:4318")) @@ -738,6 +755,11 @@ void validConfig() { .doesNotThrowAnyException(); } + private void buildAndShutdown(TelemetryExporterBuilder builder) { + TelemetryExporter build = builder.build(); + build.shutdown().join(10, TimeUnit.MILLISECONDS); + } + @Test @SuppressWarnings({"PreferJavaTimeOverload", "NullAway"}) void invalidConfig() { @@ -750,6 +772,10 @@ void invalidConfig() { assertThatThrownBy(() -> exporterBuilder().setTimeout(null)) .isInstanceOf(NullPointerException.class) .hasMessage("timeout"); + assertThatThrownBy( + () -> + buildAndShutdown(exporterBuilder().setTimeout(Duration.ofSeconds(Long.MAX_VALUE)))) + .isInstanceOf(ArithmeticException.class); assertThatThrownBy(() -> exporterBuilder().setConnectTimeout(-1, TimeUnit.MILLISECONDS)) .isInstanceOf(IllegalArgumentException.class) @@ -760,6 +786,11 @@ void invalidConfig() { assertThatThrownBy(() -> exporterBuilder().setConnectTimeout(null)) .isInstanceOf(NullPointerException.class) .hasMessage("timeout"); + assertThatThrownBy( + () -> + buildAndShutdown( + exporterBuilder().setConnectTimeout(Duration.ofSeconds(Long.MAX_VALUE)))) + .isInstanceOf(ArithmeticException.class); assertThatThrownBy(() -> exporterBuilder().setEndpoint(null)) .isInstanceOf(NullPointerException.class) diff --git a/exporters/sender/okhttp/src/main/java/io/opentelemetry/exporter/sender/okhttp/internal/OkHttpGrpcSender.java b/exporters/sender/okhttp/src/main/java/io/opentelemetry/exporter/sender/okhttp/internal/OkHttpGrpcSender.java index f8b4996b90e..a0305cb863f 100644 --- a/exporters/sender/okhttp/src/main/java/io/opentelemetry/exporter/sender/okhttp/internal/OkHttpGrpcSender.java +++ b/exporters/sender/okhttp/src/main/java/io/opentelemetry/exporter/sender/okhttp/internal/OkHttpGrpcSender.java @@ -81,11 +81,15 @@ public OkHttpGrpcSender( @Nullable RetryPolicy retryPolicy, @Nullable SSLContext sslContext, @Nullable X509TrustManager trustManager) { + int callTimeoutMillis = + (int) Math.min(Duration.ofNanos(timeoutNanos).toMillis(), Integer.MAX_VALUE); + int connectTimeoutMillis = + (int) Math.min(Duration.ofNanos(connectTimeoutNanos).toMillis(), Integer.MAX_VALUE); OkHttpClient.Builder clientBuilder = new OkHttpClient.Builder() .dispatcher(OkHttpUtil.newDispatcher()) - .callTimeout(Duration.ofNanos(timeoutNanos)) - .connectTimeout(Duration.ofNanos(connectTimeoutNanos)); + .callTimeout(Duration.ofMillis(callTimeoutMillis)) + .connectTimeout(Duration.ofMillis(connectTimeoutMillis)); if (retryPolicy != null) { clientBuilder.addInterceptor( new RetryInterceptor(retryPolicy, OkHttpGrpcSender::isRetryable)); diff --git a/exporters/sender/okhttp/src/main/java/io/opentelemetry/exporter/sender/okhttp/internal/OkHttpHttpSender.java b/exporters/sender/okhttp/src/main/java/io/opentelemetry/exporter/sender/okhttp/internal/OkHttpHttpSender.java index 53d06120e2e..9161aa42088 100644 --- a/exporters/sender/okhttp/src/main/java/io/opentelemetry/exporter/sender/okhttp/internal/OkHttpHttpSender.java +++ b/exporters/sender/okhttp/src/main/java/io/opentelemetry/exporter/sender/okhttp/internal/OkHttpHttpSender.java @@ -64,11 +64,15 @@ public OkHttpHttpSender( @Nullable RetryPolicy retryPolicy, @Nullable SSLContext sslContext, @Nullable X509TrustManager trustManager) { + int callTimeoutMillis = + (int) Math.min(Duration.ofNanos(timeoutNanos).toMillis(), Integer.MAX_VALUE); + int connectTimeoutMillis = + (int) Math.min(Duration.ofNanos(connectionTimeoutNanos).toMillis(), Integer.MAX_VALUE); OkHttpClient.Builder builder = new OkHttpClient.Builder() .dispatcher(OkHttpUtil.newDispatcher()) - .connectTimeout(Duration.ofNanos(connectionTimeoutNanos)) - .callTimeout(Duration.ofNanos(timeoutNanos)); + .connectTimeout(Duration.ofMillis(connectTimeoutMillis)) + .callTimeout(Duration.ofMillis(callTimeoutMillis)); if (proxyOptions != null) { builder.proxySelector(proxyOptions.getProxySelector()); diff --git a/exporters/zipkin/src/main/java/io/opentelemetry/exporter/zipkin/ZipkinSpanExporterBuilder.java b/exporters/zipkin/src/main/java/io/opentelemetry/exporter/zipkin/ZipkinSpanExporterBuilder.java index d13f1d4a825..0f1fae95b9a 100644 --- a/exporters/zipkin/src/main/java/io/opentelemetry/exporter/zipkin/ZipkinSpanExporterBuilder.java +++ b/exporters/zipkin/src/main/java/io/opentelemetry/exporter/zipkin/ZipkinSpanExporterBuilder.java @@ -31,7 +31,7 @@ public final class ZipkinSpanExporterBuilder { // compression is enabled by default, because this is the default of OkHttpSender, // which is created when no custom sender is set (see OkHttpSender.Builder) private boolean compressionEnabled = true; - private long readTimeoutMillis = TimeUnit.SECONDS.toMillis(10); + private int readTimeoutMillis = (int) TimeUnit.SECONDS.toMillis(10); private Supplier meterProviderSupplier = GlobalOpenTelemetry::getMeterProvider; /** @@ -156,7 +156,8 @@ public ZipkinSpanExporterBuilder setCompression(String compressionMethod) { public ZipkinSpanExporterBuilder setReadTimeout(long timeout, TimeUnit unit) { requireNonNull(unit, "unit"); checkArgument(timeout >= 0, "timeout must be non-negative"); - this.readTimeoutMillis = unit.toMillis(timeout); + long timeoutMillis = timeout == 0 ? Long.MAX_VALUE : unit.toMillis(timeout); + this.readTimeoutMillis = (int) Math.min(timeoutMillis, Integer.MAX_VALUE); return this; } @@ -212,7 +213,7 @@ public ZipkinSpanExporter build() { OkHttpSender.newBuilder() .endpoint(endpoint) .compressionEnabled(compressionEnabled) - .readTimeout((int) readTimeoutMillis) + .readTimeout(readTimeoutMillis) .build(); } OtelToZipkinSpanTransformer transformer = diff --git a/exporters/zipkin/src/test/java/io/opentelemetry/exporter/zipkin/ZipkinSpanExporterTest.java b/exporters/zipkin/src/test/java/io/opentelemetry/exporter/zipkin/ZipkinSpanExporterTest.java index 2c70691744c..b89c273bbbb 100644 --- a/exporters/zipkin/src/test/java/io/opentelemetry/exporter/zipkin/ZipkinSpanExporterTest.java +++ b/exporters/zipkin/src/test/java/io/opentelemetry/exporter/zipkin/ZipkinSpanExporterTest.java @@ -231,6 +231,21 @@ void compressionEnabledAndDisabled() { } } + @Test + @SuppressWarnings("PreferJavaTimeOverload") + void readTimeout_Zero() { + ZipkinSpanExporter exporter = + ZipkinSpanExporter.builder().setReadTimeout(0, TimeUnit.SECONDS).build(); + + try { + assertThat(exporter) + .extracting("sender.delegate.client.readTimeoutMillis") + .isEqualTo(Integer.MAX_VALUE); + } finally { + exporter.shutdown(); + } + } + @Test void stringRepresentation() { try (ZipkinSpanExporter exporter = ZipkinSpanExporter.builder().build()) { diff --git a/sdk/logs/src/main/java/io/opentelemetry/sdk/logs/export/BatchLogRecordProcessorBuilder.java b/sdk/logs/src/main/java/io/opentelemetry/sdk/logs/export/BatchLogRecordProcessorBuilder.java index 6aafa9525aa..4cf30586367 100644 --- a/sdk/logs/src/main/java/io/opentelemetry/sdk/logs/export/BatchLogRecordProcessorBuilder.java +++ b/sdk/logs/src/main/java/io/opentelemetry/sdk/logs/export/BatchLogRecordProcessorBuilder.java @@ -71,7 +71,7 @@ long getScheduleDelayNanos() { public BatchLogRecordProcessorBuilder setExporterTimeout(long timeout, TimeUnit unit) { requireNonNull(unit, "unit"); checkArgument(timeout >= 0, "timeout must be non-negative"); - exporterTimeoutNanos = unit.toNanos(timeout); + exporterTimeoutNanos = timeout == 0 ? Long.MAX_VALUE : unit.toNanos(timeout); return this; } diff --git a/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/export/BatchSpanProcessorBuilder.java b/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/export/BatchSpanProcessorBuilder.java index c3235a60f4f..3ec3fce0778 100644 --- a/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/export/BatchSpanProcessorBuilder.java +++ b/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/export/BatchSpanProcessorBuilder.java @@ -79,7 +79,7 @@ long getScheduleDelayNanos() { public BatchSpanProcessorBuilder setExporterTimeout(long timeout, TimeUnit unit) { requireNonNull(unit, "unit"); checkArgument(timeout >= 0, "timeout must be non-negative"); - exporterTimeoutNanos = unit.toNanos(timeout); + exporterTimeoutNanos = timeout == 0 ? Long.MAX_VALUE : unit.toNanos(timeout); return this; } From 81d165d75cd56fff1717b8e9bc9efdabebd2cd24 Mon Sep 17 00:00:00 2001 From: Trask Stalnaker Date: Fri, 17 Jan 2025 11:41:42 -0800 Subject: [PATCH 764/901] Remove unnecessary workflow config (#7032) --- .github/workflows/reusable-markdown-link-check.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.github/workflows/reusable-markdown-link-check.yml b/.github/workflows/reusable-markdown-link-check.yml index 93e42a98ad1..d5444b0afa5 100644 --- a/.github/workflows/reusable-markdown-link-check.yml +++ b/.github/workflows/reusable-markdown-link-check.yml @@ -11,8 +11,6 @@ jobs: - uses: lycheeverse/lychee-action@v2 with: - # remove version after next release of lychee-action - lycheeVersion: latest # excluding links to pull requests and issues is done for performance args: > --include-fragments From 2770fa1bb148661422d967b73c63a14ad23a402b Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sun, 19 Jan 2025 11:20:59 -0800 Subject: [PATCH 765/901] fix(deps): update dependency org.snakeyaml:snakeyaml-engine to v2.9 (#7022) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- dependencyManagement/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index e82a7112253..5cd8a09419c 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -21,7 +21,7 @@ val DEPENDENCY_BOMS = listOf( "org.assertj:assertj-bom:3.27.2", "org.junit:junit-bom:5.11.4", "org.testcontainers:testcontainers-bom:1.20.4", - "org.snakeyaml:snakeyaml-engine:2.8" + "org.snakeyaml:snakeyaml-engine:2.9" ) val autoValueVersion = "1.11.0" From 13e2b8c4dfeba09f361b47986febbd792ab1ae60 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sun, 19 Jan 2025 15:53:52 -0800 Subject: [PATCH 766/901] fix(deps): update dependency io.grpc:grpc-bom to v1.69.1 (#7028) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- dependencyManagement/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index 5cd8a09419c..2fd66752d74 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -14,7 +14,7 @@ val DEPENDENCY_BOMS = listOf( "com.linecorp.armeria:armeria-bom:1.31.3", "com.squareup.okhttp3:okhttp-bom:4.12.0", "com.squareup.okio:okio-bom:3.10.2", // applies to transitive dependencies of okhttp - "io.grpc:grpc-bom:1.69.0", + "io.grpc:grpc-bom:1.69.1", "io.netty:netty-bom:4.1.117.Final", "io.zipkin.brave:brave-bom:6.0.3", "io.zipkin.reporter2:zipkin-reporter-bom:3.4.3", From d704117f9d35192972e06c3f9feb2a48eb5796ed Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 22 Jan 2025 16:45:12 -0600 Subject: [PATCH 767/901] fix(deps): update dependency org.owasp:dependency-check-gradle to v12.0.1 (#7035) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- buildSrc/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts index 67ff29ca05e..8f605e56bcd 100644 --- a/buildSrc/build.gradle.kts +++ b/buildSrc/build.gradle.kts @@ -66,7 +66,7 @@ dependencies { implementation("net.ltgt.gradle:gradle-errorprone-plugin:4.1.0") implementation("net.ltgt.gradle:gradle-nullaway-plugin:2.2.0") implementation("org.jetbrains.kotlin:kotlin-gradle-plugin:2.1.0") - implementation("org.owasp:dependency-check-gradle:12.0.0") + implementation("org.owasp:dependency-check-gradle:12.0.1") implementation("ru.vyarus:gradle-animalsniffer-plugin:1.7.2") } From 14d714a31120b5f3913df504f546ed4bd0812854 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 22 Jan 2025 16:45:38 -0600 Subject: [PATCH 768/901] fix(deps): update dependency io.grpc:grpc-bom to v1.70.0 (#7036) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- dependencyManagement/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index 2fd66752d74..1141f84ddb1 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -14,7 +14,7 @@ val DEPENDENCY_BOMS = listOf( "com.linecorp.armeria:armeria-bom:1.31.3", "com.squareup.okhttp3:okhttp-bom:4.12.0", "com.squareup.okio:okio-bom:3.10.2", // applies to transitive dependencies of okhttp - "io.grpc:grpc-bom:1.69.1", + "io.grpc:grpc-bom:1.70.0", "io.netty:netty-bom:4.1.117.Final", "io.zipkin.brave:brave-bom:6.0.3", "io.zipkin.reporter2:zipkin-reporter-bom:3.4.3", From b4fec0573b40cbc0c9f26190277f28fdd7009fb9 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 24 Jan 2025 08:03:09 -0800 Subject: [PATCH 769/901] fix(deps): update dependency org.assertj:assertj-bom to v3.27.3 (#7034) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- dependencyManagement/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index 1141f84ddb1..06c2b9a0be2 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -18,7 +18,7 @@ val DEPENDENCY_BOMS = listOf( "io.netty:netty-bom:4.1.117.Final", "io.zipkin.brave:brave-bom:6.0.3", "io.zipkin.reporter2:zipkin-reporter-bom:3.4.3", - "org.assertj:assertj-bom:3.27.2", + "org.assertj:assertj-bom:3.27.3", "org.junit:junit-bom:5.11.4", "org.testcontainers:testcontainers-bom:1.20.4", "org.snakeyaml:snakeyaml-engine:2.9" From 013d1669fafe7342e7ed89513b5cfb22392065c9 Mon Sep 17 00:00:00 2001 From: Jonathan Halliday Date: Fri, 24 Jan 2025 20:20:03 +0000 Subject: [PATCH 770/901] Improve profiles attribute table handling (#7031) --- .../exporter/otlp/internal/data/ImmutableProfileData.java | 4 ++-- .../io/opentelemetry/exporter/otlp/profiles/LocationData.java | 2 +- .../exporter/otlp/profiles/LocationMarshaler.java | 2 +- .../io/opentelemetry/exporter/otlp/profiles/ProfileData.java | 4 ++-- .../exporter/otlp/profiles/ProfileMarshaler.java | 2 +- .../exporter/otlp/profiles/ProfilesRequestMarshalerTest.java | 2 +- 6 files changed, 8 insertions(+), 8 deletions(-) diff --git a/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/internal/data/ImmutableProfileData.java b/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/internal/data/ImmutableProfileData.java index c9b4a642ad3..520139b2452 100644 --- a/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/internal/data/ImmutableProfileData.java +++ b/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/internal/data/ImmutableProfileData.java @@ -6,7 +6,7 @@ package io.opentelemetry.exporter.otlp.internal.data; import com.google.auto.value.AutoValue; -import io.opentelemetry.api.common.Attributes; +import io.opentelemetry.exporter.internal.otlp.AttributeKeyValue; import io.opentelemetry.exporter.otlp.profiles.AttributeUnitData; import io.opentelemetry.exporter.otlp.profiles.FunctionData; import io.opentelemetry.exporter.otlp.profiles.LinkData; @@ -48,7 +48,7 @@ public static ProfileData create( List locationTable, List locationIndices, List functionTable, - Attributes attributeTable, + List> attributeTable, List attributeUnits, List linkTable, List stringTable, diff --git a/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/LocationData.java b/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/LocationData.java index 056e36c7026..78fdfc4cdd6 100644 --- a/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/LocationData.java +++ b/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/LocationData.java @@ -38,5 +38,5 @@ public interface LocationData { boolean isFolded(); /** References to attributes in Profile.attribute_table. */ - List getAttributes(); + List getAttributeIndices(); } diff --git a/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/LocationMarshaler.java b/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/LocationMarshaler.java index 88e1d1a26a4..40360c0eafc 100644 --- a/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/LocationMarshaler.java +++ b/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/LocationMarshaler.java @@ -30,7 +30,7 @@ static LocationMarshaler create(LocationData locationData) { locationData.getAddress(), LineMarshaler.createRepeated(locationData.getLines()), locationData.isFolded(), - locationData.getAttributes()); + locationData.getAttributeIndices()); } static LocationMarshaler[] createRepeated(List items) { diff --git a/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/ProfileData.java b/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/ProfileData.java index d37e901206b..0f6ef8e6ea3 100644 --- a/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/ProfileData.java +++ b/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/ProfileData.java @@ -5,8 +5,8 @@ package io.opentelemetry.exporter.otlp.profiles; -import io.opentelemetry.api.common.Attributes; import io.opentelemetry.api.internal.OtelEncodingUtils; +import io.opentelemetry.exporter.internal.otlp.AttributeKeyValue; import io.opentelemetry.sdk.common.InstrumentationScopeInfo; import io.opentelemetry.sdk.resources.Resource; import java.nio.ByteBuffer; @@ -51,7 +51,7 @@ public interface ProfileData { List getFunctionTable(); /** Lookup table for attributes. */ - Attributes getAttributeTable(); + List> getAttributeTable(); /** Represents a mapping between Attribute Keys and Units. */ List getAttributeUnits(); diff --git a/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/ProfileMarshaler.java b/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/ProfileMarshaler.java index be4215c8b9f..8d04bbbf94f 100644 --- a/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/ProfileMarshaler.java +++ b/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/ProfileMarshaler.java @@ -51,7 +51,7 @@ static ProfileMarshaler create(ProfileData profileData) { FunctionMarshaler[] functionMarshalers = FunctionMarshaler.createRepeated(profileData.getFunctionTable()); KeyValueMarshaler[] attributeTableMarshalers = - KeyValueMarshaler.createForAttributes(profileData.getAttributeTable()); + KeyValueMarshaler.createRepeated(profileData.getAttributeTable()); AttributeUnitMarshaler[] attributeUnitsMarshalers = AttributeUnitMarshaler.createRepeated(profileData.getAttributeUnits()); LinkMarshaler[] linkMarshalers = LinkMarshaler.createRepeated(profileData.getLinkTable()); diff --git a/exporters/otlp/profiles/src/test/java/io/opentelemetry/exporter/otlp/profiles/ProfilesRequestMarshalerTest.java b/exporters/otlp/profiles/src/test/java/io/opentelemetry/exporter/otlp/profiles/ProfilesRequestMarshalerTest.java index c7c2deec381..3ed1d9159d2 100644 --- a/exporters/otlp/profiles/src/test/java/io/opentelemetry/exporter/otlp/profiles/ProfilesRequestMarshalerTest.java +++ b/exporters/otlp/profiles/src/test/java/io/opentelemetry/exporter/otlp/profiles/ProfilesRequestMarshalerTest.java @@ -151,7 +151,7 @@ void compareResourceProfilesMarshaling() { Collections.emptyList(), listOf(1, 2), Collections.emptyList(), - Attributes.empty(), + Collections.emptyList(), Collections.emptyList(), Collections.emptyList(), Collections.emptyList(), From 85b99e94f91eaf6fd35c116ade0b844abe40e7ac Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 24 Jan 2025 14:20:14 -0600 Subject: [PATCH 771/901] chore(deps): update plugin com.gradle.develocity to v3.19.1 (#7037) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- settings.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/settings.gradle.kts b/settings.gradle.kts index ae259612d85..376db9f78b8 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -1,7 +1,7 @@ pluginManagement { plugins { id("com.gradleup.shadow") version "8.3.5" - id("com.gradle.develocity") version "3.19" + id("com.gradle.develocity") version "3.19.1" id("de.undercouch.download") version "5.6.0" id("org.jsonschema2pojo") version "1.2.2" id("io.github.gradle-nexus.publish-plugin") version "2.0.0" From cd3b0e7f9d950127759d2b0d34fed84ea438e938 Mon Sep 17 00:00:00 2001 From: jack-berg <34418638+jack-berg@users.noreply.github.com> Date: Fri, 24 Jan 2025 15:01:21 -0600 Subject: [PATCH 772/901] Fix concurrent span reusable data marshaler (#7041) Co-authored-by: Robert Elliot --- .../internal/otlp/logs/LogReusableDataMarshaler.java | 5 +++-- .../internal/otlp/metrics/MetricReusableDataMarshaler.java | 5 +++-- .../internal/otlp/traces/SpanReusableDataMarshaler.java | 5 +++-- 3 files changed, 9 insertions(+), 6 deletions(-) diff --git a/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/logs/LogReusableDataMarshaler.java b/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/logs/LogReusableDataMarshaler.java index 5f3fc50a5f5..fadaaa09bc4 100644 --- a/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/logs/LogReusableDataMarshaler.java +++ b/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/logs/LogReusableDataMarshaler.java @@ -9,9 +9,9 @@ import io.opentelemetry.sdk.common.CompletableResultCode; import io.opentelemetry.sdk.common.export.MemoryMode; import io.opentelemetry.sdk.logs.data.LogRecordData; -import java.util.ArrayDeque; import java.util.Collection; import java.util.Deque; +import java.util.concurrent.ConcurrentLinkedDeque; import java.util.function.BiFunction; /** @@ -20,7 +20,8 @@ */ public class LogReusableDataMarshaler { - private final Deque marshalerPool = new ArrayDeque<>(); + private final Deque marshalerPool = + new ConcurrentLinkedDeque<>(); private final MemoryMode memoryMode; private final BiFunction doExport; diff --git a/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/metrics/MetricReusableDataMarshaler.java b/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/metrics/MetricReusableDataMarshaler.java index c143e94fa5d..a3d7187698b 100644 --- a/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/metrics/MetricReusableDataMarshaler.java +++ b/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/metrics/MetricReusableDataMarshaler.java @@ -9,9 +9,9 @@ import io.opentelemetry.sdk.common.CompletableResultCode; import io.opentelemetry.sdk.common.export.MemoryMode; import io.opentelemetry.sdk.metrics.data.MetricData; -import java.util.ArrayDeque; import java.util.Collection; import java.util.Deque; +import java.util.concurrent.ConcurrentLinkedDeque; import java.util.function.BiFunction; /** @@ -20,7 +20,8 @@ */ public class MetricReusableDataMarshaler { - private final Deque marshalerPool = new ArrayDeque<>(); + private final Deque marshalerPool = + new ConcurrentLinkedDeque<>(); private final MemoryMode memoryMode; private final BiFunction doExport; diff --git a/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/traces/SpanReusableDataMarshaler.java b/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/traces/SpanReusableDataMarshaler.java index af69e811c89..b359b6cc30c 100644 --- a/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/traces/SpanReusableDataMarshaler.java +++ b/exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/traces/SpanReusableDataMarshaler.java @@ -9,9 +9,9 @@ import io.opentelemetry.sdk.common.CompletableResultCode; import io.opentelemetry.sdk.common.export.MemoryMode; import io.opentelemetry.sdk.trace.data.SpanData; -import java.util.ArrayDeque; import java.util.Collection; import java.util.Deque; +import java.util.concurrent.ConcurrentLinkedDeque; import java.util.function.BiFunction; /** @@ -20,7 +20,8 @@ */ public class SpanReusableDataMarshaler { - private final Deque marshalerPool = new ArrayDeque<>(); + private final Deque marshalerPool = + new ConcurrentLinkedDeque<>(); private final MemoryMode memoryMode; private final BiFunction doExport; From d2b8497de086779501beb529c41ed1c4f9e1780c Mon Sep 17 00:00:00 2001 From: Yuriy Holinko Date: Fri, 24 Jan 2025 22:01:53 +0100 Subject: [PATCH 773/901] Retry on configurable exception (#6991) --- .../otel.japicmp-conventions.gradle.kts | 3 +- .../opentelemetry-sdk-common.txt | 8 +- .../AbstractGrpcTelemetryExporterTest.java | 2 +- .../AbstractHttpTelemetryExporterTest.java | 2 +- .../sender/jdk/internal/JdkHttpSender.java | 9 +- .../okhttp/internal/RetryInterceptor.java | 18 +++- .../okhttp/internal/RetryInterceptorTest.java | 100 ++++++++++++------ .../sdk/common/export/RetryPolicy.java | 14 +++ .../sdk/common/RetryPolicyTest.java | 1 + 9 files changed, 116 insertions(+), 41 deletions(-) diff --git a/buildSrc/src/main/kotlin/otel.japicmp-conventions.gradle.kts b/buildSrc/src/main/kotlin/otel.japicmp-conventions.gradle.kts index b59be80dd9b..46901734b23 100644 --- a/buildSrc/src/main/kotlin/otel.japicmp-conventions.gradle.kts +++ b/buildSrc/src/main/kotlin/otel.japicmp-conventions.gradle.kts @@ -27,7 +27,8 @@ val latestReleasedVersion: String by lazy { class AllowNewAbstractMethodOnAutovalueClasses : AbstractRecordingSeenMembers() { override fun maybeAddViolation(member: JApiCompatibility): Violation? { - val allowableAutovalueChanges = setOf(JApiCompatibilityChangeType.METHOD_ABSTRACT_ADDED_TO_CLASS, JApiCompatibilityChangeType.METHOD_ADDED_TO_PUBLIC_CLASS) + val allowableAutovalueChanges = setOf(JApiCompatibilityChangeType.METHOD_ABSTRACT_ADDED_TO_CLASS, + JApiCompatibilityChangeType.METHOD_ADDED_TO_PUBLIC_CLASS, JApiCompatibilityChangeType.ANNOTATION_ADDED) if (member.compatibilityChanges.filter { !allowableAutovalueChanges.contains(it.type) }.isEmpty() && member is JApiMethod && isAutoValueClass(member.getjApiClass())) { diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-common.txt b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-common.txt index 83355f6883d..7ee412b4334 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-common.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-common.txt @@ -1,2 +1,8 @@ Comparing source compatibility of opentelemetry-sdk-common-1.47.0-SNAPSHOT.jar against opentelemetry-sdk-common-1.46.0.jar -No changes. \ No newline at end of file +**** MODIFIED CLASS: PUBLIC ABSTRACT io.opentelemetry.sdk.common.export.RetryPolicy (not serializable) + === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 + +++* NEW METHOD: PUBLIC(+) ABSTRACT(+) java.util.function.Predicate getRetryExceptionPredicate() + +++ NEW ANNOTATION: javax.annotation.Nullable +**** MODIFIED CLASS: PUBLIC ABSTRACT STATIC io.opentelemetry.sdk.common.export.RetryPolicy$RetryPolicyBuilder (not serializable) + === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 + +++* NEW METHOD: PUBLIC(+) ABSTRACT(+) io.opentelemetry.sdk.common.export.RetryPolicy$RetryPolicyBuilder setRetryExceptionPredicate(java.util.function.Predicate) diff --git a/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/AbstractGrpcTelemetryExporterTest.java b/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/AbstractGrpcTelemetryExporterTest.java index 5aca2a4588e..33ef67bf6dd 100644 --- a/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/AbstractGrpcTelemetryExporterTest.java +++ b/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/AbstractGrpcTelemetryExporterTest.java @@ -1050,7 +1050,7 @@ void stringRepresentation() throws IOException, CertificateEncodingException { + ", " + "compressorEncoding=gzip, " + "headers=Headers\\{.*foo=OBFUSCATED.*\\}, " - + "retryPolicy=RetryPolicy\\{maxAttempts=2, initialBackoff=PT0\\.05S, maxBackoff=PT3S, backoffMultiplier=1\\.3\\}" + + "retryPolicy=RetryPolicy\\{maxAttempts=2, initialBackoff=PT0\\.05S, maxBackoff=PT3S, backoffMultiplier=1\\.3, retryExceptionPredicate=null\\}" + ".*" // Maybe additional grpcChannel field, signal specific fields + "\\}"); } finally { diff --git a/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/AbstractHttpTelemetryExporterTest.java b/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/AbstractHttpTelemetryExporterTest.java index 6f622a6e70c..b1d30da161a 100644 --- a/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/AbstractHttpTelemetryExporterTest.java +++ b/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/AbstractHttpTelemetryExporterTest.java @@ -935,7 +935,7 @@ void stringRepresentation() throws IOException, CertificateEncodingException { + ", " + "exportAsJson=false, " + "headers=Headers\\{.*foo=OBFUSCATED.*\\}, " - + "retryPolicy=RetryPolicy\\{maxAttempts=2, initialBackoff=PT0\\.05S, maxBackoff=PT3S, backoffMultiplier=1\\.3\\}" + + "retryPolicy=RetryPolicy\\{maxAttempts=2, initialBackoff=PT0\\.05S, maxBackoff=PT3S, backoffMultiplier=1\\.3, retryExceptionPredicate=null\\}" + ".*" // Maybe additional signal specific fields + "\\}"); } finally { diff --git a/exporters/sender/jdk/src/main/java/io/opentelemetry/exporter/sender/jdk/internal/JdkHttpSender.java b/exporters/sender/jdk/src/main/java/io/opentelemetry/exporter/sender/jdk/internal/JdkHttpSender.java index c79aaf6162f..c4d3276b495 100644 --- a/exporters/sender/jdk/src/main/java/io/opentelemetry/exporter/sender/jdk/internal/JdkHttpSender.java +++ b/exporters/sender/jdk/src/main/java/io/opentelemetry/exporter/sender/jdk/internal/JdkHttpSender.java @@ -26,6 +26,7 @@ import java.time.Duration; import java.util.List; import java.util.Map; +import java.util.Optional; import java.util.Set; import java.util.StringJoiner; import java.util.concurrent.CompletableFuture; @@ -35,6 +36,7 @@ import java.util.concurrent.ThreadLocalRandom; import java.util.concurrent.TimeUnit; import java.util.function.Consumer; +import java.util.function.Predicate; import java.util.function.Supplier; import java.util.logging.Level; import java.util.logging.Logger; @@ -68,6 +70,7 @@ public final class JdkHttpSender implements HttpSender { private final long timeoutNanos; private final Supplier>> headerSupplier; @Nullable private final RetryPolicy retryPolicy; + private final Predicate retryExceptionPredicate; // Visible for testing JdkHttpSender( @@ -91,6 +94,10 @@ public final class JdkHttpSender implements HttpSender { this.timeoutNanos = timeoutNanos; this.headerSupplier = headerSupplier; this.retryPolicy = retryPolicy; + this.retryExceptionPredicate = + Optional.ofNullable(retryPolicy) + .map(RetryPolicy::getRetryExceptionPredicate) + .orElse(JdkHttpSender::isRetryableException); } JdkHttpSender( @@ -235,7 +242,7 @@ HttpResponse sendInternal(Marshaler marshaler) throws IOException { } } if (exception != null) { - boolean retryable = isRetryableException(exception); + boolean retryable = retryExceptionPredicate.test(exception); if (logger.isLoggable(Level.FINER)) { logger.log( Level.FINER, diff --git a/exporters/sender/okhttp/src/main/java/io/opentelemetry/exporter/sender/okhttp/internal/RetryInterceptor.java b/exporters/sender/okhttp/src/main/java/io/opentelemetry/exporter/sender/okhttp/internal/RetryInterceptor.java index 405c54f1945..ed17849e44c 100644 --- a/exporters/sender/okhttp/src/main/java/io/opentelemetry/exporter/sender/okhttp/internal/RetryInterceptor.java +++ b/exporters/sender/okhttp/src/main/java/io/opentelemetry/exporter/sender/okhttp/internal/RetryInterceptor.java @@ -16,6 +16,7 @@ import java.util.concurrent.ThreadLocalRandom; import java.util.concurrent.TimeUnit; import java.util.function.Function; +import java.util.function.Predicate; import java.util.logging.Level; import java.util.logging.Logger; import okhttp3.Interceptor; @@ -33,7 +34,7 @@ public final class RetryInterceptor implements Interceptor { private final RetryPolicy retryPolicy; private final Function isRetryable; - private final Function isRetryableException; + private final Predicate retryExceptionPredicate; private final Sleeper sleeper; private final BoundedLongGenerator randomLong; @@ -42,7 +43,9 @@ public RetryInterceptor(RetryPolicy retryPolicy, Function isR this( retryPolicy, isRetryable, - RetryInterceptor::isRetryableException, + retryPolicy.getRetryExceptionPredicate() == null + ? RetryInterceptor::isRetryableException + : retryPolicy.getRetryExceptionPredicate(), TimeUnit.NANOSECONDS::sleep, bound -> ThreadLocalRandom.current().nextLong(bound)); } @@ -51,12 +54,12 @@ public RetryInterceptor(RetryPolicy retryPolicy, Function isR RetryInterceptor( RetryPolicy retryPolicy, Function isRetryable, - Function isRetryableException, + Predicate retryExceptionPredicate, Sleeper sleeper, BoundedLongGenerator randomLong) { this.retryPolicy = retryPolicy; this.isRetryable = isRetryable; - this.isRetryableException = isRetryableException; + this.retryExceptionPredicate = retryExceptionPredicate; this.sleeper = sleeper; this.randomLong = randomLong; } @@ -109,7 +112,7 @@ public Response intercept(Chain chain) throws IOException { } } if (exception != null) { - boolean retryable = Boolean.TRUE.equals(isRetryableException.apply(exception)); + boolean retryable = retryExceptionPredicate.test(exception); if (logger.isLoggable(Level.FINER)) { logger.log( Level.FINER, @@ -144,6 +147,11 @@ private static String responseStringRepresentation(Response response) { return joiner.toString(); } + // Visible for testing + boolean shouldRetryOnException(IOException e) { + return retryExceptionPredicate.test(e); + } + // Visible for testing static boolean isRetryableException(IOException e) { if (e instanceof SocketTimeoutException) { diff --git a/exporters/sender/okhttp/src/test/java/io/opentelemetry/exporter/sender/okhttp/internal/RetryInterceptorTest.java b/exporters/sender/okhttp/src/test/java/io/opentelemetry/exporter/sender/okhttp/internal/RetryInterceptorTest.java index 8b47700e88b..81e01d52b82 100644 --- a/exporters/sender/okhttp/src/test/java/io/opentelemetry/exporter/sender/okhttp/internal/RetryInterceptorTest.java +++ b/exporters/sender/okhttp/src/test/java/io/opentelemetry/exporter/sender/okhttp/internal/RetryInterceptorTest.java @@ -24,11 +24,14 @@ import io.opentelemetry.sdk.common.export.RetryPolicy; import java.io.IOException; import java.net.ConnectException; +import java.net.HttpRetryException; import java.net.ServerSocket; import java.net.SocketTimeoutException; import java.time.Duration; import java.util.concurrent.TimeUnit; -import java.util.function.Function; +import java.util.function.Predicate; +import java.util.logging.Level; +import java.util.logging.Logger; import okhttp3.OkHttpClient; import okhttp3.Request; import okhttp3.Response; @@ -48,34 +51,38 @@ class RetryInterceptorTest { @Mock private RetryInterceptor.Sleeper sleeper; @Mock private RetryInterceptor.BoundedLongGenerator random; - private Function isRetryableException; + private Predicate retryExceptionPredicate; private RetryInterceptor retrier; private OkHttpClient client; @BeforeEach void setUp() { - // Note: cannot replace this with lambda or method reference because we need to spy on it - isRetryableException = + Logger logger = java.util.logging.Logger.getLogger(RetryInterceptor.class.getName()); + logger.setLevel(Level.FINER); + retryExceptionPredicate = spy( - new Function() { + new Predicate() { @Override - public Boolean apply(IOException exception) { - return RetryInterceptor.isRetryableException(exception); + public boolean test(IOException e) { + return RetryInterceptor.isRetryableException(e) + || (e instanceof HttpRetryException + && e.getMessage().contains("timeout retry")); } }); + + RetryPolicy retryPolicy = + RetryPolicy.builder() + .setBackoffMultiplier(1.6) + .setInitialBackoff(Duration.ofSeconds(1)) + .setMaxBackoff(Duration.ofSeconds(2)) + .setMaxAttempts(5) + .setRetryExceptionPredicate(retryExceptionPredicate) + .build(); + retrier = new RetryInterceptor( - RetryPolicy.builder() - .setBackoffMultiplier(1.6) - .setInitialBackoff(Duration.ofSeconds(1)) - .setMaxBackoff(Duration.ofSeconds(2)) - .setMaxAttempts(5) - .build(), - r -> !r.isSuccessful(), - isRetryableException, - sleeper, - random); + retryPolicy, r -> !r.isSuccessful(), retryExceptionPredicate, sleeper, random); client = new OkHttpClient.Builder().addInterceptor(retrier).build(); } @@ -154,7 +161,7 @@ void connectTimeout() throws Exception { client.newCall(new Request.Builder().url("http://10.255.255.1").build()).execute()) .isInstanceOf(SocketTimeoutException.class); - verify(isRetryableException, times(5)).apply(any()); + verify(retryExceptionPredicate, times(5)).test(any()); // Should retry maxAttempts, and sleep maxAttempts - 1 times verify(sleeper, times(4)).sleep(anyLong()); } @@ -174,7 +181,7 @@ void connectException() throws Exception { .execute()) .isInstanceOfAny(ConnectException.class, SocketTimeoutException.class); - verify(isRetryableException, times(5)).apply(any()); + verify(retryExceptionPredicate, times(5)).test(any()); // Should retry maxAttempts, and sleep maxAttempts - 1 times verify(sleeper, times(4)).sleep(anyLong()); } @@ -190,8 +197,8 @@ private static int freePort() { @Test void nonRetryableException() throws InterruptedException { client = connectTimeoutClient(); - // Override isRetryableException so that no exception is retryable - when(isRetryableException.apply(any())).thenReturn(false); + // Override retryPredicate so that no exception is retryable + when(retryExceptionPredicate.test(any())).thenReturn(false); // Connecting to a non-routable IP address to trigger connection timeout assertThatThrownBy( @@ -199,7 +206,7 @@ void nonRetryableException() throws InterruptedException { client.newCall(new Request.Builder().url("http://10.255.255.1").build()).execute()) .isInstanceOf(SocketTimeoutException.class); - verify(isRetryableException, times(1)).apply(any()); + verify(retryExceptionPredicate, times(1)).test(any()); verify(sleeper, never()).sleep(anyLong()); } @@ -214,20 +221,51 @@ private OkHttpClient connectTimeoutClient() { void isRetryableException() { // Should retry on connection timeouts, where error message is "Connect timed out" or "connect // timed out" - assertThat( - RetryInterceptor.isRetryableException(new SocketTimeoutException("Connect timed out"))) + assertThat(retrier.shouldRetryOnException(new SocketTimeoutException("Connect timed out"))) .isTrue(); - assertThat( - RetryInterceptor.isRetryableException(new SocketTimeoutException("connect timed out"))) + assertThat(retrier.shouldRetryOnException(new SocketTimeoutException("connect timed out"))) .isTrue(); // Shouldn't retry on read timeouts, where error message is "Read timed out" - assertThat(RetryInterceptor.isRetryableException(new SocketTimeoutException("Read timed out"))) + assertThat(retrier.shouldRetryOnException(new SocketTimeoutException("Read timed out"))) .isFalse(); - // Shouldn't retry on write timeouts, where error message is "timeout", or other IOException - assertThat(RetryInterceptor.isRetryableException(new SocketTimeoutException("timeout"))) + // Shouldn't retry on write timeouts or other IOException + assertThat(retrier.shouldRetryOnException(new SocketTimeoutException("timeout"))).isFalse(); + assertThat(retrier.shouldRetryOnException(new SocketTimeoutException())).isTrue(); + assertThat(retrier.shouldRetryOnException(new IOException("error"))).isFalse(); + + // Testing configured predicate + assertThat(retrier.shouldRetryOnException(new HttpRetryException("error", 400))).isFalse(); + assertThat(retrier.shouldRetryOnException(new HttpRetryException("timeout retry", 400))) + .isTrue(); + } + + @Test + void isRetryableExceptionDefaultBehaviour() { + RetryInterceptor retryInterceptor = + new RetryInterceptor(RetryPolicy.getDefault(), OkHttpHttpSender::isRetryable); + assertThat( + retryInterceptor.shouldRetryOnException( + new SocketTimeoutException("Connect timed out"))) + .isTrue(); + assertThat(retryInterceptor.shouldRetryOnException(new IOException("Connect timed out"))) + .isFalse(); + } + + @Test + void isRetryableExceptionCustomRetryPredicate() { + RetryInterceptor retryInterceptor = + new RetryInterceptor( + RetryPolicy.builder() + .setRetryExceptionPredicate((IOException e) -> e.getMessage().equals("retry")) + .build(), + OkHttpHttpSender::isRetryable); + + assertThat(retryInterceptor.shouldRetryOnException(new IOException("some message"))).isFalse(); + assertThat(retryInterceptor.shouldRetryOnException(new IOException("retry"))).isTrue(); + assertThat( + retryInterceptor.shouldRetryOnException( + new SocketTimeoutException("Connect timed out"))) .isFalse(); - assertThat(RetryInterceptor.isRetryableException(new SocketTimeoutException())).isTrue(); - assertThat(RetryInterceptor.isRetryableException(new IOException("error"))).isFalse(); } private Response sendRequest() throws IOException { diff --git a/sdk/common/src/main/java/io/opentelemetry/sdk/common/export/RetryPolicy.java b/sdk/common/src/main/java/io/opentelemetry/sdk/common/export/RetryPolicy.java index 1191f80ff35..311317bce4c 100644 --- a/sdk/common/src/main/java/io/opentelemetry/sdk/common/export/RetryPolicy.java +++ b/sdk/common/src/main/java/io/opentelemetry/sdk/common/export/RetryPolicy.java @@ -8,7 +8,10 @@ import static io.opentelemetry.api.internal.Utils.checkArgument; import com.google.auto.value.AutoValue; +import java.io.IOException; import java.time.Duration; +import java.util.function.Predicate; +import javax.annotation.Nullable; /** * Configuration for exporter exponential retry policy. @@ -66,6 +69,13 @@ public static RetryPolicyBuilder builder() { /** Returns the backoff multiplier. */ public abstract double getBackoffMultiplier(); + /** + * Returns the predicate used to determine if thrown exception is retryableor {@code null} if no + * predicate was set. + */ + @Nullable + public abstract Predicate getRetryExceptionPredicate(); + /** Builder for {@link RetryPolicy}. */ @AutoValue.Builder public abstract static class RetryPolicyBuilder { @@ -96,6 +106,10 @@ public abstract static class RetryPolicyBuilder { */ public abstract RetryPolicyBuilder setBackoffMultiplier(double backoffMultiplier); + /** Set the predicate to determine if retry should happen based on exception. */ + public abstract RetryPolicyBuilder setRetryExceptionPredicate( + Predicate retryExceptionPredicate); + abstract RetryPolicy autoBuild(); /** Build and return a {@link RetryPolicy} with the values of this builder. */ diff --git a/sdk/common/src/test/java/io/opentelemetry/sdk/common/RetryPolicyTest.java b/sdk/common/src/test/java/io/opentelemetry/sdk/common/RetryPolicyTest.java index 7f63a8dc9df..e0f56ff58a5 100644 --- a/sdk/common/src/test/java/io/opentelemetry/sdk/common/RetryPolicyTest.java +++ b/sdk/common/src/test/java/io/opentelemetry/sdk/common/RetryPolicyTest.java @@ -40,6 +40,7 @@ void build() { assertThat(retryPolicy.getInitialBackoff()).isEqualTo(Duration.ofMillis(2)); assertThat(retryPolicy.getMaxBackoff()).isEqualTo(Duration.ofSeconds(1)); assertThat(retryPolicy.getBackoffMultiplier()).isEqualTo(1.1); + assertThat(retryPolicy.getRetryExceptionPredicate()).isEqualTo(null); } @Test From 070aedcf5889e67a44e9d96f69f09bbe5fb5d1ab Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 24 Jan 2025 15:04:34 -0600 Subject: [PATCH 774/901] chore(deps): update dependency gradle to v8.12.1 (#7040) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- gradle/wrapper/gradle-wrapper.properties | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index e1b837a19c2..d71047787f8 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,7 +1,7 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionSha256Sum=7a00d51fb93147819aab76024feece20b6b84e420694101f276be952e08bef03 -distributionUrl=https\://services.gradle.org/distributions/gradle-8.12-bin.zip +distributionSha256Sum=8d97a97984f6cbd2b85fe4c60a743440a347544bf18818048e611f5288d46c94 +distributionUrl=https\://services.gradle.org/distributions/gradle-8.12.1-bin.zip networkTimeout=10000 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME From 5e1a3979b67a949e9c68b517609843f99cc0a2af Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sun, 26 Jan 2025 11:23:59 -0800 Subject: [PATCH 775/901] fix(deps): update dependency ru.vyarus:gradle-animalsniffer-plugin to v2 (#7042) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- buildSrc/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts index 8f605e56bcd..8e0082e2a7f 100644 --- a/buildSrc/build.gradle.kts +++ b/buildSrc/build.gradle.kts @@ -67,7 +67,7 @@ dependencies { implementation("net.ltgt.gradle:gradle-nullaway-plugin:2.2.0") implementation("org.jetbrains.kotlin:kotlin-gradle-plugin:2.1.0") implementation("org.owasp:dependency-check-gradle:12.0.1") - implementation("ru.vyarus:gradle-animalsniffer-plugin:1.7.2") + implementation("ru.vyarus:gradle-animalsniffer-plugin:2.0.0") } // We can't apply conventions to this build so include important ones such as the Java compilation From 1c1d56113d53d8b95a5dd97381932b32fe810181 Mon Sep 17 00:00:00 2001 From: jack-berg <34418638+jack-berg@users.noreply.github.com> Date: Tue, 28 Jan 2025 10:37:00 -0600 Subject: [PATCH 776/901] Expand OkHttp retry exception predicate (#7047) --- .../okhttp/internal/RetryInterceptor.java | 15 +++--- .../okhttp/internal/RetryInterceptorTest.java | 48 +++++++++++-------- .../sdk/common/export/RetryPolicy.java | 9 ++-- 3 files changed, 42 insertions(+), 30 deletions(-) diff --git a/exporters/sender/okhttp/src/main/java/io/opentelemetry/exporter/sender/okhttp/internal/RetryInterceptor.java b/exporters/sender/okhttp/src/main/java/io/opentelemetry/exporter/sender/okhttp/internal/RetryInterceptor.java index ed17849e44c..9f6cc4729f5 100644 --- a/exporters/sender/okhttp/src/main/java/io/opentelemetry/exporter/sender/okhttp/internal/RetryInterceptor.java +++ b/exporters/sender/okhttp/src/main/java/io/opentelemetry/exporter/sender/okhttp/internal/RetryInterceptor.java @@ -11,7 +11,7 @@ import java.io.IOException; import java.net.ConnectException; import java.net.SocketTimeoutException; -import java.util.Locale; +import java.net.UnknownHostException; import java.util.StringJoiner; import java.util.concurrent.ThreadLocalRandom; import java.util.concurrent.TimeUnit; @@ -154,14 +154,15 @@ boolean shouldRetryOnException(IOException e) { // Visible for testing static boolean isRetryableException(IOException e) { + // Known retryable SocketTimeoutException messages: null, "connect timed out", "timeout" + // Known retryable ConnectTimeout messages: "Failed to connect to + // localhost/[0:0:0:0:0:0:0:1]:62611" + // Known retryable UnknownHostException messages: "xxxxxx.com" if (e instanceof SocketTimeoutException) { - String message = e.getMessage(); - // Connect timeouts can produce SocketTimeoutExceptions with no message, or with "connect - // timed out" - return message == null || message.toLowerCase(Locale.ROOT).contains("connect timed out"); + return true; } else if (e instanceof ConnectException) { - // Exceptions resemble: java.net.ConnectException: Failed to connect to - // localhost/[0:0:0:0:0:0:0:1]:62611 + return true; + } else if (e instanceof UnknownHostException) { return true; } return false; diff --git a/exporters/sender/okhttp/src/test/java/io/opentelemetry/exporter/sender/okhttp/internal/RetryInterceptorTest.java b/exporters/sender/okhttp/src/test/java/io/opentelemetry/exporter/sender/okhttp/internal/RetryInterceptorTest.java index 81e01d52b82..fa7604fb99d 100644 --- a/exporters/sender/okhttp/src/test/java/io/opentelemetry/exporter/sender/okhttp/internal/RetryInterceptorTest.java +++ b/exporters/sender/okhttp/src/test/java/io/opentelemetry/exporter/sender/okhttp/internal/RetryInterceptorTest.java @@ -27,11 +27,13 @@ import java.net.HttpRetryException; import java.net.ServerSocket; import java.net.SocketTimeoutException; +import java.net.UnknownHostException; import java.time.Duration; import java.util.concurrent.TimeUnit; import java.util.function.Predicate; import java.util.logging.Level; import java.util.logging.Logger; +import java.util.stream.Stream; import okhttp3.OkHttpClient; import okhttp3.Request; import okhttp3.Response; @@ -40,6 +42,8 @@ import org.junit.jupiter.api.extension.ExtendWith; import org.junit.jupiter.api.extension.RegisterExtension; import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; import org.junit.jupiter.params.provider.ValueSource; import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; @@ -217,26 +221,30 @@ private OkHttpClient connectTimeoutClient() { .build(); } - @Test - void isRetryableException() { - // Should retry on connection timeouts, where error message is "Connect timed out" or "connect - // timed out" - assertThat(retrier.shouldRetryOnException(new SocketTimeoutException("Connect timed out"))) - .isTrue(); - assertThat(retrier.shouldRetryOnException(new SocketTimeoutException("connect timed out"))) - .isTrue(); - // Shouldn't retry on read timeouts, where error message is "Read timed out" - assertThat(retrier.shouldRetryOnException(new SocketTimeoutException("Read timed out"))) - .isFalse(); - // Shouldn't retry on write timeouts or other IOException - assertThat(retrier.shouldRetryOnException(new SocketTimeoutException("timeout"))).isFalse(); - assertThat(retrier.shouldRetryOnException(new SocketTimeoutException())).isTrue(); - assertThat(retrier.shouldRetryOnException(new IOException("error"))).isFalse(); - - // Testing configured predicate - assertThat(retrier.shouldRetryOnException(new HttpRetryException("error", 400))).isFalse(); - assertThat(retrier.shouldRetryOnException(new HttpRetryException("timeout retry", 400))) - .isTrue(); + @ParameterizedTest + @MethodSource("isRetryableExceptionArgs") + void isRetryableException(IOException exception, boolean expectedRetryResult) { + assertThat(retrier.shouldRetryOnException(exception)).isEqualTo(expectedRetryResult); + } + + private static Stream isRetryableExceptionArgs() { + return Stream.of( + // Should retry on SocketTimeoutExceptions + Arguments.of(new SocketTimeoutException("Connect timed out"), true), + Arguments.of(new SocketTimeoutException("connect timed out"), true), + Arguments.of(new SocketTimeoutException("timeout"), true), + Arguments.of(new SocketTimeoutException("Read timed out"), true), + Arguments.of(new SocketTimeoutException(), true), + // Should retry on UnknownHostExceptions + Arguments.of(new UnknownHostException("host"), true), + // Should retry on ConnectException + Arguments.of( + new ConnectException("Failed to connect to localhost/[0:0:0:0:0:0:0:1]:62611"), true), + // Shouldn't retry other IOException + Arguments.of(new IOException("error"), false), + // Testing configured predicate + Arguments.of(new HttpRetryException("error", 400), false), + Arguments.of(new HttpRetryException("timeout retry", 400), true)); } @Test diff --git a/sdk/common/src/main/java/io/opentelemetry/sdk/common/export/RetryPolicy.java b/sdk/common/src/main/java/io/opentelemetry/sdk/common/export/RetryPolicy.java index 311317bce4c..edda64d6c44 100644 --- a/sdk/common/src/main/java/io/opentelemetry/sdk/common/export/RetryPolicy.java +++ b/sdk/common/src/main/java/io/opentelemetry/sdk/common/export/RetryPolicy.java @@ -70,8 +70,8 @@ public static RetryPolicyBuilder builder() { public abstract double getBackoffMultiplier(); /** - * Returns the predicate used to determine if thrown exception is retryableor {@code null} if no - * predicate was set. + * Returns the predicate used to determine if an attempt which failed exceptionally should be + * retried, or {@code null} if the exporter specific default predicate should be used. */ @Nullable public abstract Predicate getRetryExceptionPredicate(); @@ -106,7 +106,10 @@ public abstract static class RetryPolicyBuilder { */ public abstract RetryPolicyBuilder setBackoffMultiplier(double backoffMultiplier); - /** Set the predicate to determine if retry should happen based on exception. */ + /** + * Set the predicate used to determine if an attempt which failed exceptionally should be + * retried. By default, an exporter specific default predicate should be used. + */ public abstract RetryPolicyBuilder setRetryExceptionPredicate( Predicate retryExceptionPredicate); From c4412f2070c9b0af0e2003dd9429815355a44c4f Mon Sep 17 00:00:00 2001 From: Onur Kayabasi Date: Tue, 28 Jan 2025 23:41:02 +0100 Subject: [PATCH 777/901] Follow spec on span limits, batch processors (#7030) --- .../TracerProviderConfigurationTest.java | 4 +-- .../LoggerProviderConfigurationTest.java | 4 +-- .../sdk/logs/LogLimitsBuilder.java | 4 +-- .../BatchLogRecordProcessorBuilder.java | 2 ++ .../opentelemetry/sdk/logs/LogLimitsTest.java | 11 ++++++-- .../export/BatchLogRecordProcessorTest.java | 5 ++++ .../sdk/trace/SpanLimitsBuilder.java | 12 ++++----- .../export/BatchSpanProcessorBuilder.java | 2 ++ .../sdk/trace/config/SpanLimitsTest.java | 25 +++++++++++-------- .../trace/export/BatchSpanProcessorTest.java | 4 +++ 10 files changed, 49 insertions(+), 24 deletions(-) diff --git a/sdk-extensions/autoconfigure/src/test/java/io/opentelemetry/sdk/autoconfigure/TracerProviderConfigurationTest.java b/sdk-extensions/autoconfigure/src/test/java/io/opentelemetry/sdk/autoconfigure/TracerProviderConfigurationTest.java index d12ab1744f4..e0ddcb438fe 100644 --- a/sdk-extensions/autoconfigure/src/test/java/io/opentelemetry/sdk/autoconfigure/TracerProviderConfigurationTest.java +++ b/sdk-extensions/autoconfigure/src/test/java/io/opentelemetry/sdk/autoconfigure/TracerProviderConfigurationTest.java @@ -126,7 +126,7 @@ void configureBatchSpanProcessor_configured() { Map properties = new HashMap<>(); properties.put("otel.bsp.schedule.delay", "100000"); properties.put("otel.bsp.max.queue.size", "2"); - properties.put("otel.bsp.max.export.batch.size", "3"); + properties.put("otel.bsp.max.export.batch.size", "2"); properties.put("otel.bsp.export.timeout", "4"); try (BatchSpanProcessor processor = @@ -144,7 +144,7 @@ void configureBatchSpanProcessor_configured() { assertThat(worker) .extracting("exporterTimeoutNanos") .isEqualTo(TimeUnit.MILLISECONDS.toNanos(4)); - assertThat(worker).extracting("maxExportBatchSize").isEqualTo(3); + assertThat(worker).extracting("maxExportBatchSize").isEqualTo(2); assertThat(worker) .extracting("queue") .isInstanceOfSatisfying( diff --git a/sdk-extensions/autoconfigure/src/testFullConfig/java/io/opentelemetry/sdk/autoconfigure/LoggerProviderConfigurationTest.java b/sdk-extensions/autoconfigure/src/testFullConfig/java/io/opentelemetry/sdk/autoconfigure/LoggerProviderConfigurationTest.java index d3856cd93c2..7a5473e8dea 100644 --- a/sdk-extensions/autoconfigure/src/testFullConfig/java/io/opentelemetry/sdk/autoconfigure/LoggerProviderConfigurationTest.java +++ b/sdk-extensions/autoconfigure/src/testFullConfig/java/io/opentelemetry/sdk/autoconfigure/LoggerProviderConfigurationTest.java @@ -118,7 +118,7 @@ void configureBatchLogRecordProcessor() { Map properties = new HashMap<>(); properties.put("otel.blrp.schedule.delay", "100000"); properties.put("otel.blrp.max.queue.size", "2"); - properties.put("otel.blrp.max.export.batch.size", "3"); + properties.put("otel.blrp.max.export.batch.size", "2"); properties.put("otel.blrp.export.timeout", "4"); try (BatchLogRecordProcessor processor = @@ -136,7 +136,7 @@ void configureBatchLogRecordProcessor() { assertThat(worker) .extracting("exporterTimeoutNanos") .isEqualTo(TimeUnit.MILLISECONDS.toNanos(4)); - assertThat(worker).extracting("maxExportBatchSize").isEqualTo(3); + assertThat(worker).extracting("maxExportBatchSize").isEqualTo(2); assertThat(worker) .extracting("queue") .isInstanceOfSatisfying( diff --git a/sdk/logs/src/main/java/io/opentelemetry/sdk/logs/LogLimitsBuilder.java b/sdk/logs/src/main/java/io/opentelemetry/sdk/logs/LogLimitsBuilder.java index 22650d4d896..f4f74bf5ac3 100644 --- a/sdk/logs/src/main/java/io/opentelemetry/sdk/logs/LogLimitsBuilder.java +++ b/sdk/logs/src/main/java/io/opentelemetry/sdk/logs/LogLimitsBuilder.java @@ -32,7 +32,7 @@ public final class LogLimitsBuilder { * @throws IllegalArgumentException if {@code maxNumberOfAttributes} is not positive. */ public LogLimitsBuilder setMaxNumberOfAttributes(int maxNumberOfAttributes) { - Utils.checkArgument(maxNumberOfAttributes > 0, "maxNumberOfAttributes must be greater than 0"); + Utils.checkArgument(maxNumberOfAttributes >= 0, "maxNumberOfAttributes must be non-negative"); this.maxNumAttributes = maxNumberOfAttributes; return this; } @@ -48,7 +48,7 @@ public LogLimitsBuilder setMaxNumberOfAttributes(int maxNumberOfAttributes) { */ public LogLimitsBuilder setMaxAttributeValueLength(int maxAttributeValueLength) { Utils.checkArgument( - maxAttributeValueLength > -1, "maxAttributeValueLength must be non-negative"); + maxAttributeValueLength >= 0, "maxAttributeValueLength must be non-negative"); this.maxAttributeValueLength = maxAttributeValueLength; return this; } diff --git a/sdk/logs/src/main/java/io/opentelemetry/sdk/logs/export/BatchLogRecordProcessorBuilder.java b/sdk/logs/src/main/java/io/opentelemetry/sdk/logs/export/BatchLogRecordProcessorBuilder.java index 4cf30586367..40e53302e66 100644 --- a/sdk/logs/src/main/java/io/opentelemetry/sdk/logs/export/BatchLogRecordProcessorBuilder.java +++ b/sdk/logs/src/main/java/io/opentelemetry/sdk/logs/export/BatchLogRecordProcessorBuilder.java @@ -98,9 +98,11 @@ long getExporterTimeoutNanos() { * @param maxQueueSize the maximum number of Logs that are kept in the queue before start * dropping. * @return this. + * @throws IllegalArgumentException if {@code maxQueueSize} is not positive. * @see BatchLogRecordProcessorBuilder#DEFAULT_MAX_QUEUE_SIZE */ public BatchLogRecordProcessorBuilder setMaxQueueSize(int maxQueueSize) { + checkArgument(maxQueueSize > 0, "maxQueueSize must be positive."); this.maxQueueSize = maxQueueSize; return this; } diff --git a/sdk/logs/src/test/java/io/opentelemetry/sdk/logs/LogLimitsTest.java b/sdk/logs/src/test/java/io/opentelemetry/sdk/logs/LogLimitsTest.java index 250d49f8402..4acb0666bab 100644 --- a/sdk/logs/src/test/java/io/opentelemetry/sdk/logs/LogLimitsTest.java +++ b/sdk/logs/src/test/java/io/opentelemetry/sdk/logs/LogLimitsTest.java @@ -6,6 +6,7 @@ package io.opentelemetry.sdk.logs; import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatCode; import static org.assertj.core.api.Assertions.assertThatThrownBy; import org.junit.jupiter.api.Test; @@ -33,11 +34,17 @@ void updateLogLimits_All() { @Test void invalidLogLimits() { - assertThatThrownBy(() -> LogLimits.builder().setMaxNumberOfAttributes(0)) - .isInstanceOf(IllegalArgumentException.class); assertThatThrownBy(() -> LogLimits.builder().setMaxNumberOfAttributes(-1)) .isInstanceOf(IllegalArgumentException.class); assertThatThrownBy(() -> LogLimits.builder().setMaxAttributeValueLength(-1)) .isInstanceOf(IllegalArgumentException.class); } + + @Test + void validLogLimits() { + assertThatCode(() -> LogLimits.builder().setMaxNumberOfAttributes(0)) + .doesNotThrowAnyException(); + assertThatCode(() -> LogLimits.builder().setMaxAttributeValueLength(0)) + .doesNotThrowAnyException(); + } } diff --git a/sdk/logs/src/test/java/io/opentelemetry/sdk/logs/export/BatchLogRecordProcessorTest.java b/sdk/logs/src/test/java/io/opentelemetry/sdk/logs/export/BatchLogRecordProcessorTest.java index 4c17a1768f7..e051eaf175a 100644 --- a/sdk/logs/src/test/java/io/opentelemetry/sdk/logs/export/BatchLogRecordProcessorTest.java +++ b/sdk/logs/src/test/java/io/opentelemetry/sdk/logs/export/BatchLogRecordProcessorTest.java @@ -111,6 +111,10 @@ void builderInvalidConfig() { () -> BatchLogRecordProcessor.builder(mockLogRecordExporter).setExporterTimeout(null)) .isInstanceOf(NullPointerException.class) .hasMessage("timeout"); + assertThatThrownBy( + () -> BatchLogRecordProcessor.builder(mockLogRecordExporter).setMaxQueueSize(0)) + .isInstanceOf(IllegalArgumentException.class) + .hasMessage("maxQueueSize must be positive."); } @Test @@ -337,6 +341,7 @@ public void continuesIfExporterTimesOut() throws InterruptedException { .setExporterTimeout(exporterTimeoutMillis, TimeUnit.MILLISECONDS) .setScheduleDelay(1, TimeUnit.MILLISECONDS) .setMaxQueueSize(1) + .setMaxExportBatchSize(1) .build(); SdkLoggerProvider sdkLoggerProvider = SdkLoggerProvider.builder().addLogRecordProcessor(blp).build(); diff --git a/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/SpanLimitsBuilder.java b/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/SpanLimitsBuilder.java index 14b5f06f1a6..353bc19b044 100644 --- a/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/SpanLimitsBuilder.java +++ b/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/SpanLimitsBuilder.java @@ -34,7 +34,7 @@ public final class SpanLimitsBuilder { * @throws IllegalArgumentException if {@code maxNumberOfAttributes} is not positive. */ public SpanLimitsBuilder setMaxNumberOfAttributes(int maxNumberOfAttributes) { - Utils.checkArgument(maxNumberOfAttributes > 0, "maxNumberOfAttributes must be greater than 0"); + Utils.checkArgument(maxNumberOfAttributes >= 0, "maxNumberOfAttributes must be non-negative"); this.maxNumAttributes = maxNumberOfAttributes; return this; } @@ -47,7 +47,7 @@ public SpanLimitsBuilder setMaxNumberOfAttributes(int maxNumberOfAttributes) { * @throws IllegalArgumentException if {@code maxNumberOfEvents} is not positive. */ public SpanLimitsBuilder setMaxNumberOfEvents(int maxNumberOfEvents) { - Utils.checkArgument(maxNumberOfEvents > 0, "maxNumberOfEvents must be greater than 0"); + Utils.checkArgument(maxNumberOfEvents >= 0, "maxNumberOfEvents must be non-negative"); this.maxNumEvents = maxNumberOfEvents; return this; } @@ -60,7 +60,7 @@ public SpanLimitsBuilder setMaxNumberOfEvents(int maxNumberOfEvents) { * @throws IllegalArgumentException if {@code maxNumberOfLinks} is not positive. */ public SpanLimitsBuilder setMaxNumberOfLinks(int maxNumberOfLinks) { - Utils.checkArgument(maxNumberOfLinks > 0, "maxNumberOfLinks must be greater than 0"); + Utils.checkArgument(maxNumberOfLinks >= 0, "maxNumberOfLinks must be non-negative"); this.maxNumLinks = maxNumberOfLinks; return this; } @@ -74,7 +74,7 @@ public SpanLimitsBuilder setMaxNumberOfLinks(int maxNumberOfLinks) { */ public SpanLimitsBuilder setMaxNumberOfAttributesPerEvent(int maxNumberOfAttributesPerEvent) { Utils.checkArgument( - maxNumberOfAttributesPerEvent > 0, "maxNumberOfAttributesPerEvent must be greater than 0"); + maxNumberOfAttributesPerEvent >= 0, "maxNumberOfAttributesPerEvent must be non-negative"); this.maxNumAttributesPerEvent = maxNumberOfAttributesPerEvent; return this; } @@ -88,7 +88,7 @@ public SpanLimitsBuilder setMaxNumberOfAttributesPerEvent(int maxNumberOfAttribu */ public SpanLimitsBuilder setMaxNumberOfAttributesPerLink(int maxNumberOfAttributesPerLink) { Utils.checkArgument( - maxNumberOfAttributesPerLink > 0, "maxNumberOfAttributesPerLink must be greater than 0"); + maxNumberOfAttributesPerLink >= 0, "maxNumberOfAttributesPerLink must be non-negative"); this.maxNumAttributesPerLink = maxNumberOfAttributesPerLink; return this; } @@ -104,7 +104,7 @@ public SpanLimitsBuilder setMaxNumberOfAttributesPerLink(int maxNumberOfAttribut */ public SpanLimitsBuilder setMaxAttributeValueLength(int maxAttributeValueLength) { Utils.checkArgument( - maxAttributeValueLength > -1, "maxAttributeValueLength must be non-negative"); + maxAttributeValueLength >= 0, "maxAttributeValueLength must be non-negative"); this.maxAttributeValueLength = maxAttributeValueLength; return this; } diff --git a/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/export/BatchSpanProcessorBuilder.java b/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/export/BatchSpanProcessorBuilder.java index 3ec3fce0778..8e9fe970d56 100644 --- a/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/export/BatchSpanProcessorBuilder.java +++ b/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/export/BatchSpanProcessorBuilder.java @@ -106,9 +106,11 @@ long getExporterTimeoutNanos() { * @param maxQueueSize the maximum number of Spans that are kept in the queue before start * dropping. * @return this. + * @throws IllegalArgumentException if {@code maxQueueSize} is not positive. * @see BatchSpanProcessorBuilder#DEFAULT_MAX_QUEUE_SIZE */ public BatchSpanProcessorBuilder setMaxQueueSize(int maxQueueSize) { + checkArgument(maxQueueSize > 0, "maxQueueSize must be positive."); this.maxQueueSize = maxQueueSize; return this; } diff --git a/sdk/trace/src/test/java/io/opentelemetry/sdk/trace/config/SpanLimitsTest.java b/sdk/trace/src/test/java/io/opentelemetry/sdk/trace/config/SpanLimitsTest.java index ab749cea0f5..73d9ac2e842 100644 --- a/sdk/trace/src/test/java/io/opentelemetry/sdk/trace/config/SpanLimitsTest.java +++ b/sdk/trace/src/test/java/io/opentelemetry/sdk/trace/config/SpanLimitsTest.java @@ -6,6 +6,7 @@ package io.opentelemetry.sdk.trace.config; import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatCode; import static org.assertj.core.api.Assertions.assertThatThrownBy; import io.opentelemetry.sdk.trace.SpanLimits; @@ -46,27 +47,31 @@ void updateSpanLimits_All() { @Test void invalidSpanLimits() { - assertThatThrownBy(() -> SpanLimits.builder().setMaxNumberOfAttributes(0)) - .isInstanceOf(IllegalArgumentException.class); assertThatThrownBy(() -> SpanLimits.builder().setMaxNumberOfAttributes(-1)) .isInstanceOf(IllegalArgumentException.class); - assertThatThrownBy(() -> SpanLimits.builder().setMaxNumberOfEvents(0)) - .isInstanceOf(IllegalArgumentException.class); assertThatThrownBy(() -> SpanLimits.builder().setMaxNumberOfEvents(-1)) .isInstanceOf(IllegalArgumentException.class); - assertThatThrownBy(() -> SpanLimits.builder().setMaxNumberOfLinks(0)) - .isInstanceOf(IllegalArgumentException.class); assertThatThrownBy(() -> SpanLimits.builder().setMaxNumberOfLinks(-1)) .isInstanceOf(IllegalArgumentException.class); - assertThatThrownBy(() -> SpanLimits.builder().setMaxNumberOfAttributesPerEvent(0)) - .isInstanceOf(IllegalArgumentException.class); assertThatThrownBy(() -> SpanLimits.builder().setMaxNumberOfAttributesPerEvent(-1)) .isInstanceOf(IllegalArgumentException.class); - assertThatThrownBy(() -> SpanLimits.builder().setMaxNumberOfAttributesPerLink(0)) - .isInstanceOf(IllegalArgumentException.class); assertThatThrownBy(() -> SpanLimits.builder().setMaxNumberOfAttributesPerLink(-1)) .isInstanceOf(IllegalArgumentException.class); assertThatThrownBy(() -> SpanLimits.builder().setMaxAttributeValueLength(-1)) .isInstanceOf(IllegalArgumentException.class); } + + @Test + void validSpanLimits() { + assertThatCode(() -> SpanLimits.builder().setMaxNumberOfAttributes(0)) + .doesNotThrowAnyException(); + assertThatCode(() -> SpanLimits.builder().setMaxNumberOfEvents(0)).doesNotThrowAnyException(); + assertThatCode(() -> SpanLimits.builder().setMaxNumberOfLinks(0)).doesNotThrowAnyException(); + assertThatCode(() -> SpanLimits.builder().setMaxNumberOfAttributesPerEvent(0)) + .doesNotThrowAnyException(); + assertThatCode(() -> SpanLimits.builder().setMaxNumberOfAttributesPerLink(0)) + .doesNotThrowAnyException(); + assertThatCode(() -> SpanLimits.builder().setMaxAttributeValueLength(0)) + .doesNotThrowAnyException(); + } } diff --git a/sdk/trace/src/test/java/io/opentelemetry/sdk/trace/export/BatchSpanProcessorTest.java b/sdk/trace/src/test/java/io/opentelemetry/sdk/trace/export/BatchSpanProcessorTest.java index d9f48ecab17..23b8874790c 100644 --- a/sdk/trace/src/test/java/io/opentelemetry/sdk/trace/export/BatchSpanProcessorTest.java +++ b/sdk/trace/src/test/java/io/opentelemetry/sdk/trace/export/BatchSpanProcessorTest.java @@ -121,6 +121,9 @@ void builderInvalidConfig() { assertThatThrownBy(() -> BatchSpanProcessor.builder(mockSpanExporter).setExporterTimeout(null)) .isInstanceOf(NullPointerException.class) .hasMessage("timeout"); + assertThatThrownBy(() -> BatchSpanProcessor.builder(mockSpanExporter).setMaxQueueSize(0)) + .isInstanceOf(IllegalArgumentException.class) + .hasMessage("maxQueueSize must be positive."); } @Test @@ -419,6 +422,7 @@ public void continuesIfExporterTimesOut() throws InterruptedException { .setExporterTimeout(exporterTimeoutMillis, TimeUnit.MILLISECONDS) .setScheduleDelay(1, TimeUnit.MILLISECONDS) .setMaxQueueSize(1) + .setMaxExportBatchSize(1) .build(); sdkTracerProvider = SdkTracerProvider.builder().addSpanProcessor(bsp).build(); From d7962af43e9184eaef2d5d8bf5b36a4ab3e7005f Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 29 Jan 2025 09:58:23 -0600 Subject: [PATCH 778/901] fix(deps): update dependency org.jetbrains.kotlin:kotlin-gradle-plugin to v2.1.10 (#7050) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- buildSrc/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts index 8e0082e2a7f..8250fd7f289 100644 --- a/buildSrc/build.gradle.kts +++ b/buildSrc/build.gradle.kts @@ -65,7 +65,7 @@ dependencies { implementation("me.champeau.jmh:jmh-gradle-plugin:0.7.2") implementation("net.ltgt.gradle:gradle-errorprone-plugin:4.1.0") implementation("net.ltgt.gradle:gradle-nullaway-plugin:2.2.0") - implementation("org.jetbrains.kotlin:kotlin-gradle-plugin:2.1.0") + implementation("org.jetbrains.kotlin:kotlin-gradle-plugin:2.1.10") implementation("org.owasp:dependency-check-gradle:12.0.1") implementation("ru.vyarus:gradle-animalsniffer-plugin:2.0.0") } From f8836deff72bd26e3c47e254fa8a8ee9e0927a1c Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 29 Jan 2025 09:58:40 -0600 Subject: [PATCH 779/901] fix(deps): update dependency io.opentelemetry.semconv:opentelemetry-semconv-incubating to v1.30.0-alpha-rc.1 (#7049) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- dependencyManagement/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index 06c2b9a0be2..a3347c67717 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -71,7 +71,7 @@ val DEPENDENCIES = listOf( "io.github.netmikey.logunit:logunit-jul:2.0.0", "io.jaegertracing:jaeger-client:1.8.1", "io.opentelemetry.contrib:opentelemetry-aws-xray-propagator:1.39.0-alpha", - "io.opentelemetry.semconv:opentelemetry-semconv-incubating:1.29.0-alpha", + "io.opentelemetry.semconv:opentelemetry-semconv-incubating:1.30.0-alpha-rc.1", "io.opentelemetry.proto:opentelemetry-proto:1.5.0-alpha", "io.opentracing:opentracing-api:0.33.0", "io.opentracing:opentracing-noop:0.33.0", From df425b684a3b76049ae5c97f30ec1423ed705582 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 29 Jan 2025 09:58:59 -0600 Subject: [PATCH 780/901] fix(deps): update dependency com.google.api.grpc:proto-google-common-protos to v2.51.0 (#7048) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- dependencyManagement/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index a3347c67717..da8801802e2 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -60,7 +60,7 @@ val DEPENDENCIES = listOf( "io.prometheus:simpleclient_httpserver:${prometheusClientVersion}", "javax.annotation:javax.annotation-api:1.3.2", "com.github.stefanbirkner:system-rules:1.19.0", - "com.google.api.grpc:proto-google-common-protos:2.50.1", + "com.google.api.grpc:proto-google-common-protos:2.51.0", "com.google.code.findbugs:jsr305:3.0.2", "com.google.guava:guava-beta-checker:1.0", "com.sun.net.httpserver:http:20070405", From 05bf32c5df040acc48bcd877a5317e01c03c882d Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 29 Jan 2025 09:59:13 -0600 Subject: [PATCH 781/901] fix(deps): update dependency checkstyle to v10.21.2 (#7043) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- buildSrc/src/main/kotlin/otel.java-conventions.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/buildSrc/src/main/kotlin/otel.java-conventions.gradle.kts b/buildSrc/src/main/kotlin/otel.java-conventions.gradle.kts index ff17e6dcaa2..4d2315b9bdd 100644 --- a/buildSrc/src/main/kotlin/otel.java-conventions.gradle.kts +++ b/buildSrc/src/main/kotlin/otel.java-conventions.gradle.kts @@ -42,7 +42,7 @@ java { checkstyle { configDirectory.set(file("$rootDir/buildscripts/")) - toolVersion = "10.21.1" + toolVersion = "10.21.2" isIgnoreFailures = false configProperties["rootDir"] = rootDir } From 8e31bf4f283e77b711f31e52fe7959fd3b8df648 Mon Sep 17 00:00:00 2001 From: jackshirazi Date: Wed, 29 Jan 2025 15:59:41 +0000 Subject: [PATCH 782/901] add SdkTracerProvider.setScopeConfigurator() and support (#7021) Co-authored-by: Jack Berg --- .../sdk/trace/ExtendedSdkTracer.java | 4 - .../io/opentelemetry/sdk/trace/SdkTracer.java | 16 +++- .../sdk/trace/SdkTracerProvider.java | 24 +++++- .../trace/internal/SdkTracerProviderUtil.java | 16 ++++ .../sdk/trace/SdkTracerProviderTest.java | 32 ++++++++ .../sdk/trace/SdkTracerTest.java | 9 +++ .../sdk/trace/TracerConfigTest.java | 77 +++++++++++++++++-- 7 files changed, 161 insertions(+), 17 deletions(-) diff --git a/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/ExtendedSdkTracer.java b/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/ExtendedSdkTracer.java index 25de43faf88..0c1d1c8e8b9 100644 --- a/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/ExtendedSdkTracer.java +++ b/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/ExtendedSdkTracer.java @@ -12,16 +12,12 @@ /** {@link ExtendedSdkTracer} is SDK implementation of {@link ExtendedTracer}. */ final class ExtendedSdkTracer extends SdkTracer implements ExtendedTracer { - // TODO: add dedicated API for updating scope config. - @SuppressWarnings("FieldCanBeFinal") // For now, allow updating reflectively. - private boolean tracerEnabled; ExtendedSdkTracer( TracerSharedState sharedState, InstrumentationScopeInfo instrumentationScopeInfo, TracerConfig tracerConfig) { super(sharedState, instrumentationScopeInfo, tracerConfig); - this.tracerEnabled = tracerConfig.isEnabled(); } @Override diff --git a/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/SdkTracer.java b/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/SdkTracer.java index 0238d897907..b148d0cf8c6 100644 --- a/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/SdkTracer.java +++ b/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/SdkTracer.java @@ -30,10 +30,9 @@ class SdkTracer implements Tracer { private final TracerSharedState sharedState; private final InstrumentationScopeInfo instrumentationScopeInfo; - - // TODO: add dedicated API for updating scope config. - @SuppressWarnings("FieldCanBeFinal") // For now, allow updating reflectively. - private boolean tracerEnabled; + // deliberately not volatile because of performance concerns + // - which means its eventually consistent + protected boolean tracerEnabled; SdkTracer( TracerSharedState sharedState, @@ -79,4 +78,13 @@ public SpanBuilder spanBuilder(String spanName) { InstrumentationScopeInfo getInstrumentationScopeInfo() { return instrumentationScopeInfo; } + + // Visible for testing + boolean isEnabled() { + return tracerEnabled; + } + + void updateTracerConfig(TracerConfig tracerConfig) { + this.tracerEnabled = tracerConfig.isEnabled(); + } } diff --git a/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/SdkTracerProvider.java b/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/SdkTracerProvider.java index 14ccc37c41f..7bd69a24236 100644 --- a/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/SdkTracerProvider.java +++ b/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/SdkTracerProvider.java @@ -14,6 +14,7 @@ import io.opentelemetry.sdk.internal.ComponentRegistry; import io.opentelemetry.sdk.internal.ScopeConfigurator; import io.opentelemetry.sdk.resources.Resource; +import io.opentelemetry.sdk.trace.internal.SdkTracerProviderUtil; import io.opentelemetry.sdk.trace.internal.TracerConfig; import io.opentelemetry.sdk.trace.samplers.Sampler; import java.io.Closeable; @@ -30,7 +31,9 @@ public final class SdkTracerProvider implements TracerProvider, Closeable { static final String DEFAULT_TRACER_NAME = ""; private final TracerSharedState sharedState; private final ComponentRegistry tracerSdkComponentRegistry; - private final ScopeConfigurator tracerConfigurator; + // deliberately not volatile because of performance concerns + // - which means its eventually consistent + private ScopeConfigurator tracerConfigurator; /** * Returns a new {@link SdkTracerProviderBuilder} for {@link SdkTracerProvider}. @@ -100,6 +103,25 @@ public Sampler getSampler() { return sharedState.getSampler(); } + /** + * Updates the tracer configurator, which computes {@link TracerConfig} for each {@link + * InstrumentationScopeInfo}. + * + *

      This method is experimental so not public. You may reflectively call it using {@link + * SdkTracerProviderUtil#setTracerConfigurator(SdkTracerProvider, ScopeConfigurator)}. + * + * @see TracerConfig#configuratorBuilder() + */ + void setTracerConfigurator(ScopeConfigurator tracerConfigurator) { + this.tracerConfigurator = tracerConfigurator; + this.tracerSdkComponentRegistry + .getComponents() + .forEach( + sdkTracer -> + sdkTracer.updateTracerConfig( + getTracerConfig(sdkTracer.getInstrumentationScopeInfo()))); + } + /** * Attempts to stop all the activity for {@link Tracer}s created by this provider. Calls {@link * SpanProcessor#shutdown()} for all registered {@link SpanProcessor}s. diff --git a/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/internal/SdkTracerProviderUtil.java b/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/internal/SdkTracerProviderUtil.java index 76111258a67..753a312fa1f 100644 --- a/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/internal/SdkTracerProviderUtil.java +++ b/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/internal/SdkTracerProviderUtil.java @@ -7,6 +7,7 @@ import io.opentelemetry.sdk.common.InstrumentationScopeInfo; import io.opentelemetry.sdk.internal.ScopeConfigurator; +import io.opentelemetry.sdk.trace.SdkTracerProvider; import io.opentelemetry.sdk.trace.SdkTracerProviderBuilder; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; @@ -24,6 +25,21 @@ public final class SdkTracerProviderUtil { private SdkTracerProviderUtil() {} + /** Reflectively set the {@link ScopeConfigurator} to the {@link SdkTracerProvider}. */ + public static void setTracerConfigurator( + SdkTracerProvider sdkTracerProvider, ScopeConfigurator scopeConfigurator) { + try { + Method method = + SdkTracerProvider.class.getDeclaredMethod( + "setTracerConfigurator", ScopeConfigurator.class); + method.setAccessible(true); + method.invoke(sdkTracerProvider, scopeConfigurator); + } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) { + throw new IllegalStateException( + "Error calling setTracerConfigurator on SdkTracerProvider", e); + } + } + /** Reflectively set the {@link ScopeConfigurator} to the {@link SdkTracerProviderBuilder}. */ public static void setTracerConfigurator( SdkTracerProviderBuilder sdkTracerProviderBuilder, diff --git a/sdk/trace/src/test/java/io/opentelemetry/sdk/trace/SdkTracerProviderTest.java b/sdk/trace/src/test/java/io/opentelemetry/sdk/trace/SdkTracerProviderTest.java index 44f75373cb1..61b64b4ebdf 100644 --- a/sdk/trace/src/test/java/io/opentelemetry/sdk/trace/SdkTracerProviderTest.java +++ b/sdk/trace/src/test/java/io/opentelemetry/sdk/trace/SdkTracerProviderTest.java @@ -18,7 +18,10 @@ import io.opentelemetry.sdk.common.Clock; import io.opentelemetry.sdk.common.CompletableResultCode; import io.opentelemetry.sdk.common.InstrumentationScopeInfo; +import io.opentelemetry.sdk.internal.ScopeConfigurator; import io.opentelemetry.sdk.resources.Resource; +import io.opentelemetry.sdk.trace.internal.SdkTracerProviderUtil; +import io.opentelemetry.sdk.trace.internal.TracerConfig; import io.opentelemetry.sdk.trace.samplers.Sampler; import java.util.function.Supplier; import org.junit.jupiter.api.BeforeEach; @@ -184,6 +187,35 @@ void propagatesInstrumentationScopeInfoToTracer() { assertThat(((SdkTracer) tracer).getInstrumentationScopeInfo()).isEqualTo(expected); } + @Test + void propagatesEnablementToTracerDirectly() { + propagatesEnablementToTracer(true); + } + + @Test + void propagatesEnablementToTracerByUtil() { + propagatesEnablementToTracer(false); + } + + void propagatesEnablementToTracer(boolean directly) { + SdkTracer tracer = (SdkTracer) tracerFactory.get("test"); + boolean isEnabled = tracer.isEnabled(); + ScopeConfigurator flipConfigurator = + new ScopeConfigurator() { + @Override + public TracerConfig apply(InstrumentationScopeInfo scopeInfo) { + return isEnabled ? TracerConfig.disabled() : TracerConfig.enabled(); + } + }; + // all in the same thread, so should see enablement change immediately + if (directly) { + tracerFactory.setTracerConfigurator(flipConfigurator); + } else { + SdkTracerProviderUtil.setTracerConfigurator(tracerFactory, flipConfigurator); + } + assertThat(tracer.isEnabled()).isEqualTo(!isEnabled); + } + @Test void build_SpanLimits() { SpanLimits initialSpanLimits = SpanLimits.builder().build(); diff --git a/sdk/trace/src/test/java/io/opentelemetry/sdk/trace/SdkTracerTest.java b/sdk/trace/src/test/java/io/opentelemetry/sdk/trace/SdkTracerTest.java index c17c121a36e..0ca18de5f15 100644 --- a/sdk/trace/src/test/java/io/opentelemetry/sdk/trace/SdkTracerTest.java +++ b/sdk/trace/src/test/java/io/opentelemetry/sdk/trace/SdkTracerTest.java @@ -16,6 +16,7 @@ import io.opentelemetry.sdk.trace.data.SpanData; import io.opentelemetry.sdk.trace.export.BatchSpanProcessor; import io.opentelemetry.sdk.trace.export.SpanExporter; +import io.opentelemetry.sdk.trace.internal.TracerConfig; import java.util.Collection; import java.util.concurrent.atomic.AtomicLong; import org.junit.jupiter.api.Test; @@ -50,6 +51,14 @@ void getInstrumentationScopeInfo() { assertThat(tracer.getInstrumentationScopeInfo()).isEqualTo(instrumentationScopeInfo); } + @Test + void updateEnabled() { + tracer.updateTracerConfig(TracerConfig.disabled()); + assertThat(tracer.isEnabled()).isFalse(); + tracer.updateTracerConfig(TracerConfig.enabled()); + assertThat(tracer.isEnabled()).isTrue(); + } + @Test void propagatesInstrumentationScopeInfoToSpan() { ReadableSpan readableSpan = (ReadableSpan) tracer.spanBuilder("spanName").startSpan(); diff --git a/sdk/trace/src/testIncubating/java/io/opentelemetry/sdk/trace/TracerConfigTest.java b/sdk/trace/src/testIncubating/java/io/opentelemetry/sdk/trace/TracerConfigTest.java index 4421185aeea..28a233c26e8 100644 --- a/sdk/trace/src/testIncubating/java/io/opentelemetry/sdk/trace/TracerConfigTest.java +++ b/sdk/trace/src/testIncubating/java/io/opentelemetry/sdk/trace/TracerConfigTest.java @@ -13,10 +13,8 @@ import static io.opentelemetry.sdk.trace.internal.TracerConfig.enabled; import io.opentelemetry.api.common.Attributes; -import io.opentelemetry.api.incubator.trace.ExtendedTracer; import io.opentelemetry.api.trace.Span; import io.opentelemetry.api.trace.SpanId; -import io.opentelemetry.api.trace.Tracer; import io.opentelemetry.context.Scope; import io.opentelemetry.sdk.common.InstrumentationScopeInfo; import io.opentelemetry.sdk.internal.ScopeConfigurator; @@ -42,9 +40,9 @@ void disableScopes() throws InterruptedException { .addSpanProcessor(SimpleSpanProcessor.create(exporter)) .build(); - Tracer tracerA = tracerProvider.get("tracerA"); - Tracer tracerB = tracerProvider.get("tracerB"); - Tracer tracerC = tracerProvider.get("tracerC"); + ExtendedSdkTracer tracerA = (ExtendedSdkTracer) tracerProvider.get("tracerA"); + ExtendedSdkTracer tracerB = (ExtendedSdkTracer) tracerProvider.get("tracerB"); + ExtendedSdkTracer tracerC = (ExtendedSdkTracer) tracerProvider.get("tracerC"); Span parent; Span child; @@ -92,9 +90,9 @@ void disableScopes() throws InterruptedException { .hasParentSpanId(parent.getSpanContext().getSpanId()) .hasAttributes(Attributes.builder().put("c", "1").build())); // tracerA and tracerC are enabled, tracerB is disabled. - assertThat(((ExtendedTracer) tracerA).isEnabled()).isTrue(); - assertThat(((ExtendedTracer) tracerB).isEnabled()).isFalse(); - assertThat(((ExtendedTracer) tracerA).isEnabled()).isTrue(); + assertThat(tracerA.isEnabled()).isTrue(); + assertThat(tracerB.isEnabled()).isFalse(); + assertThat(tracerC.isEnabled()).isTrue(); } @ParameterizedTest @@ -158,4 +156,67 @@ private static Stream tracerConfiguratorArgs() { Arguments.of(enableStartsWithD, scopeDog, enabled()), Arguments.of(enableStartsWithD, scopeDuck, enabled())); } + + @Test + void setScopeConfigurator() { + // 1. Initially, configure all tracers to be enabled except tracerB + InMemorySpanExporter exporter = InMemorySpanExporter.create(); + SdkTracerProvider tracerProvider = + SdkTracerProvider.builder() + .addTracerConfiguratorCondition(nameEquals("tracerB"), disabled()) + .addSpanProcessor(SimpleSpanProcessor.create(exporter)) + .build(); + + ExtendedSdkTracer tracerA = (ExtendedSdkTracer) tracerProvider.get("tracerA"); + ExtendedSdkTracer tracerB = (ExtendedSdkTracer) tracerProvider.get("tracerB"); + ExtendedSdkTracer tracerC = (ExtendedSdkTracer) tracerProvider.get("tracerC"); + + // verify isEnabled() + assertThat(tracerA.isEnabled()).isTrue(); + assertThat(tracerB.isEnabled()).isFalse(); + assertThat(tracerC.isEnabled()).isTrue(); + + // verify spans are emitted as expected + tracerA.spanBuilder("spanA").startSpan().end(); + tracerB.spanBuilder("spanB").startSpan().end(); + tracerC.spanBuilder("spanC").startSpan().end(); + assertThat(exporter.getFinishedSpanItems()) + .satisfiesExactlyInAnyOrder( + span -> assertThat(span).hasName("spanA"), span -> assertThat(span).hasName("spanC")); + exporter.reset(); + + // 2. Update config to disable all tracers + tracerProvider.setTracerConfigurator( + ScopeConfigurator.builder().setDefault(TracerConfig.disabled()).build()); + + // verify isEnabled() + assertThat(tracerA.isEnabled()).isFalse(); + assertThat(tracerB.isEnabled()).isFalse(); + assertThat(tracerC.isEnabled()).isFalse(); + + // verify spans are emitted as expected + tracerA.spanBuilder("spanA").startSpan().end(); + tracerB.spanBuilder("spanB").startSpan().end(); + tracerC.spanBuilder("spanC").startSpan().end(); + assertThat(exporter.getFinishedSpanItems()).isEmpty(); + + // 3. Update config to restore original + tracerProvider.setTracerConfigurator( + ScopeConfigurator.builder() + .addCondition(nameEquals("tracerB"), disabled()) + .build()); + + // verify isEnabled() + assertThat(tracerA.isEnabled()).isTrue(); + assertThat(tracerB.isEnabled()).isFalse(); + assertThat(tracerC.isEnabled()).isTrue(); + + // verify spans are emitted as expected + tracerA.spanBuilder("spanA").startSpan().end(); + tracerB.spanBuilder("spanB").startSpan().end(); + tracerC.spanBuilder("spanC").startSpan().end(); + assertThat(exporter.getFinishedSpanItems()) + .satisfiesExactly( + span -> assertThat(span).hasName("spanA"), span -> assertThat(span).hasName("spanC")); + } } From bf71be17d42904398ed0a0e6fc5524b1cd47d4eb Mon Sep 17 00:00:00 2001 From: jack-berg <34418638+jack-berg@users.noreply.github.com> Date: Thu, 30 Jan 2025 15:39:47 -0600 Subject: [PATCH 783/901] Drop event API / SDK (#7053) --- api/incubator/README.md | 8 - .../incubator/events/DefaultEventLogger.java | 67 -------- .../events/DefaultEventLoggerProvider.java | 41 ----- .../api/incubator/events/EventBuilder.java | 153 ------------------ .../api/incubator/events/EventLogger.java | 44 ----- .../incubator/events/EventLoggerBuilder.java | 41 ----- .../incubator/events/EventLoggerProvider.java | 45 ------ .../events/GlobalEventLoggerProvider.java | 60 ------- .../DefaultEventLoggerProviderTest.java | 39 ----- .../events/DefaultEventLoggerTest.java | 70 -------- .../incubator/events/EventApiUsageTest.java | 81 ---------- .../events/GlobalEventLoggerProviderTest.java | 51 ------ .../otlp/LogsRequestMarshalerBenchmark.java | 35 ++-- .../OtlpExporterIntegrationTest.java | 32 +--- sdk-extensions/autoconfigure/build.gradle.kts | 7 - ...AutoConfiguredOpenTelemetrySdkBuilder.java | 16 -- .../sdk/autoconfigure/IncubatingUtil.java | 24 --- .../AutoConfiguredOpenTelemetrySdkTest.java | 2 - .../autoconfigure/FileConfigurationTest.java | 9 -- .../sdk/autoconfigure/FullConfigTest.java | 16 +- ...onfigureGlobalEventLoggerProviderTest.java | 62 ------- .../sdk/logs/internal/SdkEventBuilder.java | 87 ---------- .../logs/internal/SdkEventLoggerProvider.java | 115 ------------- .../logs/internal/SdkEventBuilderTest.java | 55 ------- .../internal/SdkEventLoggerProviderTest.java | 137 ---------------- .../testing/assertj/LogAssertionsTest.java | 64 +++----- 26 files changed, 53 insertions(+), 1308 deletions(-) delete mode 100644 api/incubator/src/main/java/io/opentelemetry/api/incubator/events/DefaultEventLogger.java delete mode 100644 api/incubator/src/main/java/io/opentelemetry/api/incubator/events/DefaultEventLoggerProvider.java delete mode 100644 api/incubator/src/main/java/io/opentelemetry/api/incubator/events/EventBuilder.java delete mode 100644 api/incubator/src/main/java/io/opentelemetry/api/incubator/events/EventLogger.java delete mode 100644 api/incubator/src/main/java/io/opentelemetry/api/incubator/events/EventLoggerBuilder.java delete mode 100644 api/incubator/src/main/java/io/opentelemetry/api/incubator/events/EventLoggerProvider.java delete mode 100644 api/incubator/src/main/java/io/opentelemetry/api/incubator/events/GlobalEventLoggerProvider.java delete mode 100644 api/incubator/src/test/java/io/opentelemetry/api/incubator/events/DefaultEventLoggerProviderTest.java delete mode 100644 api/incubator/src/test/java/io/opentelemetry/api/incubator/events/DefaultEventLoggerTest.java delete mode 100644 api/incubator/src/test/java/io/opentelemetry/api/incubator/events/EventApiUsageTest.java delete mode 100644 api/incubator/src/test/java/io/opentelemetry/api/incubator/events/GlobalEventLoggerProviderTest.java delete mode 100644 sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/IncubatingUtil.java delete mode 100644 sdk-extensions/autoconfigure/src/testIncubating/java/io/opentelemetry/sdk/autoconfigure/AutoconfigureGlobalEventLoggerProviderTest.java delete mode 100644 sdk/logs/src/main/java/io/opentelemetry/sdk/logs/internal/SdkEventBuilder.java delete mode 100644 sdk/logs/src/main/java/io/opentelemetry/sdk/logs/internal/SdkEventLoggerProvider.java delete mode 100644 sdk/logs/src/testIncubating/java/io/opentelemetry/sdk/logs/internal/SdkEventBuilderTest.java delete mode 100644 sdk/logs/src/testIncubating/java/io/opentelemetry/sdk/logs/internal/SdkEventLoggerProviderTest.java diff --git a/api/incubator/README.md b/api/incubator/README.md index ee29241f9fe..e0b0ec7a080 100644 --- a/api/incubator/README.md +++ b/api/incubator/README.md @@ -2,14 +2,6 @@ Experimental APIs, including Event API, extended Log Bridge APIs, extended Metrics APIs, extended ContextPropagator APIs, and extended Trace APIs. -## Event API - -Features: - -* Event API for producing log records according to [Event Semantic Conventions](https://opentelemetry.io/docs/specs/semconv/general/events/). - -See [EventApiUsageTest](./src/test/java/io/opentelemetry/api/incubator/events/EventApiUsageTest.java). - ## Extended Log Bridge API Features: diff --git a/api/incubator/src/main/java/io/opentelemetry/api/incubator/events/DefaultEventLogger.java b/api/incubator/src/main/java/io/opentelemetry/api/incubator/events/DefaultEventLogger.java deleted file mode 100644 index c0c795c584b..00000000000 --- a/api/incubator/src/main/java/io/opentelemetry/api/incubator/events/DefaultEventLogger.java +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package io.opentelemetry.api.incubator.events; - -import io.opentelemetry.api.common.Attributes; -import io.opentelemetry.api.common.Value; -import io.opentelemetry.api.logs.Severity; -import io.opentelemetry.context.Context; -import java.time.Instant; -import java.util.concurrent.TimeUnit; - -class DefaultEventLogger implements EventLogger { - - private static final EventLogger INSTANCE = new DefaultEventLogger(); - - private DefaultEventLogger() {} - - static EventLogger getInstance() { - return INSTANCE; - } - - @Override - public EventBuilder builder(String eventName) { - return NoOpEventBuilder.INSTANCE; - } - - private static class NoOpEventBuilder implements EventBuilder { - - public static final EventBuilder INSTANCE = new NoOpEventBuilder(); - - @Override - public EventBuilder put(String key, Value value) { - return this; - } - - @Override - public EventBuilder setTimestamp(long timestamp, TimeUnit unit) { - return this; - } - - @Override - public EventBuilder setTimestamp(Instant instant) { - return this; - } - - @Override - public EventBuilder setContext(Context context) { - return this; - } - - @Override - public EventBuilder setSeverity(Severity severity) { - return this; - } - - @Override - public EventBuilder setAttributes(Attributes attributes) { - return this; - } - - @Override - public void emit() {} - } -} diff --git a/api/incubator/src/main/java/io/opentelemetry/api/incubator/events/DefaultEventLoggerProvider.java b/api/incubator/src/main/java/io/opentelemetry/api/incubator/events/DefaultEventLoggerProvider.java deleted file mode 100644 index d365e2bbd4d..00000000000 --- a/api/incubator/src/main/java/io/opentelemetry/api/incubator/events/DefaultEventLoggerProvider.java +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package io.opentelemetry.api.incubator.events; - -class DefaultEventLoggerProvider implements EventLoggerProvider { - - private static final EventLoggerProvider INSTANCE = new DefaultEventLoggerProvider(); - private static final EventLoggerBuilder NOOP_EVENT_LOGGER_BUILDER = new NoopEventLoggerBuilder(); - - private DefaultEventLoggerProvider() {} - - static EventLoggerProvider getInstance() { - return INSTANCE; - } - - @Override - public EventLoggerBuilder eventLoggerBuilder(String instrumentationScopeName) { - return NOOP_EVENT_LOGGER_BUILDER; - } - - private static class NoopEventLoggerBuilder implements EventLoggerBuilder { - - @Override - public EventLoggerBuilder setSchemaUrl(String schemaUrl) { - return this; - } - - @Override - public EventLoggerBuilder setInstrumentationVersion(String instrumentationVersion) { - return this; - } - - @Override - public EventLogger build() { - return DefaultEventLogger.getInstance(); - } - } -} diff --git a/api/incubator/src/main/java/io/opentelemetry/api/incubator/events/EventBuilder.java b/api/incubator/src/main/java/io/opentelemetry/api/incubator/events/EventBuilder.java deleted file mode 100644 index a2c43a47a0e..00000000000 --- a/api/incubator/src/main/java/io/opentelemetry/api/incubator/events/EventBuilder.java +++ /dev/null @@ -1,153 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package io.opentelemetry.api.incubator.events; - -import static java.util.stream.Collectors.toList; - -import io.opentelemetry.api.common.AttributeKey; -import io.opentelemetry.api.common.Attributes; -import io.opentelemetry.api.common.Value; -import io.opentelemetry.api.logs.Severity; -import io.opentelemetry.context.Context; -import java.time.Instant; -import java.util.ArrayList; -import java.util.List; -import java.util.concurrent.TimeUnit; - -/** The EventBuilder is used to {@link #emit()} events. */ -public interface EventBuilder { - - /** Put the given {@code key} and {@code value} in the payload. */ - default EventBuilder put(String key, String value) { - return put(key, Value.of(value)); - } - - /** Put the given {@code key} and {@code value} in the payload. */ - default EventBuilder put(String key, long value) { - return put(key, Value.of(value)); - } - - /** Put the given {@code key} and {@code value} in the payload. */ - default EventBuilder put(String key, double value) { - return put(key, Value.of(value)); - } - - /** Put the given {@code key} and {@code value} in the payload. */ - default EventBuilder put(String key, boolean value) { - return put(key, Value.of(value)); - } - - /** Put the given {@code key} and {@code value} in the payload. */ - default EventBuilder put(String key, String... value) { - List> values = new ArrayList<>(value.length); - for (String val : value) { - values.add(Value.of(val)); - } - return put(key, Value.of(values)); - } - - /** Put the given {@code key} and {@code value} in the payload. */ - default EventBuilder put(String key, long... value) { - List> values = new ArrayList<>(value.length); - for (long val : value) { - values.add(Value.of(val)); - } - return put(key, Value.of(values)); - } - - /** Put the given {@code key} and {@code value} in the payload. */ - default EventBuilder put(String key, double... value) { - List> values = new ArrayList<>(value.length); - for (double val : value) { - values.add(Value.of(val)); - } - return put(key, Value.of(values)); - } - - /** Put the given {@code key} and {@code value} in the payload. */ - default EventBuilder put(String key, boolean... value) { - List> values = new ArrayList<>(value.length); - for (boolean val : value) { - values.add(Value.of(val)); - } - return put(key, Value.of(values)); - } - - /** - * Put the given key and value in the payload. - * - *

      NOTE: The key value pair is NOT added to the event attributes. Setting event attributes is - * less common than adding entries to the event payload. Use {@link #setAttributes(Attributes)} if - * intending the data to be set in attributes instead of the payload. - */ - @SuppressWarnings("unchecked") - default EventBuilder put(AttributeKey key, T value) { - switch (key.getType()) { - case STRING: - return put(key.getKey(), (String) value); - case BOOLEAN: - return put(key.getKey(), (boolean) value); - case LONG: - return put(key.getKey(), (long) value); - case DOUBLE: - return put(key.getKey(), (double) value); - case STRING_ARRAY: - return put( - key.getKey(), - Value.of(((List) value).stream().map(Value::of).collect(toList()))); - case BOOLEAN_ARRAY: - return put( - key.getKey(), - Value.of(((List) value).stream().map(Value::of).collect(toList()))); - case LONG_ARRAY: - return put( - key.getKey(), Value.of(((List) value).stream().map(Value::of).collect(toList()))); - case DOUBLE_ARRAY: - return put( - key.getKey(), - Value.of(((List) value).stream().map(Value::of).collect(toList()))); - } - return this; - } - - /** Put the given {@code key} and {@code value} in the payload. */ - EventBuilder put(String key, Value value); - - /** - * Set the epoch {@code timestamp}, using the timestamp and unit. - * - *

      The {@code timestamp} is the time at which the event occurred. If unset, it will be set to - * the current time when {@link #emit()} is called. - */ - EventBuilder setTimestamp(long timestamp, TimeUnit unit); - - /** - * Set the epoch {@code timestamp}, using the instant. - * - *

      The {@code timestamp} is the time at which the event occurred. If unset, it will be set to - * the current time when {@link #emit()} is called. - */ - EventBuilder setTimestamp(Instant instant); - - /** Set the context. */ - EventBuilder setContext(Context context); - - /** Set the severity. */ - EventBuilder setSeverity(Severity severity); - - /** - * Set the attributes. - * - *

      Event {@link io.opentelemetry.api.common.Attributes} provide additional details about the - * Event which are not part of the well-defined {@link Value} payload. Setting event attributes is - * less common than adding entries to the event payload. Most users will want to call one of the - * {@code #put(String, ?)} methods instead. - */ - EventBuilder setAttributes(Attributes attributes); - - /** Emit an event. */ - void emit(); -} diff --git a/api/incubator/src/main/java/io/opentelemetry/api/incubator/events/EventLogger.java b/api/incubator/src/main/java/io/opentelemetry/api/incubator/events/EventLogger.java deleted file mode 100644 index 3d273a30c7a..00000000000 --- a/api/incubator/src/main/java/io/opentelemetry/api/incubator/events/EventLogger.java +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package io.opentelemetry.api.incubator.events; - -import javax.annotation.concurrent.ThreadSafe; - -/** - * A {@link EventLogger} is the entry point into an event pipeline. - * - *

      Example usage emitting events: - * - *

      {@code
      - * class MyClass {
      - *   private final EventLogger eventLogger = eventLoggerProvider
      - *         .eventLoggerBuilder("scope-name")
      - *         .build();
      - *
      - *   void doWork() {
      - *     eventLogger.builder("my-namespace.my-event")
      - *         .put("key1", "value1")
      - *         .put("key2", "value2")
      - *         .emit();
      - *     // do work
      - *   }
      - * }
      - * }
      - */ -@ThreadSafe -public interface EventLogger { - - /** - * Return a {@link EventBuilder} to emit an event. - * - * @param eventName the event name, which identifies the class or type of event. Event with the - * same name are structurally similar to one another. Event names are subject to the same - * naming rules as attribute names. Notably, they are namespaced to avoid collisions. See
      event.name semantic - * conventions for more details. - */ - EventBuilder builder(String eventName); -} diff --git a/api/incubator/src/main/java/io/opentelemetry/api/incubator/events/EventLoggerBuilder.java b/api/incubator/src/main/java/io/opentelemetry/api/incubator/events/EventLoggerBuilder.java deleted file mode 100644 index d3105cac6c7..00000000000 --- a/api/incubator/src/main/java/io/opentelemetry/api/incubator/events/EventLoggerBuilder.java +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package io.opentelemetry.api.incubator.events; - -/** - * Builder class for creating {@link EventLogger} instances. - * - *

      {@link EventLogger}s are identified by their scope name, version, and schema URL. These - * identifying fields, along with attributes, combine to form the instrumentation scope, which is - * attached to all events produced by the {@link EventLogger}. - */ -public interface EventLoggerBuilder { - - /** - * Set the scope schema URL of the resulting {@link EventLogger}. Schema URL is part of {@link - * EventLogger} identity. - * - * @param schemaUrl The schema URL. - * @return this - */ - EventLoggerBuilder setSchemaUrl(String schemaUrl); - - /** - * Sets the instrumentation scope version of the resulting {@link EventLogger}. Version is part of - * {@link EventLogger} identity. - * - * @param instrumentationScopeVersion The instrumentation scope version. - * @return this - */ - EventLoggerBuilder setInstrumentationVersion(String instrumentationScopeVersion); - - /** - * Gets or creates a {@link EventLogger} instance. - * - * @return a {@link EventLogger} instance configured with the provided options. - */ - EventLogger build(); -} diff --git a/api/incubator/src/main/java/io/opentelemetry/api/incubator/events/EventLoggerProvider.java b/api/incubator/src/main/java/io/opentelemetry/api/incubator/events/EventLoggerProvider.java deleted file mode 100644 index cfef2a0622d..00000000000 --- a/api/incubator/src/main/java/io/opentelemetry/api/incubator/events/EventLoggerProvider.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package io.opentelemetry.api.incubator.events; - -import javax.annotation.concurrent.ThreadSafe; - -/** - * A registry for creating scoped {@link EventLogger}s. The name Provider is for consistency - * with other languages and it is NOT loaded using reflection. - * - * @see EventLogger - */ -@ThreadSafe -public interface EventLoggerProvider { - - /** - * Gets or creates a named {@link EventLogger} instance. - * - * @param instrumentationScopeName A name uniquely identifying the instrumentation scope, such as - * the instrumentation library, package, or fully qualified class name. Must not be null. - * @return a Logger instance. - */ - default EventLogger get(String instrumentationScopeName) { - return eventLoggerBuilder(instrumentationScopeName).build(); - } - - /** - * Creates a LoggerBuilder for a named {@link EventLogger} instance. - * - * @param instrumentationScopeName A name uniquely identifying the instrumentation scope, such as - * the instrumentation library, package, or fully qualified class name. Must not be null. - * @return a LoggerBuilder instance. - */ - EventLoggerBuilder eventLoggerBuilder(String instrumentationScopeName); - - /** - * Returns a no-op {@link EventLoggerProvider} which provides Loggers which do not record or emit. - */ - static EventLoggerProvider noop() { - return DefaultEventLoggerProvider.getInstance(); - } -} diff --git a/api/incubator/src/main/java/io/opentelemetry/api/incubator/events/GlobalEventLoggerProvider.java b/api/incubator/src/main/java/io/opentelemetry/api/incubator/events/GlobalEventLoggerProvider.java deleted file mode 100644 index 68664f08b56..00000000000 --- a/api/incubator/src/main/java/io/opentelemetry/api/incubator/events/GlobalEventLoggerProvider.java +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package io.opentelemetry.api.incubator.events; - -import io.opentelemetry.api.GlobalOpenTelemetry; -import java.util.concurrent.atomic.AtomicReference; -import javax.annotation.Nullable; - -/** - * This class provides a temporary global accessor for {@link EventLoggerProvider} until the event - * API is marked stable. It will eventually be merged into {@link GlobalOpenTelemetry}. - */ -// We intentionally assign to be used for error reporting. -@SuppressWarnings("StaticAssignmentOfThrowable") -public final class GlobalEventLoggerProvider { - - private static final AtomicReference instance = - new AtomicReference<>(EventLoggerProvider.noop()); - - @SuppressWarnings("NonFinalStaticField") - @Nullable - private static volatile Throwable setInstanceCaller; - - private GlobalEventLoggerProvider() {} - - /** Returns the globally registered {@link EventLoggerProvider}. */ - // instance cannot be set to null - @SuppressWarnings("NullAway") - public static EventLoggerProvider get() { - return instance.get(); - } - - /** - * Sets the global {@link EventLoggerProvider}. Future calls to {@link #get()} will return the - * provided {@link EventLoggerProvider} instance. This should be called once as early as possible - * in your application initialization logic. - */ - public static void set(EventLoggerProvider eventLoggerProvider) { - boolean changed = instance.compareAndSet(EventLoggerProvider.noop(), eventLoggerProvider); - if (!changed && (eventLoggerProvider != EventLoggerProvider.noop())) { - throw new IllegalStateException( - "GlobalEventLoggerProvider.set has already been called. GlobalEventLoggerProvider.set " - + "must be called only once before any calls to GlobalEventLoggerProvider.get. " - + "Previous invocation set to cause of this exception.", - setInstanceCaller); - } - setInstanceCaller = new Throwable(); - } - - /** - * Unsets the global {@link EventLoggerProvider}. This is only meant to be used from tests which - * need to reconfigure {@link EventLoggerProvider}. - */ - public static void resetForTest() { - instance.set(EventLoggerProvider.noop()); - } -} diff --git a/api/incubator/src/test/java/io/opentelemetry/api/incubator/events/DefaultEventLoggerProviderTest.java b/api/incubator/src/test/java/io/opentelemetry/api/incubator/events/DefaultEventLoggerProviderTest.java deleted file mode 100644 index 196c0bc307a..00000000000 --- a/api/incubator/src/test/java/io/opentelemetry/api/incubator/events/DefaultEventLoggerProviderTest.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package io.opentelemetry.api.incubator.events; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatCode; - -import org.junit.jupiter.api.Test; - -class DefaultEventLoggerProviderTest { - - @Test - void noopEventLoggerProvider_doesNotThrow() { - EventLoggerProvider provider = EventLoggerProvider.noop(); - - assertThat(provider).isSameAs(DefaultEventLoggerProvider.getInstance()); - assertThatCode(() -> provider.get("scope-name")).doesNotThrowAnyException(); - assertThatCode( - () -> - provider - .eventLoggerBuilder("scope-name") - .setInstrumentationVersion("1.0") - .setSchemaUrl("http://schema.com") - .build()) - .doesNotThrowAnyException(); - - assertThatCode( - () -> - provider - .eventLoggerBuilder("scope-name") - .build() - .builder("namespace.event-name") - .emit()) - .doesNotThrowAnyException(); - } -} diff --git a/api/incubator/src/test/java/io/opentelemetry/api/incubator/events/DefaultEventLoggerTest.java b/api/incubator/src/test/java/io/opentelemetry/api/incubator/events/DefaultEventLoggerTest.java deleted file mode 100644 index ff525646ef6..00000000000 --- a/api/incubator/src/test/java/io/opentelemetry/api/incubator/events/DefaultEventLoggerTest.java +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package io.opentelemetry.api.incubator.events; - -import static org.assertj.core.api.Assertions.assertThatCode; - -import io.opentelemetry.api.common.AttributeKey; -import io.opentelemetry.api.common.Attributes; -import io.opentelemetry.api.common.Value; -import io.opentelemetry.api.logs.Severity; -import io.opentelemetry.context.Context; -import java.time.Instant; -import java.util.Arrays; -import java.util.HashMap; -import java.util.concurrent.TimeUnit; -import org.junit.jupiter.api.Test; - -class DefaultEventLoggerTest { - - @Test - @SuppressWarnings("DoubleBraceInitialization") - void builder() { - EventLogger eventLogger = DefaultEventLogger.getInstance(); - assertThatCode( - () -> - eventLogger - .builder("namespace.myEvent") - // Helper methods to set primitive types - .put("stringKey", "value") - .put("longKey", 1L) - .put("doubleKey", 1.0) - .put("boolKey", true) - // Helper methods to set primitive array types - .put("stringArrKey", "value1", "value2") - .put("longArrKey", 1L, 2L) - .put("doubleArrKey", 1.0, 2.0) - .put("boolArrKey", true, false) - // Set complex data - .put( - "valueKey", - Value.of( - new HashMap>() { - { - put("key", Value.of("value")); - } - })) - // Helper methods to set AttributeKey types - .put(AttributeKey.stringKey("attrStringKey"), "value") - .put(AttributeKey.longKey("attrLongKey"), 1L) - .put(AttributeKey.doubleKey("attrDoubleKey"), 1.0) - .put(AttributeKey.booleanKey("attrBoolKey"), true) - .put( - AttributeKey.stringArrayKey("attrStringArrKey"), - Arrays.asList("value1", "value2")) - .put(AttributeKey.longArrayKey("attrLongArrKey"), Arrays.asList(1L, 2L)) - .put(AttributeKey.doubleArrayKey("attrDoubleArrKey"), Arrays.asList(1.0, 2.0)) - .put(AttributeKey.booleanArrayKey("attrBoolArrKey"), Arrays.asList(true, false)) - // Other setters - .setTimestamp(123456L, TimeUnit.NANOSECONDS) - .setTimestamp(Instant.now()) - .setContext(Context.current()) - .setSeverity(Severity.DEBUG) - .setAttributes(Attributes.empty()) - .emit()) - .doesNotThrowAnyException(); - } -} diff --git a/api/incubator/src/test/java/io/opentelemetry/api/incubator/events/EventApiUsageTest.java b/api/incubator/src/test/java/io/opentelemetry/api/incubator/events/EventApiUsageTest.java deleted file mode 100644 index 3194978ed4f..00000000000 --- a/api/incubator/src/test/java/io/opentelemetry/api/incubator/events/EventApiUsageTest.java +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package io.opentelemetry.api.incubator.events; - -import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.assertThat; - -import com.google.common.collect.ImmutableMap; -import io.opentelemetry.api.common.Attributes; -import io.opentelemetry.api.common.Value; -import io.opentelemetry.sdk.logs.SdkLoggerProvider; -import io.opentelemetry.sdk.logs.export.SimpleLogRecordProcessor; -import io.opentelemetry.sdk.logs.internal.SdkEventLoggerProvider; -import io.opentelemetry.sdk.resources.Resource; -import io.opentelemetry.sdk.testing.exporter.InMemoryLogRecordExporter; -import java.util.concurrent.TimeUnit; -import org.junit.jupiter.api.Test; - -/** Demonstrating usage of Event API. */ -class EventApiUsageTest { - - @Test - void eventApiUsage() { - // Setup SdkEventLoggerProvider, which delegates to SdkLoggerProvider - InMemoryLogRecordExporter exporter = InMemoryLogRecordExporter.create(); - SdkLoggerProvider loggerProvider = - SdkLoggerProvider.builder() - // Default resource used for demonstration purposes - .setResource(Resource.getDefault()) - // Simple processor w/ in-memory exporter used for demonstration purposes - .addLogRecordProcessor(SimpleLogRecordProcessor.create(exporter)) - .build(); - EventLoggerProvider eventLoggerProvider = SdkEventLoggerProvider.create(loggerProvider); - - // Get an EventLogger for a scope - EventLogger eventLogger = eventLoggerProvider.get("org.foo.my-scope"); - - // Emit an event - eventLogger - .builder("org.foo.my-event") - // Add fields to the payload. The API has helpers for adding field values which are - // primitives or arrays of primitives, but you can also add a field with type Value, - // allowing for arbitrarily complex payloads. - .put("key1", "value1") - .put( - "key2", - Value.of( - ImmutableMap.of("childKey1", Value.of("value2"), "childKey2", Value.of("value3")))) - // Optionally set other fields, including timestamp, severity, context, and attributes - // (attributes provide additional details about the event which are not part of the well - // defined payload) - .emit(); - - // Events manifest as log records with an event.name attribute, and with the payload fields in - // the Value log record body - loggerProvider.forceFlush().join(10, TimeUnit.SECONDS); - assertThat(exporter.getFinishedLogRecordItems()) - .satisfiesExactly( - logData -> { - assertThat(logData) - .hasAttributes( - Attributes.builder().put("event.name", "org.foo.my-event").build()); - assertThat(logData.getBodyValue()) - .isNotNull() - .isEqualTo( - Value.of( - ImmutableMap.of( - "key1", - Value.of("value1"), - "key2", - Value.of( - ImmutableMap.of( - "childKey1", - Value.of("value2"), - "childKey2", - Value.of("value3")))))); - }); - } -} diff --git a/api/incubator/src/test/java/io/opentelemetry/api/incubator/events/GlobalEventLoggerProviderTest.java b/api/incubator/src/test/java/io/opentelemetry/api/incubator/events/GlobalEventLoggerProviderTest.java deleted file mode 100644 index d3392d59838..00000000000 --- a/api/incubator/src/test/java/io/opentelemetry/api/incubator/events/GlobalEventLoggerProviderTest.java +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package io.opentelemetry.api.incubator.events; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatThrownBy; - -import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.Test; - -class GlobalEventLoggerProviderTest { - - @BeforeAll - static void beforeClass() { - GlobalEventLoggerProvider.resetForTest(); - } - - @AfterEach - void after() { - GlobalEventLoggerProvider.resetForTest(); - } - - @Test - void setAndGet() { - assertThat(GlobalEventLoggerProvider.get()).isEqualTo(EventLoggerProvider.noop()); - EventLoggerProvider eventLoggerProvider = - instrumentationScopeName -> - EventLoggerProvider.noop().eventLoggerBuilder(instrumentationScopeName); - GlobalEventLoggerProvider.set(eventLoggerProvider); - assertThat(GlobalEventLoggerProvider.get()).isEqualTo(eventLoggerProvider); - } - - @Test - void setThenSet() { - GlobalEventLoggerProvider.set( - instrumentationScopeName -> - EventLoggerProvider.noop().eventLoggerBuilder(instrumentationScopeName)); - assertThatThrownBy( - () -> - GlobalEventLoggerProvider.set( - instrumentationScopeName -> - EventLoggerProvider.noop().eventLoggerBuilder(instrumentationScopeName))) - .isInstanceOf(IllegalStateException.class) - .hasMessageContaining("GlobalEventLoggerProvider.set has already been called") - .hasStackTraceContaining("setThenSet"); - } -} diff --git a/exporters/otlp/common/src/jmh/java/io/opentelemetry/exporter/internal/otlp/LogsRequestMarshalerBenchmark.java b/exporters/otlp/common/src/jmh/java/io/opentelemetry/exporter/internal/otlp/LogsRequestMarshalerBenchmark.java index 2d25476f42a..09bc21576c2 100644 --- a/exporters/otlp/common/src/jmh/java/io/opentelemetry/exporter/internal/otlp/LogsRequestMarshalerBenchmark.java +++ b/exporters/otlp/common/src/jmh/java/io/opentelemetry/exporter/internal/otlp/LogsRequestMarshalerBenchmark.java @@ -7,8 +7,9 @@ import io.opentelemetry.api.common.AttributeKey; import io.opentelemetry.api.common.Attributes; +import io.opentelemetry.api.common.KeyValue; import io.opentelemetry.api.common.Value; -import io.opentelemetry.api.incubator.events.EventLogger; +import io.opentelemetry.api.incubator.logs.ExtendedLogger; import io.opentelemetry.api.logs.Logger; import io.opentelemetry.api.logs.Severity; import io.opentelemetry.exporter.internal.otlp.logs.LogsRequestMarshaler; @@ -16,7 +17,6 @@ import io.opentelemetry.sdk.logs.SdkLoggerProvider; import io.opentelemetry.sdk.logs.data.LogRecordData; import io.opentelemetry.sdk.logs.export.SimpleLogRecordProcessor; -import io.opentelemetry.sdk.logs.internal.SdkEventLoggerProvider; import io.opentelemetry.sdk.resources.Resource; import io.opentelemetry.sdk.testing.exporter.InMemoryLogRecordExporter; import java.io.IOException; @@ -84,22 +84,21 @@ public class LogsRequestMarshalerBenchmark { .setSeverityText("INFO") .emit(); - SdkEventLoggerProvider eventLoggerProvider = SdkEventLoggerProvider.create(loggerProvider); - EventLogger eventLogger = eventLoggerProvider.get("event-logger"); - eventLogger - .builder("namespace.my-event-name") - // Helper methods to set primitive types - .put("stringKey", "value") - .put("longKey", 1L) - .put("doubleKey", 1.0) - .put("boolKey", true) - // Helper methods to set primitive array types - .put("stringArrKey", "value1", "value2") - .put("longArrKey", 1L, 2L) - .put("doubleArrKey", 1.0, 2.0) - .put("boolArrKey", true, false) - // Set complex data - .put("key", Value.of(Collections.singletonMap("childKey1", Value.of("value")))) + ((ExtendedLogger) logger1) + .logRecordBuilder() + .setEventName("namespace.my-event-name") + .setBody( + Value.of( + KeyValue.of("stringKey", Value.of("value")), + KeyValue.of("longKey", Value.of(1)), + KeyValue.of("doubleKey", Value.of(1.0)), + KeyValue.of("boolKey", Value.of(true)), + KeyValue.of("stringArrKey", Value.of(Value.of("value1"), Value.of("value2"))), + KeyValue.of("longArrKey", Value.of(Value.of(1), Value.of(2))), + KeyValue.of("doubleArrKey", Value.of(Value.of(1.0), Value.of(2.0))), + KeyValue.of("boolArrKey", Value.of(Value.of(true), Value.of(false))), + KeyValue.of( + "key", Value.of(Collections.singletonMap("childKey1", Value.of("value")))))) .emit(); LOGS = logRecordExporter.getFinishedLogRecordItems(); diff --git a/integration-tests/otlp/src/main/java/io/opentelemetry/integrationtest/OtlpExporterIntegrationTest.java b/integration-tests/otlp/src/main/java/io/opentelemetry/integrationtest/OtlpExporterIntegrationTest.java index 578bb57eca5..83121892006 100644 --- a/integration-tests/otlp/src/main/java/io/opentelemetry/integrationtest/OtlpExporterIntegrationTest.java +++ b/integration-tests/otlp/src/main/java/io/opentelemetry/integrationtest/OtlpExporterIntegrationTest.java @@ -22,7 +22,6 @@ import io.opentelemetry.api.common.AttributeKey; import io.opentelemetry.api.common.Attributes; import io.opentelemetry.api.common.KeyValue; -import io.opentelemetry.api.incubator.events.EventLogger; import io.opentelemetry.api.incubator.logs.ExtendedLogRecordBuilder; import io.opentelemetry.api.logs.Logger; import io.opentelemetry.api.logs.Severity; @@ -66,7 +65,6 @@ import io.opentelemetry.sdk.logs.SdkLoggerProvider; import io.opentelemetry.sdk.logs.export.BatchLogRecordProcessor; import io.opentelemetry.sdk.logs.export.LogRecordExporter; -import io.opentelemetry.sdk.logs.internal.SdkEventLoggerProvider; import io.opentelemetry.sdk.metrics.SdkMeterProvider; import io.opentelemetry.sdk.metrics.SdkMeterProviderBuilder; import io.opentelemetry.sdk.metrics.export.MetricExporter; @@ -636,10 +634,6 @@ private static void testLogRecordExporter(LogRecordExporter logRecordExporter) { .build(); Logger logger = loggerProvider.get(OtlpExporterIntegrationTest.class.getName()); - EventLogger eventLogger = - SdkEventLoggerProvider.create(loggerProvider) - .eventLoggerBuilder(OtlpExporterIntegrationTest.class.getName()) - .build(); SpanContext spanContext = SpanContext.create( @@ -672,7 +666,6 @@ private static void testLogRecordExporter(LogRecordExporter logRecordExporter) { .setSeverityText("DEBUG") .setContext(Context.current()) .emit(); - eventLogger.builder("namespace.event-name").put("key", "value").emit(); } // Closing triggers flush of processor @@ -696,7 +689,7 @@ private static void testLogRecordExporter(LogRecordExporter logRecordExporter) { ScopeLogs ilLogs = resourceLogs.getScopeLogs(0); assertThat(ilLogs.getScope().getName()).isEqualTo(OtlpExporterIntegrationTest.class.getName()); - assertThat(ilLogs.getLogRecordsCount()).isEqualTo(2); + assertThat(ilLogs.getLogRecordsCount()).isEqualTo(1); // LogRecord via Logger.logRecordBuilder()...emit() io.opentelemetry.proto.logs.v1.LogRecord protoLog1 = ilLogs.getLogRecords(0); @@ -814,29 +807,6 @@ private static void testLogRecordExporter(LogRecordExporter logRecordExporter) { assertThat(TraceFlags.fromByte((byte) protoLog1.getFlags())) .isEqualTo(spanContext.getTraceFlags()); assertThat(protoLog1.getTimeUnixNano()).isEqualTo(100); - - // LogRecord via EventLogger.emit(String, Attributes) - io.opentelemetry.proto.logs.v1.LogRecord protoLog2 = ilLogs.getLogRecords(1); - assertThat(protoLog2.getBody().getKvlistValue().getValuesList()) - .containsExactlyInAnyOrder( - io.opentelemetry.proto.common.v1.KeyValue.newBuilder() - .setKey("key") - .setValue(AnyValue.newBuilder().setStringValue("value").build()) - .build()); - assertThat(protoLog2.getAttributesList()) - .containsExactlyInAnyOrder( - io.opentelemetry.proto.common.v1.KeyValue.newBuilder() - .setKey("event.name") - .setValue(AnyValue.newBuilder().setStringValue("namespace.event-name").build()) - .build()); - assertThat(protoLog2.getSeverityText()).isEmpty(); - assertThat(TraceId.fromBytes(protoLog2.getTraceId().toByteArray())) - .isEqualTo(spanContext.getTraceId()); - assertThat(SpanId.fromBytes(protoLog2.getSpanId().toByteArray())) - .isEqualTo(spanContext.getSpanId()); - assertThat(TraceFlags.fromByte((byte) protoLog2.getFlags())) - .isEqualTo(spanContext.getTraceFlags()); - assertThat(protoLog2.getTimeUnixNano()).isGreaterThan(0); } private static class OtlpGrpcServer extends ServerExtension { diff --git a/sdk-extensions/autoconfigure/build.gradle.kts b/sdk-extensions/autoconfigure/build.gradle.kts index df01e3d34d7..e3545250888 100644 --- a/sdk-extensions/autoconfigure/build.gradle.kts +++ b/sdk-extensions/autoconfigure/build.gradle.kts @@ -10,8 +10,6 @@ dependencies { api(project(":sdk:all")) api(project(":sdk-extensions:autoconfigure-spi")) - compileOnly(project(":api:incubator")) - annotationProcessor("com.google.auto.value:auto-value") testImplementation(project(":sdk:trace-shaded-deps")) @@ -23,11 +21,6 @@ dependencies { testing { suites { - register("testIncubating") { - dependencies { - implementation(project(":api:incubator")) - } - } register("testAutoConfigureOrder") { targets { all { diff --git a/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/AutoConfiguredOpenTelemetrySdkBuilder.java b/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/AutoConfiguredOpenTelemetrySdkBuilder.java index f6ddd6c6f85..cca5f98dc89 100644 --- a/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/AutoConfiguredOpenTelemetrySdkBuilder.java +++ b/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/AutoConfiguredOpenTelemetrySdkBuilder.java @@ -63,19 +63,6 @@ */ public final class AutoConfiguredOpenTelemetrySdkBuilder implements AutoConfigurationCustomizer { - private static final boolean INCUBATOR_AVAILABLE; - - static { - boolean incubatorAvailable = false; - try { - Class.forName("io.opentelemetry.api.incubator.events.GlobalEventLoggerProvider"); - incubatorAvailable = true; - } catch (ClassNotFoundException e) { - // Not available - } - INCUBATOR_AVAILABLE = incubatorAvailable; - } - private static final Logger logger = Logger.getLogger(AutoConfiguredOpenTelemetrySdkBuilder.class.getName()); @@ -603,9 +590,6 @@ private void maybeSetAsGlobal(OpenTelemetrySdk openTelemetrySdk) { return; } GlobalOpenTelemetry.set(openTelemetrySdk); - if (INCUBATOR_AVAILABLE) { - IncubatingUtil.setGlobalEventLoggerProvider(openTelemetrySdk.getSdkLoggerProvider()); - } logger.log( Level.FINE, "Global OpenTelemetry set to {0} by autoconfiguration", openTelemetrySdk); } diff --git a/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/IncubatingUtil.java b/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/IncubatingUtil.java deleted file mode 100644 index f66e007cf34..00000000000 --- a/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/IncubatingUtil.java +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package io.opentelemetry.sdk.autoconfigure; - -import io.opentelemetry.api.incubator.events.GlobalEventLoggerProvider; -import io.opentelemetry.sdk.logs.SdkLoggerProvider; -import io.opentelemetry.sdk.logs.internal.SdkEventLoggerProvider; - -/** - * Utilities for interacting with {@code io.opentelemetry:opentelemetry-api-incubator}, which is not - * guaranteed to be present on the classpath. For all methods, callers MUST first separately - * reflectively confirm that the incubator is available on the classpath. - */ -final class IncubatingUtil { - - private IncubatingUtil() {} - - static void setGlobalEventLoggerProvider(SdkLoggerProvider sdkLoggerProvider) { - GlobalEventLoggerProvider.set(SdkEventLoggerProvider.create(sdkLoggerProvider)); - } -} diff --git a/sdk-extensions/autoconfigure/src/testFullConfig/java/io/opentelemetry/sdk/autoconfigure/AutoConfiguredOpenTelemetrySdkTest.java b/sdk-extensions/autoconfigure/src/testFullConfig/java/io/opentelemetry/sdk/autoconfigure/AutoConfiguredOpenTelemetrySdkTest.java index 4fc7dce0c35..f630b814cb7 100644 --- a/sdk-extensions/autoconfigure/src/testFullConfig/java/io/opentelemetry/sdk/autoconfigure/AutoConfiguredOpenTelemetrySdkTest.java +++ b/sdk-extensions/autoconfigure/src/testFullConfig/java/io/opentelemetry/sdk/autoconfigure/AutoConfiguredOpenTelemetrySdkTest.java @@ -13,7 +13,6 @@ import io.github.netmikey.logunit.api.LogCapturer; import io.opentelemetry.api.GlobalOpenTelemetry; import io.opentelemetry.api.OpenTelemetry; -import io.opentelemetry.api.incubator.events.GlobalEventLoggerProvider; import io.opentelemetry.exporter.prometheus.PrometheusHttpServer; import io.opentelemetry.sdk.OpenTelemetrySdk; import java.lang.reflect.Field; @@ -32,7 +31,6 @@ class AutoConfiguredOpenTelemetrySdkTest { @BeforeEach void setUp() { GlobalOpenTelemetry.resetForTest(); - GlobalEventLoggerProvider.resetForTest(); } @SuppressWarnings("ResultOfMethodCallIgnored") diff --git a/sdk-extensions/autoconfigure/src/testFullConfig/java/io/opentelemetry/sdk/autoconfigure/FileConfigurationTest.java b/sdk-extensions/autoconfigure/src/testFullConfig/java/io/opentelemetry/sdk/autoconfigure/FileConfigurationTest.java index 7eface52c5e..ef0b05b2da3 100644 --- a/sdk-extensions/autoconfigure/src/testFullConfig/java/io/opentelemetry/sdk/autoconfigure/FileConfigurationTest.java +++ b/sdk-extensions/autoconfigure/src/testFullConfig/java/io/opentelemetry/sdk/autoconfigure/FileConfigurationTest.java @@ -17,7 +17,6 @@ import io.github.netmikey.logunit.api.LogCapturer; import io.opentelemetry.api.GlobalOpenTelemetry; import io.opentelemetry.api.OpenTelemetry; -import io.opentelemetry.api.incubator.events.GlobalEventLoggerProvider; import io.opentelemetry.exporter.logging.LoggingSpanExporter; import io.opentelemetry.internal.testing.CleanupExtension; import io.opentelemetry.sdk.OpenTelemetrySdk; @@ -25,7 +24,6 @@ import io.opentelemetry.sdk.autoconfigure.spi.ConfigurationException; import io.opentelemetry.sdk.autoconfigure.spi.internal.DefaultConfigProperties; import io.opentelemetry.sdk.autoconfigure.spi.internal.StructuredConfigProperties; -import io.opentelemetry.sdk.logs.internal.SdkEventLoggerProvider; import io.opentelemetry.sdk.resources.Resource; import io.opentelemetry.sdk.trace.SdkTracerProvider; import io.opentelemetry.sdk.trace.export.SimpleSpanProcessor; @@ -72,7 +70,6 @@ void setup() throws IOException { configFilePath = tempDir.resolve("otel-config.yaml"); Files.write(configFilePath, yaml.getBytes(StandardCharsets.UTF_8)); GlobalOpenTelemetry.resetForTest(); - GlobalEventLoggerProvider.resetForTest(); } @Test @@ -135,8 +132,6 @@ void configFile_setResultAsGlobalFalse() { cleanup.addCloseable(openTelemetrySdk); assertThat(GlobalOpenTelemetry.get()).extracting("delegate").isNotSameAs(openTelemetrySdk); - assertThat(GlobalEventLoggerProvider.get()) - .isNotSameAs(openTelemetrySdk.getSdkLoggerProvider()); } @Test @@ -151,10 +146,6 @@ void configFile_setResultAsGlobalTrue() { cleanup.addCloseable(openTelemetrySdk); assertThat(GlobalOpenTelemetry.get()).extracting("delegate").isSameAs(openTelemetrySdk); - assertThat(GlobalEventLoggerProvider.get()) - .isInstanceOf(SdkEventLoggerProvider.class) - .extracting("delegateLoggerProvider") - .isSameAs(openTelemetrySdk.getSdkLoggerProvider()); } @Test diff --git a/sdk-extensions/autoconfigure/src/testFullConfig/java/io/opentelemetry/sdk/autoconfigure/FullConfigTest.java b/sdk-extensions/autoconfigure/src/testFullConfig/java/io/opentelemetry/sdk/autoconfigure/FullConfigTest.java index 96fd7e3eb61..edad134ae5e 100644 --- a/sdk-extensions/autoconfigure/src/testFullConfig/java/io/opentelemetry/sdk/autoconfigure/FullConfigTest.java +++ b/sdk-extensions/autoconfigure/src/testFullConfig/java/io/opentelemetry/sdk/autoconfigure/FullConfigTest.java @@ -18,8 +18,8 @@ import io.opentelemetry.api.GlobalOpenTelemetry; import io.opentelemetry.api.baggage.propagation.W3CBaggagePropagator; import io.opentelemetry.api.common.Attributes; -import io.opentelemetry.api.incubator.events.EventLogger; -import io.opentelemetry.api.incubator.events.GlobalEventLoggerProvider; +import io.opentelemetry.api.common.Value; +import io.opentelemetry.api.incubator.logs.ExtendedLogger; import io.opentelemetry.api.logs.Logger; import io.opentelemetry.api.logs.Severity; import io.opentelemetry.api.metrics.Meter; @@ -160,7 +160,6 @@ void setUp() { // Initialize here so we can shutdown when done GlobalOpenTelemetry.resetForTest(); - GlobalEventLoggerProvider.resetForTest(); openTelemetrySdk = AutoConfiguredOpenTelemetrySdk.initialize().getOpenTelemetrySdk(); } @@ -168,7 +167,6 @@ void setUp() { void afterEach() { openTelemetrySdk.close(); GlobalOpenTelemetry.resetForTest(); - GlobalEventLoggerProvider.resetForTest(); } @Test @@ -206,8 +204,12 @@ void configures() throws Exception { logger.logRecordBuilder().setBody("debug log message").setSeverity(Severity.DEBUG).emit(); logger.logRecordBuilder().setBody("info log message").setSeverity(Severity.INFO).emit(); - EventLogger eventLogger = GlobalEventLoggerProvider.get().eventLoggerBuilder("test").build(); - eventLogger.builder("namespace.test-name").put("cow", "moo").emit(); + ((ExtendedLogger) logger) + .logRecordBuilder() + .setEventName("namespace.test-name") + .setSeverity(Severity.INFO) + .setBody(Value.of(io.opentelemetry.api.common.KeyValue.of("cow", Value.of("moo")))) + .emit(); openTelemetrySdk.getSdkTracerProvider().forceFlush().join(10, TimeUnit.SECONDS); openTelemetrySdk.getSdkLoggerProvider().forceFlush().join(10, TimeUnit.SECONDS); @@ -305,7 +307,7 @@ void configures() throws Exception { .build()); assertThat(logRecord.getSeverityNumber()) .isEqualTo(SeverityNumber.SEVERITY_NUMBER_INFO); - assertHasKeyValue(logRecord.getAttributesList(), "event.name", "namespace.test-name"); + assertThat(logRecord.getEventName()).isEqualTo("namespace.test-name"); }); } diff --git a/sdk-extensions/autoconfigure/src/testIncubating/java/io/opentelemetry/sdk/autoconfigure/AutoconfigureGlobalEventLoggerProviderTest.java b/sdk-extensions/autoconfigure/src/testIncubating/java/io/opentelemetry/sdk/autoconfigure/AutoconfigureGlobalEventLoggerProviderTest.java deleted file mode 100644 index 8ca85372ada..00000000000 --- a/sdk-extensions/autoconfigure/src/testIncubating/java/io/opentelemetry/sdk/autoconfigure/AutoconfigureGlobalEventLoggerProviderTest.java +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package io.opentelemetry.sdk.autoconfigure; - -import static org.assertj.core.api.Assertions.assertThat; - -import io.opentelemetry.api.GlobalOpenTelemetry; -import io.opentelemetry.api.OpenTelemetry; -import io.opentelemetry.api.incubator.events.GlobalEventLoggerProvider; -import io.opentelemetry.sdk.OpenTelemetrySdk; -import io.opentelemetry.sdk.logs.internal.SdkEventLoggerProvider; -import java.util.HashMap; -import java.util.Map; -import java.util.function.Supplier; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; - -class AutoconfigureGlobalEventLoggerProviderTest { - - private AutoConfiguredOpenTelemetrySdkBuilder builder; - - @BeforeEach - void resetGlobal() { - GlobalOpenTelemetry.resetForTest(); - GlobalEventLoggerProvider.resetForTest(); - builder = - AutoConfiguredOpenTelemetrySdk.builder() - .addPropertiesSupplier(disableExportPropertySupplier()); - } - - @Test - void builder_setResultAsGlobalFalse() { - GlobalOpenTelemetry.set(OpenTelemetry.noop()); - - OpenTelemetrySdk openTelemetry = builder.build().getOpenTelemetrySdk(); - - assertThat(GlobalOpenTelemetry.get()).extracting("delegate").isNotSameAs(openTelemetry); - assertThat(GlobalEventLoggerProvider.get()).isNotSameAs(openTelemetry.getSdkLoggerProvider()); - } - - @Test - void builder_setResultAsGlobalTrue() { - OpenTelemetrySdk openTelemetry = builder.setResultAsGlobal().build().getOpenTelemetrySdk(); - - assertThat(GlobalOpenTelemetry.get()).extracting("delegate").isSameAs(openTelemetry); - assertThat(GlobalEventLoggerProvider.get()) - .isInstanceOf(SdkEventLoggerProvider.class) - .extracting("delegateLoggerProvider") - .isSameAs(openTelemetry.getSdkLoggerProvider()); - } - - private static Supplier> disableExportPropertySupplier() { - Map props = new HashMap<>(); - props.put("otel.metrics.exporter", "none"); - props.put("otel.traces.exporter", "none"); - props.put("otel.logs.exporter", "none"); - return () -> props; - } -} diff --git a/sdk/logs/src/main/java/io/opentelemetry/sdk/logs/internal/SdkEventBuilder.java b/sdk/logs/src/main/java/io/opentelemetry/sdk/logs/internal/SdkEventBuilder.java deleted file mode 100644 index 2378d9e6dad..00000000000 --- a/sdk/logs/src/main/java/io/opentelemetry/sdk/logs/internal/SdkEventBuilder.java +++ /dev/null @@ -1,87 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package io.opentelemetry.sdk.logs.internal; - -import io.opentelemetry.api.common.AttributeKey; -import io.opentelemetry.api.common.Attributes; -import io.opentelemetry.api.common.Value; -import io.opentelemetry.api.incubator.events.EventBuilder; -import io.opentelemetry.api.incubator.logs.ExtendedLogRecordBuilder; -import io.opentelemetry.api.logs.LogRecordBuilder; -import io.opentelemetry.api.logs.Severity; -import io.opentelemetry.context.Context; -import io.opentelemetry.sdk.common.Clock; -import java.time.Instant; -import java.util.HashMap; -import java.util.Map; -import java.util.concurrent.TimeUnit; - -class SdkEventBuilder implements EventBuilder { - - private static final AttributeKey EVENT_NAME = AttributeKey.stringKey("event.name"); - - private final Map> payload = new HashMap<>(); - private final Clock clock; - private final LogRecordBuilder logRecordBuilder; - private final String eventName; - private boolean hasTimestamp = false; - - SdkEventBuilder(Clock clock, LogRecordBuilder logRecordBuilder, String eventName) { - this.clock = clock; - this.logRecordBuilder = logRecordBuilder; - this.eventName = eventName; - } - - @Override - public EventBuilder put(String key, Value value) { - payload.put(key, value); - return this; - } - - @Override - public EventBuilder setTimestamp(long timestamp, TimeUnit unit) { - this.logRecordBuilder.setTimestamp(timestamp, unit); - this.hasTimestamp = true; - return this; - } - - @Override - public EventBuilder setTimestamp(Instant instant) { - this.logRecordBuilder.setTimestamp(instant); - this.hasTimestamp = true; - return this; - } - - @Override - public EventBuilder setContext(Context context) { - logRecordBuilder.setContext(context); - return this; - } - - @Override - public EventBuilder setSeverity(Severity severity) { - logRecordBuilder.setSeverity(severity); - return this; - } - - @Override - public EventBuilder setAttributes(Attributes attributes) { - logRecordBuilder.setAllAttributes(attributes); - return this; - } - - @Override - public void emit() { - if (!payload.isEmpty()) { - ((ExtendedLogRecordBuilder) logRecordBuilder).setBody(Value.of(payload)); - } - if (!hasTimestamp) { - logRecordBuilder.setTimestamp(clock.now(), TimeUnit.NANOSECONDS); - } - logRecordBuilder.setAttribute(EVENT_NAME, eventName); - logRecordBuilder.emit(); - } -} diff --git a/sdk/logs/src/main/java/io/opentelemetry/sdk/logs/internal/SdkEventLoggerProvider.java b/sdk/logs/src/main/java/io/opentelemetry/sdk/logs/internal/SdkEventLoggerProvider.java deleted file mode 100644 index d198675f552..00000000000 --- a/sdk/logs/src/main/java/io/opentelemetry/sdk/logs/internal/SdkEventLoggerProvider.java +++ /dev/null @@ -1,115 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package io.opentelemetry.sdk.logs.internal; - -import io.opentelemetry.api.incubator.events.EventBuilder; -import io.opentelemetry.api.incubator.events.EventLogger; -import io.opentelemetry.api.incubator.events.EventLoggerBuilder; -import io.opentelemetry.api.incubator.events.EventLoggerProvider; -import io.opentelemetry.api.logs.Logger; -import io.opentelemetry.api.logs.LoggerBuilder; -import io.opentelemetry.api.logs.LoggerProvider; -import io.opentelemetry.api.logs.Severity; -import io.opentelemetry.context.Context; -import io.opentelemetry.sdk.common.Clock; - -/** - * SDK implementation for {@link EventLoggerProvider}. - * - *

      Delegates all calls to the configured {@link LoggerProvider}, and its {@link LoggerBuilder}s, - * {@link Logger}s. - * - *

      This class is internal and experimental. Its APIs are unstable and can change at any time. Its - * APIs (or a version of them) may be promoted to the public stable API in the future, but no - * guarantees are made. - */ -public final class SdkEventLoggerProvider implements EventLoggerProvider { - - private static final Severity DEFAULT_SEVERITY = Severity.INFO; - - private final LoggerProvider delegateLoggerProvider; - private final Clock clock; - - private SdkEventLoggerProvider(LoggerProvider delegateLoggerProvider, Clock clock) { - this.delegateLoggerProvider = delegateLoggerProvider; - this.clock = clock; - } - - /** - * Create a {@link SdkEventLoggerProvider} which delegates to the {@code delegateLoggerProvider}. - */ - public static SdkEventLoggerProvider create(LoggerProvider delegateLoggerProvider) { - return new SdkEventLoggerProvider(delegateLoggerProvider, Clock.getDefault()); - } - - /** - * Create a {@link SdkEventLoggerProvider} which delegates to the {@code delegateLoggerProvider}. - */ - public static SdkEventLoggerProvider create(LoggerProvider delegateLoggerProvider, Clock clock) { - return new SdkEventLoggerProvider(delegateLoggerProvider, clock); - } - - @Override - public EventLogger get(String instrumentationScopeName) { - return eventLoggerBuilder(instrumentationScopeName).build(); - } - - @Override - public EventLoggerBuilder eventLoggerBuilder(String instrumentationScopeName) { - return new SdkEventLoggerBuilder( - clock, delegateLoggerProvider.loggerBuilder(instrumentationScopeName)); - } - - private static class SdkEventLoggerBuilder implements EventLoggerBuilder { - - private final Clock clock; - private final LoggerBuilder delegateLoggerBuilder; - - private SdkEventLoggerBuilder(Clock clock, LoggerBuilder delegateLoggerBuilder) { - this.clock = clock; - this.delegateLoggerBuilder = delegateLoggerBuilder; - } - - @Override - public EventLoggerBuilder setSchemaUrl(String schemaUrl) { - delegateLoggerBuilder.setSchemaUrl(schemaUrl); - return this; - } - - @Override - public EventLoggerBuilder setInstrumentationVersion(String instrumentationScopeVersion) { - delegateLoggerBuilder.setInstrumentationVersion(instrumentationScopeVersion); - return this; - } - - @Override - public EventLogger build() { - return new SdkEventLogger(clock, delegateLoggerBuilder.build()); - } - } - - private static class SdkEventLogger implements EventLogger { - - private final Clock clock; - private final Logger delegateLogger; - - private SdkEventLogger(Clock clock, Logger delegateLogger) { - this.clock = clock; - this.delegateLogger = delegateLogger; - } - - @Override - public EventBuilder builder(String eventName) { - return new SdkEventBuilder( - clock, - delegateLogger - .logRecordBuilder() - .setSeverity(DEFAULT_SEVERITY) - .setContext(Context.current()), - eventName); - } - } -} diff --git a/sdk/logs/src/testIncubating/java/io/opentelemetry/sdk/logs/internal/SdkEventBuilderTest.java b/sdk/logs/src/testIncubating/java/io/opentelemetry/sdk/logs/internal/SdkEventBuilderTest.java deleted file mode 100644 index bf45863d985..00000000000 --- a/sdk/logs/src/testIncubating/java/io/opentelemetry/sdk/logs/internal/SdkEventBuilderTest.java +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package io.opentelemetry.sdk.logs.internal; - -import static io.opentelemetry.api.common.AttributeKey.stringKey; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.anyLong; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -import io.opentelemetry.api.common.Attributes; -import io.opentelemetry.api.logs.LogRecordBuilder; -import io.opentelemetry.api.logs.Severity; -import io.opentelemetry.context.Context; -import io.opentelemetry.sdk.common.Clock; -import java.time.Instant; -import java.util.concurrent.TimeUnit; -import org.junit.jupiter.api.Test; - -class SdkEventBuilderTest { - - @Test - void emit() { - String eventName = "banana"; - - LogRecordBuilder logRecordBuilder = mock(LogRecordBuilder.class); - when(logRecordBuilder.setTimestamp(anyLong(), any())).thenReturn(logRecordBuilder); - when(logRecordBuilder.setAttribute(any(), any())).thenReturn(logRecordBuilder); - when(logRecordBuilder.setContext(any())).thenReturn(logRecordBuilder); - when(logRecordBuilder.setSeverity(any())).thenReturn(logRecordBuilder); - when(logRecordBuilder.setAllAttributes(any())).thenReturn(logRecordBuilder); - - Instant instant = Instant.now(); - Context context = Context.root(); - Attributes attributes = Attributes.builder().put("extra-attribute", "value").build(); - new SdkEventBuilder(Clock.getDefault(), logRecordBuilder, eventName) - .setTimestamp(123456L, TimeUnit.NANOSECONDS) - .setTimestamp(instant) - .setContext(context) - .setSeverity(Severity.DEBUG) - .setAttributes(attributes) - .emit(); - verify(logRecordBuilder).setAttribute(stringKey("event.name"), eventName); - verify(logRecordBuilder).setTimestamp(123456L, TimeUnit.NANOSECONDS); - verify(logRecordBuilder).setTimestamp(instant); - verify(logRecordBuilder).setContext(context); - verify(logRecordBuilder).setSeverity(Severity.DEBUG); - verify(logRecordBuilder).setAllAttributes(attributes); - verify(logRecordBuilder).emit(); - } -} diff --git a/sdk/logs/src/testIncubating/java/io/opentelemetry/sdk/logs/internal/SdkEventLoggerProviderTest.java b/sdk/logs/src/testIncubating/java/io/opentelemetry/sdk/logs/internal/SdkEventLoggerProviderTest.java deleted file mode 100644 index d033ba9bc15..00000000000 --- a/sdk/logs/src/testIncubating/java/io/opentelemetry/sdk/logs/internal/SdkEventLoggerProviderTest.java +++ /dev/null @@ -1,137 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package io.opentelemetry.sdk.logs.internal; - -import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.assertThat; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; - -import com.google.common.collect.ImmutableMap; -import io.opentelemetry.api.common.AttributeKey; -import io.opentelemetry.api.common.Attributes; -import io.opentelemetry.api.common.Value; -import io.opentelemetry.api.incubator.events.EventLogger; -import io.opentelemetry.api.logs.Severity; -import io.opentelemetry.sdk.common.Clock; -import io.opentelemetry.sdk.common.InstrumentationScopeInfo; -import io.opentelemetry.sdk.logs.ReadWriteLogRecord; -import io.opentelemetry.sdk.logs.SdkLoggerProvider; -import io.opentelemetry.sdk.resources.Resource; -import java.util.Arrays; -import java.util.Collections; -import java.util.HashMap; -import java.util.Map; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.AtomicReference; -import org.junit.jupiter.api.Test; - -class SdkEventLoggerProviderTest { - - private static final Resource RESOURCE = - Resource.builder().put("resource-key", "resource-value").build(); - - private final Clock clock = mock(Clock.class); - private final AtomicReference seenLog = new AtomicReference<>(); - private final SdkEventLoggerProvider eventEmitterProvider = - SdkEventLoggerProvider.create( - SdkLoggerProvider.builder() - .setResource(RESOURCE) - .addLogRecordProcessor((context, logRecord) -> seenLog.set(logRecord)) - .build(), - clock); - - @Test - void builder() { - when(clock.now()).thenReturn(10L); - - long yesterday = System.nanoTime() - TimeUnit.DAYS.toNanos(1); - EventLogger eventLogger = eventEmitterProvider.eventLoggerBuilder("test-scope").build(); - - eventLogger - .builder("namespace.event-name") - .put("key1", "value1") - .setTimestamp(yesterday, TimeUnit.NANOSECONDS) - .setSeverity(Severity.DEBUG) - .setAttributes(Attributes.builder().put("extra-attribute", "value").build()) - .emit(); - - assertThat(seenLog.get().toLogRecordData()) - .hasResource(RESOURCE) - .hasInstrumentationScope(InstrumentationScopeInfo.create("test-scope")) - .hasTimestamp(yesterday) - .hasSeverity(Severity.DEBUG) - .hasAttributes( - Attributes.builder() - .put("event.name", "namespace.event-name") - .put("extra-attribute", "value") - .build()); - assertThat(seenLog.get().toLogRecordData().getObservedTimestampEpochNanos()).isPositive(); - Value expectedPayload = Value.of(Collections.singletonMap("key1", Value.of("value1"))); - assertThat(seenLog.get().toLogRecordData().getBodyValue()).isEqualTo(expectedPayload); - } - - @Test - void eventBuilder_FullPayload() { - EventLogger eventLogger = eventEmitterProvider.get("test-scoe"); - - eventLogger - .builder("namespace.my-event-name") - // Helper methods to set primitive types - .put("stringKey", "value") - .put("longKey", 1L) - .put("doubleKey", 1.0) - .put("boolKey", true) - // Helper methods to set primitive array types - .put("stringArrKey", "value1", "value2") - .put("longArrKey", 1L, 2L) - .put("doubleArrKey", 1.0, 2.0) - .put("boolArrKey", true, false) - // Set complex data - .put( - "valueKey", - Value.of( - ImmutableMap.of( - "childKey1", Value.of("value"), - "childKey2", Value.of("value")))) - // Helper methods to set AttributeKey types - .put(AttributeKey.stringKey("attrStringKey"), "value") - .put(AttributeKey.longKey("attrLongKey"), 1L) - .put(AttributeKey.doubleKey("attrDoubleKey"), 1.0) - .put(AttributeKey.booleanKey("attrBoolKey"), true) - .put(AttributeKey.stringArrayKey("attrStringArrKey"), Arrays.asList("value1", "value2")) - .put(AttributeKey.longArrayKey("attrLongArrKey"), Arrays.asList(1L, 2L)) - .put(AttributeKey.doubleArrayKey("attrDoubleArrKey"), Arrays.asList(1.0, 2.0)) - .put(AttributeKey.booleanArrayKey("attrBoolArrKey"), Arrays.asList(true, false)) - .emit(); - - Map> expectedPayload = new HashMap<>(); - expectedPayload.put("stringKey", Value.of("value")); - expectedPayload.put("longKey", Value.of(1L)); - expectedPayload.put("doubleKey", Value.of(1.0)); - expectedPayload.put("boolKey", Value.of(true)); - expectedPayload.put( - "stringArrKey", Value.of(Arrays.asList(Value.of("value1"), Value.of("value2")))); - expectedPayload.put("longArrKey", Value.of(Arrays.asList(Value.of(1L), Value.of(2L)))); - expectedPayload.put("doubleArrKey", Value.of(Arrays.asList(Value.of(1.0), Value.of(2.0)))); - expectedPayload.put("boolArrKey", Value.of(Arrays.asList(Value.of(true), Value.of(false)))); - expectedPayload.put( - "valueKey", - Value.of( - ImmutableMap.of( - "childKey1", Value.of("value"), - "childKey2", Value.of("value")))); - expectedPayload.put("attrStringKey", Value.of("value")); - expectedPayload.put("attrLongKey", Value.of(1L)); - expectedPayload.put("attrDoubleKey", Value.of(1.0)); - expectedPayload.put("attrBoolKey", Value.of(true)); - expectedPayload.put( - "attrStringArrKey", Value.of(Arrays.asList(Value.of("value1"), Value.of("value2")))); - expectedPayload.put("attrLongArrKey", Value.of(Arrays.asList(Value.of(1L), Value.of(2L)))); - expectedPayload.put("attrDoubleArrKey", Value.of(Arrays.asList(Value.of(1.0), Value.of(2.0)))); - expectedPayload.put("attrBoolArrKey", Value.of(Arrays.asList(Value.of(true), Value.of(false)))); - assertThat(seenLog.get().toLogRecordData().getBodyValue()).isEqualTo(Value.of(expectedPayload)); - } -} diff --git a/sdk/testing/src/test/java/io/opentelemetry/sdk/testing/assertj/LogAssertionsTest.java b/sdk/testing/src/test/java/io/opentelemetry/sdk/testing/assertj/LogAssertionsTest.java index e30210eb9d6..165848c7f71 100644 --- a/sdk/testing/src/test/java/io/opentelemetry/sdk/testing/assertj/LogAssertionsTest.java +++ b/sdk/testing/src/test/java/io/opentelemetry/sdk/testing/assertj/LogAssertionsTest.java @@ -5,13 +5,7 @@ package io.opentelemetry.sdk.testing.assertj; -import static io.opentelemetry.api.common.AttributeKey.booleanArrayKey; -import static io.opentelemetry.api.common.AttributeKey.booleanKey; -import static io.opentelemetry.api.common.AttributeKey.doubleArrayKey; -import static io.opentelemetry.api.common.AttributeKey.doubleKey; -import static io.opentelemetry.api.common.AttributeKey.longArrayKey; import static io.opentelemetry.api.common.AttributeKey.longKey; -import static io.opentelemetry.api.common.AttributeKey.stringArrayKey; import static io.opentelemetry.api.common.AttributeKey.stringKey; import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.assertThat; import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.attributeEntry; @@ -21,8 +15,9 @@ import io.opentelemetry.api.common.AttributeKey; import io.opentelemetry.api.common.Attributes; +import io.opentelemetry.api.common.KeyValue; import io.opentelemetry.api.common.Value; -import io.opentelemetry.api.incubator.events.EventLogger; +import io.opentelemetry.api.logs.Logger; import io.opentelemetry.api.logs.Severity; import io.opentelemetry.api.trace.SpanContext; import io.opentelemetry.api.trace.TraceFlags; @@ -31,7 +26,6 @@ import io.opentelemetry.sdk.logs.SdkLoggerProvider; import io.opentelemetry.sdk.logs.data.LogRecordData; import io.opentelemetry.sdk.logs.export.SimpleLogRecordProcessor; -import io.opentelemetry.sdk.logs.internal.SdkEventLoggerProvider; import io.opentelemetry.sdk.resources.Resource; import io.opentelemetry.sdk.testing.exporter.InMemoryLogRecordExporter; import io.opentelemetry.sdk.testing.logs.internal.TestExtendedLogRecordData; @@ -292,32 +286,34 @@ void failure() { } @Test - void eventBodyAssertions() { + void logBodyAssertions() { InMemoryLogRecordExporter exporter = InMemoryLogRecordExporter.create(); SdkLoggerProvider loggerProvider = SdkLoggerProvider.builder() .addLogRecordProcessor(SimpleLogRecordProcessor.create(exporter)) .build(); - EventLogger eventLogger = SdkEventLoggerProvider.create(loggerProvider).get("test.test"); - eventLogger - .builder("foo") - .put("foostr", "bar") - .put("foobool", true) - .put("foolong", 12L) - .put("foodbl", 12.0) - .put("foostra", "bar", "baz", "buzz") - .put("foolonga", 9, 0, 2, 1, 0) - .put("foodbla", 9.1, 0.2, 2.3, 1.4, 0.5) - .put("fooboola", true, true, true, false) - .put("fooany", Value.of("grim")) - .put(stringKey("ak_str"), "bar") - .put(booleanKey("ak_bool"), true) - .put(longKey("ak_long"), 12L) - .put(doubleKey("ak_dbl"), 12.0) - .put(stringArrayKey("ak_stra"), Arrays.asList("bar", "baz", "buzz")) - .put(longArrayKey("ak_longa"), Arrays.asList(9L, 0L, 2L, 1L, 0L)) - .put(doubleArrayKey("ak_dbla"), Arrays.asList(9.1, 0.2, 2.3, 1.4, 0.5)) - .put(booleanArrayKey("ak_boola"), Arrays.asList(true, true, true, false)) + Logger logger = loggerProvider.get("test.test"); + logger + .logRecordBuilder() + .setBody( + Value.of( + KeyValue.of("foostr", Value.of("bar")), + KeyValue.of("foobool", Value.of(true)), + KeyValue.of("foolong", Value.of(12L)), + KeyValue.of("foodbl", Value.of(12.0)), + KeyValue.of( + "foostra", Value.of(Value.of("bar"), Value.of("baz"), Value.of("buzz"))), + KeyValue.of( + "foolonga", + Value.of(Value.of(9), Value.of(0), Value.of(2), Value.of(1), Value.of(0))), + KeyValue.of( + "foodbla", + Value.of( + Value.of(9.1), Value.of(0.2), Value.of(2.3), Value.of(1.4), Value.of(0.5))), + KeyValue.of( + "fooboola", + Value.of(Value.of(true), Value.of(true), Value.of(true), Value.of(false))), + KeyValue.of("fooany", Value.of("grim")))) .emit(); List logs = exporter.getFinishedLogRecordItems(); assertThat(logs).hasSize(1); @@ -330,14 +326,6 @@ void eventBodyAssertions() { .hasBodyField("foolonga", 9, 0, 2, 1, 0) .hasBodyField("foodbla", 9.1, 0.2, 2.3, 1.4, 0.5) .hasBodyField("fooboola", true, true, true, false) - .hasBodyField("fooany", Value.of("grim")) - .hasBodyField(stringKey("ak_str"), "bar") - .hasBodyField(booleanKey("ak_bool"), true) - .hasBodyField(longKey("ak_long"), 12L) - .hasBodyField(doubleKey("ak_dbl"), 12.0) - .hasBodyField(stringArrayKey("ak_stra"), Arrays.asList("bar", "baz", "buzz")) - .hasBodyField(longArrayKey("ak_longa"), Arrays.asList(9L, 0L, 2L, 1L, 0L)) - .hasBodyField(doubleArrayKey("ak_dbla"), Arrays.asList(9.1, 0.2, 2.3, 1.4, 0.5)) - .hasBodyField(booleanArrayKey("ak_boola"), Arrays.asList(true, true, true, false)); + .hasBodyField("fooany", Value.of("grim")); } } From 19e964a6368452e59a5c6b3488eaf5b0f60ef2e4 Mon Sep 17 00:00:00 2001 From: Yuriy Holinko Date: Fri, 31 Jan 2025 04:51:01 +0700 Subject: [PATCH 784/901] Expand OkHttp default retry exception predicate with SocketException (#7057) --- .../exporter/sender/okhttp/internal/RetryInterceptor.java | 4 ++++ .../exporter/sender/okhttp/internal/RetryInterceptorTest.java | 3 +++ 2 files changed, 7 insertions(+) diff --git a/exporters/sender/okhttp/src/main/java/io/opentelemetry/exporter/sender/okhttp/internal/RetryInterceptor.java b/exporters/sender/okhttp/src/main/java/io/opentelemetry/exporter/sender/okhttp/internal/RetryInterceptor.java index 9f6cc4729f5..7c3a3bfab80 100644 --- a/exporters/sender/okhttp/src/main/java/io/opentelemetry/exporter/sender/okhttp/internal/RetryInterceptor.java +++ b/exporters/sender/okhttp/src/main/java/io/opentelemetry/exporter/sender/okhttp/internal/RetryInterceptor.java @@ -10,6 +10,7 @@ import io.opentelemetry.sdk.common.export.RetryPolicy; import java.io.IOException; import java.net.ConnectException; +import java.net.SocketException; import java.net.SocketTimeoutException; import java.net.UnknownHostException; import java.util.StringJoiner; @@ -158,12 +159,15 @@ static boolean isRetryableException(IOException e) { // Known retryable ConnectTimeout messages: "Failed to connect to // localhost/[0:0:0:0:0:0:0:1]:62611" // Known retryable UnknownHostException messages: "xxxxxx.com" + // Known retryable SocketException: Socket closed if (e instanceof SocketTimeoutException) { return true; } else if (e instanceof ConnectException) { return true; } else if (e instanceof UnknownHostException) { return true; + } else if (e instanceof SocketException) { + return true; } return false; } diff --git a/exporters/sender/okhttp/src/test/java/io/opentelemetry/exporter/sender/okhttp/internal/RetryInterceptorTest.java b/exporters/sender/okhttp/src/test/java/io/opentelemetry/exporter/sender/okhttp/internal/RetryInterceptorTest.java index fa7604fb99d..3ba83683359 100644 --- a/exporters/sender/okhttp/src/test/java/io/opentelemetry/exporter/sender/okhttp/internal/RetryInterceptorTest.java +++ b/exporters/sender/okhttp/src/test/java/io/opentelemetry/exporter/sender/okhttp/internal/RetryInterceptorTest.java @@ -26,6 +26,7 @@ import java.net.ConnectException; import java.net.HttpRetryException; import java.net.ServerSocket; +import java.net.SocketException; import java.net.SocketTimeoutException; import java.net.UnknownHostException; import java.time.Duration; @@ -237,6 +238,8 @@ private static Stream isRetryableExceptionArgs() { Arguments.of(new SocketTimeoutException(), true), // Should retry on UnknownHostExceptions Arguments.of(new UnknownHostException("host"), true), + // Should retry on SocketException + Arguments.of(new SocketException("closed"), true), // Should retry on ConnectException Arguments.of( new ConnectException("Failed to connect to localhost/[0:0:0:0:0:0:0:1]:62611"), true), From 045c3e65d68d426a7ec87a80702d58edea5512a2 Mon Sep 17 00:00:00 2001 From: jack-berg <34418638+jack-berg@users.noreply.github.com> Date: Fri, 31 Jan 2025 09:19:22 -0600 Subject: [PATCH 785/901] Promote EnvironmentResourceProvider to public API (#7052) --- ...ntelemetry-sdk-extension-autoconfigure.txt | 7 +- sdk-extensions/autoconfigure/build.gradle.kts | 3 +- .../EnvironmentResourceProvider.java | 6 +- .../autoconfigure/ResourceConfiguration.java | 43 ++++- ...try.sdk.autoconfigure.spi.ResourceProvider | 2 +- .../ResourceConfigurationTest.java | 165 ++++++++++++------ 6 files changed, 165 insertions(+), 61 deletions(-) rename sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/{internal => }/EnvironmentResourceProvider.java (77%) diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-extension-autoconfigure.txt b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-extension-autoconfigure.txt index 4303d8e57e3..2eb91135544 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-extension-autoconfigure.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-extension-autoconfigure.txt @@ -1,2 +1,7 @@ Comparing source compatibility of opentelemetry-sdk-extension-autoconfigure-1.47.0-SNAPSHOT.jar against opentelemetry-sdk-extension-autoconfigure-1.46.0.jar -No changes. \ No newline at end of file ++++ NEW CLASS: PUBLIC(+) FINAL(+) io.opentelemetry.sdk.autoconfigure.EnvironmentResourceProvider (not serializable) + +++ CLASS FILE FORMAT VERSION: 52.0 <- n.a. + +++ NEW SUPERCLASS: java.lang.Object + +++ NEW CONSTRUCTOR: PUBLIC(+) EnvironmentResourceProvider() + +++ NEW METHOD: PUBLIC(+) io.opentelemetry.sdk.resources.Resource createResource(io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties) + +++ NEW METHOD: PUBLIC(+) int order() diff --git a/sdk-extensions/autoconfigure/build.gradle.kts b/sdk-extensions/autoconfigure/build.gradle.kts index e3545250888..eac32f51cdb 100644 --- a/sdk-extensions/autoconfigure/build.gradle.kts +++ b/sdk-extensions/autoconfigure/build.gradle.kts @@ -67,7 +67,8 @@ testing { targets { all { testTask { - environment("OTEL_RESOURCE_ATTRIBUTES", "service.name=test,cat=meow") + environment("OTEL_SERVICE_NAME", "test") + environment("OTEL_RESOURCE_ATTRIBUTES", "cat=meow") environment("OTEL_PROPAGATORS", "tracecontext,baggage,b3,b3multi,jaeger,ottrace,test") environment("OTEL_EXPORTER_OTLP_HEADERS", "cat=meow,dog=bark") environment("OTEL_EXPORTER_OTLP_TIMEOUT", "5000") diff --git a/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/internal/EnvironmentResourceProvider.java b/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/EnvironmentResourceProvider.java similarity index 77% rename from sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/internal/EnvironmentResourceProvider.java rename to sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/EnvironmentResourceProvider.java index ba61f957399..1af9b78e1cd 100644 --- a/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/internal/EnvironmentResourceProvider.java +++ b/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/EnvironmentResourceProvider.java @@ -3,9 +3,8 @@ * SPDX-License-Identifier: Apache-2.0 */ -package io.opentelemetry.sdk.autoconfigure.internal; +package io.opentelemetry.sdk.autoconfigure; -import io.opentelemetry.sdk.autoconfigure.ResourceConfiguration; import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties; import io.opentelemetry.sdk.autoconfigure.spi.ResourceProvider; import io.opentelemetry.sdk.resources.Resource; @@ -13,9 +12,6 @@ /** * {@link ResourceProvider} for automatically configuring {@link * ResourceConfiguration#createEnvironmentResource(ConfigProperties)}. - * - *

      This class is internal and is hence not for public use. Its APIs are unstable and can change - * at any time. */ public final class EnvironmentResourceProvider implements ResourceProvider { @Override diff --git a/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/ResourceConfiguration.java b/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/ResourceConfiguration.java index 5e94f966a39..8e00ee19ab2 100644 --- a/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/ResourceConfiguration.java +++ b/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/ResourceConfiguration.java @@ -25,6 +25,8 @@ import java.util.Map; import java.util.Set; import java.util.function.BiFunction; +import java.util.logging.Level; +import java.util.logging.Logger; /** * Auto-configuration for the OpenTelemetry {@link Resource}. @@ -33,12 +35,21 @@ */ public final class ResourceConfiguration { + private static final Logger logger = Logger.getLogger(ResourceConfiguration.class.getName()); + private static final AttributeKey SERVICE_NAME = AttributeKey.stringKey("service.name"); // Visible for testing static final String ATTRIBUTE_PROPERTY = "otel.resource.attributes"; static final String SERVICE_NAME_PROPERTY = "otel.service.name"; static final String DISABLED_ATTRIBUTE_KEYS = "otel.resource.disabled.keys"; + static final String ENABLED_RESOURCE_PROVIDERS = "otel.java.enabled.resource.providers"; + static final String DISABLED_RESOURCE_PROVIDERS = "otel.java.disabled.resource.providers"; + + private static final String OLD_ENVIRONMENT_DETECTOR_FQCN = + "io.opentelemetry.sdk.autoconfigure.internal.EnvironmentResourceProvider"; + private static final String NEW_ENVIRONMENT_DETECT_FQCN = + EnvironmentResourceProvider.class.getName(); /** * Create a {@link Resource} from the environment. The resource contains attributes parsed from @@ -88,10 +99,34 @@ static Resource configureResource( BiFunction resourceCustomizer) { Resource result = Resource.getDefault(); - Set enabledProviders = - new HashSet<>(config.getList("otel.java.enabled.resource.providers")); - Set disabledProviders = - new HashSet<>(config.getList("otel.java.disabled.resource.providers")); + Set enabledProviders = new HashSet<>(config.getList(ENABLED_RESOURCE_PROVIDERS)); + if (enabledProviders.remove(OLD_ENVIRONMENT_DETECTOR_FQCN)) { + logger.log( + Level.WARNING, + "Found reference to " + + OLD_ENVIRONMENT_DETECTOR_FQCN + + " in " + + ENABLED_RESOURCE_PROVIDERS + + ". Please update to " + + NEW_ENVIRONMENT_DETECT_FQCN + + ". Support for the old provider name will be removed after 1.49.0."); + enabledProviders.add(NEW_ENVIRONMENT_DETECT_FQCN); + } + + Set disabledProviders = new HashSet<>(config.getList(DISABLED_RESOURCE_PROVIDERS)); + if (disabledProviders.remove(OLD_ENVIRONMENT_DETECTOR_FQCN)) { + logger.log( + Level.WARNING, + "Found reference to " + + OLD_ENVIRONMENT_DETECTOR_FQCN + + " in " + + DISABLED_RESOURCE_PROVIDERS + + ". Please update to " + + NEW_ENVIRONMENT_DETECT_FQCN + + ". Support for the old provider name will be removed after 1.49.0."); + disabledProviders.add(NEW_ENVIRONMENT_DETECT_FQCN); + } + for (ResourceProvider resourceProvider : spiHelper.loadOrdered(ResourceProvider.class)) { if (!enabledProviders.isEmpty() && !enabledProviders.contains(resourceProvider.getClass().getName())) { diff --git a/sdk-extensions/autoconfigure/src/main/resources/META-INF/services/io.opentelemetry.sdk.autoconfigure.spi.ResourceProvider b/sdk-extensions/autoconfigure/src/main/resources/META-INF/services/io.opentelemetry.sdk.autoconfigure.spi.ResourceProvider index af0f9919adb..f9bd3554d79 100644 --- a/sdk-extensions/autoconfigure/src/main/resources/META-INF/services/io.opentelemetry.sdk.autoconfigure.spi.ResourceProvider +++ b/sdk-extensions/autoconfigure/src/main/resources/META-INF/services/io.opentelemetry.sdk.autoconfigure.spi.ResourceProvider @@ -1 +1 @@ -io.opentelemetry.sdk.autoconfigure.internal.EnvironmentResourceProvider +io.opentelemetry.sdk.autoconfigure.EnvironmentResourceProvider diff --git a/sdk-extensions/autoconfigure/src/testFullConfig/java/io/opentelemetry/sdk/autoconfigure/ResourceConfigurationTest.java b/sdk-extensions/autoconfigure/src/testFullConfig/java/io/opentelemetry/sdk/autoconfigure/ResourceConfigurationTest.java index 722d80b8704..785fd23cbac 100644 --- a/sdk-extensions/autoconfigure/src/testFullConfig/java/io/opentelemetry/sdk/autoconfigure/ResourceConfigurationTest.java +++ b/sdk-extensions/autoconfigure/src/testFullConfig/java/io/opentelemetry/sdk/autoconfigure/ResourceConfigurationTest.java @@ -11,29 +11,25 @@ import io.opentelemetry.api.common.Attributes; import io.opentelemetry.sdk.autoconfigure.internal.SpiHelper; import io.opentelemetry.sdk.autoconfigure.spi.internal.DefaultConfigProperties; +import io.opentelemetry.sdk.testing.assertj.AttributesAssert; import java.net.URL; import java.net.URLClassLoader; import java.util.Collections; import java.util.HashMap; import java.util.Map; +import java.util.function.Consumer; +import java.util.stream.Stream; +import javax.annotation.Nullable; import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; class ResourceConfigurationTest { private final SpiHelper spiHelper = SpiHelper.create(ResourceConfigurationTest.class.getClassLoader()); - @Test - void configureResource() { - Attributes attributes = - ResourceConfiguration.configureResource( - DefaultConfigProperties.create(Collections.emptyMap()), spiHelper, (r, c) -> r) - .getAttributes(); - - assertThat(attributes.get(AttributeKey.stringKey("animal"))).isNotNull(); - assertThat(attributes.get(AttributeKey.stringKey("color"))).isNotNull(); - } - @Test void configureResource_EmptyClassLoader() { Attributes attributes = @@ -43,55 +39,126 @@ void configureResource_EmptyClassLoader() { (r, c) -> r) .getAttributes(); + assertThat(attributes.get(AttributeKey.stringKey("service.name"))) + .isEqualTo("unknown_service:java"); + assertThat(attributes.get(AttributeKey.stringKey("cat"))).isNull(); assertThat(attributes.get(AttributeKey.stringKey("animal"))).isNull(); assertThat(attributes.get(AttributeKey.stringKey("color"))).isNull(); } - @Test - void configureResource_OnlyEnabled() { - Map customConfigs = new HashMap<>(1); - customConfigs.put( - "otel.java.enabled.resource.providers", - "io.opentelemetry.sdk.autoconfigure.provider.TestAnimalResourceProvider"); + @ParameterizedTest + @MethodSource("configureResourceArgs") + void configureResource( + @Nullable String enabledProviders, + @Nullable String disabledProviders, + Consumer attributeAssertion) { + // build.gradle.kts sets: + // OTEL_SERVICE_NAME=test + // OTEL_RESOURCE_ATTRIBUTES=cat=meow + Map config = new HashMap<>(); + if (enabledProviders != null) { + config.put("otel.java.enabled.resource.providers", enabledProviders); + } + if (disabledProviders != null) { + config.put("otel.java.disabled.resource.providers", disabledProviders); + } Attributes attributes = ResourceConfiguration.configureResource( - DefaultConfigProperties.create(customConfigs), spiHelper, (r, c) -> r) + DefaultConfigProperties.create(config), spiHelper, (r, c) -> r) .getAttributes(); - assertThat(attributes.get(AttributeKey.stringKey("animal"))).isEqualTo("cat"); - assertThat(attributes.get(AttributeKey.stringKey("color"))).isNull(); + attributeAssertion.accept(assertThat(attributes)); } - @Test - void configureResource_EnabledAndDisabled() { - Map customConfigs = new HashMap<>(2); - customConfigs.put( - "otel.java.enabled.resource.providers", - "io.opentelemetry.sdk.autoconfigure.provider.TestAnimalResourceProvider"); - customConfigs.put( - "otel.java.disabled.resource.providers", - "io.opentelemetry.sdk.extension.resources.TestColorResourceProvider"); - Attributes attributes = - ResourceConfiguration.configureResource( - DefaultConfigProperties.create(customConfigs), spiHelper, (r, c) -> r) - .getAttributes(); - - assertThat(attributes.get(AttributeKey.stringKey("animal"))).isEqualTo("cat"); - assertThat(attributes.get(AttributeKey.stringKey("color"))).isNull(); + private static Stream configureResourceArgs() { + return Stream.of( + // default + Arguments.of( + null, + null, + attributeConsumer( + attr -> attr.containsEntry("service.name", "test").containsEntry("cat", "meow"))), + // only enabled + Arguments.of( + "io.opentelemetry.sdk.autoconfigure.provider.TestAnimalResourceProvider", + null, + attributeConsumer( + attr -> + attr.containsEntry("service.name", "unknown_service:java") + .doesNotContainKey("cat") + .containsEntry("animal", "cat") + .doesNotContainKey("color"))), + // only disabled + Arguments.of( + null, + "io.opentelemetry.sdk.autoconfigure.provider.TestColorResourceProvider", + attributeConsumer( + attr -> + attr.containsEntry("service.name", "test") + .containsEntry("cat", "meow") + .containsEntry("animal", "cat") + .doesNotContainKey("color"))), + // enabled and disabled + Arguments.of( + "io.opentelemetry.sdk.autoconfigure.provider.TestAnimalResourceProvider", + "io.opentelemetry.sdk.autoconfigure.provider.TestColorResourceProvider", + attributeConsumer( + attr -> + attr.containsEntry("service.name", "unknown_service:java") + .doesNotContainKey("cat") + .containsEntry("animal", "cat") + .doesNotContainKey("color"))), + Arguments.of( + "io.opentelemetry.sdk.autoconfigure.provider.TestAnimalResourceProvider", + "io.opentelemetry.sdk.autoconfigure.provider.TestColorResourceProvider,io.opentelemetry.sdk.autoconfigure.provider.TestAnimalResourceProvider", + attributeConsumer( + attr -> + attr.containsEntry("service.name", "unknown_service:java") + .doesNotContainKey("cat") + .doesNotContainKey("animal") + .doesNotContainKey("color"))), + // environment resource provider + Arguments.of( + "io.opentelemetry.sdk.autoconfigure.EnvironmentResourceProvider", + null, + attributeConsumer( + attr -> + attr.containsEntry("service.name", "test") + .containsEntry("cat", "meow") + .doesNotContainKey("animal") + .doesNotContainKey("color"))), + Arguments.of( + null, + "io.opentelemetry.sdk.autoconfigure.EnvironmentResourceProvider", + attributeConsumer( + attr -> + attr.containsEntry("service.name", "unknown_service:java") + .doesNotContainKey("cat") + .containsEntry("animal", "cat") + .containsEntry("color", "blue"))), + // old environment resource provider FQCN + Arguments.of( + "io.opentelemetry.sdk.autoconfigure.internal.EnvironmentResourceProvider", + null, + attributeConsumer( + attr -> + attr.containsEntry("service.name", "test") + .containsEntry("cat", "meow") + .doesNotContainKey("animal") + .doesNotContainKey("color"))), + Arguments.of( + null, + "io.opentelemetry.sdk.autoconfigure.internal.EnvironmentResourceProvider", + attributeConsumer( + attr -> + attr.containsEntry("service.name", "unknown_service:java") + .doesNotContainKey("cat") + .containsEntry("animal", "cat") + .containsEntry("color", "blue")))); } - @Test - void configureResource_OnlyDisabled() { - Map customConfigs = new HashMap<>(1); - customConfigs.put( - "otel.java.disabled.resource.providers", - "io.opentelemetry.sdk.autoconfigure.provider.TestColorResourceProvider"); - Attributes attributes = - ResourceConfiguration.configureResource( - DefaultConfigProperties.create(customConfigs), spiHelper, (r, c) -> r) - .getAttributes(); - - assertThat(attributes.get(AttributeKey.stringKey("animal"))).isEqualTo("cat"); - assertThat(attributes.get(AttributeKey.stringKey("color"))).isNull(); + private static Consumer attributeConsumer( + Consumer attributesAssertConsumer) { + return attributesAssertConsumer; } } From cb64451c72a96a65d9d32a997852b87c150fcf2f Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 1 Feb 2025 17:45:10 -0800 Subject: [PATCH 786/901] fix(deps): update dependency org.owasp:dependency-check-gradle to v12.0.2 (#7061) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- buildSrc/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts index 8250fd7f289..927e7cd39f4 100644 --- a/buildSrc/build.gradle.kts +++ b/buildSrc/build.gradle.kts @@ -66,7 +66,7 @@ dependencies { implementation("net.ltgt.gradle:gradle-errorprone-plugin:4.1.0") implementation("net.ltgt.gradle:gradle-nullaway-plugin:2.2.0") implementation("org.jetbrains.kotlin:kotlin-gradle-plugin:2.1.10") - implementation("org.owasp:dependency-check-gradle:12.0.1") + implementation("org.owasp:dependency-check-gradle:12.0.2") implementation("ru.vyarus:gradle-animalsniffer-plugin:2.0.0") } From 9f0a29124eb6fa298a965fa56dba92cd73fb63a0 Mon Sep 17 00:00:00 2001 From: Trask Stalnaker Date: Thu, 6 Feb 2025 11:02:12 -0800 Subject: [PATCH 787/901] Reduce codecov target from 90 to 89 (#7077) --- .codecov.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.codecov.yaml b/.codecov.yaml index c2abc07c91d..14cd4116a58 100644 --- a/.codecov.yaml +++ b/.codecov.yaml @@ -11,7 +11,7 @@ coverage: status: project: default: - target: 90% + target: 89% paths: - "!opencensus-shim/" - "!opentracing-shim/" From 2fcd5f5bf8774ab47e629b721ac245df1311a324 Mon Sep 17 00:00:00 2001 From: Trask Stalnaker Date: Thu, 6 Feb 2025 14:40:51 -0800 Subject: [PATCH 788/901] Add OSSF Scorecard code scanning (#7067) --- .github/workflows/ossf-scorecard.yml | 47 ++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) create mode 100644 .github/workflows/ossf-scorecard.yml diff --git a/.github/workflows/ossf-scorecard.yml b/.github/workflows/ossf-scorecard.yml new file mode 100644 index 00000000000..0a306aa481d --- /dev/null +++ b/.github/workflows/ossf-scorecard.yml @@ -0,0 +1,47 @@ +name: OSSF Scorecard + +on: + push: + branches: + - main + schedule: + - cron: "43 6 * * 5" # weekly at 06:43 (UTC) on Friday + workflow_dispatch: + +permissions: read-all + +jobs: + analysis: + runs-on: ubuntu-latest + permissions: + # Needed for Code scanning upload + security-events: write + # Needed for GitHub OIDC token if publish_results is true + id-token: write + steps: + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + with: + persist-credentials: false + + - uses: ossf/scorecard-action@62b2cac7ed8198b15735ed49ab1e5cf35480ba46 # v2.4.0 + with: + results_file: results.sarif + results_format: sarif + publish_results: true + + # Upload the results as artifacts (optional). Commenting out will disable + # uploads of run results in SARIF format to the repository Actions tab. + # https://docs.github.com/en/actions/advanced-guides/storing-workflow-data-as-artifacts + - name: "Upload artifact" + uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0 + with: + name: SARIF file + path: results.sarif + retention-days: 5 + + # Upload the results to GitHub's code scanning dashboard (optional). + # Commenting out will disable upload of results to your repo's Code Scanning dashboard + - name: "Upload to code-scanning" + uses: github/codeql-action/upload-sarif@dd746615b3b9d728a6a37ca2045b68ca76d4841a # v3.28.8 + with: + sarif_file: results.sarif From d16cad3f73d1a94b210f3678720d07f9d93868e3 Mon Sep 17 00:00:00 2001 From: Emile de Weerd <151753129+edeweerd1A@users.noreply.github.com> Date: Fri, 7 Feb 2025 16:20:44 +0100 Subject: [PATCH 789/901] feat(sdk-testing): Add W3CBaggagePropagator to test utils (#7056) --- .../sdk/testing/junit4/OpenTelemetryRule.java | 8 ++++- .../junit5/OpenTelemetryExtension.java | 8 ++++- .../testing/junit4/OpenTelemetryRuleTest.java | 35 +++++++++++++++++++ .../junit5/OpenTelemetryExtensionTest.java | 34 ++++++++++++++++++ 4 files changed, 83 insertions(+), 2 deletions(-) diff --git a/sdk/testing/src/main/java/io/opentelemetry/sdk/testing/junit4/OpenTelemetryRule.java b/sdk/testing/src/main/java/io/opentelemetry/sdk/testing/junit4/OpenTelemetryRule.java index 7cf3a873cba..0fb0a7fd181 100644 --- a/sdk/testing/src/main/java/io/opentelemetry/sdk/testing/junit4/OpenTelemetryRule.java +++ b/sdk/testing/src/main/java/io/opentelemetry/sdk/testing/junit4/OpenTelemetryRule.java @@ -7,8 +7,10 @@ import io.opentelemetry.api.GlobalOpenTelemetry; import io.opentelemetry.api.OpenTelemetry; +import io.opentelemetry.api.baggage.propagation.W3CBaggagePropagator; import io.opentelemetry.api.trace.propagation.W3CTraceContextPropagator; import io.opentelemetry.context.propagation.ContextPropagators; +import io.opentelemetry.context.propagation.TextMapPropagator; import io.opentelemetry.sdk.OpenTelemetrySdk; import io.opentelemetry.sdk.logs.SdkLoggerProvider; import io.opentelemetry.sdk.logs.data.LogRecordData; @@ -84,7 +86,11 @@ public static OpenTelemetryRule create() { OpenTelemetrySdk openTelemetry = OpenTelemetrySdk.builder() - .setPropagators(ContextPropagators.create(W3CTraceContextPropagator.getInstance())) + .setPropagators( + ContextPropagators.create( + TextMapPropagator.composite( + W3CTraceContextPropagator.getInstance(), + W3CBaggagePropagator.getInstance()))) .setTracerProvider(tracerProvider) .setMeterProvider(meterProvider) .setLoggerProvider(loggerProvider) diff --git a/sdk/testing/src/main/java/io/opentelemetry/sdk/testing/junit5/OpenTelemetryExtension.java b/sdk/testing/src/main/java/io/opentelemetry/sdk/testing/junit5/OpenTelemetryExtension.java index 3aedad968c7..5ce9d1dc72a 100644 --- a/sdk/testing/src/main/java/io/opentelemetry/sdk/testing/junit5/OpenTelemetryExtension.java +++ b/sdk/testing/src/main/java/io/opentelemetry/sdk/testing/junit5/OpenTelemetryExtension.java @@ -9,8 +9,10 @@ import io.opentelemetry.api.GlobalOpenTelemetry; import io.opentelemetry.api.OpenTelemetry; +import io.opentelemetry.api.baggage.propagation.W3CBaggagePropagator; import io.opentelemetry.api.trace.propagation.W3CTraceContextPropagator; import io.opentelemetry.context.propagation.ContextPropagators; +import io.opentelemetry.context.propagation.TextMapPropagator; import io.opentelemetry.sdk.OpenTelemetrySdk; import io.opentelemetry.sdk.logs.SdkLoggerProvider; import io.opentelemetry.sdk.logs.data.LogRecordData; @@ -86,7 +88,11 @@ public static OpenTelemetryExtension create() { OpenTelemetrySdk openTelemetry = OpenTelemetrySdk.builder() - .setPropagators(ContextPropagators.create(W3CTraceContextPropagator.getInstance())) + .setPropagators( + ContextPropagators.create( + TextMapPropagator.composite( + W3CTraceContextPropagator.getInstance(), + W3CBaggagePropagator.getInstance()))) .setTracerProvider(tracerProvider) .setMeterProvider(meterProvider) .setLoggerProvider(loggerProvider) diff --git a/sdk/testing/src/test/java/io/opentelemetry/sdk/testing/junit4/OpenTelemetryRuleTest.java b/sdk/testing/src/test/java/io/opentelemetry/sdk/testing/junit4/OpenTelemetryRuleTest.java index a068d40bd0e..c37cc996f5d 100644 --- a/sdk/testing/src/test/java/io/opentelemetry/sdk/testing/junit4/OpenTelemetryRuleTest.java +++ b/sdk/testing/src/test/java/io/opentelemetry/sdk/testing/junit4/OpenTelemetryRuleTest.java @@ -7,12 +7,20 @@ import static org.assertj.core.api.Assertions.assertThat; +import io.opentelemetry.api.baggage.Baggage; import io.opentelemetry.api.common.Value; import io.opentelemetry.api.logs.Logger; import io.opentelemetry.api.metrics.LongCounter; import io.opentelemetry.api.metrics.Meter; +import io.opentelemetry.api.trace.Span; import io.opentelemetry.api.trace.Tracer; +import io.opentelemetry.context.Context; +import io.opentelemetry.context.Scope; +import io.opentelemetry.context.propagation.TextMapSetter; import io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions; +import java.util.HashMap; +import java.util.Map; +import javax.annotation.Nullable; import org.junit.Before; import org.junit.Rule; import org.junit.Test; @@ -118,4 +126,31 @@ public void getLogRecordsAgain() { .satisfies( logRecordData -> assertThat(logRecordData.getBodyValue()).isEqualTo(Value.of("body"))); } + + @Test + public void baggageAndTracePropagation() { + OpenTelemetryRule rule = OpenTelemetryRule.create(); + Span span = rule.getOpenTelemetry().getTracer("test").spanBuilder("test").startSpan(); + try (Scope baggageScope = Baggage.builder().put("key", "value").build().makeCurrent(); + Scope spanScope = span.makeCurrent()) { + Map carrier = new HashMap<>(); + rule.getOpenTelemetry() + .getPropagators() + .getTextMapPropagator() + .inject(Context.current(), carrier, new MapTextMapSetter()); + assertThat(carrier).containsEntry("baggage", "key=value"); + assertThat(carrier).containsKey("traceparent"); + } finally { + span.end(); + } + } + + public static class MapTextMapSetter implements TextMapSetter> { + @Override + public void set(@Nullable Map carrier, String key, String value) { + if (carrier != null) { + carrier.put(key, value); + } + } + } } diff --git a/sdk/testing/src/test/java/io/opentelemetry/sdk/testing/junit5/OpenTelemetryExtensionTest.java b/sdk/testing/src/test/java/io/opentelemetry/sdk/testing/junit5/OpenTelemetryExtensionTest.java index e91d3f036ea..f13c41e9878 100644 --- a/sdk/testing/src/test/java/io/opentelemetry/sdk/testing/junit5/OpenTelemetryExtensionTest.java +++ b/sdk/testing/src/test/java/io/opentelemetry/sdk/testing/junit5/OpenTelemetryExtensionTest.java @@ -10,18 +10,24 @@ import io.opentelemetry.api.GlobalOpenTelemetry; import io.opentelemetry.api.OpenTelemetry; +import io.opentelemetry.api.baggage.Baggage; import io.opentelemetry.api.common.Value; import io.opentelemetry.api.logs.Logger; import io.opentelemetry.api.metrics.LongCounter; import io.opentelemetry.api.metrics.Meter; import io.opentelemetry.api.trace.Span; import io.opentelemetry.api.trace.Tracer; +import io.opentelemetry.context.Context; import io.opentelemetry.context.Scope; +import io.opentelemetry.context.propagation.TextMapSetter; import io.opentelemetry.sdk.trace.data.SpanData; import java.util.Arrays; +import java.util.HashMap; import java.util.LinkedHashMap; +import java.util.Map; import java.util.concurrent.TimeUnit; import java.util.stream.Collectors; +import javax.annotation.Nullable; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.RegisterExtension; @@ -231,4 +237,32 @@ void afterAll() { assertThat(extension.getMetrics()).isEmpty(); assertThat(extension.getSpans()).isEmpty(); } + + @Test + void baggageAndTracePropagation() { + OpenTelemetryExtension extension = OpenTelemetryExtension.create(); + Span span = extension.getOpenTelemetry().getTracer("test").spanBuilder("test").startSpan(); + try (Scope baggageScope = Baggage.builder().put("key", "value").build().makeCurrent(); + Scope spanScope = span.makeCurrent()) { + Map carrier = new HashMap<>(); + extension + .getOpenTelemetry() + .getPropagators() + .getTextMapPropagator() + .inject(Context.current(), carrier, new MapTextMapSetter()); + assertThat(carrier).containsEntry("baggage", "key=value"); + assertThat(carrier).containsKey("traceparent"); + } finally { + span.end(); + } + } + + public static class MapTextMapSetter implements TextMapSetter> { + @Override + public void set(@Nullable Map carrier, String key, String value) { + if (carrier != null) { + carrier.put(key, value); + } + } + } } From a5739eba19c28e0c3ff1ceceea3e4a29a6807567 Mon Sep 17 00:00:00 2001 From: Michael Blum Date: Fri, 7 Feb 2025 09:34:36 -0600 Subject: [PATCH 790/901] Spec compliance: OTEL_PROPAGATORS should still work when OTEL_SDK_DISABLED (#7062) --- ...AutoConfiguredOpenTelemetrySdkBuilder.java | 122 +++++++------- .../AutoConfiguredOpenTelemetrySdkTest.java | 158 +++++++++++++++++- 2 files changed, 218 insertions(+), 62 deletions(-) diff --git a/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/AutoConfiguredOpenTelemetrySdkBuilder.java b/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/AutoConfiguredOpenTelemetrySdkBuilder.java index cca5f98dc89..09cec8b892d 100644 --- a/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/AutoConfiguredOpenTelemetrySdkBuilder.java +++ b/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/AutoConfiguredOpenTelemetrySdkBuilder.java @@ -443,65 +443,19 @@ public AutoConfiguredOpenTelemetrySdk build() { List closeables = new ArrayList<>(); try { - OpenTelemetrySdk openTelemetrySdk = OpenTelemetrySdk.builder().build(); - boolean sdkEnabled = !config.getBoolean("otel.sdk.disabled", false); + OpenTelemetrySdkBuilder sdkBuilder = OpenTelemetrySdk.builder(); + + // The propagation system is part of the API and functions in the absence of an SDK. + ContextPropagators propagators = + PropagatorConfiguration.configurePropagators(config, spiHelper, propagatorCustomizer); + sdkBuilder.setPropagators(propagators); + boolean sdkEnabled = !config.getBoolean("otel.sdk.disabled", false); if (sdkEnabled) { - SdkMeterProviderBuilder meterProviderBuilder = SdkMeterProvider.builder(); - meterProviderBuilder.setResource(resource); - MeterProviderConfiguration.configureMeterProvider( - meterProviderBuilder, - config, - spiHelper, - metricReaderCustomizer, - metricExporterCustomizer, - closeables); - meterProviderBuilder = meterProviderCustomizer.apply(meterProviderBuilder, config); - SdkMeterProvider meterProvider = meterProviderBuilder.build(); - closeables.add(meterProvider); - - SdkTracerProviderBuilder tracerProviderBuilder = SdkTracerProvider.builder(); - tracerProviderBuilder.setResource(resource); - TracerProviderConfiguration.configureTracerProvider( - tracerProviderBuilder, - config, - spiHelper, - meterProvider, - spanExporterCustomizer, - spanProcessorCustomizer, - samplerCustomizer, - closeables); - tracerProviderBuilder = tracerProviderCustomizer.apply(tracerProviderBuilder, config); - SdkTracerProvider tracerProvider = tracerProviderBuilder.build(); - closeables.add(tracerProvider); - - SdkLoggerProviderBuilder loggerProviderBuilder = SdkLoggerProvider.builder(); - loggerProviderBuilder.setResource(resource); - LoggerProviderConfiguration.configureLoggerProvider( - loggerProviderBuilder, - config, - spiHelper, - meterProvider, - logRecordExporterCustomizer, - logRecordProcessorCustomizer, - closeables); - loggerProviderBuilder = loggerProviderCustomizer.apply(loggerProviderBuilder, config); - SdkLoggerProvider loggerProvider = loggerProviderBuilder.build(); - closeables.add(loggerProvider); - - ContextPropagators propagators = - PropagatorConfiguration.configurePropagators(config, spiHelper, propagatorCustomizer); - - OpenTelemetrySdkBuilder sdkBuilder = - OpenTelemetrySdk.builder() - .setTracerProvider(tracerProvider) - .setLoggerProvider(loggerProvider) - .setMeterProvider(meterProvider) - .setPropagators(propagators); - - openTelemetrySdk = sdkBuilder.build(); + configureSdk(sdkBuilder, config, resource, spiHelper, closeables); } + OpenTelemetrySdk openTelemetrySdk = sdkBuilder.build(); maybeRegisterShutdownHook(openTelemetrySdk); maybeSetAsGlobal(openTelemetrySdk); callAutoConfigureListeners(spiHelper, openTelemetrySdk); @@ -526,6 +480,62 @@ public AutoConfiguredOpenTelemetrySdk build() { } } + // Visible for testing + void configureSdk( + OpenTelemetrySdkBuilder sdkBuilder, + ConfigProperties config, + Resource resource, + SpiHelper spiHelper, + List closeables) { + SdkMeterProviderBuilder meterProviderBuilder = SdkMeterProvider.builder(); + meterProviderBuilder.setResource(resource); + + MeterProviderConfiguration.configureMeterProvider( + meterProviderBuilder, + config, + spiHelper, + metricReaderCustomizer, + metricExporterCustomizer, + closeables); + meterProviderBuilder = meterProviderCustomizer.apply(meterProviderBuilder, config); + SdkMeterProvider meterProvider = meterProviderBuilder.build(); + closeables.add(meterProvider); + + SdkTracerProviderBuilder tracerProviderBuilder = SdkTracerProvider.builder(); + tracerProviderBuilder.setResource(resource); + TracerProviderConfiguration.configureTracerProvider( + tracerProviderBuilder, + config, + spiHelper, + meterProvider, + spanExporterCustomizer, + spanProcessorCustomizer, + samplerCustomizer, + closeables); + tracerProviderBuilder = tracerProviderCustomizer.apply(tracerProviderBuilder, config); + SdkTracerProvider tracerProvider = tracerProviderBuilder.build(); + closeables.add(tracerProvider); + + SdkLoggerProviderBuilder loggerProviderBuilder = SdkLoggerProvider.builder(); + loggerProviderBuilder.setResource(resource); + LoggerProviderConfiguration.configureLoggerProvider( + loggerProviderBuilder, + config, + spiHelper, + meterProvider, + logRecordExporterCustomizer, + logRecordProcessorCustomizer, + closeables); + loggerProviderBuilder = loggerProviderCustomizer.apply(loggerProviderBuilder, config); + SdkLoggerProvider loggerProvider = loggerProviderBuilder.build(); + closeables.add(loggerProvider); + + sdkBuilder + .setTracerProvider(tracerProvider) + .setLoggerProvider(loggerProvider) + .setMeterProvider(meterProvider); + } + @Nullable private static AutoConfiguredOpenTelemetrySdk maybeConfigureFromFile( ConfigProperties config, ComponentLoader componentLoader) { @@ -607,7 +617,7 @@ void callAutoConfigureListeners(SpiHelper spiHelper, OpenTelemetrySdk openTeleme } @SuppressWarnings("deprecation") // Support deprecated SdkTracerProviderConfigurer - private void mergeSdkTracerProviderConfigurer() { + void mergeSdkTracerProviderConfigurer() { for (io.opentelemetry.sdk.autoconfigure.spi.traces.SdkTracerProviderConfigurer configurer : componentLoader.load( io.opentelemetry.sdk.autoconfigure.spi.traces.SdkTracerProviderConfigurer.class)) { diff --git a/sdk-extensions/autoconfigure/src/test/java/io/opentelemetry/sdk/autoconfigure/AutoConfiguredOpenTelemetrySdkTest.java b/sdk-extensions/autoconfigure/src/test/java/io/opentelemetry/sdk/autoconfigure/AutoConfiguredOpenTelemetrySdkTest.java index ed2c94a7108..9b72fbefb82 100644 --- a/sdk-extensions/autoconfigure/src/test/java/io/opentelemetry/sdk/autoconfigure/AutoConfiguredOpenTelemetrySdkTest.java +++ b/sdk-extensions/autoconfigure/src/test/java/io/opentelemetry/sdk/autoconfigure/AutoConfiguredOpenTelemetrySdkTest.java @@ -67,7 +67,9 @@ import java.util.Properties; import java.util.concurrent.TimeUnit; import java.util.function.BiFunction; +import java.util.function.Consumer; import java.util.function.Supplier; +import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; @@ -391,7 +393,15 @@ void builder_registersShutdownHook() { } @Test - void shutdownHook() throws InterruptedException { + void builder_customizes() { + builder = spy(builder); + OpenTelemetrySdk sdk = builder.build().getOpenTelemetrySdk(); + assertThat(sdk).isNotNull(); + verify(builder, times(1)).mergeSdkTracerProviderConfigurer(); + } + + @Test + void builder_shutdownHook() throws InterruptedException { OpenTelemetrySdk sdk = mock(OpenTelemetrySdk.class); Thread thread = builder.shutdownHook(sdk); @@ -411,7 +421,7 @@ void builder_CallAutoConfigureListeners() { } @Test - void callAutoConfigureListeners() { + void builder_callAutoConfigureListeners() { AutoConfigureListener listener = mock(AutoConfigureListener.class); SpiHelper spiHelper = mock(SpiHelper.class); when(spiHelper.getListeners()).thenReturn(Collections.singleton(listener)); @@ -455,6 +465,39 @@ void disableSdk() { verify(logCustomizer, never()).apply(any(), any()); } + @Test + void disableSdk_PropagatorCustomizer() { + Context extracted = Context.root().with(ContextKey.named("animal"), "bear"); + + when(propagator2.extract(any(), any(), any())).thenReturn(extracted); + + AutoConfiguredOpenTelemetrySdk autoConfiguredSdk = + AutoConfiguredOpenTelemetrySdk.builder() + .addPropertiesSupplier(() -> singletonMap("otel.sdk.disabled", "true")) + .addPropertiesSupplier(() -> singletonMap("otel.propagators", "tracecontext")) + .addPropagatorCustomizer( + (previous, config) -> { + assertThat(previous).isSameAs(W3CTraceContextPropagator.getInstance()); + return propagator1; + }) + .addPropagatorCustomizer( + (previous, config) -> { + assertThat(previous).isSameAs(propagator1); + return propagator2; + }) + .build(); + + // When the SDK is disabled, propagators are still configured + assertThat(autoConfiguredSdk.getOpenTelemetrySdk().getPropagators()).isNotNull(); + Consumer propagatorConsumer = + propagator -> { + assertThat(propagator.extract(Context.root(), Collections.emptyMap(), getter)) + .isEqualTo(extracted); + }; + assertThat(autoConfiguredSdk.getOpenTelemetrySdk().getPropagators().getTextMapPropagator()) + .isInstanceOfSatisfying(TextMapPropagator.class, propagatorConsumer); + } + @Test void tracerProviderCustomizer() { InMemorySpanExporter spanExporter = InMemorySpanExporter.create(); @@ -510,6 +553,88 @@ void testNonStringProperties() { }); } + @Test + @SuppressLogger(AutoConfiguredOpenTelemetrySdkBuilder.class) + void configurationError_propagators() { + BiFunction + traceCustomizer = getTracerProviderBuilderSpy(); + BiFunction + metricCustomizer = getMeterProviderBuilderSpy(); + BiFunction logCustomizer = + getLoggerProviderBuilderSpy(); + + assertThatThrownBy( + () -> + // Override the provider builders with mocks which we can verify are closed + AutoConfiguredOpenTelemetrySdk.builder() + .addTracerProviderCustomizer(traceCustomizer) + .addMeterProviderCustomizer(metricCustomizer) + .addLoggerProviderCustomizer(logCustomizer) + .addPropertiesSupplier(() -> singletonMap("otel.metrics.exporter", "none")) + .addPropertiesSupplier(() -> singletonMap("otel.traces.exporter", "none")) + .addPropertiesSupplier(() -> singletonMap("otel.logs.exporter", "none")) + .addPropertiesSupplier(() -> singletonMap("otel.propagators", "foo")) + .addPropertiesSupplier(() -> singletonMap("otel.sdk.disabled", "true")) + .build()) + .isInstanceOf(ConfigurationException.class) + .hasMessageContaining("Unrecognized value for otel.propagators"); + + // When the SDK is disabled and propagators are mis-configured, none of the customizers are + // called + verify(traceCustomizer, never()).apply(any(), any()); + verify(metricCustomizer, never()).apply(any(), any()); + verify(logCustomizer, never()).apply(any(), any()); + + assertThatThrownBy( + () -> + // Override the provider builders with mocks which we can verify are closed + AutoConfiguredOpenTelemetrySdk.builder() + .addTracerProviderCustomizer(traceCustomizer) + .addMeterProviderCustomizer(metricCustomizer) + .addLoggerProviderCustomizer(logCustomizer) + .addPropertiesSupplier(() -> singletonMap("otel.metrics.exporter", "none")) + .addPropertiesSupplier(() -> singletonMap("otel.traces.exporter", "none")) + .addPropertiesSupplier(() -> singletonMap("otel.logs.exporter", "none")) + .addPropertiesSupplier(() -> singletonMap("otel.propagators", "foo")) + .addPropertiesSupplier(() -> singletonMap("otel.sdk.disabled", "false")) + .build()) + .isInstanceOf(ConfigurationException.class) + .hasMessageContaining("Unrecognized value for otel.propagators"); + + // When the SDK is enabled and propagators are mis-configured, none of the customizers are + // called + verify(traceCustomizer, never()).apply(any(), any()); + verify(metricCustomizer, never()).apply(any(), any()); + verify(logCustomizer, never()).apply(any(), any()); + } + + @Test + @SuppressLogger(AutoConfiguredOpenTelemetrySdkBuilder.class) + void configurationError_runtime() { + BiFunction + traceCustomizer = getTracerProviderBuilderSpy(); + BiFunction + metricCustomizer = getMeterProviderBuilderSpy(); + BiFunction logCustomizer = + getLoggerProviderBuilderSpy(); + + doThrow(new RuntimeException()).when(traceCustomizer).apply(any(), any()); + + assertThatThrownBy( + () -> + AutoConfiguredOpenTelemetrySdk.builder() + .addTracerProviderCustomizer(traceCustomizer) + .addMeterProviderCustomizer(metricCustomizer) + .addLoggerProviderCustomizer(logCustomizer) + .addPropertiesSupplier(() -> singletonMap("otel.metrics.exporter", "none")) + .addPropertiesSupplier(() -> singletonMap("otel.traces.exporter", "none")) + .addPropertiesSupplier(() -> singletonMap("otel.logs.exporter", "none")) + .addPropertiesSupplier(() -> singletonMap("otel.sdk.disabled", "false")) + .build()) + .isInstanceOf(ConfigurationException.class) + .hasMessageContaining("Unexpected configuration error"); + } + @Test @SuppressLogger(AutoConfiguredOpenTelemetrySdkBuilder.class) void configurationError_ClosesResources() { @@ -539,16 +664,37 @@ void configurationError_ClosesResources() { .addLoggerProviderCustomizer((u1, u2) -> loggerProviderBuilder) .addPropertiesSupplier(() -> singletonMap("otel.metrics.exporter", "none")) .addPropertiesSupplier(() -> singletonMap("otel.traces.exporter", "none")) - .addPropertiesSupplier(() -> singletonMap("otel.logs.exporter", "none")) - .addPropertiesSupplier(() -> singletonMap("otel.propagators", "foo")) + .addPropertiesSupplier(() -> singletonMap("otel.logs.exporter", "foo")) + .addPropertiesSupplier(() -> singletonMap("otel.sdk.disabled", "false")) .build()) .isInstanceOf(ConfigurationException.class) - .hasMessageContaining("Unrecognized value for otel.propagators"); + .hasMessageContaining("Unrecognized value for otel.logs.exporter: foo"); verify(tracerProvider).close(); verify(meterProvider).close(); - verify(loggerProvider).close(); logs.assertContains("Error closing io.opentelemetry.sdk.trace.SdkTracerProvider: Error!"); } + + @Test + @SuppressLogger(AutoConfiguredOpenTelemetrySdkBuilder.class) + void configurationError_fileNotFound() { + assertThatThrownBy( + () -> + AutoConfiguredOpenTelemetrySdk.builder() + .addPropertiesSupplier(() -> singletonMap("otel.config.file", "foo")) + .addPropertiesSupplier( + () -> singletonMap("otel.experimental.config.file", "foo")) + .addPropertiesSupplier(() -> singletonMap("otel.sdk.disabled", "true")) + .build()) + .isInstanceOf(ConfigurationException.class) + .hasMessageContaining("Configuration file not found"); + + Assertions.assertDoesNotThrow( + () -> + AutoConfiguredOpenTelemetrySdk.builder() + .addPropertiesSupplier(() -> singletonMap("otel.experimental.config.file", "")) + .addPropertiesSupplier(() -> singletonMap("otel.sdk.disabled", "true")) + .build()); + } } From ab24130dcbe7aba15872e281e5caae9a3111fee3 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 7 Feb 2025 09:36:06 -0600 Subject: [PATCH 791/901] chore(deps): update plugin com.gradleup.shadow to v8.3.6 (#7063) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- settings.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/settings.gradle.kts b/settings.gradle.kts index 376db9f78b8..3c116514c0f 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -1,6 +1,6 @@ pluginManagement { plugins { - id("com.gradleup.shadow") version "8.3.5" + id("com.gradleup.shadow") version "8.3.6" id("com.gradle.develocity") version "3.19.1" id("de.undercouch.download") version "5.6.0" id("org.jsonschema2pojo") version "1.2.2" From 22b6fea9ea9d990f640692b6540f0c2381662b92 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 7 Feb 2025 09:36:25 -0600 Subject: [PATCH 792/901] chore(deps): update gradle/actions action to v4.3.0 (#7060) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/gradle-wrapper-validation.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/gradle-wrapper-validation.yml b/.github/workflows/gradle-wrapper-validation.yml index f33287100b4..eb8538afdfb 100644 --- a/.github/workflows/gradle-wrapper-validation.yml +++ b/.github/workflows/gradle-wrapper-validation.yml @@ -13,4 +13,4 @@ jobs: steps: - uses: actions/checkout@v4 - - uses: gradle/actions/wrapper-validation@v4.2.2 + - uses: gradle/actions/wrapper-validation@v4.3.0 From e075cc157c47e1affd118d931738b56dda022761 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 7 Feb 2025 09:37:06 -0600 Subject: [PATCH 793/901] chore(deps): update plugin org.graalvm.buildtools.native to v0.10.5 (#7066) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- settings.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/settings.gradle.kts b/settings.gradle.kts index 3c116514c0f..1db18115392 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -5,7 +5,7 @@ pluginManagement { id("de.undercouch.download") version "5.6.0" id("org.jsonschema2pojo") version "1.2.2" id("io.github.gradle-nexus.publish-plugin") version "2.0.0" - id("org.graalvm.buildtools.native") version "0.10.4" + id("org.graalvm.buildtools.native") version "0.10.5" } } From a17dcd531dc463597a1233e97881b3f4d6f39de1 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 7 Feb 2025 13:13:54 -0600 Subject: [PATCH 794/901] fix(deps): update dependency me.champeau.jmh:jmh-gradle-plugin to v0.7.3 (#7054) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- buildSrc/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts index 927e7cd39f4..6dfee8ff67a 100644 --- a/buildSrc/build.gradle.kts +++ b/buildSrc/build.gradle.kts @@ -62,7 +62,7 @@ dependencies { implementation("gradle.plugin.com.google.protobuf:protobuf-gradle-plugin:0.8.18") implementation("gradle.plugin.io.morethan.jmhreport:gradle-jmh-report:0.9.6") implementation("me.champeau.gradle:japicmp-gradle-plugin:0.4.5") - implementation("me.champeau.jmh:jmh-gradle-plugin:0.7.2") + implementation("me.champeau.jmh:jmh-gradle-plugin:0.7.3") implementation("net.ltgt.gradle:gradle-errorprone-plugin:4.1.0") implementation("net.ltgt.gradle:gradle-nullaway-plugin:2.2.0") implementation("org.jetbrains.kotlin:kotlin-gradle-plugin:2.1.10") From 19650df469e3d1e43a9ae86fc516c4b7a6828212 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 7 Feb 2025 13:14:05 -0600 Subject: [PATCH 795/901] fix(deps): update dependency nl.jqno.equalsverifier:equalsverifier to v3.19 (#7055) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- dependencyManagement/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index da8801802e2..95d51cf04a0 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -76,7 +76,7 @@ val DEPENDENCIES = listOf( "io.opentracing:opentracing-api:0.33.0", "io.opentracing:opentracing-noop:0.33.0", "junit:junit:4.13.2", - "nl.jqno.equalsverifier:equalsverifier:3.18.1", + "nl.jqno.equalsverifier:equalsverifier:3.19", "org.awaitility:awaitility:4.2.2", "org.bouncycastle:bcpkix-jdk15on:1.70", "org.codehaus.mojo:animal-sniffer-annotations:1.24", From 355d17ffaa6be81c75784630e99c583c04c1348b Mon Sep 17 00:00:00 2001 From: jack-berg <34418638+jack-berg@users.noreply.github.com> Date: Fri, 7 Feb 2025 13:14:54 -0600 Subject: [PATCH 796/901] Prepare 1.47.0 (#7078) --- CHANGELOG.md | 57 +++++++++++++++++++ .../EnvironmentResourceProvider.java | 2 + .../sdk/common/export/RetryPolicy.java | 4 ++ 3 files changed, 63 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 69386e397b2..c4cc22d9964 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,63 @@ ## Unreleased +### API + +#### Incubator + +* Make `ExtendedTracer` easier to use + ([#6943](https://github.com/open-telemetry/opentelemetry-java/pull/6943)) +* Add `ExtendedLogRecordBuilder#setEventName` and corresponding SDK and OTLP serialization + ([#7012](https://github.com/open-telemetry/opentelemetry-java/pull/7012)) +* BREAKING: Drop event API / SDK + ([#7053](https://github.com/open-telemetry/opentelemetry-java/pull/7053)) + +### SDK + +* Remove -alpha artifacts from runtime classpath of stable components + ([#6944](https://github.com/open-telemetry/opentelemetry-java/pull/6944)) + +#### Traces + +* Bugfix: Follow spec on span limits, batch processors + ([#7030](https://github.com/open-telemetry/opentelemetry-java/pull/7030)) +* Add experimental `SdkTracerProvider.setScopeConfigurator(ScopeConfigurator)` for + updating `TracerConfig` at runtime + ([#7021](https://github.com/open-telemetry/opentelemetry-java/pull/7021)) + +#### Profiles + +* Add AttributeKeyValue abstraction to common otlp exporters + ([#7026](https://github.com/open-telemetry/opentelemetry-java/pull/7026)) +* Improve profiles attribute table handling + ([#7031](https://github.com/open-telemetry/opentelemetry-java/pull/7031)) + +#### Exporters + +* Interpret timeout zero value as no limit + ([#7023](https://github.com/open-telemetry/opentelemetry-java/pull/7023)) +* Bugfix - OTLP: Fix concurrent span reusable data marshaler + ([#7041](https://github.com/open-telemetry/opentelemetry-java/pull/7041)) +* OTLP: Add ability to customize retry exception predicate + ([#6991](https://github.com/open-telemetry/opentelemetry-java/pull/6991)) +* OTLP: Expand default OkHttp sender retry exception predicate + ([#7047](https://github.com/open-telemetry/opentelemetry-java/pull/7047), + [#7057](https://github.com/open-telemetry/opentelemetry-java/pull/7057)) + +#### Extensions + +* Autoconfigure: Consistent application of exporter customizers when otel.{signal}.exporter=none + ([#7017](https://github.com/open-telemetry/opentelemetry-java/pull/7017)) +* Autoconfigure: Promote EnvironmentResourceProvider to public API + ([#7052](https://github.com/open-telemetry/opentelemetry-java/pull/7052)) +* Autoconfigure: Ensure `OTEL_PROPAGATORS` still works when `OTEL_SDK_DISABLED=true`. + ([#7062](https://github.com/open-telemetry/opentelemetry-java/pull/7062))% + +#### Testing + +* Add W3CBaggagePropagator to `OpenTelemetryRule`, `OpenTelemetryExtension`. + ([#7056](https://github.com/open-telemetry/opentelemetry-java/pull/7056)) + ## Version 1.46.0 (2025-01-10) ### SDK diff --git a/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/EnvironmentResourceProvider.java b/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/EnvironmentResourceProvider.java index 1af9b78e1cd..231967c833c 100644 --- a/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/EnvironmentResourceProvider.java +++ b/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/EnvironmentResourceProvider.java @@ -12,6 +12,8 @@ /** * {@link ResourceProvider} for automatically configuring {@link * ResourceConfiguration#createEnvironmentResource(ConfigProperties)}. + * + * @since 1.47.0 */ public final class EnvironmentResourceProvider implements ResourceProvider { @Override diff --git a/sdk/common/src/main/java/io/opentelemetry/sdk/common/export/RetryPolicy.java b/sdk/common/src/main/java/io/opentelemetry/sdk/common/export/RetryPolicy.java index edda64d6c44..15fdf2d287e 100644 --- a/sdk/common/src/main/java/io/opentelemetry/sdk/common/export/RetryPolicy.java +++ b/sdk/common/src/main/java/io/opentelemetry/sdk/common/export/RetryPolicy.java @@ -72,6 +72,8 @@ public static RetryPolicyBuilder builder() { /** * Returns the predicate used to determine if an attempt which failed exceptionally should be * retried, or {@code null} if the exporter specific default predicate should be used. + * + * @since 1.47.0 */ @Nullable public abstract Predicate getRetryExceptionPredicate(); @@ -109,6 +111,8 @@ public abstract static class RetryPolicyBuilder { /** * Set the predicate used to determine if an attempt which failed exceptionally should be * retried. By default, an exporter specific default predicate should be used. + * + * @since 1.47.0 */ public abstract RetryPolicyBuilder setRetryExceptionPredicate( Predicate retryExceptionPredicate); From bd6b974e99cafd9eadcd1099129d20232763202a Mon Sep 17 00:00:00 2001 From: OpenTelemetry Bot <107717825+opentelemetrybot@users.noreply.github.com> Date: Fri, 7 Feb 2025 11:34:44 -0800 Subject: [PATCH 797/901] Update version to 1.48.0 (#7084) --- CHANGELOG.md | 2 ++ version.gradle.kts | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c4cc22d9964..afc0b9d2509 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,8 @@ ## Unreleased +## Version 1.47.0 (2025-02-07) + ### API #### Incubator diff --git a/version.gradle.kts b/version.gradle.kts index 215d9f5a3be..030e95dd215 100644 --- a/version.gradle.kts +++ b/version.gradle.kts @@ -1,7 +1,7 @@ val snapshot = true allprojects { - var ver = "1.47.0" + var ver = "1.48.0" val release = findProperty("otel.release") if (release != null) { ver += "-" + release From 41c51a052c28950f671e2b6d0aedd9015a694ebe Mon Sep 17 00:00:00 2001 From: Trask Stalnaker Date: Fri, 7 Feb 2025 12:20:41 -0800 Subject: [PATCH 798/901] Run CodeQL on PRs (#7070) --- .github/workflows/codeql-daily.yml | 44 ------------------------ .github/workflows/codeql.yml | 54 ++++++++++++++++++++++++++++++ 2 files changed, 54 insertions(+), 44 deletions(-) delete mode 100644 .github/workflows/codeql-daily.yml create mode 100644 .github/workflows/codeql.yml diff --git a/.github/workflows/codeql-daily.yml b/.github/workflows/codeql-daily.yml deleted file mode 100644 index 3331db67be3..00000000000 --- a/.github/workflows/codeql-daily.yml +++ /dev/null @@ -1,44 +0,0 @@ -name: CodeQL (daily) - -on: - schedule: - # Daily at 01:30 (UTC) - - cron: '30 1 * * *' - workflow_dispatch: - -jobs: - analyze: - runs-on: ubuntu-latest - - steps: - - uses: actions/checkout@v4 - - - name: Set up Java 17 - uses: actions/setup-java@v4 - with: - distribution: temurin - java-version: 17 - - - name: Initialize CodeQL - uses: github/codeql-action/init@v3 - with: - languages: java - # using "latest" helps to keep up with the latest Kotlin support - # see https://github.com/github/codeql-action/issues/1555#issuecomment-1452228433 - tools: latest - - - name: Set up gradle - uses: gradle/actions/setup-gradle@v4 - - name: Assemble - # skipping build cache is needed so that all modules will be analyzed - run: ./gradlew assemble --no-build-cache - - - name: Perform CodeQL analysis - uses: github/codeql-action/analyze@v3 - - open-issue-on-failure: - # open an issue on failure because it can be easy to miss CI failure notifications - needs: - - analyze - if: failure() && github.run_attempt == 1 - uses: ./.github/workflows/reusable-open-issue-on-failure.yml diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml new file mode 100644 index 00000000000..677f40b48ae --- /dev/null +++ b/.github/workflows/codeql.yml @@ -0,0 +1,54 @@ +name: CodeQL + +on: + pull_request: + branches: + - main + - release/* + - benchmarks + push: + branches: + - main + - release/* + - benchmarks + schedule: + - cron: "29 13 * * 2" # weekly at 13:29 UTC on Tuesday + +permissions: + contents: read + +jobs: + analyze: + permissions: + contents: read + actions: read # for github/codeql-action/init to get workflow details + security-events: write # for github/codeql-action/analyze to upload SARIF results + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + + - name: Set up Java 17 + uses: actions/setup-java@3a4f6e1af504cf6a31855fa899c6aa5355ba6c12 # v4.7.0 + with: + distribution: temurin + java-version: 17 + + - name: Set up gradle + uses: gradle/actions/setup-gradle@94baf225fe0a508e581a564467443d0e2379123b # v4.3.0 + + - name: Initialize CodeQL + uses: github/codeql-action/init@dd746615b3b9d728a6a37ca2045b68ca76d4841a # v3.28.8 + with: + languages: java, actions + # using "latest" helps to keep up with the latest Kotlin support + # see https://github.com/github/codeql-action/issues/1555#issuecomment-1452228433 + tools: latest + + - name: Assemble + # --no-build-cache is required for codeql to analyze all modules + # --no-daemon is required for codeql to observe the compilation + # (see https://docs.github.com/en/code-security/codeql-cli/getting-started-with-the-codeql-cli/preparing-your-code-for-codeql-analysis#specifying-build-commands) + run: ./gradlew assemble --no-build-cache --no-daemon + + - name: Perform CodeQL analysis + uses: github/codeql-action/analyze@dd746615b3b9d728a6a37ca2045b68ca76d4841a # v3.28.8 From d22baecc9518dcc7ed2a69ee0910f64d84d726cc Mon Sep 17 00:00:00 2001 From: Trask Stalnaker Date: Fri, 7 Feb 2025 12:21:04 -0800 Subject: [PATCH 799/901] Restrict token permissions (#7072) --- .github/workflows/backport.yml | 5 +++++ .github/workflows/benchmark-tags.yml | 5 +++++ .github/workflows/benchmark.yml | 5 +++++ .github/workflows/build-tracecontext-testsuite.yml | 6 ++++++ .github/workflows/docker-test-containers-daily.yml | 6 ++++++ .github/workflows/issue-management-feedback-label.yml | 6 ++++++ .github/workflows/issue-management-stale-action.yml | 7 +++++++ .github/workflows/owasp-dependency-check-daily.yml | 7 +++++-- .github/workflows/reusable-markdown-link-check.yml | 3 +++ .github/workflows/reusable-misspell-check.yml | 3 +++ 10 files changed, 51 insertions(+), 2 deletions(-) diff --git a/.github/workflows/backport.yml b/.github/workflows/backport.yml index 760c3e9999d..54b5b285097 100644 --- a/.github/workflows/backport.yml +++ b/.github/workflows/backport.yml @@ -6,8 +6,13 @@ on: description: "The pull request # to backport" required: true +permissions: + contents: read + jobs: backport: + permissions: + contents: write # for git push to PR branch runs-on: ubuntu-latest steps: - run: | diff --git a/.github/workflows/benchmark-tags.yml b/.github/workflows/benchmark-tags.yml index 5831c0f9819..04f5ccdd88d 100644 --- a/.github/workflows/benchmark-tags.yml +++ b/.github/workflows/benchmark-tags.yml @@ -3,8 +3,13 @@ name: Benchmark Tags on: workflow_dispatch: +permissions: + contents: read + jobs: sdk-benchmark: + permissions: + contents: write # for git push to benchmarks branch name: Benchmark SDK runs-on: self-hosted timeout-minutes: 10 diff --git a/.github/workflows/benchmark.yml b/.github/workflows/benchmark.yml index 1f026b2c654..442f22e0a09 100644 --- a/.github/workflows/benchmark.yml +++ b/.github/workflows/benchmark.yml @@ -5,8 +5,13 @@ on: branches: [ main ] workflow_dispatch: +permissions: + contents: read + jobs: sdk-benchmark: + permissions: + contents: write # for git push to benchmarks branch name: Benchmark SDK runs-on: self-hosted timeout-minutes: 10 diff --git a/.github/workflows/build-tracecontext-testsuite.yml b/.github/workflows/build-tracecontext-testsuite.yml index 3470424f594..236e6ad8707 100644 --- a/.github/workflows/build-tracecontext-testsuite.yml +++ b/.github/workflows/build-tracecontext-testsuite.yml @@ -9,8 +9,14 @@ on: - main workflow_dispatch: +permissions: + contents: read + jobs: publish: + permissions: + contents: read + packages: write runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 diff --git a/.github/workflows/docker-test-containers-daily.yml b/.github/workflows/docker-test-containers-daily.yml index ba9f627d22b..190737d035b 100644 --- a/.github/workflows/docker-test-containers-daily.yml +++ b/.github/workflows/docker-test-containers-daily.yml @@ -5,8 +5,14 @@ on: - cron: "23 3 * * *" workflow_dispatch: +permissions: + contents: read + jobs: copy-images: + permissions: + contents: read + packages: write strategy: matrix: include: diff --git a/.github/workflows/issue-management-feedback-label.yml b/.github/workflows/issue-management-feedback-label.yml index da9aa75b7bb..dfbba807271 100644 --- a/.github/workflows/issue-management-feedback-label.yml +++ b/.github/workflows/issue-management-feedback-label.yml @@ -4,8 +4,14 @@ on: issue_comment: types: [created] +permissions: + contents: read + jobs: issue_comment: + permissions: + contents: read + issues: write if: > contains(github.event.issue.labels.*.name, 'needs author feedback') && github.event.comment.user.login == github.event.issue.user.login diff --git a/.github/workflows/issue-management-stale-action.yml b/.github/workflows/issue-management-stale-action.yml index af57d2e3393..d222695559b 100644 --- a/.github/workflows/issue-management-stale-action.yml +++ b/.github/workflows/issue-management-stale-action.yml @@ -5,8 +5,15 @@ on: # hourly at minute 23 - cron: "23 * * * *" +permissions: + contents: read + jobs: stale: + permissions: + contents: read + issues: write # for actions/stale to close stale issues + pull-requests: write # for actions/stale to close stale PRs runs-on: ubuntu-latest steps: - uses: actions/stale@v9 diff --git a/.github/workflows/owasp-dependency-check-daily.yml b/.github/workflows/owasp-dependency-check-daily.yml index 4f346d2848b..5433e10bb08 100644 --- a/.github/workflows/owasp-dependency-check-daily.yml +++ b/.github/workflows/owasp-dependency-check-daily.yml @@ -4,13 +4,15 @@ name: OWASP dependency check (daily) on: schedule: - - cron: '30 1 * * *' + - cron: "30 1 * * *" # daily at 1:30 UTC workflow_dispatch: +permissions: + contents: read + jobs: analyze: runs-on: ubuntu-latest - steps: - uses: actions/checkout@v4 @@ -21,6 +23,7 @@ jobs: - name: Set up gradle uses: gradle/actions/setup-gradle@v4 + - name: Check dependencies run: ./gradlew dependencyCheckAnalyze diff --git a/.github/workflows/reusable-markdown-link-check.yml b/.github/workflows/reusable-markdown-link-check.yml index d5444b0afa5..d1b6b7c0e7b 100644 --- a/.github/workflows/reusable-markdown-link-check.yml +++ b/.github/workflows/reusable-markdown-link-check.yml @@ -3,6 +3,9 @@ name: Reusable - Markdown link check on: workflow_call: +permissions: + contents: read + jobs: markdown-link-check: runs-on: ubuntu-latest diff --git a/.github/workflows/reusable-misspell-check.yml b/.github/workflows/reusable-misspell-check.yml index 7876c441a9b..28eb76c5bc9 100644 --- a/.github/workflows/reusable-misspell-check.yml +++ b/.github/workflows/reusable-misspell-check.yml @@ -3,6 +3,9 @@ name: Reusable - Misspell check on: workflow_call: +permissions: + contents: read + jobs: misspell-check: runs-on: ubuntu-latest From 5b1e444980c1fa73d01d450b27ecab0a36b9affb Mon Sep 17 00:00:00 2001 From: Trask Stalnaker Date: Fri, 7 Feb 2025 12:21:19 -0800 Subject: [PATCH 800/901] Always run gradle wrapper validation (#7071) --- .github/workflows/gradle-wrapper-validation.yml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/gradle-wrapper-validation.yml b/.github/workflows/gradle-wrapper-validation.yml index eb8538afdfb..519bbd22f85 100644 --- a/.github/workflows/gradle-wrapper-validation.yml +++ b/.github/workflows/gradle-wrapper-validation.yml @@ -1,14 +1,14 @@ name: Gradle wrapper validation + on: - pull_request: - paths: - - '**/gradle/wrapper/**' push: - paths: - - '**/gradle/wrapper/**' + pull_request: + +permissions: + contents: read jobs: - validation: + gradle-wrapper-validation: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 From 867bb1f24e71b0dc74e0fc020f035f84a0640257 Mon Sep 17 00:00:00 2001 From: OpenTelemetry Bot <107717825+opentelemetrybot@users.noreply.github.com> Date: Fri, 7 Feb 2025 12:26:00 -0800 Subject: [PATCH 801/901] Post release for version 1.47.0 (#7087) --- README.md | 62 +++++++++---------- .../1.47.0_vs_1.46.0/opentelemetry-api.txt | 2 + .../opentelemetry-context.txt | 2 + .../opentelemetry-exporter-common.txt | 2 + .../opentelemetry-exporter-logging-otlp.txt | 2 + .../opentelemetry-exporter-logging.txt | 2 + .../opentelemetry-exporter-otlp-common.txt | 2 + .../opentelemetry-exporter-otlp.txt | 2 + ...y-exporter-sender-grpc-managed-channel.txt | 2 + .../opentelemetry-exporter-sender-jdk.txt | 2 + .../opentelemetry-exporter-sender-okhttp.txt | 2 + .../opentelemetry-exporter-zipkin.txt | 2 + .../opentelemetry-extension-kotlin.txt | 2 + ...ntelemetry-extension-trace-propagators.txt | 2 + .../opentelemetry-opentracing-shim.txt | 2 + .../opentelemetry-sdk-common.txt | 8 +++ ...emetry-sdk-extension-autoconfigure-spi.txt | 2 + ...ntelemetry-sdk-extension-autoconfigure.txt | 7 +++ ...ry-sdk-extension-jaeger-remote-sampler.txt | 2 + .../opentelemetry-sdk-logs.txt | 2 + .../opentelemetry-sdk-metrics.txt | 2 + .../opentelemetry-sdk-testing.txt | 2 + .../opentelemetry-sdk-trace.txt | 2 + .../1.47.0_vs_1.46.0/opentelemetry-sdk.txt | 2 + .../current_vs_latest/opentelemetry-api.txt | 2 +- .../opentelemetry-context.txt | 2 +- .../opentelemetry-exporter-common.txt | 2 +- .../opentelemetry-exporter-logging-otlp.txt | 2 +- .../opentelemetry-exporter-logging.txt | 2 +- .../opentelemetry-exporter-otlp-common.txt | 2 +- .../opentelemetry-exporter-otlp.txt | 2 +- ...y-exporter-sender-grpc-managed-channel.txt | 2 +- .../opentelemetry-exporter-sender-jdk.txt | 2 +- .../opentelemetry-exporter-sender-okhttp.txt | 2 +- .../opentelemetry-exporter-zipkin.txt | 2 +- .../opentelemetry-extension-kotlin.txt | 2 +- ...ntelemetry-extension-trace-propagators.txt | 2 +- .../opentelemetry-opentracing-shim.txt | 2 +- .../opentelemetry-sdk-common.txt | 10 +-- ...emetry-sdk-extension-autoconfigure-spi.txt | 2 +- ...ntelemetry-sdk-extension-autoconfigure.txt | 9 +-- ...ry-sdk-extension-jaeger-remote-sampler.txt | 2 +- .../opentelemetry-sdk-logs.txt | 2 +- .../opentelemetry-sdk-metrics.txt | 2 +- .../opentelemetry-sdk-testing.txt | 2 +- .../opentelemetry-sdk-trace.txt | 2 +- .../current_vs_latest/opentelemetry-sdk.txt | 2 +- 47 files changed, 113 insertions(+), 67 deletions(-) create mode 100644 docs/apidiffs/1.47.0_vs_1.46.0/opentelemetry-api.txt create mode 100644 docs/apidiffs/1.47.0_vs_1.46.0/opentelemetry-context.txt create mode 100644 docs/apidiffs/1.47.0_vs_1.46.0/opentelemetry-exporter-common.txt create mode 100644 docs/apidiffs/1.47.0_vs_1.46.0/opentelemetry-exporter-logging-otlp.txt create mode 100644 docs/apidiffs/1.47.0_vs_1.46.0/opentelemetry-exporter-logging.txt create mode 100644 docs/apidiffs/1.47.0_vs_1.46.0/opentelemetry-exporter-otlp-common.txt create mode 100644 docs/apidiffs/1.47.0_vs_1.46.0/opentelemetry-exporter-otlp.txt create mode 100644 docs/apidiffs/1.47.0_vs_1.46.0/opentelemetry-exporter-sender-grpc-managed-channel.txt create mode 100644 docs/apidiffs/1.47.0_vs_1.46.0/opentelemetry-exporter-sender-jdk.txt create mode 100644 docs/apidiffs/1.47.0_vs_1.46.0/opentelemetry-exporter-sender-okhttp.txt create mode 100644 docs/apidiffs/1.47.0_vs_1.46.0/opentelemetry-exporter-zipkin.txt create mode 100644 docs/apidiffs/1.47.0_vs_1.46.0/opentelemetry-extension-kotlin.txt create mode 100644 docs/apidiffs/1.47.0_vs_1.46.0/opentelemetry-extension-trace-propagators.txt create mode 100644 docs/apidiffs/1.47.0_vs_1.46.0/opentelemetry-opentracing-shim.txt create mode 100644 docs/apidiffs/1.47.0_vs_1.46.0/opentelemetry-sdk-common.txt create mode 100644 docs/apidiffs/1.47.0_vs_1.46.0/opentelemetry-sdk-extension-autoconfigure-spi.txt create mode 100644 docs/apidiffs/1.47.0_vs_1.46.0/opentelemetry-sdk-extension-autoconfigure.txt create mode 100644 docs/apidiffs/1.47.0_vs_1.46.0/opentelemetry-sdk-extension-jaeger-remote-sampler.txt create mode 100644 docs/apidiffs/1.47.0_vs_1.46.0/opentelemetry-sdk-logs.txt create mode 100644 docs/apidiffs/1.47.0_vs_1.46.0/opentelemetry-sdk-metrics.txt create mode 100644 docs/apidiffs/1.47.0_vs_1.46.0/opentelemetry-sdk-testing.txt create mode 100644 docs/apidiffs/1.47.0_vs_1.46.0/opentelemetry-sdk-trace.txt create mode 100644 docs/apidiffs/1.47.0_vs_1.46.0/opentelemetry-sdk.txt diff --git a/README.md b/README.md index 7706ba81e9d..6ac2f66d8a6 100644 --- a/README.md +++ b/README.md @@ -54,8 +54,8 @@ A bill of materials (or BOM) helps sync dependency versions of related artifacts | Component | Description | Artifact ID | Version | Javadoc | |----------------------------------------------|----------------------------------------|---------------------------|-------------------------------------------------------------|---------| -| [Bill of Materials (BOM)](./bom) | Bill of materials for stable artifacts | `opentelemetry-bom` | 1.46.0 | N/A | -| [Alpha Bill of Materials (BOM)](./bom-alpha) | Bill of materials for alpha artifacts | `opentelemetry-bom-alpha` | 1.46.0-alpha | N/A | +| [Bill of Materials (BOM)](./bom) | Bill of materials for stable artifacts | `opentelemetry-bom` | 1.47.0 | N/A | +| [Alpha Bill of Materials (BOM)](./bom-alpha) | Bill of materials for alpha artifacts | `opentelemetry-bom-alpha` | 1.47.0-alpha | N/A |

      @@ -65,9 +65,9 @@ The OpenTelemetry API for recording telemetry. | Component | Description | Artifact ID | Version | Javadoc | |-----------------------------------|--------------------------------------------------------------------------------------|-------------------------------|-------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| [API](./api/all) | OpenTelemetry API, including metrics, traces, baggage, context | `opentelemetry-api` | 1.46.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-api.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-api) | -| [API Incubator](./api/incubator) | API incubator, including pass through propagator, and extended tracer, and Event API | `opentelemetry-api-incubator` | 1.46.0-alpha | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-api-incubator.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-api-incubator) | -| [Context API](./context) | OpenTelemetry context API | `opentelemetry-context` | 1.46.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-context.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-context) | +| [API](./api/all) | OpenTelemetry API, including metrics, traces, baggage, context | `opentelemetry-api` | 1.47.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-api.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-api) | +| [API Incubator](./api/incubator) | API incubator, including pass through propagator, and extended tracer, and Event API | `opentelemetry-api-incubator` | 1.47.0-alpha | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-api-incubator.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-api-incubator) | +| [Context API](./context) | OpenTelemetry context API | `opentelemetry-context` | 1.47.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-context.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-context) |
      @@ -77,8 +77,8 @@ Extensions to the OpenTelemetry API. | Component | Description | Artifact ID | Version | Javadoc | |---------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|---------------------------------------------|-------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| [Kotlin Extension](./extensions/kotlin) | Context extension for coroutines | `opentelemetry-extension-kotlin` | 1.46.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-extension-kotlin.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-extension-kotlin) | -| [Trace Propagators Extension](./extensions/trace-propagators) | Trace propagators, including B3, Jaeger, OT Trace | `opentelemetry-extension-trace-propagators` | 1.46.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-extension-trace-propagators.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-extension-trace-propagators) | +| [Kotlin Extension](./extensions/kotlin) | Context extension for coroutines | `opentelemetry-extension-kotlin` | 1.47.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-extension-kotlin.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-extension-kotlin) | +| [Trace Propagators Extension](./extensions/trace-propagators) | Trace propagators, including B3, Jaeger, OT Trace | `opentelemetry-extension-trace-propagators` | 1.47.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-extension-trace-propagators.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-extension-trace-propagators) |
      @@ -88,12 +88,12 @@ The OpenTelemetry SDK for managing telemetry producing by the API. | Component | Description | Artifact ID | Version | Javadoc | |------------------------------|--------------------------------------------------------|-----------------------------|---------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| [SDK](./sdk/all) | OpenTelemetry SDK, including metrics, traces, and logs | `opentelemetry-sdk` | 1.46.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk) | -| [Metrics SDK](./sdk/metrics) | OpenTelemetry metrics SDK | `opentelemetry-sdk-metrics` | 1.46.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-metrics.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-metrics) | -| [Trace SDK](./sdk/trace) | OpenTelemetry trace SDK | `opentelemetry-sdk-trace` | 1.46.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-trace.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-trace) | -| [Log SDK](./sdk/logs) | OpenTelemetry log SDK | `opentelemetry-sdk-logs` | 1.46.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-logs.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-logs) | -| [SDK Common](./sdk/common) | Shared SDK components | `opentelemetry-sdk-common` | 1.46.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-common.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-common) | -| [SDK Testing](./sdk/testing) | Components for testing OpenTelemetry instrumentation | `opentelemetry-sdk-testing` | 1.46.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-testing.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-testing) | +| [SDK](./sdk/all) | OpenTelemetry SDK, including metrics, traces, and logs | `opentelemetry-sdk` | 1.47.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk) | +| [Metrics SDK](./sdk/metrics) | OpenTelemetry metrics SDK | `opentelemetry-sdk-metrics` | 1.47.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-metrics.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-metrics) | +| [Trace SDK](./sdk/trace) | OpenTelemetry trace SDK | `opentelemetry-sdk-trace` | 1.47.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-trace.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-trace) | +| [Log SDK](./sdk/logs) | OpenTelemetry log SDK | `opentelemetry-sdk-logs` | 1.47.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-logs.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-logs) | +| [SDK Common](./sdk/common) | Shared SDK components | `opentelemetry-sdk-common` | 1.47.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-common.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-common) | +| [SDK Testing](./sdk/testing) | Components for testing OpenTelemetry instrumentation | `opentelemetry-sdk-testing` | 1.47.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-testing.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-testing) |
      @@ -103,16 +103,16 @@ SDK exporters for shipping traces, metrics, and logs out of process. | Component | Description | Artifact ID | Version | Javadoc | |-----------------------------------------------------------------------|------------------------------------------------------------------------------|------------------------------------------------------|-------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| [OTLP Exporters](./exporters/otlp/all) | OTLP gRPC & HTTP exporters, including traces, metrics, and logs | `opentelemetry-exporter-otlp` | 1.46.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-otlp.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-otlp) | -| [OTLP Logging Exporters](./exporters/logging-otlp) | Logging exporters in OTLP JSON encoding, including traces, metrics, and logs | `opentelemetry-exporter-logging-otlp` | 1.46.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-logging-otlp.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-logging-otlp) | -| [OTLP Common](./exporters/otlp/common) | Shared OTLP components (internal) | `opentelemetry-exporter-otlp-common` | 1.46.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-otlp-common.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-otlp-common) | -| [Logging Exporter](./exporters/logging) | Logging exporters, including metrics, traces, and logs | `opentelemetry-exporter-logging` | 1.46.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-logging.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-logging) | -| [Zipkin Exporter](./exporters/zipkin) | Zipkin trace exporter | `opentelemetry-exporter-zipkin` | 1.46.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-zipkin.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-zipkin) | -| [Prometheus Exporter](./exporters/prometheus) | Prometheus metric exporter | `opentelemetry-exporter-prometheus` | 1.46.0-alpha | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-prometheus.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-prometheus) | -| [Exporter Common](./exporters/common) | Shared exporter components (internal) | `opentelemetry-exporter-common` | 1.46.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-common.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-common) | -| [OkHttp Sender](./exporters/sender/okhttp) | OkHttp implementation of HttpSender (internal) | `opentelemetry-exporter-sender-okhttp` | 1.46.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-sender-okhttp.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-sender-okhttp) | -| [JDK Sender](./exporters/sender/jdk) | Java 11+ native HttpClient implementation of HttpSender (internal) | `opentelemetry-exporter-sender-jdk` | 1.46.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-sender-jdk.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-sender-jdk) | | -| [gRPC ManagedChannel Sender](./exporters/sender/grpc-managed-channel) | gRPC ManagedChannel implementation of GrpcSender (internal) | `opentelemetry-exporter-sender-grpc-managed-channel` | 1.46.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-sender-grpc-managed-channel.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-sender-grpc-managed-channel) | | +| [OTLP Exporters](./exporters/otlp/all) | OTLP gRPC & HTTP exporters, including traces, metrics, and logs | `opentelemetry-exporter-otlp` | 1.47.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-otlp.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-otlp) | +| [OTLP Logging Exporters](./exporters/logging-otlp) | Logging exporters in OTLP JSON encoding, including traces, metrics, and logs | `opentelemetry-exporter-logging-otlp` | 1.47.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-logging-otlp.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-logging-otlp) | +| [OTLP Common](./exporters/otlp/common) | Shared OTLP components (internal) | `opentelemetry-exporter-otlp-common` | 1.47.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-otlp-common.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-otlp-common) | +| [Logging Exporter](./exporters/logging) | Logging exporters, including metrics, traces, and logs | `opentelemetry-exporter-logging` | 1.47.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-logging.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-logging) | +| [Zipkin Exporter](./exporters/zipkin) | Zipkin trace exporter | `opentelemetry-exporter-zipkin` | 1.47.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-zipkin.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-zipkin) | +| [Prometheus Exporter](./exporters/prometheus) | Prometheus metric exporter | `opentelemetry-exporter-prometheus` | 1.47.0-alpha | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-prometheus.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-prometheus) | +| [Exporter Common](./exporters/common) | Shared exporter components (internal) | `opentelemetry-exporter-common` | 1.47.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-common.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-common) | +| [OkHttp Sender](./exporters/sender/okhttp) | OkHttp implementation of HttpSender (internal) | `opentelemetry-exporter-sender-okhttp` | 1.47.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-sender-okhttp.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-sender-okhttp) | +| [JDK Sender](./exporters/sender/jdk) | Java 11+ native HttpClient implementation of HttpSender (internal) | `opentelemetry-exporter-sender-jdk` | 1.47.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-sender-jdk.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-sender-jdk) | | +| [gRPC ManagedChannel Sender](./exporters/sender/grpc-managed-channel) | gRPC ManagedChannel implementation of GrpcSender (internal) | `opentelemetry-exporter-sender-grpc-managed-channel` | 1.47.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-sender-grpc-managed-channel.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-sender-grpc-managed-channel) | |
      @@ -122,10 +122,10 @@ Extensions to the OpenTelemetry SDK. | Component | Description | Artifact ID | Version | Javadoc | |-------------------------------------------------------------------------------|------------------------------------------------------------------------------------|-----------------------------------------------------|-------------------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| [SDK Autoconfigure](./sdk-extensions/autoconfigure) | Autoconfigure OpenTelemetry SDK from env vars, system properties, and SPI | `opentelemetry-sdk-extension-autoconfigure` | 1.46.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-extension-autoconfigure.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-extension-autoconfigure) | -| [SDK Autoconfigure SPI](./sdk-extensions/autoconfigure-spi) | Service Provider Interface (SPI) definitions for autoconfigure | `opentelemetry-sdk-extension-autoconfigure-spi` | 1.46.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-extension-autoconfigure-spi.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-extension-autoconfigure-spi) | -| [SDK Jaeger Remote Sampler Extension](./sdk-extensions/jaeger-remote-sampler) | Sampler which obtains sampling configuration from remote Jaeger server | `opentelemetry-sdk-extension-jaeger-remote-sampler` | 1.46.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-extension-jaeger-remote-sampler.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-extension-jaeger-remote-sampler) | -| [SDK Incubator](./sdk-extensions/incubator) | SDK incubator, including YAML based view configuration, LeakDetectingSpanProcessor | `opentelemetry-sdk-extension-incubator` | 1.46.0-alpha | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-extension-incubator.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-extension-incubator) | +| [SDK Autoconfigure](./sdk-extensions/autoconfigure) | Autoconfigure OpenTelemetry SDK from env vars, system properties, and SPI | `opentelemetry-sdk-extension-autoconfigure` | 1.47.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-extension-autoconfigure.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-extension-autoconfigure) | +| [SDK Autoconfigure SPI](./sdk-extensions/autoconfigure-spi) | Service Provider Interface (SPI) definitions for autoconfigure | `opentelemetry-sdk-extension-autoconfigure-spi` | 1.47.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-extension-autoconfigure-spi.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-extension-autoconfigure-spi) | +| [SDK Jaeger Remote Sampler Extension](./sdk-extensions/jaeger-remote-sampler) | Sampler which obtains sampling configuration from remote Jaeger server | `opentelemetry-sdk-extension-jaeger-remote-sampler` | 1.47.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-extension-jaeger-remote-sampler.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-extension-jaeger-remote-sampler) | +| [SDK Incubator](./sdk-extensions/incubator) | SDK incubator, including YAML based view configuration, LeakDetectingSpanProcessor | `opentelemetry-sdk-extension-incubator` | 1.47.0-alpha | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-extension-incubator.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-extension-incubator) |
      @@ -135,8 +135,8 @@ Shims for bridging data from one observability library to another. | Component | Description | Artifact ID | Version | Javadoc | |----------------------------------------|--------------------------------------------------------------|----------------------------------|-------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| [OpenCensus Shim](./opencensus-shim) | Bridge opencensus metrics into the OpenTelemetry metrics SDK | `opentelemetry-opencensus-shim` | 1.46.0-alpha | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-opencensus-shim.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-opencensus-shim) | -| [OpenTracing Shim](./opentracing-shim) | Bridge opentracing spans into the OpenTelemetry trace API | `opentelemetry-opentracing-shim` | 1.46.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-opentracing-shim.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-opentracing-shim) | +| [OpenCensus Shim](./opencensus-shim) | Bridge opencensus metrics into the OpenTelemetry metrics SDK | `opentelemetry-opencensus-shim` | 1.47.0-alpha | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-opencensus-shim.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-opencensus-shim) | +| [OpenTracing Shim](./opentracing-shim) | Bridge opentracing spans into the OpenTelemetry trace API | `opentelemetry-opentracing-shim` | 1.47.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-opentracing-shim.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-opentracing-shim) |
      ## Dependencies @@ -177,7 +177,7 @@ repositories { } dependencies { - implementation platform("io.opentelemetry:opentelemetry-bom:1.47.0-SNAPSHOT") + implementation platform("io.opentelemetry:opentelemetry-bom:1.48.0-SNAPSHOT") implementation('io.opentelemetry:opentelemetry-api') } ``` @@ -199,7 +199,7 @@ dependencies { io.opentelemetry opentelemetry-bom - 1.47.0-SNAPSHOT + 1.48.0-SNAPSHOT pom import diff --git a/docs/apidiffs/1.47.0_vs_1.46.0/opentelemetry-api.txt b/docs/apidiffs/1.47.0_vs_1.46.0/opentelemetry-api.txt new file mode 100644 index 00000000000..9b8cec50e3d --- /dev/null +++ b/docs/apidiffs/1.47.0_vs_1.46.0/opentelemetry-api.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of opentelemetry-api-1.47.0.jar against opentelemetry-api-1.46.0.jar +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.47.0_vs_1.46.0/opentelemetry-context.txt b/docs/apidiffs/1.47.0_vs_1.46.0/opentelemetry-context.txt new file mode 100644 index 00000000000..9e926cbce02 --- /dev/null +++ b/docs/apidiffs/1.47.0_vs_1.46.0/opentelemetry-context.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of opentelemetry-context-1.47.0.jar against opentelemetry-context-1.46.0.jar +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.47.0_vs_1.46.0/opentelemetry-exporter-common.txt b/docs/apidiffs/1.47.0_vs_1.46.0/opentelemetry-exporter-common.txt new file mode 100644 index 00000000000..e9ad6c262dd --- /dev/null +++ b/docs/apidiffs/1.47.0_vs_1.46.0/opentelemetry-exporter-common.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of opentelemetry-exporter-common-1.47.0.jar against opentelemetry-exporter-common-1.46.0.jar +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.47.0_vs_1.46.0/opentelemetry-exporter-logging-otlp.txt b/docs/apidiffs/1.47.0_vs_1.46.0/opentelemetry-exporter-logging-otlp.txt new file mode 100644 index 00000000000..19e9e7eee9e --- /dev/null +++ b/docs/apidiffs/1.47.0_vs_1.46.0/opentelemetry-exporter-logging-otlp.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of opentelemetry-exporter-logging-otlp-1.47.0.jar against opentelemetry-exporter-logging-otlp-1.46.0.jar +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.47.0_vs_1.46.0/opentelemetry-exporter-logging.txt b/docs/apidiffs/1.47.0_vs_1.46.0/opentelemetry-exporter-logging.txt new file mode 100644 index 00000000000..f1b1755c49b --- /dev/null +++ b/docs/apidiffs/1.47.0_vs_1.46.0/opentelemetry-exporter-logging.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of opentelemetry-exporter-logging-1.47.0.jar against opentelemetry-exporter-logging-1.46.0.jar +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.47.0_vs_1.46.0/opentelemetry-exporter-otlp-common.txt b/docs/apidiffs/1.47.0_vs_1.46.0/opentelemetry-exporter-otlp-common.txt new file mode 100644 index 00000000000..c7ba2d7604b --- /dev/null +++ b/docs/apidiffs/1.47.0_vs_1.46.0/opentelemetry-exporter-otlp-common.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of opentelemetry-exporter-otlp-common-1.47.0.jar against opentelemetry-exporter-otlp-common-1.46.0.jar +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.47.0_vs_1.46.0/opentelemetry-exporter-otlp.txt b/docs/apidiffs/1.47.0_vs_1.46.0/opentelemetry-exporter-otlp.txt new file mode 100644 index 00000000000..c05d0d2101e --- /dev/null +++ b/docs/apidiffs/1.47.0_vs_1.46.0/opentelemetry-exporter-otlp.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of opentelemetry-exporter-otlp-1.47.0.jar against opentelemetry-exporter-otlp-1.46.0.jar +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.47.0_vs_1.46.0/opentelemetry-exporter-sender-grpc-managed-channel.txt b/docs/apidiffs/1.47.0_vs_1.46.0/opentelemetry-exporter-sender-grpc-managed-channel.txt new file mode 100644 index 00000000000..8df2f05993e --- /dev/null +++ b/docs/apidiffs/1.47.0_vs_1.46.0/opentelemetry-exporter-sender-grpc-managed-channel.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of opentelemetry-exporter-sender-grpc-managed-channel-1.47.0.jar against opentelemetry-exporter-sender-grpc-managed-channel-1.46.0.jar +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.47.0_vs_1.46.0/opentelemetry-exporter-sender-jdk.txt b/docs/apidiffs/1.47.0_vs_1.46.0/opentelemetry-exporter-sender-jdk.txt new file mode 100644 index 00000000000..9a32d2426b1 --- /dev/null +++ b/docs/apidiffs/1.47.0_vs_1.46.0/opentelemetry-exporter-sender-jdk.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of opentelemetry-exporter-sender-jdk-1.47.0.jar against opentelemetry-exporter-sender-jdk-1.46.0.jar +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.47.0_vs_1.46.0/opentelemetry-exporter-sender-okhttp.txt b/docs/apidiffs/1.47.0_vs_1.46.0/opentelemetry-exporter-sender-okhttp.txt new file mode 100644 index 00000000000..c1e4ef30e1e --- /dev/null +++ b/docs/apidiffs/1.47.0_vs_1.46.0/opentelemetry-exporter-sender-okhttp.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of opentelemetry-exporter-sender-okhttp-1.47.0.jar against opentelemetry-exporter-sender-okhttp-1.46.0.jar +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.47.0_vs_1.46.0/opentelemetry-exporter-zipkin.txt b/docs/apidiffs/1.47.0_vs_1.46.0/opentelemetry-exporter-zipkin.txt new file mode 100644 index 00000000000..5728b1c7ebe --- /dev/null +++ b/docs/apidiffs/1.47.0_vs_1.46.0/opentelemetry-exporter-zipkin.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of opentelemetry-exporter-zipkin-1.47.0.jar against opentelemetry-exporter-zipkin-1.46.0.jar +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.47.0_vs_1.46.0/opentelemetry-extension-kotlin.txt b/docs/apidiffs/1.47.0_vs_1.46.0/opentelemetry-extension-kotlin.txt new file mode 100644 index 00000000000..d3bb74e7598 --- /dev/null +++ b/docs/apidiffs/1.47.0_vs_1.46.0/opentelemetry-extension-kotlin.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of opentelemetry-extension-kotlin-1.47.0.jar against opentelemetry-extension-kotlin-1.46.0.jar +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.47.0_vs_1.46.0/opentelemetry-extension-trace-propagators.txt b/docs/apidiffs/1.47.0_vs_1.46.0/opentelemetry-extension-trace-propagators.txt new file mode 100644 index 00000000000..dd65f61d3ab --- /dev/null +++ b/docs/apidiffs/1.47.0_vs_1.46.0/opentelemetry-extension-trace-propagators.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of opentelemetry-extension-trace-propagators-1.47.0.jar against opentelemetry-extension-trace-propagators-1.46.0.jar +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.47.0_vs_1.46.0/opentelemetry-opentracing-shim.txt b/docs/apidiffs/1.47.0_vs_1.46.0/opentelemetry-opentracing-shim.txt new file mode 100644 index 00000000000..a95c9ed9422 --- /dev/null +++ b/docs/apidiffs/1.47.0_vs_1.46.0/opentelemetry-opentracing-shim.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of opentelemetry-opentracing-shim-1.47.0.jar against opentelemetry-opentracing-shim-1.46.0.jar +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.47.0_vs_1.46.0/opentelemetry-sdk-common.txt b/docs/apidiffs/1.47.0_vs_1.46.0/opentelemetry-sdk-common.txt new file mode 100644 index 00000000000..490ef238eff --- /dev/null +++ b/docs/apidiffs/1.47.0_vs_1.46.0/opentelemetry-sdk-common.txt @@ -0,0 +1,8 @@ +Comparing source compatibility of opentelemetry-sdk-common-1.47.0.jar against opentelemetry-sdk-common-1.46.0.jar +**** MODIFIED CLASS: PUBLIC ABSTRACT io.opentelemetry.sdk.common.export.RetryPolicy (not serializable) + === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 + +++* NEW METHOD: PUBLIC(+) ABSTRACT(+) java.util.function.Predicate getRetryExceptionPredicate() + +++ NEW ANNOTATION: javax.annotation.Nullable +**** MODIFIED CLASS: PUBLIC ABSTRACT STATIC io.opentelemetry.sdk.common.export.RetryPolicy$RetryPolicyBuilder (not serializable) + === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 + +++* NEW METHOD: PUBLIC(+) ABSTRACT(+) io.opentelemetry.sdk.common.export.RetryPolicy$RetryPolicyBuilder setRetryExceptionPredicate(java.util.function.Predicate) diff --git a/docs/apidiffs/1.47.0_vs_1.46.0/opentelemetry-sdk-extension-autoconfigure-spi.txt b/docs/apidiffs/1.47.0_vs_1.46.0/opentelemetry-sdk-extension-autoconfigure-spi.txt new file mode 100644 index 00000000000..a6c5cb9acba --- /dev/null +++ b/docs/apidiffs/1.47.0_vs_1.46.0/opentelemetry-sdk-extension-autoconfigure-spi.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of opentelemetry-sdk-extension-autoconfigure-spi-1.47.0.jar against opentelemetry-sdk-extension-autoconfigure-spi-1.46.0.jar +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.47.0_vs_1.46.0/opentelemetry-sdk-extension-autoconfigure.txt b/docs/apidiffs/1.47.0_vs_1.46.0/opentelemetry-sdk-extension-autoconfigure.txt new file mode 100644 index 00000000000..e7008c43b4f --- /dev/null +++ b/docs/apidiffs/1.47.0_vs_1.46.0/opentelemetry-sdk-extension-autoconfigure.txt @@ -0,0 +1,7 @@ +Comparing source compatibility of opentelemetry-sdk-extension-autoconfigure-1.47.0.jar against opentelemetry-sdk-extension-autoconfigure-1.46.0.jar ++++ NEW CLASS: PUBLIC(+) FINAL(+) io.opentelemetry.sdk.autoconfigure.EnvironmentResourceProvider (not serializable) + +++ CLASS FILE FORMAT VERSION: 52.0 <- n.a. + +++ NEW SUPERCLASS: java.lang.Object + +++ NEW CONSTRUCTOR: PUBLIC(+) EnvironmentResourceProvider() + +++ NEW METHOD: PUBLIC(+) io.opentelemetry.sdk.resources.Resource createResource(io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties) + +++ NEW METHOD: PUBLIC(+) int order() diff --git a/docs/apidiffs/1.47.0_vs_1.46.0/opentelemetry-sdk-extension-jaeger-remote-sampler.txt b/docs/apidiffs/1.47.0_vs_1.46.0/opentelemetry-sdk-extension-jaeger-remote-sampler.txt new file mode 100644 index 00000000000..1823240ad66 --- /dev/null +++ b/docs/apidiffs/1.47.0_vs_1.46.0/opentelemetry-sdk-extension-jaeger-remote-sampler.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of opentelemetry-sdk-extension-jaeger-remote-sampler-1.47.0.jar against opentelemetry-sdk-extension-jaeger-remote-sampler-1.46.0.jar +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.47.0_vs_1.46.0/opentelemetry-sdk-logs.txt b/docs/apidiffs/1.47.0_vs_1.46.0/opentelemetry-sdk-logs.txt new file mode 100644 index 00000000000..946e9a23b19 --- /dev/null +++ b/docs/apidiffs/1.47.0_vs_1.46.0/opentelemetry-sdk-logs.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of opentelemetry-sdk-logs-1.47.0.jar against opentelemetry-sdk-logs-1.46.0.jar +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.47.0_vs_1.46.0/opentelemetry-sdk-metrics.txt b/docs/apidiffs/1.47.0_vs_1.46.0/opentelemetry-sdk-metrics.txt new file mode 100644 index 00000000000..5a524d47f40 --- /dev/null +++ b/docs/apidiffs/1.47.0_vs_1.46.0/opentelemetry-sdk-metrics.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of opentelemetry-sdk-metrics-1.47.0.jar against opentelemetry-sdk-metrics-1.46.0.jar +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.47.0_vs_1.46.0/opentelemetry-sdk-testing.txt b/docs/apidiffs/1.47.0_vs_1.46.0/opentelemetry-sdk-testing.txt new file mode 100644 index 00000000000..37ea274d77d --- /dev/null +++ b/docs/apidiffs/1.47.0_vs_1.46.0/opentelemetry-sdk-testing.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of opentelemetry-sdk-testing-1.47.0.jar against opentelemetry-sdk-testing-1.46.0.jar +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.47.0_vs_1.46.0/opentelemetry-sdk-trace.txt b/docs/apidiffs/1.47.0_vs_1.46.0/opentelemetry-sdk-trace.txt new file mode 100644 index 00000000000..5a9f54c51ca --- /dev/null +++ b/docs/apidiffs/1.47.0_vs_1.46.0/opentelemetry-sdk-trace.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of opentelemetry-sdk-trace-1.47.0.jar against opentelemetry-sdk-trace-1.46.0.jar +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.47.0_vs_1.46.0/opentelemetry-sdk.txt b/docs/apidiffs/1.47.0_vs_1.46.0/opentelemetry-sdk.txt new file mode 100644 index 00000000000..7e212768780 --- /dev/null +++ b/docs/apidiffs/1.47.0_vs_1.46.0/opentelemetry-sdk.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of opentelemetry-sdk-1.47.0.jar against opentelemetry-sdk-1.46.0.jar +No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-api.txt b/docs/apidiffs/current_vs_latest/opentelemetry-api.txt index 58b43aee602..ef68fdedeeb 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-api.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-api.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of opentelemetry-api-1.47.0-SNAPSHOT.jar against opentelemetry-api-1.46.0.jar +Comparing source compatibility of opentelemetry-api-1.48.0-SNAPSHOT.jar against opentelemetry-api-1.47.0.jar No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-context.txt b/docs/apidiffs/current_vs_latest/opentelemetry-context.txt index 3e2bde1a9e0..235a52aabe8 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-context.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-context.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of opentelemetry-context-1.47.0-SNAPSHOT.jar against opentelemetry-context-1.46.0.jar +Comparing source compatibility of opentelemetry-context-1.48.0-SNAPSHOT.jar against opentelemetry-context-1.47.0.jar No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-common.txt b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-common.txt index 6f7d58ae7e3..aec4d1f1e22 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-common.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-common.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of opentelemetry-exporter-common-1.47.0-SNAPSHOT.jar against opentelemetry-exporter-common-1.46.0.jar +Comparing source compatibility of opentelemetry-exporter-common-1.48.0-SNAPSHOT.jar against opentelemetry-exporter-common-1.47.0.jar No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-logging-otlp.txt b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-logging-otlp.txt index 7bf18cc7e8b..9d2c3d079cc 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-logging-otlp.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-logging-otlp.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of opentelemetry-exporter-logging-otlp-1.47.0-SNAPSHOT.jar against opentelemetry-exporter-logging-otlp-1.46.0.jar +Comparing source compatibility of opentelemetry-exporter-logging-otlp-1.48.0-SNAPSHOT.jar against opentelemetry-exporter-logging-otlp-1.47.0.jar No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-logging.txt b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-logging.txt index c6ab761791a..043fcef4f5a 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-logging.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-logging.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of opentelemetry-exporter-logging-1.47.0-SNAPSHOT.jar against opentelemetry-exporter-logging-1.46.0.jar +Comparing source compatibility of opentelemetry-exporter-logging-1.48.0-SNAPSHOT.jar against opentelemetry-exporter-logging-1.47.0.jar No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-otlp-common.txt b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-otlp-common.txt index 429d75ec41b..a7a3f42c060 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-otlp-common.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-otlp-common.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of opentelemetry-exporter-otlp-common-1.47.0-SNAPSHOT.jar against opentelemetry-exporter-otlp-common-1.46.0.jar +Comparing source compatibility of opentelemetry-exporter-otlp-common-1.48.0-SNAPSHOT.jar against opentelemetry-exporter-otlp-common-1.47.0.jar No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-otlp.txt b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-otlp.txt index c56b64745c4..27040235c7a 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-otlp.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-otlp.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of opentelemetry-exporter-otlp-1.47.0-SNAPSHOT.jar against opentelemetry-exporter-otlp-1.46.0.jar +Comparing source compatibility of opentelemetry-exporter-otlp-1.48.0-SNAPSHOT.jar against opentelemetry-exporter-otlp-1.47.0.jar No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-sender-grpc-managed-channel.txt b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-sender-grpc-managed-channel.txt index f61af313c46..f00bcb039d8 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-sender-grpc-managed-channel.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-sender-grpc-managed-channel.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of opentelemetry-exporter-sender-grpc-managed-channel-1.47.0-SNAPSHOT.jar against opentelemetry-exporter-sender-grpc-managed-channel-1.46.0.jar +Comparing source compatibility of opentelemetry-exporter-sender-grpc-managed-channel-1.48.0-SNAPSHOT.jar against opentelemetry-exporter-sender-grpc-managed-channel-1.47.0.jar No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-sender-jdk.txt b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-sender-jdk.txt index 49be6b8165d..eed06090d2e 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-sender-jdk.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-sender-jdk.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of opentelemetry-exporter-sender-jdk-1.47.0-SNAPSHOT.jar against opentelemetry-exporter-sender-jdk-1.46.0.jar +Comparing source compatibility of opentelemetry-exporter-sender-jdk-1.48.0-SNAPSHOT.jar against opentelemetry-exporter-sender-jdk-1.47.0.jar No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-sender-okhttp.txt b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-sender-okhttp.txt index 79e4a63d947..bc70f8e0ea5 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-sender-okhttp.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-sender-okhttp.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of opentelemetry-exporter-sender-okhttp-1.47.0-SNAPSHOT.jar against opentelemetry-exporter-sender-okhttp-1.46.0.jar +Comparing source compatibility of opentelemetry-exporter-sender-okhttp-1.48.0-SNAPSHOT.jar against opentelemetry-exporter-sender-okhttp-1.47.0.jar No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-zipkin.txt b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-zipkin.txt index 5ab882bda63..1e8e580b7ad 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-zipkin.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-zipkin.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of opentelemetry-exporter-zipkin-1.47.0-SNAPSHOT.jar against opentelemetry-exporter-zipkin-1.46.0.jar +Comparing source compatibility of opentelemetry-exporter-zipkin-1.48.0-SNAPSHOT.jar against opentelemetry-exporter-zipkin-1.47.0.jar No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-extension-kotlin.txt b/docs/apidiffs/current_vs_latest/opentelemetry-extension-kotlin.txt index 3efd311fda2..849d729b4a4 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-extension-kotlin.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-extension-kotlin.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of opentelemetry-extension-kotlin-1.47.0-SNAPSHOT.jar against opentelemetry-extension-kotlin-1.46.0.jar +Comparing source compatibility of opentelemetry-extension-kotlin-1.48.0-SNAPSHOT.jar against opentelemetry-extension-kotlin-1.47.0.jar No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-extension-trace-propagators.txt b/docs/apidiffs/current_vs_latest/opentelemetry-extension-trace-propagators.txt index e6caaa018b9..9fb65a14f73 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-extension-trace-propagators.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-extension-trace-propagators.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of opentelemetry-extension-trace-propagators-1.47.0-SNAPSHOT.jar against opentelemetry-extension-trace-propagators-1.46.0.jar +Comparing source compatibility of opentelemetry-extension-trace-propagators-1.48.0-SNAPSHOT.jar against opentelemetry-extension-trace-propagators-1.47.0.jar No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-opentracing-shim.txt b/docs/apidiffs/current_vs_latest/opentelemetry-opentracing-shim.txt index 320013d7fc6..a6f559812df 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-opentracing-shim.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-opentracing-shim.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of opentelemetry-opentracing-shim-1.47.0-SNAPSHOT.jar against opentelemetry-opentracing-shim-1.46.0.jar +Comparing source compatibility of opentelemetry-opentracing-shim-1.48.0-SNAPSHOT.jar against opentelemetry-opentracing-shim-1.47.0.jar No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-common.txt b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-common.txt index 7ee412b4334..7c0297328f7 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-common.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-common.txt @@ -1,8 +1,2 @@ -Comparing source compatibility of opentelemetry-sdk-common-1.47.0-SNAPSHOT.jar against opentelemetry-sdk-common-1.46.0.jar -**** MODIFIED CLASS: PUBLIC ABSTRACT io.opentelemetry.sdk.common.export.RetryPolicy (not serializable) - === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 - +++* NEW METHOD: PUBLIC(+) ABSTRACT(+) java.util.function.Predicate getRetryExceptionPredicate() - +++ NEW ANNOTATION: javax.annotation.Nullable -**** MODIFIED CLASS: PUBLIC ABSTRACT STATIC io.opentelemetry.sdk.common.export.RetryPolicy$RetryPolicyBuilder (not serializable) - === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 - +++* NEW METHOD: PUBLIC(+) ABSTRACT(+) io.opentelemetry.sdk.common.export.RetryPolicy$RetryPolicyBuilder setRetryExceptionPredicate(java.util.function.Predicate) +Comparing source compatibility of opentelemetry-sdk-common-1.48.0-SNAPSHOT.jar against opentelemetry-sdk-common-1.47.0.jar +No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-extension-autoconfigure-spi.txt b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-extension-autoconfigure-spi.txt index 56525b7393e..57915cb9be6 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-extension-autoconfigure-spi.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-extension-autoconfigure-spi.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of opentelemetry-sdk-extension-autoconfigure-spi-1.47.0-SNAPSHOT.jar against opentelemetry-sdk-extension-autoconfigure-spi-1.46.0.jar +Comparing source compatibility of opentelemetry-sdk-extension-autoconfigure-spi-1.48.0-SNAPSHOT.jar against opentelemetry-sdk-extension-autoconfigure-spi-1.47.0.jar No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-extension-autoconfigure.txt b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-extension-autoconfigure.txt index 2eb91135544..9cba7e68928 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-extension-autoconfigure.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-extension-autoconfigure.txt @@ -1,7 +1,2 @@ -Comparing source compatibility of opentelemetry-sdk-extension-autoconfigure-1.47.0-SNAPSHOT.jar against opentelemetry-sdk-extension-autoconfigure-1.46.0.jar -+++ NEW CLASS: PUBLIC(+) FINAL(+) io.opentelemetry.sdk.autoconfigure.EnvironmentResourceProvider (not serializable) - +++ CLASS FILE FORMAT VERSION: 52.0 <- n.a. - +++ NEW SUPERCLASS: java.lang.Object - +++ NEW CONSTRUCTOR: PUBLIC(+) EnvironmentResourceProvider() - +++ NEW METHOD: PUBLIC(+) io.opentelemetry.sdk.resources.Resource createResource(io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties) - +++ NEW METHOD: PUBLIC(+) int order() +Comparing source compatibility of opentelemetry-sdk-extension-autoconfigure-1.48.0-SNAPSHOT.jar against opentelemetry-sdk-extension-autoconfigure-1.47.0.jar +No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-extension-jaeger-remote-sampler.txt b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-extension-jaeger-remote-sampler.txt index 71b9918c230..2f6326485f7 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-extension-jaeger-remote-sampler.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-extension-jaeger-remote-sampler.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of opentelemetry-sdk-extension-jaeger-remote-sampler-1.47.0-SNAPSHOT.jar against opentelemetry-sdk-extension-jaeger-remote-sampler-1.46.0.jar +Comparing source compatibility of opentelemetry-sdk-extension-jaeger-remote-sampler-1.48.0-SNAPSHOT.jar against opentelemetry-sdk-extension-jaeger-remote-sampler-1.47.0.jar No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-logs.txt b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-logs.txt index aa0ae633c34..1fc34295832 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-logs.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-logs.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of opentelemetry-sdk-logs-1.47.0-SNAPSHOT.jar against opentelemetry-sdk-logs-1.46.0.jar +Comparing source compatibility of opentelemetry-sdk-logs-1.48.0-SNAPSHOT.jar against opentelemetry-sdk-logs-1.47.0.jar No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-metrics.txt b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-metrics.txt index b512a547045..3cfe387fe8f 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-metrics.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-metrics.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of opentelemetry-sdk-metrics-1.47.0-SNAPSHOT.jar against opentelemetry-sdk-metrics-1.46.0.jar +Comparing source compatibility of opentelemetry-sdk-metrics-1.48.0-SNAPSHOT.jar against opentelemetry-sdk-metrics-1.47.0.jar No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-testing.txt b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-testing.txt index 07403164be2..d0bdcc79192 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-testing.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-testing.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of opentelemetry-sdk-testing-1.47.0-SNAPSHOT.jar against opentelemetry-sdk-testing-1.46.0.jar +Comparing source compatibility of opentelemetry-sdk-testing-1.48.0-SNAPSHOT.jar against opentelemetry-sdk-testing-1.47.0.jar No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-trace.txt b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-trace.txt index 4ce59781d9c..48f428554cc 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-trace.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-trace.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of opentelemetry-sdk-trace-1.47.0-SNAPSHOT.jar against opentelemetry-sdk-trace-1.46.0.jar +Comparing source compatibility of opentelemetry-sdk-trace-1.48.0-SNAPSHOT.jar against opentelemetry-sdk-trace-1.47.0.jar No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-sdk.txt b/docs/apidiffs/current_vs_latest/opentelemetry-sdk.txt index a9d84bd5ebe..42ee3328a83 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-sdk.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-sdk.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of opentelemetry-sdk-1.47.0-SNAPSHOT.jar against opentelemetry-sdk-1.46.0.jar +Comparing source compatibility of opentelemetry-sdk-1.48.0-SNAPSHOT.jar against opentelemetry-sdk-1.47.0.jar No changes. \ No newline at end of file From 89a830cfb4e0636274c5308291f9d42d0ac5a317 Mon Sep 17 00:00:00 2001 From: Trask Stalnaker Date: Sun, 9 Feb 2025 11:06:49 -0800 Subject: [PATCH 802/901] Add CLOMonitor exemption for Artifact Hub badge (#7091) --- .clomonitor.yml | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 .clomonitor.yml diff --git a/.clomonitor.yml b/.clomonitor.yml new file mode 100644 index 00000000000..7353049785b --- /dev/null +++ b/.clomonitor.yml @@ -0,0 +1,3 @@ +exemptions: + - check: artifacthub_badge + reason: "Artifact Hub doesn't support Java packages" From 92b089ab2c06846aea3e2cd4e14cbee71608f715 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sun, 9 Feb 2025 14:42:14 -0800 Subject: [PATCH 803/901] chore(deps): update github/codeql-action action to v3.28.9 (#7081) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/codeql.yml | 4 ++-- .github/workflows/ossf-scorecard.yml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index 677f40b48ae..6bec145e694 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -37,7 +37,7 @@ jobs: uses: gradle/actions/setup-gradle@94baf225fe0a508e581a564467443d0e2379123b # v4.3.0 - name: Initialize CodeQL - uses: github/codeql-action/init@dd746615b3b9d728a6a37ca2045b68ca76d4841a # v3.28.8 + uses: github/codeql-action/init@9e8d0789d4a0fa9ceb6b1738f7e269594bdd67f0 # v3.28.9 with: languages: java, actions # using "latest" helps to keep up with the latest Kotlin support @@ -51,4 +51,4 @@ jobs: run: ./gradlew assemble --no-build-cache --no-daemon - name: Perform CodeQL analysis - uses: github/codeql-action/analyze@dd746615b3b9d728a6a37ca2045b68ca76d4841a # v3.28.8 + uses: github/codeql-action/analyze@9e8d0789d4a0fa9ceb6b1738f7e269594bdd67f0 # v3.28.9 diff --git a/.github/workflows/ossf-scorecard.yml b/.github/workflows/ossf-scorecard.yml index 0a306aa481d..114c992b9ac 100644 --- a/.github/workflows/ossf-scorecard.yml +++ b/.github/workflows/ossf-scorecard.yml @@ -42,6 +42,6 @@ jobs: # Upload the results to GitHub's code scanning dashboard (optional). # Commenting out will disable upload of results to your repo's Code Scanning dashboard - name: "Upload to code-scanning" - uses: github/codeql-action/upload-sarif@dd746615b3b9d728a6a37ca2045b68ca76d4841a # v3.28.8 + uses: github/codeql-action/upload-sarif@9e8d0789d4a0fa9ceb6b1738f7e269594bdd67f0 # v3.28.9 with: sarif_file: results.sarif From 06449488ce50ee5c66a5bed7d5bcd7cec6fb9724 Mon Sep 17 00:00:00 2001 From: StepSecurity Bot Date: Mon, 10 Feb 2025 08:31:39 -0800 Subject: [PATCH 804/901] [StepSecurity] Apply security best practices (#7088) Signed-off-by: StepSecurity Bot --- .github/workflows/backport.yml | 2 +- .github/workflows/benchmark-tags.yml | 8 +++---- .github/workflows/benchmark.yml | 8 +++---- .../build-tracecontext-testsuite.yml | 6 ++--- .github/workflows/build.yml | 22 +++++++++---------- .../docker-test-containers-daily.yml | 2 +- .../workflows/generate-post-release-pr.yml | 6 ++--- .../workflows/gradle-wrapper-validation.yml | 4 ++-- .../issue-management-feedback-label.yml | 2 +- .../issue-management-stale-action.yml | 2 +- .../owasp-dependency-check-daily.yml | 8 +++---- .github/workflows/prepare-patch-release.yml | 2 +- .github/workflows/prepare-release-branch.yml | 6 ++--- .github/workflows/release.yml | 14 ++++++------ .../reusable-markdown-link-check.yml | 4 ++-- .github/workflows/reusable-misspell-check.yml | 2 +- .../reusable-open-issue-on-failure.yml | 2 +- .../tracecontext/docker/Dockerfile | 4 ++-- 18 files changed, 52 insertions(+), 52 deletions(-) diff --git a/.github/workflows/backport.yml b/.github/workflows/backport.yml index 54b5b285097..d796fc9a663 100644 --- a/.github/workflows/backport.yml +++ b/.github/workflows/backport.yml @@ -21,7 +21,7 @@ jobs: exit 1 fi - - uses: actions/checkout@v4 + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 with: # history is needed to run git cherry-pick below fetch-depth: 0 diff --git a/.github/workflows/benchmark-tags.yml b/.github/workflows/benchmark-tags.yml index 04f5ccdd88d..8cef6b9fcaa 100644 --- a/.github/workflows/benchmark-tags.yml +++ b/.github/workflows/benchmark-tags.yml @@ -44,19 +44,19 @@ jobs: - v1.30.0 - v1.30.1 steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 with: ref: ${{ matrix.tag-version }} - id: setup-java name: Set up Java for build - uses: actions/setup-java@v4 + uses: actions/setup-java@3a4f6e1af504cf6a31855fa899c6aa5355ba6c12 # v4.7.0 with: distribution: temurin java-version: 17 - name: Set up gradle - uses: gradle/actions/setup-gradle@v4 + uses: gradle/actions/setup-gradle@94baf225fe0a508e581a564467443d0e2379123b # v4.3.0 - name: Run jmh run: ./gradlew jmhJar @@ -66,7 +66,7 @@ jobs: java -jar libs/opentelemetry-sdk-trace-*-jmh.jar -rf json SpanBenchmark SpanPipelineBenchmark ExporterBenchmark - name: Store benchmark results - uses: benchmark-action/github-action-benchmark@v1 + uses: benchmark-action/github-action-benchmark@d48d326b4ca9ba73ca0cd0d59f108f9e02a381c7 # v1.20.4 with: tool: 'jmh' output-file-path: sdk/trace/build/jmh-result.json diff --git a/.github/workflows/benchmark.yml b/.github/workflows/benchmark.yml index 442f22e0a09..d8688258431 100644 --- a/.github/workflows/benchmark.yml +++ b/.github/workflows/benchmark.yml @@ -16,17 +16,17 @@ jobs: runs-on: self-hosted timeout-minutes: 10 steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - id: setup-java name: Set up Java for build - uses: actions/setup-java@v4 + uses: actions/setup-java@3a4f6e1af504cf6a31855fa899c6aa5355ba6c12 # v4.7.0 with: distribution: temurin java-version: 17 - name: Set up gradle - uses: gradle/actions/setup-gradle@v4 + uses: gradle/actions/setup-gradle@94baf225fe0a508e581a564467443d0e2379123b # v4.3.0 - name: Run jmh run: ./gradlew jmhJar @@ -36,7 +36,7 @@ jobs: java -jar libs/opentelemetry-sdk-trace-*-jmh.jar -rf json SpanBenchmark SpanPipelineBenchmark ExporterBenchmark - name: Store benchmark results - uses: benchmark-action/github-action-benchmark@v1 + uses: benchmark-action/github-action-benchmark@d48d326b4ca9ba73ca0cd0d59f108f9e02a381c7 # v1.20.4 with: tool: 'jmh' output-file-path: sdk/trace/build/jmh-result.json diff --git a/.github/workflows/build-tracecontext-testsuite.yml b/.github/workflows/build-tracecontext-testsuite.yml index 236e6ad8707..7ee35f773e6 100644 --- a/.github/workflows/build-tracecontext-testsuite.yml +++ b/.github/workflows/build-tracecontext-testsuite.yml @@ -19,17 +19,17 @@ jobs: packages: write runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - name: Login to GitHub package registry - uses: docker/login-action@v3 + uses: docker/login-action@9780b0c442fbb1117ed29e0efdff1e18412f7567 # v3.3.0 with: registry: ghcr.io username: ${{ github.repository_owner }} password: ${{ secrets.GITHUB_TOKEN }} - name: Build and push - uses: docker/build-push-action@v6 + uses: docker/build-push-action@ca877d9245402d1537745e0e356eab47c3520991 # v6.13.0 with: context: integration-tests/tracecontext/docker push: true diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 7244872f30f..2bbcf52f371 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -49,24 +49,24 @@ jobs: - os: macos-13 test-java-version: 23 steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - id: setup-java-test name: Set up Java ${{ matrix.test-java-version }} for tests - uses: actions/setup-java@v4 + uses: actions/setup-java@3a4f6e1af504cf6a31855fa899c6aa5355ba6c12 # v4.7.0 with: distribution: temurin java-version: ${{ matrix.test-java-version }} - id: setup-java name: Set up Java for build - uses: actions/setup-java@v4 + uses: actions/setup-java@3a4f6e1af504cf6a31855fa899c6aa5355ba6c12 # v4.7.0 with: distribution: temurin java-version: 17 - name: Set up gradle - uses: gradle/actions/setup-gradle@v4 + uses: gradle/actions/setup-gradle@94baf225fe0a508e581a564467443d0e2379123b # v4.3.0 - name: Build run: > ./gradlew build @@ -96,12 +96,12 @@ jobs: exit 1 fi - - uses: codecov/codecov-action@v5 + - uses: codecov/codecov-action@13ce06bfc6bbe3ecf90edbbf1bc32fe5978ca1d3 # v5.3.1 if: ${{ matrix.coverage }} env: CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} - - uses: actions/upload-artifact@v4 + - uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0 if: ${{ matrix.coverage }} with: name: coverage-report @@ -132,17 +132,17 @@ jobs: needs: build runs-on: ubuntu-24.04 steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - id: setup-java name: Set up Java - uses: actions/setup-java@v4 + uses: actions/setup-java@3a4f6e1af504cf6a31855fa899c6aa5355ba6c12 # v4.7.0 with: distribution: temurin java-version: 17 - name: Set up gradle - uses: gradle/actions/setup-gradle@v4 + uses: gradle/actions/setup-gradle@94baf225fe0a508e581a564467443d0e2379123b # v4.3.0 # skipping release branches because the versions in those branches are not snapshots # (also this skips pull requests) if: ${{ github.ref_name == 'main' && github.repository == 'open-telemetry/opentelemetry-java' }} @@ -160,8 +160,8 @@ jobs: build-graal: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 - - uses: graalvm/setup-graalvm@v1 + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + - uses: graalvm/setup-graalvm@aafbedb8d382ed0ca6167d3a051415f20c859274 # v1.2.8 with: # TODO(jack-berg): Which versions do we need to test? Should we use a matrix scheme? java-version: '21' diff --git a/.github/workflows/docker-test-containers-daily.yml b/.github/workflows/docker-test-containers-daily.yml index 190737d035b..63721df8e90 100644 --- a/.github/workflows/docker-test-containers-daily.yml +++ b/.github/workflows/docker-test-containers-daily.yml @@ -27,7 +27,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Docker login - uses: docker/login-action@v3 + uses: docker/login-action@9780b0c442fbb1117ed29e0efdff1e18412f7567 # v3.3.0 with: registry: ghcr.io username: ${{ github.repository_owner }} diff --git a/.github/workflows/generate-post-release-pr.yml b/.github/workflows/generate-post-release-pr.yml index 0087219076d..3f48db50c42 100644 --- a/.github/workflows/generate-post-release-pr.yml +++ b/.github/workflows/generate-post-release-pr.yml @@ -6,7 +6,7 @@ jobs: prereqs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - name: Verify prerequisites run: | if [[ $GITHUB_REF_NAME != main ]]; then @@ -19,10 +19,10 @@ jobs: needs: - prereqs steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - id: setup-java name: Set up Java for build - uses: actions/setup-java@v4 + uses: actions/setup-java@3a4f6e1af504cf6a31855fa899c6aa5355ba6c12 # v4.7.0 with: distribution: temurin java-version: 17 diff --git a/.github/workflows/gradle-wrapper-validation.yml b/.github/workflows/gradle-wrapper-validation.yml index 519bbd22f85..24a86ddecd2 100644 --- a/.github/workflows/gradle-wrapper-validation.yml +++ b/.github/workflows/gradle-wrapper-validation.yml @@ -11,6 +11,6 @@ jobs: gradle-wrapper-validation: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - - uses: gradle/actions/wrapper-validation@v4.3.0 + - uses: gradle/actions/wrapper-validation@94baf225fe0a508e581a564467443d0e2379123b # v4.3.0 diff --git a/.github/workflows/issue-management-feedback-label.yml b/.github/workflows/issue-management-feedback-label.yml index dfbba807271..2bd368d2be9 100644 --- a/.github/workflows/issue-management-feedback-label.yml +++ b/.github/workflows/issue-management-feedback-label.yml @@ -17,7 +17,7 @@ jobs: github.event.comment.user.login == github.event.issue.user.login runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - name: Remove label env: diff --git a/.github/workflows/issue-management-stale-action.yml b/.github/workflows/issue-management-stale-action.yml index d222695559b..44fd26028c7 100644 --- a/.github/workflows/issue-management-stale-action.yml +++ b/.github/workflows/issue-management-stale-action.yml @@ -16,7 +16,7 @@ jobs: pull-requests: write # for actions/stale to close stale PRs runs-on: ubuntu-latest steps: - - uses: actions/stale@v9 + - uses: actions/stale@5bef64f19d7facfb25b37b414482c7164d639639 # v9.1.0 with: repo-token: ${{ secrets.GITHUB_TOKEN }} days-before-stale: 7 diff --git a/.github/workflows/owasp-dependency-check-daily.yml b/.github/workflows/owasp-dependency-check-daily.yml index 5433e10bb08..eeff9cc0df2 100644 --- a/.github/workflows/owasp-dependency-check-daily.yml +++ b/.github/workflows/owasp-dependency-check-daily.yml @@ -14,21 +14,21 @@ jobs: analyze: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - - uses: actions/setup-java@v4 + - uses: actions/setup-java@3a4f6e1af504cf6a31855fa899c6aa5355ba6c12 # v4.7.0 with: distribution: temurin java-version: 17 - name: Set up gradle - uses: gradle/actions/setup-gradle@v4 + uses: gradle/actions/setup-gradle@94baf225fe0a508e581a564467443d0e2379123b # v4.3.0 - name: Check dependencies run: ./gradlew dependencyCheckAnalyze - name: Upload report if: always() - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0 with: path: javaagent/build/reports diff --git a/.github/workflows/prepare-patch-release.yml b/.github/workflows/prepare-patch-release.yml index 5da1a4f8e2c..f086cdbe7ef 100644 --- a/.github/workflows/prepare-patch-release.yml +++ b/.github/workflows/prepare-patch-release.yml @@ -6,7 +6,7 @@ jobs: prepare-patch-release: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - run: | if [[ ! $GITHUB_REF_NAME =~ ^release/v[0-9]+\.[0-9]+\.x$ ]]; then diff --git a/.github/workflows/prepare-release-branch.yml b/.github/workflows/prepare-release-branch.yml index 63d4488e850..c377a5698d5 100644 --- a/.github/workflows/prepare-release-branch.yml +++ b/.github/workflows/prepare-release-branch.yml @@ -6,7 +6,7 @@ jobs: prereqs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - name: Verify prerequisites run: | @@ -25,7 +25,7 @@ jobs: needs: - prereqs steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - name: Create release branch run: | @@ -74,7 +74,7 @@ jobs: needs: - prereqs steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - name: Set environment variables run: | diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 7fea632b3d1..2f9654b82b8 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -14,15 +14,15 @@ jobs: exit 1 fi - - uses: actions/checkout@v4 + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - - uses: actions/setup-java@v4 + - uses: actions/setup-java@3a4f6e1af504cf6a31855fa899c6aa5355ba6c12 # v4.7.0 with: distribution: temurin java-version: 17 - name: Set up gradle - uses: gradle/actions/setup-gradle@v4 + uses: gradle/actions/setup-gradle@94baf225fe0a508e581a564467443d0e2379123b # v4.3.0 - name: Build and publish artifacts run: ./gradlew assemble publishToSonatype closeAndReleaseSonatypeStagingRepository @@ -59,7 +59,7 @@ jobs: # check out main branch to verify there won't be problems with merging the change log # at the end of this workflow - - uses: actions/checkout@v4 + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 with: ref: main @@ -74,7 +74,7 @@ jobs: fi # back to the release branch - - uses: actions/checkout@v4 + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 with: # tags are needed for the generate-release-contributors.sh script fetch-depth: 0 @@ -130,7 +130,7 @@ jobs: needs: - release steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - name: Copy change log section from release branch env: @@ -139,7 +139,7 @@ jobs: sed -n "0,/^## Version $VERSION /d;/^## Version /q;p" CHANGELOG.md \ > /tmp/changelog-section.md - - uses: actions/checkout@v4 + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 with: ref: main diff --git a/.github/workflows/reusable-markdown-link-check.yml b/.github/workflows/reusable-markdown-link-check.yml index d1b6b7c0e7b..3756f98a790 100644 --- a/.github/workflows/reusable-markdown-link-check.yml +++ b/.github/workflows/reusable-markdown-link-check.yml @@ -10,9 +10,9 @@ jobs: markdown-link-check: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - - uses: lycheeverse/lychee-action@v2 + - uses: lycheeverse/lychee-action@f613c4a64e50d792e0b31ec34bbcbba12263c6a6 # v2.3.0 with: # excluding links to pull requests and issues is done for performance args: > diff --git a/.github/workflows/reusable-misspell-check.yml b/.github/workflows/reusable-misspell-check.yml index 28eb76c5bc9..76d361c777b 100644 --- a/.github/workflows/reusable-misspell-check.yml +++ b/.github/workflows/reusable-misspell-check.yml @@ -10,7 +10,7 @@ jobs: misspell-check: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - name: Install misspell run: | diff --git a/.github/workflows/reusable-open-issue-on-failure.yml b/.github/workflows/reusable-open-issue-on-failure.yml index 309b7119ed0..672113d0d2e 100644 --- a/.github/workflows/reusable-open-issue-on-failure.yml +++ b/.github/workflows/reusable-open-issue-on-failure.yml @@ -7,7 +7,7 @@ jobs: open-issue: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - name: Open issue env: diff --git a/integration-tests/tracecontext/docker/Dockerfile b/integration-tests/tracecontext/docker/Dockerfile index fc6dd4e7cea..f54a9ba2cea 100644 --- a/integration-tests/tracecontext/docker/Dockerfile +++ b/integration-tests/tracecontext/docker/Dockerfile @@ -1,4 +1,4 @@ -FROM python:3 AS build +FROM python:3@sha256:589ed6659c0e4aac182f309131cd35e85452d21072570b1f6abc45b7687093a3 AS build # Main branch SHA as of April-1-2021 ARG TRACECONTEXT_GIT_TAG="dcd3ad9b7d6ac36f70ff3739874b73c11b0302a1" @@ -11,7 +11,7 @@ RUN unzip trace-context.zip RUN rm trace-context.zip RUN mv trace-context-${TRACECONTEXT_GIT_TAG}/test /tracecontext-testsuite -FROM python:3-slim +FROM python:3-slim@sha256:ae9f9ac89467077ed1efefb6d9042132d28134ba201b2820227d46c9effd3174 RUN pip install aiohttp From 00f00433f3e727d2db85a7fc0173afe15c4b1504 Mon Sep 17 00:00:00 2001 From: jack-berg <34418638+jack-berg@users.noreply.github.com> Date: Mon, 10 Feb 2025 11:40:56 -0600 Subject: [PATCH 805/901] Continue limiting workflow permissions (#7092) --- .github/workflows/build.yml | 3 +++ .github/workflows/generate-post-release-pr.yml | 5 +++++ .github/workflows/prepare-patch-release.yml | 5 +++++ .github/workflows/prepare-release-branch.yml | 7 +++++++ .github/workflows/release.yml | 7 +++++++ .github/workflows/reusable-open-issue-on-failure.yml | 6 ++++++ 6 files changed, 33 insertions(+) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 2bbcf52f371..8dad8184561 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -12,6 +12,9 @@ concurrency: group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.sha }} cancel-in-progress: true +permissions: + contents: read + jobs: build: name: Build diff --git a/.github/workflows/generate-post-release-pr.yml b/.github/workflows/generate-post-release-pr.yml index 3f48db50c42..b6b087537d8 100644 --- a/.github/workflows/generate-post-release-pr.yml +++ b/.github/workflows/generate-post-release-pr.yml @@ -2,6 +2,9 @@ name: Generate Post-Release PR on: workflow_dispatch: +permissions: + contents: read + jobs: prereqs: runs-on: ubuntu-latest @@ -15,6 +18,8 @@ jobs: fi create-pull-request-against-main: + permissions: + contents: write # for git push to PR branch runs-on: ubuntu-latest needs: - prereqs diff --git a/.github/workflows/prepare-patch-release.yml b/.github/workflows/prepare-patch-release.yml index f086cdbe7ef..bd4fe8cb7d4 100644 --- a/.github/workflows/prepare-patch-release.yml +++ b/.github/workflows/prepare-patch-release.yml @@ -2,8 +2,13 @@ name: Prepare patch release on: workflow_dispatch: +permissions: + contents: read + jobs: prepare-patch-release: + permissions: + contents: write # for git push to PR branch runs-on: ubuntu-latest steps: - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 diff --git a/.github/workflows/prepare-release-branch.yml b/.github/workflows/prepare-release-branch.yml index c377a5698d5..382c5817083 100644 --- a/.github/workflows/prepare-release-branch.yml +++ b/.github/workflows/prepare-release-branch.yml @@ -2,6 +2,9 @@ name: Prepare release branch on: workflow_dispatch: +permissions: + contents: read + jobs: prereqs: runs-on: ubuntu-latest @@ -21,6 +24,8 @@ jobs: fi create-pull-request-against-release-branch: + permissions: + contents: write # for git push to PR branch runs-on: ubuntu-latest needs: - prereqs @@ -70,6 +75,8 @@ jobs: --base $RELEASE_BRANCH_NAME create-pull-request-against-main: + permissions: + contents: write # for git push to PR branch runs-on: ubuntu-latest needs: - prereqs diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 2f9654b82b8..7124f097b6a 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -2,8 +2,13 @@ name: Release on: workflow_dispatch: +permissions: + contents: read + jobs: release: + permissions: + contents: write # for creating the release runs-on: ubuntu-24.04 outputs: version: ${{ steps.create-github-release.outputs.version }} @@ -126,6 +131,8 @@ jobs: echo "version=$VERSION" >> $GITHUB_OUTPUT merge-change-log-to-main: + permissions: + contents: write # for git push to PR branch runs-on: ubuntu-latest needs: - release diff --git a/.github/workflows/reusable-open-issue-on-failure.yml b/.github/workflows/reusable-open-issue-on-failure.yml index 672113d0d2e..15a46db455a 100644 --- a/.github/workflows/reusable-open-issue-on-failure.yml +++ b/.github/workflows/reusable-open-issue-on-failure.yml @@ -3,8 +3,14 @@ name: Reusable - Open issue on workflow failure on: workflow_call: +permissions: + contents: read + jobs: open-issue: + permissions: + contents: read + issues: write # for creating the issue runs-on: ubuntu-latest steps: - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 From c77e66475ac86cb1a42d917ec5958ac0570325f8 Mon Sep 17 00:00:00 2001 From: Trask Stalnaker Date: Mon, 10 Feb 2025 10:33:19 -0800 Subject: [PATCH 806/901] Add OSSF scorecard badge (#7073) --- README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README.md b/README.md index 6ac2f66d8a6..224028f9655 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,11 @@ # OpenTelemetry Java + [![Continuous Build][ci-image]][ci-url] [![Coverage Status][codecov-image]][codecov-url] [![Maven Central][maven-image]][maven-url] [![Reproducible Builds](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/jvm-repo-rebuild/reproducible-central/master/content/io/opentelemetry/java/badge.json)](https://github.com/jvm-repo-rebuild/reproducible-central/blob/master/content/io/opentelemetry/java/README.md) +[![OpenSSF Scorecard](https://api.scorecard.dev/projects/github.com/open-telemetry/opentelemetry-java/badge)](https://scorecard.dev/viewer/?uri=github.com/open-telemetry/opentelemetry-java) +[![OpenSSF Best Practices](https://www.bestpractices.dev/projects/9991/badge)](https://www.bestpractices.dev/projects/9991) `opentelemetry-java` is the home of the Java implementation of the OpenTelemetry API for recording telemetry, and SDK for managing telemetry recorded by the API. From 517893e817c435f678d6c586bd6fa2eb78933228 Mon Sep 17 00:00:00 2001 From: Trask Stalnaker Date: Mon, 10 Feb 2025 10:34:29 -0800 Subject: [PATCH 807/901] Add FOSSA license scanning (#7090) --- .fossa.yml | 40 +++++++++++++++++++++++++++ .github/workflows/fossa.yml | 19 +++++++++++++ custom-checks/build.gradle.kts | 2 +- dependencyManagement/build.gradle.kts | 17 ++++++++++-- 4 files changed, 75 insertions(+), 3 deletions(-) create mode 100644 .fossa.yml create mode 100644 .github/workflows/fossa.yml diff --git a/.fossa.yml b/.fossa.yml new file mode 100644 index 00000000000..87c35f5bcae --- /dev/null +++ b/.fossa.yml @@ -0,0 +1,40 @@ +version: 3 + +targets: + only: + - type: gradle + exclude: + # these modules are not published and so consumers will not be exposed to them + - type: gradle + path: ./ + target: ':api:testing-internal' + - type: gradle + path: ./ + target: ':exporters:otlp:testing-internal' + - type: gradle + path: ./ + target: ':integration-tests' + - type: gradle + path: ./ + target: ':integration-tests:graal' + - type: gradle + path: ./ + target: ':integration-tests:graal-incubating' + - type: gradle + path: ./ + target: ':integration-tests:otlp' + - type: gradle + path: ./ + target: ':integration-tests:tracecontext' + - type: gradle + path: ./ + target: ':perf-harness' + - type: gradle + path: ./ + target: ':testing-internal' + +experimental: + gradle: + configurations-only: + # consumer will only be exposed to these dependencies + - runtimeClasspath diff --git a/.github/workflows/fossa.yml b/.github/workflows/fossa.yml new file mode 100644 index 00000000000..23cabfc684d --- /dev/null +++ b/.github/workflows/fossa.yml @@ -0,0 +1,19 @@ +name: FOSSA + +on: + push: + branches: + - main + +permissions: + contents: read + +jobs: + fossa: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + + - uses: fossas/fossa-action@93a52ecf7c3ac7eb40f5de77fd69b1a19524de94 # v1.5.0 + with: + api-key: ${{secrets.FOSSA_API_KEY}} diff --git a/custom-checks/build.gradle.kts b/custom-checks/build.gradle.kts index 5167a979be0..0139c392ffc 100644 --- a/custom-checks/build.gradle.kts +++ b/custom-checks/build.gradle.kts @@ -3,7 +3,7 @@ plugins { } dependencies { - implementation("com.google.errorprone:error_prone_core") + compileOnly("com.google.errorprone:error_prone_core") testImplementation("com.google.errorprone:error_prone_test_helpers") } diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index 95d51cf04a0..d7cd7d90f89 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -8,10 +8,14 @@ val dependencyVersions = hashMapOf() rootProject.extra["versions"] = dependencyVersions val DEPENDENCY_BOMS = listOf( + // for some reason boms show up as runtime dependencies in license and vulnerability scans + // even if they are only used by test dependencies, so not using junit bom here + // (which is EPL licensed) or armeria bom (which is Apache licensed but is getting flagged + // by FOSSA for containing EPL-licensed) + "com.fasterxml.jackson:jackson-bom:2.18.2", "com.google.guava:guava-bom:33.4.0-jre", "com.google.protobuf:protobuf-bom:4.29.3", - "com.linecorp.armeria:armeria-bom:1.31.3", "com.squareup.okhttp3:okhttp-bom:4.12.0", "com.squareup.okio:okio-bom:3.10.2", // applies to transitive dependencies of okhttp "io.grpc:grpc-bom:1.70.0", @@ -19,7 +23,6 @@ val DEPENDENCY_BOMS = listOf( "io.zipkin.brave:brave-bom:6.0.3", "io.zipkin.reporter2:zipkin-reporter-bom:3.4.3", "org.assertj:assertj-bom:3.27.3", - "org.junit:junit-bom:5.11.4", "org.testcontainers:testcontainers-bom:1.20.4", "org.snakeyaml:snakeyaml-engine:2.9" ) @@ -33,8 +36,18 @@ val slf4jVersion = "2.0.16" val opencensusVersion = "0.31.1" val prometheusClientVersion = "0.16.0" val prometheusServerVersion = "1.3.5" +val armeriaVersion = "1.31.3" +val junitVersion = "5.11.4" val DEPENDENCIES = listOf( + "org.junit.jupiter:junit-jupiter-api:${junitVersion}", + "org.junit.jupiter:junit-jupiter-params:${junitVersion}", + "org.junit.jupiter:junit-jupiter-pioneer:${junitVersion}", + "com.linecorp.armeria:armeria:${armeriaVersion}", + "com.linecorp.armeria:armeria-grpc:${armeriaVersion}", + "com.linecorp.armeria:armeria-grpc-protocol:${armeriaVersion}", + "com.linecorp.armeria:armeria-junit5:${armeriaVersion}", + "com.google.auto.value:auto-value:${autoValueVersion}", "com.google.auto.value:auto-value-annotations:${autoValueVersion}", "com.google.errorprone:error_prone_annotations:${errorProneVersion}", From 768e789160c8d0d457c6fdfc11d8016dbbaa4a61 Mon Sep 17 00:00:00 2001 From: Trask Stalnaker Date: Mon, 10 Feb 2025 10:37:51 -0800 Subject: [PATCH 808/901] Renovate best practices (#7069) --- .github/renovate.json5 | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/.github/renovate.json5 b/.github/renovate.json5 index d5a05ac2ea2..a0db8fdf9da 100644 --- a/.github/renovate.json5 +++ b/.github/renovate.json5 @@ -1,9 +1,17 @@ { "$schema": "https://docs.renovatebot.com/renovate-schema.json", "extends": [ - "config:base" + "config:recommended", + "docker:pinDigests", + "helpers:pinGitHubActionDigests" ], "packageRules": [ + { + // this is to reduce the number of renovate PRs by consolidating them into a weekly batch + "matchManagers": ["github-actions"], + "extends": ["schedule:weekly"], + "groupName": "github actions", + }, { "matchPackageNames": [ "io.opentelemetry.proto:opentelemetry-proto", From 8e71517fdbaa3ba8b3a8b2de6f663c781b03b61f Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 10 Feb 2025 18:26:11 -0800 Subject: [PATCH 809/901] fix(deps): update dependency io.netty:netty-bom to v4.1.118.final (#7093) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- dependencyManagement/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index d7cd7d90f89..fcee3a92c4c 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -19,7 +19,7 @@ val DEPENDENCY_BOMS = listOf( "com.squareup.okhttp3:okhttp-bom:4.12.0", "com.squareup.okio:okio-bom:3.10.2", // applies to transitive dependencies of okhttp "io.grpc:grpc-bom:1.70.0", - "io.netty:netty-bom:4.1.117.Final", + "io.netty:netty-bom:4.1.118.Final", "io.zipkin.brave:brave-bom:6.0.3", "io.zipkin.reporter2:zipkin-reporter-bom:3.4.3", "org.assertj:assertj-bom:3.27.3", From c285def1d98e6bccc732f073e2a758714ce76448 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 10 Feb 2025 18:26:46 -0800 Subject: [PATCH 810/901] fix(deps): update dependency com.tngtech.archunit:archunit-junit5 to v1.4.0 (#7098) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- dependencyManagement/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index fcee3a92c4c..889263cf4b2 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -77,7 +77,7 @@ val DEPENDENCIES = listOf( "com.google.code.findbugs:jsr305:3.0.2", "com.google.guava:guava-beta-checker:1.0", "com.sun.net.httpserver:http:20070405", - "com.tngtech.archunit:archunit-junit5:1.3.0", + "com.tngtech.archunit:archunit-junit5:1.4.0", "com.uber.nullaway:nullaway:0.12.3", "edu.berkeley.cs.jqf:jqf-fuzz:1.7", // jqf-fuzz version 1.8+ requires Java 11+ "eu.rekawek.toxiproxy:toxiproxy-java:2.1.7", From 27d863375bc1ecb3808dc9a693877ef733583e54 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 10 Feb 2025 18:27:11 -0800 Subject: [PATCH 811/901] fix(deps): update dependency com.google.api.grpc:proto-google-common-protos to v2.52.0 (#7097) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- dependencyManagement/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index 889263cf4b2..9421a2872d5 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -73,7 +73,7 @@ val DEPENDENCIES = listOf( "io.prometheus:simpleclient_httpserver:${prometheusClientVersion}", "javax.annotation:javax.annotation-api:1.3.2", "com.github.stefanbirkner:system-rules:1.19.0", - "com.google.api.grpc:proto-google-common-protos:2.51.0", + "com.google.api.grpc:proto-google-common-protos:2.52.0", "com.google.code.findbugs:jsr305:3.0.2", "com.google.guava:guava-beta-checker:1.0", "com.sun.net.httpserver:http:20070405", From b56b10ff57995bc2c49d54cc2bbbc52b5952e698 Mon Sep 17 00:00:00 2001 From: Trask Stalnaker Date: Tue, 11 Feb 2025 13:01:23 -0800 Subject: [PATCH 812/901] Another CLOMonitor exemption (#7096) --- .clomonitor.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.clomonitor.yml b/.clomonitor.yml index 7353049785b..09f54c0d2ef 100644 --- a/.clomonitor.yml +++ b/.clomonitor.yml @@ -1,3 +1,5 @@ exemptions: - check: artifacthub_badge reason: "Artifact Hub doesn't support Java packages" + - check: signed_releases + reason: "Maven central releases are signed and there are no GitHub release artifacts" From 43fba2e984add3de6c0d0de8db7b43f974b9e33f Mon Sep 17 00:00:00 2001 From: Trask Stalnaker Date: Tue, 11 Feb 2025 13:01:57 -0800 Subject: [PATCH 813/901] Update from ubuntu-20.04 (#7100) --- .github/workflows/build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 8dad8184561..ea718341889 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -35,7 +35,7 @@ jobs: - 23 # Collect coverage on latest LTS include: - - os: ubuntu-20.04 + - os: ubuntu-latest test-java-version: 21 coverage: true jmh-based-tests: true From 3e1d9536f80603ce00a421b8e1cbc4cd82126738 Mon Sep 17 00:00:00 2001 From: Trask Stalnaker Date: Tue, 11 Feb 2025 20:54:30 -0800 Subject: [PATCH 814/901] Less frequent Renovate (#7102) --- .github/renovate.json5 | 9 ++++++--- integration-tests/tracecontext/docker/Dockerfile | 4 ++-- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/.github/renovate.json5 b/.github/renovate.json5 index a0db8fdf9da..a7e36d8773c 100644 --- a/.github/renovate.json5 +++ b/.github/renovate.json5 @@ -7,10 +7,13 @@ ], "packageRules": [ { - // this is to reduce the number of renovate PRs by consolidating them into a weekly batch - "matchManagers": ["github-actions"], + // this is to reduce the number of renovate PRs + "matchManagers": [ + "github-actions", + "dockerfile" + ], "extends": ["schedule:weekly"], - "groupName": "github actions", + "groupName": "weekly update" }, { "matchPackageNames": [ diff --git a/integration-tests/tracecontext/docker/Dockerfile b/integration-tests/tracecontext/docker/Dockerfile index f54a9ba2cea..f6ab8d31482 100644 --- a/integration-tests/tracecontext/docker/Dockerfile +++ b/integration-tests/tracecontext/docker/Dockerfile @@ -1,4 +1,4 @@ -FROM python:3@sha256:589ed6659c0e4aac182f309131cd35e85452d21072570b1f6abc45b7687093a3 AS build +FROM python:3.13.2@sha256:589ed6659c0e4aac182f309131cd35e85452d21072570b1f6abc45b7687093a3 AS build # Main branch SHA as of April-1-2021 ARG TRACECONTEXT_GIT_TAG="dcd3ad9b7d6ac36f70ff3739874b73c11b0302a1" @@ -11,7 +11,7 @@ RUN unzip trace-context.zip RUN rm trace-context.zip RUN mv trace-context-${TRACECONTEXT_GIT_TAG}/test /tracecontext-testsuite -FROM python:3-slim@sha256:ae9f9ac89467077ed1efefb6d9042132d28134ba201b2820227d46c9effd3174 +FROM python:3.13.2-slim@sha256:ae9f9ac89467077ed1efefb6d9042132d28134ba201b2820227d46c9effd3174 RUN pip install aiohttp From e47963612ea97d5442a2b7b2a15f8045bd75e6eb Mon Sep 17 00:00:00 2001 From: Trask Stalnaker Date: Tue, 18 Feb 2025 07:57:55 -0800 Subject: [PATCH 815/901] Convert branch protections to rule sets (#7095) --- .github/repository-settings.md | 131 ++++++++++++++++++++------------- 1 file changed, 79 insertions(+), 52 deletions(-) diff --git a/.github/repository-settings.md b/.github/repository-settings.md index 79d583584b1..71ae759d069 100644 --- a/.github/repository-settings.md +++ b/.github/repository-settings.md @@ -5,71 +5,98 @@ Repository settings in addition to what's documented already at ## General > Pull Requests -* Allow squash merging > Default to pull request title +- Allow squash merging > Default to pull request title + +- Allow auto-merge ## Actions > General -* Fork pull request workflows from outside collaborators: +- Fork pull request workflows from outside collaborators: "Require approval for first-time contributors who are new to GitHub" (To reduce friction for new contributors, as the default is "Require approval for first-time contributors") -## Branch protections - -The order of branch protection rules -[can be important](https://docs.github.com/en/repositories/configuring-branches-and-merges-in-your-repository/defining-the-mergeability-of-pull-requests/managing-a-branch-protection-rule#about-branch-protection-rules). -The branch protection rules below should be added before the `**/**` branch protection rule -(this may require deleting the `**/**` rule and recreating it at the end). - -### `main` - -* Require branches to be up to date before merging: UNCHECKED - - (PR jobs take too long, and leaving this unchecked has not been a significant problem) - -* Status checks that are required: - - * EasyCLA - * required-status-check - -### `release/*` - -Same settings as above for `main`, except: +- Workflow permissions + - Default permissions granted to the `GITHUB_TOKEN` when running workflows in this repository: + Read repository contents and packages permissions + - Allow GitHub Actions to create and approve pull requests: UNCHECKED + +## Rules > Rulesets + +### `main` and release branches + +- Targeted branches: + - `main` + - `release/*` +- Branch rules + - Restrict deletions: CHECKED + - Require linear history: CHECKED + - Require a pull request before merging: CHECKED + - Required approvals: 1 + - Require review from Code Owners: CHECKED + - Allowed merge methods: Squash + - Require status checks to pass + - Do not require status checks on creation: CHECKED + - Status checks that are required + - EasyCLA + - `required-status-check` + - `gradle-wrapper-validation` + - Block force pushes: CHECKED + - Require code scanning results: CHECKED + - CodeQL + - Security alerts: High or higher + - Alerts: Errors + +### `benchmarks` branch + +- Targeted branches: + - `benchmarks` +- Branch rules + - Restrict deletions: CHECKED + - Require linear history: CHECKED + - Block force pushes: CHECKED + +### Old-style release branches + +- Targeted branches: + - `v0.*` + - `v1.*` +- Branch rules + - Restrict creations: CHECKED + - Restrict updates: CHECKED + - Restrict deletions: CHECKED + +### Restrict branch creation + +- Targeted branches + - Exclude: + - `release/*` + - `renovate/**/*` + - `otelbot/**/*` + - `revert-*/**/*` (these are created when using the GitHub UI to revert a PR) +- Restrict creations: CHECKED + +### Restrict updating tags + +- Targeted tags + - All tags +- Restrict updates: CHECKED +- Restrict deletions: CHECKED -* Restrict pushes that create matching branches: UNCHECKED - - (So that opentelemetrybot can create release branches) - -### `renovate/**/**`, and `opentelemetrybot/*` - -* Require status checks to pass before merging: UNCHECKED - - (So that renovate PRs can be rebased) - -* Restrict who can push to matching branches: UNCHECKED - - (So that bots can create PR branches in this repository) - -* Allow force pushes > Everyone - - (So that renovate PRs can be rebased) - -* Allow deletions: CHECKED +## Branch protections - (So that bot PR branches can be deleted) +### `main`, `release/*` -### `benchmarks` +- Restrict who can push to matching branches: CHECKED -- Everything UNCHECKED +## Code security and analysis - (This branch is currently only used for directly pushing benchmarking results from the - [overhead benchmark](https://github.com/open-telemetry/opentelemetry-java/actions/workflows/benchmark.yml) - job) +- Secret scanning: Enabled ## Secrets and variables > Actions -* `GPG_PASSWORD` - stored in OpenTelemetry-Java 1Password -* `GPG_PRIVATE_KEY` - stored in OpenTelemetry-Java 1Password -* `SONATYPE_KEY` - owned by [@jack-berg](https://github.com/jack-berg) -* `SONATYPE_USER` - owned by [@jack-berg](https://github.com/jack-berg) +- `GPG_PASSWORD` - stored in OpenTelemetry-Java 1Password +- `GPG_PRIVATE_KEY` - stored in OpenTelemetry-Java 1Password +- `SONATYPE_KEY` - owned by [@jack-berg](https://github.com/jack-berg) +- `SONATYPE_USER` - owned by [@jack-berg](https://github.com/jack-berg) From 3d3355305b047200c1177e844bf82128ce58b23c Mon Sep 17 00:00:00 2001 From: Trask Stalnaker Date: Tue, 18 Feb 2025 07:58:16 -0800 Subject: [PATCH 816/901] Add FOSSA team (#7104) --- .github/workflows/fossa.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/fossa.yml b/.github/workflows/fossa.yml index 23cabfc684d..982628c9121 100644 --- a/.github/workflows/fossa.yml +++ b/.github/workflows/fossa.yml @@ -17,3 +17,4 @@ jobs: - uses: fossas/fossa-action@93a52ecf7c3ac7eb40f5de77fd69b1a19524de94 # v1.5.0 with: api-key: ${{secrets.FOSSA_API_KEY}} + team: OpenTelemetry From fe73fb737a4526fe8684050b08efa4e44086d5f3 Mon Sep 17 00:00:00 2001 From: jack-berg <34418638+jack-berg@users.noreply.github.com> Date: Tue, 18 Feb 2025 09:58:58 -0600 Subject: [PATCH 817/901] Retry tests in CI (#7106) --- buildSrc/build.gradle.kts | 1 + buildSrc/src/main/kotlin/otel.java-conventions.gradle.kts | 8 ++++++++ 2 files changed, 9 insertions(+) diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts index 6dfee8ff67a..684d32abdb2 100644 --- a/buildSrc/build.gradle.kts +++ b/buildSrc/build.gradle.kts @@ -56,6 +56,7 @@ dependencies { implementation("com.diffplug.spotless:spotless-plugin-gradle:7.0.2") // Needed for japicmp but not automatically brought in for some reason. implementation("com.google.guava:guava:33.4.0-jre") + implementation("com.gradle.develocity:com.gradle.develocity.gradle.plugin:3.19.1") implementation("com.squareup:javapoet:1.13.0") implementation("com.squareup.wire:wire-compiler") implementation("com.squareup.wire:wire-gradle-plugin") diff --git a/buildSrc/src/main/kotlin/otel.java-conventions.gradle.kts b/buildSrc/src/main/kotlin/otel.java-conventions.gradle.kts index 4d2315b9bdd..a9406440b1a 100644 --- a/buildSrc/src/main/kotlin/otel.java-conventions.gradle.kts +++ b/buildSrc/src/main/kotlin/otel.java-conventions.gradle.kts @@ -113,6 +113,14 @@ tasks { ) } + val defaultMaxRetries = if (System.getenv().containsKey("CI")) 2 else 0 + val maxTestRetries = gradle.startParameter.projectProperties["maxTestRetries"]?.toInt() ?: defaultMaxRetries + + develocity.testRetry { + // You can see tests that were retried by this mechanism in the collected test reports and build scans. + maxRetries.set(maxTestRetries); + } + testLogging { exceptionFormat = TestExceptionFormat.FULL showExceptions = true From 41e54f7481a9d01d9e1ca2e9af673b4624e68dbb Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 18 Feb 2025 12:45:11 -0800 Subject: [PATCH 818/901] fix(deps): update dependency com.squareup.wire:wire-bom to v5.3.0 (#7108) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- buildSrc/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts index 684d32abdb2..906306c2a88 100644 --- a/buildSrc/build.gradle.kts +++ b/buildSrc/build.gradle.kts @@ -50,7 +50,7 @@ repositories { } dependencies { - implementation(enforcedPlatform("com.squareup.wire:wire-bom:5.2.1")) + implementation(enforcedPlatform("com.squareup.wire:wire-bom:5.3.0")) implementation("com.google.auto.value:auto-value-annotations:1.11.0") // When updating, update above in plugins too implementation("com.diffplug.spotless:spotless-plugin-gradle:7.0.2") From ca6fa4e80137801f0574d4521f18b37605faa759 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 18 Feb 2025 12:51:51 -0800 Subject: [PATCH 819/901] fix(deps): update dependency me.champeau.gradle:japicmp-gradle-plugin to v0.4.6 (#7110) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- buildSrc/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts index 906306c2a88..fa2af54de6f 100644 --- a/buildSrc/build.gradle.kts +++ b/buildSrc/build.gradle.kts @@ -62,7 +62,7 @@ dependencies { implementation("com.squareup.wire:wire-gradle-plugin") implementation("gradle.plugin.com.google.protobuf:protobuf-gradle-plugin:0.8.18") implementation("gradle.plugin.io.morethan.jmhreport:gradle-jmh-report:0.9.6") - implementation("me.champeau.gradle:japicmp-gradle-plugin:0.4.5") + implementation("me.champeau.gradle:japicmp-gradle-plugin:0.4.6") implementation("me.champeau.jmh:jmh-gradle-plugin:0.7.3") implementation("net.ltgt.gradle:gradle-errorprone-plugin:4.1.0") implementation("net.ltgt.gradle:gradle-nullaway-plugin:2.2.0") From d69ea6c37db53a61942280ebb569520e15f2aed0 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 18 Feb 2025 12:52:27 -0800 Subject: [PATCH 820/901] fix(deps): update dependency io.zipkin.brave:brave-bom to v6.1.0 (#7111) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- dependencyManagement/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index 9421a2872d5..099ca583ebf 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -20,7 +20,7 @@ val DEPENDENCY_BOMS = listOf( "com.squareup.okio:okio-bom:3.10.2", // applies to transitive dependencies of okhttp "io.grpc:grpc-bom:1.70.0", "io.netty:netty-bom:4.1.118.Final", - "io.zipkin.brave:brave-bom:6.0.3", + "io.zipkin.brave:brave-bom:6.1.0", "io.zipkin.reporter2:zipkin-reporter-bom:3.4.3", "org.assertj:assertj-bom:3.27.3", "org.testcontainers:testcontainers-bom:1.20.4", From 8ed2e0c79f0a8ab8feceb01adf3b62617f577316 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 18 Feb 2025 14:30:19 -0800 Subject: [PATCH 821/901] fix(deps): update dependency io.zipkin.reporter2:zipkin-reporter-bom to v3.5.0 (#7112) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- dependencyManagement/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index 099ca583ebf..a6d10098c5e 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -21,7 +21,7 @@ val DEPENDENCY_BOMS = listOf( "io.grpc:grpc-bom:1.70.0", "io.netty:netty-bom:4.1.118.Final", "io.zipkin.brave:brave-bom:6.1.0", - "io.zipkin.reporter2:zipkin-reporter-bom:3.4.3", + "io.zipkin.reporter2:zipkin-reporter-bom:3.5.0", "org.assertj:assertj-bom:3.27.3", "org.testcontainers:testcontainers-bom:1.20.4", "org.snakeyaml:snakeyaml-engine:2.9" From 3f3b42483a0b62acc2f4a672c96a2d9e8f7f5482 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 18 Feb 2025 14:41:25 -0800 Subject: [PATCH 822/901] fix(deps): update dependency org.owasp:dependency-check-gradle to v12.1.0 (#7113) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- buildSrc/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts index fa2af54de6f..e02dbf2fd3f 100644 --- a/buildSrc/build.gradle.kts +++ b/buildSrc/build.gradle.kts @@ -67,7 +67,7 @@ dependencies { implementation("net.ltgt.gradle:gradle-errorprone-plugin:4.1.0") implementation("net.ltgt.gradle:gradle-nullaway-plugin:2.2.0") implementation("org.jetbrains.kotlin:kotlin-gradle-plugin:2.1.10") - implementation("org.owasp:dependency-check-gradle:12.0.2") + implementation("org.owasp:dependency-check-gradle:12.1.0") implementation("ru.vyarus:gradle-animalsniffer-plugin:2.0.0") } From d08c5030d3806e5f80b1c0d746a9350e11bafde6 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 18 Feb 2025 18:12:09 -0600 Subject: [PATCH 823/901] fix(deps): update dependency io.opentelemetry.semconv:opentelemetry-semconv-incubating to v1.30.0-alpha (#7122) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- dependencyManagement/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index a6d10098c5e..24b6b97c337 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -84,7 +84,7 @@ val DEPENDENCIES = listOf( "io.github.netmikey.logunit:logunit-jul:2.0.0", "io.jaegertracing:jaeger-client:1.8.1", "io.opentelemetry.contrib:opentelemetry-aws-xray-propagator:1.39.0-alpha", - "io.opentelemetry.semconv:opentelemetry-semconv-incubating:1.30.0-alpha-rc.1", + "io.opentelemetry.semconv:opentelemetry-semconv-incubating:1.30.0-alpha", "io.opentelemetry.proto:opentelemetry-proto:1.5.0-alpha", "io.opentracing:opentracing-api:0.33.0", "io.opentracing:opentracing-noop:0.33.0", From a9d7f1ebda42c9255e7e5fb10232f7a2269d4722 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 18 Feb 2025 16:35:36 -0800 Subject: [PATCH 824/901] fix(deps): update dependency nl.jqno.equalsverifier:equalsverifier to v3.19.1 (#7117) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- dependencyManagement/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index 24b6b97c337..748eab8de86 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -89,7 +89,7 @@ val DEPENDENCIES = listOf( "io.opentracing:opentracing-api:0.33.0", "io.opentracing:opentracing-noop:0.33.0", "junit:junit:4.13.2", - "nl.jqno.equalsverifier:equalsverifier:3.19", + "nl.jqno.equalsverifier:equalsverifier:3.19.1", "org.awaitility:awaitility:4.2.2", "org.bouncycastle:bcpkix-jdk15on:1.70", "org.codehaus.mojo:animal-sniffer-annotations:1.24", From 5b93c08eeda64b372614afb6ce9ba81cc3f36d2a Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 18 Feb 2025 16:36:32 -0800 Subject: [PATCH 825/901] fix(deps): update dependency com.gradle.develocity:com.gradle.develocity.gradle.plugin to v3.19.2 (#7121) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- buildSrc/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts index e02dbf2fd3f..c56c4943f19 100644 --- a/buildSrc/build.gradle.kts +++ b/buildSrc/build.gradle.kts @@ -56,7 +56,7 @@ dependencies { implementation("com.diffplug.spotless:spotless-plugin-gradle:7.0.2") // Needed for japicmp but not automatically brought in for some reason. implementation("com.google.guava:guava:33.4.0-jre") - implementation("com.gradle.develocity:com.gradle.develocity.gradle.plugin:3.19.1") + implementation("com.gradle.develocity:com.gradle.develocity.gradle.plugin:3.19.2") implementation("com.squareup:javapoet:1.13.0") implementation("com.squareup.wire:wire-compiler") implementation("com.squareup.wire:wire-gradle-plugin") From f937eff1eecce906cf7f6c9b2a688872da1cf8e7 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 18 Feb 2025 18:52:21 -0800 Subject: [PATCH 826/901] chore(deps): update plugin com.gradle.develocity to v3.19.2 (#7120) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- settings.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/settings.gradle.kts b/settings.gradle.kts index 1db18115392..10ab444628a 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -1,7 +1,7 @@ pluginManagement { plugins { id("com.gradleup.shadow") version "8.3.6" - id("com.gradle.develocity") version "3.19.1" + id("com.gradle.develocity") version "3.19.2" id("de.undercouch.download") version "5.6.0" id("org.jsonschema2pojo") version "1.2.2" id("io.github.gradle-nexus.publish-plugin") version "2.0.0" From 5879f48dc8cf6c4707d3fe819168d8b76a0b8575 Mon Sep 17 00:00:00 2001 From: Trask Stalnaker Date: Wed, 19 Feb 2025 07:57:55 -0800 Subject: [PATCH 827/901] Fix OWASP dependency check workflow (#7115) --- .github/repository-settings.md | 3 ++ .../owasp-dependency-check-daily.yml | 13 ++++++ .../reusable-workflow-notification.yml | 44 +++++++++++++++++++ 3 files changed, 60 insertions(+) create mode 100644 .github/workflows/reusable-workflow-notification.yml diff --git a/.github/repository-settings.md b/.github/repository-settings.md index 71ae759d069..662f3849b33 100644 --- a/.github/repository-settings.md +++ b/.github/repository-settings.md @@ -98,5 +98,8 @@ Repository settings in addition to what's documented already at - `GPG_PASSWORD` - stored in OpenTelemetry-Java 1Password - `GPG_PRIVATE_KEY` - stored in OpenTelemetry-Java 1Password +- `NVD_API_KEY` - stored in OpenTelemetry-Java 1Password + - Generated at https://nvd.nist.gov/developers/request-an-api-key + - Key is associated with [@trask](https://github.com/trask)'s gmail address - `SONATYPE_KEY` - owned by [@jack-berg](https://github.com/jack-berg) - `SONATYPE_USER` - owned by [@jack-berg](https://github.com/jack-berg) diff --git a/.github/workflows/owasp-dependency-check-daily.yml b/.github/workflows/owasp-dependency-check-daily.yml index eeff9cc0df2..95302cf1172 100644 --- a/.github/workflows/owasp-dependency-check-daily.yml +++ b/.github/workflows/owasp-dependency-check-daily.yml @@ -26,9 +26,22 @@ jobs: - name: Check dependencies run: ./gradlew dependencyCheckAnalyze + env: + NVD_API_KEY: ${{ secrets.NVD_API_KEY }} - name: Upload report if: always() uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0 with: path: javaagent/build/reports + + workflow-notification: + permissions: + contents: read + issues: write + needs: + - analyze + if: always() + uses: ./.github/workflows/reusable-workflow-notification.yml + with: + success: ${{ needs.analyze.result == 'success' }} diff --git a/.github/workflows/reusable-workflow-notification.yml b/.github/workflows/reusable-workflow-notification.yml new file mode 100644 index 00000000000..701f90f5a08 --- /dev/null +++ b/.github/workflows/reusable-workflow-notification.yml @@ -0,0 +1,44 @@ +# this is useful because notifications for scheduled workflows are only sent to the user who +# initially created the given workflow +name: Reusable - Workflow notification + +on: + workflow_call: + inputs: + success: + type: boolean + required: true + +permissions: + contents: read + +jobs: + workflow-notification: + permissions: + contents: read + issues: write + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + + - name: Open issue or add comment if issue already open + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + # TODO (trask) search doesn't support exact phrases, so it's possible that this could grab the wrong issue + number=$(gh issue list --search "in:title Workflow failed: $GITHUB_WORKFLOW" --limit 1 --json number -q .[].number) + + echo $number + echo ${{ inputs.success }} + + if [[ $number ]]; then + if [[ "${{ inputs.success }}" == "true" ]]; then + gh issue close $number + else + gh issue comment $number \ + --body "See [$GITHUB_WORKFLOW #$GITHUB_RUN_NUMBER](https://github.com/$GITHUB_REPOSITORY/actions/runs/$GITHUB_RUN_ID)." + fi + elif [[ "${{ inputs.success }}" == "false" ]]; then + gh issue create --title "Workflow failed: $GITHUB_WORKFLOW (#$GITHUB_RUN_NUMBER)" \ + --body "See [$GITHUB_WORKFLOW #$GITHUB_RUN_NUMBER](https://github.com/$GITHUB_REPOSITORY/actions/runs/$GITHUB_RUN_ID)." + fi From 0465c791512ac7688698601dd9bfa822dbec0fad Mon Sep 17 00:00:00 2001 From: Trask Stalnaker Date: Thu, 20 Feb 2025 09:19:22 -0800 Subject: [PATCH 828/901] Fix OWASP dependency check workflow (#7126) --- buildSrc/src/main/kotlin/otel.java-conventions.gradle.kts | 1 + 1 file changed, 1 insertion(+) diff --git a/buildSrc/src/main/kotlin/otel.java-conventions.gradle.kts b/buildSrc/src/main/kotlin/otel.java-conventions.gradle.kts index a9406440b1a..a94892cf17d 100644 --- a/buildSrc/src/main/kotlin/otel.java-conventions.gradle.kts +++ b/buildSrc/src/main/kotlin/otel.java-conventions.gradle.kts @@ -66,6 +66,7 @@ dependencyCheck { "jmhRuntimeOnly") failBuildOnCVSS = 7.0f // fail on high or critical CVE analyzers.assemblyEnabled = false // not sure why its trying to analyze .NET assemblies + nvd.apiKey = System.getenv("NVD_API_KEY") } val testJavaVersion = gradle.startParameter.projectProperties.get("testJavaVersion")?.let(JavaVersion::toVersion) From 37969926d13f7f62cf4fa9b2f46794c01d0cfb3a Mon Sep 17 00:00:00 2001 From: jack-berg <34418638+jack-berg@users.noreply.github.com> Date: Thu, 20 Feb 2025 15:58:18 -0600 Subject: [PATCH 829/901] Disable owasp dependency check on :custom-checks (#7128) --- custom-checks/build.gradle.kts | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/custom-checks/build.gradle.kts b/custom-checks/build.gradle.kts index 0139c392ffc..22ce0614b30 100644 --- a/custom-checks/build.gradle.kts +++ b/custom-checks/build.gradle.kts @@ -80,3 +80,8 @@ configurations { } } } + +// Skip OWASP dependencyCheck task on test module +dependencyCheck { + skip = true +} From 56941a5ba66992ab8fb30662c310a6205f90ca22 Mon Sep 17 00:00:00 2001 From: jack-berg <34418638+jack-berg@users.noreply.github.com> Date: Fri, 21 Feb 2025 10:13:57 -0600 Subject: [PATCH 830/901] Remove support for otel.java.experimental.exporter.memory_mode (#7127) --- .../exporter/internal/ExporterBuilderUtil.java | 10 ---------- .../logging/otlp/AbstractOtlpStdoutExporterTest.java | 4 ++-- 2 files changed, 2 insertions(+), 12 deletions(-) diff --git a/exporters/common/src/main/java/io/opentelemetry/exporter/internal/ExporterBuilderUtil.java b/exporters/common/src/main/java/io/opentelemetry/exporter/internal/ExporterBuilderUtil.java index 9e3a1fcf266..f67c7fe7164 100644 --- a/exporters/common/src/main/java/io/opentelemetry/exporter/internal/ExporterBuilderUtil.java +++ b/exporters/common/src/main/java/io/opentelemetry/exporter/internal/ExporterBuilderUtil.java @@ -21,7 +21,6 @@ import java.net.URISyntaxException; import java.util.Locale; import java.util.function.Consumer; -import java.util.logging.Logger; /** * Utilities for exporter builders. @@ -31,8 +30,6 @@ */ public final class ExporterBuilderUtil { - private static final Logger logger = Logger.getLogger(ExporterBuilderUtil.class.getName()); - /** Validate OTLP endpoint. */ public static URI validateEndpoint(String endpoint) { URI uri; @@ -54,13 +51,6 @@ public static URI validateEndpoint(String endpoint) { public static void configureExporterMemoryMode( ConfigProperties config, Consumer memoryModeConsumer) { String memoryModeStr = config.getString("otel.java.exporter.memory_mode"); - if (memoryModeStr == null) { - memoryModeStr = config.getString("otel.java.experimental.exporter.memory_mode"); - if (memoryModeStr != null) { - logger.warning( - "otel.java.experimental.exporter.memory_mode was set but has been replaced with otel.java.exporter.memory_mode and will be removed in a future release"); - } - } if (memoryModeStr == null) { return; } diff --git a/exporters/logging-otlp/src/test/java/io/opentelemetry/exporter/logging/otlp/AbstractOtlpStdoutExporterTest.java b/exporters/logging-otlp/src/test/java/io/opentelemetry/exporter/logging/otlp/AbstractOtlpStdoutExporterTest.java index 54835720d3c..fbfd771a038 100644 --- a/exporters/logging-otlp/src/test/java/io/opentelemetry/exporter/logging/otlp/AbstractOtlpStdoutExporterTest.java +++ b/exporters/logging-otlp/src/test/java/io/opentelemetry/exporter/logging/otlp/AbstractOtlpStdoutExporterTest.java @@ -293,13 +293,13 @@ void providerConfig() { assertThat( exporterFromProvider( DefaultConfigProperties.createFromMap( - singletonMap("otel.java.experimental.exporter.memory_mode", "immutable_data")))) + singletonMap("otel.java.exporter.memory_mode", "immutable_data")))) .extracting("memoryMode") .isEqualTo(MemoryMode.IMMUTABLE_DATA); assertThat( exporterFromProvider( DefaultConfigProperties.createFromMap( - singletonMap("otel.java.experimental.exporter.memory_mode", "reusable_data")))) + singletonMap("otel.java.exporter.memory_mode", "reusable_data")))) .extracting("memoryMode") .isEqualTo(MemoryMode.REUSABLE_DATA); } From ee731aabd355a9d755911db91efbb894ae09a07e Mon Sep 17 00:00:00 2001 From: jason plumb <75337021+breedx-splk@users.noreply.github.com> Date: Mon, 24 Feb 2025 08:13:35 -0800 Subject: [PATCH 831/901] Add some helpful logging attribute methods (#7089) Co-authored-by: jack-berg <34418638+jack-berg@users.noreply.github.com> --- .../api/logs/LogRecordBuilder.java | 89 ++++++++++++++++++- .../current_vs_latest/opentelemetry-api.txt | 8 +- .../sdk/logs/SdkLogRecordBuilderTest.java | 25 +++++- 3 files changed, 119 insertions(+), 3 deletions(-) diff --git a/api/all/src/main/java/io/opentelemetry/api/logs/LogRecordBuilder.java b/api/all/src/main/java/io/opentelemetry/api/logs/LogRecordBuilder.java index 2166ab2b6b8..cc5da82c22e 100644 --- a/api/all/src/main/java/io/opentelemetry/api/logs/LogRecordBuilder.java +++ b/api/all/src/main/java/io/opentelemetry/api/logs/LogRecordBuilder.java @@ -5,6 +5,11 @@ package io.opentelemetry.api.logs; +import static io.opentelemetry.api.common.AttributeKey.booleanKey; +import static io.opentelemetry.api.common.AttributeKey.doubleKey; +import static io.opentelemetry.api.common.AttributeKey.longKey; +import static io.opentelemetry.api.common.AttributeKey.stringKey; + import io.opentelemetry.api.common.AttributeKey; import io.opentelemetry.api.common.Attributes; import io.opentelemetry.api.common.Value; @@ -98,9 +103,91 @@ default LogRecordBuilder setAllAttributes(Attributes attributes) { return this; } - /** Sets an attribute. */ + /** + * Sets an attribute on the {@code LogRecord}. If the {@code LogRecord} previously contained a + * mapping for the key, the old value is replaced by the specified value. + * + * @param key the key for this attribute. + * @param value the value for this attribute. + * @return this. + */ LogRecordBuilder setAttribute(AttributeKey key, T value); + /** + * Sets a String attribute on the {@code LogRecord}. If the {@code LogRecord} previously contained + * a mapping for the key, the old value is replaced by the specified value. + * + *

      Note: It is strongly recommended to use {@link #setAttribute(AttributeKey, Object)}, and + * pre-allocate your keys, if possible. + * + * @param key the key for this attribute. + * @param value the value for this attribute. + * @return this. + */ + default LogRecordBuilder setAttribute(String key, String value) { + return setAttribute(stringKey(key), value); + } + + /** + * Sets a Long attribute on the {@code LogRecord}. If the {@code LogRecord} previously contained a + * mapping for the key, the old value is replaced by the specified value. + * + *

      Note: It is strongly recommended to use {@link #setAttribute(AttributeKey, Object)}, and + * pre-allocate your keys, if possible. + * + * @param key the key for this attribute. + * @param value the value for this attribute. + * @return this. + */ + default LogRecordBuilder setAttribute(String key, long value) { + return setAttribute(longKey(key), value); + } + + /** + * Sets a Double attribute on the {@code LogRecord}. If the {@code LogRecord} previously contained + * a mapping for the key, the old value is replaced by the specified value. + * + *

      Note: It is strongly recommended to use {@link #setAttribute(AttributeKey, Object)}, and + * pre-allocate your keys, if possible. + * + * @param key the key for this attribute. + * @param value the value for this attribute. + * @return this. + */ + default LogRecordBuilder setAttribute(String key, double value) { + return setAttribute(doubleKey(key), value); + } + + /** + * Sets a Boolean attribute on the {@code LogRecord}. If the {@code LogRecord} previously + * contained a mapping for the key, the old value is replaced by the specified value. + * + *

      Note: It is strongly recommended to use {@link #setAttribute(AttributeKey, Object)}, and + * pre-allocate your keys, if possible. + * + * @param key the key for this attribute. + * @param value the value for this attribute. + * @return this. + */ + default LogRecordBuilder setAttribute(String key, boolean value) { + return setAttribute(booleanKey(key), value); + } + + /** + * Sets an Integer attribute on the {@code LogRecord}. If the {@code LogRecord} previously + * contained a mapping for the key, the old value is replaced by the specified value. + * + *

      Note: It is strongly recommended to use {@link #setAttribute(AttributeKey, Object)}, and + * pre-allocate your keys, if possible. + * + * @param key the key for this attribute. + * @param value the value for this attribute. + * @return this. + */ + default LogRecordBuilder setAttribute(String key, int value) { + return setAttribute(key, (long) value); + } + /** Emit the log record. */ void emit(); } diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-api.txt b/docs/apidiffs/current_vs_latest/opentelemetry-api.txt index ef68fdedeeb..bd14d189fd7 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-api.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-api.txt @@ -1,2 +1,8 @@ Comparing source compatibility of opentelemetry-api-1.48.0-SNAPSHOT.jar against opentelemetry-api-1.47.0.jar -No changes. \ No newline at end of file +*** MODIFIED INTERFACE: PUBLIC ABSTRACT io.opentelemetry.api.logs.LogRecordBuilder (not serializable) + === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 + +++ NEW METHOD: PUBLIC(+) io.opentelemetry.api.logs.LogRecordBuilder setAttribute(java.lang.String, java.lang.String) + +++ NEW METHOD: PUBLIC(+) io.opentelemetry.api.logs.LogRecordBuilder setAttribute(java.lang.String, long) + +++ NEW METHOD: PUBLIC(+) io.opentelemetry.api.logs.LogRecordBuilder setAttribute(java.lang.String, double) + +++ NEW METHOD: PUBLIC(+) io.opentelemetry.api.logs.LogRecordBuilder setAttribute(java.lang.String, boolean) + +++ NEW METHOD: PUBLIC(+) io.opentelemetry.api.logs.LogRecordBuilder setAttribute(java.lang.String, int) diff --git a/sdk/logs/src/test/java/io/opentelemetry/sdk/logs/SdkLogRecordBuilderTest.java b/sdk/logs/src/test/java/io/opentelemetry/sdk/logs/SdkLogRecordBuilderTest.java index 0be11e67b31..202f73917f1 100644 --- a/sdk/logs/src/test/java/io/opentelemetry/sdk/logs/SdkLogRecordBuilderTest.java +++ b/sdk/logs/src/test/java/io/opentelemetry/sdk/logs/SdkLogRecordBuilderTest.java @@ -5,7 +5,12 @@ package io.opentelemetry.sdk.logs; +import static io.opentelemetry.api.common.AttributeKey.booleanKey; +import static io.opentelemetry.api.common.AttributeKey.doubleKey; +import static io.opentelemetry.api.common.AttributeKey.longKey; +import static io.opentelemetry.api.common.AttributeKey.stringKey; import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.assertThat; +import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.equalTo; import static org.mockito.Mockito.when; import io.opentelemetry.api.common.AttributeKey; @@ -77,7 +82,7 @@ void emit_AllFields() { builder.setTimestamp(timestamp); builder.setObservedTimestamp(456, TimeUnit.SECONDS); builder.setObservedTimestamp(observedTimestamp); - builder.setAttribute(null, null); + builder.setAttribute((String) null, (String) null); builder.setAttribute(AttributeKey.stringKey("k1"), "v1"); builder.setAllAttributes(Attributes.builder().put("k2", "v2").put("k3", "v3").build()); builder.setContext(Span.wrap(spanContext).storeInContext(Context.root())); @@ -116,4 +121,22 @@ void emit_NoFields() { .hasSpanContext(SpanContext.getInvalid()) .hasSeverity(Severity.UNDEFINED_SEVERITY_NUMBER); } + + @Test + void testConvenienceAttributeMethods() { + builder + .setAttribute("foo", "bar") + .setAttribute("lk", 12L) + .setAttribute("dk", 12.123) + .setAttribute("bk", true) + .setAttribute("ik", 13) + .emit(); + assertThat(emittedLog.get().toLogRecordData()) + .hasAttributesSatisfyingExactly( + equalTo(stringKey("foo"), "bar"), + equalTo(longKey("lk"), 12L), + equalTo(doubleKey("dk"), 12.123), + equalTo(booleanKey("bk"), true), + equalTo(longKey("ik"), 13L)); + } } From 3c77016788a064d745538ab1b0b43e328f67648c Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 24 Feb 2025 10:23:07 -0600 Subject: [PATCH 832/901] chore(deps): update weekly update (#7114) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/build-tracecontext-testsuite.yml | 2 +- .github/workflows/build.yml | 4 ++-- .github/workflows/codeql.yml | 4 ++-- .github/workflows/ossf-scorecard.yml | 6 +++--- .github/workflows/owasp-dependency-check-daily.yml | 2 +- integration-tests/tracecontext/docker/Dockerfile | 2 +- 6 files changed, 10 insertions(+), 10 deletions(-) diff --git a/.github/workflows/build-tracecontext-testsuite.yml b/.github/workflows/build-tracecontext-testsuite.yml index 7ee35f773e6..d15f8e8d4e4 100644 --- a/.github/workflows/build-tracecontext-testsuite.yml +++ b/.github/workflows/build-tracecontext-testsuite.yml @@ -29,7 +29,7 @@ jobs: password: ${{ secrets.GITHUB_TOKEN }} - name: Build and push - uses: docker/build-push-action@ca877d9245402d1537745e0e356eab47c3520991 # v6.13.0 + uses: docker/build-push-action@0adf9959216b96bec444f325f1e493d4aa344497 # v6.14.0 with: context: integration-tests/tracecontext/docker push: true diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index ea718341889..adb645a68c6 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -104,7 +104,7 @@ jobs: env: CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} - - uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0 + - uses: actions/upload-artifact@4cec3d8aa04e39d1a68397de0c4cd6fb9dce8ec1 # v4.6.1 if: ${{ matrix.coverage }} with: name: coverage-report @@ -164,7 +164,7 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - - uses: graalvm/setup-graalvm@aafbedb8d382ed0ca6167d3a051415f20c859274 # v1.2.8 + - uses: graalvm/setup-graalvm@b0cb26a8da53cb3e97cdc0c827d8e3071240e730 # v1.3.1 with: # TODO(jack-berg): Which versions do we need to test? Should we use a matrix scheme? java-version: '21' diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index 6bec145e694..5ed35ce27b0 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -37,7 +37,7 @@ jobs: uses: gradle/actions/setup-gradle@94baf225fe0a508e581a564467443d0e2379123b # v4.3.0 - name: Initialize CodeQL - uses: github/codeql-action/init@9e8d0789d4a0fa9ceb6b1738f7e269594bdd67f0 # v3.28.9 + uses: github/codeql-action/init@b56ba49b26e50535fa1e7f7db0f4f7b4bf65d80d # v3.28.10 with: languages: java, actions # using "latest" helps to keep up with the latest Kotlin support @@ -51,4 +51,4 @@ jobs: run: ./gradlew assemble --no-build-cache --no-daemon - name: Perform CodeQL analysis - uses: github/codeql-action/analyze@9e8d0789d4a0fa9ceb6b1738f7e269594bdd67f0 # v3.28.9 + uses: github/codeql-action/analyze@b56ba49b26e50535fa1e7f7db0f4f7b4bf65d80d # v3.28.10 diff --git a/.github/workflows/ossf-scorecard.yml b/.github/workflows/ossf-scorecard.yml index 114c992b9ac..f57e5edcf28 100644 --- a/.github/workflows/ossf-scorecard.yml +++ b/.github/workflows/ossf-scorecard.yml @@ -23,7 +23,7 @@ jobs: with: persist-credentials: false - - uses: ossf/scorecard-action@62b2cac7ed8198b15735ed49ab1e5cf35480ba46 # v2.4.0 + - uses: ossf/scorecard-action@f49aabe0b5af0936a0987cfb85d86b75731b0186 # v2.4.1 with: results_file: results.sarif results_format: sarif @@ -33,7 +33,7 @@ jobs: # uploads of run results in SARIF format to the repository Actions tab. # https://docs.github.com/en/actions/advanced-guides/storing-workflow-data-as-artifacts - name: "Upload artifact" - uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0 + uses: actions/upload-artifact@4cec3d8aa04e39d1a68397de0c4cd6fb9dce8ec1 # v4.6.1 with: name: SARIF file path: results.sarif @@ -42,6 +42,6 @@ jobs: # Upload the results to GitHub's code scanning dashboard (optional). # Commenting out will disable upload of results to your repo's Code Scanning dashboard - name: "Upload to code-scanning" - uses: github/codeql-action/upload-sarif@9e8d0789d4a0fa9ceb6b1738f7e269594bdd67f0 # v3.28.9 + uses: github/codeql-action/upload-sarif@b56ba49b26e50535fa1e7f7db0f4f7b4bf65d80d # v3.28.10 with: sarif_file: results.sarif diff --git a/.github/workflows/owasp-dependency-check-daily.yml b/.github/workflows/owasp-dependency-check-daily.yml index 95302cf1172..cb2051d5521 100644 --- a/.github/workflows/owasp-dependency-check-daily.yml +++ b/.github/workflows/owasp-dependency-check-daily.yml @@ -31,7 +31,7 @@ jobs: - name: Upload report if: always() - uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0 + uses: actions/upload-artifact@4cec3d8aa04e39d1a68397de0c4cd6fb9dce8ec1 # v4.6.1 with: path: javaagent/build/reports diff --git a/integration-tests/tracecontext/docker/Dockerfile b/integration-tests/tracecontext/docker/Dockerfile index f6ab8d31482..c908887a8eb 100644 --- a/integration-tests/tracecontext/docker/Dockerfile +++ b/integration-tests/tracecontext/docker/Dockerfile @@ -1,4 +1,4 @@ -FROM python:3.13.2@sha256:589ed6659c0e4aac182f309131cd35e85452d21072570b1f6abc45b7687093a3 AS build +FROM python:3.13.2@sha256:08471c63c5fdf2644adc142a7fa8d0290eb405cda14c473fbe5b4cd0933af601 AS build # Main branch SHA as of April-1-2021 ARG TRACECONTEXT_GIT_TAG="dcd3ad9b7d6ac36f70ff3739874b73c11b0302a1" From b5daeb08710bb74ffd54a135baff420d1406a8b1 Mon Sep 17 00:00:00 2001 From: Trask Stalnaker Date: Mon, 24 Feb 2025 08:24:08 -0800 Subject: [PATCH 833/901] Fix otlp logging exporter test to be more realistic (#7136) --- .../opentelemetry/exporter/logging/otlp/TestDataExporter.java | 2 ++ .../logging-otlp/src/test/resources/expected-logs-wrapper.json | 2 -- exporters/logging-otlp/src/test/resources/expected-logs.json | 2 -- 3 files changed, 2 insertions(+), 4 deletions(-) diff --git a/exporters/logging-otlp/src/test/java/io/opentelemetry/exporter/logging/otlp/TestDataExporter.java b/exporters/logging-otlp/src/test/java/io/opentelemetry/exporter/logging/otlp/TestDataExporter.java index 63040a9beb1..8ef1c4ace44 100644 --- a/exporters/logging-otlp/src/test/java/io/opentelemetry/exporter/logging/otlp/TestDataExporter.java +++ b/exporters/logging-otlp/src/test/java/io/opentelemetry/exporter/logging/otlp/TestDataExporter.java @@ -62,6 +62,7 @@ abstract class TestDataExporter { .setTimestamp(100L, TimeUnit.NANOSECONDS) .setObservedTimestamp(200L, TimeUnit.NANOSECONDS) .setAttributes(Attributes.of(stringKey("animal"), "cat", longKey("lives"), 9L)) + .setTotalAttributeCount(2) .setSpanContext( SpanContext.create( "12345678876543211234567887654322", @@ -81,6 +82,7 @@ abstract class TestDataExporter { .setTimestamp(100L, TimeUnit.NANOSECONDS) .setObservedTimestamp(200L, TimeUnit.NANOSECONDS) .setAttributes(Attributes.of(booleanKey("important"), true)) + .setTotalAttributeCount(1) .setSpanContext( SpanContext.create( "12345678876543211234567887654322", diff --git a/exporters/logging-otlp/src/test/resources/expected-logs-wrapper.json b/exporters/logging-otlp/src/test/resources/expected-logs-wrapper.json index c298d824182..65767985bc2 100644 --- a/exporters/logging-otlp/src/test/resources/expected-logs-wrapper.json +++ b/exporters/logging-otlp/src/test/resources/expected-logs-wrapper.json @@ -49,7 +49,6 @@ } } ], - "droppedAttributesCount": -2, "traceId": "12345678876543211234567887654322", "spanId": "8765432112345876" } @@ -78,7 +77,6 @@ } } ], - "droppedAttributesCount": -1, "traceId": "12345678876543211234567887654322", "spanId": "8765432112345875" } diff --git a/exporters/logging-otlp/src/test/resources/expected-logs.json b/exporters/logging-otlp/src/test/resources/expected-logs.json index 6eae7f28ad3..f9bb36dd273 100644 --- a/exporters/logging-otlp/src/test/resources/expected-logs.json +++ b/exporters/logging-otlp/src/test/resources/expected-logs.json @@ -47,7 +47,6 @@ } } ], - "droppedAttributesCount": -2, "traceId": "12345678876543211234567887654322", "spanId": "8765432112345876" } @@ -76,7 +75,6 @@ } } ], - "droppedAttributesCount": -1, "traceId": "12345678876543211234567887654322", "spanId": "8765432112345875" } From f33cba3b1d5af6e949795c2403b1bac4966b0149 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 24 Feb 2025 11:15:47 -0600 Subject: [PATCH 834/901] fix(deps): update prometheusserverversion to v1.3.6 (#7107) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Co-authored-by: Jack Berg --- dependencyManagement/build.gradle.kts | 2 +- .../exporter/prometheus/PrometheusHttpServerTest.java | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index 748eab8de86..654cd41cc4e 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -35,7 +35,7 @@ val mockitoVersion = "4.11.0" val slf4jVersion = "2.0.16" val opencensusVersion = "0.31.1" val prometheusClientVersion = "0.16.0" -val prometheusServerVersion = "1.3.5" +val prometheusServerVersion = "1.3.6" val armeriaVersion = "1.31.3" val junitVersion = "5.11.4" diff --git a/exporters/prometheus/src/test/java/io/opentelemetry/exporter/prometheus/PrometheusHttpServerTest.java b/exporters/prometheus/src/test/java/io/opentelemetry/exporter/prometheus/PrometheusHttpServerTest.java index 4f69f2069be..b7aab6de939 100644 --- a/exporters/prometheus/src/test/java/io/opentelemetry/exporter/prometheus/PrometheusHttpServerTest.java +++ b/exporters/prometheus/src/test/java/io/opentelemetry/exporter/prometheus/PrometheusHttpServerTest.java @@ -42,9 +42,9 @@ import io.opentelemetry.sdk.resources.Resource; import io.prometheus.metrics.exporter.httpserver.HTTPServer; import io.prometheus.metrics.exporter.httpserver.MetricsHandler; -import io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics; +import io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics; import io.prometheus.metrics.model.registry.PrometheusRegistry; -import io.prometheus.metrics.shaded.com_google_protobuf_4_29_1.TextFormat; +import io.prometheus.metrics.shaded.com_google_protobuf_4_29_3.TextFormat; import java.io.ByteArrayInputStream; import java.io.IOException; import java.net.ServerSocket; From c91f56ece855be9d3ac59d53ad53dcd93e2397ba Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 24 Feb 2025 14:21:29 -0600 Subject: [PATCH 835/901] fix(deps): update dependency org.testcontainers:testcontainers-bom to v1.20.5 (#7124) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- dependencyManagement/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index 654cd41cc4e..834a469ac42 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -23,7 +23,7 @@ val DEPENDENCY_BOMS = listOf( "io.zipkin.brave:brave-bom:6.1.0", "io.zipkin.reporter2:zipkin-reporter-bom:3.5.0", "org.assertj:assertj-bom:3.27.3", - "org.testcontainers:testcontainers-bom:1.20.4", + "org.testcontainers:testcontainers-bom:1.20.5", "org.snakeyaml:snakeyaml-engine:2.9" ) From 80af8a33a0194d6b5ed3bbe0718031defe3e7844 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 24 Feb 2025 14:21:58 -0600 Subject: [PATCH 836/901] fix(deps): update dependency checkstyle to v10.21.3 (#7138) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- buildSrc/src/main/kotlin/otel.java-conventions.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/buildSrc/src/main/kotlin/otel.java-conventions.gradle.kts b/buildSrc/src/main/kotlin/otel.java-conventions.gradle.kts index a94892cf17d..e95dc6acc11 100644 --- a/buildSrc/src/main/kotlin/otel.java-conventions.gradle.kts +++ b/buildSrc/src/main/kotlin/otel.java-conventions.gradle.kts @@ -42,7 +42,7 @@ java { checkstyle { configDirectory.set(file("$rootDir/buildscripts/")) - toolVersion = "10.21.2" + toolVersion = "10.21.3" isIgnoreFailures = false configProperties["rootDir"] = rootDir } From 9f5b67b3c36b44aacb16eb9b5a3156ae431f51e3 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 24 Feb 2025 14:22:22 -0600 Subject: [PATCH 837/901] fix(deps): update junit5 monorepo to v5.12.0 (#7132) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- dependencyManagement/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index 834a469ac42..41010f246de 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -37,7 +37,7 @@ val opencensusVersion = "0.31.1" val prometheusClientVersion = "0.16.0" val prometheusServerVersion = "1.3.6" val armeriaVersion = "1.31.3" -val junitVersion = "5.11.4" +val junitVersion = "5.12.0" val DEPENDENCIES = listOf( "org.junit.jupiter:junit-jupiter-api:${junitVersion}", From 2de5a2c484868d308470ad3fea4aadf3ec59005b Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 24 Feb 2025 14:22:38 -0600 Subject: [PATCH 838/901] fix(deps): update dependency org.awaitility:awaitility to v4.3.0 (#7131) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- dependencyManagement/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index 41010f246de..97425d32ae1 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -90,7 +90,7 @@ val DEPENDENCIES = listOf( "io.opentracing:opentracing-noop:0.33.0", "junit:junit:4.13.2", "nl.jqno.equalsverifier:equalsverifier:3.19.1", - "org.awaitility:awaitility:4.2.2", + "org.awaitility:awaitility:4.3.0", "org.bouncycastle:bcpkix-jdk15on:1.70", "org.codehaus.mojo:animal-sniffer-annotations:1.24", "org.jctools:jctools-core:4.0.5", From 31f484f39f72d1bdfeccb0ee54278563273e1021 Mon Sep 17 00:00:00 2001 From: chukun Date: Tue, 25 Feb 2025 13:00:37 -0500 Subject: [PATCH 839/901] #6454 log warning and adjust maxExportBatchSize when exceeds maxQueueSize. (#7045) Co-authored-by: Jack Berg --- .../BatchLogRecordProcessorBuilder.java | 14 +++++++ .../export/BatchLogRecordProcessorTest.java | 42 +++++++++++++++++++ .../export/BatchSpanProcessorBuilder.java | 13 ++++++ .../trace/export/BatchSpanProcessorTest.java | 41 ++++++++++++++++++ 4 files changed, 110 insertions(+) diff --git a/sdk/logs/src/main/java/io/opentelemetry/sdk/logs/export/BatchLogRecordProcessorBuilder.java b/sdk/logs/src/main/java/io/opentelemetry/sdk/logs/export/BatchLogRecordProcessorBuilder.java index 40e53302e66..e809acb951a 100644 --- a/sdk/logs/src/main/java/io/opentelemetry/sdk/logs/export/BatchLogRecordProcessorBuilder.java +++ b/sdk/logs/src/main/java/io/opentelemetry/sdk/logs/export/BatchLogRecordProcessorBuilder.java @@ -11,6 +11,8 @@ import io.opentelemetry.api.metrics.MeterProvider; import java.time.Duration; import java.util.concurrent.TimeUnit; +import java.util.logging.Level; +import java.util.logging.Logger; /** * Builder class for {@link BatchLogRecordProcessor}. @@ -18,6 +20,8 @@ * @since 1.27.0 */ public final class BatchLogRecordProcessorBuilder { + private static final Logger logger = + Logger.getLogger(BatchLogRecordProcessorBuilder.class.getName()); // Visible for testing static final long DEFAULT_SCHEDULE_DELAY_MILLIS = 1000; @@ -103,6 +107,9 @@ long getExporterTimeoutNanos() { */ public BatchLogRecordProcessorBuilder setMaxQueueSize(int maxQueueSize) { checkArgument(maxQueueSize > 0, "maxQueueSize must be positive."); + if (maxExportBatchSize > maxQueueSize) { + logger.log(Level.WARNING, "maxExportBatchSize should not exceed maxQueueSize."); + } this.maxQueueSize = maxQueueSize; return this; } @@ -124,6 +131,9 @@ int getMaxQueueSize() { */ public BatchLogRecordProcessorBuilder setMaxExportBatchSize(int maxExportBatchSize) { checkArgument(maxExportBatchSize > 0, "maxExportBatchSize must be positive."); + if (maxExportBatchSize > maxQueueSize) { + logger.log(Level.WARNING, "maxExportBatchSize should not exceed maxQueueSize."); + } this.maxExportBatchSize = maxExportBatchSize; return this; } @@ -150,6 +160,10 @@ int getMaxExportBatchSize() { * @return a new {@link BatchLogRecordProcessor}. */ public BatchLogRecordProcessor build() { + if (maxExportBatchSize > maxQueueSize) { + maxExportBatchSize = maxQueueSize; + logger.log(Level.FINE, "Using maxExportBatchSize: {0}", maxExportBatchSize); + } return new BatchLogRecordProcessor( logRecordExporter, meterProvider, diff --git a/sdk/logs/src/test/java/io/opentelemetry/sdk/logs/export/BatchLogRecordProcessorTest.java b/sdk/logs/src/test/java/io/opentelemetry/sdk/logs/export/BatchLogRecordProcessorTest.java index e051eaf175a..4f388a5ca49 100644 --- a/sdk/logs/src/test/java/io/opentelemetry/sdk/logs/export/BatchLogRecordProcessorTest.java +++ b/sdk/logs/src/test/java/io/opentelemetry/sdk/logs/export/BatchLogRecordProcessorTest.java @@ -10,10 +10,13 @@ import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.assertj.core.api.AssertionsForClassTypes.assertThatCode; import static org.awaitility.Awaitility.await; +import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyList; import static org.mockito.ArgumentMatchers.argThat; import static org.mockito.Mockito.doThrow; import static org.mockito.Mockito.reset; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import io.opentelemetry.api.internal.GuardedBy; @@ -21,6 +24,7 @@ import io.opentelemetry.sdk.common.CompletableResultCode; import io.opentelemetry.sdk.logs.SdkLoggerProvider; import io.opentelemetry.sdk.logs.data.LogRecordData; +import java.time.Duration; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; @@ -117,6 +121,44 @@ void builderInvalidConfig() { .hasMessage("maxQueueSize must be positive."); } + @Test + void builderAdjustMaxBatchSize() { + LogRecordExporter dummyExporter = new CompletableLogRecordExporter(); + + BatchLogRecordProcessorBuilder builder = + BatchLogRecordProcessor.builder(dummyExporter) + .setMaxQueueSize(513) + .setMaxExportBatchSize(1000); + builder.build(); + + assertThat(builder.getMaxExportBatchSize()).isEqualTo(513); + assertThat(builder.getMaxQueueSize()).isEqualTo(513); + } + + @Test + void maxExportBatchSizeExceedsQueueSize() throws InterruptedException { + // Given a processor configured with a maxExportBatchSize > maxQueueSize, ensure that after n = + // maxQueueSize logs are emitted, export is triggered and that the queue is fully drained and + // exported. + int maxQueueSize = 2048; + when(mockLogRecordExporter.export(any())).thenReturn(CompletableResultCode.ofSuccess()); + SdkLoggerProvider sdkLoggerProvider = + SdkLoggerProvider.builder() + .addLogRecordProcessor( + BatchLogRecordProcessor.builder(mockLogRecordExporter) + .setScheduleDelay(Duration.ofSeconds(Integer.MAX_VALUE)) + .setMaxExportBatchSize(2049) + .setMaxQueueSize(maxQueueSize) + .build()) + .build(); + + for (int i = 0; i < maxQueueSize; i++) { + emitLog(sdkLoggerProvider, "log " + i); + } + + await().untilAsserted(() -> verify(mockLogRecordExporter, times(1)).export(any())); + } + @Test void emitMultipleLogs() { WaitingLogRecordExporter waitingLogRecordExporter = diff --git a/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/export/BatchSpanProcessorBuilder.java b/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/export/BatchSpanProcessorBuilder.java index 8e9fe970d56..f968e35594a 100644 --- a/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/export/BatchSpanProcessorBuilder.java +++ b/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/export/BatchSpanProcessorBuilder.java @@ -11,9 +11,12 @@ import io.opentelemetry.api.metrics.MeterProvider; import java.time.Duration; import java.util.concurrent.TimeUnit; +import java.util.logging.Level; +import java.util.logging.Logger; /** Builder class for {@link BatchSpanProcessor}. */ public final class BatchSpanProcessorBuilder { + private static final Logger logger = Logger.getLogger(BatchSpanProcessorBuilder.class.getName()); // Visible for testing static final long DEFAULT_SCHEDULE_DELAY_MILLIS = 5000; @@ -111,6 +114,9 @@ long getExporterTimeoutNanos() { */ public BatchSpanProcessorBuilder setMaxQueueSize(int maxQueueSize) { checkArgument(maxQueueSize > 0, "maxQueueSize must be positive."); + if (maxExportBatchSize > maxQueueSize) { + logger.log(Level.WARNING, "maxExportBatchSize should not exceed maxQueueSize."); + } this.maxQueueSize = maxQueueSize; return this; } @@ -132,6 +138,9 @@ int getMaxQueueSize() { */ public BatchSpanProcessorBuilder setMaxExportBatchSize(int maxExportBatchSize) { checkArgument(maxExportBatchSize > 0, "maxExportBatchSize must be positive."); + if (maxExportBatchSize > maxQueueSize) { + logger.log(Level.WARNING, "maxExportBatchSize should not exceed maxQueueSize."); + } this.maxExportBatchSize = maxExportBatchSize; return this; } @@ -158,6 +167,10 @@ int getMaxExportBatchSize() { * @return a new {@link BatchSpanProcessor}. */ public BatchSpanProcessor build() { + if (maxExportBatchSize > maxQueueSize) { + maxExportBatchSize = maxQueueSize; + logger.log(Level.FINE, "Using maxExportBatchSize: {0}", maxExportBatchSize); + } return new BatchSpanProcessor( spanExporter, exportUnsampledSpans, diff --git a/sdk/trace/src/test/java/io/opentelemetry/sdk/trace/export/BatchSpanProcessorTest.java b/sdk/trace/src/test/java/io/opentelemetry/sdk/trace/export/BatchSpanProcessorTest.java index 23b8874790c..89aff56d9c7 100644 --- a/sdk/trace/src/test/java/io/opentelemetry/sdk/trace/export/BatchSpanProcessorTest.java +++ b/sdk/trace/src/test/java/io/opentelemetry/sdk/trace/export/BatchSpanProcessorTest.java @@ -14,6 +14,8 @@ import static org.mockito.ArgumentMatchers.argThat; import static org.mockito.Mockito.doThrow; import static org.mockito.Mockito.reset; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import io.opentelemetry.api.internal.GuardedBy; @@ -26,6 +28,7 @@ import io.opentelemetry.sdk.trace.data.SpanData; import io.opentelemetry.sdk.trace.samplers.Sampler; import io.opentelemetry.sdk.trace.samplers.SamplingResult; +import java.time.Duration; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; @@ -126,6 +129,44 @@ void builderInvalidConfig() { .hasMessage("maxQueueSize must be positive."); } + @Test + void builderAdjustMaxBatchSize() { + SpanExporter dummyExporter = new CompletableSpanExporter(); + + BatchSpanProcessorBuilder builder = + BatchSpanProcessor.builder(dummyExporter).setMaxQueueSize(513).setMaxExportBatchSize(1000); + builder.build(); + + assertThat(builder.getMaxExportBatchSize()).isEqualTo(513); + assertThat(builder.getMaxQueueSize()).isEqualTo(513); + } + + @Test + void maxExportBatchSizeExceedsQueueSize() throws InterruptedException { + // Given a processor configured with a maxExportBatchSize > maxQueueSize, ensure that after n = + // maxQueueSize spans are ended, export is triggered and that the queue is fully drained and + // exported. + int maxQueueSize = 2048; + when(mockSpanExporter.export(any())).thenReturn(CompletableResultCode.ofSuccess()); + sdkTracerProvider = + SdkTracerProvider.builder() + .addSpanProcessor( + BatchSpanProcessor.builder(mockSpanExporter) + .setScheduleDelay(Duration.ofSeconds(Integer.MAX_VALUE)) + .setMaxExportBatchSize(2049) + .setMaxQueueSize(maxQueueSize) + .build()) + .build(); + + for (int i = 0; i < maxQueueSize; i++) { + createEndedSpan("span " + i); + } + + Thread.sleep(10); + + await().untilAsserted(() -> verify(mockSpanExporter, times(1)).export(any())); + } + @Test void startEndRequirements() { BatchSpanProcessor spansProcessor = From 3d3bff5bda625e9a8a6d0403625e9fc4b1606b22 Mon Sep 17 00:00:00 2001 From: jack-berg <34418638+jack-berg@users.noreply.github.com> Date: Wed, 26 Feb 2025 16:26:59 -0600 Subject: [PATCH 840/901] Fix bug preventing accurate reporting of dropped attribute count (#7142) --- .../sdk/internal/AttributesMap.java | 21 +++++++++++++++---- .../io/opentelemetry/sdk/trace/SdkSpan.java | 1 + .../opentelemetry/sdk/trace/SdkSpanTest.java | 19 ++++++++++++++++- 3 files changed, 36 insertions(+), 5 deletions(-) diff --git a/sdk/common/src/main/java/io/opentelemetry/sdk/internal/AttributesMap.java b/sdk/common/src/main/java/io/opentelemetry/sdk/internal/AttributesMap.java index 735d5eb1341..9616eb75fcf 100644 --- a/sdk/common/src/main/java/io/opentelemetry/sdk/internal/AttributesMap.java +++ b/sdk/common/src/main/java/io/opentelemetry/sdk/internal/AttributesMap.java @@ -18,6 +18,14 @@ * A map with a fixed capacity that drops attributes when the map gets full, and which truncates * string and array string attribute values to the {@link #lengthLimit}. * + *

      WARNING: In order to reduce memory allocation, this class extends {@link HashMap} when it + * would be more appropriate to delegate. The problem with extending is that we don't enforce that + * all {@link HashMap} methods for reading / writing data conform to the configured attribute + * limits. Therefore, it's easy to accidentally call something like {@link Map#putAll(Map)} or + * {@link Map#put(Object, Object)} and bypass the restrictions (see #7135). Callers MUST + * take care to only call methods from {@link AttributesMap}, and not {@link HashMap}. + * *

      This class is internal and is hence not for public use. Its APIs are unstable and can change * at any time. */ @@ -44,13 +52,18 @@ public static AttributesMap create(long capacity, int lengthLimit) { return new AttributesMap(capacity, lengthLimit); } - /** Add the attribute key value pair, applying capacity and length limits. */ - public void put(AttributeKey key, T value) { + /** + * Add the attribute key value pair, applying capacity and length limits. Callers MUST ensure the + * {@code value} type matches the type required by {@code key}. + */ + @Override + @Nullable + public Object put(AttributeKey key, Object value) { totalAddedValues++; if (size() >= capacity && !containsKey(key)) { - return; + return null; } - super.put(key, AttributeUtil.applyAttributeLengthLimit(value, lengthLimit)); + return super.put(key, AttributeUtil.applyAttributeLengthLimit(value, lengthLimit)); } /** Get the total number of attributes added, including those dropped for capcity limits. */ diff --git a/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/SdkSpan.java b/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/SdkSpan.java index f3821c55540..c1c788bf931 100644 --- a/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/SdkSpan.java +++ b/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/SdkSpan.java @@ -466,6 +466,7 @@ public ReadWriteSpan recordException(Throwable exception) { } @Override + @SuppressWarnings("unchecked") public ReadWriteSpan recordException(Throwable exception, Attributes additionalAttributes) { if (exception == null) { return this; diff --git a/sdk/trace/src/test/java/io/opentelemetry/sdk/trace/SdkSpanTest.java b/sdk/trace/src/test/java/io/opentelemetry/sdk/trace/SdkSpanTest.java index 180fd377b0c..fb387cf2a18 100644 --- a/sdk/trace/src/test/java/io/opentelemetry/sdk/trace/SdkSpanTest.java +++ b/sdk/trace/src/test/java/io/opentelemetry/sdk/trace/SdkSpanTest.java @@ -1277,6 +1277,21 @@ void recordException_additionalAttributes() { }); } + @Test + void recordException_SpanLimits() { + SdkSpan span = createTestSpan(SpanLimits.builder().setMaxNumberOfAttributes(2).build()); + span.recordException( + new IllegalStateException("error"), + Attributes.builder().put("key1", "value").put("key2", "value").build()); + + List events = span.toSpanData().getEvents(); + assertThat(events.size()).isEqualTo(1); + EventData event = events.get(0); + assertThat(event.getAttributes().size()).isEqualTo(2); + assertThat(event.getTotalAttributeCount()).isEqualTo(5); + assertThat(event.getTotalAttributeCount() - event.getAttributes().size()).isPositive(); + } + @Test void badArgsIgnored() { SdkSpan span = createTestRootSpan(); @@ -1519,7 +1534,9 @@ void testAsSpanData() { Resource resource = this.resource; Attributes attributes = TestUtils.generateRandomAttributes(); AttributesMap attributesWithCapacity = AttributesMap.create(32, Integer.MAX_VALUE); - attributes.forEach(attributesWithCapacity::put); + attributes.forEach( + (attributeKey, object) -> + attributesWithCapacity.put((AttributeKey) attributeKey, object)); Attributes event1Attributes = TestUtils.generateRandomAttributes(); Attributes event2Attributes = TestUtils.generateRandomAttributes(); SpanContext context = From 5a10b685d41c7413b3d30b5cfd956b3944193436 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 26 Feb 2025 17:16:40 -0600 Subject: [PATCH 841/901] fix(deps): update dependency io.netty:netty-bom to v4.1.119.final (#7149) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- dependencyManagement/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index 97425d32ae1..30e2f65e65e 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -19,7 +19,7 @@ val DEPENDENCY_BOMS = listOf( "com.squareup.okhttp3:okhttp-bom:4.12.0", "com.squareup.okio:okio-bom:3.10.2", // applies to transitive dependencies of okhttp "io.grpc:grpc-bom:1.70.0", - "io.netty:netty-bom:4.1.118.Final", + "io.netty:netty-bom:4.1.119.Final", "io.zipkin.brave:brave-bom:6.1.0", "io.zipkin.reporter2:zipkin-reporter-bom:3.5.0", "org.assertj:assertj-bom:3.27.3", From 865c89f47dee869e03b1bd4a3e99a2e213dd1ce8 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 26 Feb 2025 17:17:00 -0600 Subject: [PATCH 842/901] fix(deps): update dependency com.google.api.grpc:proto-google-common-protos to v2.53.0 (#7147) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- dependencyManagement/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index 30e2f65e65e..b57d5fcf283 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -73,7 +73,7 @@ val DEPENDENCIES = listOf( "io.prometheus:simpleclient_httpserver:${prometheusClientVersion}", "javax.annotation:javax.annotation-api:1.3.2", "com.github.stefanbirkner:system-rules:1.19.0", - "com.google.api.grpc:proto-google-common-protos:2.52.0", + "com.google.api.grpc:proto-google-common-protos:2.53.0", "com.google.code.findbugs:jsr305:3.0.2", "com.google.guava:guava-beta-checker:1.0", "com.sun.net.httpserver:http:20070405", From 313d391e558598006f9a858a355105a24864d7bf Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 26 Feb 2025 17:17:18 -0600 Subject: [PATCH 843/901] fix(deps): update slf4j monorepo to v2.0.17 (#7146) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- dependencyManagement/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index b57d5fcf283..c5aff71797f 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -32,7 +32,7 @@ val errorProneVersion = "2.36.0" val jmhVersion = "1.37" // Mockito 5.x.x requires Java 11 https://github.com/mockito/mockito/releases/tag/v5.0.0 val mockitoVersion = "4.11.0" -val slf4jVersion = "2.0.16" +val slf4jVersion = "2.0.17" val opencensusVersion = "0.31.1" val prometheusClientVersion = "0.16.0" val prometheusServerVersion = "1.3.6" From cd1f61725c4ff3a312a42f7cea3bc9f04ef82435 Mon Sep 17 00:00:00 2001 From: jack-berg <34418638+jack-berg@users.noreply.github.com> Date: Thu, 27 Feb 2025 10:57:03 -0600 Subject: [PATCH 844/901] Suppress a variety of noisy test logs (#7154) --- .../logging/otlp/internal/writer/LoggerJsonWriterTest.java | 2 ++ .../logging/otlp/internal/writer/StreamJsonWriterTest.java | 2 ++ .../exporter/prometheus/PrometheusHttpServerTest.java | 1 + .../sdk/autoconfigure/ResourceConfigurationTest.java | 2 ++ .../sdk/metrics/internal/view/ViewRegistryTest.java | 1 + 5 files changed, 8 insertions(+) diff --git a/exporters/logging-otlp/src/test/java/io/opentelemetry/exporter/logging/otlp/internal/writer/LoggerJsonWriterTest.java b/exporters/logging-otlp/src/test/java/io/opentelemetry/exporter/logging/otlp/internal/writer/LoggerJsonWriterTest.java index 0810f3c7510..680c7cc444d 100644 --- a/exporters/logging-otlp/src/test/java/io/opentelemetry/exporter/logging/otlp/internal/writer/LoggerJsonWriterTest.java +++ b/exporters/logging-otlp/src/test/java/io/opentelemetry/exporter/logging/otlp/internal/writer/LoggerJsonWriterTest.java @@ -12,12 +12,14 @@ import com.fasterxml.jackson.core.JsonGenerator; import io.github.netmikey.logunit.api.LogCapturer; import io.opentelemetry.exporter.internal.marshal.Marshaler; +import io.opentelemetry.internal.testing.slf4j.SuppressLogger; import java.io.IOException; import java.util.logging.Logger; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.RegisterExtension; import org.mockito.Mockito; +@SuppressLogger(LoggerJsonWriter.class) class LoggerJsonWriterTest { @RegisterExtension diff --git a/exporters/logging-otlp/src/test/java/io/opentelemetry/exporter/logging/otlp/internal/writer/StreamJsonWriterTest.java b/exporters/logging-otlp/src/test/java/io/opentelemetry/exporter/logging/otlp/internal/writer/StreamJsonWriterTest.java index eabfbc53517..048fcab1c17 100644 --- a/exporters/logging-otlp/src/test/java/io/opentelemetry/exporter/logging/otlp/internal/writer/StreamJsonWriterTest.java +++ b/exporters/logging-otlp/src/test/java/io/opentelemetry/exporter/logging/otlp/internal/writer/StreamJsonWriterTest.java @@ -12,6 +12,7 @@ import com.fasterxml.jackson.core.JsonGenerator; import io.github.netmikey.logunit.api.LogCapturer; import io.opentelemetry.exporter.internal.marshal.Marshaler; +import io.opentelemetry.internal.testing.slf4j.SuppressLogger; import java.io.FilterOutputStream; import java.io.IOException; import java.io.OutputStream; @@ -23,6 +24,7 @@ import org.mockito.Mockito; @SuppressWarnings("SystemOut") +@SuppressLogger(StreamJsonWriter.class) class StreamJsonWriterTest { @RegisterExtension diff --git a/exporters/prometheus/src/test/java/io/opentelemetry/exporter/prometheus/PrometheusHttpServerTest.java b/exporters/prometheus/src/test/java/io/opentelemetry/exporter/prometheus/PrometheusHttpServerTest.java index b7aab6de939..e78000f4aec 100644 --- a/exporters/prometheus/src/test/java/io/opentelemetry/exporter/prometheus/PrometheusHttpServerTest.java +++ b/exporters/prometheus/src/test/java/io/opentelemetry/exporter/prometheus/PrometheusHttpServerTest.java @@ -345,6 +345,7 @@ void fetchHealth() { @Test @SuppressLogger(PrometheusHttpServer.class) + @SuppressLogger(Otel2PrometheusConverter.class) void fetch_DuplicateMetrics() { Resource resource = Resource.create(Attributes.of(stringKey("kr"), "vr")); metricData.set( diff --git a/sdk-extensions/autoconfigure/src/testFullConfig/java/io/opentelemetry/sdk/autoconfigure/ResourceConfigurationTest.java b/sdk-extensions/autoconfigure/src/testFullConfig/java/io/opentelemetry/sdk/autoconfigure/ResourceConfigurationTest.java index 785fd23cbac..ae2342aeff9 100644 --- a/sdk-extensions/autoconfigure/src/testFullConfig/java/io/opentelemetry/sdk/autoconfigure/ResourceConfigurationTest.java +++ b/sdk-extensions/autoconfigure/src/testFullConfig/java/io/opentelemetry/sdk/autoconfigure/ResourceConfigurationTest.java @@ -9,6 +9,7 @@ import io.opentelemetry.api.common.AttributeKey; import io.opentelemetry.api.common.Attributes; +import io.opentelemetry.internal.testing.slf4j.SuppressLogger; import io.opentelemetry.sdk.autoconfigure.internal.SpiHelper; import io.opentelemetry.sdk.autoconfigure.spi.internal.DefaultConfigProperties; import io.opentelemetry.sdk.testing.assertj.AttributesAssert; @@ -25,6 +26,7 @@ import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.MethodSource; +@SuppressLogger(ResourceConfiguration.class) class ResourceConfigurationTest { private final SpiHelper spiHelper = diff --git a/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/internal/view/ViewRegistryTest.java b/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/internal/view/ViewRegistryTest.java index 8eb4997fb76..ee1a61d1d35 100644 --- a/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/internal/view/ViewRegistryTest.java +++ b/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/internal/view/ViewRegistryTest.java @@ -434,6 +434,7 @@ void defaults() { } @Test + @SuppressLogger(ViewRegistry.class) void findViews_ApplyAdvice() { // use incompatible aggregation for histogram DefaultAggregationSelector aggregationSelector = From 3dd7134f814b5d22f66f23c0347a8809450210fb Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 28 Feb 2025 09:10:44 -0800 Subject: [PATCH 845/901] fix(deps): update dependency com.android.tools:desugar_jdk_libs to v2.1.5 (#7144) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- dependencyManagement/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index c5aff71797f..608f305bf2d 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -97,7 +97,7 @@ val DEPENDENCIES = listOf( "org.junit-pioneer:junit-pioneer:1.9.1", "org.mock-server:mockserver-netty:5.15.0:shaded", "org.skyscreamer:jsonassert:1.5.3", - "com.android.tools:desugar_jdk_libs:2.1.4", + "com.android.tools:desugar_jdk_libs:2.1.5", ) javaPlatform { From 173e80b9c2fbd6ab33d03b667f03133026e7be79 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 28 Feb 2025 16:03:43 -0800 Subject: [PATCH 846/901] chore(deps): update dependency gradle to v8.13 (#7145) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- gradle/wrapper/gradle-wrapper.properties | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index d71047787f8..36e4933e1da 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,7 +1,7 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionSha256Sum=8d97a97984f6cbd2b85fe4c60a743440a347544bf18818048e611f5288d46c94 -distributionUrl=https\://services.gradle.org/distributions/gradle-8.12.1-bin.zip +distributionSha256Sum=20f1b1176237254a6fc204d8434196fa11a4cfb387567519c61556e8710aed78 +distributionUrl=https\://services.gradle.org/distributions/gradle-8.13-bin.zip networkTimeout=10000 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME From d1ce438e00832f1fb354ce55ec3abdf86abbc28e Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 28 Feb 2025 16:04:13 -0800 Subject: [PATCH 847/901] fix(deps): update dependency com.uber.nullaway:nullaway to v0.12.4 (#7158) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- dependencyManagement/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index 608f305bf2d..c801a9a44a1 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -78,7 +78,7 @@ val DEPENDENCIES = listOf( "com.google.guava:guava-beta-checker:1.0", "com.sun.net.httpserver:http:20070405", "com.tngtech.archunit:archunit-junit5:1.4.0", - "com.uber.nullaway:nullaway:0.12.3", + "com.uber.nullaway:nullaway:0.12.4", "edu.berkeley.cs.jqf:jqf-fuzz:1.7", // jqf-fuzz version 1.8+ requires Java 11+ "eu.rekawek.toxiproxy:toxiproxy-java:2.1.7", "io.github.netmikey.logunit:logunit-jul:2.0.0", From dc46ccd2c9618a06a374dbb31e38d6397cc69f8c Mon Sep 17 00:00:00 2001 From: jack-berg <34418638+jack-berg@users.noreply.github.com> Date: Mon, 3 Mar 2025 17:01:10 -0600 Subject: [PATCH 848/901] Add support for setting OTLP exporter service class loader (#7150) --- .../opentelemetry-exporter-otlp.txt | 19 +++++++++- .../internal/grpc/GrpcExporterBuilder.java | 11 ++++-- .../internal/http/HttpExporterBuilder.java | 11 ++++-- .../OtlpHttpLogRecordExporterBuilder.java | 7 ++++ .../OtlpHttpMetricExporterBuilder.java | 7 ++++ .../trace/OtlpHttpSpanExporterBuilder.java | 7 ++++ .../OtlpGrpcLogRecordExporterBuilder.java | 7 ++++ .../OtlpGrpcMetricExporterBuilder.java | 7 ++++ .../trace/OtlpGrpcSpanExporterBuilder.java | 7 ++++ .../AbstractGrpcTelemetryExporterTest.java | 35 +++++++++++++++++++ .../AbstractHttpTelemetryExporterTest.java | 35 +++++++++++++++++++ .../GrpcLogRecordExporterBuilderWrapper.java | 7 ++++ .../GrpcMetricExporterBuilderWrapper.java | 7 ++++ .../GrpcSpanExporterBuilderWrapper.java | 6 ++++ .../HttpLogRecordExporterBuilderWrapper.java | 7 ++++ .../HttpMetricExporterBuilderWrapper.java | 7 ++++ .../HttpSpanExporterBuilderWrapper.java | 6 ++++ ...anagedChannelTelemetryExporterBuilder.java | 6 ++++ .../internal/TelemetryExporterBuilder.java | 2 ++ 19 files changed, 196 insertions(+), 5 deletions(-) diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-otlp.txt b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-otlp.txt index 27040235c7a..5345e196089 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-otlp.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-otlp.txt @@ -1,2 +1,19 @@ Comparing source compatibility of opentelemetry-exporter-otlp-1.48.0-SNAPSHOT.jar against opentelemetry-exporter-otlp-1.47.0.jar -No changes. \ No newline at end of file +*** MODIFIED CLASS: PUBLIC FINAL io.opentelemetry.exporter.otlp.http.logs.OtlpHttpLogRecordExporterBuilder (not serializable) + === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 + +++ NEW METHOD: PUBLIC(+) io.opentelemetry.exporter.otlp.http.logs.OtlpHttpLogRecordExporterBuilder setServiceClassLoader(java.lang.ClassLoader) +*** MODIFIED CLASS: PUBLIC FINAL io.opentelemetry.exporter.otlp.http.metrics.OtlpHttpMetricExporterBuilder (not serializable) + === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 + +++ NEW METHOD: PUBLIC(+) io.opentelemetry.exporter.otlp.http.metrics.OtlpHttpMetricExporterBuilder setServiceClassLoader(java.lang.ClassLoader) +*** MODIFIED CLASS: PUBLIC FINAL io.opentelemetry.exporter.otlp.http.trace.OtlpHttpSpanExporterBuilder (not serializable) + === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 + +++ NEW METHOD: PUBLIC(+) io.opentelemetry.exporter.otlp.http.trace.OtlpHttpSpanExporterBuilder setServiceClassLoader(java.lang.ClassLoader) +*** MODIFIED CLASS: PUBLIC FINAL io.opentelemetry.exporter.otlp.logs.OtlpGrpcLogRecordExporterBuilder (not serializable) + === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 + +++ NEW METHOD: PUBLIC(+) io.opentelemetry.exporter.otlp.logs.OtlpGrpcLogRecordExporterBuilder setServiceClassLoader(java.lang.ClassLoader) +*** MODIFIED CLASS: PUBLIC FINAL io.opentelemetry.exporter.otlp.metrics.OtlpGrpcMetricExporterBuilder (not serializable) + === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 + +++ NEW METHOD: PUBLIC(+) io.opentelemetry.exporter.otlp.metrics.OtlpGrpcMetricExporterBuilder setServiceClassLoader(java.lang.ClassLoader) +*** MODIFIED CLASS: PUBLIC FINAL io.opentelemetry.exporter.otlp.trace.OtlpGrpcSpanExporterBuilder (not serializable) + === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 + +++ NEW METHOD: PUBLIC(+) io.opentelemetry.exporter.otlp.trace.OtlpGrpcSpanExporterBuilder setServiceClassLoader(java.lang.ClassLoader) diff --git a/exporters/common/src/main/java/io/opentelemetry/exporter/internal/grpc/GrpcExporterBuilder.java b/exporters/common/src/main/java/io/opentelemetry/exporter/internal/grpc/GrpcExporterBuilder.java index 3ddf45c03e4..1720b0e417b 100644 --- a/exporters/common/src/main/java/io/opentelemetry/exporter/internal/grpc/GrpcExporterBuilder.java +++ b/exporters/common/src/main/java/io/opentelemetry/exporter/internal/grpc/GrpcExporterBuilder.java @@ -62,6 +62,7 @@ public class GrpcExporterBuilder { private TlsConfigHelper tlsConfigHelper = new TlsConfigHelper(); @Nullable private RetryPolicy retryPolicy = RetryPolicy.getDefault(); private Supplier meterProviderSupplier = GlobalOpenTelemetry::getMeterProvider; + private ClassLoader serviceClassLoader = GrpcExporterBuilder.class.getClassLoader(); // Use Object type since gRPC may not be on the classpath. @Nullable private Object grpcChannel; @@ -147,6 +148,11 @@ public GrpcExporterBuilder setMeterProvider(Supplier meterProv return this; } + public GrpcExporterBuilder setServiceClassLoader(ClassLoader servieClassLoader) { + this.serviceClassLoader = servieClassLoader; + return this; + } + @SuppressWarnings("BuilderReturnThis") public GrpcExporterBuilder copy() { GrpcExporterBuilder copy = @@ -242,6 +248,7 @@ public String toString(boolean includePrefixAndSuffix) { if (grpcChannel != null) { joiner.add("grpcChannel=" + grpcChannel); } + joiner.add("serviceClassLoader=" + serviceClassLoader); // Note: omit tlsConfigHelper because we can't log the configuration in any readable way // Note: omit meterProviderSupplier because we can't log the configuration in any readable way return joiner.toString(); @@ -268,10 +275,10 @@ public String toString() { * matching provider. If none match, throw {@link IllegalStateException}. * */ - private static GrpcSenderProvider resolveGrpcSenderProvider() { + private GrpcSenderProvider resolveGrpcSenderProvider() { Map grpcSenderProviders = new HashMap<>(); for (GrpcSenderProvider spi : - ServiceLoader.load(GrpcSenderProvider.class, GrpcExporterBuilder.class.getClassLoader())) { + ServiceLoader.load(GrpcSenderProvider.class, serviceClassLoader)) { grpcSenderProviders.put(spi.getClass().getName(), spi); } diff --git a/exporters/common/src/main/java/io/opentelemetry/exporter/internal/http/HttpExporterBuilder.java b/exporters/common/src/main/java/io/opentelemetry/exporter/internal/http/HttpExporterBuilder.java index a82da5afc9a..f38450ca6e8 100644 --- a/exporters/common/src/main/java/io/opentelemetry/exporter/internal/http/HttpExporterBuilder.java +++ b/exporters/common/src/main/java/io/opentelemetry/exporter/internal/http/HttpExporterBuilder.java @@ -60,6 +60,7 @@ public final class HttpExporterBuilder { private TlsConfigHelper tlsConfigHelper = new TlsConfigHelper(); @Nullable private RetryPolicy retryPolicy = RetryPolicy.getDefault(); private Supplier meterProviderSupplier = GlobalOpenTelemetry::getMeterProvider; + private ClassLoader serviceClassLoader = HttpExporterBuilder.class.getClassLoader(); public HttpExporterBuilder(String exporterName, String type, String defaultEndpoint) { this.exporterName = exporterName; @@ -131,6 +132,11 @@ public HttpExporterBuilder setProxyOptions(ProxyOptions proxyOptions) { return this; } + public HttpExporterBuilder setServiceClassLoader(ClassLoader servieClassLoader) { + this.serviceClassLoader = servieClassLoader; + return this; + } + public HttpExporterBuilder exportAsJson() { this.exportAsJson = true; return this; @@ -222,6 +228,7 @@ public String toString(boolean includePrefixAndSuffix) { if (retryPolicy != null) { joiner.add("retryPolicy=" + retryPolicy); } + joiner.add("serviceClassLoader=" + serviceClassLoader); // Note: omit tlsConfigHelper because we can't log the configuration in any readable way // Note: omit meterProviderSupplier because we can't log the configuration in any readable way return joiner.toString(); @@ -248,10 +255,10 @@ public String toString() { * matching provider. If none match, throw {@link IllegalStateException}. * */ - private static HttpSenderProvider resolveHttpSenderProvider() { + private HttpSenderProvider resolveHttpSenderProvider() { Map httpSenderProviders = new HashMap<>(); for (HttpSenderProvider spi : - ServiceLoader.load(HttpSenderProvider.class, HttpExporterBuilder.class.getClassLoader())) { + ServiceLoader.load(HttpSenderProvider.class, serviceClassLoader)) { httpSenderProviders.put(spi.getClass().getName(), spi); } diff --git a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/logs/OtlpHttpLogRecordExporterBuilder.java b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/logs/OtlpHttpLogRecordExporterBuilder.java index 0602cf2b506..2b260643e4b 100644 --- a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/logs/OtlpHttpLogRecordExporterBuilder.java +++ b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/logs/OtlpHttpLogRecordExporterBuilder.java @@ -225,6 +225,13 @@ public OtlpHttpLogRecordExporterBuilder setMemoryMode(MemoryMode memoryMode) { return this; } + /** Set the {@link ClassLoader} used to load the sender API. */ + public OtlpHttpLogRecordExporterBuilder setServiceClassLoader(ClassLoader serviceClassLoader) { + requireNonNull(serviceClassLoader, "serviceClassLoader"); + delegate.setServiceClassLoader(serviceClassLoader); + return this; + } + /** * Constructs a new instance of the exporter based on the builder's values. * diff --git a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/metrics/OtlpHttpMetricExporterBuilder.java b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/metrics/OtlpHttpMetricExporterBuilder.java index e0cb6f4a493..36c0b0fc71a 100644 --- a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/metrics/OtlpHttpMetricExporterBuilder.java +++ b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/metrics/OtlpHttpMetricExporterBuilder.java @@ -253,6 +253,13 @@ public OtlpHttpMetricExporterBuilder setMemoryMode(MemoryMode memoryMode) { return this; } + /** Set the {@link ClassLoader} used to load the sender API. */ + public OtlpHttpMetricExporterBuilder setServiceClassLoader(ClassLoader serviceClassLoader) { + requireNonNull(serviceClassLoader, "serviceClassLoader"); + delegate.setServiceClassLoader(serviceClassLoader); + return this; + } + OtlpHttpMetricExporterBuilder exportAsJson() { delegate.exportAsJson(); return this; diff --git a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/trace/OtlpHttpSpanExporterBuilder.java b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/trace/OtlpHttpSpanExporterBuilder.java index fb547af942a..88674f9230e 100644 --- a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/trace/OtlpHttpSpanExporterBuilder.java +++ b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/trace/OtlpHttpSpanExporterBuilder.java @@ -226,6 +226,13 @@ public OtlpHttpSpanExporterBuilder setMemoryMode(MemoryMode memoryMode) { return this; } + /** Set the {@link ClassLoader} used to load the sender API. */ + public OtlpHttpSpanExporterBuilder setServiceClassLoader(ClassLoader serviceClassLoader) { + requireNonNull(serviceClassLoader, "serviceClassLoader"); + delegate.setServiceClassLoader(serviceClassLoader); + return this; + } + /** * Constructs a new instance of the exporter based on the builder's values. * diff --git a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/logs/OtlpGrpcLogRecordExporterBuilder.java b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/logs/OtlpGrpcLogRecordExporterBuilder.java index 2ab6e29be09..6ff1999d47a 100644 --- a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/logs/OtlpGrpcLogRecordExporterBuilder.java +++ b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/logs/OtlpGrpcLogRecordExporterBuilder.java @@ -258,6 +258,13 @@ public OtlpGrpcLogRecordExporterBuilder setMemoryMode(MemoryMode memoryMode) { return this; } + /** Set the {@link ClassLoader} used to load the sender API. */ + public OtlpGrpcLogRecordExporterBuilder setServiceClassLoader(ClassLoader serviceClassLoader) { + requireNonNull(serviceClassLoader, "serviceClassLoader"); + delegate.setServiceClassLoader(serviceClassLoader); + return this; + } + /** * Constructs a new instance of the exporter based on the builder's values. * diff --git a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/metrics/OtlpGrpcMetricExporterBuilder.java b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/metrics/OtlpGrpcMetricExporterBuilder.java index c6f02dec4c7..01d0f7b69ab 100644 --- a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/metrics/OtlpGrpcMetricExporterBuilder.java +++ b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/metrics/OtlpGrpcMetricExporterBuilder.java @@ -286,6 +286,13 @@ public OtlpGrpcMetricExporterBuilder setMemoryMode(MemoryMode memoryMode) { return this; } + /** Set the {@link ClassLoader} used to load the sender API. */ + public OtlpGrpcMetricExporterBuilder setServiceClassLoader(ClassLoader serviceClassLoader) { + requireNonNull(serviceClassLoader, "serviceClassLoader"); + delegate.setServiceClassLoader(serviceClassLoader); + return this; + } + /** * Constructs a new instance of the exporter based on the builder's values. * diff --git a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/trace/OtlpGrpcSpanExporterBuilder.java b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/trace/OtlpGrpcSpanExporterBuilder.java index 0a24398eeed..f9c49eac104 100644 --- a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/trace/OtlpGrpcSpanExporterBuilder.java +++ b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/trace/OtlpGrpcSpanExporterBuilder.java @@ -255,6 +255,13 @@ public OtlpGrpcSpanExporterBuilder setMemoryMode(MemoryMode memoryMode) { return this; } + /** Set the {@link ClassLoader} used to load the sender API. */ + public OtlpGrpcSpanExporterBuilder setServiceClassLoader(ClassLoader serviceClassLoader) { + requireNonNull(serviceClassLoader, "serviceClassLoader"); + delegate.setServiceClassLoader(serviceClassLoader); + return this; + } + /** * Constructs a new instance of the exporter based on the builder's values. * diff --git a/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/AbstractGrpcTelemetryExporterTest.java b/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/AbstractGrpcTelemetryExporterTest.java index 33ef67bf6dd..765d9195db1 100644 --- a/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/AbstractGrpcTelemetryExporterTest.java +++ b/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/AbstractGrpcTelemetryExporterTest.java @@ -47,6 +47,7 @@ import java.io.IOException; import java.io.UncheckedIOException; import java.lang.reflect.Field; +import java.net.URL; import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.security.cert.CertificateEncodingException; @@ -54,6 +55,7 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; +import java.util.Enumeration; import java.util.List; import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletionStage; @@ -872,6 +874,39 @@ void validConfig() { .doesNotThrowAnyException(); } + @Test + void customServiceClassLoader() { + ClassLoaderSpy classLoaderSpy = + new ClassLoaderSpy(AbstractHttpTelemetryExporterTest.class.getClassLoader()); + + TelemetryExporter exporter = + exporterBuilder() + .setServiceClassLoader(classLoaderSpy) + .setEndpoint(server.httpUri().toString()) + .build(); + + assertThat(classLoaderSpy.getResourcesNames) + .isEqualTo( + Collections.singletonList( + "META-INF/services/io.opentelemetry.exporter.internal.grpc.GrpcSenderProvider")); + + exporter.shutdown(); + } + + private static class ClassLoaderSpy extends ClassLoader { + private final List getResourcesNames = new ArrayList<>(); + + private ClassLoaderSpy(ClassLoader delegate) { + super(delegate); + } + + @Override + public Enumeration getResources(String name) throws IOException { + getResourcesNames.add(name); + return super.getResources(name); + } + } + private void buildAndShutdown(TelemetryExporterBuilder builder) { TelemetryExporter build = builder.build(); build.shutdown().join(10, TimeUnit.MILLISECONDS); diff --git a/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/AbstractHttpTelemetryExporterTest.java b/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/AbstractHttpTelemetryExporterTest.java index b1d30da161a..318511c1efc 100644 --- a/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/AbstractHttpTelemetryExporterTest.java +++ b/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/AbstractHttpTelemetryExporterTest.java @@ -49,6 +49,7 @@ import java.io.UncheckedIOException; import java.lang.reflect.Field; import java.net.InetSocketAddress; +import java.net.URL; import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.security.cert.CertificateEncodingException; @@ -57,6 +58,7 @@ import java.util.Arrays; import java.util.Base64; import java.util.Collections; +import java.util.Enumeration; import java.util.List; import java.util.concurrent.CompletableFuture; import java.util.concurrent.ConcurrentLinkedQueue; @@ -873,6 +875,39 @@ void toBuilderEquality() } } + @Test + void customServiceClassLoader() { + ClassLoaderSpy classLoaderSpy = + new ClassLoaderSpy(AbstractHttpTelemetryExporterTest.class.getClassLoader()); + + TelemetryExporter exporter = + exporterBuilder() + .setServiceClassLoader(classLoaderSpy) + .setEndpoint(server.httpUri() + path) + .build(); + + assertThat(classLoaderSpy.getResourcesNames) + .isEqualTo( + Collections.singletonList( + "META-INF/services/io.opentelemetry.exporter.internal.http.HttpSenderProvider")); + + exporter.shutdown(); + } + + private static class ClassLoaderSpy extends ClassLoader { + private final List getResourcesNames = new ArrayList<>(); + + private ClassLoaderSpy(ClassLoader delegate) { + super(delegate); + } + + @Override + public Enumeration getResources(String name) throws IOException { + getResourcesNames.add(name); + return super.getResources(name); + } + } + @Test void stringRepresentation() throws IOException, CertificateEncodingException { TelemetryExporter telemetryExporter = exporterBuilder().build(); diff --git a/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/GrpcLogRecordExporterBuilderWrapper.java b/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/GrpcLogRecordExporterBuilderWrapper.java index 259be25632f..d2301babe92 100644 --- a/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/GrpcLogRecordExporterBuilderWrapper.java +++ b/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/GrpcLogRecordExporterBuilderWrapper.java @@ -112,6 +112,13 @@ public TelemetryExporterBuilder setChannel(Object channel) { return this; } + @Override + public TelemetryExporterBuilder setServiceClassLoader( + ClassLoader serviceClassLoader) { + builder.setServiceClassLoader(serviceClassLoader); + return this; + } + @Override public TelemetryExporter build() { return TelemetryExporter.wrap(builder.build()); diff --git a/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/GrpcMetricExporterBuilderWrapper.java b/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/GrpcMetricExporterBuilderWrapper.java index afe3a7eeb56..c0f6d6f218a 100644 --- a/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/GrpcMetricExporterBuilderWrapper.java +++ b/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/GrpcMetricExporterBuilderWrapper.java @@ -112,6 +112,13 @@ public TelemetryExporterBuilder setChannel(Object channel) { return this; } + @Override + public TelemetryExporterBuilder setServiceClassLoader( + ClassLoader serviceClassLoader) { + builder.setServiceClassLoader(serviceClassLoader); + return this; + } + @Override public TelemetryExporter build() { return TelemetryExporter.wrap(builder.build()); diff --git a/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/GrpcSpanExporterBuilderWrapper.java b/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/GrpcSpanExporterBuilderWrapper.java index 40e0c94f797..71a9bbe29ea 100644 --- a/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/GrpcSpanExporterBuilderWrapper.java +++ b/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/GrpcSpanExporterBuilderWrapper.java @@ -113,6 +113,12 @@ public TelemetryExporterBuilder setChannel(Object channel) { return this; } + @Override + public TelemetryExporterBuilder setServiceClassLoader(ClassLoader serviceClassLoader) { + builder.setServiceClassLoader(serviceClassLoader); + return this; + } + @Override public TelemetryExporter build() { return TelemetryExporter.wrap(builder.build()); diff --git a/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/HttpLogRecordExporterBuilderWrapper.java b/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/HttpLogRecordExporterBuilderWrapper.java index 359cec9e016..1d4738f6084 100644 --- a/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/HttpLogRecordExporterBuilderWrapper.java +++ b/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/HttpLogRecordExporterBuilderWrapper.java @@ -112,6 +112,13 @@ public TelemetryExporterBuilder setChannel(Object channel) { throw new UnsupportedOperationException("Not implemented"); } + @Override + public TelemetryExporterBuilder setServiceClassLoader( + ClassLoader serviceClassLoader) { + builder.setServiceClassLoader(serviceClassLoader); + return this; + } + @Override public TelemetryExporter build() { return TelemetryExporter.wrap(builder.build()); diff --git a/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/HttpMetricExporterBuilderWrapper.java b/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/HttpMetricExporterBuilderWrapper.java index 0058f51a760..2510af696ef 100644 --- a/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/HttpMetricExporterBuilderWrapper.java +++ b/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/HttpMetricExporterBuilderWrapper.java @@ -111,6 +111,13 @@ public TelemetryExporterBuilder setChannel(Object channel) { throw new UnsupportedOperationException("Not implemented"); } + @Override + public TelemetryExporterBuilder setServiceClassLoader( + ClassLoader serviceClassLoader) { + builder.setServiceClassLoader(serviceClassLoader); + return this; + } + @Override public TelemetryExporter build() { return TelemetryExporter.wrap(builder.build()); diff --git a/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/HttpSpanExporterBuilderWrapper.java b/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/HttpSpanExporterBuilderWrapper.java index 993abe5d2bb..a13afb47341 100644 --- a/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/HttpSpanExporterBuilderWrapper.java +++ b/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/HttpSpanExporterBuilderWrapper.java @@ -111,6 +111,12 @@ public TelemetryExporterBuilder setChannel(Object channel) { throw new UnsupportedOperationException("Not implemented"); } + @Override + public TelemetryExporterBuilder setServiceClassLoader(ClassLoader serviceClassLoader) { + builder.setServiceClassLoader(serviceClassLoader); + return this; + } + @Override public TelemetryExporter build() { return TelemetryExporter.wrap(builder.build()); diff --git a/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/ManagedChannelTelemetryExporterBuilder.java b/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/ManagedChannelTelemetryExporterBuilder.java index 941a30359b1..6f01128a578 100644 --- a/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/ManagedChannelTelemetryExporterBuilder.java +++ b/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/ManagedChannelTelemetryExporterBuilder.java @@ -159,6 +159,12 @@ public TelemetryExporterBuilder setChannel(Object channel) { throw new UnsupportedOperationException(); } + @Override + public TelemetryExporterBuilder setServiceClassLoader(ClassLoader serviceClassLoader) { + delegate.setServiceClassLoader(serviceClassLoader); + return this; + } + @Override public TelemetryExporter build() { Runnable shutdownCallback; diff --git a/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/TelemetryExporterBuilder.java b/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/TelemetryExporterBuilder.java index 4e71e81132f..b37ce746db7 100644 --- a/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/TelemetryExporterBuilder.java +++ b/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/TelemetryExporterBuilder.java @@ -63,5 +63,7 @@ static TelemetryExporterBuilder wrap(OtlpGrpcLogRecordExporterBui TelemetryExporterBuilder setChannel(Object channel); + TelemetryExporterBuilder setServiceClassLoader(ClassLoader serviceClassLoader); + TelemetryExporter build(); } From 16f3637b0b7877c9f8b2cb23f170c5797f488df4 Mon Sep 17 00:00:00 2001 From: tianlan xu <1203946234@qq.com> Date: Tue, 4 Mar 2025 07:01:53 +0800 Subject: [PATCH 849/901] fix bug: throttledRateLimiter is not once per minute, but five times (#7156) --- .../sdk/internal/ThrottlingLogger.java | 3 +- .../sdk/internal/ThrottlingLoggerTest.java | 37 +++++++++++++++++++ 2 files changed, 39 insertions(+), 1 deletion(-) diff --git a/sdk/common/src/main/java/io/opentelemetry/sdk/internal/ThrottlingLogger.java b/sdk/common/src/main/java/io/opentelemetry/sdk/internal/ThrottlingLogger.java index d4bd64d1af8..e2c671cdff9 100644 --- a/sdk/common/src/main/java/io/opentelemetry/sdk/internal/ThrottlingLogger.java +++ b/sdk/common/src/main/java/io/opentelemetry/sdk/internal/ThrottlingLogger.java @@ -41,7 +41,8 @@ public ThrottlingLogger(Logger delegate) { this.fastRateLimiter = new RateLimiter(RATE_LIMIT / rateTimeUnit.toSeconds(1), RATE_LIMIT, clock); this.throttledRateLimiter = - new RateLimiter(RATE_LIMIT / rateTimeUnit.toSeconds(1), THROTTLED_RATE_LIMIT, clock); + new RateLimiter( + THROTTLED_RATE_LIMIT / rateTimeUnit.toSeconds(1), THROTTLED_RATE_LIMIT, clock); } /** Log a message at the given level. */ diff --git a/sdk/common/src/test/java/io/opentelemetry/sdk/internal/ThrottlingLoggerTest.java b/sdk/common/src/test/java/io/opentelemetry/sdk/internal/ThrottlingLoggerTest.java index 1c35b23ba0f..624c0fc5fec 100644 --- a/sdk/common/src/test/java/io/opentelemetry/sdk/internal/ThrottlingLoggerTest.java +++ b/sdk/common/src/test/java/io/opentelemetry/sdk/internal/ThrottlingLoggerTest.java @@ -144,4 +144,41 @@ void afterAMinuteLetOneThrough() { assertThat(logs.getEvents()).hasSize(9); assertThat(logs.getEvents().get(8).getMessage()).isEqualTo("oh no!"); } + + @Test + void allowOnlyOneLogPerMinuteAfterSuppression() { + TestClock clock = TestClock.create(); + ThrottlingLogger logger = new ThrottlingLogger(realLogger, clock); + + logger.log(Level.WARNING, "oh no!"); + logger.log(Level.WARNING, "oh no!"); + logger.log(Level.WARNING, "oh no!"); + logger.log(Level.WARNING, "oh no!"); + logger.log(Level.WARNING, "oh no!"); + + logger.log(Level.WARNING, "oh no I should trigger suppression!"); + logger.log(Level.WARNING, "oh no I should be suppressed!"); + + assertThat(logs.getEvents()).hasSize(7); + + clock.advance(Duration.ofMillis(12_001)); + logger.log(Level.WARNING, "suppression 1"); + clock.advance(Duration.ofMillis(12_001)); + logger.log(Level.WARNING, "suppression 2"); + clock.advance(Duration.ofMillis(12_001)); + logger.log(Level.WARNING, "suppression 3"); + clock.advance(Duration.ofMillis(12_001)); + logger.log(Level.WARNING, "suppression 4"); + clock.advance(Duration.ofMillis(12_001)); + logger.log(Level.WARNING, "allowed 1"); + + logs.assertDoesNotContain("suppression 1"); + logs.assertDoesNotContain("suppression 2"); + logs.assertDoesNotContain("suppression 3"); + logs.assertDoesNotContain("suppression 4"); + logs.assertContains("allowed 1"); + + assertThat(logs.getEvents()).hasSize(8); + assertThat(logs.getEvents().get(7).getMessage()).isEqualTo("allowed 1"); + } } From 0a993b392c8696d09922615938a8e05c50cc5ed6 Mon Sep 17 00:00:00 2001 From: jack-berg <34418638+jack-berg@users.noreply.github.com> Date: Tue, 4 Mar 2025 09:47:13 -0600 Subject: [PATCH 850/901] Update android animalsniffer min API version to 23 (#7153) --- VERSIONING.md | 2 +- animal-sniffer-signature/build.gradle.kts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/VERSIONING.md b/VERSIONING.md index d7566cacff4..c54306a711c 100644 --- a/VERSIONING.md +++ b/VERSIONING.md @@ -72,7 +72,7 @@ respect to semantic versioning. | Language | Minimum Version | Applicability | Semconv Notes | |----------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|---------------------------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| | Java | 8+ | All artifacts, unless otherwise noted | Changing requires major version bump. | -| Android | 21+ (NOTE: [desugaring](https://developer.android.com/studio/write/java8-support#library-desugaring) is required. We stay up to date with the latest version of [desugar_jdk_libs](https://github.com/google/desugar_jdk_libs).) | Artifacts using `otel.animalsniffer-conventions` plugin | Kept in sync with minimum requirements for [Google Play services](https://developers.google.com/android/guides/setup). Subject to change in minor version. | +| Android | 23+ (NOTE: [desugaring](https://developer.android.com/studio/write/java8-support#library-desugaring) is required. We stay up to date with the latest version of [desugar_jdk_libs](https://github.com/google/desugar_jdk_libs).) | Artifacts using `otel.animalsniffer-conventions` plugin | Kept in sync with minimum requirements for [Google Play services](https://developers.google.com/android/guides/setup). Subject to change in minor version. | | Kotlin | 1.6+ | Only applies to `opentelemetry-extension-kotlin` | Kept in sync with [minimum non-deprecated](https://kotlinlang.org/docs/gradle-compiler-options.html#attributes-common-to-jvm-and-js) version. Subject to change in minor versions. | ## API vs SDK diff --git a/animal-sniffer-signature/build.gradle.kts b/animal-sniffer-signature/build.gradle.kts index f571179e8ff..f9f070f24e7 100644 --- a/animal-sniffer-signature/build.gradle.kts +++ b/animal-sniffer-signature/build.gradle.kts @@ -27,7 +27,7 @@ configurations.add(signatureJarClasspath) configurations.add(generatedSignature) dependencies { - signature("com.toasttab.android:gummy-bears-api-21:0.10.0@signature") + signature("com.toasttab.android:gummy-bears-api-23:0.10.0@signature") signatureJar("com.android.tools:desugar_jdk_libs") } From 3c71b798a5dc50d87e00698acfafc8d88f9e14fd Mon Sep 17 00:00:00 2001 From: jack-berg <34418638+jack-berg@users.noreply.github.com> Date: Tue, 4 Mar 2025 12:46:56 -0600 Subject: [PATCH 851/901] Test with graalvm 23 (#7167) --- .github/workflows/build.yml | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index adb645a68c6..b2659ab7fbc 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -161,13 +161,19 @@ jobs: GPG_PASSWORD: ${{ secrets.GPG_PASSWORD }} build-graal: + name: Build GraalVM runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + test-graal-version: + - 21 + - 23 steps: - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - uses: graalvm/setup-graalvm@b0cb26a8da53cb3e97cdc0c827d8e3071240e730 # v1.3.1 with: - # TODO(jack-berg): Which versions do we need to test? Should we use a matrix scheme? - java-version: '21' + java-version: ${{ matrix.test-graal-version }} distribution: 'graalvm' components: 'native-image' github-token: ${{ secrets.GITHUB_TOKEN }} From 5015698d2b4ec4f620d9f1da14d9b8bef964279c Mon Sep 17 00:00:00 2001 From: jack-berg <34418638+jack-berg@users.noreply.github.com> Date: Tue, 4 Mar 2025 16:49:05 -0600 Subject: [PATCH 852/901] Remove obsolete SdkMeterProviderUtil#setCardinalitylimit API (#7169) --- .../metrics/internal/SdkMeterProviderUtil.java | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/SdkMeterProviderUtil.java b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/SdkMeterProviderUtil.java index 1b203d9d9a2..0f6d3035b25 100644 --- a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/SdkMeterProviderUtil.java +++ b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/SdkMeterProviderUtil.java @@ -120,21 +120,6 @@ private static void addAttributesProcessor( } } - /** - * Reflectively set the {@code cardinalityLimit} on the {@link ViewBuilder}. - * - * @param viewBuilder the builder - */ - public static void setCardinalityLimit(ViewBuilder viewBuilder, int cardinalityLimit) { - try { - Method method = ViewBuilder.class.getDeclaredMethod("setCardinalityLimit", int.class); - method.setAccessible(true); - method.invoke(viewBuilder, cardinalityLimit); - } catch (NoSuchMethodException | InvocationTargetException | IllegalAccessException e) { - throw new IllegalStateException("Error setting cardinalityLimit on ViewBuilder", e); - } - } - /** Reflectively reset the {@link SdkMeterProvider}, clearing all registered instruments. */ public static void resetForTest(SdkMeterProvider sdkMeterProvider) { try { From 061879192892ed8978b7d67c7f6839ec43ee5796 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 4 Mar 2025 16:55:57 -0600 Subject: [PATCH 853/901] fix(deps): update dependency io.grpc:grpc-bom to v1.71.0 (#7171) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- dependencyManagement/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index c801a9a44a1..6ec70e1fcb6 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -18,7 +18,7 @@ val DEPENDENCY_BOMS = listOf( "com.google.protobuf:protobuf-bom:4.29.3", "com.squareup.okhttp3:okhttp-bom:4.12.0", "com.squareup.okio:okio-bom:3.10.2", // applies to transitive dependencies of okhttp - "io.grpc:grpc-bom:1.70.0", + "io.grpc:grpc-bom:1.71.0", "io.netty:netty-bom:4.1.119.Final", "io.zipkin.brave:brave-bom:6.1.0", "io.zipkin.reporter2:zipkin-reporter-bom:3.5.0", From 33b37abe9ac329d6b2f0ba281cb6adb38e227e26 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 4 Mar 2025 16:56:12 -0600 Subject: [PATCH 854/901] fix(deps): update dependency org.testcontainers:testcontainers-bom to v1.20.6 (#7170) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- dependencyManagement/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index 6ec70e1fcb6..6a797f26267 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -23,7 +23,7 @@ val DEPENDENCY_BOMS = listOf( "io.zipkin.brave:brave-bom:6.1.0", "io.zipkin.reporter2:zipkin-reporter-bom:3.5.0", "org.assertj:assertj-bom:3.27.3", - "org.testcontainers:testcontainers-bom:1.20.5", + "org.testcontainers:testcontainers-bom:1.20.6", "org.snakeyaml:snakeyaml-engine:2.9" ) From cd8640514885d80d19c82202d5fc4486e7040312 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 4 Mar 2025 16:56:30 -0600 Subject: [PATCH 855/901] fix(deps): update dependency checkstyle to v10.21.4 (#7166) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- buildSrc/src/main/kotlin/otel.java-conventions.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/buildSrc/src/main/kotlin/otel.java-conventions.gradle.kts b/buildSrc/src/main/kotlin/otel.java-conventions.gradle.kts index e95dc6acc11..ea6230fda36 100644 --- a/buildSrc/src/main/kotlin/otel.java-conventions.gradle.kts +++ b/buildSrc/src/main/kotlin/otel.java-conventions.gradle.kts @@ -42,7 +42,7 @@ java { checkstyle { configDirectory.set(file("$rootDir/buildscripts/")) - toolVersion = "10.21.3" + toolVersion = "10.21.4" isIgnoreFailures = false configProperties["rootDir"] = rootDir } From b3e3fff83c19574ccab198cd3140329823fbd6ae Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 4 Mar 2025 16:59:28 -0600 Subject: [PATCH 856/901] chore(deps): update weekly update (#7163) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/build-tracecontext-testsuite.yml | 2 +- .github/workflows/build.yml | 4 ++-- integration-tests/tracecontext/docker/Dockerfile | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/build-tracecontext-testsuite.yml b/.github/workflows/build-tracecontext-testsuite.yml index d15f8e8d4e4..c6540c2d766 100644 --- a/.github/workflows/build-tracecontext-testsuite.yml +++ b/.github/workflows/build-tracecontext-testsuite.yml @@ -29,7 +29,7 @@ jobs: password: ${{ secrets.GITHUB_TOKEN }} - name: Build and push - uses: docker/build-push-action@0adf9959216b96bec444f325f1e493d4aa344497 # v6.14.0 + uses: docker/build-push-action@471d1dc4e07e5cdedd4c2171150001c434f0b7a4 # v6.15.0 with: context: integration-tests/tracecontext/docker push: true diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index b2659ab7fbc..98c62ff8609 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -99,7 +99,7 @@ jobs: exit 1 fi - - uses: codecov/codecov-action@13ce06bfc6bbe3ecf90edbbf1bc32fe5978ca1d3 # v5.3.1 + - uses: codecov/codecov-action@0565863a31f2c772f9f0395002a31e3f06189574 # v5.4.0 if: ${{ matrix.coverage }} env: CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} @@ -171,7 +171,7 @@ jobs: - 23 steps: - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - - uses: graalvm/setup-graalvm@b0cb26a8da53cb3e97cdc0c827d8e3071240e730 # v1.3.1 + - uses: graalvm/setup-graalvm@01ed653ac833fe80569f1ef9f25585ba2811baab # v1.3.3 with: java-version: ${{ matrix.test-graal-version }} distribution: 'graalvm' diff --git a/integration-tests/tracecontext/docker/Dockerfile b/integration-tests/tracecontext/docker/Dockerfile index c908887a8eb..d9de90d1102 100644 --- a/integration-tests/tracecontext/docker/Dockerfile +++ b/integration-tests/tracecontext/docker/Dockerfile @@ -1,4 +1,4 @@ -FROM python:3.13.2@sha256:08471c63c5fdf2644adc142a7fa8d0290eb405cda14c473fbe5b4cd0933af601 AS build +FROM python:3.13.2@sha256:385ccb8304f6330738a6d9e6fa0bd7608e006da7e15bc52b33b0398e1ba4a15b AS build # Main branch SHA as of April-1-2021 ARG TRACECONTEXT_GIT_TAG="dcd3ad9b7d6ac36f70ff3739874b73c11b0302a1" @@ -11,7 +11,7 @@ RUN unzip trace-context.zip RUN rm trace-context.zip RUN mv trace-context-${TRACECONTEXT_GIT_TAG}/test /tracecontext-testsuite -FROM python:3.13.2-slim@sha256:ae9f9ac89467077ed1efefb6d9042132d28134ba201b2820227d46c9effd3174 +FROM python:3.13.2-slim@sha256:f3614d98f38b0525d670f287b0474385952e28eb43016655dd003d0e28cf8652 RUN pip install aiohttp From 42056f57c87b5c1b979a0e0b6b74a132b9162245 Mon Sep 17 00:00:00 2001 From: jack-berg <34418638+jack-berg@users.noreply.github.com> Date: Tue, 4 Mar 2025 17:21:19 -0600 Subject: [PATCH 857/901] Introduce ConfigProvider API (#6549) --- api/incubator/build.gradle.kts | 3 + .../api/incubator/config/ConfigProvider.java | 37 ++++ .../config/DeclarativeConfigException.java | 22 +++ .../config/DeclarativeConfigProperties.java | 74 ++++---- .../EmptyDeclarativeConfigProperties.java | 18 +- .../config/GlobalConfigProvider.java | 63 +++++++ .../config/InstrumentationConfigUtil.java | 151 ++++++++++++++++ .../api/incubator/ConfigProviderTest.java | 20 +++ .../config/GlobalConfigProviderTest.java | 44 +++++ .../config/InstrumentationConfigUtilTest.java | 169 ++++++++++++++++++ exporters/common/build.gradle.kts | 1 + .../internal/ExporterBuilderUtil.java | 64 ------- .../IncubatingExporterBuilderUtil.java | 93 ++++++++++ exporters/logging-otlp/build.gradle.kts | 2 + ...outLogRecordExporterComponentProvider.java | 8 +- ...StdoutMetricExporterComponentProvider.java | 12 +- ...lpStdoutSpanExporterComponentProvider.java | 8 +- .../otlp/AbstractOtlpStdoutExporterTest.java | 6 +- .../otlp/OtlpStdoutMetricExporterTest.java | 4 +- exporters/logging/build.gradle.kts | 1 + ...oleLogRecordExporterComponentProvider.java | 4 +- ...onsoleMetricExporterComponentProvider.java | 4 +- .../ConsoleSpanExporterComponentProvider.java | 4 +- exporters/otlp/all/build.gradle.kts | 2 + .../otlp/internal/OtlpConfigUtil.java | 96 +--------- .../internal/OtlpDeclarativeConfigUtil.java | 120 +++++++++++++ ...tlpLogRecordExporterComponentProvider.java | 10 +- .../OtlpMetricExporterComponentProvider.java | 20 +-- .../OtlpSpanExporterComponentProvider.java | 10 +- exporters/prometheus/build.gradle.kts | 1 + .../internal/PrometheusComponentProvider.java | 4 +- exporters/zipkin/build.gradle.kts | 1 + .../ZipkinSpanExporterComponentProvider.java | 4 +- extensions/trace-propagators/build.gradle.kts | 1 + .../internal/B3ComponentProvider.java | 4 +- .../internal/B3MultiComponentProvider.java | 4 +- .../internal/JaegerComponentProvider.java | 4 +- .../internal/OtTraceComponentProvider.java | 4 +- .../autoconfigure-spi/build.gradle.kts | 1 + .../spi/internal/ComponentProvider.java | 7 +- sdk-extensions/autoconfigure/build.gradle.kts | 10 +- .../AutoConfiguredOpenTelemetrySdk.java | 21 ++- ...AutoConfiguredOpenTelemetrySdkBuilder.java | 68 +++---- .../sdk/autoconfigure/IncubatingUtil.java | 88 +++++++++ .../internal/AutoConfigureUtil.java | 16 +- .../sdk/autoconfigure/internal/SpiHelper.java | 51 ------ .../AutoConfiguredOpenTelemetrySdkTest.java | 23 --- ...java => DeclarativeConfigurationTest.java} | 13 +- .../sdk/autoconfigure/FullConfigTest.java | 21 --- .../DeclarativeConfigurationTest.java} | 95 +++++++--- sdk-extensions/incubator/build.gradle.kts | 4 +- .../fileconfig/AggregationFactory.java | 6 +- .../fileconfig/AttributeListFactory.java | 4 +- ...ion.java => DeclarativeConfiguration.java} | 80 +++++---- .../incubator/fileconfig/FileConfigUtil.java | 68 ++++++- .../fileconfig/InstrumentSelectorFactory.java | 6 +- .../fileconfig/LogRecordExporterFactory.java | 6 +- .../fileconfig/LogRecordProcessorFactory.java | 6 +- .../fileconfig/MetricExporterFactory.java | 6 +- .../fileconfig/MetricReaderFactory.java | 7 +- .../OpenTelemetryConfigurationFactory.java | 5 +- .../incubator/fileconfig/ResourceFactory.java | 14 +- .../incubator/fileconfig/SamplerFactory.java | 6 +- .../fileconfig/SdkConfigProvider.java | 39 ++++ .../fileconfig/SpanExporterFactory.java | 6 +- .../fileconfig/SpanProcessorFactory.java | 6 +- .../fileconfig/TextMapPropagatorFactory.java | 4 +- ...a => YamlDeclarativeConfigProperties.java} | 81 +++++---- .../fileconfig/AttributeListFactoryTest.java | 4 +- ...> DeclarativeConfigurationCreateTest.java} | 22 +-- ...=> DeclarativeConfigurationParseTest.java} | 23 +-- .../InstrumentSelectorFactoryTest.java | 4 +- .../LogRecordExporterFactoryTest.java | 66 +++++-- .../LogRecordProcessorFactoryTest.java | 8 +- .../fileconfig/MetricExporterFactoryTest.java | 64 +++++-- .../fileconfig/MetricReaderFactoryTest.java | 10 +- ...OpenTelemetryConfigurationFactoryTest.java | 4 +- .../fileconfig/ResourceFactoryTest.java | 2 +- .../fileconfig/SamplerFactoryTest.java | 4 +- .../fileconfig/SpanExporterFactoryTest.java | 84 ++++++--- .../fileconfig/SpanProcessorFactoryTest.java | 8 +- .../TextMapPropagatorFactoryTest.java | 8 +- ... YamlDeclarativeConfigPropertiesTest.java} | 33 ++-- .../LogRecordExporterComponentProvider.java | 8 +- .../LogRecordProcessorComponentProvider.java | 8 +- .../MetricExporterComponentProvider.java | 8 +- .../component/ResourceComponentProvider.java | 4 +- ...ResourceOrderedFirstComponentProvider.java | 4 +- ...esourceOrderedSecondComponentProvider.java | 4 +- .../component/SamplerComponentProvider.java | 8 +- .../SpanExporterComponentProvider.java | 8 +- .../SpanProcessorComponentProvider.java | 8 +- .../TextMapPropagatorComponentProvider.java | 8 +- .../jaeger-remote-sampler/build.gradle.kts | 1 + .../JaegerRemoteSamplerComponentProvider.java | 10 +- 95 files changed, 1542 insertions(+), 746 deletions(-) create mode 100644 api/incubator/src/main/java/io/opentelemetry/api/incubator/config/ConfigProvider.java create mode 100644 api/incubator/src/main/java/io/opentelemetry/api/incubator/config/DeclarativeConfigException.java rename sdk-extensions/autoconfigure-spi/src/main/java/io/opentelemetry/sdk/autoconfigure/spi/internal/StructuredConfigProperties.java => api/incubator/src/main/java/io/opentelemetry/api/incubator/config/DeclarativeConfigProperties.java (68%) rename sdk-extensions/autoconfigure-spi/src/main/java/io/opentelemetry/sdk/autoconfigure/spi/internal/EmptyStructuredConfigProperties.java => api/incubator/src/main/java/io/opentelemetry/api/incubator/config/EmptyDeclarativeConfigProperties.java (63%) create mode 100644 api/incubator/src/main/java/io/opentelemetry/api/incubator/config/GlobalConfigProvider.java create mode 100644 api/incubator/src/main/java/io/opentelemetry/api/incubator/config/InstrumentationConfigUtil.java create mode 100644 api/incubator/src/test/java/io/opentelemetry/api/incubator/ConfigProviderTest.java create mode 100644 api/incubator/src/test/java/io/opentelemetry/api/incubator/config/GlobalConfigProviderTest.java create mode 100644 api/incubator/src/test/java/io/opentelemetry/api/incubator/config/InstrumentationConfigUtilTest.java create mode 100644 exporters/common/src/main/java/io/opentelemetry/exporter/internal/IncubatingExporterBuilderUtil.java create mode 100644 exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/OtlpDeclarativeConfigUtil.java create mode 100644 sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/IncubatingUtil.java rename sdk-extensions/autoconfigure/src/test/java/io/opentelemetry/sdk/autoconfigure/{FileConfigurationTest.java => DeclarativeConfigurationTest.java} (73%) rename sdk-extensions/autoconfigure/src/{testFullConfig/java/io/opentelemetry/sdk/autoconfigure/FileConfigurationTest.java => testIncubating/java/io/opentelemetry/sdk/autoconfigure/DeclarativeConfigurationTest.java} (66%) rename sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/{FileConfiguration.java => DeclarativeConfiguration.java} (78%) create mode 100644 sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/SdkConfigProvider.java rename sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/{YamlStructuredConfigProperties.java => YamlDeclarativeConfigProperties.java} (74%) rename sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/{FileConfigurationCreateTest.java => DeclarativeConfigurationCreateTest.java} (87%) rename sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/{FileConfigurationParseTest.java => DeclarativeConfigurationParseTest.java} (98%) rename sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/{YamlStructuredConfigPropertiesTest.java => YamlDeclarativeConfigPropertiesTest.java} (88%) diff --git a/api/incubator/build.gradle.kts b/api/incubator/build.gradle.kts index bdf12950acf..205b5504a0f 100644 --- a/api/incubator/build.gradle.kts +++ b/api/incubator/build.gradle.kts @@ -14,6 +14,9 @@ dependencies { annotationProcessor("com.google.auto.value:auto-value") + // To use parsed config file as input for InstrumentationConfigUtilTest + testImplementation(project(":sdk-extensions:incubator")) + testImplementation(project(":sdk:testing")) testImplementation(project(":api:testing-internal")) diff --git a/api/incubator/src/main/java/io/opentelemetry/api/incubator/config/ConfigProvider.java b/api/incubator/src/main/java/io/opentelemetry/api/incubator/config/ConfigProvider.java new file mode 100644 index 00000000000..62cc044e653 --- /dev/null +++ b/api/incubator/src/main/java/io/opentelemetry/api/incubator/config/ConfigProvider.java @@ -0,0 +1,37 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.api.incubator.config; + +import javax.annotation.Nullable; +import javax.annotation.concurrent.ThreadSafe; + +/** + * A registry for accessing declarative configuration. + * + *

      The name Provider is for consistency with other languages and it is NOT loaded + * using reflection. + * + *

      See {@link InstrumentationConfigUtil} for convenience methods for extracting config from + * {@link ConfigProvider}. + */ +@ThreadSafe +public interface ConfigProvider { + + /** + * Returns the {@link DeclarativeConfigProperties} corresponding to instrumentation + * config, or {@code null} if unavailable. + * + * @return the instrumentation {@link DeclarativeConfigProperties} + */ + @Nullable + DeclarativeConfigProperties getInstrumentationConfig(); + + /** Returns a no-op {@link ConfigProvider}. */ + static ConfigProvider noop() { + return () -> null; + } +} diff --git a/api/incubator/src/main/java/io/opentelemetry/api/incubator/config/DeclarativeConfigException.java b/api/incubator/src/main/java/io/opentelemetry/api/incubator/config/DeclarativeConfigException.java new file mode 100644 index 00000000000..3ce49c6454d --- /dev/null +++ b/api/incubator/src/main/java/io/opentelemetry/api/incubator/config/DeclarativeConfigException.java @@ -0,0 +1,22 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.api.incubator.config; + +/** An exception that is thrown when errors occur with declarative configuration. */ +public final class DeclarativeConfigException extends RuntimeException { + + private static final long serialVersionUID = 3036584181551130522L; + + /** Create a new configuration exception with specified {@code message} and without a cause. */ + public DeclarativeConfigException(String message) { + super(message); + } + + /** Create a new configuration exception with specified {@code message} and {@code cause}. */ + public DeclarativeConfigException(String message, Throwable cause) { + super(message, cause); + } +} diff --git a/sdk-extensions/autoconfigure-spi/src/main/java/io/opentelemetry/sdk/autoconfigure/spi/internal/StructuredConfigProperties.java b/api/incubator/src/main/java/io/opentelemetry/api/incubator/config/DeclarativeConfigProperties.java similarity index 68% rename from sdk-extensions/autoconfigure-spi/src/main/java/io/opentelemetry/sdk/autoconfigure/spi/internal/StructuredConfigProperties.java rename to api/incubator/src/main/java/io/opentelemetry/api/incubator/config/DeclarativeConfigProperties.java index ced88005614..ef8e2343f22 100644 --- a/sdk-extensions/autoconfigure-spi/src/main/java/io/opentelemetry/sdk/autoconfigure/spi/internal/StructuredConfigProperties.java +++ b/api/incubator/src/main/java/io/opentelemetry/api/incubator/config/DeclarativeConfigProperties.java @@ -3,20 +3,18 @@ * SPDX-License-Identifier: Apache-2.0 */ -package io.opentelemetry.sdk.autoconfigure.spi.internal; +package io.opentelemetry.api.incubator.config; import static io.opentelemetry.api.internal.ConfigUtil.defaultIfNull; -import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties; -import io.opentelemetry.sdk.autoconfigure.spi.ConfigurationException; import java.util.List; import java.util.Set; import javax.annotation.Nullable; /** - * An interface for accessing structured configuration data. + * An interface for accessing declarative configuration data. * - *

      An instance of {@link StructuredConfigProperties} is equivalent to a An instance of {@link DeclarativeConfigProperties} is equivalent to a YAML mapping node. It has accessors for * reading scalar properties, {@link #getStructured(String)} for reading children which are * themselves mappings, and {@link #getStructuredList(String)} for reading children which are @@ -25,24 +23,24 @@ *

      This class is internal and is hence not for public use. Its APIs are unstable and can change * at any time. */ -public interface StructuredConfigProperties { +public interface DeclarativeConfigProperties { /** - * Return an empty {@link StructuredConfigProperties} instance. + * Return an empty {@link DeclarativeConfigProperties} instance. * *

      Useful for walking the tree without checking for null. For example, to access a string key * nested at .foo.bar.baz, call: {@code config.getStructured("foo", empty()).getStructured("bar", * empty()).getString("baz")}. */ - static StructuredConfigProperties empty() { - return EmptyStructuredConfigProperties.getInstance(); + static DeclarativeConfigProperties empty() { + return EmptyDeclarativeConfigProperties.getInstance(); } /** * Returns a {@link String} configuration property. * * @return null if the property has not been configured - * @throws ConfigurationException if the property is not a valid scalar string + * @throws DeclarativeConfigException if the property is not a valid scalar string */ @Nullable String getString(String name); @@ -52,7 +50,7 @@ static StructuredConfigProperties empty() { * * @return a {@link String} configuration property or {@code defaultValue} if a property with * {@code name} has not been configured - * @throws ConfigurationException if the property is not a valid scalar string + * @throws DeclarativeConfigException if the property is not a valid scalar string */ default String getString(String name, String defaultValue) { return defaultIfNull(getString(name), defaultValue); @@ -63,7 +61,7 @@ default String getString(String name, String defaultValue) { * {@link Boolean#parseBoolean(String)} for handling the values. * * @return null if the property has not been configured - * @throws ConfigurationException if the property is not a valid scalar boolean + * @throws DeclarativeConfigException if the property is not a valid scalar boolean */ @Nullable Boolean getBoolean(String name); @@ -73,7 +71,7 @@ default String getString(String name, String defaultValue) { * * @return a {@link Boolean} configuration property or {@code defaultValue} if a property with * {@code name} has not been configured - * @throws ConfigurationException if the property is not a valid scalar boolean + * @throws DeclarativeConfigException if the property is not a valid scalar boolean */ default boolean getBoolean(String name, boolean defaultValue) { return defaultIfNull(getBoolean(name), defaultValue); @@ -86,7 +84,7 @@ default boolean getBoolean(String name, boolean defaultValue) { * {@link Long#intValue()} which may result in loss of precision. * * @return null if the property has not been configured - * @throws ConfigurationException if the property is not a valid scalar integer + * @throws DeclarativeConfigException if the property is not a valid scalar integer */ @Nullable Integer getInt(String name); @@ -99,7 +97,7 @@ default boolean getBoolean(String name, boolean defaultValue) { * * @return a {@link Integer} configuration property or {@code defaultValue} if a property with * {@code name} has not been configured - * @throws ConfigurationException if the property is not a valid scalar integer + * @throws DeclarativeConfigException if the property is not a valid scalar integer */ default int getInt(String name, int defaultValue) { return defaultIfNull(getInt(name), defaultValue); @@ -109,7 +107,7 @@ default int getInt(String name, int defaultValue) { * Returns a {@link Long} configuration property. * * @return null if the property has not been configured - * @throws ConfigurationException if the property is not a valid scalar long + * @throws DeclarativeConfigException if the property is not a valid scalar long */ @Nullable Long getLong(String name); @@ -119,7 +117,7 @@ default int getInt(String name, int defaultValue) { * * @return a {@link Long} configuration property or {@code defaultValue} if a property with {@code * name} has not been configured - * @throws ConfigurationException if the property is not a valid scalar long + * @throws DeclarativeConfigException if the property is not a valid scalar long */ default long getLong(String name, long defaultValue) { return defaultIfNull(getLong(name), defaultValue); @@ -129,7 +127,7 @@ default long getLong(String name, long defaultValue) { * Returns a {@link Double} configuration property. * * @return null if the property has not been configured - * @throws ConfigurationException if the property is not a valid scalar double + * @throws DeclarativeConfigException if the property is not a valid scalar double */ @Nullable Double getDouble(String name); @@ -139,7 +137,7 @@ default long getLong(String name, long defaultValue) { * * @return a {@link Double} configuration property or {@code defaultValue} if a property with * {@code name} has not been configured - * @throws ConfigurationException if the property is not a valid scalar double + * @throws DeclarativeConfigException if the property is not a valid scalar double */ default double getDouble(String name, double defaultValue) { return defaultIfNull(getDouble(name), defaultValue); @@ -153,8 +151,8 @@ default double getDouble(String name, double defaultValue) { * @param scalarType the scalar type, one of {@link String}, {@link Boolean}, {@link Long} or * {@link Double} * @return a {@link List} configuration property, or null if the property has not been configured - * @throws ConfigurationException if the property is not a valid sequence of scalars, or if {@code - * scalarType} is not supported + * @throws DeclarativeConfigException if the property is not a valid sequence of scalars, or if + * {@code scalarType} is not supported */ @Nullable List getScalarList(String name, Class scalarType); @@ -163,56 +161,58 @@ default double getDouble(String name, double defaultValue) { * Returns a {@link List} configuration property. Entries which are not strings are converted to * their string representation. * - * @see ConfigProperties#getList(String name) + * @param name the property name + * @param scalarType the scalar type, one of {@link String}, {@link Boolean}, {@link Long} or + * {@link Double} * @return a {@link List} configuration property or {@code defaultValue} if a property with {@code * name} has not been configured - * @throws ConfigurationException if the property is not a valid sequence of scalars + * @throws DeclarativeConfigException if the property is not a valid sequence of scalars */ default List getScalarList(String name, Class scalarType, List defaultValue) { return defaultIfNull(getScalarList(name, scalarType), defaultValue); } /** - * Returns a {@link StructuredConfigProperties} configuration property. + * Returns a {@link DeclarativeConfigProperties} configuration property. * * @return a map-valued configuration property, or {@code null} if {@code name} has not been * configured - * @throws ConfigurationException if the property is not a mapping + * @throws DeclarativeConfigException if the property is not a mapping */ @Nullable - StructuredConfigProperties getStructured(String name); + DeclarativeConfigProperties getStructured(String name); /** - * Returns a {@link StructuredConfigProperties} configuration property. + * Returns a list of {@link DeclarativeConfigProperties} configuration property. * * @return a map-valued configuration property, or {@code defaultValue} if {@code name} has not * been configured - * @throws ConfigurationException if the property is not a mapping + * @throws DeclarativeConfigException if the property is not a mapping */ - default StructuredConfigProperties getStructured( - String name, StructuredConfigProperties defaultValue) { + default DeclarativeConfigProperties getStructured( + String name, DeclarativeConfigProperties defaultValue) { return defaultIfNull(getStructured(name), defaultValue); } /** - * Returns a list of {@link StructuredConfigProperties} configuration property. + * Returns a list of {@link DeclarativeConfigProperties} configuration property. * * @return a list of map-valued configuration property, or {@code null} if {@code name} has not * been configured - * @throws ConfigurationException if the property is not a sequence of mappings + * @throws DeclarativeConfigException if the property is not a sequence of mappings */ @Nullable - List getStructuredList(String name); + List getStructuredList(String name); /** - * Returns a list of {@link StructuredConfigProperties} configuration property. + * Returns a list of {@link DeclarativeConfigProperties} configuration property. * * @return a list of map-valued configuration property, or {@code defaultValue} if {@code name} * has not been configured - * @throws ConfigurationException if the property is not a sequence of mappings + * @throws DeclarativeConfigException if the property is not a sequence of mappings */ - default List getStructuredList( - String name, List defaultValue) { + default List getStructuredList( + String name, List defaultValue) { return defaultIfNull(getStructuredList(name), defaultValue); } diff --git a/sdk-extensions/autoconfigure-spi/src/main/java/io/opentelemetry/sdk/autoconfigure/spi/internal/EmptyStructuredConfigProperties.java b/api/incubator/src/main/java/io/opentelemetry/api/incubator/config/EmptyDeclarativeConfigProperties.java similarity index 63% rename from sdk-extensions/autoconfigure-spi/src/main/java/io/opentelemetry/sdk/autoconfigure/spi/internal/EmptyStructuredConfigProperties.java rename to api/incubator/src/main/java/io/opentelemetry/api/incubator/config/EmptyDeclarativeConfigProperties.java index 2315dfa013f..77b8a265492 100644 --- a/sdk-extensions/autoconfigure-spi/src/main/java/io/opentelemetry/sdk/autoconfigure/spi/internal/EmptyStructuredConfigProperties.java +++ b/api/incubator/src/main/java/io/opentelemetry/api/incubator/config/EmptyDeclarativeConfigProperties.java @@ -3,22 +3,22 @@ * SPDX-License-Identifier: Apache-2.0 */ -package io.opentelemetry.sdk.autoconfigure.spi.internal; +package io.opentelemetry.api.incubator.config; import java.util.Collections; import java.util.List; import java.util.Set; import javax.annotation.Nullable; -/** Empty instance of {@link StructuredConfigProperties}. */ -final class EmptyStructuredConfigProperties implements StructuredConfigProperties { +/** Empty instance of {@link DeclarativeConfigProperties}. */ +final class EmptyDeclarativeConfigProperties implements DeclarativeConfigProperties { - private static final EmptyStructuredConfigProperties INSTANCE = - new EmptyStructuredConfigProperties(); + private static final EmptyDeclarativeConfigProperties INSTANCE = + new EmptyDeclarativeConfigProperties(); - private EmptyStructuredConfigProperties() {} + private EmptyDeclarativeConfigProperties() {} - static EmptyStructuredConfigProperties getInstance() { + static EmptyDeclarativeConfigProperties getInstance() { return INSTANCE; } @@ -60,13 +60,13 @@ public List getScalarList(String name, Class scalarType) { @Nullable @Override - public StructuredConfigProperties getStructured(String name) { + public DeclarativeConfigProperties getStructured(String name) { return null; } @Nullable @Override - public List getStructuredList(String name) { + public List getStructuredList(String name) { return null; } diff --git a/api/incubator/src/main/java/io/opentelemetry/api/incubator/config/GlobalConfigProvider.java b/api/incubator/src/main/java/io/opentelemetry/api/incubator/config/GlobalConfigProvider.java new file mode 100644 index 00000000000..b0daef4968d --- /dev/null +++ b/api/incubator/src/main/java/io/opentelemetry/api/incubator/config/GlobalConfigProvider.java @@ -0,0 +1,63 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.api.incubator.config; + +import io.opentelemetry.api.GlobalOpenTelemetry; +import java.util.concurrent.atomic.AtomicReference; +import javax.annotation.Nullable; + +/** + * This class provides a temporary global accessor for {@link ConfigProvider} until the + * instrumentation config API is marked stable. It will eventually be merged into {@link + * GlobalOpenTelemetry}. + */ +// We intentionally assign to be used for error reporting. +@SuppressWarnings("StaticAssignmentOfThrowable") +public final class GlobalConfigProvider { + + private static final AtomicReference instance = + new AtomicReference<>(ConfigProvider.noop()); + + @SuppressWarnings("NonFinalStaticField") + @Nullable + private static volatile Throwable setInstanceCaller; + + private GlobalConfigProvider() {} + + /** Returns the globally registered {@link ConfigProvider}. */ + // instance cannot be set to null + @SuppressWarnings("NullAway") + public static ConfigProvider get() { + return instance.get(); + } + + /** + * Sets the global {@link ConfigProvider}. Future calls to {@link #get()} will return the provided + * {@link ConfigProvider} instance. This should be called once as early as possible in your + * application initialization logic. + * + * @throws IllegalStateException when called more than once + */ + public static void set(ConfigProvider configProvider) { + boolean changed = instance.compareAndSet(ConfigProvider.noop(), configProvider); + if (!changed && (configProvider != ConfigProvider.noop())) { + throw new IllegalStateException( + "GlobalConfigProvider.set has already been called. GlobalConfigProvider.set " + + "must be called only once before any calls to GlobalConfigProvider.get. " + + "Previous invocation set to cause of this exception.", + setInstanceCaller); + } + setInstanceCaller = new Throwable(); + } + + /** + * Unsets the global {@link ConfigProvider}. This is only meant to be used from tests which need + * to reconfigure {@link ConfigProvider}. + */ + public static void resetForTest() { + instance.set(ConfigProvider.noop()); + } +} diff --git a/api/incubator/src/main/java/io/opentelemetry/api/incubator/config/InstrumentationConfigUtil.java b/api/incubator/src/main/java/io/opentelemetry/api/incubator/config/InstrumentationConfigUtil.java new file mode 100644 index 00000000000..e1e95e93153 --- /dev/null +++ b/api/incubator/src/main/java/io/opentelemetry/api/incubator/config/InstrumentationConfigUtil.java @@ -0,0 +1,151 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.api.incubator.config; + +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.function.Function; +import javax.annotation.Nullable; + +/** + * A collection of convenience methods to extract instrumentation config from {@link + * ConfigProvider#getInstrumentationConfig()}. + */ +public class InstrumentationConfigUtil { + + /** + * Return a map representation of the peer service map entries in {@code + * .instrumentation.general.peer.service_mapping}, or null if none is configured. + * + * @throws DeclarativeConfigException if an unexpected type is encountered accessing the property + */ + @Nullable + public static Map peerServiceMapping(ConfigProvider configProvider) { + List serviceMappingList = + getOrNull( + configProvider, + config -> config.getStructuredList("service_mapping"), + "general", + "peer"); + if (serviceMappingList == null) { + return null; + } + Map serviceMapping = new LinkedHashMap<>(); + serviceMappingList.forEach( + entry -> { + String peer = entry.getString("peer"); + String service = entry.getString("service"); + if (peer != null && service != null) { + serviceMapping.put(peer, service); + } + }); + return serviceMapping.isEmpty() ? null : serviceMapping; + } + + /** + * Return {@code .instrumentation.general.http.client.request_captured_headers}, or null if none + * is configured. + * + * @throws DeclarativeConfigException if an unexpected type is encountered accessing the property + */ + @Nullable + public static List httpClientRequestCapturedHeaders(ConfigProvider configProvider) { + return getOrNull( + configProvider, + config -> config.getScalarList("request_captured_headers", String.class), + "general", + "http", + "client"); + } + + /** + * Return {@code .instrumentation.general.http.client.response_captured_headers}, or null if none + * is configured. + * + * @throws DeclarativeConfigException if an unexpected type is encountered accessing the property + */ + @Nullable + public static List httpClientResponseCapturedHeaders(ConfigProvider configProvider) { + return getOrNull( + configProvider, + config -> config.getScalarList("response_captured_headers", String.class), + "general", + "http", + "client"); + } + + /** + * Return {@code .instrumentation.general.http.server.request_captured_headers}, or null if none + * is configured. + * + * @throws DeclarativeConfigException if an unexpected type is encountered accessing the property + */ + @Nullable + public static List httpServerRequestCapturedHeaders(ConfigProvider configProvider) { + return getOrNull( + configProvider, + config -> config.getScalarList("request_captured_headers", String.class), + "general", + "http", + "server"); + } + + /** + * Return {@code .instrumentation.general.http.server.response_captured_headers}, or null if none + * is configured. + * + * @throws DeclarativeConfigException if an unexpected type is encountered accessing the property + */ + @Nullable + public static List httpSeverResponseCapturedHeaders(ConfigProvider configProvider) { + return getOrNull( + configProvider, + config -> config.getScalarList("response_captured_headers", String.class), + "general", + "http", + "server"); + } + + /** + * Return {@code .instrumentation.java.}, or null if none is configured. + * + * @throws DeclarativeConfigException if an unexpected type is encountered accessing the property + */ + @Nullable + public static DeclarativeConfigProperties javaInstrumentationConfig( + ConfigProvider configProvider, String instrumentationName) { + return getOrNull(configProvider, config -> config.getStructured(instrumentationName), "java"); + } + + /** + * Walk down the {@code segments} of {@link ConfigProvider#getInstrumentationConfig()} and call + * {@code accessor} on the terminal node. Returns null if {@link + * ConfigProvider#getInstrumentationConfig()} is null, or if null is encountered walking the + * {@code segments}, or if {@code accessor} returns null. + * + *

      See other methods in {@link InstrumentationConfigUtil} for usage examples. + */ + @Nullable + public static T getOrNull( + ConfigProvider configProvider, + Function accessor, + String... segments) { + DeclarativeConfigProperties config = configProvider.getInstrumentationConfig(); + if (config == null) { + return null; + } + for (String segment : segments) { + config = config.getStructured(segment); + if (config == null) { + return null; + } + } + return accessor.apply(config); + } + + private InstrumentationConfigUtil() {} +} diff --git a/api/incubator/src/test/java/io/opentelemetry/api/incubator/ConfigProviderTest.java b/api/incubator/src/test/java/io/opentelemetry/api/incubator/ConfigProviderTest.java new file mode 100644 index 00000000000..9c9e4bf41e1 --- /dev/null +++ b/api/incubator/src/test/java/io/opentelemetry/api/incubator/ConfigProviderTest.java @@ -0,0 +1,20 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.api.incubator; + +import static org.assertj.core.api.Assertions.assertThat; + +import io.opentelemetry.api.incubator.config.ConfigProvider; +import org.junit.jupiter.api.Test; + +class ConfigProviderTest { + + @Test + void noopEquality() { + ConfigProvider noop = ConfigProvider.noop(); + assertThat(ConfigProvider.noop()).isSameAs(noop); + } +} diff --git a/api/incubator/src/test/java/io/opentelemetry/api/incubator/config/GlobalConfigProviderTest.java b/api/incubator/src/test/java/io/opentelemetry/api/incubator/config/GlobalConfigProviderTest.java new file mode 100644 index 00000000000..ecd837a5298 --- /dev/null +++ b/api/incubator/src/test/java/io/opentelemetry/api/incubator/config/GlobalConfigProviderTest.java @@ -0,0 +1,44 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.api.incubator.config; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; + +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; + +class GlobalConfigProviderTest { + + @BeforeAll + static void beforeClass() { + GlobalConfigProvider.resetForTest(); + } + + @AfterEach + void after() { + GlobalConfigProvider.resetForTest(); + } + + @Test + void setAndGet() { + assertThat(GlobalConfigProvider.get()).isEqualTo(ConfigProvider.noop()); + ConfigProvider configProvider = DeclarativeConfigProperties::empty; + GlobalConfigProvider.set(configProvider); + assertThat(GlobalConfigProvider.get()).isSameAs(configProvider); + } + + @Test + void setThenSet() { + ConfigProvider configProvider = DeclarativeConfigProperties::empty; + GlobalConfigProvider.set(configProvider); + assertThatThrownBy(() -> GlobalConfigProvider.set(configProvider)) + .isInstanceOf(IllegalStateException.class) + .hasMessageContaining("GlobalConfigProvider.set has already been called") + .hasStackTraceContaining("setThenSet"); + } +} diff --git a/api/incubator/src/test/java/io/opentelemetry/api/incubator/config/InstrumentationConfigUtilTest.java b/api/incubator/src/test/java/io/opentelemetry/api/incubator/config/InstrumentationConfigUtilTest.java new file mode 100644 index 00000000000..94da0f2d10b --- /dev/null +++ b/api/incubator/src/test/java/io/opentelemetry/api/incubator/config/InstrumentationConfigUtilTest.java @@ -0,0 +1,169 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.api.incubator.config; + +import static org.assertj.core.api.Assertions.assertThat; + +import com.google.common.collect.ImmutableMap; +import io.opentelemetry.sdk.extension.incubator.fileconfig.DeclarativeConfiguration; +import io.opentelemetry.sdk.extension.incubator.fileconfig.SdkConfigProvider; +import io.opentelemetry.sdk.extension.incubator.fileconfig.YamlDeclarativeConfigProperties; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.OpenTelemetryConfigurationModel; +import java.io.ByteArrayInputStream; +import java.nio.charset.StandardCharsets; +import java.util.Arrays; +import org.junit.jupiter.api.Test; + +class InstrumentationConfigUtilTest { + + /** + * See kitchen-sink.yaml. + */ + private static final String kitchenSinkInstrumentationConfig = + "instrumentation:\n" + + " general:\n" + + " peer:\n" + + " service_mapping:\n" + + " - peer: 1.2.3.4\n" + + " service: FooService\n" + + " - peer: 2.3.4.5\n" + + " service: BarService\n" + + " http:\n" + + " client:\n" + + " request_captured_headers:\n" + + " - client-request-header1\n" + + " - client-request-header2\n" + + " response_captured_headers:\n" + + " - client-response-header1\n" + + " - client-response-header2\n" + + " server:\n" + + " request_captured_headers:\n" + + " - server-request-header1\n" + + " - server-request-header2\n" + + " response_captured_headers:\n" + + " - server-response-header1\n" + + " - server-response-header2\n" + + " java:\n" + + " example:\n" + + " property: \"value\""; + + private static final ConfigProvider kitchenSinkConfigProvider = + toConfigProvider(kitchenSinkInstrumentationConfig); + private static final ConfigProvider emptyInstrumentationConfigProvider = + toConfigProvider("instrumentation:\n"); + private static final ConfigProvider emptyGeneralConfigProvider = + toConfigProvider("instrumentation:\n general:\n"); + private static final ConfigProvider emptyHttpConfigProvider = + toConfigProvider("instrumentation:\n general:\n http:\n"); + + private static ConfigProvider toConfigProvider(String configYaml) { + OpenTelemetryConfigurationModel configuration = + DeclarativeConfiguration.parse( + new ByteArrayInputStream(configYaml.getBytes(StandardCharsets.UTF_8))); + return SdkConfigProvider.create(configuration); + } + + @Test + void peerServiceMapping() { + assertThat(InstrumentationConfigUtil.peerServiceMapping(kitchenSinkConfigProvider)) + .isEqualTo(ImmutableMap.of("1.2.3.4", "FooService", "2.3.4.5", "BarService")); + assertThat(InstrumentationConfigUtil.peerServiceMapping(emptyInstrumentationConfigProvider)) + .isNull(); + assertThat(InstrumentationConfigUtil.peerServiceMapping(emptyGeneralConfigProvider)).isNull(); + assertThat(InstrumentationConfigUtil.peerServiceMapping(emptyHttpConfigProvider)).isNull(); + } + + @Test + void httpClientRequestCapturedHeaders() { + assertThat( + InstrumentationConfigUtil.httpClientRequestCapturedHeaders(kitchenSinkConfigProvider)) + .isEqualTo(Arrays.asList("client-request-header1", "client-request-header2")); + assertThat( + InstrumentationConfigUtil.httpClientRequestCapturedHeaders( + emptyInstrumentationConfigProvider)) + .isNull(); + assertThat( + InstrumentationConfigUtil.httpClientRequestCapturedHeaders(emptyGeneralConfigProvider)) + .isNull(); + assertThat(InstrumentationConfigUtil.httpClientRequestCapturedHeaders(emptyHttpConfigProvider)) + .isNull(); + } + + @Test + void httpClientResponseCapturedHeaders() { + assertThat( + InstrumentationConfigUtil.httpClientResponseCapturedHeaders(kitchenSinkConfigProvider)) + .isEqualTo(Arrays.asList("client-response-header1", "client-response-header2")); + assertThat( + InstrumentationConfigUtil.httpClientResponseCapturedHeaders( + emptyInstrumentationConfigProvider)) + .isNull(); + assertThat( + InstrumentationConfigUtil.httpClientResponseCapturedHeaders(emptyGeneralConfigProvider)) + .isNull(); + assertThat(InstrumentationConfigUtil.httpClientResponseCapturedHeaders(emptyHttpConfigProvider)) + .isNull(); + } + + @Test + void httpServerRequestCapturedHeaders() { + assertThat( + InstrumentationConfigUtil.httpServerRequestCapturedHeaders(kitchenSinkConfigProvider)) + .isEqualTo(Arrays.asList("server-request-header1", "server-request-header2")); + assertThat( + InstrumentationConfigUtil.httpServerRequestCapturedHeaders( + emptyInstrumentationConfigProvider)) + .isNull(); + assertThat( + InstrumentationConfigUtil.httpServerRequestCapturedHeaders(emptyGeneralConfigProvider)) + .isNull(); + assertThat(InstrumentationConfigUtil.httpServerRequestCapturedHeaders(emptyHttpConfigProvider)) + .isNull(); + } + + @Test + void httpServerResponseCapturedHeaders() { + assertThat( + InstrumentationConfigUtil.httpSeverResponseCapturedHeaders(kitchenSinkConfigProvider)) + .isEqualTo(Arrays.asList("server-response-header1", "server-response-header2")); + assertThat( + InstrumentationConfigUtil.httpSeverResponseCapturedHeaders( + emptyInstrumentationConfigProvider)) + .isNull(); + assertThat( + InstrumentationConfigUtil.httpSeverResponseCapturedHeaders(emptyGeneralConfigProvider)) + .isNull(); + assertThat(InstrumentationConfigUtil.httpSeverResponseCapturedHeaders(emptyHttpConfigProvider)) + .isNull(); + } + + @Test + void javaInstrumentationConfig() { + assertThat( + InstrumentationConfigUtil.javaInstrumentationConfig( + kitchenSinkConfigProvider, "example")) + .isNotNull() + .isInstanceOfSatisfying( + YamlDeclarativeConfigProperties.class, + exampleConfig -> + assertThat(exampleConfig.toMap()).isEqualTo(ImmutableMap.of("property", "value"))); + assertThat( + InstrumentationConfigUtil.javaInstrumentationConfig(kitchenSinkConfigProvider, "foo")) + .isNull(); + assertThat( + InstrumentationConfigUtil.javaInstrumentationConfig( + emptyInstrumentationConfigProvider, "example")) + .isNull(); + assertThat( + InstrumentationConfigUtil.javaInstrumentationConfig( + emptyGeneralConfigProvider, "example")) + .isNull(); + assertThat( + InstrumentationConfigUtil.javaInstrumentationConfig(emptyHttpConfigProvider, "example")) + .isNull(); + } +} diff --git a/exporters/common/build.gradle.kts b/exporters/common/build.gradle.kts index bbca8bc416a..8d5f38224e7 100644 --- a/exporters/common/build.gradle.kts +++ b/exporters/common/build.gradle.kts @@ -13,6 +13,7 @@ dependencies { api(project(":api:all")) api(project(":sdk-extensions:autoconfigure-spi")) + compileOnly(project(":api:incubator")) compileOnly(project(":sdk:common")) compileOnly(project(":exporters:common:compile-stub")) diff --git a/exporters/common/src/main/java/io/opentelemetry/exporter/internal/ExporterBuilderUtil.java b/exporters/common/src/main/java/io/opentelemetry/exporter/internal/ExporterBuilderUtil.java index f67c7fe7164..9e93cc38ab3 100644 --- a/exporters/common/src/main/java/io/opentelemetry/exporter/internal/ExporterBuilderUtil.java +++ b/exporters/common/src/main/java/io/opentelemetry/exporter/internal/ExporterBuilderUtil.java @@ -9,7 +9,6 @@ import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties; import io.opentelemetry.sdk.autoconfigure.spi.ConfigurationException; -import io.opentelemetry.sdk.autoconfigure.spi.internal.StructuredConfigProperties; import io.opentelemetry.sdk.common.export.MemoryMode; import io.opentelemetry.sdk.metrics.Aggregation; import io.opentelemetry.sdk.metrics.InstrumentType; @@ -63,22 +62,6 @@ public static void configureExporterMemoryMode( memoryModeConsumer.accept(memoryMode); } - /** Invoke the {@code memoryModeConsumer} with the configured {@link MemoryMode}. */ - public static void configureExporterMemoryMode( - StructuredConfigProperties config, Consumer memoryModeConsumer) { - String memoryModeStr = config.getString("memory_mode"); - if (memoryModeStr == null) { - return; - } - MemoryMode memoryMode; - try { - memoryMode = MemoryMode.valueOf(memoryModeStr.toUpperCase(Locale.ROOT)); - } catch (IllegalArgumentException e) { - throw new ConfigurationException("Unrecognized memory_mode: " + memoryModeStr, e); - } - memoryModeConsumer.accept(memoryMode); - } - /** * Invoke the {@code defaultAggregationSelectorConsumer} with the configured {@link * DefaultAggregationSelector}. @@ -126,30 +109,6 @@ public static void configureOtlpAggregationTemporality( aggregationTemporalitySelectorConsumer.accept(temporalitySelector); } - public static void configureOtlpAggregationTemporality( - StructuredConfigProperties config, - Consumer aggregationTemporalitySelectorConsumer) { - String temporalityStr = config.getString("temporality_preference"); - if (temporalityStr == null) { - return; - } - AggregationTemporalitySelector temporalitySelector; - switch (temporalityStr.toLowerCase(Locale.ROOT)) { - case "cumulative": - temporalitySelector = AggregationTemporalitySelector.alwaysCumulative(); - break; - case "delta": - temporalitySelector = AggregationTemporalitySelector.deltaPreferred(); - break; - case "lowmemory": - temporalitySelector = AggregationTemporalitySelector.lowMemory(); - break; - default: - throw new ConfigurationException("Unrecognized temporality_preference: " + temporalityStr); - } - aggregationTemporalitySelectorConsumer.accept(temporalitySelector); - } - /** * Invoke the {@code defaultAggregationSelectorConsumer} with the configured {@link * DefaultAggregationSelector}. @@ -165,28 +124,5 @@ public static void configureOtlpHistogramDefaultAggregation( } } - /** - * Invoke the {@code defaultAggregationSelectorConsumer} with the configured {@link - * DefaultAggregationSelector}. - */ - public static void configureOtlpHistogramDefaultAggregation( - StructuredConfigProperties config, - Consumer defaultAggregationSelectorConsumer) { - String defaultHistogramAggregation = config.getString("default_histogram_aggregation"); - if (defaultHistogramAggregation == null) { - return; - } - if (AggregationUtil.aggregationName(Aggregation.base2ExponentialBucketHistogram()) - .equalsIgnoreCase(defaultHistogramAggregation)) { - defaultAggregationSelectorConsumer.accept( - DefaultAggregationSelector.getDefault() - .with(InstrumentType.HISTOGRAM, Aggregation.base2ExponentialBucketHistogram())); - } else if (!AggregationUtil.aggregationName(explicitBucketHistogram()) - .equalsIgnoreCase(defaultHistogramAggregation)) { - throw new ConfigurationException( - "Unrecognized default_histogram_aggregation: " + defaultHistogramAggregation); - } - } - private ExporterBuilderUtil() {} } diff --git a/exporters/common/src/main/java/io/opentelemetry/exporter/internal/IncubatingExporterBuilderUtil.java b/exporters/common/src/main/java/io/opentelemetry/exporter/internal/IncubatingExporterBuilderUtil.java new file mode 100644 index 00000000000..f5992879cf8 --- /dev/null +++ b/exporters/common/src/main/java/io/opentelemetry/exporter/internal/IncubatingExporterBuilderUtil.java @@ -0,0 +1,93 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.exporter.internal; + +import static io.opentelemetry.sdk.metrics.Aggregation.explicitBucketHistogram; + +import io.opentelemetry.api.incubator.config.DeclarativeConfigProperties; +import io.opentelemetry.sdk.autoconfigure.spi.ConfigurationException; +import io.opentelemetry.sdk.common.export.MemoryMode; +import io.opentelemetry.sdk.metrics.Aggregation; +import io.opentelemetry.sdk.metrics.InstrumentType; +import io.opentelemetry.sdk.metrics.export.AggregationTemporalitySelector; +import io.opentelemetry.sdk.metrics.export.DefaultAggregationSelector; +import io.opentelemetry.sdk.metrics.internal.aggregator.AggregationUtil; +import java.util.Locale; +import java.util.function.Consumer; + +/** + * Utilities for exporter builders. + * + *

      This class is internal and is hence not for public use. Its APIs are unstable and can change + * at any time. + */ +public final class IncubatingExporterBuilderUtil { + + /** Invoke the {@code memoryModeConsumer} with the configured {@link MemoryMode}. */ + public static void configureExporterMemoryMode( + DeclarativeConfigProperties config, Consumer memoryModeConsumer) { + String memoryModeStr = config.getString("memory_mode"); + if (memoryModeStr == null) { + return; + } + MemoryMode memoryMode; + try { + memoryMode = MemoryMode.valueOf(memoryModeStr.toUpperCase(Locale.ROOT)); + } catch (IllegalArgumentException e) { + throw new ConfigurationException("Unrecognized memory_mode: " + memoryModeStr, e); + } + memoryModeConsumer.accept(memoryMode); + } + + public static void configureOtlpAggregationTemporality( + DeclarativeConfigProperties config, + Consumer aggregationTemporalitySelectorConsumer) { + String temporalityStr = config.getString("temporality_preference"); + if (temporalityStr == null) { + return; + } + AggregationTemporalitySelector temporalitySelector; + switch (temporalityStr.toLowerCase(Locale.ROOT)) { + case "cumulative": + temporalitySelector = AggregationTemporalitySelector.alwaysCumulative(); + break; + case "delta": + temporalitySelector = AggregationTemporalitySelector.deltaPreferred(); + break; + case "lowmemory": + temporalitySelector = AggregationTemporalitySelector.lowMemory(); + break; + default: + throw new ConfigurationException("Unrecognized temporality_preference: " + temporalityStr); + } + aggregationTemporalitySelectorConsumer.accept(temporalitySelector); + } + + /** + * Invoke the {@code defaultAggregationSelectorConsumer} with the configured {@link + * DefaultAggregationSelector}. + */ + public static void configureOtlpHistogramDefaultAggregation( + DeclarativeConfigProperties config, + Consumer defaultAggregationSelectorConsumer) { + String defaultHistogramAggregation = config.getString("default_histogram_aggregation"); + if (defaultHistogramAggregation == null) { + return; + } + if (AggregationUtil.aggregationName(Aggregation.base2ExponentialBucketHistogram()) + .equalsIgnoreCase(defaultHistogramAggregation)) { + defaultAggregationSelectorConsumer.accept( + DefaultAggregationSelector.getDefault() + .with(InstrumentType.HISTOGRAM, Aggregation.base2ExponentialBucketHistogram())); + } else if (!AggregationUtil.aggregationName(explicitBucketHistogram()) + .equalsIgnoreCase(defaultHistogramAggregation)) { + throw new ConfigurationException( + "Unrecognized default_histogram_aggregation: " + defaultHistogramAggregation); + } + } + + private IncubatingExporterBuilderUtil() {} +} diff --git a/exporters/logging-otlp/build.gradle.kts b/exporters/logging-otlp/build.gradle.kts index a65f52f8522..0870f2c9937 100644 --- a/exporters/logging-otlp/build.gradle.kts +++ b/exporters/logging-otlp/build.gradle.kts @@ -14,10 +14,12 @@ dependencies { implementation(project(":sdk:logs")) implementation(project(":exporters:otlp:common")) + compileOnly(project(":api:incubator")) implementation(project(":sdk-extensions:autoconfigure-spi")) implementation("com.fasterxml.jackson.core:jackson-core") + testImplementation(project(":api:incubator")) testImplementation(project(":sdk:testing")) testImplementation("com.google.guava:guava") diff --git a/exporters/logging-otlp/src/main/java/io/opentelemetry/exporter/logging/otlp/internal/logs/OtlpStdoutLogRecordExporterComponentProvider.java b/exporters/logging-otlp/src/main/java/io/opentelemetry/exporter/logging/otlp/internal/logs/OtlpStdoutLogRecordExporterComponentProvider.java index e80747a86ea..57817346d71 100644 --- a/exporters/logging-otlp/src/main/java/io/opentelemetry/exporter/logging/otlp/internal/logs/OtlpStdoutLogRecordExporterComponentProvider.java +++ b/exporters/logging-otlp/src/main/java/io/opentelemetry/exporter/logging/otlp/internal/logs/OtlpStdoutLogRecordExporterComponentProvider.java @@ -5,9 +5,9 @@ package io.opentelemetry.exporter.logging.otlp.internal.logs; -import io.opentelemetry.exporter.internal.ExporterBuilderUtil; +import io.opentelemetry.api.incubator.config.DeclarativeConfigProperties; +import io.opentelemetry.exporter.internal.IncubatingExporterBuilderUtil; import io.opentelemetry.sdk.autoconfigure.spi.internal.ComponentProvider; -import io.opentelemetry.sdk.autoconfigure.spi.internal.StructuredConfigProperties; import io.opentelemetry.sdk.logs.export.LogRecordExporter; /** @@ -30,9 +30,9 @@ public String getName() { } @Override - public LogRecordExporter create(StructuredConfigProperties config) { + public LogRecordExporter create(DeclarativeConfigProperties config) { OtlpStdoutLogRecordExporterBuilder builder = OtlpStdoutLogRecordExporter.builder(); - ExporterBuilderUtil.configureExporterMemoryMode(config, builder::setMemoryMode); + IncubatingExporterBuilderUtil.configureExporterMemoryMode(config, builder::setMemoryMode); return builder.build(); } } diff --git a/exporters/logging-otlp/src/main/java/io/opentelemetry/exporter/logging/otlp/internal/metrics/OtlpStdoutMetricExporterComponentProvider.java b/exporters/logging-otlp/src/main/java/io/opentelemetry/exporter/logging/otlp/internal/metrics/OtlpStdoutMetricExporterComponentProvider.java index 2a69bd0c7d1..c600edbd59d 100644 --- a/exporters/logging-otlp/src/main/java/io/opentelemetry/exporter/logging/otlp/internal/metrics/OtlpStdoutMetricExporterComponentProvider.java +++ b/exporters/logging-otlp/src/main/java/io/opentelemetry/exporter/logging/otlp/internal/metrics/OtlpStdoutMetricExporterComponentProvider.java @@ -5,9 +5,9 @@ package io.opentelemetry.exporter.logging.otlp.internal.metrics; -import io.opentelemetry.exporter.internal.ExporterBuilderUtil; +import io.opentelemetry.api.incubator.config.DeclarativeConfigProperties; +import io.opentelemetry.exporter.internal.IncubatingExporterBuilderUtil; import io.opentelemetry.sdk.autoconfigure.spi.internal.ComponentProvider; -import io.opentelemetry.sdk.autoconfigure.spi.internal.StructuredConfigProperties; import io.opentelemetry.sdk.metrics.export.MetricExporter; /** @@ -30,12 +30,12 @@ public String getName() { } @Override - public MetricExporter create(StructuredConfigProperties config) { + public MetricExporter create(DeclarativeConfigProperties config) { OtlpStdoutMetricExporterBuilder builder = OtlpStdoutMetricExporter.builder(); - ExporterBuilderUtil.configureExporterMemoryMode(config, builder::setMemoryMode); - ExporterBuilderUtil.configureOtlpAggregationTemporality( + IncubatingExporterBuilderUtil.configureExporterMemoryMode(config, builder::setMemoryMode); + IncubatingExporterBuilderUtil.configureOtlpAggregationTemporality( config, builder::setAggregationTemporalitySelector); - ExporterBuilderUtil.configureOtlpHistogramDefaultAggregation( + IncubatingExporterBuilderUtil.configureOtlpHistogramDefaultAggregation( config, builder::setDefaultAggregationSelector); return builder.build(); } diff --git a/exporters/logging-otlp/src/main/java/io/opentelemetry/exporter/logging/otlp/internal/traces/OtlpStdoutSpanExporterComponentProvider.java b/exporters/logging-otlp/src/main/java/io/opentelemetry/exporter/logging/otlp/internal/traces/OtlpStdoutSpanExporterComponentProvider.java index c21029ed133..8a821b3977b 100644 --- a/exporters/logging-otlp/src/main/java/io/opentelemetry/exporter/logging/otlp/internal/traces/OtlpStdoutSpanExporterComponentProvider.java +++ b/exporters/logging-otlp/src/main/java/io/opentelemetry/exporter/logging/otlp/internal/traces/OtlpStdoutSpanExporterComponentProvider.java @@ -5,9 +5,9 @@ package io.opentelemetry.exporter.logging.otlp.internal.traces; -import io.opentelemetry.exporter.internal.ExporterBuilderUtil; +import io.opentelemetry.api.incubator.config.DeclarativeConfigProperties; +import io.opentelemetry.exporter.internal.IncubatingExporterBuilderUtil; import io.opentelemetry.sdk.autoconfigure.spi.internal.ComponentProvider; -import io.opentelemetry.sdk.autoconfigure.spi.internal.StructuredConfigProperties; import io.opentelemetry.sdk.trace.export.SpanExporter; /** @@ -30,9 +30,9 @@ public String getName() { } @Override - public SpanExporter create(StructuredConfigProperties config) { + public SpanExporter create(DeclarativeConfigProperties config) { OtlpStdoutSpanExporterBuilder builder = OtlpStdoutSpanExporter.builder(); - ExporterBuilderUtil.configureExporterMemoryMode(config, builder::setMemoryMode); + IncubatingExporterBuilderUtil.configureExporterMemoryMode(config, builder::setMemoryMode); return builder.build(); } } diff --git a/exporters/logging-otlp/src/test/java/io/opentelemetry/exporter/logging/otlp/AbstractOtlpStdoutExporterTest.java b/exporters/logging-otlp/src/test/java/io/opentelemetry/exporter/logging/otlp/AbstractOtlpStdoutExporterTest.java index fbfd771a038..7605cc851dc 100644 --- a/exporters/logging-otlp/src/test/java/io/opentelemetry/exporter/logging/otlp/AbstractOtlpStdoutExporterTest.java +++ b/exporters/logging-otlp/src/test/java/io/opentelemetry/exporter/logging/otlp/AbstractOtlpStdoutExporterTest.java @@ -15,10 +15,10 @@ import com.google.common.collect.ImmutableList; import com.google.common.collect.Streams; import io.github.netmikey.logunit.api.LogCapturer; +import io.opentelemetry.api.incubator.config.DeclarativeConfigProperties; import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties; import io.opentelemetry.sdk.autoconfigure.spi.internal.ComponentProvider; import io.opentelemetry.sdk.autoconfigure.spi.internal.DefaultConfigProperties; -import io.opentelemetry.sdk.autoconfigure.spi.internal.StructuredConfigProperties; import io.opentelemetry.sdk.common.export.MemoryMode; import java.io.BufferedOutputStream; import java.io.ByteArrayOutputStream; @@ -306,7 +306,7 @@ void providerConfig() { @Test void componentProviderConfig() { - StructuredConfigProperties properties = mock(StructuredConfigProperties.class); + DeclarativeConfigProperties properties = mock(DeclarativeConfigProperties.class); T exporter = exporterFromComponentProvider(properties); assertThat(exporter).extracting("wrapperJsonObject").isEqualTo(true); @@ -328,7 +328,7 @@ void componentProviderConfig() { } @SuppressWarnings("unchecked") - protected T exporterFromComponentProvider(StructuredConfigProperties properties) { + protected T exporterFromComponentProvider(DeclarativeConfigProperties properties) { return (T) ((ComponentProvider) loadSpi(ComponentProvider.class) diff --git a/exporters/logging-otlp/src/test/java/io/opentelemetry/exporter/logging/otlp/OtlpStdoutMetricExporterTest.java b/exporters/logging-otlp/src/test/java/io/opentelemetry/exporter/logging/otlp/OtlpStdoutMetricExporterTest.java index fc081e229f4..df91f1e2cba 100644 --- a/exporters/logging-otlp/src/test/java/io/opentelemetry/exporter/logging/otlp/OtlpStdoutMetricExporterTest.java +++ b/exporters/logging-otlp/src/test/java/io/opentelemetry/exporter/logging/otlp/OtlpStdoutMetricExporterTest.java @@ -11,10 +11,10 @@ import static org.mockito.Mockito.when; import com.google.common.collect.ImmutableMap; +import io.opentelemetry.api.incubator.config.DeclarativeConfigProperties; import io.opentelemetry.exporter.logging.otlp.internal.metrics.OtlpStdoutMetricExporter; import io.opentelemetry.exporter.logging.otlp.internal.metrics.OtlpStdoutMetricExporterBuilder; import io.opentelemetry.sdk.autoconfigure.spi.internal.DefaultConfigProperties; -import io.opentelemetry.sdk.autoconfigure.spi.internal.StructuredConfigProperties; import io.opentelemetry.sdk.autoconfigure.spi.metrics.ConfigurableMetricExporterProvider; import io.opentelemetry.sdk.common.export.MemoryMode; import io.opentelemetry.sdk.metrics.Aggregation; @@ -81,7 +81,7 @@ void providerMetricConfig() { @Test void componentProviderMetricConfig() { - StructuredConfigProperties properties = mock(StructuredConfigProperties.class); + DeclarativeConfigProperties properties = mock(DeclarativeConfigProperties.class); when(properties.getString("temporality_preference")).thenReturn("DELTA"); when(properties.getString("default_histogram_aggregation")) .thenReturn("BASE2_EXPONENTIAL_BUCKET_HISTOGRAM"); diff --git a/exporters/logging/build.gradle.kts b/exporters/logging/build.gradle.kts index 6feefb00fe8..82e96771834 100644 --- a/exporters/logging/build.gradle.kts +++ b/exporters/logging/build.gradle.kts @@ -12,6 +12,7 @@ dependencies { api(project(":sdk:all")) implementation(project(":sdk-extensions:autoconfigure-spi")) + compileOnly(project(":api:incubator")) testImplementation(project(":sdk:testing")) } diff --git a/exporters/logging/src/main/java/io/opentelemetry/exporter/logging/internal/ConsoleLogRecordExporterComponentProvider.java b/exporters/logging/src/main/java/io/opentelemetry/exporter/logging/internal/ConsoleLogRecordExporterComponentProvider.java index 8c9d048c3b0..2d8141cc4f2 100644 --- a/exporters/logging/src/main/java/io/opentelemetry/exporter/logging/internal/ConsoleLogRecordExporterComponentProvider.java +++ b/exporters/logging/src/main/java/io/opentelemetry/exporter/logging/internal/ConsoleLogRecordExporterComponentProvider.java @@ -5,9 +5,9 @@ package io.opentelemetry.exporter.logging.internal; +import io.opentelemetry.api.incubator.config.DeclarativeConfigProperties; import io.opentelemetry.exporter.logging.SystemOutLogRecordExporter; import io.opentelemetry.sdk.autoconfigure.spi.internal.ComponentProvider; -import io.opentelemetry.sdk.autoconfigure.spi.internal.StructuredConfigProperties; import io.opentelemetry.sdk.logs.export.LogRecordExporter; /** @@ -30,7 +30,7 @@ public String getName() { } @Override - public LogRecordExporter create(StructuredConfigProperties config) { + public LogRecordExporter create(DeclarativeConfigProperties config) { return SystemOutLogRecordExporter.create(); } } diff --git a/exporters/logging/src/main/java/io/opentelemetry/exporter/logging/internal/ConsoleMetricExporterComponentProvider.java b/exporters/logging/src/main/java/io/opentelemetry/exporter/logging/internal/ConsoleMetricExporterComponentProvider.java index df5270ca11a..6fab453403f 100644 --- a/exporters/logging/src/main/java/io/opentelemetry/exporter/logging/internal/ConsoleMetricExporterComponentProvider.java +++ b/exporters/logging/src/main/java/io/opentelemetry/exporter/logging/internal/ConsoleMetricExporterComponentProvider.java @@ -5,9 +5,9 @@ package io.opentelemetry.exporter.logging.internal; +import io.opentelemetry.api.incubator.config.DeclarativeConfigProperties; import io.opentelemetry.exporter.logging.LoggingMetricExporter; import io.opentelemetry.sdk.autoconfigure.spi.internal.ComponentProvider; -import io.opentelemetry.sdk.autoconfigure.spi.internal.StructuredConfigProperties; import io.opentelemetry.sdk.metrics.export.MetricExporter; /** @@ -30,7 +30,7 @@ public String getName() { } @Override - public MetricExporter create(StructuredConfigProperties config) { + public MetricExporter create(DeclarativeConfigProperties config) { return LoggingMetricExporter.create(); } } diff --git a/exporters/logging/src/main/java/io/opentelemetry/exporter/logging/internal/ConsoleSpanExporterComponentProvider.java b/exporters/logging/src/main/java/io/opentelemetry/exporter/logging/internal/ConsoleSpanExporterComponentProvider.java index a6fa1950bdf..fd65a5acad8 100644 --- a/exporters/logging/src/main/java/io/opentelemetry/exporter/logging/internal/ConsoleSpanExporterComponentProvider.java +++ b/exporters/logging/src/main/java/io/opentelemetry/exporter/logging/internal/ConsoleSpanExporterComponentProvider.java @@ -5,9 +5,9 @@ package io.opentelemetry.exporter.logging.internal; +import io.opentelemetry.api.incubator.config.DeclarativeConfigProperties; import io.opentelemetry.exporter.logging.LoggingSpanExporter; import io.opentelemetry.sdk.autoconfigure.spi.internal.ComponentProvider; -import io.opentelemetry.sdk.autoconfigure.spi.internal.StructuredConfigProperties; import io.opentelemetry.sdk.trace.export.SpanExporter; /** @@ -29,7 +29,7 @@ public String getName() { } @Override - public SpanExporter create(StructuredConfigProperties config) { + public SpanExporter create(DeclarativeConfigProperties config) { return LoggingSpanExporter.create(); } } diff --git a/exporters/otlp/all/build.gradle.kts b/exporters/otlp/all/build.gradle.kts index 0c0ef6b75b7..eb9ad982c6f 100644 --- a/exporters/otlp/all/build.gradle.kts +++ b/exporters/otlp/all/build.gradle.kts @@ -20,6 +20,8 @@ dependencies { implementation(project(":exporters:sender:okhttp")) implementation(project(":sdk-extensions:autoconfigure-spi")) + compileOnly(project(":api:incubator")) + compileOnly("io.grpc:grpc-stub") testImplementation(project(":exporters:otlp:testing-internal")) diff --git a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/OtlpConfigUtil.java b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/OtlpConfigUtil.java index 999fc412a5a..bf580474066 100644 --- a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/OtlpConfigUtil.java +++ b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/OtlpConfigUtil.java @@ -8,8 +8,6 @@ import io.opentelemetry.exporter.internal.ExporterBuilderUtil; import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties; import io.opentelemetry.sdk.autoconfigure.spi.ConfigurationException; -import io.opentelemetry.sdk.autoconfigure.spi.internal.DefaultConfigProperties; -import io.opentelemetry.sdk.autoconfigure.spi.internal.StructuredConfigProperties; import io.opentelemetry.sdk.common.export.MemoryMode; import io.opentelemetry.sdk.common.export.RetryPolicy; import java.io.File; @@ -20,8 +18,6 @@ import java.net.URLDecoder; import java.nio.charset.StandardCharsets; import java.time.Duration; -import java.util.Collections; -import java.util.List; import java.util.Map; import java.util.function.BiConsumer; import java.util.function.Consumer; @@ -52,18 +48,6 @@ public static String getOtlpProtocol(String dataType, ConfigProperties config) { return config.getString("otel.exporter.otlp.protocol", PROTOCOL_GRPC); } - /** Determine the configured OTLP protocol for the {@code dataType}. */ - public static String getStructuredConfigOtlpProtocol(StructuredConfigProperties config) { - // NOTE: The default OTLP protocol is different for declarative config than for env var / system - // property based config. This is intentional. OpenTelemetry changed the default protocol - // recommendation from grpc to http/protobuf, but the autoconfigure's env var / system property - // based config did not update to reflect this before stabilizing, and changing is a breaking - // change requiring a major version bump. Declarative config is not yet stable and therefore can - // switch to the current default recommendation, which aligns also aligns with the behavior of - // the OpenTelemetry Java Agent 2.x+. - return config.getString("protocol", PROTOCOL_HTTP_PROTOBUF); - } - /** Invoke the setters with the OTLP configuration for the {@code dataType}. */ @SuppressWarnings("TooManyParameters") public static void configureOtlpExporterBuilder( @@ -164,81 +148,7 @@ public static void configureOtlpExporterBuilder( ExporterBuilderUtil.configureExporterMemoryMode(config, setMemoryMode); } - /** Invoke the setters with the OTLP configuration for the {@code dataType}. */ - @SuppressWarnings("TooManyParameters") - public static void configureOtlpExporterBuilder( - String dataType, - StructuredConfigProperties config, - Consumer setEndpoint, - BiConsumer addHeader, - Consumer setCompression, - Consumer setTimeout, - Consumer setTrustedCertificates, - BiConsumer setClientTls, - Consumer setRetryPolicy, - Consumer setMemoryMode) { - String protocol = getStructuredConfigOtlpProtocol(config); - boolean isHttpProtobuf = protocol.equals(PROTOCOL_HTTP_PROTOBUF); - URL endpoint = validateEndpoint(config.getString("endpoint"), isHttpProtobuf); - if (endpoint != null) { - setEndpoint.accept(endpoint.toString()); - } - - String headerList = config.getString("headers_list"); - if (headerList != null) { - ConfigProperties headersListConfig = - DefaultConfigProperties.createFromMap( - Collections.singletonMap("otel.exporter.otlp.headers", headerList)); - configureOtlpHeaders(headersListConfig, dataType, addHeader); - } - - List headers = config.getStructuredList("headers"); - if (headers != null) { - headers.forEach( - header -> { - String name = header.getString("name"); - String value = header.getString("value"); - if (name != null && value != null) { - addHeader.accept(name, value); - } - }); - } - - String compression = config.getString("compression"); - if (compression != null) { - setCompression.accept(compression); - } - - Integer timeoutMs = config.getInt("timeout"); - if (timeoutMs != null) { - setTimeout.accept(Duration.ofMillis(timeoutMs)); - } - - String certificatePath = config.getString("certificate"); - String clientKeyPath = config.getString("client_key"); - String clientKeyChainPath = config.getString("client_certificate"); - - if (clientKeyPath != null && clientKeyChainPath == null) { - throw new ConfigurationException( - "client_key provided without client_certificate - both client_key and client_certificate must be set"); - } else if (clientKeyPath == null && clientKeyChainPath != null) { - throw new ConfigurationException( - "client_certificate provided without client_key - both client_key and client_certificate must be set"); - } - byte[] certificateBytes = readFileBytes(certificatePath); - if (certificateBytes != null) { - setTrustedCertificates.accept(certificateBytes); - } - byte[] clientKeyBytes = readFileBytes(clientKeyPath); - byte[] clientKeyChainBytes = readFileBytes(clientKeyChainPath); - if (clientKeyBytes != null && clientKeyChainBytes != null) { - setClientTls.accept(clientKeyBytes, clientKeyChainBytes); - } - - ExporterBuilderUtil.configureExporterMemoryMode(config, setMemoryMode); - } - - private static void configureOtlpHeaders( + static void configureOtlpHeaders( ConfigProperties config, String dataType, BiConsumer addHeader) { Map headers = config.getMap("otel.exporter.otlp." + dataType + ".headers"); if (headers.isEmpty()) { @@ -266,7 +176,7 @@ private static URL createUrl(URL context, String spec) { } @Nullable - private static URL validateEndpoint(@Nullable String endpoint, boolean isHttpProtobuf) { + static URL validateEndpoint(@Nullable String endpoint, boolean isHttpProtobuf) { if (endpoint == null) { return null; } @@ -314,7 +224,7 @@ private static URL validateEndpoint(@Nullable String endpoint, boolean isHttpPro } @Nullable - private static byte[] readFileBytes(@Nullable String filePath) { + static byte[] readFileBytes(@Nullable String filePath) { if (filePath == null) { return null; } diff --git a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/OtlpDeclarativeConfigUtil.java b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/OtlpDeclarativeConfigUtil.java new file mode 100644 index 00000000000..55ed905364e --- /dev/null +++ b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/OtlpDeclarativeConfigUtil.java @@ -0,0 +1,120 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.exporter.otlp.internal; + +import static io.opentelemetry.exporter.otlp.internal.OtlpConfigUtil.PROTOCOL_HTTP_PROTOBUF; +import static io.opentelemetry.exporter.otlp.internal.OtlpConfigUtil.configureOtlpHeaders; +import static io.opentelemetry.exporter.otlp.internal.OtlpConfigUtil.readFileBytes; +import static io.opentelemetry.exporter.otlp.internal.OtlpConfigUtil.validateEndpoint; + +import io.opentelemetry.api.incubator.config.DeclarativeConfigProperties; +import io.opentelemetry.exporter.internal.IncubatingExporterBuilderUtil; +import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties; +import io.opentelemetry.sdk.autoconfigure.spi.ConfigurationException; +import io.opentelemetry.sdk.autoconfigure.spi.internal.DefaultConfigProperties; +import io.opentelemetry.sdk.common.export.MemoryMode; +import io.opentelemetry.sdk.common.export.RetryPolicy; +import java.net.URL; +import java.time.Duration; +import java.util.Collections; +import java.util.List; +import java.util.function.BiConsumer; +import java.util.function.Consumer; + +/** + * This class is internal and is hence not for public use. Its APIs are unstable and can change at + * any time. + */ +public final class OtlpDeclarativeConfigUtil { + + /** Determine the configured OTLP protocol for the {@code dataType}. */ + public static String getStructuredConfigOtlpProtocol(DeclarativeConfigProperties config) { + // NOTE: The default OTLP protocol is different for declarative config than for env var / system + // property based config. This is intentional. OpenTelemetry changed the default protocol + // recommendation from grpc to http/protobuf, but the autoconfigure's env var / system property + // based config did not update to reflect this before stabilizing, and changing is a breaking + // change requiring a major version bump. Declarative config is not yet stable and therefore can + // switch to the current default recommendation, which aligns also aligns with the behavior of + // the OpenTelemetry Java Agent 2.x+. + return config.getString("protocol", PROTOCOL_HTTP_PROTOBUF); + } + + /** Invoke the setters with the OTLP configuration for the {@code dataType}. */ + @SuppressWarnings("TooManyParameters") + public static void configureOtlpExporterBuilder( + String dataType, + DeclarativeConfigProperties config, + Consumer setEndpoint, + BiConsumer addHeader, + Consumer setCompression, + Consumer setTimeout, + Consumer setTrustedCertificates, + BiConsumer setClientTls, + Consumer setRetryPolicy, + Consumer setMemoryMode) { + String protocol = getStructuredConfigOtlpProtocol(config); + boolean isHttpProtobuf = protocol.equals(PROTOCOL_HTTP_PROTOBUF); + URL endpoint = validateEndpoint(config.getString("endpoint"), isHttpProtobuf); + if (endpoint != null) { + setEndpoint.accept(endpoint.toString()); + } + + String headerList = config.getString("headers_list"); + if (headerList != null) { + ConfigProperties headersListConfig = + DefaultConfigProperties.createFromMap( + Collections.singletonMap("otel.exporter.otlp.headers", headerList)); + configureOtlpHeaders(headersListConfig, dataType, addHeader); + } + + List headers = config.getStructuredList("headers"); + if (headers != null) { + headers.forEach( + header -> { + String name = header.getString("name"); + String value = header.getString("value"); + if (name != null && value != null) { + addHeader.accept(name, value); + } + }); + } + + String compression = config.getString("compression"); + if (compression != null) { + setCompression.accept(compression); + } + + Integer timeoutMs = config.getInt("timeout"); + if (timeoutMs != null) { + setTimeout.accept(Duration.ofMillis(timeoutMs)); + } + + String certificatePath = config.getString("certificate"); + String clientKeyPath = config.getString("client_key"); + String clientKeyChainPath = config.getString("client_certificate"); + + if (clientKeyPath != null && clientKeyChainPath == null) { + throw new ConfigurationException( + "client_key provided without client_certificate - both client_key and client_certificate must be set"); + } else if (clientKeyPath == null && clientKeyChainPath != null) { + throw new ConfigurationException( + "client_certificate provided without client_key - both client_key and client_certificate must be set"); + } + byte[] certificateBytes = readFileBytes(certificatePath); + if (certificateBytes != null) { + setTrustedCertificates.accept(certificateBytes); + } + byte[] clientKeyBytes = readFileBytes(clientKeyPath); + byte[] clientKeyChainBytes = readFileBytes(clientKeyChainPath); + if (clientKeyBytes != null && clientKeyChainBytes != null) { + setClientTls.accept(clientKeyBytes, clientKeyChainBytes); + } + + IncubatingExporterBuilderUtil.configureExporterMemoryMode(config, setMemoryMode); + } + + private OtlpDeclarativeConfigUtil() {} +} diff --git a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/OtlpLogRecordExporterComponentProvider.java b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/OtlpLogRecordExporterComponentProvider.java index 9134976e495..e10fd8bdd34 100644 --- a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/OtlpLogRecordExporterComponentProvider.java +++ b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/OtlpLogRecordExporterComponentProvider.java @@ -9,13 +9,13 @@ import static io.opentelemetry.exporter.otlp.internal.OtlpConfigUtil.PROTOCOL_GRPC; import static io.opentelemetry.exporter.otlp.internal.OtlpConfigUtil.PROTOCOL_HTTP_PROTOBUF; +import io.opentelemetry.api.incubator.config.DeclarativeConfigProperties; import io.opentelemetry.exporter.otlp.http.logs.OtlpHttpLogRecordExporter; import io.opentelemetry.exporter.otlp.http.logs.OtlpHttpLogRecordExporterBuilder; import io.opentelemetry.exporter.otlp.logs.OtlpGrpcLogRecordExporter; import io.opentelemetry.exporter.otlp.logs.OtlpGrpcLogRecordExporterBuilder; import io.opentelemetry.sdk.autoconfigure.spi.ConfigurationException; import io.opentelemetry.sdk.autoconfigure.spi.internal.ComponentProvider; -import io.opentelemetry.sdk.autoconfigure.spi.internal.StructuredConfigProperties; import io.opentelemetry.sdk.logs.export.LogRecordExporter; /** @@ -39,13 +39,13 @@ public String getName() { } @Override - public LogRecordExporter create(StructuredConfigProperties config) { - String protocol = OtlpConfigUtil.getStructuredConfigOtlpProtocol(config); + public LogRecordExporter create(DeclarativeConfigProperties config) { + String protocol = OtlpDeclarativeConfigUtil.getStructuredConfigOtlpProtocol(config); if (protocol.equals(PROTOCOL_HTTP_PROTOBUF)) { OtlpHttpLogRecordExporterBuilder builder = httpBuilder(); - OtlpConfigUtil.configureOtlpExporterBuilder( + OtlpDeclarativeConfigUtil.configureOtlpExporterBuilder( DATA_TYPE_LOGS, config, builder::setEndpoint, @@ -61,7 +61,7 @@ public LogRecordExporter create(StructuredConfigProperties config) { } else if (protocol.equals(PROTOCOL_GRPC)) { OtlpGrpcLogRecordExporterBuilder builder = grpcBuilder(); - OtlpConfigUtil.configureOtlpExporterBuilder( + OtlpDeclarativeConfigUtil.configureOtlpExporterBuilder( DATA_TYPE_LOGS, config, builder::setEndpoint, diff --git a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/OtlpMetricExporterComponentProvider.java b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/OtlpMetricExporterComponentProvider.java index a08cab883b1..c3b17710708 100644 --- a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/OtlpMetricExporterComponentProvider.java +++ b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/OtlpMetricExporterComponentProvider.java @@ -9,14 +9,14 @@ import static io.opentelemetry.exporter.otlp.internal.OtlpConfigUtil.PROTOCOL_GRPC; import static io.opentelemetry.exporter.otlp.internal.OtlpConfigUtil.PROTOCOL_HTTP_PROTOBUF; -import io.opentelemetry.exporter.internal.ExporterBuilderUtil; +import io.opentelemetry.api.incubator.config.DeclarativeConfigProperties; +import io.opentelemetry.exporter.internal.IncubatingExporterBuilderUtil; import io.opentelemetry.exporter.otlp.http.metrics.OtlpHttpMetricExporter; import io.opentelemetry.exporter.otlp.http.metrics.OtlpHttpMetricExporterBuilder; import io.opentelemetry.exporter.otlp.metrics.OtlpGrpcMetricExporter; import io.opentelemetry.exporter.otlp.metrics.OtlpGrpcMetricExporterBuilder; import io.opentelemetry.sdk.autoconfigure.spi.ConfigurationException; import io.opentelemetry.sdk.autoconfigure.spi.internal.ComponentProvider; -import io.opentelemetry.sdk.autoconfigure.spi.internal.StructuredConfigProperties; import io.opentelemetry.sdk.metrics.export.MetricExporter; /** @@ -39,13 +39,13 @@ public String getName() { } @Override - public MetricExporter create(StructuredConfigProperties config) { - String protocol = OtlpConfigUtil.getStructuredConfigOtlpProtocol(config); + public MetricExporter create(DeclarativeConfigProperties config) { + String protocol = OtlpDeclarativeConfigUtil.getStructuredConfigOtlpProtocol(config); if (protocol.equals(PROTOCOL_HTTP_PROTOBUF)) { OtlpHttpMetricExporterBuilder builder = httpBuilder(); - OtlpConfigUtil.configureOtlpExporterBuilder( + OtlpDeclarativeConfigUtil.configureOtlpExporterBuilder( DATA_TYPE_METRICS, config, builder::setEndpoint, @@ -56,16 +56,16 @@ public MetricExporter create(StructuredConfigProperties config) { builder::setClientTls, builder::setRetryPolicy, builder::setMemoryMode); - ExporterBuilderUtil.configureOtlpAggregationTemporality( + IncubatingExporterBuilderUtil.configureOtlpAggregationTemporality( config, builder::setAggregationTemporalitySelector); - ExporterBuilderUtil.configureOtlpHistogramDefaultAggregation( + IncubatingExporterBuilderUtil.configureOtlpHistogramDefaultAggregation( config, builder::setDefaultAggregationSelector); return builder.build(); } else if (protocol.equals(PROTOCOL_GRPC)) { OtlpGrpcMetricExporterBuilder builder = grpcBuilder(); - OtlpConfigUtil.configureOtlpExporterBuilder( + OtlpDeclarativeConfigUtil.configureOtlpExporterBuilder( DATA_TYPE_METRICS, config, builder::setEndpoint, @@ -76,9 +76,9 @@ public MetricExporter create(StructuredConfigProperties config) { builder::setClientTls, builder::setRetryPolicy, builder::setMemoryMode); - ExporterBuilderUtil.configureOtlpAggregationTemporality( + IncubatingExporterBuilderUtil.configureOtlpAggregationTemporality( config, builder::setAggregationTemporalitySelector); - ExporterBuilderUtil.configureOtlpHistogramDefaultAggregation( + IncubatingExporterBuilderUtil.configureOtlpHistogramDefaultAggregation( config, builder::setDefaultAggregationSelector); return builder.build(); diff --git a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/OtlpSpanExporterComponentProvider.java b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/OtlpSpanExporterComponentProvider.java index 1f84115b252..befa77c6fd3 100644 --- a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/OtlpSpanExporterComponentProvider.java +++ b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/OtlpSpanExporterComponentProvider.java @@ -9,13 +9,13 @@ import static io.opentelemetry.exporter.otlp.internal.OtlpConfigUtil.PROTOCOL_GRPC; import static io.opentelemetry.exporter.otlp.internal.OtlpConfigUtil.PROTOCOL_HTTP_PROTOBUF; +import io.opentelemetry.api.incubator.config.DeclarativeConfigProperties; import io.opentelemetry.exporter.otlp.http.trace.OtlpHttpSpanExporter; import io.opentelemetry.exporter.otlp.http.trace.OtlpHttpSpanExporterBuilder; import io.opentelemetry.exporter.otlp.trace.OtlpGrpcSpanExporter; import io.opentelemetry.exporter.otlp.trace.OtlpGrpcSpanExporterBuilder; import io.opentelemetry.sdk.autoconfigure.spi.ConfigurationException; import io.opentelemetry.sdk.autoconfigure.spi.internal.ComponentProvider; -import io.opentelemetry.sdk.autoconfigure.spi.internal.StructuredConfigProperties; import io.opentelemetry.sdk.trace.export.SpanExporter; /** @@ -38,13 +38,13 @@ public String getName() { } @Override - public SpanExporter create(StructuredConfigProperties config) { - String protocol = OtlpConfigUtil.getStructuredConfigOtlpProtocol(config); + public SpanExporter create(DeclarativeConfigProperties config) { + String protocol = OtlpDeclarativeConfigUtil.getStructuredConfigOtlpProtocol(config); if (protocol.equals(PROTOCOL_HTTP_PROTOBUF)) { OtlpHttpSpanExporterBuilder builder = httpBuilder(); - OtlpConfigUtil.configureOtlpExporterBuilder( + OtlpDeclarativeConfigUtil.configureOtlpExporterBuilder( DATA_TYPE_TRACES, config, builder::setEndpoint, @@ -60,7 +60,7 @@ public SpanExporter create(StructuredConfigProperties config) { } else if (protocol.equals(PROTOCOL_GRPC)) { OtlpGrpcSpanExporterBuilder builder = grpcBuilder(); - OtlpConfigUtil.configureOtlpExporterBuilder( + OtlpDeclarativeConfigUtil.configureOtlpExporterBuilder( DATA_TYPE_TRACES, config, builder::setEndpoint, diff --git a/exporters/prometheus/build.gradle.kts b/exporters/prometheus/build.gradle.kts index 3b44fad2c56..30e52664419 100644 --- a/exporters/prometheus/build.gradle.kts +++ b/exporters/prometheus/build.gradle.kts @@ -9,6 +9,7 @@ otelJava.moduleName.set("io.opentelemetry.exporter.prometheus") dependencies { api(project(":sdk:metrics")) + compileOnly(project(":api:incubator")) implementation(project(":exporters:common")) implementation(project(":sdk-extensions:autoconfigure-spi")) implementation("io.prometheus:prometheus-metrics-exporter-httpserver") diff --git a/exporters/prometheus/src/main/java/io/opentelemetry/exporter/prometheus/internal/PrometheusComponentProvider.java b/exporters/prometheus/src/main/java/io/opentelemetry/exporter/prometheus/internal/PrometheusComponentProvider.java index 7599619a3a5..04b8094608a 100644 --- a/exporters/prometheus/src/main/java/io/opentelemetry/exporter/prometheus/internal/PrometheusComponentProvider.java +++ b/exporters/prometheus/src/main/java/io/opentelemetry/exporter/prometheus/internal/PrometheusComponentProvider.java @@ -5,10 +5,10 @@ package io.opentelemetry.exporter.prometheus.internal; +import io.opentelemetry.api.incubator.config.DeclarativeConfigProperties; import io.opentelemetry.exporter.prometheus.PrometheusHttpServer; import io.opentelemetry.exporter.prometheus.PrometheusHttpServerBuilder; import io.opentelemetry.sdk.autoconfigure.spi.internal.ComponentProvider; -import io.opentelemetry.sdk.autoconfigure.spi.internal.StructuredConfigProperties; import io.opentelemetry.sdk.metrics.export.MetricReader; /** @@ -30,7 +30,7 @@ public String getName() { } @Override - public MetricReader create(StructuredConfigProperties config) { + public MetricReader create(DeclarativeConfigProperties config) { PrometheusHttpServerBuilder prometheusBuilder = PrometheusHttpServer.builder(); Integer port = config.getInt("port"); diff --git a/exporters/zipkin/build.gradle.kts b/exporters/zipkin/build.gradle.kts index ade51707932..1636cd7ace8 100644 --- a/exporters/zipkin/build.gradle.kts +++ b/exporters/zipkin/build.gradle.kts @@ -15,6 +15,7 @@ dependencies { implementation(project(":exporters:common")) implementation(project(":sdk-extensions:autoconfigure-spi")) + compileOnly(project(":api:incubator")) implementation("io.zipkin.reporter2:zipkin-sender-okhttp3") diff --git a/exporters/zipkin/src/main/java/io/opentelemetry/exporter/zipkin/internal/ZipkinSpanExporterComponentProvider.java b/exporters/zipkin/src/main/java/io/opentelemetry/exporter/zipkin/internal/ZipkinSpanExporterComponentProvider.java index f539a8ecde6..42c43eef14a 100644 --- a/exporters/zipkin/src/main/java/io/opentelemetry/exporter/zipkin/internal/ZipkinSpanExporterComponentProvider.java +++ b/exporters/zipkin/src/main/java/io/opentelemetry/exporter/zipkin/internal/ZipkinSpanExporterComponentProvider.java @@ -5,10 +5,10 @@ package io.opentelemetry.exporter.zipkin.internal; +import io.opentelemetry.api.incubator.config.DeclarativeConfigProperties; import io.opentelemetry.exporter.zipkin.ZipkinSpanExporter; import io.opentelemetry.exporter.zipkin.ZipkinSpanExporterBuilder; import io.opentelemetry.sdk.autoconfigure.spi.internal.ComponentProvider; -import io.opentelemetry.sdk.autoconfigure.spi.internal.StructuredConfigProperties; import io.opentelemetry.sdk.trace.export.SpanExporter; import java.time.Duration; @@ -30,7 +30,7 @@ public String getName() { } @Override - public SpanExporter create(StructuredConfigProperties config) { + public SpanExporter create(DeclarativeConfigProperties config) { ZipkinSpanExporterBuilder builder = ZipkinSpanExporter.builder(); String endpoint = config.getString("endpoint"); diff --git a/extensions/trace-propagators/build.gradle.kts b/extensions/trace-propagators/build.gradle.kts index 0683986978d..8ede73f0b0e 100644 --- a/extensions/trace-propagators/build.gradle.kts +++ b/extensions/trace-propagators/build.gradle.kts @@ -12,6 +12,7 @@ otelJava.moduleName.set("io.opentelemetry.extension.trace.propagation") dependencies { api(project(":api:all")) + compileOnly(project(":api:incubator")) compileOnly(project(":sdk-extensions:autoconfigure-spi")) testImplementation("io.jaegertracing:jaeger-client") diff --git a/extensions/trace-propagators/src/main/java/io/opentelemetry/extension/trace/propagation/internal/B3ComponentProvider.java b/extensions/trace-propagators/src/main/java/io/opentelemetry/extension/trace/propagation/internal/B3ComponentProvider.java index ba42a1fd07e..ebd766640f9 100644 --- a/extensions/trace-propagators/src/main/java/io/opentelemetry/extension/trace/propagation/internal/B3ComponentProvider.java +++ b/extensions/trace-propagators/src/main/java/io/opentelemetry/extension/trace/propagation/internal/B3ComponentProvider.java @@ -5,10 +5,10 @@ package io.opentelemetry.extension.trace.propagation.internal; +import io.opentelemetry.api.incubator.config.DeclarativeConfigProperties; import io.opentelemetry.context.propagation.TextMapPropagator; import io.opentelemetry.extension.trace.propagation.B3Propagator; import io.opentelemetry.sdk.autoconfigure.spi.internal.ComponentProvider; -import io.opentelemetry.sdk.autoconfigure.spi.internal.StructuredConfigProperties; /** * Declarative configuration SPI implementation for {@link B3Propagator} which allows enables the @@ -30,7 +30,7 @@ public String getName() { } @Override - public TextMapPropagator create(StructuredConfigProperties config) { + public TextMapPropagator create(DeclarativeConfigProperties config) { return B3Propagator.injectingSingleHeader(); } } diff --git a/extensions/trace-propagators/src/main/java/io/opentelemetry/extension/trace/propagation/internal/B3MultiComponentProvider.java b/extensions/trace-propagators/src/main/java/io/opentelemetry/extension/trace/propagation/internal/B3MultiComponentProvider.java index a95e195621c..0fb223d81a7 100644 --- a/extensions/trace-propagators/src/main/java/io/opentelemetry/extension/trace/propagation/internal/B3MultiComponentProvider.java +++ b/extensions/trace-propagators/src/main/java/io/opentelemetry/extension/trace/propagation/internal/B3MultiComponentProvider.java @@ -5,10 +5,10 @@ package io.opentelemetry.extension.trace.propagation.internal; +import io.opentelemetry.api.incubator.config.DeclarativeConfigProperties; import io.opentelemetry.context.propagation.TextMapPropagator; import io.opentelemetry.extension.trace.propagation.B3Propagator; import io.opentelemetry.sdk.autoconfigure.spi.internal.ComponentProvider; -import io.opentelemetry.sdk.autoconfigure.spi.internal.StructuredConfigProperties; /** * Declarative configuration SPI implementation for {@link B3Propagator} which allows enables the @@ -30,7 +30,7 @@ public String getName() { } @Override - public TextMapPropagator create(StructuredConfigProperties config) { + public TextMapPropagator create(DeclarativeConfigProperties config) { return B3Propagator.injectingMultiHeaders(); } } diff --git a/extensions/trace-propagators/src/main/java/io/opentelemetry/extension/trace/propagation/internal/JaegerComponentProvider.java b/extensions/trace-propagators/src/main/java/io/opentelemetry/extension/trace/propagation/internal/JaegerComponentProvider.java index d3e3111b3fd..1326dd4cc83 100644 --- a/extensions/trace-propagators/src/main/java/io/opentelemetry/extension/trace/propagation/internal/JaegerComponentProvider.java +++ b/extensions/trace-propagators/src/main/java/io/opentelemetry/extension/trace/propagation/internal/JaegerComponentProvider.java @@ -5,10 +5,10 @@ package io.opentelemetry.extension.trace.propagation.internal; +import io.opentelemetry.api.incubator.config.DeclarativeConfigProperties; import io.opentelemetry.context.propagation.TextMapPropagator; import io.opentelemetry.extension.trace.propagation.JaegerPropagator; import io.opentelemetry.sdk.autoconfigure.spi.internal.ComponentProvider; -import io.opentelemetry.sdk.autoconfigure.spi.internal.StructuredConfigProperties; /** * Declarative configuration SPI implementation for {@link JaegerPropagator}. @@ -29,7 +29,7 @@ public String getName() { } @Override - public TextMapPropagator create(StructuredConfigProperties config) { + public TextMapPropagator create(DeclarativeConfigProperties config) { return JaegerPropagator.getInstance(); } } diff --git a/extensions/trace-propagators/src/main/java/io/opentelemetry/extension/trace/propagation/internal/OtTraceComponentProvider.java b/extensions/trace-propagators/src/main/java/io/opentelemetry/extension/trace/propagation/internal/OtTraceComponentProvider.java index 3e4f978f626..261eb5f8585 100644 --- a/extensions/trace-propagators/src/main/java/io/opentelemetry/extension/trace/propagation/internal/OtTraceComponentProvider.java +++ b/extensions/trace-propagators/src/main/java/io/opentelemetry/extension/trace/propagation/internal/OtTraceComponentProvider.java @@ -5,11 +5,11 @@ package io.opentelemetry.extension.trace.propagation.internal; +import io.opentelemetry.api.incubator.config.DeclarativeConfigProperties; import io.opentelemetry.context.propagation.TextMapPropagator; import io.opentelemetry.extension.trace.propagation.B3Propagator; import io.opentelemetry.extension.trace.propagation.OtTracePropagator; import io.opentelemetry.sdk.autoconfigure.spi.internal.ComponentProvider; -import io.opentelemetry.sdk.autoconfigure.spi.internal.StructuredConfigProperties; /** * Declarative configuration SPI implementation for {@link B3Propagator}. @@ -30,7 +30,7 @@ public String getName() { } @Override - public TextMapPropagator create(StructuredConfigProperties config) { + public TextMapPropagator create(DeclarativeConfigProperties config) { return OtTracePropagator.getInstance(); } } diff --git a/sdk-extensions/autoconfigure-spi/build.gradle.kts b/sdk-extensions/autoconfigure-spi/build.gradle.kts index 53b10f0a104..32985cdf4e9 100644 --- a/sdk-extensions/autoconfigure-spi/build.gradle.kts +++ b/sdk-extensions/autoconfigure-spi/build.gradle.kts @@ -8,4 +8,5 @@ otelJava.moduleName.set("io.opentelemetry.sdk.autoconfigure.spi") dependencies { api(project(":sdk:all")) + compileOnly(project(":api:incubator")) } diff --git a/sdk-extensions/autoconfigure-spi/src/main/java/io/opentelemetry/sdk/autoconfigure/spi/internal/ComponentProvider.java b/sdk-extensions/autoconfigure-spi/src/main/java/io/opentelemetry/sdk/autoconfigure/spi/internal/ComponentProvider.java index 4724a3d1954..5772a0a1797 100644 --- a/sdk-extensions/autoconfigure-spi/src/main/java/io/opentelemetry/sdk/autoconfigure/spi/internal/ComponentProvider.java +++ b/sdk-extensions/autoconfigure-spi/src/main/java/io/opentelemetry/sdk/autoconfigure/spi/internal/ComponentProvider.java @@ -5,6 +5,7 @@ package io.opentelemetry.sdk.autoconfigure.spi.internal; +import io.opentelemetry.api.incubator.config.DeclarativeConfigProperties; import io.opentelemetry.context.propagation.TextMapPropagator; import io.opentelemetry.sdk.logs.LogRecordProcessor; import io.opentelemetry.sdk.logs.export.LogRecordExporter; @@ -20,8 +21,8 @@ * configuration. * *

      NOTE: when {@link #getType()} is {@link Resource}, the {@link #getName()} is not (currently) - * used, and {@link #create(StructuredConfigProperties)} is (currently) called with an empty {@link - * StructuredConfigProperties}. + * used, and {@link #create(DeclarativeConfigProperties)} is (currently) called with an empty {@link + * DeclarativeConfigProperties}. * *

      This class is internal and is hence not for public use. Its APIs are unstable and can change * at any time. @@ -58,5 +59,5 @@ public interface ComponentProvider { */ // TODO (jack-berg): consider dynamic configuration use case before stabilizing in case that // affects any API decisions - T create(StructuredConfigProperties config); + T create(DeclarativeConfigProperties config); } diff --git a/sdk-extensions/autoconfigure/build.gradle.kts b/sdk-extensions/autoconfigure/build.gradle.kts index eac32f51cdb..a00685f6e6d 100644 --- a/sdk-extensions/autoconfigure/build.gradle.kts +++ b/sdk-extensions/autoconfigure/build.gradle.kts @@ -10,6 +10,8 @@ dependencies { api(project(":sdk:all")) api(project(":sdk-extensions:autoconfigure-spi")) + compileOnly(project(":api:incubator")) + annotationProcessor("com.google.auto.value:auto-value") testImplementation(project(":sdk:trace-shaded-deps")) @@ -45,7 +47,6 @@ testing { } register("testFullConfig") { dependencies { - implementation(project(":api:incubator")) implementation(project(":extensions:trace-propagators")) implementation(project(":exporters:logging")) implementation(project(":exporters:logging-otlp")) @@ -78,6 +79,13 @@ testing { } } } + register("testIncubating") { + dependencies { + implementation(project(":sdk-extensions:incubator")) + implementation(project(":exporters:logging")) + implementation(project(":sdk:testing")) + } + } } } diff --git a/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/AutoConfiguredOpenTelemetrySdk.java b/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/AutoConfiguredOpenTelemetrySdk.java index 666da0f89c7..c5d9c77f4ee 100644 --- a/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/AutoConfiguredOpenTelemetrySdk.java +++ b/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/AutoConfiguredOpenTelemetrySdk.java @@ -8,9 +8,10 @@ import com.google.auto.value.AutoValue; import io.opentelemetry.api.GlobalOpenTelemetry; import io.opentelemetry.api.OpenTelemetry; +import io.opentelemetry.api.incubator.config.ConfigProvider; import io.opentelemetry.sdk.OpenTelemetrySdk; +import io.opentelemetry.sdk.autoconfigure.internal.AutoConfigureUtil; import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties; -import io.opentelemetry.sdk.autoconfigure.spi.internal.StructuredConfigProperties; import io.opentelemetry.sdk.resources.Resource; import javax.annotation.Nullable; import javax.annotation.concurrent.Immutable; @@ -48,9 +49,8 @@ static AutoConfiguredOpenTelemetrySdk create( OpenTelemetrySdk sdk, Resource resource, @Nullable ConfigProperties config, - @Nullable StructuredConfigProperties structuredConfigProperties) { - return new AutoValue_AutoConfiguredOpenTelemetrySdk( - sdk, resource, config, structuredConfigProperties); + @Nullable Object configProvider) { + return new AutoValue_AutoConfiguredOpenTelemetrySdk(sdk, resource, config, configProvider); } /** @@ -70,19 +70,24 @@ static AutoConfiguredOpenTelemetrySdk create( * Returns the {@link ConfigProperties} used for auto-configuration, or {@code null} if * declarative configuration was used. * - * @see #getStructuredConfig() + *

      This method is experimental so not public. You may reflectively call it using {@link + * AutoConfigureUtil#getConfig(AutoConfiguredOpenTelemetrySdk)}. + * + * @see #getConfigProvider() */ @Nullable abstract ConfigProperties getConfig(); /** - * Returns the {@link StructuredConfigProperties} used for auto-configuration, or {@code null} if - * declarative configuration was not used. + * Returns the {@link ConfigProvider}, or {@code null} if declarative configuration was not used. + * + *

      This method is experimental so not public. You may reflectively call it using {@link + * AutoConfigureUtil#getConfigProvider(AutoConfiguredOpenTelemetrySdk)}. * * @see #getConfig() */ @Nullable - abstract StructuredConfigProperties getStructuredConfig(); + abstract Object getConfigProvider(); AutoConfiguredOpenTelemetrySdk() {} } diff --git a/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/AutoConfiguredOpenTelemetrySdkBuilder.java b/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/AutoConfiguredOpenTelemetrySdkBuilder.java index 09cec8b892d..0e1586497a6 100644 --- a/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/AutoConfiguredOpenTelemetrySdkBuilder.java +++ b/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/AutoConfiguredOpenTelemetrySdkBuilder.java @@ -20,7 +20,6 @@ import io.opentelemetry.sdk.autoconfigure.spi.ConfigurationException; import io.opentelemetry.sdk.autoconfigure.spi.internal.AutoConfigureListener; import io.opentelemetry.sdk.autoconfigure.spi.internal.DefaultConfigProperties; -import io.opentelemetry.sdk.autoconfigure.spi.internal.StructuredConfigProperties; import io.opentelemetry.sdk.logs.LogRecordProcessor; import io.opentelemetry.sdk.logs.SdkLoggerProvider; import io.opentelemetry.sdk.logs.SdkLoggerProviderBuilder; @@ -36,12 +35,7 @@ import io.opentelemetry.sdk.trace.export.SpanExporter; import io.opentelemetry.sdk.trace.samplers.Sampler; import java.io.Closeable; -import java.io.FileInputStream; -import java.io.FileNotFoundException; import java.io.IOException; -import java.io.InputStream; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; @@ -65,6 +59,18 @@ public final class AutoConfiguredOpenTelemetrySdkBuilder implements AutoConfigur private static final Logger logger = Logger.getLogger(AutoConfiguredOpenTelemetrySdkBuilder.class.getName()); + private static final boolean INCUBATOR_AVAILABLE; + + static { + boolean incubatorAvailable = false; + try { + Class.forName("io.opentelemetry.sdk.extension.incubator.fileconfig.DeclarativeConfiguration"); + incubatorAvailable = true; + } catch (ClassNotFoundException e) { + // Not available + } + INCUBATOR_AVAILABLE = incubatorAvailable; + } @Nullable private ConfigProperties config; @@ -431,7 +437,8 @@ public AutoConfiguredOpenTelemetrySdk build() { maybeConfigureFromFile(config, componentLoader); if (fromFileConfiguration != null) { maybeRegisterShutdownHook(fromFileConfiguration.getOpenTelemetrySdk()); - maybeSetAsGlobal(fromFileConfiguration.getOpenTelemetrySdk()); + maybeSetAsGlobal( + fromFileConfiguration.getOpenTelemetrySdk(), fromFileConfiguration.getConfigProvider()); return fromFileConfiguration; } @@ -457,7 +464,7 @@ public AutoConfiguredOpenTelemetrySdk build() { OpenTelemetrySdk openTelemetrySdk = sdkBuilder.build(); maybeRegisterShutdownHook(openTelemetrySdk); - maybeSetAsGlobal(openTelemetrySdk); + maybeSetAsGlobal(openTelemetrySdk, null); callAutoConfigureListeners(spiHelper, openTelemetrySdk); return AutoConfiguredOpenTelemetrySdk.create(openTelemetrySdk, resource, config, null); @@ -548,44 +555,11 @@ private static AutoConfiguredOpenTelemetrySdk maybeConfigureFromFile( if (configurationFile == null || configurationFile.isEmpty()) { return null; } - logger.fine("Autoconfiguring from configuration file: " + configurationFile); - try (FileInputStream fis = new FileInputStream(configurationFile)) { - Class configurationFactory = - Class.forName("io.opentelemetry.sdk.extension.incubator.fileconfig.FileConfiguration"); - Method parse = configurationFactory.getMethod("parse", InputStream.class); - Object model = parse.invoke(null, fis); - Class openTelemetryConfiguration = - Class.forName( - "io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.OpenTelemetryConfigurationModel"); - Method create = - configurationFactory.getMethod( - "create", openTelemetryConfiguration, ComponentLoader.class); - OpenTelemetrySdk sdk = (OpenTelemetrySdk) create.invoke(null, model, componentLoader); - Method toConfigProperties = - configurationFactory.getMethod("toConfigProperties", openTelemetryConfiguration); - StructuredConfigProperties structuredConfigProperties = - (StructuredConfigProperties) toConfigProperties.invoke(null, model); - // Note: can't access declarative configuration resource without reflection so setting a dummy - // resource - return AutoConfiguredOpenTelemetrySdk.create( - sdk, Resource.getDefault(), null, structuredConfigProperties); - } catch (FileNotFoundException e) { - throw new ConfigurationException("Configuration file not found", e); - } catch (ClassNotFoundException | NoSuchMethodException | IllegalAccessException e) { + if (!INCUBATOR_AVAILABLE) { throw new ConfigurationException( - "Error configuring from file. Is opentelemetry-sdk-extension-incubator on the classpath?", - e); - } catch (InvocationTargetException e) { - Throwable cause = e.getCause(); - if (cause instanceof ConfigurationException) { - throw (ConfigurationException) cause; - } - throw new ConfigurationException("Unexpected error configuring from file", e); - } catch (IOException e) { - // IOException (other than FileNotFoundException which is caught above) is only thrown - // above by FileInputStream.close() - throw new ConfigurationException("Error closing file", e); + "Cannot autoconfigure from config file without opentelemetry-sdk-extension-incubator on the classpath"); } + return IncubatingUtil.configureFromFile(logger, configurationFile, componentLoader); } private void maybeRegisterShutdownHook(OpenTelemetrySdk openTelemetrySdk) { @@ -595,11 +569,15 @@ private void maybeRegisterShutdownHook(OpenTelemetrySdk openTelemetrySdk) { Runtime.getRuntime().addShutdownHook(shutdownHook(openTelemetrySdk)); } - private void maybeSetAsGlobal(OpenTelemetrySdk openTelemetrySdk) { + private void maybeSetAsGlobal( + OpenTelemetrySdk openTelemetrySdk, @Nullable Object configProvider) { if (!setResultAsGlobal) { return; } GlobalOpenTelemetry.set(openTelemetrySdk); + if (INCUBATOR_AVAILABLE && configProvider != null) { + IncubatingUtil.setGlobalConfigProvider(configProvider); + } logger.log( Level.FINE, "Global OpenTelemetry set to {0} by autoconfiguration", openTelemetrySdk); } diff --git a/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/IncubatingUtil.java b/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/IncubatingUtil.java new file mode 100644 index 00000000000..a1280e241d4 --- /dev/null +++ b/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/IncubatingUtil.java @@ -0,0 +1,88 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.sdk.autoconfigure; + +import io.opentelemetry.api.incubator.config.ConfigProvider; +import io.opentelemetry.api.incubator.config.DeclarativeConfigException; +import io.opentelemetry.api.incubator.config.GlobalConfigProvider; +import io.opentelemetry.sdk.OpenTelemetrySdk; +import io.opentelemetry.sdk.autoconfigure.internal.ComponentLoader; +import io.opentelemetry.sdk.autoconfigure.spi.ConfigurationException; +import io.opentelemetry.sdk.resources.Resource; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.Objects; +import java.util.logging.Logger; + +/** + * Utilities for interacting with incubating components ({@code + * io.opentelemetry:opentelemetry-api-incubator} and {@code + * io.opentelemetry:opentelemetry-sdk-extension-incubator}), which are not guaranteed to be present + * on the classpath. For all methods, callers MUST first separately reflectively confirm that the + * incubator is available on the classpath. + */ +final class IncubatingUtil { + + private IncubatingUtil() {} + + static AutoConfiguredOpenTelemetrySdk configureFromFile( + Logger logger, String configurationFile, ComponentLoader componentLoader) { + logger.fine("Autoconfiguring from configuration file: " + configurationFile); + try (FileInputStream fis = new FileInputStream(configurationFile)) { + Class declarativeConfiguration = + Class.forName( + "io.opentelemetry.sdk.extension.incubator.fileconfig.DeclarativeConfiguration"); + Method parse = declarativeConfiguration.getMethod("parse", InputStream.class); + Object model = parse.invoke(null, fis); + Class openTelemetryConfiguration = + Class.forName( + "io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.OpenTelemetryConfigurationModel"); + Method create = + declarativeConfiguration.getMethod( + "create", openTelemetryConfiguration, ComponentLoader.class); + OpenTelemetrySdk sdk = (OpenTelemetrySdk) create.invoke(null, model, componentLoader); + Class sdkConfigProvider = + Class.forName("io.opentelemetry.sdk.extension.incubator.fileconfig.SdkConfigProvider"); + Method createFileConfigProvider = + sdkConfigProvider.getMethod("create", openTelemetryConfiguration); + ConfigProvider configProvider = (ConfigProvider) createFileConfigProvider.invoke(null, model); + // Note: can't access file configuration resource without reflection so setting a dummy + // resource + return AutoConfiguredOpenTelemetrySdk.create( + sdk, Resource.getDefault(), null, configProvider); + } catch (FileNotFoundException e) { + throw new ConfigurationException("Configuration file not found", e); + } catch (ClassNotFoundException | NoSuchMethodException | IllegalAccessException e) { + throw new ConfigurationException( + "Error configuring from file. Is opentelemetry-sdk-extension-incubator on the classpath?", + e); + } catch (InvocationTargetException e) { + Throwable cause = e.getCause(); + if (cause instanceof DeclarativeConfigException) { + throw toConfigurationException((DeclarativeConfigException) cause); + } + throw new ConfigurationException("Unexpected error configuring from file", e); + } catch (IOException e) { + // IOException (other than FileNotFoundException which is caught above) is only thrown + // above by FileInputStream.close() + throw new ConfigurationException("Error closing file", e); + } + } + + private static ConfigurationException toConfigurationException( + DeclarativeConfigException exception) { + String message = Objects.requireNonNull(exception.getMessage()); + return new ConfigurationException(message, exception); + } + + static void setGlobalConfigProvider(Object configProvider) { + GlobalConfigProvider.set((ConfigProvider) configProvider); + } +} diff --git a/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/internal/AutoConfigureUtil.java b/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/internal/AutoConfigureUtil.java index fe18ac8d41b..52f0236e8d2 100644 --- a/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/internal/AutoConfigureUtil.java +++ b/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/internal/AutoConfigureUtil.java @@ -5,10 +5,10 @@ package io.opentelemetry.sdk.autoconfigure.internal; +import io.opentelemetry.api.incubator.config.ConfigProvider; import io.opentelemetry.sdk.autoconfigure.AutoConfiguredOpenTelemetrySdk; import io.opentelemetry.sdk.autoconfigure.AutoConfiguredOpenTelemetrySdkBuilder; import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties; -import io.opentelemetry.sdk.autoconfigure.spi.internal.StructuredConfigProperties; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.function.Function; @@ -25,7 +25,7 @@ private AutoConfigureUtil() {} /** * Returns the {@link ConfigProperties} used for auto-configuration. * - * @return the config properties, or {@code null} if file based configuration is used + * @return the config properties, or {@code null} if declarative configuration is used */ @Nullable public static ConfigProperties getConfig( @@ -41,21 +41,21 @@ public static ConfigProperties getConfig( } /** - * Returns the {@link StructuredConfigProperties} used for auto-configuration when file based + * Returns the {@link ConfigProvider} resulting from auto-configuration when declarative * configuration is used. * - * @return the config properties, or {@code null} if file based configuration is NOT used + * @return the {@link ConfigProvider}, or {@code null} if declarative configuration is NOT used */ @Nullable - public static StructuredConfigProperties getStructuredConfig( + public static ConfigProvider getConfigProvider( AutoConfiguredOpenTelemetrySdk autoConfiguredOpenTelemetrySdk) { try { - Method method = AutoConfiguredOpenTelemetrySdk.class.getDeclaredMethod("getStructuredConfig"); + Method method = AutoConfiguredOpenTelemetrySdk.class.getDeclaredMethod("getConfigProvider"); method.setAccessible(true); - return (StructuredConfigProperties) method.invoke(autoConfiguredOpenTelemetrySdk); + return (ConfigProvider) method.invoke(autoConfiguredOpenTelemetrySdk); } catch (NoSuchMethodException | InvocationTargetException | IllegalAccessException e) { throw new IllegalStateException( - "Error calling getStructuredConfig on AutoConfiguredOpenTelemetrySdk", e); + "Error calling getConfigProvider on AutoConfiguredOpenTelemetrySdk", e); } } diff --git a/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/internal/SpiHelper.java b/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/internal/SpiHelper.java index 6f3196a6f61..db4ca4ff64d 100644 --- a/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/internal/SpiHelper.java +++ b/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/internal/SpiHelper.java @@ -6,11 +6,8 @@ package io.opentelemetry.sdk.autoconfigure.internal; import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties; -import io.opentelemetry.sdk.autoconfigure.spi.ConfigurationException; import io.opentelemetry.sdk.autoconfigure.spi.Ordered; import io.opentelemetry.sdk.autoconfigure.spi.internal.AutoConfigureListener; -import io.opentelemetry.sdk.autoconfigure.spi.internal.ComponentProvider; -import io.opentelemetry.sdk.autoconfigure.spi.internal.StructuredConfigProperties; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; @@ -23,7 +20,6 @@ import java.util.function.BiFunction; import java.util.function.Function; import java.util.function.Supplier; -import java.util.stream.Collectors; /** * This class is internal and is hence not for public use. Its APIs are unstable and can change at @@ -90,53 +86,6 @@ public NamedSpiManager loadConfigurable( return NamedSpiManager.create(nameToProvider); } - /** - * Find a registered {@link ComponentProvider} with {@link ComponentProvider#getType()} matching - * {@code type}, {@link ComponentProvider#getName()} matching {@code name}, and call {@link - * ComponentProvider#create(StructuredConfigProperties)} with the given {@code config}. - * - * @throws ConfigurationException if no matching providers are found, or if multiple are found - * (i.e. conflict), or if {@link ComponentProvider#create(StructuredConfigProperties)} throws - */ - @SuppressWarnings({"unchecked", "rawtypes"}) - public T loadComponent(Class type, String name, StructuredConfigProperties config) { - // TODO(jack-berg): cache loaded component providers - List componentProviders = load(ComponentProvider.class); - List> matchedProviders = - componentProviders.stream() - .map( - (Function>) - componentProvider -> componentProvider) - .filter( - componentProvider -> - componentProvider.getType() == type && name.equals(componentProvider.getName())) - .collect(Collectors.toList()); - if (matchedProviders.isEmpty()) { - throw new ConfigurationException( - "No component provider detected for " + type.getName() + " with name \"" + name + "\"."); - } - if (matchedProviders.size() > 1) { - throw new ConfigurationException( - "Component provider conflict. Multiple providers detected for " - + type.getName() - + " with name \"" - + name - + "\": " - + componentProviders.stream() - .map(provider -> provider.getClass().getName()) - .collect(Collectors.joining(",", "[", "]"))); - } - // Exactly one matching component provider - ComponentProvider provider = (ComponentProvider) matchedProviders.get(0); - - try { - return provider.create(config); - } catch (Throwable throwable) { - throw new ConfigurationException( - "Error configuring " + type.getName() + " with name \"" + name + "\"", throwable); - } - } - /** * Load implementations of an ordered SPI (i.e. implements {@link Ordered}). * diff --git a/sdk-extensions/autoconfigure/src/test/java/io/opentelemetry/sdk/autoconfigure/AutoConfiguredOpenTelemetrySdkTest.java b/sdk-extensions/autoconfigure/src/test/java/io/opentelemetry/sdk/autoconfigure/AutoConfiguredOpenTelemetrySdkTest.java index 9b72fbefb82..c7ae65de9a0 100644 --- a/sdk-extensions/autoconfigure/src/test/java/io/opentelemetry/sdk/autoconfigure/AutoConfiguredOpenTelemetrySdkTest.java +++ b/sdk-extensions/autoconfigure/src/test/java/io/opentelemetry/sdk/autoconfigure/AutoConfiguredOpenTelemetrySdkTest.java @@ -69,7 +69,6 @@ import java.util.function.BiFunction; import java.util.function.Consumer; import java.util.function.Supplier; -import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; @@ -675,26 +674,4 @@ void configurationError_ClosesResources() { logs.assertContains("Error closing io.opentelemetry.sdk.trace.SdkTracerProvider: Error!"); } - - @Test - @SuppressLogger(AutoConfiguredOpenTelemetrySdkBuilder.class) - void configurationError_fileNotFound() { - assertThatThrownBy( - () -> - AutoConfiguredOpenTelemetrySdk.builder() - .addPropertiesSupplier(() -> singletonMap("otel.config.file", "foo")) - .addPropertiesSupplier( - () -> singletonMap("otel.experimental.config.file", "foo")) - .addPropertiesSupplier(() -> singletonMap("otel.sdk.disabled", "true")) - .build()) - .isInstanceOf(ConfigurationException.class) - .hasMessageContaining("Configuration file not found"); - - Assertions.assertDoesNotThrow( - () -> - AutoConfiguredOpenTelemetrySdk.builder() - .addPropertiesSupplier(() -> singletonMap("otel.experimental.config.file", "")) - .addPropertiesSupplier(() -> singletonMap("otel.sdk.disabled", "true")) - .build()); - } } diff --git a/sdk-extensions/autoconfigure/src/test/java/io/opentelemetry/sdk/autoconfigure/FileConfigurationTest.java b/sdk-extensions/autoconfigure/src/test/java/io/opentelemetry/sdk/autoconfigure/DeclarativeConfigurationTest.java similarity index 73% rename from sdk-extensions/autoconfigure/src/test/java/io/opentelemetry/sdk/autoconfigure/FileConfigurationTest.java rename to sdk-extensions/autoconfigure/src/test/java/io/opentelemetry/sdk/autoconfigure/DeclarativeConfigurationTest.java index 955e5817693..8dec1132b5c 100644 --- a/sdk-extensions/autoconfigure/src/test/java/io/opentelemetry/sdk/autoconfigure/FileConfigurationTest.java +++ b/sdk-extensions/autoconfigure/src/test/java/io/opentelemetry/sdk/autoconfigure/DeclarativeConfigurationTest.java @@ -7,7 +7,6 @@ import static org.assertj.core.api.Assertions.assertThatThrownBy; -import io.github.netmikey.logunit.api.LogCapturer; import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties; import io.opentelemetry.sdk.autoconfigure.spi.ConfigurationException; import io.opentelemetry.sdk.autoconfigure.spi.internal.DefaultConfigProperties; @@ -17,16 +16,9 @@ import java.nio.file.Path; import java.util.Collections; import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.RegisterExtension; import org.junit.jupiter.api.io.TempDir; -import org.slf4j.event.Level; -class FileConfigurationTest { - - @RegisterExtension - static final LogCapturer logCapturer = - LogCapturer.create() - .captureForLogger(AutoConfiguredOpenTelemetrySdkBuilder.class.getName(), Level.TRACE); +class DeclarativeConfigurationTest { @Test void configFile(@TempDir Path tempDir) throws IOException { @@ -50,7 +42,6 @@ void configFile(@TempDir Path tempDir) throws IOException { assertThatThrownBy(() -> AutoConfiguredOpenTelemetrySdk.builder().setConfig(config).build()) .isInstanceOf(ConfigurationException.class) .hasMessage( - "Error configuring from file. Is opentelemetry-sdk-extension-incubator on the classpath?"); - logCapturer.assertContains("Autoconfiguring from configuration file: " + path); + "Cannot autoconfigure from config file without opentelemetry-sdk-extension-incubator on the classpath"); } } diff --git a/sdk-extensions/autoconfigure/src/testFullConfig/java/io/opentelemetry/sdk/autoconfigure/FullConfigTest.java b/sdk-extensions/autoconfigure/src/testFullConfig/java/io/opentelemetry/sdk/autoconfigure/FullConfigTest.java index edad134ae5e..0a0a905ae8d 100644 --- a/sdk-extensions/autoconfigure/src/testFullConfig/java/io/opentelemetry/sdk/autoconfigure/FullConfigTest.java +++ b/sdk-extensions/autoconfigure/src/testFullConfig/java/io/opentelemetry/sdk/autoconfigure/FullConfigTest.java @@ -18,8 +18,6 @@ import io.opentelemetry.api.GlobalOpenTelemetry; import io.opentelemetry.api.baggage.propagation.W3CBaggagePropagator; import io.opentelemetry.api.common.Attributes; -import io.opentelemetry.api.common.Value; -import io.opentelemetry.api.incubator.logs.ExtendedLogger; import io.opentelemetry.api.logs.Logger; import io.opentelemetry.api.logs.Severity; import io.opentelemetry.api.metrics.Meter; @@ -38,7 +36,6 @@ import io.opentelemetry.proto.collector.trace.v1.TraceServiceGrpc; import io.opentelemetry.proto.common.v1.AnyValue; import io.opentelemetry.proto.common.v1.KeyValue; -import io.opentelemetry.proto.logs.v1.SeverityNumber; import io.opentelemetry.proto.metrics.v1.Metric; import io.opentelemetry.sdk.OpenTelemetrySdk; import java.util.ArrayList; @@ -204,13 +201,6 @@ void configures() throws Exception { logger.logRecordBuilder().setBody("debug log message").setSeverity(Severity.DEBUG).emit(); logger.logRecordBuilder().setBody("info log message").setSeverity(Severity.INFO).emit(); - ((ExtendedLogger) logger) - .logRecordBuilder() - .setEventName("namespace.test-name") - .setSeverity(Severity.INFO) - .setBody(Value.of(io.opentelemetry.api.common.KeyValue.of("cow", Value.of("moo")))) - .emit(); - openTelemetrySdk.getSdkTracerProvider().forceFlush().join(10, TimeUnit.SECONDS); openTelemetrySdk.getSdkLoggerProvider().forceFlush().join(10, TimeUnit.SECONDS); openTelemetrySdk.getSdkMeterProvider().forceFlush().join(10, TimeUnit.SECONDS); @@ -297,17 +287,6 @@ void configures() throws Exception { assertThat(logRecord.getBody().getStringValue()).isEqualTo("info log message"); assertThat(logRecord.getSeverityNumberValue()) .isEqualTo(Severity.INFO.getSeverityNumber()); - }, - logRecord -> { - assertThat(logRecord.getBody().getKvlistValue().getValuesList()) - .containsExactlyInAnyOrder( - KeyValue.newBuilder() - .setKey("cow") - .setValue(AnyValue.newBuilder().setStringValue("moo").build()) - .build()); - assertThat(logRecord.getSeverityNumber()) - .isEqualTo(SeverityNumber.SEVERITY_NUMBER_INFO); - assertThat(logRecord.getEventName()).isEqualTo("namespace.test-name"); }); } diff --git a/sdk-extensions/autoconfigure/src/testFullConfig/java/io/opentelemetry/sdk/autoconfigure/FileConfigurationTest.java b/sdk-extensions/autoconfigure/src/testIncubating/java/io/opentelemetry/sdk/autoconfigure/DeclarativeConfigurationTest.java similarity index 66% rename from sdk-extensions/autoconfigure/src/testFullConfig/java/io/opentelemetry/sdk/autoconfigure/FileConfigurationTest.java rename to sdk-extensions/autoconfigure/src/testIncubating/java/io/opentelemetry/sdk/autoconfigure/DeclarativeConfigurationTest.java index ef0b05b2da3..22fe2c6ef9f 100644 --- a/sdk-extensions/autoconfigure/src/testFullConfig/java/io/opentelemetry/sdk/autoconfigure/FileConfigurationTest.java +++ b/sdk-extensions/autoconfigure/src/testIncubating/java/io/opentelemetry/sdk/autoconfigure/DeclarativeConfigurationTest.java @@ -6,6 +6,8 @@ package io.opentelemetry.sdk.autoconfigure; import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.assertThat; +import static java.util.Collections.singletonMap; +import static org.assertj.core.api.Assertions.assertThatCode; import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.doReturn; @@ -17,13 +19,18 @@ import io.github.netmikey.logunit.api.LogCapturer; import io.opentelemetry.api.GlobalOpenTelemetry; import io.opentelemetry.api.OpenTelemetry; +import io.opentelemetry.api.incubator.config.ConfigProvider; +import io.opentelemetry.api.incubator.config.DeclarativeConfigProperties; +import io.opentelemetry.api.incubator.config.GlobalConfigProvider; +import io.opentelemetry.api.incubator.config.InstrumentationConfigUtil; import io.opentelemetry.exporter.logging.LoggingSpanExporter; import io.opentelemetry.internal.testing.CleanupExtension; +import io.opentelemetry.internal.testing.slf4j.SuppressLogger; import io.opentelemetry.sdk.OpenTelemetrySdk; +import io.opentelemetry.sdk.autoconfigure.internal.AutoConfigureUtil; import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties; import io.opentelemetry.sdk.autoconfigure.spi.ConfigurationException; import io.opentelemetry.sdk.autoconfigure.spi.internal.DefaultConfigProperties; -import io.opentelemetry.sdk.autoconfigure.spi.internal.StructuredConfigProperties; import io.opentelemetry.sdk.resources.Resource; import io.opentelemetry.sdk.trace.SdkTracerProvider; import io.opentelemetry.sdk.trace.export.SimpleSpanProcessor; @@ -31,14 +38,16 @@ import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.Path; +import java.util.Arrays; import java.util.Collections; +import org.assertj.core.api.Assertions; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.RegisterExtension; import org.junit.jupiter.api.io.TempDir; import org.slf4j.event.Level; -class FileConfigurationTest { +class DeclarativeConfigurationTest { @RegisterExtension private static final CleanupExtension cleanup = new CleanupExtension(); @@ -63,13 +72,43 @@ void setup() throws IOException { + " - simple:\n" + " exporter:\n" + " console: {}\n" - + "other:\n" - + " str_key: str_value\n" - + " map_key:\n" - + " str_key1: str_value1\n"; + + "instrumentation:\n" + + " general:\n" + + " http:\n" + + " client:\n" + + " request_captured_headers:\n" + + " - Content-Type\n" + + " - Accept\n" + + " java:\n" + + " example:\n" + + " key: value\n"; configFilePath = tempDir.resolve("otel-config.yaml"); Files.write(configFilePath, yaml.getBytes(StandardCharsets.UTF_8)); GlobalOpenTelemetry.resetForTest(); + GlobalConfigProvider.resetForTest(); + } + + @Test + @SuppressLogger(AutoConfiguredOpenTelemetrySdkBuilder.class) + void configFile_fileNotFound() { + assertThatThrownBy( + () -> + AutoConfiguredOpenTelemetrySdk.builder() + .addPropertiesSupplier(() -> singletonMap("otel.config.file", "foo")) + .addPropertiesSupplier( + () -> singletonMap("otel.experimental.config.file", "foo")) + .addPropertiesSupplier(() -> singletonMap("otel.sdk.disabled", "true")) + .build()) + .isInstanceOf(ConfigurationException.class) + .hasMessageContaining("Configuration file not found"); + + assertThatCode( + () -> + AutoConfiguredOpenTelemetrySdk.builder() + .addPropertiesSupplier(() -> singletonMap("otel.experimental.config.file", "")) + .addPropertiesSupplier(() -> singletonMap("otel.sdk.disabled", "true")) + .build()) + .doesNotThrowAnyException(); } @Test @@ -95,13 +134,14 @@ void configFile_Valid() { builder.setConfig(config).build(); cleanup.addCloseable(autoConfiguredOpenTelemetrySdk.getOpenTelemetrySdk()); - assertThat(autoConfiguredOpenTelemetrySdk.getOpenTelemetrySdk().toString()) + Assertions.assertThat(autoConfiguredOpenTelemetrySdk.getOpenTelemetrySdk().toString()) .isEqualTo(expectedSdk.toString()); // AutoConfiguredOpenTelemetrySdk#getResource() is set to a dummy value when configuring from // file - assertThat(autoConfiguredOpenTelemetrySdk.getResource()).isEqualTo(Resource.getDefault()); + Assertions.assertThat(autoConfiguredOpenTelemetrySdk.getResource()) + .isEqualTo(Resource.getDefault()); verify(builder, times(1)).shutdownHook(autoConfiguredOpenTelemetrySdk.getOpenTelemetrySdk()); - assertThat(Runtime.getRuntime().removeShutdownHook(thread)).isTrue(); + Assertions.assertThat(Runtime.getRuntime().removeShutdownHook(thread)).isTrue(); logCapturer.assertContains("Autoconfiguring from configuration file: " + configFilePath); } @@ -131,7 +171,11 @@ void configFile_setResultAsGlobalFalse() { OpenTelemetrySdk openTelemetrySdk = autoConfiguredOpenTelemetrySdk.getOpenTelemetrySdk(); cleanup.addCloseable(openTelemetrySdk); - assertThat(GlobalOpenTelemetry.get()).extracting("delegate").isNotSameAs(openTelemetrySdk); + Assertions.assertThat(GlobalOpenTelemetry.get()) + .extracting("delegate") + .isNotSameAs(openTelemetrySdk); + assertThat(GlobalConfigProvider.get()) + .isNotSameAs(autoConfiguredOpenTelemetrySdk.getConfigProvider()); } @Test @@ -145,7 +189,11 @@ void configFile_setResultAsGlobalTrue() { OpenTelemetrySdk openTelemetrySdk = autoConfiguredOpenTelemetrySdk.getOpenTelemetrySdk(); cleanup.addCloseable(openTelemetrySdk); - assertThat(GlobalOpenTelemetry.get()).extracting("delegate").isSameAs(openTelemetrySdk); + Assertions.assertThat(GlobalOpenTelemetry.get()) + .extracting("delegate") + .isSameAs(openTelemetrySdk); + assertThat(GlobalConfigProvider.get()) + .isSameAs(autoConfiguredOpenTelemetrySdk.getConfigProvider()); } @Test @@ -174,7 +222,7 @@ void configFile_Error(@TempDir Path tempDir) throws IOException { } @Test - void configFile_StructuredConfigProperties() { + void configFile_ConfigProvider() { ConfigProperties config = DefaultConfigProperties.createFromMap( Collections.singletonMap("otel.experimental.config.file", configFilePath.toString())); @@ -185,14 +233,19 @@ void configFile_StructuredConfigProperties() { cleanup.addCloseable(openTelemetrySdk); // getConfig() should return ExtendedConfigProperties generic representation of the config file - StructuredConfigProperties structuredConfigProps = - autoConfiguredOpenTelemetrySdk.getStructuredConfig(); - assertThat(structuredConfigProps).isNotNull(); - StructuredConfigProperties otherProps = structuredConfigProps.getStructured("other"); - assertThat(otherProps).isNotNull(); - assertThat(otherProps.getString("str_key")).isEqualTo("str_value"); - StructuredConfigProperties otherMapKeyProps = otherProps.getStructured("map_key"); - assertThat(otherMapKeyProps).isNotNull(); - assertThat(otherMapKeyProps.getString("str_key1")).isEqualTo("str_value1"); + ConfigProvider globalConfigProvider = GlobalConfigProvider.get(); + assertThat(globalConfigProvider) + .isNotNull() + .isSameAs(AutoConfigureUtil.getConfigProvider(autoConfiguredOpenTelemetrySdk)); + DeclarativeConfigProperties instrumentationConfig = + globalConfigProvider.getInstrumentationConfig(); + assertThat(instrumentationConfig).isNotNull(); + + // Extract instrumentation config from ConfigProvider + assertThat(InstrumentationConfigUtil.httpClientRequestCapturedHeaders(globalConfigProvider)) + .isEqualTo(Arrays.asList("Content-Type", "Accept")); + assertThat(InstrumentationConfigUtil.javaInstrumentationConfig(globalConfigProvider, "example")) + .isNotNull() + .satisfies(exampleConfig -> assertThat(exampleConfig.getString("key")).isEqualTo("value")); } } diff --git a/sdk-extensions/incubator/build.gradle.kts b/sdk-extensions/incubator/build.gradle.kts index 92be979672f..20e91bd2e5c 100644 --- a/sdk-extensions/incubator/build.gradle.kts +++ b/sdk-extensions/incubator/build.gradle.kts @@ -25,6 +25,7 @@ dependencies { implementation("org.snakeyaml:snakeyaml-engine") // io.opentelemetry.sdk.extension.incubator.fileconfig + api(project(":api:incubator")) implementation("com.fasterxml.jackson.core:jackson-databind") api("com.fasterxml.jackson.core:jackson-annotations") implementation("com.fasterxml.jackson.dataformat:jackson-dataformat-yaml") @@ -39,7 +40,8 @@ dependencies { testImplementation(project(":sdk-extensions:jaeger-remote-sampler")) testImplementation(project(":extensions:trace-propagators")) // As a part of the tests we check that we can parse examples without error. The https://github.com/open-telemetry/opentelemetry-configuration/blob/main/examples/kitchen-sink.yam contains a reference to the xray propagator - testImplementation("io.opentelemetry.contrib:opentelemetry-aws-xray-propagator") + // TODO: add when updated to reflect new API locations + // testImplementation("io.opentelemetry.contrib:opentelemetry-aws-xray-propagator") testImplementation("com.linecorp.armeria:armeria-junit5") testImplementation("com.google.guava:guava-testlib") diff --git a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/AggregationFactory.java b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/AggregationFactory.java index 5626d27c212..b856d0da4a5 100644 --- a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/AggregationFactory.java +++ b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/AggregationFactory.java @@ -5,8 +5,8 @@ package io.opentelemetry.sdk.extension.incubator.fileconfig; +import io.opentelemetry.api.incubator.config.DeclarativeConfigException; import io.opentelemetry.sdk.autoconfigure.internal.SpiHelper; -import io.opentelemetry.sdk.autoconfigure.spi.ConfigurationException; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.AggregationModel; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.Base2ExponentialBucketHistogramModel; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.ExplicitBucketHistogramModel; @@ -50,7 +50,7 @@ public Aggregation create( try { return Aggregation.base2ExponentialBucketHistogram(maxSize, maxScale); } catch (IllegalArgumentException e) { - throw new ConfigurationException("Invalid exponential bucket histogram", e); + throw new DeclarativeConfigException("Invalid exponential bucket histogram", e); } } ExplicitBucketHistogramModel explicitBucketHistogram = model.getExplicitBucketHistogram(); @@ -62,7 +62,7 @@ public Aggregation create( try { return Aggregation.explicitBucketHistogram(boundaries); } catch (IllegalArgumentException e) { - throw new ConfigurationException("Invalid explicit bucket histogram", e); + throw new DeclarativeConfigException("Invalid explicit bucket histogram", e); } } diff --git a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/AttributeListFactory.java b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/AttributeListFactory.java index 23d08e7fae7..c79f1503e35 100644 --- a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/AttributeListFactory.java +++ b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/AttributeListFactory.java @@ -10,8 +10,8 @@ import io.opentelemetry.api.common.AttributeKey; import io.opentelemetry.api.common.Attributes; import io.opentelemetry.api.common.AttributesBuilder; +import io.opentelemetry.api.incubator.config.DeclarativeConfigException; import io.opentelemetry.sdk.autoconfigure.internal.SpiHelper; -import io.opentelemetry.sdk.autoconfigure.spi.ConfigurationException; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.AttributeNameValueModel; import java.io.Closeable; import java.util.List; @@ -115,7 +115,7 @@ private static void addToBuilder( } break; } - throw new ConfigurationException( + throw new DeclarativeConfigException( "Error processing attribute with name \"" + name + "\": value did not match type " diff --git a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/FileConfiguration.java b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/DeclarativeConfiguration.java similarity index 78% rename from sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/FileConfiguration.java rename to sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/DeclarativeConfiguration.java index 7e5e98344d6..673ced041fe 100644 --- a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/FileConfiguration.java +++ b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/DeclarativeConfiguration.java @@ -9,12 +9,12 @@ import com.fasterxml.jackson.annotation.Nulls; import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.databind.ObjectMapper; +import io.opentelemetry.api.incubator.config.DeclarativeConfigException; +import io.opentelemetry.api.incubator.config.DeclarativeConfigProperties; import io.opentelemetry.sdk.OpenTelemetrySdk; import io.opentelemetry.sdk.autoconfigure.internal.ComponentLoader; import io.opentelemetry.sdk.autoconfigure.internal.SpiHelper; -import io.opentelemetry.sdk.autoconfigure.spi.ConfigurationException; import io.opentelemetry.sdk.autoconfigure.spi.internal.ComponentProvider; -import io.opentelemetry.sdk.autoconfigure.spi.internal.StructuredConfigProperties; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.OpenTelemetryConfigurationModel; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.SamplerModel; import io.opentelemetry.sdk.trace.samplers.Sampler; @@ -42,18 +42,20 @@ import org.snakeyaml.engine.v2.schema.CoreSchema; /** - * Configure {@link OpenTelemetrySdk} from YAML configuration files conforming to the schema in open-telemetry/opentelemetry-configuration. - * - * @see #parseAndCreate(InputStream) + * Configure {@link OpenTelemetrySdk} using declarative + * configuration. For most users, this means calling {@link #parseAndCreate(InputStream)} with a + * YAML + * configuration file. */ -public final class FileConfiguration { +public final class DeclarativeConfiguration { - private static final Logger logger = Logger.getLogger(FileConfiguration.class.getName()); + private static final Logger logger = Logger.getLogger(DeclarativeConfiguration.class.getName()); private static final Pattern ENV_VARIABLE_REFERENCE = Pattern.compile("\\$\\{([a-zA-Z_][a-zA-Z0-9_]*)(:-([^\n}]*))?}"); private static final ComponentLoader DEFAULT_COMPONENT_LOADER = - SpiHelper.serviceComponentLoader(FileConfiguration.class.getClassLoader()); + SpiHelper.serviceComponentLoader(DeclarativeConfiguration.class.getClassLoader()); private static final ObjectMapper MAPPER; @@ -70,12 +72,12 @@ public final class FileConfiguration { MAPPER.configOverride(Boolean.class).setSetterInfo(JsonSetter.Value.forValueNulls(Nulls.SET)); } - private FileConfiguration() {} + private DeclarativeConfiguration() {} /** * Combines {@link #parse(InputStream)} and {@link #create(OpenTelemetryConfigurationModel)}. * - * @throws ConfigurationException if unable to parse or interpret + * @throws DeclarativeConfigException if unable to parse or interpret */ public static OpenTelemetrySdk parseAndCreate(InputStream inputStream) { OpenTelemetryConfigurationModel configurationModel = parse(inputStream); @@ -88,7 +90,7 @@ public static OpenTelemetrySdk parseAndCreate(InputStream inputStream) { * * @param configurationModel the configuration model * @return the {@link OpenTelemetrySdk} - * @throws ConfigurationException if unable to interpret + * @throws DeclarativeConfigException if unable to interpret */ public static OpenTelemetrySdk create(OpenTelemetryConfigurationModel configurationModel) { return create(configurationModel, DEFAULT_COMPONENT_LOADER); @@ -102,7 +104,7 @@ public static OpenTelemetrySdk create(OpenTelemetryConfigurationModel configurat * @param componentLoader the component loader used to load {@link ComponentProvider} * implementations * @return the {@link OpenTelemetrySdk} - * @throws ConfigurationException if unable to interpret + * @throws DeclarativeConfigException if unable to interpret */ public static OpenTelemetrySdk create( OpenTelemetryConfigurationModel configurationModel, ComponentLoader componentLoader) { @@ -118,13 +120,13 @@ public static OpenTelemetrySdk create( *

      Before parsing, environment variable substitution is performed as described in {@link * EnvSubstitutionConstructor}. * - * @throws ConfigurationException if unable to parse + * @throws DeclarativeConfigException if unable to parse */ public static OpenTelemetryConfigurationModel parse(InputStream configuration) { try { return parse(configuration, System.getenv()); } catch (RuntimeException e) { - throw new ConfigurationException("Unable to parse configuration input stream", e); + throw new DeclarativeConfigException("Unable to parse configuration input stream", e); } } @@ -143,35 +145,35 @@ static Object loadYaml(InputStream inputStream, Map environmentV } /** - * Convert the {@code model} to a generic {@link StructuredConfigProperties}. + * Convert the {@code model} to a generic {@link DeclarativeConfigProperties}. * * @param model the configuration model - * @return a generic {@link StructuredConfigProperties} representation of the model + * @return a generic {@link DeclarativeConfigProperties} representation of the model */ - public static StructuredConfigProperties toConfigProperties( + public static DeclarativeConfigProperties toConfigProperties( OpenTelemetryConfigurationModel model) { return toConfigProperties(model, DEFAULT_COMPONENT_LOADER); } /** - * Convert the {@code configuration} YAML to a generic {@link StructuredConfigProperties}. + * Convert the {@code configuration} YAML to a generic {@link DeclarativeConfigProperties}. * * @param configuration configuration YAML - * @return a generic {@link StructuredConfigProperties} representation of the model + * @return a generic {@link DeclarativeConfigProperties} representation of the model */ - public static StructuredConfigProperties toConfigProperties(InputStream configuration) { + public static DeclarativeConfigProperties toConfigProperties(InputStream configuration) { Object yamlObj = loadYaml(configuration, System.getenv()); return toConfigProperties(yamlObj, DEFAULT_COMPONENT_LOADER); } - static StructuredConfigProperties toConfigProperties( + static DeclarativeConfigProperties toConfigProperties( Object model, ComponentLoader componentLoader) { Map configurationMap = MAPPER.convertValue(model, new TypeReference>() {}); if (configurationMap == null) { configurationMap = Collections.emptyMap(); } - return YamlStructuredConfigProperties.create(configurationMap, componentLoader); + return YamlDeclarativeConfigProperties.create(configurationMap, componentLoader); } /** @@ -179,33 +181,33 @@ static StructuredConfigProperties toConfigProperties( * *

      This is used when samplers are composed, with one sampler accepting one or more additional * samplers as config properties. The {@link ComponentProvider} implementation can call this to - * configure a delegate {@link SamplerModel} from the {@link StructuredConfigProperties} + * configure a delegate {@link SamplerModel} from the {@link DeclarativeConfigProperties} * corresponding to a particular config property. */ // TODO(jack-berg): add create methods for all SDK extension components supported by // ComponentProvider - public static Sampler createSampler(StructuredConfigProperties genericSamplerModel) { - YamlStructuredConfigProperties yamlStructuredConfigProperties = - requireYamlStructuredConfigProperties(genericSamplerModel); - SamplerModel samplerModel = convertToModel(yamlStructuredConfigProperties, SamplerModel.class); + public static Sampler createSampler(DeclarativeConfigProperties genericSamplerModel) { + YamlDeclarativeConfigProperties yamlDeclarativeConfigProperties = + requireYamlDeclarativeConfigProperties(genericSamplerModel); + SamplerModel samplerModel = convertToModel(yamlDeclarativeConfigProperties, SamplerModel.class); return createAndMaybeCleanup( SamplerFactory.getInstance(), - SpiHelper.create(yamlStructuredConfigProperties.getComponentLoader()), + SpiHelper.create(yamlDeclarativeConfigProperties.getComponentLoader()), samplerModel); } - private static YamlStructuredConfigProperties requireYamlStructuredConfigProperties( - StructuredConfigProperties structuredConfigProperties) { - if (!(structuredConfigProperties instanceof YamlStructuredConfigProperties)) { - throw new ConfigurationException( - "Only YamlStructuredConfigProperties can be converted to model"); + private static YamlDeclarativeConfigProperties requireYamlDeclarativeConfigProperties( + DeclarativeConfigProperties declarativeConfigProperties) { + if (!(declarativeConfigProperties instanceof YamlDeclarativeConfigProperties)) { + throw new DeclarativeConfigException( + "Only YamlDeclarativeConfigProperties can be converted to model"); } - return (YamlStructuredConfigProperties) structuredConfigProperties; + return (YamlDeclarativeConfigProperties) declarativeConfigProperties; } static T convertToModel( - YamlStructuredConfigProperties structuredConfigProperties, Class modelType) { - return MAPPER.convertValue(structuredConfigProperties.toMap(), modelType); + YamlDeclarativeConfigProperties yamlDeclarativeConfigProperties, Class modelType) { + return MAPPER.convertValue(yamlDeclarativeConfigProperties.toMap(), modelType); } static R createAndMaybeCleanup(Factory factory, SpiHelper spiHelper, M model) { @@ -223,10 +225,10 @@ static R createAndMaybeCleanup(Factory factory, SpiHelper spiHelper "Error closing " + closeable.getClass().getName() + ": " + ex.getMessage()); } } - if (e instanceof ConfigurationException) { + if (e instanceof DeclarativeConfigException) { throw e; } - throw new ConfigurationException("Unexpected configuration error", e); + throw new DeclarativeConfigException("Unexpected configuration error", e); } } diff --git a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/FileConfigUtil.java b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/FileConfigUtil.java index f4c1346dc72..a84143ede67 100644 --- a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/FileConfigUtil.java +++ b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/FileConfigUtil.java @@ -5,12 +5,14 @@ package io.opentelemetry.sdk.extension.incubator.fileconfig; +import io.opentelemetry.api.incubator.config.DeclarativeConfigException; +import io.opentelemetry.api.incubator.config.DeclarativeConfigProperties; import io.opentelemetry.sdk.autoconfigure.internal.SpiHelper; -import io.opentelemetry.sdk.autoconfigure.spi.ConfigurationException; import io.opentelemetry.sdk.autoconfigure.spi.internal.ComponentProvider; -import io.opentelemetry.sdk.autoconfigure.spi.internal.StructuredConfigProperties; import java.io.Closeable; import java.util.List; +import java.util.function.Function; +import java.util.stream.Collectors; import javax.annotation.Nullable; final class FileConfigUtil { @@ -34,7 +36,7 @@ static T assertNotNull(@Nullable T object, String description) { static T requireNonNull(@Nullable T object, String description) { if (object == null) { - throw new ConfigurationException(description + " is required but is null"); + throw new DeclarativeConfigException(description + " is required but is null"); } return object; } @@ -42,15 +44,63 @@ static T requireNonNull(@Nullable T object, String description) { /** * Find a registered {@link ComponentProvider} which {@link ComponentProvider#getType()} matching * {@code type}, {@link ComponentProvider#getName()} matching {@code name}, and call {@link - * ComponentProvider#create(StructuredConfigProperties)} with the given {@code model}. + * ComponentProvider#create(DeclarativeConfigProperties)} with the given {@code model}. * - * @throws ConfigurationException if no matching providers are found, or if multiple are found - * (i.e. conflict), or if {@link ComponentProvider#create(StructuredConfigProperties)} throws + * @throws DeclarativeConfigException if no matching providers are found, or if multiple are found + * (i.e. conflict), or if {@link ComponentProvider#create(DeclarativeConfigProperties)} throws */ static T loadComponent(SpiHelper spiHelper, Class type, String name, Object model) { // Map model to generic structured config properties - StructuredConfigProperties config = - FileConfiguration.toConfigProperties(model, spiHelper.getComponentLoader()); - return spiHelper.loadComponent(type, name, config); + DeclarativeConfigProperties config = + DeclarativeConfiguration.toConfigProperties(model, spiHelper.getComponentLoader()); + return loadComponentHelper(spiHelper, type, name, config); + } + + /** + * Find a registered {@link ComponentProvider} with {@link ComponentProvider#getType()} matching + * {@code type}, {@link ComponentProvider#getName()} matching {@code name}, and call {@link + * ComponentProvider#create(DeclarativeConfigProperties)} with the given {@code config}. + * + * @throws DeclarativeConfigException if no matching providers are found, or if multiple are found + * (i.e. conflict), or if {@link ComponentProvider#create(DeclarativeConfigProperties)} throws + */ + @SuppressWarnings({"unchecked", "rawtypes"}) + private static T loadComponentHelper( + SpiHelper spiHelper, Class type, String name, DeclarativeConfigProperties config) { + // TODO(jack-berg): cache loaded component providers + List componentProviders = spiHelper.load(ComponentProvider.class); + List> matchedProviders = + componentProviders.stream() + .map( + (Function>) + componentProvider -> componentProvider) + .filter( + componentProvider -> + componentProvider.getType() == type && name.equals(componentProvider.getName())) + .collect(Collectors.toList()); + if (matchedProviders.isEmpty()) { + throw new DeclarativeConfigException( + "No component provider detected for " + type.getName() + " with name \"" + name + "\"."); + } + if (matchedProviders.size() > 1) { + throw new DeclarativeConfigException( + "Component provider conflict. Multiple providers detected for " + + type.getName() + + " with name \"" + + name + + "\": " + + componentProviders.stream() + .map(provider -> provider.getClass().getName()) + .collect(Collectors.joining(",", "[", "]"))); + } + // Exactly one matching component provider + ComponentProvider provider = (ComponentProvider) matchedProviders.get(0); + + try { + return provider.create(config); + } catch (Throwable throwable) { + throw new DeclarativeConfigException( + "Error configuring " + type.getName() + " with name \"" + name + "\"", throwable); + } } } diff --git a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/InstrumentSelectorFactory.java b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/InstrumentSelectorFactory.java index 767908c6595..d45d1ac3218 100644 --- a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/InstrumentSelectorFactory.java +++ b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/InstrumentSelectorFactory.java @@ -5,8 +5,8 @@ package io.opentelemetry.sdk.extension.incubator.fileconfig; +import io.opentelemetry.api.incubator.config.DeclarativeConfigException; import io.opentelemetry.sdk.autoconfigure.internal.SpiHelper; -import io.opentelemetry.sdk.autoconfigure.spi.ConfigurationException; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.SelectorModel; import io.opentelemetry.sdk.metrics.InstrumentSelector; import io.opentelemetry.sdk.metrics.InstrumentSelectorBuilder; @@ -36,7 +36,7 @@ public InstrumentSelector create( try { instrumentType = InstrumentType.valueOf(model.getInstrumentType().name()); } catch (IllegalArgumentException e) { - throw new ConfigurationException( + throw new DeclarativeConfigException( "Unrecognized instrument type: " + model.getInstrumentType(), e); } builder.setType(instrumentType); @@ -54,7 +54,7 @@ public InstrumentSelector create( try { return builder.build(); } catch (IllegalArgumentException e) { - throw new ConfigurationException("Invalid selector", e); + throw new DeclarativeConfigException("Invalid selector", e); } } } diff --git a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/LogRecordExporterFactory.java b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/LogRecordExporterFactory.java index e006befe0f7..1af81a7e7f6 100644 --- a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/LogRecordExporterFactory.java +++ b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/LogRecordExporterFactory.java @@ -7,8 +7,8 @@ import static java.util.stream.Collectors.joining; +import io.opentelemetry.api.incubator.config.DeclarativeConfigException; import io.opentelemetry.sdk.autoconfigure.internal.SpiHelper; -import io.opentelemetry.sdk.autoconfigure.spi.ConfigurationException; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.ConsoleModel; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.LogRecordExporterModel; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.OtlpModel; @@ -43,7 +43,7 @@ public LogRecordExporter create( if (!model.getAdditionalProperties().isEmpty()) { Map additionalProperties = model.getAdditionalProperties(); if (additionalProperties.size() > 1) { - throw new ConfigurationException( + throw new DeclarativeConfigException( "Invalid configuration - multiple log record exporters set: " + additionalProperties.keySet().stream().collect(joining(",", "[", "]"))); } @@ -61,7 +61,7 @@ public LogRecordExporter create( exporterKeyValue.getValue()); return FileConfigUtil.addAndReturn(closeables, logRecordExporter); } else { - throw new ConfigurationException("log exporter must be set"); + throw new DeclarativeConfigException("log exporter must be set"); } } } diff --git a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/LogRecordProcessorFactory.java b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/LogRecordProcessorFactory.java index 3861617ad84..2bee5d9a8de 100644 --- a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/LogRecordProcessorFactory.java +++ b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/LogRecordProcessorFactory.java @@ -7,8 +7,8 @@ import static java.util.stream.Collectors.joining; +import io.opentelemetry.api.incubator.config.DeclarativeConfigException; import io.opentelemetry.sdk.autoconfigure.internal.SpiHelper; -import io.opentelemetry.sdk.autoconfigure.spi.ConfigurationException; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.BatchLogRecordProcessorModel; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.LogRecordExporterModel; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.LogRecordProcessorModel; @@ -75,7 +75,7 @@ public LogRecordProcessor create( if (!model.getAdditionalProperties().isEmpty()) { Map additionalProperties = model.getAdditionalProperties(); if (additionalProperties.size() > 1) { - throw new ConfigurationException( + throw new DeclarativeConfigException( "Invalid configuration - multiple log record processors set: " + additionalProperties.keySet().stream().collect(joining(",", "[", "]"))); } @@ -93,7 +93,7 @@ public LogRecordProcessor create( processorKeyValue.getValue()); return FileConfigUtil.addAndReturn(closeables, logRecordProcessor); } else { - throw new ConfigurationException("log processor must be set"); + throw new DeclarativeConfigException("log processor must be set"); } } } diff --git a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/MetricExporterFactory.java b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/MetricExporterFactory.java index 6d9616f8524..0b5e12aab8e 100644 --- a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/MetricExporterFactory.java +++ b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/MetricExporterFactory.java @@ -7,8 +7,8 @@ import static java.util.stream.Collectors.joining; +import io.opentelemetry.api.incubator.config.DeclarativeConfigException; import io.opentelemetry.sdk.autoconfigure.internal.SpiHelper; -import io.opentelemetry.sdk.autoconfigure.spi.ConfigurationException; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.OtlpMetricModel; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.PushMetricExporterModel; import io.opentelemetry.sdk.metrics.export.MetricExporter; @@ -41,7 +41,7 @@ public MetricExporter create( if (!model.getAdditionalProperties().isEmpty()) { Map additionalProperties = model.getAdditionalProperties(); if (additionalProperties.size() > 1) { - throw new ConfigurationException( + throw new DeclarativeConfigException( "Invalid configuration - multiple metric exporters set: " + additionalProperties.keySet().stream().collect(joining(",", "[", "]"))); } @@ -59,7 +59,7 @@ public MetricExporter create( exporterKeyValue.getValue()); return FileConfigUtil.addAndReturn(closeables, metricExporter); } else { - throw new ConfigurationException("metric exporter must be set"); + throw new DeclarativeConfigException("metric exporter must be set"); } } } diff --git a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/MetricReaderFactory.java b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/MetricReaderFactory.java index fe7bd8bbf1a..db6227c617c 100644 --- a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/MetricReaderFactory.java +++ b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/MetricReaderFactory.java @@ -7,8 +7,8 @@ import static io.opentelemetry.sdk.extension.incubator.fileconfig.FileConfigUtil.requireNonNull; +import io.opentelemetry.api.incubator.config.DeclarativeConfigException; import io.opentelemetry.sdk.autoconfigure.internal.SpiHelper; -import io.opentelemetry.sdk.autoconfigure.spi.ConfigurationException; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.MetricReaderModel; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.PeriodicMetricReaderModel; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.PrometheusModel; @@ -62,9 +62,10 @@ public MetricReader create( return FileConfigUtil.addAndReturn(closeables, metricReader); } - throw new ConfigurationException("prometheus is the only currently supported pull reader"); + throw new DeclarativeConfigException( + "prometheus is the only currently supported pull reader"); } - throw new ConfigurationException("reader must be set"); + throw new DeclarativeConfigException("reader must be set"); } } diff --git a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/OpenTelemetryConfigurationFactory.java b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/OpenTelemetryConfigurationFactory.java index 5df6a4766a3..8f19de2b721 100644 --- a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/OpenTelemetryConfigurationFactory.java +++ b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/OpenTelemetryConfigurationFactory.java @@ -5,10 +5,10 @@ package io.opentelemetry.sdk.extension.incubator.fileconfig; +import io.opentelemetry.api.incubator.config.DeclarativeConfigException; import io.opentelemetry.sdk.OpenTelemetrySdk; import io.opentelemetry.sdk.OpenTelemetrySdkBuilder; import io.opentelemetry.sdk.autoconfigure.internal.SpiHelper; -import io.opentelemetry.sdk.autoconfigure.spi.ConfigurationException; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.OpenTelemetryConfigurationModel; import io.opentelemetry.sdk.resources.Resource; import java.io.Closeable; @@ -32,7 +32,8 @@ public OpenTelemetrySdk create( OpenTelemetryConfigurationModel model, SpiHelper spiHelper, List closeables) { OpenTelemetrySdkBuilder builder = OpenTelemetrySdk.builder(); if (!"0.3".equals(model.getFileFormat())) { - throw new ConfigurationException("Unsupported file format. Supported formats include: 0.3"); + throw new DeclarativeConfigException( + "Unsupported file format. Supported formats include: 0.3"); } if (Objects.equals(Boolean.TRUE, model.getDisabled())) { diff --git a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/ResourceFactory.java b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/ResourceFactory.java index 6e40822a6b4..0b240007d3f 100644 --- a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/ResourceFactory.java +++ b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/ResourceFactory.java @@ -7,13 +7,13 @@ import static io.opentelemetry.sdk.internal.GlobUtil.toGlobPatternPredicate; +import io.opentelemetry.api.incubator.config.DeclarativeConfigException; +import io.opentelemetry.api.incubator.config.DeclarativeConfigProperties; import io.opentelemetry.sdk.autoconfigure.ResourceConfiguration; import io.opentelemetry.sdk.autoconfigure.internal.SpiHelper; -import io.opentelemetry.sdk.autoconfigure.spi.ConfigurationException; import io.opentelemetry.sdk.autoconfigure.spi.Ordered; import io.opentelemetry.sdk.autoconfigure.spi.internal.ComponentProvider; import io.opentelemetry.sdk.autoconfigure.spi.internal.DefaultConfigProperties; -import io.opentelemetry.sdk.autoconfigure.spi.internal.StructuredConfigProperties; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.AttributeNameValueModel; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.DetectorAttributesModel; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.DetectorsModel; @@ -31,10 +31,6 @@ final class ResourceFactory implements Factory { - private static final StructuredConfigProperties EMPTY_CONFIG = - FileConfiguration.toConfigProperties( - Collections.emptyMap(), - SpiHelper.serviceComponentLoader(ResourceFactory.class.getClassLoader())); private static final ResourceFactory INSTANCE = new ResourceFactory(); private ResourceFactory() {} @@ -86,7 +82,7 @@ public Resource create(ResourceModel model, SpiHelper spiHelper, List *

      In declarative configuration, a resource detector is a {@link ComponentProvider} with {@link * ComponentProvider#getType()} set to {@link Resource}. Unlike other {@link ComponentProvider}s, * the resource detector version does not use {@link ComponentProvider#getName()} (except for - * debug messages), and {@link ComponentProvider#create(StructuredConfigProperties)} is called + * debug messages), and {@link ComponentProvider#create(DeclarativeConfigProperties)} is called * with an empty instance. Additionally, the {@link Ordered#order()} value is respected for * resource detectors which implement {@link Ordered}. */ @@ -100,9 +96,9 @@ private static List loadFromResourceDetectors(SpiHelper spiHelper) { } Resource resource; try { - resource = (Resource) componentProvider.create(EMPTY_CONFIG); + resource = (Resource) componentProvider.create(DeclarativeConfigProperties.empty()); } catch (Throwable throwable) { - throw new ConfigurationException( + throw new DeclarativeConfigException( "Error configuring " + Resource.class.getName() + " with name \"" diff --git a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/SamplerFactory.java b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/SamplerFactory.java index 0b38631e0db..491355418ec 100644 --- a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/SamplerFactory.java +++ b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/SamplerFactory.java @@ -7,8 +7,8 @@ import static java.util.stream.Collectors.joining; +import io.opentelemetry.api.incubator.config.DeclarativeConfigException; import io.opentelemetry.sdk.autoconfigure.internal.SpiHelper; -import io.opentelemetry.sdk.autoconfigure.spi.ConfigurationException; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.JaegerRemoteModel; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.ParentBasedModel; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.SamplerModel; @@ -81,7 +81,7 @@ public Sampler create(SamplerModel model, SpiHelper spiHelper, List c if (!model.getAdditionalProperties().isEmpty()) { Map additionalProperties = model.getAdditionalProperties(); if (additionalProperties.size() > 1) { - throw new ConfigurationException( + throw new DeclarativeConfigException( "Invalid configuration - multiple samplers exporters set: " + additionalProperties.keySet().stream().collect(joining(",", "[", "]"))); } @@ -95,7 +95,7 @@ public Sampler create(SamplerModel model, SpiHelper spiHelper, List c spiHelper, Sampler.class, exporterKeyValue.getKey(), exporterKeyValue.getValue()); return FileConfigUtil.addAndReturn(closeables, sampler); } else { - throw new ConfigurationException("sampler must be set"); + throw new DeclarativeConfigException("sampler must be set"); } } } diff --git a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/SdkConfigProvider.java b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/SdkConfigProvider.java new file mode 100644 index 00000000000..8c8d549e007 --- /dev/null +++ b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/SdkConfigProvider.java @@ -0,0 +1,39 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.sdk.extension.incubator.fileconfig; + +import io.opentelemetry.api.incubator.config.ConfigProvider; +import io.opentelemetry.api.incubator.config.DeclarativeConfigProperties; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.OpenTelemetryConfigurationModel; +import javax.annotation.Nullable; + +/** SDK implementation of {@link ConfigProvider}. */ +public final class SdkConfigProvider implements ConfigProvider { + + @Nullable private final DeclarativeConfigProperties instrumentationConfig; + + private SdkConfigProvider(OpenTelemetryConfigurationModel model) { + DeclarativeConfigProperties configProperties = + DeclarativeConfiguration.toConfigProperties(model); + this.instrumentationConfig = configProperties.getStructured("instrumentation"); + } + + /** + * Create a {@link SdkConfigProvider} from the {@code model}. + * + * @param model the configuration model + * @return the {@link SdkConfigProvider} + */ + public static SdkConfigProvider create(OpenTelemetryConfigurationModel model) { + return new SdkConfigProvider(model); + } + + @Nullable + @Override + public DeclarativeConfigProperties getInstrumentationConfig() { + return instrumentationConfig; + } +} diff --git a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/SpanExporterFactory.java b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/SpanExporterFactory.java index 652b3917acf..a984c109033 100644 --- a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/SpanExporterFactory.java +++ b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/SpanExporterFactory.java @@ -7,8 +7,8 @@ import static java.util.stream.Collectors.joining; +import io.opentelemetry.api.incubator.config.DeclarativeConfigException; import io.opentelemetry.sdk.autoconfigure.internal.SpiHelper; -import io.opentelemetry.sdk.autoconfigure.spi.ConfigurationException; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.OtlpModel; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.SpanExporterModel; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.ZipkinModel; @@ -47,7 +47,7 @@ public SpanExporter create( if (!model.getAdditionalProperties().isEmpty()) { Map additionalProperties = model.getAdditionalProperties(); if (additionalProperties.size() > 1) { - throw new ConfigurationException( + throw new DeclarativeConfigException( "Invalid configuration - multiple span exporters set: " + additionalProperties.keySet().stream().collect(joining(",", "[", "]"))); } @@ -65,7 +65,7 @@ public SpanExporter create( exporterKeyValue.getValue()); return FileConfigUtil.addAndReturn(closeables, spanExporter); } else { - throw new ConfigurationException("span exporter must be set"); + throw new DeclarativeConfigException("span exporter must be set"); } } } diff --git a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/SpanProcessorFactory.java b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/SpanProcessorFactory.java index 4a174e201f4..f663f3e97a4 100644 --- a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/SpanProcessorFactory.java +++ b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/SpanProcessorFactory.java @@ -7,8 +7,8 @@ import static java.util.stream.Collectors.joining; +import io.opentelemetry.api.incubator.config.DeclarativeConfigException; import io.opentelemetry.sdk.autoconfigure.internal.SpiHelper; -import io.opentelemetry.sdk.autoconfigure.spi.ConfigurationException; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.BatchSpanProcessorModel; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.SimpleSpanProcessorModel; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.SpanExporterModel; @@ -71,7 +71,7 @@ public SpanProcessor create( if (!model.getAdditionalProperties().isEmpty()) { Map additionalProperties = model.getAdditionalProperties(); if (additionalProperties.size() > 1) { - throw new ConfigurationException( + throw new DeclarativeConfigException( "Invalid configuration - multiple span processors set: " + additionalProperties.keySet().stream().collect(joining(",", "[", "]"))); } @@ -89,7 +89,7 @@ public SpanProcessor create( processorKeyValue.getValue()); return FileConfigUtil.addAndReturn(closeables, spanProcessor); } else { - throw new ConfigurationException("span processor must be set"); + throw new DeclarativeConfigException("span processor must be set"); } } } diff --git a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/TextMapPropagatorFactory.java b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/TextMapPropagatorFactory.java index b2a212aaa57..798a4b337ec 100644 --- a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/TextMapPropagatorFactory.java +++ b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/TextMapPropagatorFactory.java @@ -6,10 +6,10 @@ package io.opentelemetry.sdk.extension.incubator.fileconfig; import io.opentelemetry.api.baggage.propagation.W3CBaggagePropagator; +import io.opentelemetry.api.incubator.config.DeclarativeConfigException; import io.opentelemetry.api.trace.propagation.W3CTraceContextPropagator; import io.opentelemetry.context.propagation.TextMapPropagator; import io.opentelemetry.sdk.autoconfigure.internal.SpiHelper; -import io.opentelemetry.sdk.autoconfigure.spi.ConfigurationException; import java.io.Closeable; import java.util.ArrayList; import java.util.Arrays; @@ -35,7 +35,7 @@ public TextMapPropagator create( if (model.contains("none")) { if (model.size() > 1) { - throw new ConfigurationException( + throw new DeclarativeConfigException( "propagators contains \"none\" along with other propagators"); } return TextMapPropagator.noop(); diff --git a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/YamlStructuredConfigProperties.java b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/YamlDeclarativeConfigProperties.java similarity index 74% rename from sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/YamlStructuredConfigProperties.java rename to sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/YamlDeclarativeConfigProperties.java index f302ee5c805..8a4a70704fb 100644 --- a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/YamlStructuredConfigProperties.java +++ b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/YamlDeclarativeConfigProperties.java @@ -8,14 +8,15 @@ import static java.util.stream.Collectors.joining; import static java.util.stream.Collectors.toList; +import io.opentelemetry.api.incubator.config.DeclarativeConfigException; +import io.opentelemetry.api.incubator.config.DeclarativeConfigProperties; import io.opentelemetry.sdk.autoconfigure.internal.ComponentLoader; -import io.opentelemetry.sdk.autoconfigure.spi.ConfigurationException; -import io.opentelemetry.sdk.autoconfigure.spi.internal.StructuredConfigProperties; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.OpenTelemetryConfigurationModel; import java.util.Arrays; import java.util.Collections; import java.util.HashMap; -import java.util.HashSet; +import java.util.LinkedHashMap; +import java.util.LinkedHashSet; import java.util.List; import java.util.Map; import java.util.Objects; @@ -24,27 +25,35 @@ import javax.annotation.Nullable; /** - * Implementation of {@link StructuredConfigProperties} which uses a declarative configuration model - * as a source. + * Implementation of {@link DeclarativeConfigProperties} which uses a file configuration model as a + * source. + * + *

      This class is internal and is hence not for public use. Its APIs are unstable and can change + * at any time. * * @see #getStructured(String) Accessing nested maps * @see #getStructuredList(String) Accessing lists of maps - * @see FileConfiguration#toConfigProperties(Object, ComponentLoader) Converting configuration model - * to properties + * @see DeclarativeConfiguration#toConfigProperties(Object, ComponentLoader) Converting + * configuration model to properties */ -final class YamlStructuredConfigProperties implements StructuredConfigProperties { +public final class YamlDeclarativeConfigProperties implements DeclarativeConfigProperties { + + private static final Set> SUPPORTED_SCALAR_TYPES = + Collections.unmodifiableSet( + new LinkedHashSet<>( + Arrays.asList(String.class, Boolean.class, Long.class, Double.class))); /** Values are {@link #isPrimitive(Object)}, {@link List} of scalars. */ private final Map simpleEntries; - private final Map> listEntries; - private final Map mapEntries; + private final Map> listEntries; + private final Map mapEntries; private final ComponentLoader componentLoader; - private YamlStructuredConfigProperties( + private YamlDeclarativeConfigProperties( Map simpleEntries, - Map> listEntries, - Map mapEntries, + Map> listEntries, + Map mapEntries, ComponentLoader componentLoader) { this.simpleEntries = simpleEntries; this.listEntries = listEntries; @@ -53,20 +62,20 @@ private YamlStructuredConfigProperties( } /** - * Create a {@link YamlStructuredConfigProperties} from the {@code properties} map. + * Create a {@link YamlDeclarativeConfigProperties} from the {@code properties} map. * - *

      {@code properties} is expected to be the output of YAML parsing (i.e. with Jackson {@link + *

      {@code properties} is expected to be the output of YAML parsing (i.e. with Jackson {@code * com.fasterxml.jackson.databind.ObjectMapper}), and have values which are scalars, lists of * scalars, lists of maps, and maps. * - * @see FileConfiguration#toConfigProperties(OpenTelemetryConfigurationModel) + * @see DeclarativeConfiguration#toConfigProperties(OpenTelemetryConfigurationModel) */ @SuppressWarnings("unchecked") - static YamlStructuredConfigProperties create( + static YamlDeclarativeConfigProperties create( Map properties, ComponentLoader componentLoader) { - Map simpleEntries = new HashMap<>(); - Map> listEntries = new HashMap<>(); - Map mapEntries = new HashMap<>(); + Map simpleEntries = new LinkedHashMap<>(); + Map> listEntries = new LinkedHashMap<>(); + Map mapEntries = new LinkedHashMap<>(); for (Map.Entry entry : properties.entrySet()) { String key = entry.getKey(); Object value = entry.getValue(); @@ -79,34 +88,34 @@ static YamlStructuredConfigProperties create( continue; } if (isListOfMaps(value)) { - List list = + List list = ((List>) value) .stream() - .map(map -> YamlStructuredConfigProperties.create(map, componentLoader)) + .map(map -> YamlDeclarativeConfigProperties.create(map, componentLoader)) .collect(toList()); listEntries.put(key, list); continue; } if (isMap(value)) { - YamlStructuredConfigProperties configProperties = - YamlStructuredConfigProperties.create((Map) value, componentLoader); + YamlDeclarativeConfigProperties configProperties = + YamlDeclarativeConfigProperties.create((Map) value, componentLoader); mapEntries.put(key, configProperties); continue; } - throw new ConfigurationException( + throw new DeclarativeConfigException( "Unable to initialize ExtendedConfigProperties. Key \"" + key + "\" has unrecognized object type " + value.getClass().getName()); } - return new YamlStructuredConfigProperties( + return new YamlDeclarativeConfigProperties( simpleEntries, listEntries, mapEntries, componentLoader); } private static boolean isPrimitiveList(Object object) { if (object instanceof List) { List list = (List) object; - return list.stream().allMatch(YamlStructuredConfigProperties::isPrimitive); + return list.stream().allMatch(YamlDeclarativeConfigProperties::isPrimitive); } return false; } @@ -178,16 +187,12 @@ public Double getDouble(String name) { return doubleOrNull(simpleEntries.get(name)); } - private static final Set> SUPPORTED_SCALAR_TYPES = - Collections.unmodifiableSet( - new HashSet<>(Arrays.asList(String.class, Boolean.class, Long.class, Double.class))); - @Nullable @Override @SuppressWarnings("unchecked") public List getScalarList(String name, Class scalarType) { if (!SUPPORTED_SCALAR_TYPES.contains(scalarType)) { - throw new ConfigurationException( + throw new DeclarativeConfigException( "Unsupported scalar type " + scalarType.getName() + ". Supported types include " @@ -259,14 +264,14 @@ private static Double doubleOrNull(@Nullable Object value) { @Nullable @Override - public StructuredConfigProperties getStructured(String name) { + public DeclarativeConfigProperties getStructured(String name) { return mapEntries.get(name); } @Nullable @Override - public List getStructuredList(String name) { - List value = listEntries.get(name); + public List getStructuredList(String name) { + List value = listEntries.get(name); if (value != null) { return Collections.unmodifiableList(value); } @@ -275,7 +280,7 @@ public List getStructuredList(String name) { @Override public Set getPropertyKeys() { - Set keys = new HashSet<>(); + Set keys = new LinkedHashSet<>(); keys.addAll(simpleEntries.keySet()); keys.addAll(listEntries.keySet()); keys.addAll(mapEntries.keySet()); @@ -284,7 +289,7 @@ public Set getPropertyKeys() { @Override public String toString() { - StringJoiner joiner = new StringJoiner(", ", "YamlStructuredConfigProperties{", "}"); + StringJoiner joiner = new StringJoiner(", ", "YamlDeclarativeConfigProperties{", "}"); simpleEntries.forEach((key, value) -> joiner.add(key + "=" + value)); listEntries.forEach((key, value) -> joiner.add(key + "=" + value)); mapEntries.forEach((key, value) -> joiner.add(key + "=" + value)); @@ -297,7 +302,7 @@ public Map toMap() { listEntries.forEach( (key, value) -> result.put( - key, value.stream().map(YamlStructuredConfigProperties::toMap).collect(toList()))); + key, value.stream().map(YamlDeclarativeConfigProperties::toMap).collect(toList()))); mapEntries.forEach((key, value) -> result.put(key, value.toMap())); return Collections.unmodifiableMap(result); } diff --git a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/AttributeListFactoryTest.java b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/AttributeListFactoryTest.java index 59dd61c03cf..2b3bca05212 100644 --- a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/AttributeListFactoryTest.java +++ b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/AttributeListFactoryTest.java @@ -10,8 +10,8 @@ import static org.mockito.Mockito.mock; import io.opentelemetry.api.common.Attributes; +import io.opentelemetry.api.incubator.config.DeclarativeConfigException; import io.opentelemetry.sdk.autoconfigure.internal.SpiHelper; -import io.opentelemetry.sdk.autoconfigure.spi.ConfigurationException; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.AttributeNameValueModel; import java.util.Arrays; import java.util.Collections; @@ -31,7 +31,7 @@ void create_InvalidAttributes(List model, String expect () -> AttributeListFactory.getInstance() .create(model, mock(SpiHelper.class), Collections.emptyList())) - .isInstanceOf(ConfigurationException.class) + .isInstanceOf(DeclarativeConfigException.class) .hasMessageContaining(expectedMessage); } diff --git a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/FileConfigurationCreateTest.java b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/DeclarativeConfigurationCreateTest.java similarity index 87% rename from sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/FileConfigurationCreateTest.java rename to sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/DeclarativeConfigurationCreateTest.java index 54f91614df7..5b0e2fbca1b 100644 --- a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/FileConfigurationCreateTest.java +++ b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/DeclarativeConfigurationCreateTest.java @@ -12,8 +12,8 @@ import com.linecorp.armeria.testing.junit5.server.SelfSignedCertificateExtension; import io.github.netmikey.logunit.api.LogCapturer; +import io.opentelemetry.api.incubator.config.DeclarativeConfigException; import io.opentelemetry.internal.testing.CleanupExtension; -import io.opentelemetry.sdk.autoconfigure.spi.ConfigurationException; import java.io.ByteArrayInputStream; import java.io.File; import java.io.IOException; @@ -28,7 +28,7 @@ import org.junit.jupiter.api.io.TempDir; import org.slf4j.event.Level; -class FileConfigurationCreateTest { +class DeclarativeConfigurationCreateTest { @RegisterExtension static final SelfSignedCertificateExtension serverTls = new SelfSignedCertificateExtension(); @@ -40,12 +40,12 @@ class FileConfigurationCreateTest { @RegisterExtension LogCapturer logCapturer = - LogCapturer.create().captureForLogger(FileConfiguration.class.getName(), Level.TRACE); + LogCapturer.create().captureForLogger(DeclarativeConfiguration.class.getName(), Level.TRACE); /** * Verify each example in open-telemetry/opentelemetry-configuration/examples - * can pass {@link FileConfiguration#parseAndCreate(InputStream)}. + * can pass {@link DeclarativeConfiguration#parseAndCreate(InputStream)}. */ @Test void parseAndCreate_Examples(@TempDir Path tempDir) @@ -90,12 +90,15 @@ void parseAndCreate_Examples(@TempDir Path tempDir) "client_certificate: .*\n", "client_certificate: " + clientCertificatePath.replace("\\", "\\\\") - + System.lineSeparator()); + + System.lineSeparator()) + // TODO: remove once updated ComponentProvider SPI contract implemented in + // https://github.com/open-telemetry/opentelemetry-java-contrib/tree/main/aws-xray-propagator + .replaceAll("xray,", ""); InputStream is = new ByteArrayInputStream(rewrittenExampleContent.getBytes(StandardCharsets.UTF_8)); // Verify that file can be parsed and interpreted without error - assertThatCode(() -> cleanup.addCloseable(FileConfiguration.parseAndCreate(is))) + assertThatCode(() -> cleanup.addCloseable(DeclarativeConfiguration.parseAndCreate(is))) .as("Example file: " + example.getName()) .doesNotThrowAnyException(); } @@ -119,9 +122,9 @@ void parseAndCreate_Exception_CleansUpPartials() { assertThatThrownBy( () -> - FileConfiguration.parseAndCreate( + DeclarativeConfiguration.parseAndCreate( new ByteArrayInputStream(yaml.getBytes(StandardCharsets.UTF_8)))) - .isInstanceOf(ConfigurationException.class) + .isInstanceOf(DeclarativeConfigException.class) .hasMessage( "No component provider detected for io.opentelemetry.sdk.logs.export.LogRecordExporter with name \"foo\"."); logCapturer.assertContains( @@ -144,9 +147,8 @@ void parseAndCreate_EmptyComponentProviderConfig() { assertThatCode( () -> - FileConfiguration.parseAndCreate( + DeclarativeConfiguration.parseAndCreate( new ByteArrayInputStream(yaml.getBytes(StandardCharsets.UTF_8)))) .doesNotThrowAnyException(); - ; } } diff --git a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/FileConfigurationParseTest.java b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/DeclarativeConfigurationParseTest.java similarity index 98% rename from sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/FileConfigurationParseTest.java rename to sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/DeclarativeConfigurationParseTest.java index 7de63dcb45c..f8ad7330c07 100644 --- a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/FileConfigurationParseTest.java +++ b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/DeclarativeConfigurationParseTest.java @@ -8,7 +8,7 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; -import io.opentelemetry.sdk.autoconfigure.spi.ConfigurationException; +import io.opentelemetry.api.incubator.config.DeclarativeConfigException; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.AggregationModel; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.AlwaysOffModel; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.AlwaysOnModel; @@ -76,15 +76,15 @@ import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.MethodSource; -class FileConfigurationParseTest { +class DeclarativeConfigurationParseTest { @Test void parse_BadInputStream() { assertThatThrownBy( () -> - FileConfiguration.parseAndCreate( + DeclarativeConfiguration.parseAndCreate( new ByteArrayInputStream("foo".getBytes(StandardCharsets.UTF_8)))) - .isInstanceOf(ConfigurationException.class) + .isInstanceOf(DeclarativeConfigException.class) .hasMessage("Unable to parse configuration input stream"); } @@ -446,7 +446,7 @@ void parse_KitchenSinkExampleFile() throws IOException { try (FileInputStream configExampleFile = new FileInputStream(System.getenv("CONFIG_EXAMPLE_DIR") + "/kitchen-sink.yaml")) { - OpenTelemetryConfigurationModel config = FileConfiguration.parse(configExampleFile); + OpenTelemetryConfigurationModel config = DeclarativeConfiguration.parse(configExampleFile); // General config assertThat(config.getFileFormat()).isEqualTo("0.3"); @@ -499,7 +499,7 @@ void parse_nullValuesParsedToEmptyObjects() { + " aggregation:\n" + " drop: {}\n"; OpenTelemetryConfigurationModel objectPlaceholderModel = - FileConfiguration.parse( + DeclarativeConfiguration.parse( new ByteArrayInputStream(objectPlaceholderString.getBytes(StandardCharsets.UTF_8))); String noOjbectPlaceholderString = @@ -517,7 +517,7 @@ void parse_nullValuesParsedToEmptyObjects() { + " aggregation:\n" + " drop:\n"; OpenTelemetryConfigurationModel noObjectPlaceholderModel = - FileConfiguration.parse( + DeclarativeConfiguration.parse( new ByteArrayInputStream(noOjbectPlaceholderString.getBytes(StandardCharsets.UTF_8))); SpanExporterModel exporter = @@ -551,7 +551,8 @@ void parse_nullBoxedPrimitivesParsedToNull() { + " ratio:\n"; // Double OpenTelemetryConfigurationModel model = - FileConfiguration.parse(new ByteArrayInputStream(yaml.getBytes(StandardCharsets.UTF_8))); + DeclarativeConfiguration.parse( + new ByteArrayInputStream(yaml.getBytes(StandardCharsets.UTF_8))); assertThat(model.getFileFormat()).isNull(); assertThat(model.getDisabled()).isNull(); @@ -573,7 +574,7 @@ void parse_nullBoxedPrimitivesParsedToNull() { @MethodSource("coreSchemaValuesArgs") void coreSchemaValues(String rawYaml, Object expectedYamlResult) { Object yaml = - FileConfiguration.loadYaml( + DeclarativeConfiguration.loadYaml( new ByteArrayInputStream(rawYaml.getBytes(StandardCharsets.UTF_8)), Collections.emptyMap()); assertThat(yaml).isEqualTo(expectedYamlResult); @@ -601,7 +602,7 @@ void envSubstituteAndLoadYaml(String rawYaml, Object expectedYamlResult) { environmentVariables.put("HEX", "0xdeadbeef"); Object yaml = - FileConfiguration.loadYaml( + DeclarativeConfiguration.loadYaml( new ByteArrayInputStream(rawYaml.getBytes(StandardCharsets.UTF_8)), environmentVariables); assertThat(yaml).isEqualTo(expectedYamlResult); @@ -689,7 +690,7 @@ void read_WithEnvironmentVariables() { Map envVars = new HashMap<>(); envVars.put("OTEL_EXPORTER_OTLP_ENDPOINT", "http://collector:4317"); OpenTelemetryConfigurationModel model = - FileConfiguration.parse( + DeclarativeConfiguration.parse( new ByteArrayInputStream(yaml.getBytes(StandardCharsets.UTF_8)), envVars); assertThat(model) .isEqualTo( diff --git a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/InstrumentSelectorFactoryTest.java b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/InstrumentSelectorFactoryTest.java index fd9a2640708..3f3192e5853 100644 --- a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/InstrumentSelectorFactoryTest.java +++ b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/InstrumentSelectorFactoryTest.java @@ -9,8 +9,8 @@ import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.mockito.Mockito.mock; +import io.opentelemetry.api.incubator.config.DeclarativeConfigException; import io.opentelemetry.sdk.autoconfigure.internal.SpiHelper; -import io.opentelemetry.sdk.autoconfigure.spi.ConfigurationException; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.SelectorModel; import io.opentelemetry.sdk.metrics.InstrumentSelector; import io.opentelemetry.sdk.metrics.InstrumentType; @@ -25,7 +25,7 @@ void create_Defaults() { () -> InstrumentSelectorFactory.getInstance() .create(new SelectorModel(), mock(SpiHelper.class), Collections.emptyList())) - .isInstanceOf(ConfigurationException.class) + .isInstanceOf(DeclarativeConfigException.class) .hasMessage("Invalid selector"); } diff --git a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/LogRecordExporterFactoryTest.java b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/LogRecordExporterFactoryTest.java index 802b1b9d4c0..39b95d7e75d 100644 --- a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/LogRecordExporterFactoryTest.java +++ b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/LogRecordExporterFactoryTest.java @@ -8,17 +8,18 @@ import static io.opentelemetry.sdk.extension.incubator.fileconfig.FileConfigTestUtil.createTempFileWithContent; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; -import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; import com.google.common.collect.ImmutableMap; import com.linecorp.armeria.testing.junit5.server.SelfSignedCertificateExtension; +import io.opentelemetry.api.incubator.config.DeclarativeConfigException; +import io.opentelemetry.api.incubator.config.DeclarativeConfigProperties; import io.opentelemetry.exporter.otlp.http.logs.OtlpHttpLogRecordExporter; import io.opentelemetry.internal.testing.CleanupExtension; import io.opentelemetry.sdk.autoconfigure.internal.SpiHelper; -import io.opentelemetry.sdk.autoconfigure.spi.ConfigurationException; -import io.opentelemetry.sdk.autoconfigure.spi.internal.StructuredConfigProperties; +import io.opentelemetry.sdk.autoconfigure.spi.internal.ComponentProvider; import io.opentelemetry.sdk.extension.incubator.fileconfig.component.LogRecordExporterComponentProvider; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.LogRecordExporterModel; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.NameStringValuePairModel; @@ -31,12 +32,16 @@ import java.time.Duration; import java.util.ArrayList; import java.util.Arrays; +import java.util.Collections; import java.util.List; +import java.util.stream.Collectors; +import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.junit.jupiter.api.extension.RegisterExtension; import org.junit.jupiter.api.io.TempDir; import org.mockito.ArgumentCaptor; +import org.mockito.Mockito; import org.mockito.junit.jupiter.MockitoExtension; import org.mockito.junit.jupiter.MockitoSettings; import org.mockito.quality.Strictness; @@ -53,12 +58,36 @@ class LogRecordExporterFactoryTest { @RegisterExtension CleanupExtension cleanup = new CleanupExtension(); - private SpiHelper spiHelper = - SpiHelper.create(LogRecordExporterFactoryTest.class.getClassLoader()); + private final SpiHelper spiHelper = + spy(SpiHelper.create(SpanExporterFactoryTest.class.getClassLoader())); + private List> loadedComponentProviders = Collections.emptyList(); + + @BeforeEach + @SuppressWarnings("unchecked") + void setup() { + when(spiHelper.load(ComponentProvider.class)) + .thenAnswer( + invocation -> { + List> result = + (List>) invocation.callRealMethod(); + loadedComponentProviders = + result.stream().map(Mockito::spy).collect(Collectors.toList()); + return loadedComponentProviders; + }); + } + + private ComponentProvider getComponentProvider(String name, Class type) { + return loadedComponentProviders.stream() + .filter( + componentProvider -> + componentProvider.getName().equals(name) + && componentProvider.getType().equals(type)) + .findFirst() + .orElseThrow(IllegalStateException::new); + } @Test void create_OtlpDefaults() { - spiHelper = spy(spiHelper); List closeables = new ArrayList<>(); OtlpHttpLogRecordExporter expectedExporter = OtlpHttpLogRecordExporter.getDefault(); cleanup.addCloseable(expectedExporter); @@ -78,11 +107,11 @@ void create_OtlpDefaults() { assertThat(exporter.toString()).isEqualTo(expectedExporter.toString()); - ArgumentCaptor configCaptor = - ArgumentCaptor.forClass(StructuredConfigProperties.class); - verify(spiHelper) - .loadComponent(eq(LogRecordExporter.class), eq("otlp"), configCaptor.capture()); - StructuredConfigProperties configProperties = configCaptor.getValue(); + ArgumentCaptor configCaptor = + ArgumentCaptor.forClass(DeclarativeConfigProperties.class); + ComponentProvider componentProvider = getComponentProvider("otlp", LogRecordExporter.class); + verify(componentProvider).create(configCaptor.capture()); + DeclarativeConfigProperties configProperties = configCaptor.getValue(); assertThat(configProperties.getString("protocol")).isNull(); assertThat(configProperties.getString("endpoint")).isNull(); assertThat(configProperties.getStructured("headers")).isNull(); @@ -96,7 +125,6 @@ void create_OtlpDefaults() { @Test void create_OtlpConfigured(@TempDir Path tempDir) throws CertificateEncodingException, IOException { - spiHelper = spy(spiHelper); List closeables = new ArrayList<>(); OtlpHttpLogRecordExporter expectedExporter = OtlpHttpLogRecordExporter.builder() @@ -147,14 +175,14 @@ void create_OtlpConfigured(@TempDir Path tempDir) assertThat(exporter.toString()).isEqualTo(expectedExporter.toString()); - ArgumentCaptor configCaptor = - ArgumentCaptor.forClass(StructuredConfigProperties.class); - verify(spiHelper) - .loadComponent(eq(LogRecordExporter.class), eq("otlp"), configCaptor.capture()); - StructuredConfigProperties configProperties = configCaptor.getValue(); + ArgumentCaptor configCaptor = + ArgumentCaptor.forClass(DeclarativeConfigProperties.class); + ComponentProvider componentProvider = getComponentProvider("otlp", LogRecordExporter.class); + verify(componentProvider).create(configCaptor.capture()); + DeclarativeConfigProperties configProperties = configCaptor.getValue(); assertThat(configProperties.getString("protocol")).isEqualTo("http/protobuf"); assertThat(configProperties.getString("endpoint")).isEqualTo("http://example:4318/v1/logs"); - List headers = configProperties.getStructuredList("headers"); + List headers = configProperties.getStructuredList("headers"); assertThat(headers) .isNotNull() .satisfiesExactly( @@ -187,7 +215,7 @@ void create_SpiExporter_Unknown() { "unknown_key", ImmutableMap.of("key1", "value1")), spiHelper, new ArrayList<>())) - .isInstanceOf(ConfigurationException.class) + .isInstanceOf(DeclarativeConfigException.class) .hasMessage( "No component provider detected for io.opentelemetry.sdk.logs.export.LogRecordExporter with name \"unknown_key\"."); cleanup.addCloseables(closeables); diff --git a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/LogRecordProcessorFactoryTest.java b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/LogRecordProcessorFactoryTest.java index e5e29c26981..00314510786 100644 --- a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/LogRecordProcessorFactoryTest.java +++ b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/LogRecordProcessorFactoryTest.java @@ -9,10 +9,10 @@ import static org.assertj.core.api.Assertions.assertThatThrownBy; import com.google.common.collect.ImmutableMap; +import io.opentelemetry.api.incubator.config.DeclarativeConfigException; import io.opentelemetry.exporter.otlp.http.logs.OtlpHttpLogRecordExporter; import io.opentelemetry.internal.testing.CleanupExtension; import io.opentelemetry.sdk.autoconfigure.internal.SpiHelper; -import io.opentelemetry.sdk.autoconfigure.spi.ConfigurationException; import io.opentelemetry.sdk.extension.incubator.fileconfig.component.LogRecordProcessorComponentProvider; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.BatchLogRecordProcessorModel; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.LogRecordExporterModel; @@ -44,7 +44,7 @@ void create_BatchNullExporter() { new LogRecordProcessorModel().withBatch(new BatchLogRecordProcessorModel()), spiHelper, Collections.emptyList())) - .isInstanceOf(ConfigurationException.class) + .isInstanceOf(DeclarativeConfigException.class) .hasMessage("batch log record processor exporter is required but is null"); } @@ -112,7 +112,7 @@ void create_SimpleNullExporter() { .withSimple(new SimpleLogRecordProcessorModel()), spiHelper, Collections.emptyList())) - .isInstanceOf(ConfigurationException.class) + .isInstanceOf(DeclarativeConfigException.class) .hasMessage("simple log record processor exporter is required but is null"); } @@ -150,7 +150,7 @@ void create_SpiProcessor_Unknown() { "unknown_key", ImmutableMap.of("key1", "value1")), spiHelper, new ArrayList<>())) - .isInstanceOf(ConfigurationException.class) + .isInstanceOf(DeclarativeConfigException.class) .hasMessage( "No component provider detected for io.opentelemetry.sdk.logs.LogRecordProcessor with name \"unknown_key\"."); } diff --git a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/MetricExporterFactoryTest.java b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/MetricExporterFactoryTest.java index 0474bbcba6f..51b066b2d97 100644 --- a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/MetricExporterFactoryTest.java +++ b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/MetricExporterFactoryTest.java @@ -8,18 +8,19 @@ import static io.opentelemetry.sdk.extension.incubator.fileconfig.FileConfigTestUtil.createTempFileWithContent; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; -import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; import com.google.common.collect.ImmutableMap; import com.linecorp.armeria.testing.junit5.server.SelfSignedCertificateExtension; +import io.opentelemetry.api.incubator.config.DeclarativeConfigException; +import io.opentelemetry.api.incubator.config.DeclarativeConfigProperties; import io.opentelemetry.exporter.logging.LoggingMetricExporter; import io.opentelemetry.exporter.otlp.http.metrics.OtlpHttpMetricExporter; import io.opentelemetry.internal.testing.CleanupExtension; import io.opentelemetry.sdk.autoconfigure.internal.SpiHelper; -import io.opentelemetry.sdk.autoconfigure.spi.ConfigurationException; -import io.opentelemetry.sdk.autoconfigure.spi.internal.StructuredConfigProperties; +import io.opentelemetry.sdk.autoconfigure.spi.internal.ComponentProvider; import io.opentelemetry.sdk.extension.incubator.fileconfig.component.MetricExporterComponentProvider; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.ConsoleModel; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.NameStringValuePairModel; @@ -36,12 +37,16 @@ import java.time.Duration; import java.util.ArrayList; import java.util.Arrays; +import java.util.Collections; import java.util.List; +import java.util.stream.Collectors; +import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.junit.jupiter.api.extension.RegisterExtension; import org.junit.jupiter.api.io.TempDir; import org.mockito.ArgumentCaptor; +import org.mockito.Mockito; import org.mockito.junit.jupiter.MockitoExtension; import org.mockito.junit.jupiter.MockitoSettings; import org.mockito.quality.Strictness; @@ -58,11 +63,36 @@ class MetricExporterFactoryTest { @RegisterExtension CleanupExtension cleanup = new CleanupExtension(); - private SpiHelper spiHelper = SpiHelper.create(MetricExporterFactoryTest.class.getClassLoader()); + private final SpiHelper spiHelper = + spy(SpiHelper.create(SpanExporterFactoryTest.class.getClassLoader())); + private List> loadedComponentProviders = Collections.emptyList(); + + @BeforeEach + @SuppressWarnings("unchecked") + void setup() { + when(spiHelper.load(ComponentProvider.class)) + .thenAnswer( + invocation -> { + List> result = + (List>) invocation.callRealMethod(); + loadedComponentProviders = + result.stream().map(Mockito::spy).collect(Collectors.toList()); + return loadedComponentProviders; + }); + } + + private ComponentProvider getComponentProvider(String name, Class type) { + return loadedComponentProviders.stream() + .filter( + componentProvider -> + componentProvider.getName().equals(name) + && componentProvider.getType().equals(type)) + .findFirst() + .orElseThrow(IllegalStateException::new); + } @Test void create_OtlpDefaults() { - spiHelper = spy(spiHelper); List closeables = new ArrayList<>(); OtlpHttpMetricExporter expectedExporter = OtlpHttpMetricExporter.getDefault(); cleanup.addCloseable(expectedExporter); @@ -80,10 +110,11 @@ void create_OtlpDefaults() { assertThat(exporter.toString()).isEqualTo(expectedExporter.toString()); - ArgumentCaptor configCaptor = - ArgumentCaptor.forClass(StructuredConfigProperties.class); - verify(spiHelper).loadComponent(eq(MetricExporter.class), eq("otlp"), configCaptor.capture()); - StructuredConfigProperties configProperties = configCaptor.getValue(); + ArgumentCaptor configCaptor = + ArgumentCaptor.forClass(DeclarativeConfigProperties.class); + ComponentProvider componentProvider = getComponentProvider("otlp", MetricExporter.class); + verify(componentProvider).create(configCaptor.capture()); + DeclarativeConfigProperties configProperties = configCaptor.getValue(); assertThat(configProperties.getString("protocol")).isNull(); assertThat(configProperties.getString("endpoint")).isNull(); assertThat(configProperties.getStructured("headers")).isNull(); @@ -99,7 +130,6 @@ void create_OtlpDefaults() { @Test void create_OtlpConfigured(@TempDir Path tempDir) throws CertificateEncodingException, IOException { - spiHelper = spy(spiHelper); List closeables = new ArrayList<>(); OtlpHttpMetricExporter expectedExporter = OtlpHttpMetricExporter.builder() @@ -158,13 +188,14 @@ void create_OtlpConfigured(@TempDir Path tempDir) assertThat(exporter.toString()).isEqualTo(expectedExporter.toString()); - ArgumentCaptor configCaptor = - ArgumentCaptor.forClass(StructuredConfigProperties.class); - verify(spiHelper).loadComponent(eq(MetricExporter.class), eq("otlp"), configCaptor.capture()); - StructuredConfigProperties configProperties = configCaptor.getValue(); + ArgumentCaptor configCaptor = + ArgumentCaptor.forClass(DeclarativeConfigProperties.class); + ComponentProvider componentProvider = getComponentProvider("otlp", MetricExporter.class); + verify(componentProvider).create(configCaptor.capture()); + DeclarativeConfigProperties configProperties = configCaptor.getValue(); assertThat(configProperties.getString("protocol")).isEqualTo("http/protobuf"); assertThat(configProperties.getString("endpoint")).isEqualTo("http://example:4318/v1/metrics"); - List headers = configProperties.getStructuredList("headers"); + List headers = configProperties.getStructuredList("headers"); assertThat(headers) .isNotNull() .satisfiesExactly( @@ -188,7 +219,6 @@ void create_OtlpConfigured(@TempDir Path tempDir) @Test void create_Console() { - spiHelper = spy(spiHelper); List closeables = new ArrayList<>(); LoggingMetricExporter expectedExporter = LoggingMetricExporter.create(); cleanup.addCloseable(expectedExporter); @@ -219,7 +249,7 @@ void create_SpiExporter_Unknown() { "unknown_key", ImmutableMap.of("key1", "value1")), spiHelper, new ArrayList<>())) - .isInstanceOf(ConfigurationException.class) + .isInstanceOf(DeclarativeConfigException.class) .hasMessage( "No component provider detected for io.opentelemetry.sdk.metrics.export.MetricExporter with name \"unknown_key\"."); } diff --git a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/MetricReaderFactoryTest.java b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/MetricReaderFactoryTest.java index db065d8c1cd..287e8977866 100644 --- a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/MetricReaderFactoryTest.java +++ b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/MetricReaderFactoryTest.java @@ -11,11 +11,11 @@ import static org.mockito.Mockito.verify; import io.github.netmikey.logunit.api.LogCapturer; +import io.opentelemetry.api.incubator.config.DeclarativeConfigException; import io.opentelemetry.exporter.otlp.http.metrics.OtlpHttpMetricExporter; import io.opentelemetry.exporter.prometheus.PrometheusHttpServer; import io.opentelemetry.internal.testing.CleanupExtension; import io.opentelemetry.sdk.autoconfigure.internal.SpiHelper; -import io.opentelemetry.sdk.autoconfigure.spi.ConfigurationException; import io.opentelemetry.sdk.autoconfigure.spi.internal.ComponentProvider; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.MetricReaderModel; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.OtlpMetricModel; @@ -40,7 +40,7 @@ class MetricReaderFactoryTest { @RegisterExtension LogCapturer logCapturer = - LogCapturer.create().captureForLogger(FileConfiguration.class.getName()); + LogCapturer.create().captureForLogger(DeclarativeConfiguration.class.getName()); private SpiHelper spiHelper = SpiHelper.create(MetricReaderFactoryTest.class.getClassLoader()); @@ -53,7 +53,7 @@ void create_PeriodicNullExporter() { new MetricReaderModel().withPeriodic(new PeriodicMetricReaderModel()), spiHelper, Collections.emptyList())) - .isInstanceOf(ConfigurationException.class) + .isInstanceOf(DeclarativeConfigException.class) .hasMessage("periodic metric reader exporter is required but is null"); } @@ -179,7 +179,7 @@ void create_InvalidPullReader() { new MetricReaderModel().withPull(new PullMetricReaderModel()), spiHelper, Collections.emptyList())) - .isInstanceOf(ConfigurationException.class) + .isInstanceOf(DeclarativeConfigException.class) .hasMessage("pull metric reader exporter is required but is null"); assertThatThrownBy( @@ -192,7 +192,7 @@ void create_InvalidPullReader() { .withExporter(new PullMetricExporterModel())), spiHelper, Collections.emptyList())) - .isInstanceOf(ConfigurationException.class) + .isInstanceOf(DeclarativeConfigException.class) .hasMessage("prometheus is the only currently supported pull reader"); } diff --git a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/OpenTelemetryConfigurationFactoryTest.java b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/OpenTelemetryConfigurationFactoryTest.java index 449eb59ab0d..3d102c13dfa 100644 --- a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/OpenTelemetryConfigurationFactoryTest.java +++ b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/OpenTelemetryConfigurationFactoryTest.java @@ -10,6 +10,7 @@ import static org.assertj.core.api.Assertions.assertThatThrownBy; import io.opentelemetry.api.baggage.propagation.W3CBaggagePropagator; +import io.opentelemetry.api.incubator.config.DeclarativeConfigException; import io.opentelemetry.api.trace.propagation.W3CTraceContextPropagator; import io.opentelemetry.context.propagation.ContextPropagators; import io.opentelemetry.context.propagation.TextMapPropagator; @@ -22,7 +23,6 @@ import io.opentelemetry.internal.testing.CleanupExtension; import io.opentelemetry.sdk.OpenTelemetrySdk; import io.opentelemetry.sdk.autoconfigure.internal.SpiHelper; -import io.opentelemetry.sdk.autoconfigure.spi.ConfigurationException; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.AlwaysOnModel; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.AttributeNameValueModel; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.BatchLogRecordProcessorModel; @@ -82,7 +82,7 @@ void create_InvalidFileFormat() { () -> OpenTelemetryConfigurationFactory.getInstance() .create(testCase, spiHelper, closeables)) - .isInstanceOf(ConfigurationException.class) + .isInstanceOf(DeclarativeConfigException.class) .hasMessage("Unsupported file format. Supported formats include: 0.3"); cleanup.addCloseables(closeables); } diff --git a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/ResourceFactoryTest.java b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/ResourceFactoryTest.java index e863a4ecb51..7c0b954faf9 100644 --- a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/ResourceFactoryTest.java +++ b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/ResourceFactoryTest.java @@ -26,7 +26,7 @@ class ResourceFactoryTest { - private SpiHelper spiHelper = SpiHelper.create(MetricExporterFactoryTest.class.getClassLoader()); + private SpiHelper spiHelper = SpiHelper.create(ResourceFactoryTest.class.getClassLoader()); @Test void create() { diff --git a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/SamplerFactoryTest.java b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/SamplerFactoryTest.java index 363bb301975..f57073d5246 100644 --- a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/SamplerFactoryTest.java +++ b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/SamplerFactoryTest.java @@ -9,10 +9,10 @@ import static org.assertj.core.api.Assertions.assertThatThrownBy; import com.google.common.collect.ImmutableMap; +import io.opentelemetry.api.incubator.config.DeclarativeConfigException; import io.opentelemetry.internal.testing.CleanupExtension; import io.opentelemetry.internal.testing.slf4j.SuppressLogger; import io.opentelemetry.sdk.autoconfigure.internal.SpiHelper; -import io.opentelemetry.sdk.autoconfigure.spi.ConfigurationException; import io.opentelemetry.sdk.extension.incubator.fileconfig.component.SamplerComponentProvider; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.AlwaysOffModel; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.AlwaysOnModel; @@ -140,7 +140,7 @@ void create_SpiExporter_Unknown() { "unknown_key", ImmutableMap.of("key1", "value1")), spiHelper, new ArrayList<>())) - .isInstanceOf(ConfigurationException.class) + .isInstanceOf(DeclarativeConfigException.class) .hasMessage( "No component provider detected for io.opentelemetry.sdk.trace.samplers.Sampler with name \"unknown_key\"."); cleanup.addCloseables(closeables); diff --git a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/SpanExporterFactoryTest.java b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/SpanExporterFactoryTest.java index bccfcc560c4..22089676920 100644 --- a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/SpanExporterFactoryTest.java +++ b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/SpanExporterFactoryTest.java @@ -8,19 +8,20 @@ import static io.opentelemetry.sdk.extension.incubator.fileconfig.FileConfigTestUtil.createTempFileWithContent; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; -import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; import com.google.common.collect.ImmutableMap; import com.linecorp.armeria.testing.junit5.server.SelfSignedCertificateExtension; +import io.opentelemetry.api.incubator.config.DeclarativeConfigException; +import io.opentelemetry.api.incubator.config.DeclarativeConfigProperties; import io.opentelemetry.exporter.logging.LoggingSpanExporter; import io.opentelemetry.exporter.otlp.http.trace.OtlpHttpSpanExporter; import io.opentelemetry.exporter.zipkin.ZipkinSpanExporter; import io.opentelemetry.internal.testing.CleanupExtension; import io.opentelemetry.sdk.autoconfigure.internal.SpiHelper; -import io.opentelemetry.sdk.autoconfigure.spi.ConfigurationException; -import io.opentelemetry.sdk.autoconfigure.spi.internal.StructuredConfigProperties; +import io.opentelemetry.sdk.autoconfigure.spi.internal.ComponentProvider; import io.opentelemetry.sdk.extension.incubator.fileconfig.component.SpanExporterComponentProvider; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.ConsoleModel; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.NameStringValuePairModel; @@ -34,12 +35,16 @@ import java.time.Duration; import java.util.ArrayList; import java.util.Arrays; +import java.util.Collections; import java.util.List; +import java.util.stream.Collectors; +import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.junit.jupiter.api.extension.RegisterExtension; import org.junit.jupiter.api.io.TempDir; import org.mockito.ArgumentCaptor; +import org.mockito.Mockito; import org.mockito.junit.jupiter.MockitoExtension; import org.mockito.junit.jupiter.MockitoSettings; import org.mockito.quality.Strictness; @@ -56,11 +61,36 @@ class SpanExporterFactoryTest { @RegisterExtension CleanupExtension cleanup = new CleanupExtension(); - private SpiHelper spiHelper = SpiHelper.create(SpanExporterFactoryTest.class.getClassLoader()); + private final SpiHelper spiHelper = + spy(SpiHelper.create(SpanExporterFactoryTest.class.getClassLoader())); + private List> loadedComponentProviders = Collections.emptyList(); + + @BeforeEach + @SuppressWarnings("unchecked") + void setup() { + when(spiHelper.load(ComponentProvider.class)) + .thenAnswer( + invocation -> { + List> result = + (List>) invocation.callRealMethod(); + loadedComponentProviders = + result.stream().map(Mockito::spy).collect(Collectors.toList()); + return loadedComponentProviders; + }); + } + + private ComponentProvider getComponentProvider(String name, Class type) { + return loadedComponentProviders.stream() + .filter( + componentProvider -> + componentProvider.getName().equals(name) + && componentProvider.getType().equals(type)) + .findFirst() + .orElseThrow(IllegalStateException::new); + } @Test void create_OtlpDefaults() { - spiHelper = spy(spiHelper); List closeables = new ArrayList<>(); OtlpHttpSpanExporter expectedExporter = OtlpHttpSpanExporter.getDefault(); cleanup.addCloseable(expectedExporter); @@ -78,10 +108,11 @@ void create_OtlpDefaults() { assertThat(exporter.toString()).isEqualTo(expectedExporter.toString()); - ArgumentCaptor configCaptor = - ArgumentCaptor.forClass(StructuredConfigProperties.class); - verify(spiHelper).loadComponent(eq(SpanExporter.class), eq("otlp"), configCaptor.capture()); - StructuredConfigProperties configProperties = configCaptor.getValue(); + ArgumentCaptor configCaptor = + ArgumentCaptor.forClass(DeclarativeConfigProperties.class); + ComponentProvider componentProvider = getComponentProvider("otlp", SpanExporter.class); + verify(componentProvider).create(configCaptor.capture()); + DeclarativeConfigProperties configProperties = configCaptor.getValue(); assertThat(configProperties.getString("protocol")).isNull(); assertThat(configProperties.getString("endpoint")).isNull(); assertThat(configProperties.getStructured("headers")).isNull(); @@ -95,7 +126,6 @@ void create_OtlpDefaults() { @Test void create_OtlpConfigured(@TempDir Path tempDir) throws CertificateEncodingException, IOException { - spiHelper = spy(spiHelper); List closeables = new ArrayList<>(); OtlpHttpSpanExporter expectedExporter = OtlpHttpSpanExporter.builder() @@ -146,13 +176,14 @@ void create_OtlpConfigured(@TempDir Path tempDir) assertThat(exporter.toString()).isEqualTo(expectedExporter.toString()); - ArgumentCaptor configCaptor = - ArgumentCaptor.forClass(StructuredConfigProperties.class); - verify(spiHelper).loadComponent(eq(SpanExporter.class), eq("otlp"), configCaptor.capture()); - StructuredConfigProperties configProperties = configCaptor.getValue(); + ArgumentCaptor configCaptor = + ArgumentCaptor.forClass(DeclarativeConfigProperties.class); + ComponentProvider componentProvider = getComponentProvider("otlp", SpanExporter.class); + verify(componentProvider).create(configCaptor.capture()); + DeclarativeConfigProperties configProperties = configCaptor.getValue(); assertThat(configProperties.getString("protocol")).isEqualTo("http/protobuf"); assertThat(configProperties.getString("endpoint")).isEqualTo("http://example:4318/v1/traces"); - List headers = configProperties.getStructuredList("headers"); + List headers = configProperties.getStructuredList("headers"); assertThat(headers) .isNotNull() .satisfiesExactly( @@ -173,7 +204,6 @@ void create_OtlpConfigured(@TempDir Path tempDir) @Test void create_Console() { - spiHelper = spy(spiHelper); List closeables = new ArrayList<>(); LoggingSpanExporter expectedExporter = LoggingSpanExporter.create(); cleanup.addCloseable(expectedExporter); @@ -194,7 +224,6 @@ void create_Console() { @Test void create_ZipkinDefaults() { - spiHelper = spy(spiHelper); List closeables = new ArrayList<>(); ZipkinSpanExporter expectedExporter = ZipkinSpanExporter.builder().build(); @@ -213,17 +242,17 @@ void create_ZipkinDefaults() { assertThat(exporter.toString()).isEqualTo(expectedExporter.toString()); - ArgumentCaptor configCaptor = - ArgumentCaptor.forClass(StructuredConfigProperties.class); - verify(spiHelper).loadComponent(eq(SpanExporter.class), eq("zipkin"), configCaptor.capture()); - StructuredConfigProperties configProperties = configCaptor.getValue(); + ArgumentCaptor configCaptor = + ArgumentCaptor.forClass(DeclarativeConfigProperties.class); + ComponentProvider componentProvider = getComponentProvider("zipkin", SpanExporter.class); + verify(componentProvider).create(configCaptor.capture()); + DeclarativeConfigProperties configProperties = configCaptor.getValue(); assertThat(configProperties.getString("endpoint")).isNull(); assertThat(configProperties.getLong("timeout")).isNull(); } @Test void create_ZipkinConfigured() { - spiHelper = spy(spiHelper); List closeables = new ArrayList<>(); ZipkinSpanExporter expectedExporter = ZipkinSpanExporter.builder() @@ -248,10 +277,11 @@ void create_ZipkinConfigured() { assertThat(exporter.toString()).isEqualTo(expectedExporter.toString()); - ArgumentCaptor configCaptor = - ArgumentCaptor.forClass(StructuredConfigProperties.class); - verify(spiHelper).loadComponent(eq(SpanExporter.class), eq("zipkin"), configCaptor.capture()); - StructuredConfigProperties configProperties = configCaptor.getValue(); + ArgumentCaptor configCaptor = + ArgumentCaptor.forClass(DeclarativeConfigProperties.class); + ComponentProvider componentProvider = getComponentProvider("zipkin", SpanExporter.class); + verify(componentProvider).create(configCaptor.capture()); + DeclarativeConfigProperties configProperties = configCaptor.getValue(); assertThat(configProperties.getString("endpoint")).isEqualTo("http://zipkin:9411/v1/v2/spans"); assertThat(configProperties.getLong("timeout")).isEqualTo(15_000); } @@ -270,7 +300,7 @@ void create_SpiExporter_Unknown() { "unknown_key", ImmutableMap.of("key1", "value1")), spiHelper, new ArrayList<>())) - .isInstanceOf(ConfigurationException.class) + .isInstanceOf(DeclarativeConfigException.class) .hasMessage( "No component provider detected for io.opentelemetry.sdk.trace.export.SpanExporter with name \"unknown_key\"."); cleanup.addCloseables(closeables); diff --git a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/SpanProcessorFactoryTest.java b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/SpanProcessorFactoryTest.java index 6da913c6f65..a1b7bb32ba4 100644 --- a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/SpanProcessorFactoryTest.java +++ b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/SpanProcessorFactoryTest.java @@ -9,10 +9,10 @@ import static org.assertj.core.api.Assertions.assertThatThrownBy; import com.google.common.collect.ImmutableMap; +import io.opentelemetry.api.incubator.config.DeclarativeConfigException; import io.opentelemetry.exporter.otlp.http.trace.OtlpHttpSpanExporter; import io.opentelemetry.internal.testing.CleanupExtension; import io.opentelemetry.sdk.autoconfigure.internal.SpiHelper; -import io.opentelemetry.sdk.autoconfigure.spi.ConfigurationException; import io.opentelemetry.sdk.extension.incubator.fileconfig.component.SpanProcessorComponentProvider; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.BatchSpanProcessorModel; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.OtlpModel; @@ -44,7 +44,7 @@ void create_BatchNullExporter() { new SpanProcessorModel().withBatch(new BatchSpanProcessorModel()), spiHelper, Collections.emptyList())) - .isInstanceOf(ConfigurationException.class) + .isInstanceOf(DeclarativeConfigException.class) .hasMessage("batch span processor exporter is required but is null"); } @@ -111,7 +111,7 @@ void create_SimpleNullExporter() { new SpanProcessorModel().withSimple(new SimpleSpanProcessorModel()), spiHelper, Collections.emptyList())) - .isInstanceOf(ConfigurationException.class) + .isInstanceOf(DeclarativeConfigException.class) .hasMessage("simple span processor exporter is required but is null"); } @@ -149,7 +149,7 @@ void create_SpiProcessor_Unknown() { "unknown_key", ImmutableMap.of("key1", "value1")), spiHelper, new ArrayList<>())) - .isInstanceOf(ConfigurationException.class) + .isInstanceOf(DeclarativeConfigException.class) .hasMessage( "No component provider detected for io.opentelemetry.sdk.trace.SpanProcessor with name \"unknown_key\"."); } diff --git a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/TextMapPropagatorFactoryTest.java b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/TextMapPropagatorFactoryTest.java index d2a1d5d242d..17d21a7f364 100644 --- a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/TextMapPropagatorFactoryTest.java +++ b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/TextMapPropagatorFactoryTest.java @@ -9,13 +9,13 @@ import static org.assertj.core.api.Assertions.assertThatThrownBy; import io.opentelemetry.api.baggage.propagation.W3CBaggagePropagator; +import io.opentelemetry.api.incubator.config.DeclarativeConfigException; import io.opentelemetry.api.trace.propagation.W3CTraceContextPropagator; import io.opentelemetry.context.propagation.TextMapPropagator; import io.opentelemetry.extension.trace.propagation.B3Propagator; import io.opentelemetry.extension.trace.propagation.JaegerPropagator; import io.opentelemetry.extension.trace.propagation.OtTracePropagator; import io.opentelemetry.sdk.autoconfigure.internal.SpiHelper; -import io.opentelemetry.sdk.autoconfigure.spi.ConfigurationException; import io.opentelemetry.sdk.extension.incubator.fileconfig.component.TextMapPropagatorComponentProvider; import java.util.ArrayList; import java.util.Arrays; @@ -65,7 +65,7 @@ void create_NoneAndOther() { () -> TextMapPropagatorFactory.getInstance() .create(Arrays.asList("none", "foo"), spiHelper, Collections.emptyList())) - .isInstanceOf(ConfigurationException.class) + .isInstanceOf(DeclarativeConfigException.class) .hasMessage("propagators contains \"none\" along with other propagators"); } @@ -75,7 +75,7 @@ void create_SpiPropagator_Unknown() { () -> TextMapPropagatorFactory.getInstance() .create(Collections.singletonList("foo"), spiHelper, Collections.emptyList())) - .isInstanceOf(ConfigurationException.class) + .isInstanceOf(DeclarativeConfigException.class) .hasMessage( "No component provider detected for io.opentelemetry.context.propagation.TextMapPropagator with name \"foo\"."); } @@ -91,7 +91,7 @@ void create_SpiPropagator_Valid() { testTextMapPropagator -> assertThat(testTextMapPropagator.config) .isInstanceOfSatisfying( - YamlStructuredConfigProperties.class, + YamlDeclarativeConfigProperties.class, config -> assertThat(config.getPropertyKeys()).isEmpty())); } } diff --git a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/YamlStructuredConfigPropertiesTest.java b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/YamlDeclarativeConfigPropertiesTest.java similarity index 88% rename from sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/YamlStructuredConfigPropertiesTest.java rename to sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/YamlDeclarativeConfigPropertiesTest.java index 3bbd11bcef5..14f213245f4 100644 --- a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/YamlStructuredConfigPropertiesTest.java +++ b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/YamlDeclarativeConfigPropertiesTest.java @@ -5,11 +5,11 @@ package io.opentelemetry.sdk.extension.incubator.fileconfig; -import static io.opentelemetry.sdk.autoconfigure.spi.internal.StructuredConfigProperties.empty; +import static io.opentelemetry.api.incubator.config.DeclarativeConfigProperties.empty; import static org.assertj.core.api.Assertions.assertThat; import com.google.common.collect.ImmutableSet; -import io.opentelemetry.sdk.autoconfigure.spi.internal.StructuredConfigProperties; +import io.opentelemetry.api.incubator.config.DeclarativeConfigProperties; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.OpenTelemetryConfigurationModel; import java.io.ByteArrayInputStream; import java.nio.charset.StandardCharsets; @@ -19,7 +19,7 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; -class YamlStructuredConfigPropertiesTest { +class YamlDeclarativeConfigPropertiesTest { private static final String extendedSchema = "file_format: \"0.3\"\n" @@ -56,23 +56,23 @@ class YamlStructuredConfigPropertiesTest { + " - str_key1: str_value1\n" + " int_key1: 2"; - private StructuredConfigProperties structuredConfigProps; + private DeclarativeConfigProperties structuredConfigProps; @BeforeEach void setup() { OpenTelemetryConfigurationModel configuration = - FileConfiguration.parse( + DeclarativeConfiguration.parse( new ByteArrayInputStream(extendedSchema.getBytes(StandardCharsets.UTF_8))); - structuredConfigProps = FileConfiguration.toConfigProperties(configuration); + structuredConfigProps = DeclarativeConfiguration.toConfigProperties(configuration); } @Test void configurationSchema() { // Validate can read declarative configuration schema properties assertThat(structuredConfigProps.getString("file_format")).isEqualTo("0.3"); - StructuredConfigProperties resourceProps = structuredConfigProps.getStructured("resource"); + DeclarativeConfigProperties resourceProps = structuredConfigProps.getStructured("resource"); assertThat(resourceProps).isNotNull(); - List resourceAttributesList = + List resourceAttributesList = resourceProps.getStructuredList("attributes"); assertThat(resourceAttributesList) .isNotNull() @@ -90,7 +90,7 @@ void additionalProperties() { // Validate can read properties not part of configuration schema // .other - StructuredConfigProperties otherProps = structuredConfigProps.getStructured("other"); + DeclarativeConfigProperties otherProps = structuredConfigProps.getStructured("other"); assertThat(otherProps).isNotNull(); assertThat(otherProps.getPropertyKeys()) .isEqualTo( @@ -135,14 +135,15 @@ void additionalProperties() { .isEqualTo(Collections.singletonList(true)); // .other.map_key - StructuredConfigProperties otherMapKeyProps = otherProps.getStructured("map_key"); + DeclarativeConfigProperties otherMapKeyProps = otherProps.getStructured("map_key"); assertThat(otherMapKeyProps).isNotNull(); assertThat(otherMapKeyProps.getPropertyKeys()) .isEqualTo(ImmutableSet.of("str_key1", "int_key1", "map_key1")); assertThat(otherMapKeyProps.getString("str_key1")).isEqualTo("str_value1"); assertThat(otherMapKeyProps.getInt("int_key1")).isEqualTo(2); // other.map_key.map_key1 - StructuredConfigProperties otherMapKeyMapKey1Props = otherMapKeyProps.getStructured("map_key1"); + DeclarativeConfigProperties otherMapKeyMapKey1Props = + otherMapKeyProps.getStructured("map_key1"); assertThat(otherMapKeyMapKey1Props).isNotNull(); assertThat(otherMapKeyMapKey1Props.getPropertyKeys()) .isEqualTo(ImmutableSet.of("str_key2", "int_key2")); @@ -150,22 +151,22 @@ void additionalProperties() { assertThat(otherMapKeyMapKey1Props.getInt("int_key2")).isEqualTo(3); // .other.list_key - List listKey = otherProps.getStructuredList("list_key"); + List listKey = otherProps.getStructuredList("list_key"); assertThat(listKey).hasSize(2); - StructuredConfigProperties listKeyProps1 = listKey.get(0); + DeclarativeConfigProperties listKeyProps1 = listKey.get(0); assertThat(listKeyProps1.getPropertyKeys()) .isEqualTo(ImmutableSet.of("str_key1", "int_key1", "map_key1")); assertThat(listKeyProps1.getString("str_key1")).isEqualTo("str_value1"); assertThat(listKeyProps1.getInt("int_key1")).isEqualTo(2); // .other.list_key[0] - StructuredConfigProperties listKeyProps1MapKeyProps = listKeyProps1.getStructured("map_key1"); + DeclarativeConfigProperties listKeyProps1MapKeyProps = listKeyProps1.getStructured("map_key1"); assertThat(listKeyProps1MapKeyProps).isNotNull(); assertThat(listKeyProps1MapKeyProps.getPropertyKeys()) .isEqualTo(ImmutableSet.of("str_key2", "int_key2")); assertThat(listKeyProps1MapKeyProps.getString("str_key2")).isEqualTo("str_value2"); assertThat(listKeyProps1MapKeyProps.getInt("int_key2")).isEqualTo(3); // .other.list_key[1] - StructuredConfigProperties listKeyProps2 = listKey.get(1); + DeclarativeConfigProperties listKeyProps2 = listKey.get(1); assertThat(listKeyProps2.getPropertyKeys()).isEqualTo(ImmutableSet.of("str_key1", "int_key1")); assertThat(listKeyProps2.getString("str_key1")).isEqualTo("str_value1"); assertThat(listKeyProps2.getInt("int_key1")).isEqualTo(2); @@ -213,7 +214,7 @@ void missingKeys() { @Test void wrongType() { - StructuredConfigProperties otherProps = structuredConfigProps.getStructured("other"); + DeclarativeConfigProperties otherProps = structuredConfigProps.getStructured("other"); assertThat(otherProps).isNotNull(); assertThat(otherProps.getString("int_key")).isNull(); diff --git a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/component/LogRecordExporterComponentProvider.java b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/component/LogRecordExporterComponentProvider.java index 2f2d6f56c7c..f21c1d1bf09 100644 --- a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/component/LogRecordExporterComponentProvider.java +++ b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/component/LogRecordExporterComponentProvider.java @@ -5,8 +5,8 @@ package io.opentelemetry.sdk.extension.incubator.fileconfig.component; +import io.opentelemetry.api.incubator.config.DeclarativeConfigProperties; import io.opentelemetry.sdk.autoconfigure.spi.internal.ComponentProvider; -import io.opentelemetry.sdk.autoconfigure.spi.internal.StructuredConfigProperties; import io.opentelemetry.sdk.common.CompletableResultCode; import io.opentelemetry.sdk.logs.data.LogRecordData; import io.opentelemetry.sdk.logs.export.LogRecordExporter; @@ -24,15 +24,15 @@ public String getName() { } @Override - public LogRecordExporter create(StructuredConfigProperties config) { + public LogRecordExporter create(DeclarativeConfigProperties config) { return new TestLogRecordExporter(config); } public static class TestLogRecordExporter implements LogRecordExporter { - public final StructuredConfigProperties config; + public final DeclarativeConfigProperties config; - private TestLogRecordExporter(StructuredConfigProperties config) { + private TestLogRecordExporter(DeclarativeConfigProperties config) { this.config = config; } diff --git a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/component/LogRecordProcessorComponentProvider.java b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/component/LogRecordProcessorComponentProvider.java index 581f2726154..a44cd939c74 100644 --- a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/component/LogRecordProcessorComponentProvider.java +++ b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/component/LogRecordProcessorComponentProvider.java @@ -5,9 +5,9 @@ package io.opentelemetry.sdk.extension.incubator.fileconfig.component; +import io.opentelemetry.api.incubator.config.DeclarativeConfigProperties; import io.opentelemetry.context.Context; import io.opentelemetry.sdk.autoconfigure.spi.internal.ComponentProvider; -import io.opentelemetry.sdk.autoconfigure.spi.internal.StructuredConfigProperties; import io.opentelemetry.sdk.common.CompletableResultCode; import io.opentelemetry.sdk.logs.LogRecordProcessor; import io.opentelemetry.sdk.logs.ReadWriteLogRecord; @@ -24,15 +24,15 @@ public String getName() { } @Override - public LogRecordProcessor create(StructuredConfigProperties config) { + public LogRecordProcessor create(DeclarativeConfigProperties config) { return new TestLogRecordProcessor(config); } public static class TestLogRecordProcessor implements LogRecordProcessor { - public final StructuredConfigProperties config; + public final DeclarativeConfigProperties config; - private TestLogRecordProcessor(StructuredConfigProperties config) { + private TestLogRecordProcessor(DeclarativeConfigProperties config) { this.config = config; } diff --git a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/component/MetricExporterComponentProvider.java b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/component/MetricExporterComponentProvider.java index b0c46a8be92..80ea6b556ce 100644 --- a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/component/MetricExporterComponentProvider.java +++ b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/component/MetricExporterComponentProvider.java @@ -5,8 +5,8 @@ package io.opentelemetry.sdk.extension.incubator.fileconfig.component; +import io.opentelemetry.api.incubator.config.DeclarativeConfigProperties; import io.opentelemetry.sdk.autoconfigure.spi.internal.ComponentProvider; -import io.opentelemetry.sdk.autoconfigure.spi.internal.StructuredConfigProperties; import io.opentelemetry.sdk.common.CompletableResultCode; import io.opentelemetry.sdk.metrics.InstrumentType; import io.opentelemetry.sdk.metrics.data.AggregationTemporality; @@ -27,15 +27,15 @@ public String getName() { } @Override - public MetricExporter create(StructuredConfigProperties config) { + public MetricExporter create(DeclarativeConfigProperties config) { return new TestMetricExporter(config); } public static class TestMetricExporter implements MetricExporter { - public final StructuredConfigProperties config; + public final DeclarativeConfigProperties config; - private TestMetricExporter(StructuredConfigProperties config) { + private TestMetricExporter(DeclarativeConfigProperties config) { this.config = config; } diff --git a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/component/ResourceComponentProvider.java b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/component/ResourceComponentProvider.java index 13b0e86c05a..0ec06894896 100644 --- a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/component/ResourceComponentProvider.java +++ b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/component/ResourceComponentProvider.java @@ -5,8 +5,8 @@ package io.opentelemetry.sdk.extension.incubator.fileconfig.component; +import io.opentelemetry.api.incubator.config.DeclarativeConfigProperties; import io.opentelemetry.sdk.autoconfigure.spi.internal.ComponentProvider; -import io.opentelemetry.sdk.autoconfigure.spi.internal.StructuredConfigProperties; import io.opentelemetry.sdk.resources.Resource; public class ResourceComponentProvider implements ComponentProvider { @@ -21,7 +21,7 @@ public String getName() { } @Override - public Resource create(StructuredConfigProperties config) { + public Resource create(DeclarativeConfigProperties config) { return Resource.builder().put("shape", "square").put("color", "red").build(); } } diff --git a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/component/ResourceOrderedFirstComponentProvider.java b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/component/ResourceOrderedFirstComponentProvider.java index f2f41e5b955..181c7b469c8 100644 --- a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/component/ResourceOrderedFirstComponentProvider.java +++ b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/component/ResourceOrderedFirstComponentProvider.java @@ -5,9 +5,9 @@ package io.opentelemetry.sdk.extension.incubator.fileconfig.component; +import io.opentelemetry.api.incubator.config.DeclarativeConfigProperties; import io.opentelemetry.sdk.autoconfigure.spi.Ordered; import io.opentelemetry.sdk.autoconfigure.spi.internal.ComponentProvider; -import io.opentelemetry.sdk.autoconfigure.spi.internal.StructuredConfigProperties; import io.opentelemetry.sdk.resources.Resource; public class ResourceOrderedFirstComponentProvider implements ComponentProvider, Ordered { @@ -22,7 +22,7 @@ public String getName() { } @Override - public Resource create(StructuredConfigProperties config) { + public Resource create(DeclarativeConfigProperties config) { return Resource.builder().put("order", "first").build(); } diff --git a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/component/ResourceOrderedSecondComponentProvider.java b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/component/ResourceOrderedSecondComponentProvider.java index 00017b2b7d4..5cbb5e299e4 100644 --- a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/component/ResourceOrderedSecondComponentProvider.java +++ b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/component/ResourceOrderedSecondComponentProvider.java @@ -5,9 +5,9 @@ package io.opentelemetry.sdk.extension.incubator.fileconfig.component; +import io.opentelemetry.api.incubator.config.DeclarativeConfigProperties; import io.opentelemetry.sdk.autoconfigure.spi.Ordered; import io.opentelemetry.sdk.autoconfigure.spi.internal.ComponentProvider; -import io.opentelemetry.sdk.autoconfigure.spi.internal.StructuredConfigProperties; import io.opentelemetry.sdk.resources.Resource; public class ResourceOrderedSecondComponentProvider @@ -23,7 +23,7 @@ public String getName() { } @Override - public Resource create(StructuredConfigProperties config) { + public Resource create(DeclarativeConfigProperties config) { return Resource.builder().put("order", "second").build(); } diff --git a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/component/SamplerComponentProvider.java b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/component/SamplerComponentProvider.java index 2d4c983e4d7..3264dd91fc7 100644 --- a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/component/SamplerComponentProvider.java +++ b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/component/SamplerComponentProvider.java @@ -6,10 +6,10 @@ package io.opentelemetry.sdk.extension.incubator.fileconfig.component; import io.opentelemetry.api.common.Attributes; +import io.opentelemetry.api.incubator.config.DeclarativeConfigProperties; import io.opentelemetry.api.trace.SpanKind; import io.opentelemetry.context.Context; import io.opentelemetry.sdk.autoconfigure.spi.internal.ComponentProvider; -import io.opentelemetry.sdk.autoconfigure.spi.internal.StructuredConfigProperties; import io.opentelemetry.sdk.trace.data.LinkData; import io.opentelemetry.sdk.trace.samplers.Sampler; import io.opentelemetry.sdk.trace.samplers.SamplingResult; @@ -27,15 +27,15 @@ public String getName() { } @Override - public Sampler create(StructuredConfigProperties config) { + public Sampler create(DeclarativeConfigProperties config) { return new TestSampler(config); } public static class TestSampler implements Sampler { - public final StructuredConfigProperties config; + public final DeclarativeConfigProperties config; - private TestSampler(StructuredConfigProperties config) { + private TestSampler(DeclarativeConfigProperties config) { this.config = config; } diff --git a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/component/SpanExporterComponentProvider.java b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/component/SpanExporterComponentProvider.java index f387454f0fd..ddaca3ca4b9 100644 --- a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/component/SpanExporterComponentProvider.java +++ b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/component/SpanExporterComponentProvider.java @@ -5,8 +5,8 @@ package io.opentelemetry.sdk.extension.incubator.fileconfig.component; +import io.opentelemetry.api.incubator.config.DeclarativeConfigProperties; import io.opentelemetry.sdk.autoconfigure.spi.internal.ComponentProvider; -import io.opentelemetry.sdk.autoconfigure.spi.internal.StructuredConfigProperties; import io.opentelemetry.sdk.common.CompletableResultCode; import io.opentelemetry.sdk.trace.data.SpanData; import io.opentelemetry.sdk.trace.export.SpanExporter; @@ -24,15 +24,15 @@ public String getName() { } @Override - public SpanExporter create(StructuredConfigProperties config) { + public SpanExporter create(DeclarativeConfigProperties config) { return new TestSpanExporter(config); } public static class TestSpanExporter implements SpanExporter { - public final StructuredConfigProperties config; + public final DeclarativeConfigProperties config; - private TestSpanExporter(StructuredConfigProperties config) { + private TestSpanExporter(DeclarativeConfigProperties config) { this.config = config; } diff --git a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/component/SpanProcessorComponentProvider.java b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/component/SpanProcessorComponentProvider.java index 7bfe0936cd9..3a1ddf9b13a 100644 --- a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/component/SpanProcessorComponentProvider.java +++ b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/component/SpanProcessorComponentProvider.java @@ -5,9 +5,9 @@ package io.opentelemetry.sdk.extension.incubator.fileconfig.component; +import io.opentelemetry.api.incubator.config.DeclarativeConfigProperties; import io.opentelemetry.context.Context; import io.opentelemetry.sdk.autoconfigure.spi.internal.ComponentProvider; -import io.opentelemetry.sdk.autoconfigure.spi.internal.StructuredConfigProperties; import io.opentelemetry.sdk.common.CompletableResultCode; import io.opentelemetry.sdk.trace.ReadWriteSpan; import io.opentelemetry.sdk.trace.ReadableSpan; @@ -25,15 +25,15 @@ public String getName() { } @Override - public SpanProcessor create(StructuredConfigProperties config) { + public SpanProcessor create(DeclarativeConfigProperties config) { return new TestSpanProcessor(config); } public static class TestSpanProcessor implements SpanProcessor { - public final StructuredConfigProperties config; + public final DeclarativeConfigProperties config; - private TestSpanProcessor(StructuredConfigProperties config) { + private TestSpanProcessor(DeclarativeConfigProperties config) { this.config = config; } diff --git a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/component/TextMapPropagatorComponentProvider.java b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/component/TextMapPropagatorComponentProvider.java index a3005beba4b..0ab454da8ad 100644 --- a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/component/TextMapPropagatorComponentProvider.java +++ b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/component/TextMapPropagatorComponentProvider.java @@ -5,12 +5,12 @@ package io.opentelemetry.sdk.extension.incubator.fileconfig.component; +import io.opentelemetry.api.incubator.config.DeclarativeConfigProperties; import io.opentelemetry.context.Context; import io.opentelemetry.context.propagation.TextMapGetter; import io.opentelemetry.context.propagation.TextMapPropagator; import io.opentelemetry.context.propagation.TextMapSetter; import io.opentelemetry.sdk.autoconfigure.spi.internal.ComponentProvider; -import io.opentelemetry.sdk.autoconfigure.spi.internal.StructuredConfigProperties; import java.util.Collection; import java.util.Collections; import javax.annotation.Nullable; @@ -27,15 +27,15 @@ public String getName() { } @Override - public TextMapPropagator create(StructuredConfigProperties config) { + public TextMapPropagator create(DeclarativeConfigProperties config) { return new TestTextMapPropagator(config); } public static class TestTextMapPropagator implements TextMapPropagator { - public final StructuredConfigProperties config; + public final DeclarativeConfigProperties config; - private TestTextMapPropagator(StructuredConfigProperties config) { + private TestTextMapPropagator(DeclarativeConfigProperties config) { this.config = config; } diff --git a/sdk-extensions/jaeger-remote-sampler/build.gradle.kts b/sdk-extensions/jaeger-remote-sampler/build.gradle.kts index ac250eef3d1..32b51d6065d 100644 --- a/sdk-extensions/jaeger-remote-sampler/build.gradle.kts +++ b/sdk-extensions/jaeger-remote-sampler/build.gradle.kts @@ -12,6 +12,7 @@ otelJava.moduleName.set("io.opentelemetry.sdk.extension.trace.jaeger") dependencies { api(project(":sdk:all")) + compileOnly(project(":api:incubator")) compileOnly(project(":sdk-extensions:autoconfigure")) compileOnly(project(":sdk-extensions:incubator")) diff --git a/sdk-extensions/jaeger-remote-sampler/src/main/java/io/opentelemetry/sdk/extension/trace/jaeger/sampler/internal/JaegerRemoteSamplerComponentProvider.java b/sdk-extensions/jaeger-remote-sampler/src/main/java/io/opentelemetry/sdk/extension/trace/jaeger/sampler/internal/JaegerRemoteSamplerComponentProvider.java index 9ce99c908b2..fd89f42cae9 100644 --- a/sdk-extensions/jaeger-remote-sampler/src/main/java/io/opentelemetry/sdk/extension/trace/jaeger/sampler/internal/JaegerRemoteSamplerComponentProvider.java +++ b/sdk-extensions/jaeger-remote-sampler/src/main/java/io/opentelemetry/sdk/extension/trace/jaeger/sampler/internal/JaegerRemoteSamplerComponentProvider.java @@ -5,9 +5,9 @@ package io.opentelemetry.sdk.extension.trace.jaeger.sampler.internal; +import io.opentelemetry.api.incubator.config.DeclarativeConfigProperties; import io.opentelemetry.sdk.autoconfigure.spi.internal.ComponentProvider; -import io.opentelemetry.sdk.autoconfigure.spi.internal.StructuredConfigProperties; -import io.opentelemetry.sdk.extension.incubator.fileconfig.FileConfiguration; +import io.opentelemetry.sdk.extension.incubator.fileconfig.DeclarativeConfiguration; import io.opentelemetry.sdk.extension.trace.jaeger.sampler.JaegerRemoteSampler; import io.opentelemetry.sdk.extension.trace.jaeger.sampler.JaegerRemoteSamplerBuilder; import io.opentelemetry.sdk.trace.samplers.Sampler; @@ -31,7 +31,7 @@ public String getName() { } @Override - public Sampler create(StructuredConfigProperties config) { + public Sampler create(DeclarativeConfigProperties config) { JaegerRemoteSamplerBuilder builder = JaegerRemoteSampler.builder(); // Optional configuration @@ -43,9 +43,9 @@ public Sampler create(StructuredConfigProperties config) { if (pollingIntervalMs != null) { builder.setPollingInterval(Duration.ofMillis(pollingIntervalMs)); } - StructuredConfigProperties initialSamplerModel = config.getStructured("initial_sampler"); + DeclarativeConfigProperties initialSamplerModel = config.getStructured("initial_sampler"); if (initialSamplerModel != null) { - Sampler initialSampler = FileConfiguration.createSampler(initialSamplerModel); + Sampler initialSampler = DeclarativeConfiguration.createSampler(initialSamplerModel); builder.setInitialSampler(initialSampler); } From 1b1d5373758f1fbcc3e5dc74b70bb2cd9b2c32fd Mon Sep 17 00:00:00 2001 From: chukun Date: Wed, 5 Mar 2025 10:50:22 -0500 Subject: [PATCH 858/901] Reduce warning log about maxExportBatchSize. (#7148) --- .../logs/export/BatchLogRecordProcessorBuilder.java | 11 ++++------- .../sdk/trace/export/BatchSpanProcessorBuilder.java | 11 ++++------- 2 files changed, 8 insertions(+), 14 deletions(-) diff --git a/sdk/logs/src/main/java/io/opentelemetry/sdk/logs/export/BatchLogRecordProcessorBuilder.java b/sdk/logs/src/main/java/io/opentelemetry/sdk/logs/export/BatchLogRecordProcessorBuilder.java index e809acb951a..5e17848c774 100644 --- a/sdk/logs/src/main/java/io/opentelemetry/sdk/logs/export/BatchLogRecordProcessorBuilder.java +++ b/sdk/logs/src/main/java/io/opentelemetry/sdk/logs/export/BatchLogRecordProcessorBuilder.java @@ -107,9 +107,6 @@ long getExporterTimeoutNanos() { */ public BatchLogRecordProcessorBuilder setMaxQueueSize(int maxQueueSize) { checkArgument(maxQueueSize > 0, "maxQueueSize must be positive."); - if (maxExportBatchSize > maxQueueSize) { - logger.log(Level.WARNING, "maxExportBatchSize should not exceed maxQueueSize."); - } this.maxQueueSize = maxQueueSize; return this; } @@ -131,9 +128,6 @@ int getMaxQueueSize() { */ public BatchLogRecordProcessorBuilder setMaxExportBatchSize(int maxExportBatchSize) { checkArgument(maxExportBatchSize > 0, "maxExportBatchSize must be positive."); - if (maxExportBatchSize > maxQueueSize) { - logger.log(Level.WARNING, "maxExportBatchSize should not exceed maxQueueSize."); - } this.maxExportBatchSize = maxExportBatchSize; return this; } @@ -161,8 +155,11 @@ int getMaxExportBatchSize() { */ public BatchLogRecordProcessor build() { if (maxExportBatchSize > maxQueueSize) { + logger.log( + Level.WARNING, + "maxExportBatchSize should not exceed maxQueueSize. Setting maxExportBatchSize to {0} instead of {1}", + new Object[] {maxQueueSize, maxExportBatchSize}); maxExportBatchSize = maxQueueSize; - logger.log(Level.FINE, "Using maxExportBatchSize: {0}", maxExportBatchSize); } return new BatchLogRecordProcessor( logRecordExporter, diff --git a/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/export/BatchSpanProcessorBuilder.java b/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/export/BatchSpanProcessorBuilder.java index f968e35594a..d89083ded06 100644 --- a/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/export/BatchSpanProcessorBuilder.java +++ b/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/export/BatchSpanProcessorBuilder.java @@ -114,9 +114,6 @@ long getExporterTimeoutNanos() { */ public BatchSpanProcessorBuilder setMaxQueueSize(int maxQueueSize) { checkArgument(maxQueueSize > 0, "maxQueueSize must be positive."); - if (maxExportBatchSize > maxQueueSize) { - logger.log(Level.WARNING, "maxExportBatchSize should not exceed maxQueueSize."); - } this.maxQueueSize = maxQueueSize; return this; } @@ -138,9 +135,6 @@ int getMaxQueueSize() { */ public BatchSpanProcessorBuilder setMaxExportBatchSize(int maxExportBatchSize) { checkArgument(maxExportBatchSize > 0, "maxExportBatchSize must be positive."); - if (maxExportBatchSize > maxQueueSize) { - logger.log(Level.WARNING, "maxExportBatchSize should not exceed maxQueueSize."); - } this.maxExportBatchSize = maxExportBatchSize; return this; } @@ -168,8 +162,11 @@ int getMaxExportBatchSize() { */ public BatchSpanProcessor build() { if (maxExportBatchSize > maxQueueSize) { + logger.log( + Level.WARNING, + "maxExportBatchSize should not exceed maxQueueSize. Setting maxExportBatchSize to {0} instead of {1}", + new Object[] {maxQueueSize, maxExportBatchSize}); maxExportBatchSize = maxQueueSize; - logger.log(Level.FINE, "Using maxExportBatchSize: {0}", maxExportBatchSize); } return new BatchSpanProcessor( spanExporter, From 0de9fc084d80f5ca7040b5eba950f0d1ede0a5ed Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 5 Mar 2025 09:50:44 -0600 Subject: [PATCH 859/901] fix(deps): update armeriaversion to v1.32.0 (#7174) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- dependencyManagement/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index 6a797f26267..89356df3ccc 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -36,7 +36,7 @@ val slf4jVersion = "2.0.17" val opencensusVersion = "0.31.1" val prometheusClientVersion = "0.16.0" val prometheusServerVersion = "1.3.6" -val armeriaVersion = "1.31.3" +val armeriaVersion = "1.32.0" val junitVersion = "5.12.0" val DEPENDENCIES = listOf( From 4d34b53e0c8c369c30613b6e2cd3fff1dfddebe3 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 5 Mar 2025 09:51:29 -0600 Subject: [PATCH 860/901] fix(deps): update dependency com.squareup.wire:wire-bom to v5.3.1 (#7177) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- buildSrc/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts index c56c4943f19..4d7a859c9cf 100644 --- a/buildSrc/build.gradle.kts +++ b/buildSrc/build.gradle.kts @@ -50,7 +50,7 @@ repositories { } dependencies { - implementation(enforcedPlatform("com.squareup.wire:wire-bom:5.3.0")) + implementation(enforcedPlatform("com.squareup.wire:wire-bom:5.3.1")) implementation("com.google.auto.value:auto-value-annotations:1.11.0") // When updating, update above in plugins too implementation("com.diffplug.spotless:spotless-plugin-gradle:7.0.2") From 8efade69a16f86164d52a9b9699620fc254ce772 Mon Sep 17 00:00:00 2001 From: jack-berg <34418638+jack-berg@users.noreply.github.com> Date: Thu, 6 Mar 2025 11:57:46 -0600 Subject: [PATCH 861/901] Extract sender parameters to config carrier class (#7151) --- .../internal/grpc/GrpcExporterBuilder.java | 23 ++--- .../internal/grpc/GrpcSenderConfig.java | 85 +++++++++++++++++++ .../internal/grpc/GrpcSenderProvider.java | 27 +----- .../internal/http/HttpExporterBuilder.java | 23 ++--- .../internal/http/HttpSenderConfig.java | 81 ++++++++++++++++++ .../internal/http/HttpSenderProvider.java | 26 +----- .../internal/UpstreamGrpcSenderProvider.java | 35 +++----- .../jdk/internal/JdkHttpSenderProvider.java | 43 +++------- .../internal/OkHttpGrpcSenderProvider.java | 42 +++------ .../internal/OkHttpHttpSenderProvider.java | 45 +++------- 10 files changed, 242 insertions(+), 188 deletions(-) create mode 100644 exporters/common/src/main/java/io/opentelemetry/exporter/internal/grpc/GrpcSenderConfig.java create mode 100644 exporters/common/src/main/java/io/opentelemetry/exporter/internal/http/HttpSenderConfig.java diff --git a/exporters/common/src/main/java/io/opentelemetry/exporter/internal/grpc/GrpcExporterBuilder.java b/exporters/common/src/main/java/io/opentelemetry/exporter/internal/grpc/GrpcExporterBuilder.java index 1720b0e417b..9af2b47cf6e 100644 --- a/exporters/common/src/main/java/io/opentelemetry/exporter/internal/grpc/GrpcExporterBuilder.java +++ b/exporters/common/src/main/java/io/opentelemetry/exporter/internal/grpc/GrpcExporterBuilder.java @@ -205,17 +205,18 @@ public GrpcExporter build() { GrpcSenderProvider grpcSenderProvider = resolveGrpcSenderProvider(); GrpcSender grpcSender = grpcSenderProvider.createSender( - endpoint, - grpcEndpointPath, - compressor, - timeoutNanos, - connectTimeoutNanos, - headerSupplier, - grpcChannel, - grpcStubFactory, - retryPolicy, - isPlainHttp ? null : tlsConfigHelper.getSslContext(), - isPlainHttp ? null : tlsConfigHelper.getTrustManager()); + GrpcSenderConfig.create( + endpoint, + grpcEndpointPath, + compressor, + timeoutNanos, + connectTimeoutNanos, + headerSupplier, + grpcChannel, + grpcStubFactory, + retryPolicy, + isPlainHttp ? null : tlsConfigHelper.getSslContext(), + isPlainHttp ? null : tlsConfigHelper.getTrustManager())); LOGGER.log(Level.FINE, "Using GrpcSender: " + grpcSender.getClass().getName()); return new GrpcExporter<>(exporterName, type, grpcSender, meterProviderSupplier); diff --git a/exporters/common/src/main/java/io/opentelemetry/exporter/internal/grpc/GrpcSenderConfig.java b/exporters/common/src/main/java/io/opentelemetry/exporter/internal/grpc/GrpcSenderConfig.java new file mode 100644 index 00000000000..1685961f41e --- /dev/null +++ b/exporters/common/src/main/java/io/opentelemetry/exporter/internal/grpc/GrpcSenderConfig.java @@ -0,0 +1,85 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.exporter.internal.grpc; + +import com.google.auto.value.AutoValue; +import io.grpc.Channel; +import io.opentelemetry.exporter.internal.compression.Compressor; +import io.opentelemetry.exporter.internal.marshal.Marshaler; +import io.opentelemetry.sdk.common.export.RetryPolicy; +import java.net.URI; +import java.util.List; +import java.util.Map; +import java.util.function.BiFunction; +import java.util.function.Supplier; +import javax.annotation.Nullable; +import javax.annotation.concurrent.Immutable; +import javax.net.ssl.SSLContext; +import javax.net.ssl.X509TrustManager; + +/** + * This class is internal and is hence not for public use. Its APIs are unstable and can change at + * any time. + */ +@AutoValue +@Immutable +public abstract class GrpcSenderConfig { + + @SuppressWarnings("TooManyParameters") + public static GrpcSenderConfig create( + URI endpoint, + String endpointPath, + @Nullable Compressor compressor, + long timeoutNanos, + long connectTimeoutNanos, + Supplier>> headersSupplier, + @Nullable Object managedChannel, + Supplier>> stubFactory, + @Nullable RetryPolicy retryPolicy, + @Nullable SSLContext sslContext, + @Nullable X509TrustManager trustManager) { + return new AutoValue_GrpcSenderConfig<>( + endpoint, + endpointPath, + compressor, + timeoutNanos, + connectTimeoutNanos, + headersSupplier, + managedChannel, + stubFactory, + retryPolicy, + sslContext, + trustManager); + } + + public abstract URI getEndpoint(); + + public abstract String getEndpointPath(); + + @Nullable + public abstract Compressor getCompressor(); + + public abstract long getTimeoutNanos(); + + public abstract long getConnectTimeoutNanos(); + + public abstract Supplier>> getHeadersSupplier(); + + @Nullable + public abstract Object getManagedChannel(); + + public abstract Supplier>> + getStubFactory(); + + @Nullable + public abstract RetryPolicy getRetryPolicy(); + + @Nullable + public abstract SSLContext getSslContext(); + + @Nullable + public abstract X509TrustManager getTrustManager(); +} diff --git a/exporters/common/src/main/java/io/opentelemetry/exporter/internal/grpc/GrpcSenderProvider.java b/exporters/common/src/main/java/io/opentelemetry/exporter/internal/grpc/GrpcSenderProvider.java index 48f0e927d26..5b2883cf066 100644 --- a/exporters/common/src/main/java/io/opentelemetry/exporter/internal/grpc/GrpcSenderProvider.java +++ b/exporters/common/src/main/java/io/opentelemetry/exporter/internal/grpc/GrpcSenderProvider.java @@ -5,18 +5,7 @@ package io.opentelemetry.exporter.internal.grpc; -import io.grpc.Channel; -import io.opentelemetry.exporter.internal.compression.Compressor; import io.opentelemetry.exporter.internal.marshal.Marshaler; -import io.opentelemetry.sdk.common.export.RetryPolicy; -import java.net.URI; -import java.util.List; -import java.util.Map; -import java.util.function.BiFunction; -import java.util.function.Supplier; -import javax.annotation.Nullable; -import javax.net.ssl.SSLContext; -import javax.net.ssl.X509TrustManager; /** * A service provider interface (SPI) for providing {@link GrpcSender}s backed by different client @@ -27,18 +16,6 @@ */ public interface GrpcSenderProvider { - /** Returns a {@link GrpcSender} configured with the provided parameters. */ - @SuppressWarnings("TooManyParameters") - GrpcSender createSender( - URI endpoint, - String endpointPath, - @Nullable Compressor compressor, - long timeoutNanos, - long connectTimeoutNanos, - Supplier>> headersSupplier, - @Nullable Object managedChannel, - Supplier>> stubFactory, - @Nullable RetryPolicy retryPolicy, - @Nullable SSLContext sslContext, - @Nullable X509TrustManager trustManager); + /** Returns a {@link GrpcSender} configured with the provided config. */ + GrpcSender createSender(GrpcSenderConfig grpcSenderConfig); } diff --git a/exporters/common/src/main/java/io/opentelemetry/exporter/internal/http/HttpExporterBuilder.java b/exporters/common/src/main/java/io/opentelemetry/exporter/internal/http/HttpExporterBuilder.java index f38450ca6e8..3091408af58 100644 --- a/exporters/common/src/main/java/io/opentelemetry/exporter/internal/http/HttpExporterBuilder.java +++ b/exporters/common/src/main/java/io/opentelemetry/exporter/internal/http/HttpExporterBuilder.java @@ -187,17 +187,18 @@ public HttpExporter build() { HttpSenderProvider httpSenderProvider = resolveHttpSenderProvider(); HttpSender httpSender = httpSenderProvider.createSender( - endpoint, - compressor, - exportAsJson, - exportAsJson ? "application/json" : "application/x-protobuf", - timeoutNanos, - connectTimeoutNanos, - headerSupplier, - proxyOptions, - retryPolicy, - isPlainHttp ? null : tlsConfigHelper.getSslContext(), - isPlainHttp ? null : tlsConfigHelper.getTrustManager()); + HttpSenderConfig.create( + endpoint, + compressor, + exportAsJson, + exportAsJson ? "application/json" : "application/x-protobuf", + timeoutNanos, + connectTimeoutNanos, + headerSupplier, + proxyOptions, + retryPolicy, + isPlainHttp ? null : tlsConfigHelper.getSslContext(), + isPlainHttp ? null : tlsConfigHelper.getTrustManager())); LOGGER.log(Level.FINE, "Using HttpSender: " + httpSender.getClass().getName()); return new HttpExporter<>(exporterName, type, httpSender, meterProviderSupplier, exportAsJson); diff --git a/exporters/common/src/main/java/io/opentelemetry/exporter/internal/http/HttpSenderConfig.java b/exporters/common/src/main/java/io/opentelemetry/exporter/internal/http/HttpSenderConfig.java new file mode 100644 index 00000000000..03b50a44848 --- /dev/null +++ b/exporters/common/src/main/java/io/opentelemetry/exporter/internal/http/HttpSenderConfig.java @@ -0,0 +1,81 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.exporter.internal.http; + +import com.google.auto.value.AutoValue; +import io.opentelemetry.exporter.internal.compression.Compressor; +import io.opentelemetry.sdk.common.export.ProxyOptions; +import io.opentelemetry.sdk.common.export.RetryPolicy; +import java.util.List; +import java.util.Map; +import java.util.function.Supplier; +import javax.annotation.Nullable; +import javax.annotation.concurrent.Immutable; +import javax.net.ssl.SSLContext; +import javax.net.ssl.X509TrustManager; + +/** + * This class is internal and is hence not for public use. Its APIs are unstable and can change at + * any time. + */ +@AutoValue +@Immutable +public abstract class HttpSenderConfig { + + @SuppressWarnings("TooManyParameters") + public static HttpSenderConfig create( + String endpoint, + @Nullable Compressor compressor, + boolean exportAsJson, + String contentType, + long timeoutNanos, + long connectTimeoutNanos, + Supplier>> headerSupplier, + @Nullable ProxyOptions proxyOptions, + @Nullable RetryPolicy retryPolicy, + @Nullable SSLContext sslContext, + @Nullable X509TrustManager trustManager) { + return new AutoValue_HttpSenderConfig( + endpoint, + compressor, + exportAsJson, + contentType, + timeoutNanos, + connectTimeoutNanos, + headerSupplier, + proxyOptions, + retryPolicy, + sslContext, + trustManager); + } + + public abstract String getEndpoint(); + + @Nullable + public abstract Compressor getCompressor(); + + public abstract boolean getExportAsJson(); + + public abstract String getContentType(); + + public abstract long getTimeoutNanos(); + + public abstract long getConnectTimeoutNanos(); + + public abstract Supplier>> getHeadersSupplier(); + + @Nullable + public abstract ProxyOptions getProxyOptions(); + + @Nullable + public abstract RetryPolicy getRetryPolicy(); + + @Nullable + public abstract SSLContext getSslContext(); + + @Nullable + public abstract X509TrustManager getTrustManager(); +} diff --git a/exporters/common/src/main/java/io/opentelemetry/exporter/internal/http/HttpSenderProvider.java b/exporters/common/src/main/java/io/opentelemetry/exporter/internal/http/HttpSenderProvider.java index 651343beaed..10563f5a00d 100644 --- a/exporters/common/src/main/java/io/opentelemetry/exporter/internal/http/HttpSenderProvider.java +++ b/exporters/common/src/main/java/io/opentelemetry/exporter/internal/http/HttpSenderProvider.java @@ -5,16 +5,6 @@ package io.opentelemetry.exporter.internal.http; -import io.opentelemetry.exporter.internal.compression.Compressor; -import io.opentelemetry.sdk.common.export.ProxyOptions; -import io.opentelemetry.sdk.common.export.RetryPolicy; -import java.util.List; -import java.util.Map; -import java.util.function.Supplier; -import javax.annotation.Nullable; -import javax.net.ssl.SSLContext; -import javax.net.ssl.X509TrustManager; - /** * A service provider interface (SPI) for providing {@link HttpSender}s backed by different HTTP * client libraries. @@ -24,18 +14,6 @@ */ public interface HttpSenderProvider { - /** Returns a {@link HttpSender} configured with the provided parameters. */ - @SuppressWarnings("TooManyParameters") - HttpSender createSender( - String endpoint, - @Nullable Compressor compressor, - boolean exportAsJson, - String contentType, - long timeoutNanos, - long connectTimeout, - Supplier>> headerSupplier, - @Nullable ProxyOptions proxyOptions, - @Nullable RetryPolicy retryPolicy, - @Nullable SSLContext sslContext, - @Nullable X509TrustManager trustManager); + /** Returns a {@link HttpSender} configured with the provided config. */ + HttpSender createSender(HttpSenderConfig httpSenderConfig); } diff --git a/exporters/sender/grpc-managed-channel/src/main/java/io/opentelemetry/exporter/sender/grpc/managedchannel/internal/UpstreamGrpcSenderProvider.java b/exporters/sender/grpc-managed-channel/src/main/java/io/opentelemetry/exporter/sender/grpc/managedchannel/internal/UpstreamGrpcSenderProvider.java index d07bc4ed614..c2c7cb3d85c 100644 --- a/exporters/sender/grpc-managed-channel/src/main/java/io/opentelemetry/exporter/sender/grpc/managedchannel/internal/UpstreamGrpcSenderProvider.java +++ b/exporters/sender/grpc-managed-channel/src/main/java/io/opentelemetry/exporter/sender/grpc/managedchannel/internal/UpstreamGrpcSenderProvider.java @@ -12,20 +12,15 @@ import io.grpc.ManagedChannelBuilder; import io.opentelemetry.exporter.internal.compression.Compressor; import io.opentelemetry.exporter.internal.grpc.GrpcSender; +import io.opentelemetry.exporter.internal.grpc.GrpcSenderConfig; import io.opentelemetry.exporter.internal.grpc.GrpcSenderProvider; import io.opentelemetry.exporter.internal.grpc.MarshalerServiceStub; import io.opentelemetry.exporter.internal.marshal.Marshaler; -import io.opentelemetry.sdk.common.export.RetryPolicy; import java.io.IOException; import java.io.OutputStream; import java.net.URI; import java.util.List; import java.util.Map; -import java.util.function.BiFunction; -import java.util.function.Supplier; -import javax.annotation.Nullable; -import javax.net.ssl.SSLContext; -import javax.net.ssl.X509TrustManager; /** * {@link GrpcSender} SPI implementation for {@link UpstreamGrpcSender}. @@ -36,27 +31,17 @@ public class UpstreamGrpcSenderProvider implements GrpcSenderProvider { @Override - public GrpcSender createSender( - URI endpoint, - String endpointPath, - @Nullable Compressor compressor, - long timeoutNanos, - long connectTimeoutNanos, - Supplier>> headersSupplier, - @Nullable Object managedChannel, - Supplier>> stubFactory, - @Nullable RetryPolicy retryPolicy, - @Nullable SSLContext sslContext, - @Nullable X509TrustManager trustManager) { + public GrpcSender createSender(GrpcSenderConfig grpcSenderConfig) { boolean shutdownChannel = false; + Object managedChannel = grpcSenderConfig.getManagedChannel(); if (managedChannel == null) { // Shutdown the channel as part of the exporter shutdown sequence if shutdownChannel = true; - managedChannel = minimalFallbackManagedChannel(endpoint); + managedChannel = minimalFallbackManagedChannel(grpcSenderConfig.getEndpoint()); } String authorityOverride = null; - Map> headers = headersSupplier.get(); + Map> headers = grpcSenderConfig.getHeadersSupplier().get(); if (headers != null) { for (Map.Entry> entry : headers.entrySet()) { if (entry.getKey().equals("host") && !entry.getValue().isEmpty()) { @@ -66,6 +51,7 @@ public GrpcSender createSender( } String compression = Codec.Identity.NONE.getMessageEncoding(); + Compressor compressor = grpcSenderConfig.getCompressor(); if (compressor != null) { CompressorRegistry.getDefaultInstance() .register( @@ -84,12 +70,17 @@ public OutputStream compress(OutputStream os) throws IOException { } MarshalerServiceStub stub = - stubFactory + grpcSenderConfig + .getStubFactory() .get() .apply((Channel) managedChannel, authorityOverride) .withCompression(compression); - return new UpstreamGrpcSender<>(stub, shutdownChannel, timeoutNanos, headersSupplier); + return new UpstreamGrpcSender<>( + stub, + shutdownChannel, + grpcSenderConfig.getTimeoutNanos(), + grpcSenderConfig.getHeadersSupplier()); } /** diff --git a/exporters/sender/jdk/src/main/java/io/opentelemetry/exporter/sender/jdk/internal/JdkHttpSenderProvider.java b/exporters/sender/jdk/src/main/java/io/opentelemetry/exporter/sender/jdk/internal/JdkHttpSenderProvider.java index f5905599183..4cf4f26a2a1 100644 --- a/exporters/sender/jdk/src/main/java/io/opentelemetry/exporter/sender/jdk/internal/JdkHttpSenderProvider.java +++ b/exporters/sender/jdk/src/main/java/io/opentelemetry/exporter/sender/jdk/internal/JdkHttpSenderProvider.java @@ -5,17 +5,9 @@ package io.opentelemetry.exporter.sender.jdk.internal; -import io.opentelemetry.exporter.internal.compression.Compressor; import io.opentelemetry.exporter.internal.http.HttpSender; +import io.opentelemetry.exporter.internal.http.HttpSenderConfig; import io.opentelemetry.exporter.internal.http.HttpSenderProvider; -import io.opentelemetry.sdk.common.export.ProxyOptions; -import io.opentelemetry.sdk.common.export.RetryPolicy; -import java.util.List; -import java.util.Map; -import java.util.function.Supplier; -import javax.annotation.Nullable; -import javax.net.ssl.SSLContext; -import javax.net.ssl.X509TrustManager; /** * {@link HttpSender} SPI implementation for {@link JdkHttpSender}. @@ -26,28 +18,17 @@ public final class JdkHttpSenderProvider implements HttpSenderProvider { @Override - public HttpSender createSender( - String endpoint, - @Nullable Compressor compressor, - boolean exportAsJson, - String contentType, - long timeoutNanos, - long connectTimeout, - Supplier>> headerSupplier, - @Nullable ProxyOptions proxyOptions, - @Nullable RetryPolicy retryPolicy, - @Nullable SSLContext sslContext, - @Nullable X509TrustManager trustManager) { + public HttpSender createSender(HttpSenderConfig httpSenderConfig) { return new JdkHttpSender( - endpoint, - compressor, - exportAsJson, - contentType, - timeoutNanos, - connectTimeout, - headerSupplier, - retryPolicy, - proxyOptions, - sslContext); + httpSenderConfig.getEndpoint(), + httpSenderConfig.getCompressor(), + httpSenderConfig.getExportAsJson(), + httpSenderConfig.getContentType(), + httpSenderConfig.getTimeoutNanos(), + httpSenderConfig.getConnectTimeoutNanos(), + httpSenderConfig.getHeadersSupplier(), + httpSenderConfig.getRetryPolicy(), + httpSenderConfig.getProxyOptions(), + httpSenderConfig.getSslContext()); } } diff --git a/exporters/sender/okhttp/src/main/java/io/opentelemetry/exporter/sender/okhttp/internal/OkHttpGrpcSenderProvider.java b/exporters/sender/okhttp/src/main/java/io/opentelemetry/exporter/sender/okhttp/internal/OkHttpGrpcSenderProvider.java index b6595ee2866..c87f2739b4c 100644 --- a/exporters/sender/okhttp/src/main/java/io/opentelemetry/exporter/sender/okhttp/internal/OkHttpGrpcSenderProvider.java +++ b/exporters/sender/okhttp/src/main/java/io/opentelemetry/exporter/sender/okhttp/internal/OkHttpGrpcSenderProvider.java @@ -5,21 +5,10 @@ package io.opentelemetry.exporter.sender.okhttp.internal; -import io.grpc.Channel; -import io.opentelemetry.exporter.internal.compression.Compressor; import io.opentelemetry.exporter.internal.grpc.GrpcSender; +import io.opentelemetry.exporter.internal.grpc.GrpcSenderConfig; import io.opentelemetry.exporter.internal.grpc.GrpcSenderProvider; -import io.opentelemetry.exporter.internal.grpc.MarshalerServiceStub; import io.opentelemetry.exporter.internal.marshal.Marshaler; -import io.opentelemetry.sdk.common.export.RetryPolicy; -import java.net.URI; -import java.util.List; -import java.util.Map; -import java.util.function.BiFunction; -import java.util.function.Supplier; -import javax.net.ssl.SSLContext; -import javax.net.ssl.X509TrustManager; -import org.jetbrains.annotations.Nullable; /** * {@link GrpcSender} SPI implementation for {@link OkHttpGrpcSender}. @@ -30,26 +19,15 @@ public class OkHttpGrpcSenderProvider implements GrpcSenderProvider { @Override - public GrpcSender createSender( - URI endpoint, - String endpointPath, - @Nullable Compressor compressor, - long timeoutNanos, - long connectTimeoutNanos, - Supplier>> headersSupplier, - @Nullable Object managedChannel, - Supplier>> stubFactory, - @Nullable RetryPolicy retryPolicy, - @Nullable SSLContext sslContext, - @Nullable X509TrustManager trustManager) { + public GrpcSender createSender(GrpcSenderConfig grpcSenderConfig) { return new OkHttpGrpcSender<>( - endpoint.resolve(endpointPath).toString(), - compressor, - timeoutNanos, - connectTimeoutNanos, - headersSupplier, - retryPolicy, - sslContext, - trustManager); + grpcSenderConfig.getEndpoint().resolve(grpcSenderConfig.getEndpointPath()).toString(), + grpcSenderConfig.getCompressor(), + grpcSenderConfig.getTimeoutNanos(), + grpcSenderConfig.getConnectTimeoutNanos(), + grpcSenderConfig.getHeadersSupplier(), + grpcSenderConfig.getRetryPolicy(), + grpcSenderConfig.getSslContext(), + grpcSenderConfig.getTrustManager()); } } diff --git a/exporters/sender/okhttp/src/main/java/io/opentelemetry/exporter/sender/okhttp/internal/OkHttpHttpSenderProvider.java b/exporters/sender/okhttp/src/main/java/io/opentelemetry/exporter/sender/okhttp/internal/OkHttpHttpSenderProvider.java index f5036a21271..989f3644506 100644 --- a/exporters/sender/okhttp/src/main/java/io/opentelemetry/exporter/sender/okhttp/internal/OkHttpHttpSenderProvider.java +++ b/exporters/sender/okhttp/src/main/java/io/opentelemetry/exporter/sender/okhttp/internal/OkHttpHttpSenderProvider.java @@ -5,17 +5,9 @@ package io.opentelemetry.exporter.sender.okhttp.internal; -import io.opentelemetry.exporter.internal.compression.Compressor; import io.opentelemetry.exporter.internal.http.HttpSender; +import io.opentelemetry.exporter.internal.http.HttpSenderConfig; import io.opentelemetry.exporter.internal.http.HttpSenderProvider; -import io.opentelemetry.sdk.common.export.ProxyOptions; -import io.opentelemetry.sdk.common.export.RetryPolicy; -import java.util.List; -import java.util.Map; -import java.util.function.Supplier; -import javax.net.ssl.SSLContext; -import javax.net.ssl.X509TrustManager; -import org.jetbrains.annotations.Nullable; /** * {@link HttpSender} SPI implementation for {@link OkHttpHttpSender}. @@ -26,29 +18,18 @@ public final class OkHttpHttpSenderProvider implements HttpSenderProvider { @Override - public HttpSender createSender( - String endpoint, - @Nullable Compressor compressor, - boolean exportAsJson, - String contentType, - long timeoutNanos, - long connectTimeout, - Supplier>> headerSupplier, - @Nullable ProxyOptions proxyOptions, - @Nullable RetryPolicy retryPolicy, - @Nullable SSLContext sslContext, - @Nullable X509TrustManager trustManager) { + public HttpSender createSender(HttpSenderConfig httpSenderConfig) { return new OkHttpHttpSender( - endpoint, - compressor, - exportAsJson, - contentType, - timeoutNanos, - connectTimeout, - headerSupplier, - proxyOptions, - retryPolicy, - sslContext, - trustManager); + httpSenderConfig.getEndpoint(), + httpSenderConfig.getCompressor(), + httpSenderConfig.getExportAsJson(), + httpSenderConfig.getContentType(), + httpSenderConfig.getTimeoutNanos(), + httpSenderConfig.getConnectTimeoutNanos(), + httpSenderConfig.getHeadersSupplier(), + httpSenderConfig.getProxyOptions(), + httpSenderConfig.getRetryPolicy(), + httpSenderConfig.getSslContext(), + httpSenderConfig.getTrustManager()); } } From 2e4f9ede58234676005eba11d8f9047d63d6c918 Mon Sep 17 00:00:00 2001 From: jack-berg <34418638+jack-berg@users.noreply.github.com> Date: Fri, 7 Mar 2025 10:03:15 -0600 Subject: [PATCH 862/901] Prepare for 1.48.0 release (#7183) Co-authored-by: Trask Stalnaker --- CHANGELOG.md | 47 +++++++++++++++++++ .../api/logs/LogRecordBuilder.java | 5 ++ .../OtlpHttpLogRecordExporterBuilder.java | 6 ++- .../OtlpHttpMetricExporterBuilder.java | 6 ++- .../trace/OtlpHttpSpanExporterBuilder.java | 6 ++- .../OtlpGrpcLogRecordExporterBuilder.java | 6 ++- .../OtlpGrpcMetricExporterBuilder.java | 6 ++- .../trace/OtlpGrpcSpanExporterBuilder.java | 6 ++- 8 files changed, 82 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index afc0b9d2509..04ba31e5290 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,53 @@ ## Unreleased +### API + +* Add some helpful logging attribute methods to `LogRecordBuilder` + ([#7089](https://github.com/open-telemetry/opentelemetry-java/pull/7089)) + +#### Incubator + +* Introduce ConfigProvider API. Rename `StructuredConfigProperties` to `DeclarativeConfigProperties` + and move to `opentelemetry-api-incubator`. Rename `FileConfiguration` + to `DeclarativeConfiguration`. + ([#6549](https://github.com/open-telemetry/opentelemetry-java/pull/6549)) + +### SDK + +* Log warning and adjust when BatchLogRecordProcessor, BatchSpanProcessor `maxExportBatchSize` + exceeds `maxQueueSize`. + ([#7045](https://github.com/open-telemetry/opentelemetry-java/pull/7045), + [#7148](https://github.com/open-telemetry/opentelemetry-java/pull/7148)) +* Fix bug causing `ThrottlingLogger` to log more than once per minute + ([#7156](https://github.com/open-telemetry/opentelemetry-java/pull/7156)) + +#### Metrics + +* Remove obsolete `SdkMeterProviderUtil#setCardinalitylimit` API + ([#7169](https://github.com/open-telemetry/opentelemetry-java/pull/7169)) + +#### Traces + +* Fix bug preventing accurate reporting of span event dropped attribute count + ([#7142](https://github.com/open-telemetry/opentelemetry-java/pull/7142)) + +#### Exporters + +* OTLP: remove support for `otel.java.experimental.exporter.memory_mode` + which was previously replaced by `otel.java.exporter.memory_mode` + ([#7127](https://github.com/open-telemetry/opentelemetry-java/pull/7127)) +* OTLP: Extract sender parameters to config carrier class + (incubating API) + ([#7151](https://github.com/open-telemetry/opentelemetry-java/pull/7151)) +* OTLP: Add support for setting OTLP exporter service class loader + ([#7150](https://github.com/open-telemetry/opentelemetry-java/pull/7150)) + +### Tooling + +* Update android animalsniffer min API version to 23 + ([#7153](https://github.com/open-telemetry/opentelemetry-java/pull/7153)) + ## Version 1.47.0 (2025-02-07) ### API diff --git a/api/all/src/main/java/io/opentelemetry/api/logs/LogRecordBuilder.java b/api/all/src/main/java/io/opentelemetry/api/logs/LogRecordBuilder.java index cc5da82c22e..9e071baed1d 100644 --- a/api/all/src/main/java/io/opentelemetry/api/logs/LogRecordBuilder.java +++ b/api/all/src/main/java/io/opentelemetry/api/logs/LogRecordBuilder.java @@ -123,6 +123,7 @@ default LogRecordBuilder setAllAttributes(Attributes attributes) { * @param key the key for this attribute. * @param value the value for this attribute. * @return this. + * @since 1.48.0 */ default LogRecordBuilder setAttribute(String key, String value) { return setAttribute(stringKey(key), value); @@ -138,6 +139,7 @@ default LogRecordBuilder setAttribute(String key, String value) { * @param key the key for this attribute. * @param value the value for this attribute. * @return this. + * @since 1.48.0 */ default LogRecordBuilder setAttribute(String key, long value) { return setAttribute(longKey(key), value); @@ -153,6 +155,7 @@ default LogRecordBuilder setAttribute(String key, long value) { * @param key the key for this attribute. * @param value the value for this attribute. * @return this. + * @since 1.48.0 */ default LogRecordBuilder setAttribute(String key, double value) { return setAttribute(doubleKey(key), value); @@ -168,6 +171,7 @@ default LogRecordBuilder setAttribute(String key, double value) { * @param key the key for this attribute. * @param value the value for this attribute. * @return this. + * @since 1.48.0 */ default LogRecordBuilder setAttribute(String key, boolean value) { return setAttribute(booleanKey(key), value); @@ -183,6 +187,7 @@ default LogRecordBuilder setAttribute(String key, boolean value) { * @param key the key for this attribute. * @param value the value for this attribute. * @return this. + * @since 1.48.0 */ default LogRecordBuilder setAttribute(String key, int value) { return setAttribute(key, (long) value); diff --git a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/logs/OtlpHttpLogRecordExporterBuilder.java b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/logs/OtlpHttpLogRecordExporterBuilder.java index 2b260643e4b..65f32ec406e 100644 --- a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/logs/OtlpHttpLogRecordExporterBuilder.java +++ b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/logs/OtlpHttpLogRecordExporterBuilder.java @@ -225,7 +225,11 @@ public OtlpHttpLogRecordExporterBuilder setMemoryMode(MemoryMode memoryMode) { return this; } - /** Set the {@link ClassLoader} used to load the sender API. */ + /** + * Set the {@link ClassLoader} used to load the sender API. + * + * @since 1.48.0 + */ public OtlpHttpLogRecordExporterBuilder setServiceClassLoader(ClassLoader serviceClassLoader) { requireNonNull(serviceClassLoader, "serviceClassLoader"); delegate.setServiceClassLoader(serviceClassLoader); diff --git a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/metrics/OtlpHttpMetricExporterBuilder.java b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/metrics/OtlpHttpMetricExporterBuilder.java index 36c0b0fc71a..7772d42bdf5 100644 --- a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/metrics/OtlpHttpMetricExporterBuilder.java +++ b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/metrics/OtlpHttpMetricExporterBuilder.java @@ -253,7 +253,11 @@ public OtlpHttpMetricExporterBuilder setMemoryMode(MemoryMode memoryMode) { return this; } - /** Set the {@link ClassLoader} used to load the sender API. */ + /** + * Set the {@link ClassLoader} used to load the sender API. + * + * @since 1.48.0 + */ public OtlpHttpMetricExporterBuilder setServiceClassLoader(ClassLoader serviceClassLoader) { requireNonNull(serviceClassLoader, "serviceClassLoader"); delegate.setServiceClassLoader(serviceClassLoader); diff --git a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/trace/OtlpHttpSpanExporterBuilder.java b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/trace/OtlpHttpSpanExporterBuilder.java index 88674f9230e..4a228ef0e5d 100644 --- a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/trace/OtlpHttpSpanExporterBuilder.java +++ b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/trace/OtlpHttpSpanExporterBuilder.java @@ -226,7 +226,11 @@ public OtlpHttpSpanExporterBuilder setMemoryMode(MemoryMode memoryMode) { return this; } - /** Set the {@link ClassLoader} used to load the sender API. */ + /** + * Set the {@link ClassLoader} used to load the sender API. + * + * @since 1.48.0 + */ public OtlpHttpSpanExporterBuilder setServiceClassLoader(ClassLoader serviceClassLoader) { requireNonNull(serviceClassLoader, "serviceClassLoader"); delegate.setServiceClassLoader(serviceClassLoader); diff --git a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/logs/OtlpGrpcLogRecordExporterBuilder.java b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/logs/OtlpGrpcLogRecordExporterBuilder.java index 6ff1999d47a..6a0c08d7e5c 100644 --- a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/logs/OtlpGrpcLogRecordExporterBuilder.java +++ b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/logs/OtlpGrpcLogRecordExporterBuilder.java @@ -258,7 +258,11 @@ public OtlpGrpcLogRecordExporterBuilder setMemoryMode(MemoryMode memoryMode) { return this; } - /** Set the {@link ClassLoader} used to load the sender API. */ + /** + * Set the {@link ClassLoader} used to load the sender API. + * + * @since 1.48.0 + */ public OtlpGrpcLogRecordExporterBuilder setServiceClassLoader(ClassLoader serviceClassLoader) { requireNonNull(serviceClassLoader, "serviceClassLoader"); delegate.setServiceClassLoader(serviceClassLoader); diff --git a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/metrics/OtlpGrpcMetricExporterBuilder.java b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/metrics/OtlpGrpcMetricExporterBuilder.java index 01d0f7b69ab..64aeb2995e1 100644 --- a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/metrics/OtlpGrpcMetricExporterBuilder.java +++ b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/metrics/OtlpGrpcMetricExporterBuilder.java @@ -286,7 +286,11 @@ public OtlpGrpcMetricExporterBuilder setMemoryMode(MemoryMode memoryMode) { return this; } - /** Set the {@link ClassLoader} used to load the sender API. */ + /** + * Set the {@link ClassLoader} used to load the sender API. + * + * @since 1.48.0 + */ public OtlpGrpcMetricExporterBuilder setServiceClassLoader(ClassLoader serviceClassLoader) { requireNonNull(serviceClassLoader, "serviceClassLoader"); delegate.setServiceClassLoader(serviceClassLoader); diff --git a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/trace/OtlpGrpcSpanExporterBuilder.java b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/trace/OtlpGrpcSpanExporterBuilder.java index f9c49eac104..22fb030d1a9 100644 --- a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/trace/OtlpGrpcSpanExporterBuilder.java +++ b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/trace/OtlpGrpcSpanExporterBuilder.java @@ -255,7 +255,11 @@ public OtlpGrpcSpanExporterBuilder setMemoryMode(MemoryMode memoryMode) { return this; } - /** Set the {@link ClassLoader} used to load the sender API. */ + /** + * Set the {@link ClassLoader} used to load the sender API. + * + * @since 1.48.0 + */ public OtlpGrpcSpanExporterBuilder setServiceClassLoader(ClassLoader serviceClassLoader) { requireNonNull(serviceClassLoader, "serviceClassLoader"); delegate.setServiceClassLoader(serviceClassLoader); From 974653fe667d20a268fae901ea0293241855ad65 Mon Sep 17 00:00:00 2001 From: OpenTelemetry Bot <107717825+opentelemetrybot@users.noreply.github.com> Date: Fri, 7 Mar 2025 14:47:00 -0800 Subject: [PATCH 863/901] Update version to 1.49.0 (#7186) --- CHANGELOG.md | 2 ++ version.gradle.kts | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 04ba31e5290..48869706d1a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,8 @@ ## Unreleased +## Version 1.48.0 (2025-03-07) + ### API * Add some helpful logging attribute methods to `LogRecordBuilder` diff --git a/version.gradle.kts b/version.gradle.kts index 030e95dd215..ea6092c8622 100644 --- a/version.gradle.kts +++ b/version.gradle.kts @@ -1,7 +1,7 @@ val snapshot = true allprojects { - var ver = "1.48.0" + var ver = "1.49.0" val release = findProperty("otel.release") if (release != null) { ver += "-" + release From 9d4f61ad0b0abfe90594d73d11bd328fead0dfca Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 10 Mar 2025 09:36:10 -0500 Subject: [PATCH 864/901] fix(deps): update dependency com.fasterxml.jackson:jackson-bom to v2.18.3 (#7162) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- dependencyManagement/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index 89356df3ccc..518a647c993 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -13,7 +13,7 @@ val DEPENDENCY_BOMS = listOf( // (which is EPL licensed) or armeria bom (which is Apache licensed but is getting flagged // by FOSSA for containing EPL-licensed) - "com.fasterxml.jackson:jackson-bom:2.18.2", + "com.fasterxml.jackson:jackson-bom:2.18.3", "com.google.guava:guava-bom:33.4.0-jre", "com.google.protobuf:protobuf-bom:4.29.3", "com.squareup.okhttp3:okhttp-bom:4.12.0", From 708244ec48ef8d742a00be9b546f46effc668c92 Mon Sep 17 00:00:00 2001 From: OpenTelemetry Bot <107717825+opentelemetrybot@users.noreply.github.com> Date: Mon, 10 Mar 2025 08:55:16 -0700 Subject: [PATCH 865/901] Post release for version 1.48.0 (#7190) --- README.md | 62 +++++++++---------- .../1.48.0_vs_1.47.0/opentelemetry-api.txt | 8 +++ .../opentelemetry-context.txt | 2 + .../opentelemetry-exporter-common.txt | 2 + .../opentelemetry-exporter-logging-otlp.txt | 2 + .../opentelemetry-exporter-logging.txt | 2 + .../opentelemetry-exporter-otlp-common.txt | 2 + .../opentelemetry-exporter-otlp.txt | 19 ++++++ ...y-exporter-sender-grpc-managed-channel.txt | 2 + .../opentelemetry-exporter-sender-jdk.txt | 2 + .../opentelemetry-exporter-sender-okhttp.txt | 2 + .../opentelemetry-exporter-zipkin.txt | 2 + .../opentelemetry-extension-kotlin.txt | 2 + ...ntelemetry-extension-trace-propagators.txt | 2 + .../opentelemetry-opentracing-shim.txt | 2 + .../opentelemetry-sdk-common.txt | 2 + ...emetry-sdk-extension-autoconfigure-spi.txt | 2 + ...ntelemetry-sdk-extension-autoconfigure.txt | 2 + ...ry-sdk-extension-jaeger-remote-sampler.txt | 2 + .../opentelemetry-sdk-logs.txt | 2 + .../opentelemetry-sdk-metrics.txt | 2 + .../opentelemetry-sdk-testing.txt | 2 + .../opentelemetry-sdk-trace.txt | 2 + .../1.48.0_vs_1.47.0/opentelemetry-sdk.txt | 2 + .../current_vs_latest/opentelemetry-api.txt | 10 +-- .../opentelemetry-context.txt | 2 +- .../opentelemetry-exporter-common.txt | 2 +- .../opentelemetry-exporter-logging-otlp.txt | 2 +- .../opentelemetry-exporter-logging.txt | 2 +- .../opentelemetry-exporter-otlp-common.txt | 2 +- .../opentelemetry-exporter-otlp.txt | 21 +------ ...y-exporter-sender-grpc-managed-channel.txt | 2 +- .../opentelemetry-exporter-sender-jdk.txt | 2 +- .../opentelemetry-exporter-sender-okhttp.txt | 2 +- .../opentelemetry-exporter-zipkin.txt | 2 +- .../opentelemetry-extension-kotlin.txt | 2 +- ...ntelemetry-extension-trace-propagators.txt | 2 +- .../opentelemetry-opentracing-shim.txt | 2 +- .../opentelemetry-sdk-common.txt | 2 +- ...emetry-sdk-extension-autoconfigure-spi.txt | 2 +- ...ntelemetry-sdk-extension-autoconfigure.txt | 2 +- ...ry-sdk-extension-jaeger-remote-sampler.txt | 2 +- .../opentelemetry-sdk-logs.txt | 2 +- .../opentelemetry-sdk-metrics.txt | 2 +- .../opentelemetry-sdk-testing.txt | 2 +- .../opentelemetry-sdk-trace.txt | 2 +- .../current_vs_latest/opentelemetry-sdk.txt | 2 +- 47 files changed, 125 insertions(+), 79 deletions(-) create mode 100644 docs/apidiffs/1.48.0_vs_1.47.0/opentelemetry-api.txt create mode 100644 docs/apidiffs/1.48.0_vs_1.47.0/opentelemetry-context.txt create mode 100644 docs/apidiffs/1.48.0_vs_1.47.0/opentelemetry-exporter-common.txt create mode 100644 docs/apidiffs/1.48.0_vs_1.47.0/opentelemetry-exporter-logging-otlp.txt create mode 100644 docs/apidiffs/1.48.0_vs_1.47.0/opentelemetry-exporter-logging.txt create mode 100644 docs/apidiffs/1.48.0_vs_1.47.0/opentelemetry-exporter-otlp-common.txt create mode 100644 docs/apidiffs/1.48.0_vs_1.47.0/opentelemetry-exporter-otlp.txt create mode 100644 docs/apidiffs/1.48.0_vs_1.47.0/opentelemetry-exporter-sender-grpc-managed-channel.txt create mode 100644 docs/apidiffs/1.48.0_vs_1.47.0/opentelemetry-exporter-sender-jdk.txt create mode 100644 docs/apidiffs/1.48.0_vs_1.47.0/opentelemetry-exporter-sender-okhttp.txt create mode 100644 docs/apidiffs/1.48.0_vs_1.47.0/opentelemetry-exporter-zipkin.txt create mode 100644 docs/apidiffs/1.48.0_vs_1.47.0/opentelemetry-extension-kotlin.txt create mode 100644 docs/apidiffs/1.48.0_vs_1.47.0/opentelemetry-extension-trace-propagators.txt create mode 100644 docs/apidiffs/1.48.0_vs_1.47.0/opentelemetry-opentracing-shim.txt create mode 100644 docs/apidiffs/1.48.0_vs_1.47.0/opentelemetry-sdk-common.txt create mode 100644 docs/apidiffs/1.48.0_vs_1.47.0/opentelemetry-sdk-extension-autoconfigure-spi.txt create mode 100644 docs/apidiffs/1.48.0_vs_1.47.0/opentelemetry-sdk-extension-autoconfigure.txt create mode 100644 docs/apidiffs/1.48.0_vs_1.47.0/opentelemetry-sdk-extension-jaeger-remote-sampler.txt create mode 100644 docs/apidiffs/1.48.0_vs_1.47.0/opentelemetry-sdk-logs.txt create mode 100644 docs/apidiffs/1.48.0_vs_1.47.0/opentelemetry-sdk-metrics.txt create mode 100644 docs/apidiffs/1.48.0_vs_1.47.0/opentelemetry-sdk-testing.txt create mode 100644 docs/apidiffs/1.48.0_vs_1.47.0/opentelemetry-sdk-trace.txt create mode 100644 docs/apidiffs/1.48.0_vs_1.47.0/opentelemetry-sdk.txt diff --git a/README.md b/README.md index 224028f9655..9178908bdcb 100644 --- a/README.md +++ b/README.md @@ -57,8 +57,8 @@ A bill of materials (or BOM) helps sync dependency versions of related artifacts | Component | Description | Artifact ID | Version | Javadoc | |----------------------------------------------|----------------------------------------|---------------------------|-------------------------------------------------------------|---------| -| [Bill of Materials (BOM)](./bom) | Bill of materials for stable artifacts | `opentelemetry-bom` | 1.47.0 | N/A | -| [Alpha Bill of Materials (BOM)](./bom-alpha) | Bill of materials for alpha artifacts | `opentelemetry-bom-alpha` | 1.47.0-alpha | N/A | +| [Bill of Materials (BOM)](./bom) | Bill of materials for stable artifacts | `opentelemetry-bom` | 1.48.0 | N/A | +| [Alpha Bill of Materials (BOM)](./bom-alpha) | Bill of materials for alpha artifacts | `opentelemetry-bom-alpha` | 1.48.0-alpha | N/A |

      @@ -68,9 +68,9 @@ The OpenTelemetry API for recording telemetry. | Component | Description | Artifact ID | Version | Javadoc | |-----------------------------------|--------------------------------------------------------------------------------------|-------------------------------|-------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| [API](./api/all) | OpenTelemetry API, including metrics, traces, baggage, context | `opentelemetry-api` | 1.47.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-api.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-api) | -| [API Incubator](./api/incubator) | API incubator, including pass through propagator, and extended tracer, and Event API | `opentelemetry-api-incubator` | 1.47.0-alpha | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-api-incubator.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-api-incubator) | -| [Context API](./context) | OpenTelemetry context API | `opentelemetry-context` | 1.47.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-context.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-context) | +| [API](./api/all) | OpenTelemetry API, including metrics, traces, baggage, context | `opentelemetry-api` | 1.48.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-api.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-api) | +| [API Incubator](./api/incubator) | API incubator, including pass through propagator, and extended tracer, and Event API | `opentelemetry-api-incubator` | 1.48.0-alpha | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-api-incubator.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-api-incubator) | +| [Context API](./context) | OpenTelemetry context API | `opentelemetry-context` | 1.48.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-context.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-context) |
      @@ -80,8 +80,8 @@ Extensions to the OpenTelemetry API. | Component | Description | Artifact ID | Version | Javadoc | |---------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|---------------------------------------------|-------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| [Kotlin Extension](./extensions/kotlin) | Context extension for coroutines | `opentelemetry-extension-kotlin` | 1.47.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-extension-kotlin.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-extension-kotlin) | -| [Trace Propagators Extension](./extensions/trace-propagators) | Trace propagators, including B3, Jaeger, OT Trace | `opentelemetry-extension-trace-propagators` | 1.47.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-extension-trace-propagators.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-extension-trace-propagators) | +| [Kotlin Extension](./extensions/kotlin) | Context extension for coroutines | `opentelemetry-extension-kotlin` | 1.48.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-extension-kotlin.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-extension-kotlin) | +| [Trace Propagators Extension](./extensions/trace-propagators) | Trace propagators, including B3, Jaeger, OT Trace | `opentelemetry-extension-trace-propagators` | 1.48.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-extension-trace-propagators.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-extension-trace-propagators) |
      @@ -91,12 +91,12 @@ The OpenTelemetry SDK for managing telemetry producing by the API. | Component | Description | Artifact ID | Version | Javadoc | |------------------------------|--------------------------------------------------------|-----------------------------|---------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| [SDK](./sdk/all) | OpenTelemetry SDK, including metrics, traces, and logs | `opentelemetry-sdk` | 1.47.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk) | -| [Metrics SDK](./sdk/metrics) | OpenTelemetry metrics SDK | `opentelemetry-sdk-metrics` | 1.47.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-metrics.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-metrics) | -| [Trace SDK](./sdk/trace) | OpenTelemetry trace SDK | `opentelemetry-sdk-trace` | 1.47.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-trace.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-trace) | -| [Log SDK](./sdk/logs) | OpenTelemetry log SDK | `opentelemetry-sdk-logs` | 1.47.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-logs.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-logs) | -| [SDK Common](./sdk/common) | Shared SDK components | `opentelemetry-sdk-common` | 1.47.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-common.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-common) | -| [SDK Testing](./sdk/testing) | Components for testing OpenTelemetry instrumentation | `opentelemetry-sdk-testing` | 1.47.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-testing.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-testing) | +| [SDK](./sdk/all) | OpenTelemetry SDK, including metrics, traces, and logs | `opentelemetry-sdk` | 1.48.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk) | +| [Metrics SDK](./sdk/metrics) | OpenTelemetry metrics SDK | `opentelemetry-sdk-metrics` | 1.48.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-metrics.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-metrics) | +| [Trace SDK](./sdk/trace) | OpenTelemetry trace SDK | `opentelemetry-sdk-trace` | 1.48.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-trace.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-trace) | +| [Log SDK](./sdk/logs) | OpenTelemetry log SDK | `opentelemetry-sdk-logs` | 1.48.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-logs.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-logs) | +| [SDK Common](./sdk/common) | Shared SDK components | `opentelemetry-sdk-common` | 1.48.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-common.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-common) | +| [SDK Testing](./sdk/testing) | Components for testing OpenTelemetry instrumentation | `opentelemetry-sdk-testing` | 1.48.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-testing.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-testing) |
      @@ -106,16 +106,16 @@ SDK exporters for shipping traces, metrics, and logs out of process. | Component | Description | Artifact ID | Version | Javadoc | |-----------------------------------------------------------------------|------------------------------------------------------------------------------|------------------------------------------------------|-------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| [OTLP Exporters](./exporters/otlp/all) | OTLP gRPC & HTTP exporters, including traces, metrics, and logs | `opentelemetry-exporter-otlp` | 1.47.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-otlp.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-otlp) | -| [OTLP Logging Exporters](./exporters/logging-otlp) | Logging exporters in OTLP JSON encoding, including traces, metrics, and logs | `opentelemetry-exporter-logging-otlp` | 1.47.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-logging-otlp.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-logging-otlp) | -| [OTLP Common](./exporters/otlp/common) | Shared OTLP components (internal) | `opentelemetry-exporter-otlp-common` | 1.47.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-otlp-common.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-otlp-common) | -| [Logging Exporter](./exporters/logging) | Logging exporters, including metrics, traces, and logs | `opentelemetry-exporter-logging` | 1.47.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-logging.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-logging) | -| [Zipkin Exporter](./exporters/zipkin) | Zipkin trace exporter | `opentelemetry-exporter-zipkin` | 1.47.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-zipkin.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-zipkin) | -| [Prometheus Exporter](./exporters/prometheus) | Prometheus metric exporter | `opentelemetry-exporter-prometheus` | 1.47.0-alpha | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-prometheus.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-prometheus) | -| [Exporter Common](./exporters/common) | Shared exporter components (internal) | `opentelemetry-exporter-common` | 1.47.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-common.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-common) | -| [OkHttp Sender](./exporters/sender/okhttp) | OkHttp implementation of HttpSender (internal) | `opentelemetry-exporter-sender-okhttp` | 1.47.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-sender-okhttp.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-sender-okhttp) | -| [JDK Sender](./exporters/sender/jdk) | Java 11+ native HttpClient implementation of HttpSender (internal) | `opentelemetry-exporter-sender-jdk` | 1.47.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-sender-jdk.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-sender-jdk) | | -| [gRPC ManagedChannel Sender](./exporters/sender/grpc-managed-channel) | gRPC ManagedChannel implementation of GrpcSender (internal) | `opentelemetry-exporter-sender-grpc-managed-channel` | 1.47.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-sender-grpc-managed-channel.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-sender-grpc-managed-channel) | | +| [OTLP Exporters](./exporters/otlp/all) | OTLP gRPC & HTTP exporters, including traces, metrics, and logs | `opentelemetry-exporter-otlp` | 1.48.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-otlp.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-otlp) | +| [OTLP Logging Exporters](./exporters/logging-otlp) | Logging exporters in OTLP JSON encoding, including traces, metrics, and logs | `opentelemetry-exporter-logging-otlp` | 1.48.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-logging-otlp.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-logging-otlp) | +| [OTLP Common](./exporters/otlp/common) | Shared OTLP components (internal) | `opentelemetry-exporter-otlp-common` | 1.48.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-otlp-common.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-otlp-common) | +| [Logging Exporter](./exporters/logging) | Logging exporters, including metrics, traces, and logs | `opentelemetry-exporter-logging` | 1.48.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-logging.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-logging) | +| [Zipkin Exporter](./exporters/zipkin) | Zipkin trace exporter | `opentelemetry-exporter-zipkin` | 1.48.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-zipkin.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-zipkin) | +| [Prometheus Exporter](./exporters/prometheus) | Prometheus metric exporter | `opentelemetry-exporter-prometheus` | 1.48.0-alpha | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-prometheus.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-prometheus) | +| [Exporter Common](./exporters/common) | Shared exporter components (internal) | `opentelemetry-exporter-common` | 1.48.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-common.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-common) | +| [OkHttp Sender](./exporters/sender/okhttp) | OkHttp implementation of HttpSender (internal) | `opentelemetry-exporter-sender-okhttp` | 1.48.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-sender-okhttp.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-sender-okhttp) | +| [JDK Sender](./exporters/sender/jdk) | Java 11+ native HttpClient implementation of HttpSender (internal) | `opentelemetry-exporter-sender-jdk` | 1.48.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-sender-jdk.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-sender-jdk) | | +| [gRPC ManagedChannel Sender](./exporters/sender/grpc-managed-channel) | gRPC ManagedChannel implementation of GrpcSender (internal) | `opentelemetry-exporter-sender-grpc-managed-channel` | 1.48.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporter-sender-grpc-managed-channel.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporter-sender-grpc-managed-channel) | |
      @@ -125,10 +125,10 @@ Extensions to the OpenTelemetry SDK. | Component | Description | Artifact ID | Version | Javadoc | |-------------------------------------------------------------------------------|------------------------------------------------------------------------------------|-----------------------------------------------------|-------------------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| [SDK Autoconfigure](./sdk-extensions/autoconfigure) | Autoconfigure OpenTelemetry SDK from env vars, system properties, and SPI | `opentelemetry-sdk-extension-autoconfigure` | 1.47.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-extension-autoconfigure.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-extension-autoconfigure) | -| [SDK Autoconfigure SPI](./sdk-extensions/autoconfigure-spi) | Service Provider Interface (SPI) definitions for autoconfigure | `opentelemetry-sdk-extension-autoconfigure-spi` | 1.47.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-extension-autoconfigure-spi.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-extension-autoconfigure-spi) | -| [SDK Jaeger Remote Sampler Extension](./sdk-extensions/jaeger-remote-sampler) | Sampler which obtains sampling configuration from remote Jaeger server | `opentelemetry-sdk-extension-jaeger-remote-sampler` | 1.47.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-extension-jaeger-remote-sampler.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-extension-jaeger-remote-sampler) | -| [SDK Incubator](./sdk-extensions/incubator) | SDK incubator, including YAML based view configuration, LeakDetectingSpanProcessor | `opentelemetry-sdk-extension-incubator` | 1.47.0-alpha | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-extension-incubator.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-extension-incubator) | +| [SDK Autoconfigure](./sdk-extensions/autoconfigure) | Autoconfigure OpenTelemetry SDK from env vars, system properties, and SPI | `opentelemetry-sdk-extension-autoconfigure` | 1.48.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-extension-autoconfigure.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-extension-autoconfigure) | +| [SDK Autoconfigure SPI](./sdk-extensions/autoconfigure-spi) | Service Provider Interface (SPI) definitions for autoconfigure | `opentelemetry-sdk-extension-autoconfigure-spi` | 1.48.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-extension-autoconfigure-spi.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-extension-autoconfigure-spi) | +| [SDK Jaeger Remote Sampler Extension](./sdk-extensions/jaeger-remote-sampler) | Sampler which obtains sampling configuration from remote Jaeger server | `opentelemetry-sdk-extension-jaeger-remote-sampler` | 1.48.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-extension-jaeger-remote-sampler.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-extension-jaeger-remote-sampler) | +| [SDK Incubator](./sdk-extensions/incubator) | SDK incubator, including YAML based view configuration, LeakDetectingSpanProcessor | `opentelemetry-sdk-extension-incubator` | 1.48.0-alpha | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-extension-incubator.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-extension-incubator) |
      @@ -138,8 +138,8 @@ Shims for bridging data from one observability library to another. | Component | Description | Artifact ID | Version | Javadoc | |----------------------------------------|--------------------------------------------------------------|----------------------------------|-------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| [OpenCensus Shim](./opencensus-shim) | Bridge opencensus metrics into the OpenTelemetry metrics SDK | `opentelemetry-opencensus-shim` | 1.47.0-alpha | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-opencensus-shim.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-opencensus-shim) | -| [OpenTracing Shim](./opentracing-shim) | Bridge opentracing spans into the OpenTelemetry trace API | `opentelemetry-opentracing-shim` | 1.47.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-opentracing-shim.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-opentracing-shim) | +| [OpenCensus Shim](./opencensus-shim) | Bridge opencensus metrics into the OpenTelemetry metrics SDK | `opentelemetry-opencensus-shim` | 1.48.0-alpha | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-opencensus-shim.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-opencensus-shim) | +| [OpenTracing Shim](./opentracing-shim) | Bridge opentracing spans into the OpenTelemetry trace API | `opentelemetry-opentracing-shim` | 1.48.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-opentracing-shim.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-opentracing-shim) |
      ## Dependencies @@ -180,7 +180,7 @@ repositories { } dependencies { - implementation platform("io.opentelemetry:opentelemetry-bom:1.48.0-SNAPSHOT") + implementation platform("io.opentelemetry:opentelemetry-bom:1.49.0-SNAPSHOT") implementation('io.opentelemetry:opentelemetry-api') } ``` @@ -202,7 +202,7 @@ dependencies { io.opentelemetry opentelemetry-bom - 1.48.0-SNAPSHOT + 1.49.0-SNAPSHOT pom import diff --git a/docs/apidiffs/1.48.0_vs_1.47.0/opentelemetry-api.txt b/docs/apidiffs/1.48.0_vs_1.47.0/opentelemetry-api.txt new file mode 100644 index 00000000000..de788f13512 --- /dev/null +++ b/docs/apidiffs/1.48.0_vs_1.47.0/opentelemetry-api.txt @@ -0,0 +1,8 @@ +Comparing source compatibility of opentelemetry-api-1.48.0.jar against opentelemetry-api-1.47.0.jar +*** MODIFIED INTERFACE: PUBLIC ABSTRACT io.opentelemetry.api.logs.LogRecordBuilder (not serializable) + === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 + +++ NEW METHOD: PUBLIC(+) io.opentelemetry.api.logs.LogRecordBuilder setAttribute(java.lang.String, java.lang.String) + +++ NEW METHOD: PUBLIC(+) io.opentelemetry.api.logs.LogRecordBuilder setAttribute(java.lang.String, long) + +++ NEW METHOD: PUBLIC(+) io.opentelemetry.api.logs.LogRecordBuilder setAttribute(java.lang.String, double) + +++ NEW METHOD: PUBLIC(+) io.opentelemetry.api.logs.LogRecordBuilder setAttribute(java.lang.String, boolean) + +++ NEW METHOD: PUBLIC(+) io.opentelemetry.api.logs.LogRecordBuilder setAttribute(java.lang.String, int) diff --git a/docs/apidiffs/1.48.0_vs_1.47.0/opentelemetry-context.txt b/docs/apidiffs/1.48.0_vs_1.47.0/opentelemetry-context.txt new file mode 100644 index 00000000000..3b24635de3f --- /dev/null +++ b/docs/apidiffs/1.48.0_vs_1.47.0/opentelemetry-context.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of opentelemetry-context-1.48.0.jar against opentelemetry-context-1.47.0.jar +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.48.0_vs_1.47.0/opentelemetry-exporter-common.txt b/docs/apidiffs/1.48.0_vs_1.47.0/opentelemetry-exporter-common.txt new file mode 100644 index 00000000000..41b6de6cda4 --- /dev/null +++ b/docs/apidiffs/1.48.0_vs_1.47.0/opentelemetry-exporter-common.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of opentelemetry-exporter-common-1.48.0.jar against opentelemetry-exporter-common-1.47.0.jar +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.48.0_vs_1.47.0/opentelemetry-exporter-logging-otlp.txt b/docs/apidiffs/1.48.0_vs_1.47.0/opentelemetry-exporter-logging-otlp.txt new file mode 100644 index 00000000000..11d31d04e77 --- /dev/null +++ b/docs/apidiffs/1.48.0_vs_1.47.0/opentelemetry-exporter-logging-otlp.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of opentelemetry-exporter-logging-otlp-1.48.0.jar against opentelemetry-exporter-logging-otlp-1.47.0.jar +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.48.0_vs_1.47.0/opentelemetry-exporter-logging.txt b/docs/apidiffs/1.48.0_vs_1.47.0/opentelemetry-exporter-logging.txt new file mode 100644 index 00000000000..a0fdd19735b --- /dev/null +++ b/docs/apidiffs/1.48.0_vs_1.47.0/opentelemetry-exporter-logging.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of opentelemetry-exporter-logging-1.48.0.jar against opentelemetry-exporter-logging-1.47.0.jar +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.48.0_vs_1.47.0/opentelemetry-exporter-otlp-common.txt b/docs/apidiffs/1.48.0_vs_1.47.0/opentelemetry-exporter-otlp-common.txt new file mode 100644 index 00000000000..c29eb51623d --- /dev/null +++ b/docs/apidiffs/1.48.0_vs_1.47.0/opentelemetry-exporter-otlp-common.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of opentelemetry-exporter-otlp-common-1.48.0.jar against opentelemetry-exporter-otlp-common-1.47.0.jar +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.48.0_vs_1.47.0/opentelemetry-exporter-otlp.txt b/docs/apidiffs/1.48.0_vs_1.47.0/opentelemetry-exporter-otlp.txt new file mode 100644 index 00000000000..f5dd0481cd3 --- /dev/null +++ b/docs/apidiffs/1.48.0_vs_1.47.0/opentelemetry-exporter-otlp.txt @@ -0,0 +1,19 @@ +Comparing source compatibility of opentelemetry-exporter-otlp-1.48.0.jar against opentelemetry-exporter-otlp-1.47.0.jar +*** MODIFIED CLASS: PUBLIC FINAL io.opentelemetry.exporter.otlp.http.logs.OtlpHttpLogRecordExporterBuilder (not serializable) + === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 + +++ NEW METHOD: PUBLIC(+) io.opentelemetry.exporter.otlp.http.logs.OtlpHttpLogRecordExporterBuilder setServiceClassLoader(java.lang.ClassLoader) +*** MODIFIED CLASS: PUBLIC FINAL io.opentelemetry.exporter.otlp.http.metrics.OtlpHttpMetricExporterBuilder (not serializable) + === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 + +++ NEW METHOD: PUBLIC(+) io.opentelemetry.exporter.otlp.http.metrics.OtlpHttpMetricExporterBuilder setServiceClassLoader(java.lang.ClassLoader) +*** MODIFIED CLASS: PUBLIC FINAL io.opentelemetry.exporter.otlp.http.trace.OtlpHttpSpanExporterBuilder (not serializable) + === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 + +++ NEW METHOD: PUBLIC(+) io.opentelemetry.exporter.otlp.http.trace.OtlpHttpSpanExporterBuilder setServiceClassLoader(java.lang.ClassLoader) +*** MODIFIED CLASS: PUBLIC FINAL io.opentelemetry.exporter.otlp.logs.OtlpGrpcLogRecordExporterBuilder (not serializable) + === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 + +++ NEW METHOD: PUBLIC(+) io.opentelemetry.exporter.otlp.logs.OtlpGrpcLogRecordExporterBuilder setServiceClassLoader(java.lang.ClassLoader) +*** MODIFIED CLASS: PUBLIC FINAL io.opentelemetry.exporter.otlp.metrics.OtlpGrpcMetricExporterBuilder (not serializable) + === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 + +++ NEW METHOD: PUBLIC(+) io.opentelemetry.exporter.otlp.metrics.OtlpGrpcMetricExporterBuilder setServiceClassLoader(java.lang.ClassLoader) +*** MODIFIED CLASS: PUBLIC FINAL io.opentelemetry.exporter.otlp.trace.OtlpGrpcSpanExporterBuilder (not serializable) + === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 + +++ NEW METHOD: PUBLIC(+) io.opentelemetry.exporter.otlp.trace.OtlpGrpcSpanExporterBuilder setServiceClassLoader(java.lang.ClassLoader) diff --git a/docs/apidiffs/1.48.0_vs_1.47.0/opentelemetry-exporter-sender-grpc-managed-channel.txt b/docs/apidiffs/1.48.0_vs_1.47.0/opentelemetry-exporter-sender-grpc-managed-channel.txt new file mode 100644 index 00000000000..e22d383387d --- /dev/null +++ b/docs/apidiffs/1.48.0_vs_1.47.0/opentelemetry-exporter-sender-grpc-managed-channel.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of opentelemetry-exporter-sender-grpc-managed-channel-1.48.0.jar against opentelemetry-exporter-sender-grpc-managed-channel-1.47.0.jar +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.48.0_vs_1.47.0/opentelemetry-exporter-sender-jdk.txt b/docs/apidiffs/1.48.0_vs_1.47.0/opentelemetry-exporter-sender-jdk.txt new file mode 100644 index 00000000000..6bdb9162c26 --- /dev/null +++ b/docs/apidiffs/1.48.0_vs_1.47.0/opentelemetry-exporter-sender-jdk.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of opentelemetry-exporter-sender-jdk-1.48.0.jar against opentelemetry-exporter-sender-jdk-1.47.0.jar +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.48.0_vs_1.47.0/opentelemetry-exporter-sender-okhttp.txt b/docs/apidiffs/1.48.0_vs_1.47.0/opentelemetry-exporter-sender-okhttp.txt new file mode 100644 index 00000000000..7b009644b8e --- /dev/null +++ b/docs/apidiffs/1.48.0_vs_1.47.0/opentelemetry-exporter-sender-okhttp.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of opentelemetry-exporter-sender-okhttp-1.48.0.jar against opentelemetry-exporter-sender-okhttp-1.47.0.jar +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.48.0_vs_1.47.0/opentelemetry-exporter-zipkin.txt b/docs/apidiffs/1.48.0_vs_1.47.0/opentelemetry-exporter-zipkin.txt new file mode 100644 index 00000000000..74111836a9c --- /dev/null +++ b/docs/apidiffs/1.48.0_vs_1.47.0/opentelemetry-exporter-zipkin.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of opentelemetry-exporter-zipkin-1.48.0.jar against opentelemetry-exporter-zipkin-1.47.0.jar +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.48.0_vs_1.47.0/opentelemetry-extension-kotlin.txt b/docs/apidiffs/1.48.0_vs_1.47.0/opentelemetry-extension-kotlin.txt new file mode 100644 index 00000000000..ed295a0cfbe --- /dev/null +++ b/docs/apidiffs/1.48.0_vs_1.47.0/opentelemetry-extension-kotlin.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of opentelemetry-extension-kotlin-1.48.0.jar against opentelemetry-extension-kotlin-1.47.0.jar +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.48.0_vs_1.47.0/opentelemetry-extension-trace-propagators.txt b/docs/apidiffs/1.48.0_vs_1.47.0/opentelemetry-extension-trace-propagators.txt new file mode 100644 index 00000000000..adf485b5aea --- /dev/null +++ b/docs/apidiffs/1.48.0_vs_1.47.0/opentelemetry-extension-trace-propagators.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of opentelemetry-extension-trace-propagators-1.48.0.jar against opentelemetry-extension-trace-propagators-1.47.0.jar +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.48.0_vs_1.47.0/opentelemetry-opentracing-shim.txt b/docs/apidiffs/1.48.0_vs_1.47.0/opentelemetry-opentracing-shim.txt new file mode 100644 index 00000000000..ece95e4201f --- /dev/null +++ b/docs/apidiffs/1.48.0_vs_1.47.0/opentelemetry-opentracing-shim.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of opentelemetry-opentracing-shim-1.48.0.jar against opentelemetry-opentracing-shim-1.47.0.jar +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.48.0_vs_1.47.0/opentelemetry-sdk-common.txt b/docs/apidiffs/1.48.0_vs_1.47.0/opentelemetry-sdk-common.txt new file mode 100644 index 00000000000..6e9a0615356 --- /dev/null +++ b/docs/apidiffs/1.48.0_vs_1.47.0/opentelemetry-sdk-common.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of opentelemetry-sdk-common-1.48.0.jar against opentelemetry-sdk-common-1.47.0.jar +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.48.0_vs_1.47.0/opentelemetry-sdk-extension-autoconfigure-spi.txt b/docs/apidiffs/1.48.0_vs_1.47.0/opentelemetry-sdk-extension-autoconfigure-spi.txt new file mode 100644 index 00000000000..bc568f86e98 --- /dev/null +++ b/docs/apidiffs/1.48.0_vs_1.47.0/opentelemetry-sdk-extension-autoconfigure-spi.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of opentelemetry-sdk-extension-autoconfigure-spi-1.48.0.jar against opentelemetry-sdk-extension-autoconfigure-spi-1.47.0.jar +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.48.0_vs_1.47.0/opentelemetry-sdk-extension-autoconfigure.txt b/docs/apidiffs/1.48.0_vs_1.47.0/opentelemetry-sdk-extension-autoconfigure.txt new file mode 100644 index 00000000000..ed248b7e6a9 --- /dev/null +++ b/docs/apidiffs/1.48.0_vs_1.47.0/opentelemetry-sdk-extension-autoconfigure.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of opentelemetry-sdk-extension-autoconfigure-1.48.0.jar against opentelemetry-sdk-extension-autoconfigure-1.47.0.jar +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.48.0_vs_1.47.0/opentelemetry-sdk-extension-jaeger-remote-sampler.txt b/docs/apidiffs/1.48.0_vs_1.47.0/opentelemetry-sdk-extension-jaeger-remote-sampler.txt new file mode 100644 index 00000000000..98b608173eb --- /dev/null +++ b/docs/apidiffs/1.48.0_vs_1.47.0/opentelemetry-sdk-extension-jaeger-remote-sampler.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of opentelemetry-sdk-extension-jaeger-remote-sampler-1.48.0.jar against opentelemetry-sdk-extension-jaeger-remote-sampler-1.47.0.jar +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.48.0_vs_1.47.0/opentelemetry-sdk-logs.txt b/docs/apidiffs/1.48.0_vs_1.47.0/opentelemetry-sdk-logs.txt new file mode 100644 index 00000000000..db0e655c47c --- /dev/null +++ b/docs/apidiffs/1.48.0_vs_1.47.0/opentelemetry-sdk-logs.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of opentelemetry-sdk-logs-1.48.0.jar against opentelemetry-sdk-logs-1.47.0.jar +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.48.0_vs_1.47.0/opentelemetry-sdk-metrics.txt b/docs/apidiffs/1.48.0_vs_1.47.0/opentelemetry-sdk-metrics.txt new file mode 100644 index 00000000000..83956eff6a5 --- /dev/null +++ b/docs/apidiffs/1.48.0_vs_1.47.0/opentelemetry-sdk-metrics.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of opentelemetry-sdk-metrics-1.48.0.jar against opentelemetry-sdk-metrics-1.47.0.jar +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.48.0_vs_1.47.0/opentelemetry-sdk-testing.txt b/docs/apidiffs/1.48.0_vs_1.47.0/opentelemetry-sdk-testing.txt new file mode 100644 index 00000000000..111061e57cf --- /dev/null +++ b/docs/apidiffs/1.48.0_vs_1.47.0/opentelemetry-sdk-testing.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of opentelemetry-sdk-testing-1.48.0.jar against opentelemetry-sdk-testing-1.47.0.jar +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.48.0_vs_1.47.0/opentelemetry-sdk-trace.txt b/docs/apidiffs/1.48.0_vs_1.47.0/opentelemetry-sdk-trace.txt new file mode 100644 index 00000000000..d02ca48d06a --- /dev/null +++ b/docs/apidiffs/1.48.0_vs_1.47.0/opentelemetry-sdk-trace.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of opentelemetry-sdk-trace-1.48.0.jar against opentelemetry-sdk-trace-1.47.0.jar +No changes. \ No newline at end of file diff --git a/docs/apidiffs/1.48.0_vs_1.47.0/opentelemetry-sdk.txt b/docs/apidiffs/1.48.0_vs_1.47.0/opentelemetry-sdk.txt new file mode 100644 index 00000000000..d5907c73bae --- /dev/null +++ b/docs/apidiffs/1.48.0_vs_1.47.0/opentelemetry-sdk.txt @@ -0,0 +1,2 @@ +Comparing source compatibility of opentelemetry-sdk-1.48.0.jar against opentelemetry-sdk-1.47.0.jar +No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-api.txt b/docs/apidiffs/current_vs_latest/opentelemetry-api.txt index bd14d189fd7..d7c6fb68622 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-api.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-api.txt @@ -1,8 +1,2 @@ -Comparing source compatibility of opentelemetry-api-1.48.0-SNAPSHOT.jar against opentelemetry-api-1.47.0.jar -*** MODIFIED INTERFACE: PUBLIC ABSTRACT io.opentelemetry.api.logs.LogRecordBuilder (not serializable) - === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 - +++ NEW METHOD: PUBLIC(+) io.opentelemetry.api.logs.LogRecordBuilder setAttribute(java.lang.String, java.lang.String) - +++ NEW METHOD: PUBLIC(+) io.opentelemetry.api.logs.LogRecordBuilder setAttribute(java.lang.String, long) - +++ NEW METHOD: PUBLIC(+) io.opentelemetry.api.logs.LogRecordBuilder setAttribute(java.lang.String, double) - +++ NEW METHOD: PUBLIC(+) io.opentelemetry.api.logs.LogRecordBuilder setAttribute(java.lang.String, boolean) - +++ NEW METHOD: PUBLIC(+) io.opentelemetry.api.logs.LogRecordBuilder setAttribute(java.lang.String, int) +Comparing source compatibility of opentelemetry-api-1.49.0-SNAPSHOT.jar against opentelemetry-api-1.48.0.jar +No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-context.txt b/docs/apidiffs/current_vs_latest/opentelemetry-context.txt index 235a52aabe8..3b637cee8a4 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-context.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-context.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of opentelemetry-context-1.48.0-SNAPSHOT.jar against opentelemetry-context-1.47.0.jar +Comparing source compatibility of opentelemetry-context-1.49.0-SNAPSHOT.jar against opentelemetry-context-1.48.0.jar No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-common.txt b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-common.txt index aec4d1f1e22..570550ff81f 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-common.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-common.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of opentelemetry-exporter-common-1.48.0-SNAPSHOT.jar against opentelemetry-exporter-common-1.47.0.jar +Comparing source compatibility of opentelemetry-exporter-common-1.49.0-SNAPSHOT.jar against opentelemetry-exporter-common-1.48.0.jar No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-logging-otlp.txt b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-logging-otlp.txt index 9d2c3d079cc..5f08806fef4 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-logging-otlp.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-logging-otlp.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of opentelemetry-exporter-logging-otlp-1.48.0-SNAPSHOT.jar against opentelemetry-exporter-logging-otlp-1.47.0.jar +Comparing source compatibility of opentelemetry-exporter-logging-otlp-1.49.0-SNAPSHOT.jar against opentelemetry-exporter-logging-otlp-1.48.0.jar No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-logging.txt b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-logging.txt index 043fcef4f5a..9ab45b7a17f 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-logging.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-logging.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of opentelemetry-exporter-logging-1.48.0-SNAPSHOT.jar against opentelemetry-exporter-logging-1.47.0.jar +Comparing source compatibility of opentelemetry-exporter-logging-1.49.0-SNAPSHOT.jar against opentelemetry-exporter-logging-1.48.0.jar No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-otlp-common.txt b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-otlp-common.txt index a7a3f42c060..c02b046db32 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-otlp-common.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-otlp-common.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of opentelemetry-exporter-otlp-common-1.48.0-SNAPSHOT.jar against opentelemetry-exporter-otlp-common-1.47.0.jar +Comparing source compatibility of opentelemetry-exporter-otlp-common-1.49.0-SNAPSHOT.jar against opentelemetry-exporter-otlp-common-1.48.0.jar No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-otlp.txt b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-otlp.txt index 5345e196089..369a2a1163d 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-otlp.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-otlp.txt @@ -1,19 +1,2 @@ -Comparing source compatibility of opentelemetry-exporter-otlp-1.48.0-SNAPSHOT.jar against opentelemetry-exporter-otlp-1.47.0.jar -*** MODIFIED CLASS: PUBLIC FINAL io.opentelemetry.exporter.otlp.http.logs.OtlpHttpLogRecordExporterBuilder (not serializable) - === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 - +++ NEW METHOD: PUBLIC(+) io.opentelemetry.exporter.otlp.http.logs.OtlpHttpLogRecordExporterBuilder setServiceClassLoader(java.lang.ClassLoader) -*** MODIFIED CLASS: PUBLIC FINAL io.opentelemetry.exporter.otlp.http.metrics.OtlpHttpMetricExporterBuilder (not serializable) - === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 - +++ NEW METHOD: PUBLIC(+) io.opentelemetry.exporter.otlp.http.metrics.OtlpHttpMetricExporterBuilder setServiceClassLoader(java.lang.ClassLoader) -*** MODIFIED CLASS: PUBLIC FINAL io.opentelemetry.exporter.otlp.http.trace.OtlpHttpSpanExporterBuilder (not serializable) - === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 - +++ NEW METHOD: PUBLIC(+) io.opentelemetry.exporter.otlp.http.trace.OtlpHttpSpanExporterBuilder setServiceClassLoader(java.lang.ClassLoader) -*** MODIFIED CLASS: PUBLIC FINAL io.opentelemetry.exporter.otlp.logs.OtlpGrpcLogRecordExporterBuilder (not serializable) - === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 - +++ NEW METHOD: PUBLIC(+) io.opentelemetry.exporter.otlp.logs.OtlpGrpcLogRecordExporterBuilder setServiceClassLoader(java.lang.ClassLoader) -*** MODIFIED CLASS: PUBLIC FINAL io.opentelemetry.exporter.otlp.metrics.OtlpGrpcMetricExporterBuilder (not serializable) - === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 - +++ NEW METHOD: PUBLIC(+) io.opentelemetry.exporter.otlp.metrics.OtlpGrpcMetricExporterBuilder setServiceClassLoader(java.lang.ClassLoader) -*** MODIFIED CLASS: PUBLIC FINAL io.opentelemetry.exporter.otlp.trace.OtlpGrpcSpanExporterBuilder (not serializable) - === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 - +++ NEW METHOD: PUBLIC(+) io.opentelemetry.exporter.otlp.trace.OtlpGrpcSpanExporterBuilder setServiceClassLoader(java.lang.ClassLoader) +Comparing source compatibility of opentelemetry-exporter-otlp-1.49.0-SNAPSHOT.jar against opentelemetry-exporter-otlp-1.48.0.jar +No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-sender-grpc-managed-channel.txt b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-sender-grpc-managed-channel.txt index f00bcb039d8..9c3f334ad4d 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-sender-grpc-managed-channel.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-sender-grpc-managed-channel.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of opentelemetry-exporter-sender-grpc-managed-channel-1.48.0-SNAPSHOT.jar against opentelemetry-exporter-sender-grpc-managed-channel-1.47.0.jar +Comparing source compatibility of opentelemetry-exporter-sender-grpc-managed-channel-1.49.0-SNAPSHOT.jar against opentelemetry-exporter-sender-grpc-managed-channel-1.48.0.jar No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-sender-jdk.txt b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-sender-jdk.txt index eed06090d2e..afe9b8526d5 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-sender-jdk.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-sender-jdk.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of opentelemetry-exporter-sender-jdk-1.48.0-SNAPSHOT.jar against opentelemetry-exporter-sender-jdk-1.47.0.jar +Comparing source compatibility of opentelemetry-exporter-sender-jdk-1.49.0-SNAPSHOT.jar against opentelemetry-exporter-sender-jdk-1.48.0.jar No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-sender-okhttp.txt b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-sender-okhttp.txt index bc70f8e0ea5..0815487f216 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-sender-okhttp.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-sender-okhttp.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of opentelemetry-exporter-sender-okhttp-1.48.0-SNAPSHOT.jar against opentelemetry-exporter-sender-okhttp-1.47.0.jar +Comparing source compatibility of opentelemetry-exporter-sender-okhttp-1.49.0-SNAPSHOT.jar against opentelemetry-exporter-sender-okhttp-1.48.0.jar No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-zipkin.txt b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-zipkin.txt index 1e8e580b7ad..6b359d37696 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-zipkin.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-zipkin.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of opentelemetry-exporter-zipkin-1.48.0-SNAPSHOT.jar against opentelemetry-exporter-zipkin-1.47.0.jar +Comparing source compatibility of opentelemetry-exporter-zipkin-1.49.0-SNAPSHOT.jar against opentelemetry-exporter-zipkin-1.48.0.jar No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-extension-kotlin.txt b/docs/apidiffs/current_vs_latest/opentelemetry-extension-kotlin.txt index 849d729b4a4..7e059b2f568 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-extension-kotlin.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-extension-kotlin.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of opentelemetry-extension-kotlin-1.48.0-SNAPSHOT.jar against opentelemetry-extension-kotlin-1.47.0.jar +Comparing source compatibility of opentelemetry-extension-kotlin-1.49.0-SNAPSHOT.jar against opentelemetry-extension-kotlin-1.48.0.jar No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-extension-trace-propagators.txt b/docs/apidiffs/current_vs_latest/opentelemetry-extension-trace-propagators.txt index 9fb65a14f73..09c848c2104 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-extension-trace-propagators.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-extension-trace-propagators.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of opentelemetry-extension-trace-propagators-1.48.0-SNAPSHOT.jar against opentelemetry-extension-trace-propagators-1.47.0.jar +Comparing source compatibility of opentelemetry-extension-trace-propagators-1.49.0-SNAPSHOT.jar against opentelemetry-extension-trace-propagators-1.48.0.jar No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-opentracing-shim.txt b/docs/apidiffs/current_vs_latest/opentelemetry-opentracing-shim.txt index a6f559812df..0c209995480 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-opentracing-shim.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-opentracing-shim.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of opentelemetry-opentracing-shim-1.48.0-SNAPSHOT.jar against opentelemetry-opentracing-shim-1.47.0.jar +Comparing source compatibility of opentelemetry-opentracing-shim-1.49.0-SNAPSHOT.jar against opentelemetry-opentracing-shim-1.48.0.jar No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-common.txt b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-common.txt index 7c0297328f7..87bf61b8638 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-common.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-common.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of opentelemetry-sdk-common-1.48.0-SNAPSHOT.jar against opentelemetry-sdk-common-1.47.0.jar +Comparing source compatibility of opentelemetry-sdk-common-1.49.0-SNAPSHOT.jar against opentelemetry-sdk-common-1.48.0.jar No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-extension-autoconfigure-spi.txt b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-extension-autoconfigure-spi.txt index 57915cb9be6..9d3fc17fdaa 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-extension-autoconfigure-spi.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-extension-autoconfigure-spi.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of opentelemetry-sdk-extension-autoconfigure-spi-1.48.0-SNAPSHOT.jar against opentelemetry-sdk-extension-autoconfigure-spi-1.47.0.jar +Comparing source compatibility of opentelemetry-sdk-extension-autoconfigure-spi-1.49.0-SNAPSHOT.jar against opentelemetry-sdk-extension-autoconfigure-spi-1.48.0.jar No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-extension-autoconfigure.txt b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-extension-autoconfigure.txt index 9cba7e68928..d8f56fdc42b 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-extension-autoconfigure.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-extension-autoconfigure.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of opentelemetry-sdk-extension-autoconfigure-1.48.0-SNAPSHOT.jar against opentelemetry-sdk-extension-autoconfigure-1.47.0.jar +Comparing source compatibility of opentelemetry-sdk-extension-autoconfigure-1.49.0-SNAPSHOT.jar against opentelemetry-sdk-extension-autoconfigure-1.48.0.jar No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-extension-jaeger-remote-sampler.txt b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-extension-jaeger-remote-sampler.txt index 2f6326485f7..c7caaf55da2 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-extension-jaeger-remote-sampler.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-extension-jaeger-remote-sampler.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of opentelemetry-sdk-extension-jaeger-remote-sampler-1.48.0-SNAPSHOT.jar against opentelemetry-sdk-extension-jaeger-remote-sampler-1.47.0.jar +Comparing source compatibility of opentelemetry-sdk-extension-jaeger-remote-sampler-1.49.0-SNAPSHOT.jar against opentelemetry-sdk-extension-jaeger-remote-sampler-1.48.0.jar No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-logs.txt b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-logs.txt index 1fc34295832..401256abc53 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-logs.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-logs.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of opentelemetry-sdk-logs-1.48.0-SNAPSHOT.jar against opentelemetry-sdk-logs-1.47.0.jar +Comparing source compatibility of opentelemetry-sdk-logs-1.49.0-SNAPSHOT.jar against opentelemetry-sdk-logs-1.48.0.jar No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-metrics.txt b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-metrics.txt index 3cfe387fe8f..d3dba97c51d 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-metrics.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-metrics.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of opentelemetry-sdk-metrics-1.48.0-SNAPSHOT.jar against opentelemetry-sdk-metrics-1.47.0.jar +Comparing source compatibility of opentelemetry-sdk-metrics-1.49.0-SNAPSHOT.jar against opentelemetry-sdk-metrics-1.48.0.jar No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-testing.txt b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-testing.txt index d0bdcc79192..2d1a38296f1 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-testing.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-testing.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of opentelemetry-sdk-testing-1.48.0-SNAPSHOT.jar against opentelemetry-sdk-testing-1.47.0.jar +Comparing source compatibility of opentelemetry-sdk-testing-1.49.0-SNAPSHOT.jar against opentelemetry-sdk-testing-1.48.0.jar No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-trace.txt b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-trace.txt index 48f428554cc..b5c1d3c6dad 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-trace.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-trace.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of opentelemetry-sdk-trace-1.48.0-SNAPSHOT.jar against opentelemetry-sdk-trace-1.47.0.jar +Comparing source compatibility of opentelemetry-sdk-trace-1.49.0-SNAPSHOT.jar against opentelemetry-sdk-trace-1.48.0.jar No changes. \ No newline at end of file diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-sdk.txt b/docs/apidiffs/current_vs_latest/opentelemetry-sdk.txt index 42ee3328a83..d724acf4872 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-sdk.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-sdk.txt @@ -1,2 +1,2 @@ -Comparing source compatibility of opentelemetry-sdk-1.48.0-SNAPSHOT.jar against opentelemetry-sdk-1.47.0.jar +Comparing source compatibility of opentelemetry-sdk-1.49.0-SNAPSHOT.jar against opentelemetry-sdk-1.48.0.jar No changes. \ No newline at end of file From d511a28df9807c5dc8dad7821a86ac8043882d25 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 10 Mar 2025 11:18:12 -0500 Subject: [PATCH 866/901] chore(deps): update github/codeql-action action to v3.28.11 (#7189) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/codeql.yml | 4 ++-- .github/workflows/ossf-scorecard.yml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index 5ed35ce27b0..5f63fc39e47 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -37,7 +37,7 @@ jobs: uses: gradle/actions/setup-gradle@94baf225fe0a508e581a564467443d0e2379123b # v4.3.0 - name: Initialize CodeQL - uses: github/codeql-action/init@b56ba49b26e50535fa1e7f7db0f4f7b4bf65d80d # v3.28.10 + uses: github/codeql-action/init@6bb031afdd8eb862ea3fc1848194185e076637e5 # v3.28.11 with: languages: java, actions # using "latest" helps to keep up with the latest Kotlin support @@ -51,4 +51,4 @@ jobs: run: ./gradlew assemble --no-build-cache --no-daemon - name: Perform CodeQL analysis - uses: github/codeql-action/analyze@b56ba49b26e50535fa1e7f7db0f4f7b4bf65d80d # v3.28.10 + uses: github/codeql-action/analyze@6bb031afdd8eb862ea3fc1848194185e076637e5 # v3.28.11 diff --git a/.github/workflows/ossf-scorecard.yml b/.github/workflows/ossf-scorecard.yml index f57e5edcf28..ebc6b099014 100644 --- a/.github/workflows/ossf-scorecard.yml +++ b/.github/workflows/ossf-scorecard.yml @@ -42,6 +42,6 @@ jobs: # Upload the results to GitHub's code scanning dashboard (optional). # Commenting out will disable upload of results to your repo's Code Scanning dashboard - name: "Upload to code-scanning" - uses: github/codeql-action/upload-sarif@b56ba49b26e50535fa1e7f7db0f4f7b4bf65d80d # v3.28.10 + uses: github/codeql-action/upload-sarif@6bb031afdd8eb862ea3fc1848194185e076637e5 # v3.28.11 with: sarif_file: results.sarif From d0848e335155381208d5c5a2656e1fdd01d528a3 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 12 Mar 2025 09:53:26 -0500 Subject: [PATCH 867/901] fix(deps): update dependency com.google.api.grpc:proto-google-common-protos to v2.54.0 (#7192) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- dependencyManagement/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index 518a647c993..e96ebb7317b 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -73,7 +73,7 @@ val DEPENDENCIES = listOf( "io.prometheus:simpleclient_httpserver:${prometheusClientVersion}", "javax.annotation:javax.annotation-api:1.3.2", "com.github.stefanbirkner:system-rules:1.19.0", - "com.google.api.grpc:proto-google-common-protos:2.53.0", + "com.google.api.grpc:proto-google-common-protos:2.54.0", "com.google.code.findbugs:jsr305:3.0.2", "com.google.guava:guava-beta-checker:1.0", "com.sun.net.httpserver:http:20070405", From a3dd67739a3f79ab1f09c5f50f8465b068644f02 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 12 Mar 2025 09:53:45 -0500 Subject: [PATCH 868/901] chore(deps): update plugin org.graalvm.buildtools.native to v0.10.6 (#7193) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- settings.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/settings.gradle.kts b/settings.gradle.kts index 10ab444628a..59803cb6497 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -5,7 +5,7 @@ pluginManagement { id("de.undercouch.download") version "5.6.0" id("org.jsonschema2pojo") version "1.2.2" id("io.github.gradle-nexus.publish-plugin") version "2.0.0" - id("org.graalvm.buildtools.native") version "0.10.5" + id("org.graalvm.buildtools.native") version "0.10.6" } } From 0673fcfda59cdc0b3ac46d8b886a1e861755fee7 Mon Sep 17 00:00:00 2001 From: jack-berg <34418638+jack-berg@users.noreply.github.com> Date: Thu, 13 Mar 2025 11:53:19 -0500 Subject: [PATCH 869/901] Add support for setting OTLP exporter executor service (#7152) --- .../opentelemetry-exporter-otlp.txt | 19 ++- .../internal/grpc/GrpcExporterBuilder.java | 13 +- .../internal/grpc/GrpcSenderConfig.java | 10 +- .../internal/http/HttpExporterBuilder.java | 13 +- .../internal/http/HttpSenderConfig.java | 10 +- .../otlp/trace/OltpExporterBenchmark.java | 4 +- .../OtlpHttpLogRecordExporterBuilder.java | 14 +++ .../OtlpHttpMetricExporterBuilder.java | 14 +++ .../trace/OtlpHttpSpanExporterBuilder.java | 14 +++ .../OtlpGrpcLogRecordExporterBuilder.java | 14 +++ .../OtlpGrpcMetricExporterBuilder.java | 14 +++ .../trace/OtlpGrpcSpanExporterBuilder.java | 14 +++ .../AbstractGrpcTelemetryExporterTest.java | 26 ++++ .../AbstractHttpTelemetryExporterTest.java | 26 ++++ .../testing/internal/ExecutorServiceSpy.java | 113 ++++++++++++++++++ .../GrpcLogRecordExporterBuilderWrapper.java | 8 ++ .../GrpcMetricExporterBuilderWrapper.java | 7 ++ .../GrpcSpanExporterBuilderWrapper.java | 7 ++ .../HttpLogRecordExporterBuilderWrapper.java | 8 ++ .../HttpMetricExporterBuilderWrapper.java | 7 ++ .../HttpSpanExporterBuilderWrapper.java | 7 ++ ...anagedChannelTelemetryExporterBuilder.java | 7 ++ .../internal/TelemetryExporterBuilder.java | 3 + .../internal/UpstreamGrpcSender.java | 9 +- .../internal/UpstreamGrpcSenderProvider.java | 3 +- .../sender/jdk/internal/JdkHttpSender.java | 23 +++- .../jdk/internal/JdkHttpSenderProvider.java | 3 +- .../jdk/internal/JdkHttpSenderTest.java | 13 +- .../okhttp/internal/OkHttpGrpcSender.java | 22 +++- .../internal/OkHttpGrpcSenderProvider.java | 3 +- .../okhttp/internal/OkHttpHttpSender.java | 22 +++- .../internal/OkHttpHttpSenderProvider.java | 3 +- .../internal/OkHttpGrpcSuppressionTest.java | 2 +- .../internal/OkHttpHttpSuppressionTest.java | 1 + 34 files changed, 442 insertions(+), 34 deletions(-) create mode 100644 exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/ExecutorServiceSpy.java diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-otlp.txt b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-otlp.txt index 369a2a1163d..018e2e3884d 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-otlp.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-otlp.txt @@ -1,2 +1,19 @@ Comparing source compatibility of opentelemetry-exporter-otlp-1.49.0-SNAPSHOT.jar against opentelemetry-exporter-otlp-1.48.0.jar -No changes. \ No newline at end of file +*** MODIFIED CLASS: PUBLIC FINAL io.opentelemetry.exporter.otlp.http.logs.OtlpHttpLogRecordExporterBuilder (not serializable) + === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 + +++ NEW METHOD: PUBLIC(+) io.opentelemetry.exporter.otlp.http.logs.OtlpHttpLogRecordExporterBuilder setExecutorService(java.util.concurrent.ExecutorService) +*** MODIFIED CLASS: PUBLIC FINAL io.opentelemetry.exporter.otlp.http.metrics.OtlpHttpMetricExporterBuilder (not serializable) + === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 + +++ NEW METHOD: PUBLIC(+) io.opentelemetry.exporter.otlp.http.metrics.OtlpHttpMetricExporterBuilder setExecutorService(java.util.concurrent.ExecutorService) +*** MODIFIED CLASS: PUBLIC FINAL io.opentelemetry.exporter.otlp.http.trace.OtlpHttpSpanExporterBuilder (not serializable) + === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 + +++ NEW METHOD: PUBLIC(+) io.opentelemetry.exporter.otlp.http.trace.OtlpHttpSpanExporterBuilder setExecutorService(java.util.concurrent.ExecutorService) +*** MODIFIED CLASS: PUBLIC FINAL io.opentelemetry.exporter.otlp.logs.OtlpGrpcLogRecordExporterBuilder (not serializable) + === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 + +++ NEW METHOD: PUBLIC(+) io.opentelemetry.exporter.otlp.logs.OtlpGrpcLogRecordExporterBuilder setExecutorService(java.util.concurrent.ExecutorService) +*** MODIFIED CLASS: PUBLIC FINAL io.opentelemetry.exporter.otlp.metrics.OtlpGrpcMetricExporterBuilder (not serializable) + === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 + +++ NEW METHOD: PUBLIC(+) io.opentelemetry.exporter.otlp.metrics.OtlpGrpcMetricExporterBuilder setExecutorService(java.util.concurrent.ExecutorService) +*** MODIFIED CLASS: PUBLIC FINAL io.opentelemetry.exporter.otlp.trace.OtlpGrpcSpanExporterBuilder (not serializable) + === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 + +++ NEW METHOD: PUBLIC(+) io.opentelemetry.exporter.otlp.trace.OtlpGrpcSpanExporterBuilder setExecutorService(java.util.concurrent.ExecutorService) diff --git a/exporters/common/src/main/java/io/opentelemetry/exporter/internal/grpc/GrpcExporterBuilder.java b/exporters/common/src/main/java/io/opentelemetry/exporter/internal/grpc/GrpcExporterBuilder.java index 9af2b47cf6e..d5cd41d1066 100644 --- a/exporters/common/src/main/java/io/opentelemetry/exporter/internal/grpc/GrpcExporterBuilder.java +++ b/exporters/common/src/main/java/io/opentelemetry/exporter/internal/grpc/GrpcExporterBuilder.java @@ -25,6 +25,7 @@ import java.util.Optional; import java.util.ServiceLoader; import java.util.StringJoiner; +import java.util.concurrent.ExecutorService; import java.util.concurrent.TimeUnit; import java.util.function.BiFunction; import java.util.function.Supplier; @@ -63,6 +64,7 @@ public class GrpcExporterBuilder { @Nullable private RetryPolicy retryPolicy = RetryPolicy.getDefault(); private Supplier meterProviderSupplier = GlobalOpenTelemetry::getMeterProvider; private ClassLoader serviceClassLoader = GrpcExporterBuilder.class.getClassLoader(); + @Nullable private ExecutorService executorService; // Use Object type since gRPC may not be on the classpath. @Nullable private Object grpcChannel; @@ -153,6 +155,11 @@ public GrpcExporterBuilder setServiceClassLoader(ClassLoader servieClassLoade return this; } + public GrpcExporterBuilder setExecutorService(ExecutorService executorService) { + this.executorService = executorService; + return this; + } + @SuppressWarnings("BuilderReturnThis") public GrpcExporterBuilder copy() { GrpcExporterBuilder copy = @@ -216,7 +223,8 @@ public GrpcExporter build() { grpcStubFactory, retryPolicy, isPlainHttp ? null : tlsConfigHelper.getSslContext(), - isPlainHttp ? null : tlsConfigHelper.getTrustManager())); + isPlainHttp ? null : tlsConfigHelper.getTrustManager(), + executorService)); LOGGER.log(Level.FINE, "Using GrpcSender: " + grpcSender.getClass().getName()); return new GrpcExporter<>(exporterName, type, grpcSender, meterProviderSupplier); @@ -250,6 +258,9 @@ public String toString(boolean includePrefixAndSuffix) { joiner.add("grpcChannel=" + grpcChannel); } joiner.add("serviceClassLoader=" + serviceClassLoader); + if (executorService != null) { + joiner.add("executorService=" + executorService); + } // Note: omit tlsConfigHelper because we can't log the configuration in any readable way // Note: omit meterProviderSupplier because we can't log the configuration in any readable way return joiner.toString(); diff --git a/exporters/common/src/main/java/io/opentelemetry/exporter/internal/grpc/GrpcSenderConfig.java b/exporters/common/src/main/java/io/opentelemetry/exporter/internal/grpc/GrpcSenderConfig.java index 1685961f41e..8f4f546d6c4 100644 --- a/exporters/common/src/main/java/io/opentelemetry/exporter/internal/grpc/GrpcSenderConfig.java +++ b/exporters/common/src/main/java/io/opentelemetry/exporter/internal/grpc/GrpcSenderConfig.java @@ -13,6 +13,7 @@ import java.net.URI; import java.util.List; import java.util.Map; +import java.util.concurrent.ExecutorService; import java.util.function.BiFunction; import java.util.function.Supplier; import javax.annotation.Nullable; @@ -40,7 +41,8 @@ public static GrpcSenderConfig create( Supplier>> stubFactory, @Nullable RetryPolicy retryPolicy, @Nullable SSLContext sslContext, - @Nullable X509TrustManager trustManager) { + @Nullable X509TrustManager trustManager, + @Nullable ExecutorService executorService) { return new AutoValue_GrpcSenderConfig<>( endpoint, endpointPath, @@ -52,7 +54,8 @@ public static GrpcSenderConfig create( stubFactory, retryPolicy, sslContext, - trustManager); + trustManager, + executorService); } public abstract URI getEndpoint(); @@ -82,4 +85,7 @@ public static GrpcSenderConfig create( @Nullable public abstract X509TrustManager getTrustManager(); + + @Nullable + public abstract ExecutorService getExecutorService(); } diff --git a/exporters/common/src/main/java/io/opentelemetry/exporter/internal/http/HttpExporterBuilder.java b/exporters/common/src/main/java/io/opentelemetry/exporter/internal/http/HttpExporterBuilder.java index 3091408af58..631dd0f9a9e 100644 --- a/exporters/common/src/main/java/io/opentelemetry/exporter/internal/http/HttpExporterBuilder.java +++ b/exporters/common/src/main/java/io/opentelemetry/exporter/internal/http/HttpExporterBuilder.java @@ -23,6 +23,7 @@ import java.util.Optional; import java.util.ServiceLoader; import java.util.StringJoiner; +import java.util.concurrent.ExecutorService; import java.util.concurrent.TimeUnit; import java.util.function.Supplier; import java.util.logging.Level; @@ -61,6 +62,7 @@ public final class HttpExporterBuilder { @Nullable private RetryPolicy retryPolicy = RetryPolicy.getDefault(); private Supplier meterProviderSupplier = GlobalOpenTelemetry::getMeterProvider; private ClassLoader serviceClassLoader = HttpExporterBuilder.class.getClassLoader(); + @Nullable private ExecutorService executorService; public HttpExporterBuilder(String exporterName, String type, String defaultEndpoint) { this.exporterName = exporterName; @@ -137,6 +139,11 @@ public HttpExporterBuilder setServiceClassLoader(ClassLoader servieClassLoade return this; } + public HttpExporterBuilder setExecutorService(ExecutorService executorService) { + this.executorService = executorService; + return this; + } + public HttpExporterBuilder exportAsJson() { this.exportAsJson = true; return this; @@ -198,7 +205,8 @@ public HttpExporter build() { proxyOptions, retryPolicy, isPlainHttp ? null : tlsConfigHelper.getSslContext(), - isPlainHttp ? null : tlsConfigHelper.getTrustManager())); + isPlainHttp ? null : tlsConfigHelper.getTrustManager(), + executorService)); LOGGER.log(Level.FINE, "Using HttpSender: " + httpSender.getClass().getName()); return new HttpExporter<>(exporterName, type, httpSender, meterProviderSupplier, exportAsJson); @@ -230,6 +238,9 @@ public String toString(boolean includePrefixAndSuffix) { joiner.add("retryPolicy=" + retryPolicy); } joiner.add("serviceClassLoader=" + serviceClassLoader); + if (executorService != null) { + joiner.add("executorService=" + executorService); + } // Note: omit tlsConfigHelper because we can't log the configuration in any readable way // Note: omit meterProviderSupplier because we can't log the configuration in any readable way return joiner.toString(); diff --git a/exporters/common/src/main/java/io/opentelemetry/exporter/internal/http/HttpSenderConfig.java b/exporters/common/src/main/java/io/opentelemetry/exporter/internal/http/HttpSenderConfig.java index 03b50a44848..78b63afaf1d 100644 --- a/exporters/common/src/main/java/io/opentelemetry/exporter/internal/http/HttpSenderConfig.java +++ b/exporters/common/src/main/java/io/opentelemetry/exporter/internal/http/HttpSenderConfig.java @@ -11,6 +11,7 @@ import io.opentelemetry.sdk.common.export.RetryPolicy; import java.util.List; import java.util.Map; +import java.util.concurrent.ExecutorService; import java.util.function.Supplier; import javax.annotation.Nullable; import javax.annotation.concurrent.Immutable; @@ -37,7 +38,8 @@ public static HttpSenderConfig create( @Nullable ProxyOptions proxyOptions, @Nullable RetryPolicy retryPolicy, @Nullable SSLContext sslContext, - @Nullable X509TrustManager trustManager) { + @Nullable X509TrustManager trustManager, + @Nullable ExecutorService executorService) { return new AutoValue_HttpSenderConfig( endpoint, compressor, @@ -49,7 +51,8 @@ public static HttpSenderConfig create( proxyOptions, retryPolicy, sslContext, - trustManager); + trustManager, + executorService); } public abstract String getEndpoint(); @@ -78,4 +81,7 @@ public static HttpSenderConfig create( @Nullable public abstract X509TrustManager getTrustManager(); + + @Nullable + public abstract ExecutorService getExecutorService(); } diff --git a/exporters/otlp/all/src/jmh/java/io/opentelemetry/exporter/otlp/trace/OltpExporterBenchmark.java b/exporters/otlp/all/src/jmh/java/io/opentelemetry/exporter/otlp/trace/OltpExporterBenchmark.java index 5dc9f2107c8..f45272a4bca 100644 --- a/exporters/otlp/all/src/jmh/java/io/opentelemetry/exporter/otlp/trace/OltpExporterBenchmark.java +++ b/exporters/otlp/all/src/jmh/java/io/opentelemetry/exporter/otlp/trace/OltpExporterBenchmark.java @@ -88,7 +88,8 @@ public void setUp() { MarshalerTraceServiceGrpc.newFutureStub(defaultGrpcChannel, null), /* shutdownChannel= */ false, 10, - Collections::emptyMap), + Collections::emptyMap, + null), MeterProvider::noop); okhttpGrpcSender = @@ -105,6 +106,7 @@ public void setUp() { Collections::emptyMap, null, null, + null, null), MeterProvider::noop); diff --git a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/logs/OtlpHttpLogRecordExporterBuilder.java b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/logs/OtlpHttpLogRecordExporterBuilder.java index 65f32ec406e..e9cabecb870 100644 --- a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/logs/OtlpHttpLogRecordExporterBuilder.java +++ b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/logs/OtlpHttpLogRecordExporterBuilder.java @@ -21,6 +21,7 @@ import io.opentelemetry.sdk.common.export.RetryPolicy; import java.time.Duration; import java.util.Map; +import java.util.concurrent.ExecutorService; import java.util.concurrent.TimeUnit; import java.util.function.Supplier; import javax.annotation.Nullable; @@ -236,6 +237,19 @@ public OtlpHttpLogRecordExporterBuilder setServiceClassLoader(ClassLoader servic return this; } + /** + * Set the {@link ExecutorService} used to execute requests. + * + *

      NOTE: By calling this method, you are opting into managing the lifecycle of the {@code + * executorService}. {@link ExecutorService#shutdown()} will NOT be called when this exporter is + * shutdown. + */ + public OtlpHttpLogRecordExporterBuilder setExecutorService(ExecutorService executorService) { + requireNonNull(executorService, "executorService"); + delegate.setExecutorService(executorService); + return this; + } + /** * Constructs a new instance of the exporter based on the builder's values. * diff --git a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/metrics/OtlpHttpMetricExporterBuilder.java b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/metrics/OtlpHttpMetricExporterBuilder.java index 7772d42bdf5..3073e8fc12c 100644 --- a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/metrics/OtlpHttpMetricExporterBuilder.java +++ b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/metrics/OtlpHttpMetricExporterBuilder.java @@ -26,6 +26,7 @@ import java.time.Duration; import java.util.Collection; import java.util.Map; +import java.util.concurrent.ExecutorService; import java.util.concurrent.TimeUnit; import java.util.function.Supplier; import javax.annotation.Nullable; @@ -264,6 +265,19 @@ public OtlpHttpMetricExporterBuilder setServiceClassLoader(ClassLoader serviceCl return this; } + /** + * Set the {@link ExecutorService} used to execute requests. + * + *

      NOTE: By calling this method, you are opting into managing the lifecycle of the {@code + * executorService}. {@link ExecutorService#shutdown()} will NOT be called when this exporter is + * shutdown. + */ + public OtlpHttpMetricExporterBuilder setExecutorService(ExecutorService executorService) { + requireNonNull(executorService, "executorService"); + delegate.setExecutorService(executorService); + return this; + } + OtlpHttpMetricExporterBuilder exportAsJson() { delegate.exportAsJson(); return this; diff --git a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/trace/OtlpHttpSpanExporterBuilder.java b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/trace/OtlpHttpSpanExporterBuilder.java index 4a228ef0e5d..cdb262e4ca0 100644 --- a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/trace/OtlpHttpSpanExporterBuilder.java +++ b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/trace/OtlpHttpSpanExporterBuilder.java @@ -21,6 +21,7 @@ import io.opentelemetry.sdk.common.export.RetryPolicy; import java.time.Duration; import java.util.Map; +import java.util.concurrent.ExecutorService; import java.util.concurrent.TimeUnit; import java.util.function.Supplier; import javax.annotation.Nullable; @@ -237,6 +238,19 @@ public OtlpHttpSpanExporterBuilder setServiceClassLoader(ClassLoader serviceClas return this; } + /** + * Set the {@link ExecutorService} used to execute requests. + * + *

      NOTE: By calling this method, you are opting into managing the lifecycle of the {@code + * executorService}. {@link ExecutorService#shutdown()} will NOT be called when this exporter is + * shutdown. + */ + public OtlpHttpSpanExporterBuilder setExecutorService(ExecutorService executorService) { + requireNonNull(executorService, "executorService"); + delegate.setExecutorService(executorService); + return this; + } + /** * Constructs a new instance of the exporter based on the builder's values. * diff --git a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/logs/OtlpGrpcLogRecordExporterBuilder.java b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/logs/OtlpGrpcLogRecordExporterBuilder.java index 6a0c08d7e5c..a42d991926b 100644 --- a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/logs/OtlpGrpcLogRecordExporterBuilder.java +++ b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/logs/OtlpGrpcLogRecordExporterBuilder.java @@ -22,6 +22,7 @@ import java.net.URI; import java.time.Duration; import java.util.Map; +import java.util.concurrent.ExecutorService; import java.util.concurrent.TimeUnit; import java.util.function.Supplier; import javax.annotation.Nullable; @@ -269,6 +270,19 @@ public OtlpGrpcLogRecordExporterBuilder setServiceClassLoader(ClassLoader servic return this; } + /** + * Set the {@link ExecutorService} used to execute requests. + * + *

      NOTE: By calling this method, you are opting into managing the lifecycle of the {@code + * executorService}. {@link ExecutorService#shutdown()} will NOT be called when this exporter is + * shutdown. + */ + public OtlpGrpcLogRecordExporterBuilder setExecutorService(ExecutorService executorService) { + requireNonNull(executorService, "executorService"); + delegate.setExecutorService(executorService); + return this; + } + /** * Constructs a new instance of the exporter based on the builder's values. * diff --git a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/metrics/OtlpGrpcMetricExporterBuilder.java b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/metrics/OtlpGrpcMetricExporterBuilder.java index 64aeb2995e1..a93ee626dde 100644 --- a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/metrics/OtlpGrpcMetricExporterBuilder.java +++ b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/metrics/OtlpGrpcMetricExporterBuilder.java @@ -27,6 +27,7 @@ import java.time.Duration; import java.util.Collection; import java.util.Map; +import java.util.concurrent.ExecutorService; import java.util.concurrent.TimeUnit; import java.util.function.Supplier; import javax.annotation.Nullable; @@ -297,6 +298,19 @@ public OtlpGrpcMetricExporterBuilder setServiceClassLoader(ClassLoader serviceCl return this; } + /** + * Set the {@link ExecutorService} used to execute requests. + * + *

      NOTE: By calling this method, you are opting into managing the lifecycle of the {@code + * executorService}. {@link ExecutorService#shutdown()} will NOT be called when this exporter is + * shutdown. + */ + public OtlpGrpcMetricExporterBuilder setExecutorService(ExecutorService executorService) { + requireNonNull(executorService, "executorService"); + delegate.setExecutorService(executorService); + return this; + } + /** * Constructs a new instance of the exporter based on the builder's values. * diff --git a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/trace/OtlpGrpcSpanExporterBuilder.java b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/trace/OtlpGrpcSpanExporterBuilder.java index 22fb030d1a9..1b2649df15b 100644 --- a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/trace/OtlpGrpcSpanExporterBuilder.java +++ b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/trace/OtlpGrpcSpanExporterBuilder.java @@ -22,6 +22,7 @@ import java.net.URI; import java.time.Duration; import java.util.Map; +import java.util.concurrent.ExecutorService; import java.util.concurrent.TimeUnit; import java.util.function.Supplier; import javax.annotation.Nullable; @@ -266,6 +267,19 @@ public OtlpGrpcSpanExporterBuilder setServiceClassLoader(ClassLoader serviceClas return this; } + /** + * Set the {@link ExecutorService} used to execute requests. + * + *

      NOTE: By calling this method, you are opting into managing the lifecycle of the {@code + * executorService}. {@link ExecutorService#shutdown()} will NOT be called when this exporter is + * shutdown. + */ + public OtlpGrpcSpanExporterBuilder setExecutorService(ExecutorService executorService) { + requireNonNull(executorService, "executorService"); + delegate.setExecutorService(executorService); + return this; + } + /** * Constructs a new instance of the exporter based on the builder's values. * diff --git a/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/AbstractGrpcTelemetryExporterTest.java b/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/AbstractGrpcTelemetryExporterTest.java index 765d9195db1..d8caa8ad22d 100644 --- a/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/AbstractGrpcTelemetryExporterTest.java +++ b/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/AbstractGrpcTelemetryExporterTest.java @@ -60,6 +60,7 @@ import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletionStage; import java.util.concurrent.ConcurrentLinkedQueue; +import java.util.concurrent.Executors; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicInteger; import java.util.function.Function; @@ -814,6 +815,31 @@ void overrideHost() { .satisfies(req -> assertThat(req.authority()).isEqualTo("opentelemetry")); } + @Test + void executorService() { + ExecutorServiceSpy executorService = + new ExecutorServiceSpy(Executors.newSingleThreadExecutor()); + + TelemetryExporter exporter = + exporterBuilder() + .setEndpoint(server.httpUri().toString()) + .setExecutorService(executorService) + .build(); + + try { + CompletableResultCode result = + exporter.export(Collections.singletonList(generateFakeTelemetry())); + + assertThat(result.join(10, TimeUnit.SECONDS).isSuccess()).isTrue(); + assertThat(executorService.getTaskCount()).isPositive(); + } finally { + exporter.shutdown(); + // If setting executor, the user is responsible for calling shutdown + assertThat(executorService.isShutdown()).isFalse(); + executorService.shutdown(); + } + } + @Test @SuppressWarnings("PreferJavaTimeOverload") void validConfig() { diff --git a/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/AbstractHttpTelemetryExporterTest.java b/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/AbstractHttpTelemetryExporterTest.java index 318511c1efc..f59dc1ec3b4 100644 --- a/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/AbstractHttpTelemetryExporterTest.java +++ b/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/AbstractHttpTelemetryExporterTest.java @@ -62,6 +62,7 @@ import java.util.List; import java.util.concurrent.CompletableFuture; import java.util.concurrent.ConcurrentLinkedQueue; +import java.util.concurrent.Executors; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicInteger; import java.util.function.Function; @@ -697,6 +698,31 @@ void proxy() { } } + @Test + void executorService() { + ExecutorServiceSpy executorService = + new ExecutorServiceSpy(Executors.newSingleThreadExecutor()); + + TelemetryExporter exporter = + exporterBuilder() + .setEndpoint(server.httpUri() + path) + .setExecutorService(executorService) + .build(); + + try { + CompletableResultCode result = + exporter.export(Collections.singletonList(generateFakeTelemetry())); + + assertThat(result.join(10, TimeUnit.SECONDS).isSuccess()).isTrue(); + assertThat(executorService.getTaskCount()).isPositive(); + } finally { + exporter.shutdown(); + // If setting executor, the user is responsible for calling shutdown + assertThat(executorService.isShutdown()).isFalse(); + executorService.shutdown(); + } + } + @Test @SuppressWarnings("PreferJavaTimeOverload") void validConfig() { diff --git a/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/ExecutorServiceSpy.java b/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/ExecutorServiceSpy.java new file mode 100644 index 00000000000..f16cf99edb0 --- /dev/null +++ b/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/ExecutorServiceSpy.java @@ -0,0 +1,113 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.exporter.otlp.testing.internal; + +import java.util.Collection; +import java.util.List; +import java.util.concurrent.Callable; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Future; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; +import org.jetbrains.annotations.NotNull; + +class ExecutorServiceSpy implements ExecutorService { + + private final ExecutorService delegate; + private int taskCount; + + ExecutorServiceSpy(ExecutorService delegate) { + this.delegate = delegate; + } + + @Override + public void shutdown() { + delegate.shutdown(); + } + + @NotNull + @Override + public List shutdownNow() { + return delegate.shutdownNow(); + } + + @Override + public boolean isShutdown() { + return delegate.isShutdown(); + } + + @Override + public boolean isTerminated() { + return delegate.isTerminated(); + } + + @Override + public boolean awaitTermination(long timeout, @NotNull TimeUnit unit) + throws InterruptedException { + return delegate.awaitTermination(timeout, unit); + } + + @NotNull + @Override + public Future submit(@NotNull Callable task) { + taskCount++; + return delegate.submit(task); + } + + @NotNull + @Override + public Future submit(@NotNull Runnable task, T result) { + taskCount++; + return delegate.submit(task, result); + } + + @NotNull + @Override + public Future submit(@NotNull Runnable task) { + taskCount++; + return delegate.submit(task); + } + + @NotNull + @Override + public List> invokeAll(@NotNull Collection> tasks) + throws InterruptedException { + return delegate.invokeAll(tasks); + } + + @NotNull + @Override + public List> invokeAll( + @NotNull Collection> tasks, long timeout, @NotNull TimeUnit unit) + throws InterruptedException { + return delegate.invokeAll(tasks, timeout, unit); + } + + @NotNull + @Override + public T invokeAny(@NotNull Collection> tasks) + throws InterruptedException, ExecutionException { + return delegate.invokeAny(tasks); + } + + @Override + public T invokeAny( + @NotNull Collection> tasks, long timeout, @NotNull TimeUnit unit) + throws InterruptedException, ExecutionException, TimeoutException { + return delegate.invokeAny(tasks, timeout, unit); + } + + @Override + public void execute(@NotNull Runnable command) { + taskCount++; + delegate.execute(command); + } + + public int getTaskCount() { + return taskCount; + } +} diff --git a/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/GrpcLogRecordExporterBuilderWrapper.java b/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/GrpcLogRecordExporterBuilderWrapper.java index d2301babe92..e0a2da5c767 100644 --- a/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/GrpcLogRecordExporterBuilderWrapper.java +++ b/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/GrpcLogRecordExporterBuilderWrapper.java @@ -12,6 +12,7 @@ import io.opentelemetry.sdk.logs.data.LogRecordData; import java.time.Duration; import java.util.Map; +import java.util.concurrent.ExecutorService; import java.util.concurrent.TimeUnit; import java.util.function.Supplier; import javax.annotation.Nullable; @@ -119,6 +120,13 @@ public TelemetryExporterBuilder setServiceClassLoader( return this; } + @Override + public TelemetryExporterBuilder setExecutorService( + ExecutorService executorService) { + builder.setExecutorService(executorService); + return this; + } + @Override public TelemetryExporter build() { return TelemetryExporter.wrap(builder.build()); diff --git a/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/GrpcMetricExporterBuilderWrapper.java b/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/GrpcMetricExporterBuilderWrapper.java index c0f6d6f218a..09bd0a339be 100644 --- a/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/GrpcMetricExporterBuilderWrapper.java +++ b/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/GrpcMetricExporterBuilderWrapper.java @@ -12,6 +12,7 @@ import io.opentelemetry.sdk.metrics.data.MetricData; import java.time.Duration; import java.util.Map; +import java.util.concurrent.ExecutorService; import java.util.concurrent.TimeUnit; import java.util.function.Supplier; import javax.annotation.Nullable; @@ -119,6 +120,12 @@ public TelemetryExporterBuilder setServiceClassLoader( return this; } + @Override + public TelemetryExporterBuilder setExecutorService(ExecutorService executorService) { + builder.setExecutorService(executorService); + return this; + } + @Override public TelemetryExporter build() { return TelemetryExporter.wrap(builder.build()); diff --git a/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/GrpcSpanExporterBuilderWrapper.java b/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/GrpcSpanExporterBuilderWrapper.java index 71a9bbe29ea..0ddb5e46d85 100644 --- a/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/GrpcSpanExporterBuilderWrapper.java +++ b/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/GrpcSpanExporterBuilderWrapper.java @@ -12,6 +12,7 @@ import io.opentelemetry.sdk.trace.data.SpanData; import java.time.Duration; import java.util.Map; +import java.util.concurrent.ExecutorService; import java.util.concurrent.TimeUnit; import java.util.function.Supplier; import javax.annotation.Nullable; @@ -119,6 +120,12 @@ public TelemetryExporterBuilder setServiceClassLoader(ClassLoader serv return this; } + @Override + public TelemetryExporterBuilder setExecutorService(ExecutorService executorService) { + builder.setExecutorService(executorService); + return this; + } + @Override public TelemetryExporter build() { return TelemetryExporter.wrap(builder.build()); diff --git a/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/HttpLogRecordExporterBuilderWrapper.java b/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/HttpLogRecordExporterBuilderWrapper.java index 1d4738f6084..0060bde1d16 100644 --- a/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/HttpLogRecordExporterBuilderWrapper.java +++ b/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/HttpLogRecordExporterBuilderWrapper.java @@ -11,6 +11,7 @@ import io.opentelemetry.sdk.logs.data.LogRecordData; import java.time.Duration; import java.util.Map; +import java.util.concurrent.ExecutorService; import java.util.concurrent.TimeUnit; import java.util.function.Supplier; import javax.annotation.Nullable; @@ -119,6 +120,13 @@ public TelemetryExporterBuilder setServiceClassLoader( return this; } + @Override + public TelemetryExporterBuilder setExecutorService( + ExecutorService executorService) { + builder.setExecutorService(executorService); + return this; + } + @Override public TelemetryExporter build() { return TelemetryExporter.wrap(builder.build()); diff --git a/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/HttpMetricExporterBuilderWrapper.java b/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/HttpMetricExporterBuilderWrapper.java index 2510af696ef..f9a9f87c7ae 100644 --- a/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/HttpMetricExporterBuilderWrapper.java +++ b/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/HttpMetricExporterBuilderWrapper.java @@ -11,6 +11,7 @@ import io.opentelemetry.sdk.metrics.data.MetricData; import java.time.Duration; import java.util.Map; +import java.util.concurrent.ExecutorService; import java.util.concurrent.TimeUnit; import java.util.function.Supplier; import javax.annotation.Nullable; @@ -118,6 +119,12 @@ public TelemetryExporterBuilder setServiceClassLoader( return this; } + @Override + public TelemetryExporterBuilder setExecutorService(ExecutorService executorService) { + builder.setExecutorService(executorService); + return this; + } + @Override public TelemetryExporter build() { return TelemetryExporter.wrap(builder.build()); diff --git a/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/HttpSpanExporterBuilderWrapper.java b/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/HttpSpanExporterBuilderWrapper.java index a13afb47341..7bdca0f20e8 100644 --- a/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/HttpSpanExporterBuilderWrapper.java +++ b/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/HttpSpanExporterBuilderWrapper.java @@ -11,6 +11,7 @@ import io.opentelemetry.sdk.trace.data.SpanData; import java.time.Duration; import java.util.Map; +import java.util.concurrent.ExecutorService; import java.util.concurrent.TimeUnit; import java.util.function.Supplier; import javax.annotation.Nullable; @@ -117,6 +118,12 @@ public TelemetryExporterBuilder setServiceClassLoader(ClassLoader serv return this; } + @Override + public TelemetryExporterBuilder setExecutorService(ExecutorService executorService) { + builder.setExecutorService(executorService); + return this; + } + @Override public TelemetryExporter build() { return TelemetryExporter.wrap(builder.build()); diff --git a/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/ManagedChannelTelemetryExporterBuilder.java b/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/ManagedChannelTelemetryExporterBuilder.java index 6f01128a578..8b080cfbfda 100644 --- a/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/ManagedChannelTelemetryExporterBuilder.java +++ b/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/ManagedChannelTelemetryExporterBuilder.java @@ -22,6 +22,7 @@ import java.time.Duration; import java.util.Collection; import java.util.Map; +import java.util.concurrent.ExecutorService; import java.util.concurrent.TimeUnit; import java.util.function.Supplier; import javax.annotation.Nullable; @@ -165,6 +166,12 @@ public TelemetryExporterBuilder setServiceClassLoader(ClassLoader serviceClas return this; } + @Override + public TelemetryExporterBuilder setExecutorService(ExecutorService executorService) { + delegate.setExecutorService(executorService); + return this; + } + @Override public TelemetryExporter build() { Runnable shutdownCallback; diff --git a/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/TelemetryExporterBuilder.java b/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/TelemetryExporterBuilder.java index b37ce746db7..f8cf7ef4567 100644 --- a/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/TelemetryExporterBuilder.java +++ b/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/TelemetryExporterBuilder.java @@ -15,6 +15,7 @@ import io.opentelemetry.sdk.trace.data.SpanData; import java.time.Duration; import java.util.Map; +import java.util.concurrent.ExecutorService; import java.util.concurrent.TimeUnit; import java.util.function.Supplier; import javax.annotation.Nullable; @@ -65,5 +66,7 @@ static TelemetryExporterBuilder wrap(OtlpGrpcLogRecordExporterBui TelemetryExporterBuilder setServiceClassLoader(ClassLoader serviceClassLoader); + TelemetryExporterBuilder setExecutorService(ExecutorService executorService); + TelemetryExporter build(); } diff --git a/exporters/sender/grpc-managed-channel/src/main/java/io/opentelemetry/exporter/sender/grpc/managedchannel/internal/UpstreamGrpcSender.java b/exporters/sender/grpc-managed-channel/src/main/java/io/opentelemetry/exporter/sender/grpc/managedchannel/internal/UpstreamGrpcSender.java index 1f1ae5e4d28..85a677d1894 100644 --- a/exporters/sender/grpc-managed-channel/src/main/java/io/opentelemetry/exporter/sender/grpc/managedchannel/internal/UpstreamGrpcSender.java +++ b/exporters/sender/grpc-managed-channel/src/main/java/io/opentelemetry/exporter/sender/grpc/managedchannel/internal/UpstreamGrpcSender.java @@ -22,6 +22,8 @@ import java.time.Duration; import java.util.List; import java.util.Map; +import java.util.concurrent.Executor; +import java.util.concurrent.ExecutorService; import java.util.function.Consumer; import java.util.function.Supplier; import javax.annotation.Nullable; @@ -38,17 +40,20 @@ public final class UpstreamGrpcSender implements GrpcSender private final boolean shutdownChannel; private final long timeoutNanos; private final Supplier>> headersSupplier; + private final Executor executor; /** Creates a new {@link UpstreamGrpcSender}. */ public UpstreamGrpcSender( MarshalerServiceStub stub, boolean shutdownChannel, long timeoutNanos, - Supplier>> headersSupplier) { + Supplier>> headersSupplier, + @Nullable ExecutorService executorService) { this.stub = stub; this.shutdownChannel = shutdownChannel; this.timeoutNanos = timeoutNanos; this.headersSupplier = headersSupplier; + this.executor = executorService == null ? MoreExecutors.directExecutor() : executorService; } @Override @@ -88,7 +93,7 @@ public void onFailure(Throwable t) { } } }, - MoreExecutors.directExecutor()); + executor); } /** diff --git a/exporters/sender/grpc-managed-channel/src/main/java/io/opentelemetry/exporter/sender/grpc/managedchannel/internal/UpstreamGrpcSenderProvider.java b/exporters/sender/grpc-managed-channel/src/main/java/io/opentelemetry/exporter/sender/grpc/managedchannel/internal/UpstreamGrpcSenderProvider.java index c2c7cb3d85c..3b26aeedbfd 100644 --- a/exporters/sender/grpc-managed-channel/src/main/java/io/opentelemetry/exporter/sender/grpc/managedchannel/internal/UpstreamGrpcSenderProvider.java +++ b/exporters/sender/grpc-managed-channel/src/main/java/io/opentelemetry/exporter/sender/grpc/managedchannel/internal/UpstreamGrpcSenderProvider.java @@ -80,7 +80,8 @@ public OutputStream compress(OutputStream os) throws IOException { stub, shutdownChannel, grpcSenderConfig.getTimeoutNanos(), - grpcSenderConfig.getHeadersSupplier()); + grpcSenderConfig.getHeadersSupplier(), + grpcSenderConfig.getExecutorService()); } /** diff --git a/exporters/sender/jdk/src/main/java/io/opentelemetry/exporter/sender/jdk/internal/JdkHttpSender.java b/exporters/sender/jdk/src/main/java/io/opentelemetry/exporter/sender/jdk/internal/JdkHttpSender.java index c4d3276b495..20d219edaf5 100644 --- a/exporters/sender/jdk/src/main/java/io/opentelemetry/exporter/sender/jdk/internal/JdkHttpSender.java +++ b/exporters/sender/jdk/src/main/java/io/opentelemetry/exporter/sender/jdk/internal/JdkHttpSender.java @@ -61,7 +61,8 @@ public final class JdkHttpSender implements HttpSender { private static final Logger logger = Logger.getLogger(JdkHttpSender.class.getName()); - private final ExecutorService executorService = Executors.newFixedThreadPool(5); + private final boolean managedExecutor; + private final ExecutorService executorService; private final HttpClient client; private final URI uri; @Nullable private final Compressor compressor; @@ -81,7 +82,8 @@ public final class JdkHttpSender implements HttpSender { String contentType, long timeoutNanos, Supplier>> headerSupplier, - @Nullable RetryPolicy retryPolicy) { + @Nullable RetryPolicy retryPolicy, + @Nullable ExecutorService executorService) { this.client = client; try { this.uri = new URI(endpoint); @@ -98,6 +100,13 @@ public final class JdkHttpSender implements HttpSender { Optional.ofNullable(retryPolicy) .map(RetryPolicy::getRetryExceptionPredicate) .orElse(JdkHttpSender::isRetryableException); + if (executorService == null) { + this.executorService = Executors.newFixedThreadPool(5); + this.managedExecutor = true; + } else { + this.executorService = executorService; + this.managedExecutor = false; + } } JdkHttpSender( @@ -110,7 +119,8 @@ public final class JdkHttpSender implements HttpSender { Supplier>> headerSupplier, @Nullable RetryPolicy retryPolicy, @Nullable ProxyOptions proxyOptions, - @Nullable SSLContext sslContext) { + @Nullable SSLContext sslContext, + @Nullable ExecutorService executorService) { this( configureClient(sslContext, connectTimeoutNanos, proxyOptions), endpoint, @@ -119,7 +129,8 @@ public final class JdkHttpSender implements HttpSender { contentType, timeoutNanos, headerSupplier, - retryPolicy); + retryPolicy, + executorService); } private static HttpClient configureClient( @@ -363,7 +374,9 @@ private void resetPool() { @Override public CompletableResultCode shutdown() { - executorService.shutdown(); + if (managedExecutor) { + executorService.shutdown(); + } return CompletableResultCode.ofSuccess(); } } diff --git a/exporters/sender/jdk/src/main/java/io/opentelemetry/exporter/sender/jdk/internal/JdkHttpSenderProvider.java b/exporters/sender/jdk/src/main/java/io/opentelemetry/exporter/sender/jdk/internal/JdkHttpSenderProvider.java index 4cf4f26a2a1..35b7f819aa2 100644 --- a/exporters/sender/jdk/src/main/java/io/opentelemetry/exporter/sender/jdk/internal/JdkHttpSenderProvider.java +++ b/exporters/sender/jdk/src/main/java/io/opentelemetry/exporter/sender/jdk/internal/JdkHttpSenderProvider.java @@ -29,6 +29,7 @@ public HttpSender createSender(HttpSenderConfig httpSenderConfig) { httpSenderConfig.getHeadersSupplier(), httpSenderConfig.getRetryPolicy(), httpSenderConfig.getProxyOptions(), - httpSenderConfig.getSslContext()); + httpSenderConfig.getSslContext(), + httpSenderConfig.getExecutorService()); } } diff --git a/exporters/sender/jdk/src/test/java/io/opentelemetry/exporter/sender/jdk/internal/JdkHttpSenderTest.java b/exporters/sender/jdk/src/test/java/io/opentelemetry/exporter/sender/jdk/internal/JdkHttpSenderTest.java index 5df723b6560..c5c26f69bec 100644 --- a/exporters/sender/jdk/src/test/java/io/opentelemetry/exporter/sender/jdk/internal/JdkHttpSenderTest.java +++ b/exporters/sender/jdk/src/test/java/io/opentelemetry/exporter/sender/jdk/internal/JdkHttpSenderTest.java @@ -62,10 +62,8 @@ void setup() throws IOException, InterruptedException { "text/plain", Duration.ofSeconds(10).toNanos(), Collections::emptyMap, - RetryPolicy.builder() - .setMaxAttempts(2) - .setInitialBackoff(Duration.ofMillis(1)) - .build()); + RetryPolicy.builder().setMaxAttempts(2).setInitialBackoff(Duration.ofMillis(1)).build(), + null); } @Test @@ -90,10 +88,8 @@ void sendInternal_RetryableConnectException() throws IOException, InterruptedExc "text/plain", Duration.ofSeconds(10).toNanos(), Collections::emptyMap, - RetryPolicy.builder() - .setMaxAttempts(2) - .setInitialBackoff(Duration.ofMillis(1)) - .build()); + RetryPolicy.builder().setMaxAttempts(2).setInitialBackoff(Duration.ofMillis(1)).build(), + null); assertThatThrownBy(() -> sender.sendInternal(new NoOpMarshaler())) .satisfies( @@ -149,6 +145,7 @@ void connectTimeout() { Collections::emptyMap, null, null, + null, null); assertThat(sender) diff --git a/exporters/sender/okhttp/src/main/java/io/opentelemetry/exporter/sender/okhttp/internal/OkHttpGrpcSender.java b/exporters/sender/okhttp/src/main/java/io/opentelemetry/exporter/sender/okhttp/internal/OkHttpGrpcSender.java index a0305cb863f..673e4271cb0 100644 --- a/exporters/sender/okhttp/src/main/java/io/opentelemetry/exporter/sender/okhttp/internal/OkHttpGrpcSender.java +++ b/exporters/sender/okhttp/src/main/java/io/opentelemetry/exporter/sender/okhttp/internal/OkHttpGrpcSender.java @@ -40,6 +40,7 @@ import java.util.Collections; import java.util.List; import java.util.Map; +import java.util.concurrent.ExecutorService; import java.util.function.Consumer; import java.util.function.Supplier; import javax.annotation.Nullable; @@ -48,6 +49,7 @@ import okhttp3.Call; import okhttp3.Callback; import okhttp3.ConnectionSpec; +import okhttp3.Dispatcher; import okhttp3.HttpUrl; import okhttp3.OkHttpClient; import okhttp3.Protocol; @@ -66,6 +68,7 @@ public final class OkHttpGrpcSender implements GrpcSender>> headersSupplier; @@ -80,14 +83,25 @@ public OkHttpGrpcSender( Supplier>> headersSupplier, @Nullable RetryPolicy retryPolicy, @Nullable SSLContext sslContext, - @Nullable X509TrustManager trustManager) { + @Nullable X509TrustManager trustManager, + @Nullable ExecutorService executorService) { int callTimeoutMillis = (int) Math.min(Duration.ofNanos(timeoutNanos).toMillis(), Integer.MAX_VALUE); int connectTimeoutMillis = (int) Math.min(Duration.ofNanos(connectTimeoutNanos).toMillis(), Integer.MAX_VALUE); + + Dispatcher dispatcher; + if (executorService == null) { + dispatcher = OkHttpUtil.newDispatcher(); + this.managedExecutor = true; + } else { + dispatcher = new Dispatcher(executorService); + this.managedExecutor = false; + } + OkHttpClient.Builder clientBuilder = new OkHttpClient.Builder() - .dispatcher(OkHttpUtil.newDispatcher()) + .dispatcher(dispatcher) .callTimeout(Duration.ofMillis(callTimeoutMillis)) .connectTimeout(Duration.ofMillis(connectTimeoutMillis)); if (retryPolicy != null) { @@ -198,7 +212,9 @@ private static String grpcMessage(Response response) { @Override public CompletableResultCode shutdown() { client.dispatcher().cancelAll(); - client.dispatcher().executorService().shutdownNow(); + if (managedExecutor) { + client.dispatcher().executorService().shutdownNow(); + } client.connectionPool().evictAll(); return CompletableResultCode.ofSuccess(); } diff --git a/exporters/sender/okhttp/src/main/java/io/opentelemetry/exporter/sender/okhttp/internal/OkHttpGrpcSenderProvider.java b/exporters/sender/okhttp/src/main/java/io/opentelemetry/exporter/sender/okhttp/internal/OkHttpGrpcSenderProvider.java index c87f2739b4c..4d7f0136919 100644 --- a/exporters/sender/okhttp/src/main/java/io/opentelemetry/exporter/sender/okhttp/internal/OkHttpGrpcSenderProvider.java +++ b/exporters/sender/okhttp/src/main/java/io/opentelemetry/exporter/sender/okhttp/internal/OkHttpGrpcSenderProvider.java @@ -28,6 +28,7 @@ public GrpcSender createSender(GrpcSenderConfig grpc grpcSenderConfig.getHeadersSupplier(), grpcSenderConfig.getRetryPolicy(), grpcSenderConfig.getSslContext(), - grpcSenderConfig.getTrustManager()); + grpcSenderConfig.getTrustManager(), + grpcSenderConfig.getExecutorService()); } } diff --git a/exporters/sender/okhttp/src/main/java/io/opentelemetry/exporter/sender/okhttp/internal/OkHttpHttpSender.java b/exporters/sender/okhttp/src/main/java/io/opentelemetry/exporter/sender/okhttp/internal/OkHttpHttpSender.java index 9161aa42088..7b5e2081ec4 100644 --- a/exporters/sender/okhttp/src/main/java/io/opentelemetry/exporter/sender/okhttp/internal/OkHttpHttpSender.java +++ b/exporters/sender/okhttp/src/main/java/io/opentelemetry/exporter/sender/okhttp/internal/OkHttpHttpSender.java @@ -18,6 +18,7 @@ import java.util.Collections; import java.util.List; import java.util.Map; +import java.util.concurrent.ExecutorService; import java.util.function.Consumer; import java.util.function.Supplier; import javax.annotation.Nullable; @@ -26,6 +27,7 @@ import okhttp3.Call; import okhttp3.Callback; import okhttp3.ConnectionSpec; +import okhttp3.Dispatcher; import okhttp3.HttpUrl; import okhttp3.MediaType; import okhttp3.OkHttpClient; @@ -43,6 +45,7 @@ */ public final class OkHttpHttpSender implements HttpSender { + private final boolean managedExecutor; private final OkHttpClient client; private final HttpUrl url; @Nullable private final Compressor compressor; @@ -63,14 +66,25 @@ public OkHttpHttpSender( @Nullable ProxyOptions proxyOptions, @Nullable RetryPolicy retryPolicy, @Nullable SSLContext sslContext, - @Nullable X509TrustManager trustManager) { + @Nullable X509TrustManager trustManager, + @Nullable ExecutorService executorService) { int callTimeoutMillis = (int) Math.min(Duration.ofNanos(timeoutNanos).toMillis(), Integer.MAX_VALUE); int connectTimeoutMillis = (int) Math.min(Duration.ofNanos(connectionTimeoutNanos).toMillis(), Integer.MAX_VALUE); + + Dispatcher dispatcher; + if (executorService == null) { + dispatcher = OkHttpUtil.newDispatcher(); + this.managedExecutor = true; + } else { + dispatcher = new Dispatcher(executorService); + this.managedExecutor = false; + } + OkHttpClient.Builder builder = new OkHttpClient.Builder() - .dispatcher(OkHttpUtil.newDispatcher()) + .dispatcher(dispatcher) .connectTimeout(Duration.ofMillis(connectTimeoutMillis)) .callTimeout(Duration.ofMillis(callTimeoutMillis)); @@ -162,7 +176,9 @@ public byte[] responseBody() throws IOException { @Override public CompletableResultCode shutdown() { client.dispatcher().cancelAll(); - client.dispatcher().executorService().shutdownNow(); + if (managedExecutor) { + client.dispatcher().executorService().shutdownNow(); + } client.connectionPool().evictAll(); return CompletableResultCode.ofSuccess(); } diff --git a/exporters/sender/okhttp/src/main/java/io/opentelemetry/exporter/sender/okhttp/internal/OkHttpHttpSenderProvider.java b/exporters/sender/okhttp/src/main/java/io/opentelemetry/exporter/sender/okhttp/internal/OkHttpHttpSenderProvider.java index 989f3644506..8c7c3aa0f4b 100644 --- a/exporters/sender/okhttp/src/main/java/io/opentelemetry/exporter/sender/okhttp/internal/OkHttpHttpSenderProvider.java +++ b/exporters/sender/okhttp/src/main/java/io/opentelemetry/exporter/sender/okhttp/internal/OkHttpHttpSenderProvider.java @@ -30,6 +30,7 @@ public HttpSender createSender(HttpSenderConfig httpSenderConfig) { httpSenderConfig.getProxyOptions(), httpSenderConfig.getRetryPolicy(), httpSenderConfig.getSslContext(), - httpSenderConfig.getTrustManager()); + httpSenderConfig.getTrustManager(), + httpSenderConfig.getExecutorService()); } } diff --git a/exporters/sender/okhttp/src/test/java/io/opentelemetry/exporter/sender/okhttp/internal/OkHttpGrpcSuppressionTest.java b/exporters/sender/okhttp/src/test/java/io/opentelemetry/exporter/sender/okhttp/internal/OkHttpGrpcSuppressionTest.java index 6eb0a4393b3..39457f4e2de 100644 --- a/exporters/sender/okhttp/src/test/java/io/opentelemetry/exporter/sender/okhttp/internal/OkHttpGrpcSuppressionTest.java +++ b/exporters/sender/okhttp/src/test/java/io/opentelemetry/exporter/sender/okhttp/internal/OkHttpGrpcSuppressionTest.java @@ -21,7 +21,7 @@ void send(OkHttpGrpcSender sender, Runnable onSuccess, Runnable @Override OkHttpGrpcSender createSender(String endpoint) { return new OkHttpGrpcSender<>( - "https://localhost", null, 10L, 10L, Collections::emptyMap, null, null, null); + "https://localhost", null, 10L, 10L, Collections::emptyMap, null, null, null, null); } protected static class DummyMarshaler extends MarshalerWithSize { diff --git a/exporters/sender/okhttp/src/test/java/io/opentelemetry/exporter/sender/okhttp/internal/OkHttpHttpSuppressionTest.java b/exporters/sender/okhttp/src/test/java/io/opentelemetry/exporter/sender/okhttp/internal/OkHttpHttpSuppressionTest.java index 046dbee521a..38686c36526 100644 --- a/exporters/sender/okhttp/src/test/java/io/opentelemetry/exporter/sender/okhttp/internal/OkHttpHttpSuppressionTest.java +++ b/exporters/sender/okhttp/src/test/java/io/opentelemetry/exporter/sender/okhttp/internal/OkHttpHttpSuppressionTest.java @@ -46,6 +46,7 @@ OkHttpHttpSender createSender(String endpoint) { null, null, null, + null, null); } } From 490173b0dad1c96e2e6b16a50637a05c810922ed Mon Sep 17 00:00:00 2001 From: jack-berg <34418638+jack-berg@users.noreply.github.com> Date: Fri, 14 Mar 2025 13:51:46 -0500 Subject: [PATCH 870/901] Remove support for otel.experimental.exporter.otlp.retry.enabled (#7200) --- .../exporter/otlp/internal/OtlpConfigUtil.java | 7 ------- 1 file changed, 7 deletions(-) diff --git a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/OtlpConfigUtil.java b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/OtlpConfigUtil.java index bf580474066..8bfcb4b3960 100644 --- a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/OtlpConfigUtil.java +++ b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/OtlpConfigUtil.java @@ -134,13 +134,6 @@ public static void configureOtlpExporterBuilder( } Boolean retryDisabled = config.getBoolean("otel.java.exporter.otlp.retry.disabled"); - if (retryDisabled == null) { - Boolean experimentalRetryEnabled = - config.getBoolean("otel.experimental.exporter.otlp.retry.enabled"); - if (experimentalRetryEnabled != null) { - retryDisabled = !experimentalRetryEnabled; - } - } if (retryDisabled != null && retryDisabled) { setRetryPolicy.accept(null); } From 09bac7d077b1dacf8001370d2fa787f77ab32756 Mon Sep 17 00:00:00 2001 From: jack-berg <34418638+jack-berg@users.noreply.github.com> Date: Mon, 17 Mar 2025 09:44:49 -0500 Subject: [PATCH 871/901] Stable cardinality limit property otel.java.metrics.cardinality.limit (#7199) --- .../MeterProviderConfiguration.java | 22 ++++++++++++----- .../MeterProviderConfigurationTest.java | 24 +++++++++++++++++-- 2 files changed, 38 insertions(+), 8 deletions(-) diff --git a/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/MeterProviderConfiguration.java b/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/MeterProviderConfiguration.java index 161fc4895b1..8686c1208c1 100644 --- a/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/MeterProviderConfiguration.java +++ b/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/MeterProviderConfiguration.java @@ -21,10 +21,13 @@ import java.util.Locale; import java.util.Set; import java.util.function.BiFunction; +import java.util.logging.Logger; import java.util.stream.Collectors; final class MeterProviderConfiguration { + private static final Logger logger = Logger.getLogger(MeterProviderConfiguration.class.getName()); + static void configureMeterProvider( SdkMeterProviderBuilder meterProviderBuilder, ConfigProperties config, @@ -51,19 +54,26 @@ static void configureMeterProvider( break; } - int cardinalityLimit = - config.getInt( - "otel.experimental.metrics.cardinality.limit", MetricStorage.DEFAULT_MAX_CARDINALITY); - if (cardinalityLimit < 1) { - throw new ConfigurationException("otel.experimental.metrics.cardinality.limit must be >= 1"); + Integer cardinalityLimit = config.getInt("otel.java.metrics.cardinality.limit"); + if (cardinalityLimit == null) { + cardinalityLimit = config.getInt("otel.experimental.metrics.cardinality.limit"); + if (cardinalityLimit != null) { + logger.warning( + "otel.experimental.metrics.cardinality.limit is deprecated and will be removed after 1.51.0 release. Please use otel.java.metrics.cardinality.limit instead."); + } + } + if (cardinalityLimit != null && cardinalityLimit < 1) { + throw new ConfigurationException("otel.java.metrics.cardinality.limit must be >= 1"); } + int resolvedCardinalityLimit = + cardinalityLimit == null ? MetricStorage.DEFAULT_MAX_CARDINALITY : cardinalityLimit; configureMetricReaders( config, spiHelper, metricReaderCustomizer, metricExporterCustomizer, closeables) .forEach( reader -> meterProviderBuilder.registerMetricReader( - reader, instrumentType -> cardinalityLimit)); + reader, instrumentType -> resolvedCardinalityLimit)); } static List configureMetricReaders( diff --git a/sdk-extensions/autoconfigure/src/testFullConfig/java/io/opentelemetry/sdk/autoconfigure/MeterProviderConfigurationTest.java b/sdk-extensions/autoconfigure/src/testFullConfig/java/io/opentelemetry/sdk/autoconfigure/MeterProviderConfigurationTest.java index 52945668621..da5ce587d27 100644 --- a/sdk-extensions/autoconfigure/src/testFullConfig/java/io/opentelemetry/sdk/autoconfigure/MeterProviderConfigurationTest.java +++ b/sdk-extensions/autoconfigure/src/testFullConfig/java/io/opentelemetry/sdk/autoconfigure/MeterProviderConfigurationTest.java @@ -46,7 +46,7 @@ void configureMeterProvider_InvalidCardinalityLimit() { ImmutableMap.of( "otel.metrics.exporter", "logging", - "otel.experimental.metrics.cardinality.limit", + "otel.java.metrics.cardinality.limit", "0")), spiHelper, (a, b) -> a, @@ -54,7 +54,7 @@ void configureMeterProvider_InvalidCardinalityLimit() { closeables); }) .isInstanceOf(ConfigurationException.class) - .hasMessage("otel.experimental.metrics.cardinality.limit must be >= 1"); + .hasMessage("otel.java.metrics.cardinality.limit must be >= 1"); cleanup.addCloseables(closeables); } @@ -77,6 +77,26 @@ void configureMeterProvider_ConfiguresCardinalityLimit() { // Customized limit cardinality limit to 100 builder = SdkMeterProvider.builder(); + MeterProviderConfiguration.configureMeterProvider( + builder, + DefaultConfigProperties.createFromMap( + ImmutableMap.of( + "otel.metrics.exporter", + "logging", + "otel.java.metrics.cardinality.limit", + "100", + // otel.java.metrics.cardinality.limit takes priority over deprecated property + "otel.experimental.metrics.cardinality.limit", + "200")), + spiHelper, + (a, b) -> a, + (a, b) -> a, + closeables); + cleanup.addCloseables(closeables); + assertCardinalityLimit(builder, 100); + + // Deprecated property + builder = SdkMeterProvider.builder(); MeterProviderConfiguration.configureMeterProvider( builder, DefaultConfigProperties.createFromMap( From 9c1b9f609fe6ece64923c126990f57981b7171fc Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 17 Mar 2025 10:13:02 -0700 Subject: [PATCH 872/901] fix(deps): update dependency com.google.api.grpc:proto-google-common-protos to v2.54.1 (#7198) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- dependencyManagement/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index e96ebb7317b..ab1e3088cab 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -73,7 +73,7 @@ val DEPENDENCIES = listOf( "io.prometheus:simpleclient_httpserver:${prometheusClientVersion}", "javax.annotation:javax.annotation-api:1.3.2", "com.github.stefanbirkner:system-rules:1.19.0", - "com.google.api.grpc:proto-google-common-protos:2.54.0", + "com.google.api.grpc:proto-google-common-protos:2.54.1", "com.google.code.findbugs:jsr305:3.0.2", "com.google.guava:guava-beta-checker:1.0", "com.sun.net.httpserver:http:20070405", From 9b596d03d1e2b7ee80c14b4f304fb7cfbefd7fe5 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 21 Mar 2025 07:41:31 -0700 Subject: [PATCH 873/901] fix(deps): update junit5 monorepo to v5.12.1 (#7203) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- dependencyManagement/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index ab1e3088cab..e95cec434f7 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -37,7 +37,7 @@ val opencensusVersion = "0.31.1" val prometheusClientVersion = "0.16.0" val prometheusServerVersion = "1.3.6" val armeriaVersion = "1.32.0" -val junitVersion = "5.12.0" +val junitVersion = "5.12.1" val DEPENDENCIES = listOf( "org.junit.jupiter:junit-jupiter-api:${junitVersion}", From 9172089ab928e9ed8e21bb57fa6edf8f545698cf Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 21 Mar 2025 07:44:54 -0700 Subject: [PATCH 874/901] fix(deps): update dependency nl.jqno.equalsverifier:equalsverifier to v3.19.2 (#7202) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- dependencyManagement/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index e95cec434f7..735e81b6311 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -89,7 +89,7 @@ val DEPENDENCIES = listOf( "io.opentracing:opentracing-api:0.33.0", "io.opentracing:opentracing-noop:0.33.0", "junit:junit:4.13.2", - "nl.jqno.equalsverifier:equalsverifier:3.19.1", + "nl.jqno.equalsverifier:equalsverifier:3.19.2", "org.awaitility:awaitility:4.3.0", "org.bouncycastle:bcpkix-jdk15on:1.70", "org.codehaus.mojo:animal-sniffer-annotations:1.24", From 000fd0f20919efbcb7e39e1ca493a246e0eb3dde Mon Sep 17 00:00:00 2001 From: Gregor Zeitlinger Date: Fri, 21 Mar 2025 18:40:16 +0100 Subject: [PATCH 875/901] add config model customizer (#7118) Co-authored-by: jack-berg <34418638+jack-berg@users.noreply.github.com> --- .../fileconfig/DeclarativeConfiguration.java | 13 +++++- .../DeclarativeConfigurationBuilder.java | 35 ++++++++++++++++ .../DeclarativeConfigurationCustomizer.java | 21 ++++++++++ ...rativeConfigurationCustomizerProvider.java | 19 +++++++++ .../DeclarativeConfigurationCreateTest.java | 36 +++++++++++++++- ...rativeConfigurationCustomizerProvider.java | 42 +++++++++++++++++++ ...DeclarativeConfigurationCustomizerProvider | 1 + 7 files changed, 164 insertions(+), 3 deletions(-) create mode 100644 sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/DeclarativeConfigurationBuilder.java create mode 100644 sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/DeclarativeConfigurationCustomizer.java create mode 100644 sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/DeclarativeConfigurationCustomizerProvider.java create mode 100644 sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/TestDeclarativeConfigurationCustomizerProvider.java create mode 100644 sdk-extensions/incubator/src/test/resources/META-INF/services/io.opentelemetry.sdk.extension.incubator.fileconfig.DeclarativeConfigurationCustomizerProvider diff --git a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/DeclarativeConfiguration.java b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/DeclarativeConfiguration.java index 673ced041fe..f19c85116ac 100644 --- a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/DeclarativeConfiguration.java +++ b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/DeclarativeConfiguration.java @@ -108,10 +108,19 @@ public static OpenTelemetrySdk create(OpenTelemetryConfigurationModel configurat */ public static OpenTelemetrySdk create( OpenTelemetryConfigurationModel configurationModel, ComponentLoader componentLoader) { + SpiHelper spiHelper = SpiHelper.create(componentLoader); + + DeclarativeConfigurationBuilder builder = new DeclarativeConfigurationBuilder(); + + for (DeclarativeConfigurationCustomizerProvider provider : + spiHelper.loadOrdered(DeclarativeConfigurationCustomizerProvider.class)) { + provider.customize(builder); + } + return createAndMaybeCleanup( OpenTelemetryConfigurationFactory.getInstance(), - SpiHelper.create(componentLoader), - configurationModel); + spiHelper, + builder.customizeModel(configurationModel)); } /** diff --git a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/DeclarativeConfigurationBuilder.java b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/DeclarativeConfigurationBuilder.java new file mode 100644 index 00000000000..c96aa629fe9 --- /dev/null +++ b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/DeclarativeConfigurationBuilder.java @@ -0,0 +1,35 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.sdk.extension.incubator.fileconfig; + +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.OpenTelemetryConfigurationModel; +import java.util.function.Function; + +/** Builder for the declarative configuration. */ +public class DeclarativeConfigurationBuilder implements DeclarativeConfigurationCustomizer { + private Function + modelCustomizer = Function.identity(); + + @Override + public void addModelCustomizer( + Function customizer) { + modelCustomizer = mergeCustomizer(modelCustomizer, customizer); + } + + private static Function mergeCustomizer( + Function first, Function second) { + return (I configured) -> { + O1 firstResult = first.apply(configured); + return second.apply(firstResult); + }; + } + + /** Customize the configuration model. */ + public OpenTelemetryConfigurationModel customizeModel( + OpenTelemetryConfigurationModel configurationModel) { + return modelCustomizer.apply(configurationModel); + } +} diff --git a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/DeclarativeConfigurationCustomizer.java b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/DeclarativeConfigurationCustomizer.java new file mode 100644 index 00000000000..3e8e327355c --- /dev/null +++ b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/DeclarativeConfigurationCustomizer.java @@ -0,0 +1,21 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.sdk.extension.incubator.fileconfig; + +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.OpenTelemetryConfigurationModel; +import java.util.function.Function; + +/** A service provider interface (SPI) for customizing declarative configuration. */ +public interface DeclarativeConfigurationCustomizer { + /** + * Method invoked when configuring the SDK to allow further customization of the declarative + * configuration. + * + * @param customizer the customizer to add + */ + void addModelCustomizer( + Function customizer); +} diff --git a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/DeclarativeConfigurationCustomizerProvider.java b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/DeclarativeConfigurationCustomizerProvider.java new file mode 100644 index 00000000000..e5ec52c60d4 --- /dev/null +++ b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/DeclarativeConfigurationCustomizerProvider.java @@ -0,0 +1,19 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.sdk.extension.incubator.fileconfig; + +import io.opentelemetry.sdk.autoconfigure.spi.Ordered; + +/** A service provider interface (SPI) for customizing declarative configuration. */ +public interface DeclarativeConfigurationCustomizerProvider extends Ordered { + /** + * Method invoked when configuring the SDK to allow further customization of the declarative + * configuration. + * + * @param customizer the customizer to add + */ + void customize(DeclarativeConfigurationCustomizer customizer); +} diff --git a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/DeclarativeConfigurationCreateTest.java b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/DeclarativeConfigurationCreateTest.java index 5b0e2fbca1b..262270670c4 100644 --- a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/DeclarativeConfigurationCreateTest.java +++ b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/DeclarativeConfigurationCreateTest.java @@ -14,6 +14,11 @@ import io.github.netmikey.logunit.api.LogCapturer; import io.opentelemetry.api.incubator.config.DeclarativeConfigException; import io.opentelemetry.internal.testing.CleanupExtension; +import io.opentelemetry.sdk.OpenTelemetrySdk; +import io.opentelemetry.sdk.autoconfigure.internal.SpiHelper; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.OpenTelemetryConfigurationModel; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.SpanProcessorModel; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.TracerProviderModel; import java.io.ByteArrayInputStream; import java.io.File; import java.io.IOException; @@ -22,6 +27,7 @@ import java.nio.file.Files; import java.nio.file.Path; import java.security.cert.CertificateEncodingException; +import java.util.Collections; import java.util.Objects; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.RegisterExtension; @@ -61,7 +67,7 @@ void parseAndCreate_Examples(@TempDir Path tempDir) tempDir, "clientCertificate.cert", clientTls.certificate().getEncoded()); File examplesDir = new File(System.getenv("CONFIG_EXAMPLE_DIR")); - assertThat(examplesDir.isDirectory()).isTrue(); + assertThat(examplesDir).isDirectory(); for (File example : Objects.requireNonNull(examplesDir.listFiles())) { // Skip anchors.yaml because support for merge (i.e. "<<: *anchor") was explicitly removed in @@ -151,4 +157,32 @@ void parseAndCreate_EmptyComponentProviderConfig() { new ByteArrayInputStream(yaml.getBytes(StandardCharsets.UTF_8)))) .doesNotThrowAnyException(); } + + @Test + void create_ModelCustomizer() { + OpenTelemetryConfigurationModel model = new OpenTelemetryConfigurationModel(); + model.withFileFormat("0.3"); + model.withTracerProvider( + new TracerProviderModel() + .withProcessors( + Collections.singletonList( + new SpanProcessorModel().withAdditionalProperty("test", null)))); + OpenTelemetrySdk sdk = + DeclarativeConfiguration.create( + model, + // customizer is TestDeclarativeConfigurationCustomizerProvider + SpiHelper.serviceComponentLoader( + DeclarativeConfigurationCreateTest.class.getClassLoader())); + assertThat(sdk.toString()) + .contains( + "resource=Resource{schemaUrl=null, attributes={" + + "color=\"blue\", " + + "foo=\"bar\", " + + "order=\"second\", " + + "service.name=\"unknown_service:java\", " + + "shape=\"square\", " + + "telemetry.sdk.language=\"java\", " + + "telemetry.sdk.name=\"opentelemetry\", " + + "telemetry.sdk.version=\""); + } } diff --git a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/TestDeclarativeConfigurationCustomizerProvider.java b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/TestDeclarativeConfigurationCustomizerProvider.java new file mode 100644 index 00000000000..33187b73ba2 --- /dev/null +++ b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/TestDeclarativeConfigurationCustomizerProvider.java @@ -0,0 +1,42 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.sdk.extension.incubator.fileconfig; + +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.AttributeNameValueModel; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.ResourceModel; +import java.util.ArrayList; +import java.util.List; + +public class TestDeclarativeConfigurationCustomizerProvider + implements DeclarativeConfigurationCustomizerProvider { + @Override + public void customize(DeclarativeConfigurationCustomizer customizer) { + customizer.addModelCustomizer( + model -> { + ResourceModel resource = model.getResource(); + if (resource == null) { + resource = new ResourceModel(); + model.withResource(resource); + } + List attributes = resource.getAttributes(); + if (attributes == null) { + attributes = new ArrayList<>(); + resource.withAttributes(attributes); + } + attributes.add( + new AttributeNameValueModel() + .withName("foo") + .withType(AttributeNameValueModel.Type.STRING) + .withValue("bar")); + attributes.add( + new AttributeNameValueModel() + .withName("color") + .withType(AttributeNameValueModel.Type.STRING) + .withValue("blue")); + return model; + }); + } +} diff --git a/sdk-extensions/incubator/src/test/resources/META-INF/services/io.opentelemetry.sdk.extension.incubator.fileconfig.DeclarativeConfigurationCustomizerProvider b/sdk-extensions/incubator/src/test/resources/META-INF/services/io.opentelemetry.sdk.extension.incubator.fileconfig.DeclarativeConfigurationCustomizerProvider new file mode 100644 index 00000000000..f60ca4e082e --- /dev/null +++ b/sdk-extensions/incubator/src/test/resources/META-INF/services/io.opentelemetry.sdk.extension.incubator.fileconfig.DeclarativeConfigurationCustomizerProvider @@ -0,0 +1 @@ +io.opentelemetry.sdk.extension.incubator.fileconfig.TestDeclarativeConfigurationCustomizerProvider From 747368a94bcfadd9a44117ae44d5a5d352969761 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 22 Mar 2025 15:07:47 -0700 Subject: [PATCH 876/901] fix(deps): update armeriaversion to v1.32.3 (#7197) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- dependencyManagement/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index 735e81b6311..ae9dcb2fa25 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -36,7 +36,7 @@ val slf4jVersion = "2.0.17" val opencensusVersion = "0.31.1" val prometheusClientVersion = "0.16.0" val prometheusServerVersion = "1.3.6" -val armeriaVersion = "1.32.0" +val armeriaVersion = "1.32.3" val junitVersion = "5.12.1" val DEPENDENCIES = listOf( From 3ac1f9f695d3c2cd160263229fa0e27a1d431225 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 22 Mar 2025 15:12:09 -0700 Subject: [PATCH 877/901] fix(deps): update dependency com.toasttab.android:gummy-bears-api-23 to v0.12.0 (#7204) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- animal-sniffer-signature/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/animal-sniffer-signature/build.gradle.kts b/animal-sniffer-signature/build.gradle.kts index f9f070f24e7..f9e67347a07 100644 --- a/animal-sniffer-signature/build.gradle.kts +++ b/animal-sniffer-signature/build.gradle.kts @@ -27,7 +27,7 @@ configurations.add(signatureJarClasspath) configurations.add(generatedSignature) dependencies { - signature("com.toasttab.android:gummy-bears-api-23:0.10.0@signature") + signature("com.toasttab.android:gummy-bears-api-23:0.12.0@signature") signatureJar("com.android.tools:desugar_jdk_libs") } From cc7b268cec1e1517651c4a741834c4d081e01a96 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 22 Mar 2025 15:12:27 -0700 Subject: [PATCH 878/901] fix(deps): update dependency com.google.guava:guava to v33.4.5-jre (#7212) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- buildSrc/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts index 4d7a859c9cf..4aaeab51789 100644 --- a/buildSrc/build.gradle.kts +++ b/buildSrc/build.gradle.kts @@ -55,7 +55,7 @@ dependencies { // When updating, update above in plugins too implementation("com.diffplug.spotless:spotless-plugin-gradle:7.0.2") // Needed for japicmp but not automatically brought in for some reason. - implementation("com.google.guava:guava:33.4.0-jre") + implementation("com.google.guava:guava:33.4.5-jre") implementation("com.gradle.develocity:com.gradle.develocity.gradle.plugin:3.19.2") implementation("com.squareup:javapoet:1.13.0") implementation("com.squareup.wire:wire-compiler") From 9e0efd4267b544e82736fe72538d783d80bb50a4 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 22 Mar 2025 15:12:43 -0700 Subject: [PATCH 879/901] fix(deps): update dependency org.jetbrains.kotlin:kotlin-gradle-plugin to v2.1.20 (#7215) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- buildSrc/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts index 4aaeab51789..4b2a09d67a3 100644 --- a/buildSrc/build.gradle.kts +++ b/buildSrc/build.gradle.kts @@ -66,7 +66,7 @@ dependencies { implementation("me.champeau.jmh:jmh-gradle-plugin:0.7.3") implementation("net.ltgt.gradle:gradle-errorprone-plugin:4.1.0") implementation("net.ltgt.gradle:gradle-nullaway-plugin:2.2.0") - implementation("org.jetbrains.kotlin:kotlin-gradle-plugin:2.1.10") + implementation("org.jetbrains.kotlin:kotlin-gradle-plugin:2.1.20") implementation("org.owasp:dependency-check-gradle:12.1.0") implementation("ru.vyarus:gradle-animalsniffer-plugin:2.0.0") } From 3c12e3af1ac433a5ceac8fa68ab8f39b8f5954eb Mon Sep 17 00:00:00 2001 From: Yuriy Holinko Date: Tue, 25 Mar 2025 18:20:12 +0200 Subject: [PATCH 880/901] Refine delay jitter for exponential backoff (#7206) --- .../sender/jdk/internal/JdkHttpSender.java | 23 +++---- .../okhttp/internal/RetryInterceptor.java | 64 +++++++++---------- .../okhttp/internal/RetryInterceptorTest.java | 64 +++++++++++++------ 3 files changed, 84 insertions(+), 67 deletions(-) diff --git a/exporters/sender/jdk/src/main/java/io/opentelemetry/exporter/sender/jdk/internal/JdkHttpSender.java b/exporters/sender/jdk/src/main/java/io/opentelemetry/exporter/sender/jdk/internal/JdkHttpSender.java index 20d219edaf5..312149728af 100644 --- a/exporters/sender/jdk/src/main/java/io/opentelemetry/exporter/sender/jdk/internal/JdkHttpSender.java +++ b/exporters/sender/jdk/src/main/java/io/opentelemetry/exporter/sender/jdk/internal/JdkHttpSender.java @@ -213,9 +213,11 @@ HttpResponse sendInternal(Marshaler marshaler) throws IOException { do { if (attempt > 0) { // Compute and sleep for backoff - long upperBoundNanos = Math.min(nextBackoffNanos, retryPolicy.getMaxBackoff().toNanos()); - long backoffNanos = ThreadLocalRandom.current().nextLong(upperBoundNanos); - nextBackoffNanos = (long) (nextBackoffNanos * retryPolicy.getBackoffMultiplier()); + long currentBackoffNanos = + Math.min(nextBackoffNanos, retryPolicy.getMaxBackoff().toNanos()); + long backoffNanos = + (long) (ThreadLocalRandom.current().nextDouble(0.8d, 1.2d) * currentBackoffNanos); + nextBackoffNanos = (long) (currentBackoffNanos * retryPolicy.getBackoffMultiplier()); try { TimeUnit.NANOSECONDS.sleep(backoffNanos); } catch (InterruptedException e) { @@ -227,16 +229,11 @@ HttpResponse sendInternal(Marshaler marshaler) throws IOException { break; } } - - attempt++; + httpResponse = null; + exception = null; requestBuilder.timeout(Duration.ofNanos(timeoutNanos - (System.nanoTime() - startTimeNanos))); try { httpResponse = sendRequest(requestBuilder, byteBufferPool); - } catch (IOException e) { - exception = e; - } - - if (httpResponse != null) { boolean retryable = retryableStatusCodes.contains(httpResponse.statusCode()); if (logger.isLoggable(Level.FINER)) { logger.log( @@ -251,8 +248,8 @@ HttpResponse sendInternal(Marshaler marshaler) throws IOException { if (!retryable) { return httpResponse; } - } - if (exception != null) { + } catch (IOException e) { + exception = e; boolean retryable = retryExceptionPredicate.test(exception); if (logger.isLoggable(Level.FINER)) { logger.log( @@ -268,7 +265,7 @@ HttpResponse sendInternal(Marshaler marshaler) throws IOException { throw exception; } } - } while (attempt < retryPolicy.getMaxAttempts()); + } while (++attempt < retryPolicy.getMaxAttempts()); if (httpResponse != null) { return httpResponse; diff --git a/exporters/sender/okhttp/src/main/java/io/opentelemetry/exporter/sender/okhttp/internal/RetryInterceptor.java b/exporters/sender/okhttp/src/main/java/io/opentelemetry/exporter/sender/okhttp/internal/RetryInterceptor.java index 7c3a3bfab80..988c8277c26 100644 --- a/exporters/sender/okhttp/src/main/java/io/opentelemetry/exporter/sender/okhttp/internal/RetryInterceptor.java +++ b/exporters/sender/okhttp/src/main/java/io/opentelemetry/exporter/sender/okhttp/internal/RetryInterceptor.java @@ -18,6 +18,7 @@ import java.util.concurrent.TimeUnit; import java.util.function.Function; import java.util.function.Predicate; +import java.util.function.Supplier; import java.util.logging.Level; import java.util.logging.Logger; import okhttp3.Interceptor; @@ -37,7 +38,7 @@ public final class RetryInterceptor implements Interceptor { private final Function isRetryable; private final Predicate retryExceptionPredicate; private final Sleeper sleeper; - private final BoundedLongGenerator randomLong; + private final Supplier randomJitter; /** Constructs a new retrier. */ public RetryInterceptor(RetryPolicy retryPolicy, Function isRetryable) { @@ -48,7 +49,7 @@ public RetryInterceptor(RetryPolicy retryPolicy, Function isR ? RetryInterceptor::isRetryableException : retryPolicy.getRetryExceptionPredicate(), TimeUnit.NANOSECONDS::sleep, - bound -> ThreadLocalRandom.current().nextLong(bound)); + () -> ThreadLocalRandom.current().nextDouble(0.8d, 1.2d)); } // Visible for testing @@ -57,12 +58,12 @@ public RetryInterceptor(RetryPolicy retryPolicy, Function isR Function isRetryable, Predicate retryExceptionPredicate, Sleeper sleeper, - BoundedLongGenerator randomLong) { + Supplier randomJitter) { this.retryPolicy = retryPolicy; this.isRetryable = isRetryable; this.retryExceptionPredicate = retryExceptionPredicate; this.sleeper = sleeper; - this.randomLong = randomLong; + this.randomJitter = randomJitter; } @Override @@ -75,9 +76,10 @@ public Response intercept(Chain chain) throws IOException { if (attempt > 0) { // Compute and sleep for backoff // https://github.com/grpc/proposal/blob/master/A6-client-retries.md#exponential-backoff - long upperBoundNanos = Math.min(nextBackoffNanos, retryPolicy.getMaxBackoff().toNanos()); - long backoffNanos = randomLong.get(upperBoundNanos); - nextBackoffNanos = (long) (nextBackoffNanos * retryPolicy.getBackoffMultiplier()); + long currentBackoffNanos = + Math.min(nextBackoffNanos, retryPolicy.getMaxBackoff().toNanos()); + long backoffNanos = (long) (randomJitter.get() * currentBackoffNanos); + nextBackoffNanos = (long) (currentBackoffNanos * retryPolicy.getBackoffMultiplier()); try { sleeper.sleep(backoffNanos); } catch (InterruptedException e) { @@ -88,31 +90,31 @@ public Response intercept(Chain chain) throws IOException { if (response != null) { response.close(); } + exception = null; } - - attempt++; try { response = chain.proceed(chain.request()); + if (response != null) { + boolean retryable = Boolean.TRUE.equals(isRetryable.apply(response)); + if (logger.isLoggable(Level.FINER)) { + logger.log( + Level.FINER, + "Attempt " + + attempt + + " returned " + + (retryable ? "retryable" : "non-retryable") + + " response: " + + responseStringRepresentation(response)); + } + if (!retryable) { + return response; + } + } else { + throw new NullPointerException("response cannot be null."); + } } catch (IOException e) { exception = e; - } - if (response != null) { - boolean retryable = Boolean.TRUE.equals(isRetryable.apply(response)); - if (logger.isLoggable(Level.FINER)) { - logger.log( - Level.FINER, - "Attempt " - + attempt - + " returned " - + (retryable ? "retryable" : "non-retryable") - + " response: " - + responseStringRepresentation(response)); - } - if (!retryable) { - return response; - } - } - if (exception != null) { + response = null; boolean retryable = retryExceptionPredicate.test(exception); if (logger.isLoggable(Level.FINER)) { logger.log( @@ -128,8 +130,7 @@ public Response intercept(Chain chain) throws IOException { throw exception; } } - - } while (attempt < retryPolicy.getMaxAttempts()); + } while (++attempt < retryPolicy.getMaxAttempts()); if (response != null) { return response; @@ -172,11 +173,6 @@ static boolean isRetryableException(IOException e) { return false; } - // Visible for testing - interface BoundedLongGenerator { - long get(long bound); - } - // Visible for testing interface Sleeper { void sleep(long delayNanos) throws InterruptedException; diff --git a/exporters/sender/okhttp/src/test/java/io/opentelemetry/exporter/sender/okhttp/internal/RetryInterceptorTest.java b/exporters/sender/okhttp/src/test/java/io/opentelemetry/exporter/sender/okhttp/internal/RetryInterceptorTest.java index 3ba83683359..ca2ad7d5966 100644 --- a/exporters/sender/okhttp/src/test/java/io/opentelemetry/exporter/sender/okhttp/internal/RetryInterceptorTest.java +++ b/exporters/sender/okhttp/src/test/java/io/opentelemetry/exporter/sender/okhttp/internal/RetryInterceptorTest.java @@ -9,8 +9,9 @@ import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyLong; +import static org.mockito.Mockito.doAnswer; import static org.mockito.Mockito.doNothing; -import static org.mockito.Mockito.doThrow; +import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.verify; @@ -32,9 +33,11 @@ import java.time.Duration; import java.util.concurrent.TimeUnit; import java.util.function.Predicate; +import java.util.function.Supplier; import java.util.logging.Level; import java.util.logging.Logger; import java.util.stream.Stream; +import okhttp3.Interceptor; import okhttp3.OkHttpClient; import okhttp3.Request; import okhttp3.Response; @@ -47,7 +50,9 @@ import org.junit.jupiter.params.provider.MethodSource; import org.junit.jupiter.params.provider.ValueSource; import org.mockito.Mock; +import org.mockito.invocation.InvocationOnMock; import org.mockito.junit.jupiter.MockitoExtension; +import org.mockito.stubbing.Answer; @ExtendWith(MockitoExtension.class) class RetryInterceptorTest { @@ -55,7 +60,7 @@ class RetryInterceptorTest { @RegisterExtension static final MockWebServerExtension server = new MockWebServerExtension(); @Mock private RetryInterceptor.Sleeper sleeper; - @Mock private RetryInterceptor.BoundedLongGenerator random; + @Mock private Supplier random; private Predicate retryExceptionPredicate; private RetryInterceptor retrier; @@ -91,6 +96,24 @@ public boolean test(IOException e) { client = new OkHttpClient.Builder().addInterceptor(retrier).build(); } + @Test + void noRetryOnNullResponse() throws IOException { + Interceptor.Chain chain = mock(Interceptor.Chain.class); + when(chain.proceed(any())).thenReturn(null); + when(chain.request()) + .thenReturn(new Request.Builder().url(server.httpUri().toString()).build()); + assertThatThrownBy( + () -> { + retrier.intercept(chain); + }) + .isInstanceOf(NullPointerException.class) + .hasMessage("response cannot be null."); + + verifyNoInteractions(retryExceptionPredicate); + verifyNoInteractions(random); + verifyNoInteractions(sleeper); + } + @Test void noRetry() throws Exception { server.enqueue(HttpResponse.of(HttpStatus.OK)); @@ -109,17 +132,8 @@ void noRetry() throws Exception { @ValueSource(ints = {5, 6}) void backsOff(int attempts) throws Exception { succeedOnAttempt(attempts); - - // Will backoff 4 times - when(random.get((long) (TimeUnit.SECONDS.toNanos(1) * Math.pow(1.6, 0)))).thenReturn(100L); - when(random.get((long) (TimeUnit.SECONDS.toNanos(1) * Math.pow(1.6, 1)))).thenReturn(50L); - // Capped - when(random.get(TimeUnit.SECONDS.toNanos(2))).thenReturn(500L).thenReturn(510L); - - doNothing().when(sleeper).sleep(100); - doNothing().when(sleeper).sleep(50); - doNothing().when(sleeper).sleep(500); - doNothing().when(sleeper).sleep(510); + when(random.get()).thenReturn(1.0d); + doNothing().when(sleeper).sleep(anyLong()); try (Response response = sendRequest()) { if (attempts <= 5) { @@ -139,16 +153,26 @@ void interrupted() throws Exception { succeedOnAttempt(5); // Backs off twice, second is interrupted - when(random.get((long) (TimeUnit.SECONDS.toNanos(1) * Math.pow(1.6, 0)))).thenReturn(100L); - when(random.get((long) (TimeUnit.SECONDS.toNanos(1) * Math.pow(1.6, 1)))).thenReturn(50L); + when(random.get()).thenReturn(1.0d).thenReturn(1.0d); + doAnswer( + new Answer() { + int counter = 0; - doNothing().when(sleeper).sleep(100); - doThrow(new InterruptedException()).when(sleeper).sleep(50); + @Override + public Void answer(InvocationOnMock invocation) throws Throwable { + if (counter++ == 1) { + throw new InterruptedException(); + } + return null; + } + }) + .when(sleeper) + .sleep(anyLong()); try (Response response = sendRequest()) { assertThat(response.isSuccessful()).isFalse(); } - + verify(sleeper, times(2)).sleep(anyLong()); for (int i = 0; i < 2; i++) { server.takeRequest(0, TimeUnit.NANOSECONDS); } @@ -157,7 +181,7 @@ void interrupted() throws Exception { @Test void connectTimeout() throws Exception { client = connectTimeoutClient(); - when(random.get(anyLong())).thenReturn(1L); + when(random.get()).thenReturn(1.0d); doNothing().when(sleeper).sleep(anyLong()); // Connecting to a non-routable IP address to trigger connection error @@ -174,7 +198,7 @@ void connectTimeout() throws Exception { @Test void connectException() throws Exception { client = connectTimeoutClient(); - when(random.get(anyLong())).thenReturn(1L); + when(random.get()).thenReturn(1.0d); doNothing().when(sleeper).sleep(anyLong()); // Connecting to localhost on an unused port address to trigger java.net.ConnectException From a1fed617427b3fa36e0042ea84aa9a5c9ced1ec7 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 25 Mar 2025 16:33:03 -0700 Subject: [PATCH 881/901] fix(deps): update dependency com.google.guava:guava-bom to v33.4.5-jre (#7213) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Co-authored-by: Jack Berg --- dependencyManagement/build.gradle.kts | 2 +- .../trace/jaeger/sampler/UpstreamGrpcService.java | 3 ++- .../sdk/trace/samplers/ParentBasedSamplerTest.java | 9 ++++++++- 3 files changed, 11 insertions(+), 3 deletions(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index ae9dcb2fa25..691a436bd33 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -14,7 +14,7 @@ val DEPENDENCY_BOMS = listOf( // by FOSSA for containing EPL-licensed) "com.fasterxml.jackson:jackson-bom:2.18.3", - "com.google.guava:guava-bom:33.4.0-jre", + "com.google.guava:guava-bom:33.4.5-jre", "com.google.protobuf:protobuf-bom:4.29.3", "com.squareup.okhttp3:okhttp-bom:4.12.0", "com.squareup.okio:okio-bom:3.10.2", // applies to transitive dependencies of okhttp diff --git a/sdk-extensions/jaeger-remote-sampler/src/main/java/io/opentelemetry/sdk/extension/trace/jaeger/sampler/UpstreamGrpcService.java b/sdk-extensions/jaeger-remote-sampler/src/main/java/io/opentelemetry/sdk/extension/trace/jaeger/sampler/UpstreamGrpcService.java index 49551df496f..2976ff1302c 100644 --- a/sdk-extensions/jaeger-remote-sampler/src/main/java/io/opentelemetry/sdk/extension/trace/jaeger/sampler/UpstreamGrpcService.java +++ b/sdk-extensions/jaeger-remote-sampler/src/main/java/io/opentelemetry/sdk/extension/trace/jaeger/sampler/UpstreamGrpcService.java @@ -12,6 +12,7 @@ import io.opentelemetry.exporter.internal.grpc.MarshalerServiceStub; import io.opentelemetry.sdk.common.CompletableResultCode; import java.time.Duration; +import java.util.Objects; import java.util.logging.Level; import java.util.logging.Logger; @@ -52,7 +53,7 @@ public SamplingStrategyResponseUnMarshaler execute( } try { - return Futures.getUnchecked(stub.export(exportRequest)); + return Objects.requireNonNull(Futures.getUnchecked(stub.export(exportRequest))); } catch (Throwable t) { Status status = Status.fromThrowable(t); diff --git a/sdk/trace/src/test/java/io/opentelemetry/sdk/trace/samplers/ParentBasedSamplerTest.java b/sdk/trace/src/test/java/io/opentelemetry/sdk/trace/samplers/ParentBasedSamplerTest.java index 5264fabfff9..0d7238c912c 100644 --- a/sdk/trace/src/test/java/io/opentelemetry/sdk/trace/samplers/ParentBasedSamplerTest.java +++ b/sdk/trace/src/test/java/io/opentelemetry/sdk/trace/samplers/ParentBasedSamplerTest.java @@ -410,6 +410,13 @@ void getDescription() { @Test void equals() { - EqualsVerifier.forClass(ParentBasedSampler.class).verify(); + EqualsVerifier.forClass(ParentBasedSampler.class) + .withNonnullFields( + "root", + "remoteParentSampled", + "remoteParentNotSampled", + "localParentSampled", + "localParentNotSampled") + .verify(); } } From 7b732c84981eb22d0b7d5f7cb2e0d0885bb49565 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 25 Mar 2025 20:21:42 -0700 Subject: [PATCH 882/901] fix(deps): update dependency com.google.guava:guava to v33.4.6-jre (#7222) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- buildSrc/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts index 4b2a09d67a3..8d50a09a5f4 100644 --- a/buildSrc/build.gradle.kts +++ b/buildSrc/build.gradle.kts @@ -55,7 +55,7 @@ dependencies { // When updating, update above in plugins too implementation("com.diffplug.spotless:spotless-plugin-gradle:7.0.2") // Needed for japicmp but not automatically brought in for some reason. - implementation("com.google.guava:guava:33.4.5-jre") + implementation("com.google.guava:guava:33.4.6-jre") implementation("com.gradle.develocity:com.gradle.develocity.gradle.plugin:3.19.2") implementation("com.squareup:javapoet:1.13.0") implementation("com.squareup.wire:wire-compiler") From 526137fd640d17eee4c1deeeb4249a1229631b81 Mon Sep 17 00:00:00 2001 From: jack-berg <34418638+jack-berg@users.noreply.github.com> Date: Tue, 25 Mar 2025 22:24:19 -0500 Subject: [PATCH 883/901] Add more attribute advice tests to show interaction with views (#7143) --- .../sdk/metrics/AttributesAdviceTest.java | 109 ++++++++++++++---- 1 file changed, 86 insertions(+), 23 deletions(-) diff --git a/sdk/metrics/src/testIncubating/java/io/opentelemetry/sdk/metrics/AttributesAdviceTest.java b/sdk/metrics/src/testIncubating/java/io/opentelemetry/sdk/metrics/AttributesAdviceTest.java index af6a746da00..f30a9204878 100644 --- a/sdk/metrics/src/testIncubating/java/io/opentelemetry/sdk/metrics/AttributesAdviceTest.java +++ b/sdk/metrics/src/testIncubating/java/io/opentelemetry/sdk/metrics/AttributesAdviceTest.java @@ -11,7 +11,7 @@ import static java.util.Arrays.asList; import static org.junit.jupiter.params.provider.Arguments.arguments; -import com.google.common.util.concurrent.AtomicDouble; +import io.opentelemetry.api.baggage.Baggage; import io.opentelemetry.api.common.AttributeKey; import io.opentelemetry.api.common.Attributes; import io.opentelemetry.api.incubator.metrics.ExtendedDoubleCounterBuilder; @@ -24,6 +24,7 @@ import io.opentelemetry.api.incubator.metrics.ExtendedLongUpDownCounterBuilder; import io.opentelemetry.api.metrics.DoubleCounter; import io.opentelemetry.api.metrics.DoubleCounterBuilder; +import io.opentelemetry.api.metrics.DoubleGauge; import io.opentelemetry.api.metrics.DoubleGaugeBuilder; import io.opentelemetry.api.metrics.DoubleHistogram; import io.opentelemetry.api.metrics.DoubleHistogramBuilder; @@ -31,11 +32,14 @@ import io.opentelemetry.api.metrics.DoubleUpDownCounterBuilder; import io.opentelemetry.api.metrics.LongCounter; import io.opentelemetry.api.metrics.LongCounterBuilder; +import io.opentelemetry.api.metrics.LongGauge; import io.opentelemetry.api.metrics.LongGaugeBuilder; import io.opentelemetry.api.metrics.LongHistogram; import io.opentelemetry.api.metrics.LongHistogramBuilder; import io.opentelemetry.api.metrics.LongUpDownCounter; import io.opentelemetry.api.metrics.LongUpDownCounterBuilder; +import io.opentelemetry.context.Scope; +import io.opentelemetry.sdk.metrics.internal.SdkMeterProviderUtil; import io.opentelemetry.sdk.testing.assertj.AbstractPointAssert; import io.opentelemetry.sdk.testing.assertj.DoublePointAssert; import io.opentelemetry.sdk.testing.assertj.HistogramPointAssert; @@ -43,8 +47,6 @@ import io.opentelemetry.sdk.testing.assertj.MetricAssert; import io.opentelemetry.sdk.testing.exporter.InMemoryMetricReader; import java.util.List; -import java.util.concurrent.atomic.AtomicLong; -import java.util.concurrent.atomic.AtomicReference; import java.util.function.Consumer; import java.util.stream.Stream; import javax.annotation.Nullable; @@ -140,6 +142,81 @@ void instrumentWithAdviceAndViews( equalTo(stringKey("key2"), "2"), equalTo(stringKey("key3"), "3")))); } + @ParameterizedTest + @ArgumentsSource(InstrumentsProvider.class) + void instrumentWithAdviceAndDescriptionViews( + InstrumentFactory instrumentFactory, PointsAssert> pointsAssert) { + InMemoryMetricReader reader = InMemoryMetricReader.create(); + // Register a view which sets a description. Since any matching view supersedes any instrument + // advice, the attribute advice is ignored and all attributes are recorded. + meterProvider = + SdkMeterProvider.builder() + .registerMetricReader(reader) + .registerView( + InstrumentSelector.builder().setName("test").build(), + View.builder().setDescription("description").build()) + .build(); + + Instrument instrument = + instrumentFactory.create( + meterProvider, "test", asList(stringKey("key1"), stringKey("key2"))); + instrument.record(1, ATTRIBUTES); + + assertThat(reader.collectAllMetrics()) + .satisfiesExactly( + metric -> + pointsAssert.hasPointSatisfying( + assertThat(metric), + point -> + point.hasAttributesSatisfyingExactly( + equalTo(stringKey("key1"), "1"), + equalTo(stringKey("key2"), "2"), + equalTo(stringKey("key3"), "3")))); + } + + @ParameterizedTest + @ArgumentsSource(InstrumentsProvider.class) + void instrumentWithAdviceAndBaggage( + InstrumentFactory instrumentFactory, PointsAssert> pointsAssert) { + InMemoryMetricReader reader = InMemoryMetricReader.create(); + SdkMeterProviderBuilder builder = SdkMeterProvider.builder(); + // Register a view which appends a baggage entry. Since any matching view supersedes any + // instrument advice, the attribute advice is ignored and all attributes + the baggage entry are + // recorded. + ViewBuilder viewBuilder = View.builder(); + SdkMeterProviderUtil.appendFilteredBaggageAttributes( + viewBuilder, name -> name.equals("baggage1")); + meterProvider = + builder + .registerMetricReader(reader) + .registerView(InstrumentSelector.builder().setName("*").build(), viewBuilder.build()) + .build(); + + Instrument instrument = + instrumentFactory.create( + meterProvider, "test", asList(stringKey("key1"), stringKey("key2"))); + try (Scope unused = + Baggage.current().toBuilder() + .put("baggage1", "value1") + .put("baggage2", "value2") + .build() + .makeCurrent()) { + instrument.record(1, ATTRIBUTES); + } + + assertThat(reader.collectAllMetrics()) + .satisfiesExactly( + metric -> + pointsAssert.hasPointSatisfying( + assertThat(metric), + point -> + point.hasAttributesSatisfyingExactly( + equalTo(stringKey("key1"), "1"), + equalTo(stringKey("key2"), "2"), + equalTo(stringKey("key3"), "3"), + equalTo(stringKey("baggage1"), "value1")))); + } + static final class InstrumentsProvider implements ArgumentsProvider { @Override @@ -189,15 +266,8 @@ public Stream provideArguments(ExtensionContext context) { ((ExtendedDoubleGaugeBuilder) doubleGaugeBuilder) .setAttributesAdvice(attributesAdvice); } - AtomicDouble valueRef = new AtomicDouble(); - AtomicReference attributesRef = new AtomicReference<>(); - doubleGaugeBuilder.buildWithCallback( - measurement -> - measurement.record(valueRef.doubleValue(), attributesRef.get())); - return (value, attributes) -> { - valueRef.set((double) value); - attributesRef.set(attributes); - }; + DoubleGauge gauge = doubleGaugeBuilder.build(); + return gauge::set; }, (PointsAssert) (metricAssert, assertions) -> @@ -207,21 +277,14 @@ public Stream provideArguments(ExtensionContext context) { arguments( (InstrumentFactory) (meterProvider, name, attributesAdvice) -> { - LongGaugeBuilder doubleGaugeBuilder = + LongGaugeBuilder longGaugeBuilder = meterProvider.get("meter").gaugeBuilder(name).ofLongs(); if (attributesAdvice != null) { - ((ExtendedLongGaugeBuilder) doubleGaugeBuilder) + ((ExtendedLongGaugeBuilder) longGaugeBuilder) .setAttributesAdvice(attributesAdvice); } - AtomicLong valueRef = new AtomicLong(); - AtomicReference attributesRef = new AtomicReference<>(); - doubleGaugeBuilder.buildWithCallback( - measurement -> - measurement.record(valueRef.longValue(), attributesRef.get())); - return (value, attributes) -> { - valueRef.set(value); - attributesRef.set(attributes); - }; + LongGauge gauge = longGaugeBuilder.build(); + return gauge::set; }, (PointsAssert) (metricAssert, assertions) -> From 9698d24fdfceb2eeeac54fb963ac062daeb0a5b1 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 26 Mar 2025 17:20:13 -0500 Subject: [PATCH 884/901] fix(deps): update dependency com.google.guava:guava-bom to v33.4.6-jre (#7223) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- dependencyManagement/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index 691a436bd33..f1b76fb707f 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -14,7 +14,7 @@ val DEPENDENCY_BOMS = listOf( // by FOSSA for containing EPL-licensed) "com.fasterxml.jackson:jackson-bom:2.18.3", - "com.google.guava:guava-bom:33.4.5-jre", + "com.google.guava:guava-bom:33.4.6-jre", "com.google.protobuf:protobuf-bom:4.29.3", "com.squareup.okhttp3:okhttp-bom:4.12.0", "com.squareup.okio:okio-bom:3.10.2", // applies to transitive dependencies of okhttp From e6f90f58ce82c861f91fdf7474914ac66939b28f Mon Sep 17 00:00:00 2001 From: Anton Rybochkin Date: Wed, 26 Mar 2025 23:21:13 +0100 Subject: [PATCH 885/901] Avoid linear queue.size() calls in span producers by storing queue size separately (#7141) Co-authored-by: Trask Stalnaker --- .../sdk/trace/internal/JcTools.java | 12 ++++++----- .../sdk/trace/export/BatchSpanProcessor.java | 20 +++++++++++-------- 2 files changed, 19 insertions(+), 13 deletions(-) diff --git a/sdk/trace-shaded-deps/src/main/java/io/opentelemetry/sdk/trace/internal/JcTools.java b/sdk/trace-shaded-deps/src/main/java/io/opentelemetry/sdk/trace/internal/JcTools.java index 06976ad13d5..fa009ebdc0f 100644 --- a/sdk/trace-shaded-deps/src/main/java/io/opentelemetry/sdk/trace/internal/JcTools.java +++ b/sdk/trace-shaded-deps/src/main/java/io/opentelemetry/sdk/trace/internal/JcTools.java @@ -64,21 +64,23 @@ public static long capacity(Queue queue) { * @throws IllegalArgumentException if maxExportBatchSize is negative */ @SuppressWarnings("unchecked") - public static void drain(Queue queue, int limit, Consumer consumer) { + public static int drain(Queue queue, int limit, Consumer consumer) { if (queue instanceof MessagePassingQueue) { - ((MessagePassingQueue) queue).drain(consumer::accept, limit); + return ((MessagePassingQueue) queue).drain(consumer::accept, limit); } else { - drainNonJcQueue(queue, limit, consumer); + return drainNonJcQueue(queue, limit, consumer); } } - private static void drainNonJcQueue( + private static int drainNonJcQueue( Queue queue, int maxExportBatchSize, Consumer consumer) { int polledCount = 0; T item; - while (polledCount++ < maxExportBatchSize && (item = queue.poll()) != null) { + while (polledCount < maxExportBatchSize && (item = queue.poll()) != null) { consumer.accept(item); + ++polledCount; } + return polledCount; } private JcTools() {} diff --git a/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/export/BatchSpanProcessor.java b/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/export/BatchSpanProcessor.java index f6093c5ae8f..cdedb5abb1c 100644 --- a/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/export/BatchSpanProcessor.java +++ b/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/export/BatchSpanProcessor.java @@ -173,6 +173,7 @@ private static final class Worker implements Runnable { private long nextExportTime; private final Queue queue; + private final AtomicInteger queueSize = new AtomicInteger(); // When waiting on the spans queue, exporter thread sets this atomic to the number of more // spans it needs before doing an export. Writer threads would then wait for the queue to reach // spansNeeded size before notifying the exporter thread about new entries. @@ -237,7 +238,7 @@ private void addSpan(ReadableSpan span) { if (!queue.offer(span)) { processedSpansCounter.add(1, droppedAttrs); } else { - if (queue.size() >= spansNeeded.get()) { + if (queueSize.incrementAndGet() >= spansNeeded.get()) { signal.offer(true); } } @@ -251,8 +252,7 @@ public void run() { if (flushRequested.get() != null) { flush(); } - JcTools.drain( - queue, maxExportBatchSize - batch.size(), span -> batch.add(span.toSpanData())); + drain(maxExportBatchSize - batch.size()); if (batch.size() >= maxExportBatchSize || System.nanoTime() >= nextExportTime) { exportCurrentBatch(); @@ -274,13 +274,17 @@ public void run() { } } + private int drain(int limit) { + int drained = JcTools.drain(queue, limit, span -> batch.add(span.toSpanData())); + queueSize.addAndGet(-drained); + return drained; + } + private void flush() { - int spansToFlush = queue.size(); + int spansToFlush = queueSize.get(); while (spansToFlush > 0) { - ReadableSpan span = queue.poll(); - assert span != null; - batch.add(span.toSpanData()); - spansToFlush--; + int drained = drain(maxExportBatchSize - batch.size()); + spansToFlush -= drained; if (batch.size() >= maxExportBatchSize) { exportCurrentBatch(); } From 2cf5f0128b726ea208e50e749c9915b813a5e72b Mon Sep 17 00:00:00 2001 From: jack-berg <34418638+jack-berg@users.noreply.github.com> Date: Thu, 27 Mar 2025 13:30:24 -0500 Subject: [PATCH 886/901] Fix declarative config xray todo (#7226) --- .github/renovate.json5 | 1 + dependencyManagement/build.gradle.kts | 2 +- sdk-extensions/incubator/build.gradle.kts | 4 +--- .../fileconfig/DeclarativeConfigurationCreateTest.java | 5 +---- 4 files changed, 4 insertions(+), 8 deletions(-) diff --git a/.github/renovate.json5 b/.github/renovate.json5 index a7e36d8773c..2056841ddb7 100644 --- a/.github/renovate.json5 +++ b/.github/renovate.json5 @@ -17,6 +17,7 @@ }, { "matchPackageNames": [ + "io.opentelemetry.contrib:opentelemetry-aws-xray-propagator", "io.opentelemetry.proto:opentelemetry-proto", "io.opentelemetry.semconv:opentelemetry-semconv-incubating" ], diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index f1b76fb707f..9b13223a8a0 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -83,7 +83,7 @@ val DEPENDENCIES = listOf( "eu.rekawek.toxiproxy:toxiproxy-java:2.1.7", "io.github.netmikey.logunit:logunit-jul:2.0.0", "io.jaegertracing:jaeger-client:1.8.1", - "io.opentelemetry.contrib:opentelemetry-aws-xray-propagator:1.39.0-alpha", + "io.opentelemetry.contrib:opentelemetry-aws-xray-propagator:1.45.0-alpha", "io.opentelemetry.semconv:opentelemetry-semconv-incubating:1.30.0-alpha", "io.opentelemetry.proto:opentelemetry-proto:1.5.0-alpha", "io.opentracing:opentracing-api:0.33.0", diff --git a/sdk-extensions/incubator/build.gradle.kts b/sdk-extensions/incubator/build.gradle.kts index 20e91bd2e5c..7b89d8e94ec 100644 --- a/sdk-extensions/incubator/build.gradle.kts +++ b/sdk-extensions/incubator/build.gradle.kts @@ -39,9 +39,7 @@ dependencies { testImplementation(project(":exporters:zipkin")) testImplementation(project(":sdk-extensions:jaeger-remote-sampler")) testImplementation(project(":extensions:trace-propagators")) - // As a part of the tests we check that we can parse examples without error. The https://github.com/open-telemetry/opentelemetry-configuration/blob/main/examples/kitchen-sink.yam contains a reference to the xray propagator - // TODO: add when updated to reflect new API locations - // testImplementation("io.opentelemetry.contrib:opentelemetry-aws-xray-propagator") + testImplementation("io.opentelemetry.contrib:opentelemetry-aws-xray-propagator") testImplementation("com.linecorp.armeria:armeria-junit5") testImplementation("com.google.guava:guava-testlib") diff --git a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/DeclarativeConfigurationCreateTest.java b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/DeclarativeConfigurationCreateTest.java index 262270670c4..d512ee9f6d3 100644 --- a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/DeclarativeConfigurationCreateTest.java +++ b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/DeclarativeConfigurationCreateTest.java @@ -96,10 +96,7 @@ void parseAndCreate_Examples(@TempDir Path tempDir) "client_certificate: .*\n", "client_certificate: " + clientCertificatePath.replace("\\", "\\\\") - + System.lineSeparator()) - // TODO: remove once updated ComponentProvider SPI contract implemented in - // https://github.com/open-telemetry/opentelemetry-java-contrib/tree/main/aws-xray-propagator - .replaceAll("xray,", ""); + + System.lineSeparator()); InputStream is = new ByteArrayInputStream(rewrittenExampleContent.getBytes(StandardCharsets.UTF_8)); From e46742d944c9916b4086197794f5d2c0d7b4bf46 Mon Sep 17 00:00:00 2001 From: Lauri Tulmin Date: Fri, 28 Mar 2025 18:17:29 +0200 Subject: [PATCH 887/901] Don't initialize DeclarativeConfiguration in incubator available test (#7227) --- .../autoconfigure/AutoConfiguredOpenTelemetrySdkBuilder.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/AutoConfiguredOpenTelemetrySdkBuilder.java b/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/AutoConfiguredOpenTelemetrySdkBuilder.java index 0e1586497a6..e12848f0d81 100644 --- a/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/AutoConfiguredOpenTelemetrySdkBuilder.java +++ b/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/AutoConfiguredOpenTelemetrySdkBuilder.java @@ -64,7 +64,10 @@ public final class AutoConfiguredOpenTelemetrySdkBuilder implements AutoConfigur static { boolean incubatorAvailable = false; try { - Class.forName("io.opentelemetry.sdk.extension.incubator.fileconfig.DeclarativeConfiguration"); + Class.forName( + "io.opentelemetry.sdk.extension.incubator.fileconfig.DeclarativeConfiguration", + false, + AutoConfiguredOpenTelemetrySdkBuilder.class.getClassLoader()); incubatorAvailable = true; } catch (ClassNotFoundException e) { // Not available From f2f990c81d0c25191d796cbc866c11f6983b343a Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 29 Mar 2025 12:29:01 -0700 Subject: [PATCH 888/901] fix(deps): update dependency com.uber.nullaway:nullaway to v0.12.6 (#7224) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- dependencyManagement/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index 9b13223a8a0..b03805a1c4a 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -78,7 +78,7 @@ val DEPENDENCIES = listOf( "com.google.guava:guava-beta-checker:1.0", "com.sun.net.httpserver:http:20070405", "com.tngtech.archunit:archunit-junit5:1.4.0", - "com.uber.nullaway:nullaway:0.12.4", + "com.uber.nullaway:nullaway:0.12.6", "edu.berkeley.cs.jqf:jqf-fuzz:1.7", // jqf-fuzz version 1.8+ requires Java 11+ "eu.rekawek.toxiproxy:toxiproxy-java:2.1.7", "io.github.netmikey.logunit:logunit-jul:2.0.0", From 22acb3e8ecd075659ecfce2e208645b10d30e77f Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sun, 30 Mar 2025 17:48:44 -0700 Subject: [PATCH 889/901] fix(deps): update dependency checkstyle to v10.22.0 (#7228) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- buildSrc/src/main/kotlin/otel.java-conventions.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/buildSrc/src/main/kotlin/otel.java-conventions.gradle.kts b/buildSrc/src/main/kotlin/otel.java-conventions.gradle.kts index ea6230fda36..7ae4951bf94 100644 --- a/buildSrc/src/main/kotlin/otel.java-conventions.gradle.kts +++ b/buildSrc/src/main/kotlin/otel.java-conventions.gradle.kts @@ -42,7 +42,7 @@ java { checkstyle { configDirectory.set(file("$rootDir/buildscripts/")) - toolVersion = "10.21.4" + toolVersion = "10.22.0" isIgnoreFailures = false configProperties["rootDir"] = rootDir } From 0c6a04710b5c575ab3008cb53f5fe7344c0ce77c Mon Sep 17 00:00:00 2001 From: jack-berg <34418638+jack-berg@users.noreply.github.com> Date: Tue, 1 Apr 2025 11:29:49 -0500 Subject: [PATCH 890/901] Remove armeria log decorator to clean up build logs (#7232) --- .../testing/internal/AbstractHttpTelemetryExporterTest.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/AbstractHttpTelemetryExporterTest.java b/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/AbstractHttpTelemetryExporterTest.java index f59dc1ec3b4..705593c65fb 100644 --- a/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/AbstractHttpTelemetryExporterTest.java +++ b/exporters/otlp/testing-internal/src/main/java/io/opentelemetry/exporter/otlp/testing/internal/AbstractHttpTelemetryExporterTest.java @@ -22,7 +22,6 @@ import com.linecorp.armeria.server.HttpService; import com.linecorp.armeria.server.ServerBuilder; import com.linecorp.armeria.server.ServiceRequestContext; -import com.linecorp.armeria.server.logging.LoggingService; import com.linecorp.armeria.testing.junit5.server.SelfSignedCertificateExtension; import com.linecorp.armeria.testing.junit5.server.ServerExtension; import io.github.netmikey.logunit.api.LogCapturer; @@ -149,7 +148,8 @@ protected void configure(ServerBuilder sb) { sb.https(0); sb.tls(TlsKeyPair.of(certificate.privateKey(), certificate.certificate())); sb.tlsCustomizer(ssl -> ssl.trustManager(clientCertificate.certificate())); - sb.decorator(LoggingService.newDecorator()); + // Uncomment for detailed request / response logs from server + // sb.decorator(LoggingService.newDecorator()); } }; From 1500b0f3ba3c88d3abba2557657298e354f2ce39 Mon Sep 17 00:00:00 2001 From: jack-berg <34418638+jack-berg@users.noreply.github.com> Date: Tue, 1 Apr 2025 14:56:22 -0500 Subject: [PATCH 891/901] Fix jmh link (#7233) --- docs/jmh.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/jmh.md b/docs/jmh.md index 698e0174419..6a399072c18 100644 --- a/docs/jmh.md +++ b/docs/jmh.md @@ -1,7 +1,7 @@ # how to jmh -[jmh] (Java Benchmark Harness) is a tool for running benchmarks and reporting results. +[jmh](https://github.com/openjdk/jmh) is a tool for running benchmarks and reporting results. opentelemetry-java has a lot of micro benchmarks. They live inside `jmh` directories in the appropriate module. From e34049b74e0ba177c769352ef897c00e6c15f9f9 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 1 Apr 2025 18:27:58 -0700 Subject: [PATCH 892/901] fix(deps): update dependency io.opentelemetry.semconv:opentelemetry-semconv-incubating to v1.31.0-alpha (#7234) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- dependencyManagement/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index b03805a1c4a..3aad2354af4 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -84,7 +84,7 @@ val DEPENDENCIES = listOf( "io.github.netmikey.logunit:logunit-jul:2.0.0", "io.jaegertracing:jaeger-client:1.8.1", "io.opentelemetry.contrib:opentelemetry-aws-xray-propagator:1.45.0-alpha", - "io.opentelemetry.semconv:opentelemetry-semconv-incubating:1.30.0-alpha", + "io.opentelemetry.semconv:opentelemetry-semconv-incubating:1.31.0-alpha", "io.opentelemetry.proto:opentelemetry-proto:1.5.0-alpha", "io.opentracing:opentracing-api:0.33.0", "io.opentracing:opentracing-noop:0.33.0", From a48b48fa29b453394ac5ea09aa58ef4bc01a1c7e Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 2 Apr 2025 14:04:24 -0500 Subject: [PATCH 893/901] fix(deps): update dependency com.google.protobuf:protobuf-bom to v4.30.0 (#7173) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Co-authored-by: Jack Berg --- dependencyManagement/build.gradle.kts | 2 +- exporters/otlp/profiles/build.gradle.kts | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index 3aad2354af4..128b7f4b017 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -15,7 +15,7 @@ val DEPENDENCY_BOMS = listOf( "com.fasterxml.jackson:jackson-bom:2.18.3", "com.google.guava:guava-bom:33.4.6-jre", - "com.google.protobuf:protobuf-bom:4.29.3", + "com.google.protobuf:protobuf-bom:4.30.2", "com.squareup.okhttp3:okhttp-bom:4.12.0", "com.squareup.okio:okio-bom:3.10.2", // applies to transitive dependencies of okhttp "io.grpc:grpc-bom:1.71.0", diff --git a/exporters/otlp/profiles/build.gradle.kts b/exporters/otlp/profiles/build.gradle.kts index 069d8b97033..51979a5c8c6 100644 --- a/exporters/otlp/profiles/build.gradle.kts +++ b/exporters/otlp/profiles/build.gradle.kts @@ -17,6 +17,7 @@ dependencies { annotationProcessor("com.google.auto.value:auto-value") + testCompileOnly("com.google.guava:guava") testImplementation("com.fasterxml.jackson.core:jackson-databind") testImplementation("com.google.protobuf:protobuf-java-util") testImplementation("io.opentelemetry.proto:opentelemetry-proto") From dc44948c4f9bf41ff429b4cda2a55eb1da9c5f54 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 2 Apr 2025 14:22:33 -0500 Subject: [PATCH 894/901] fix(deps): update dependency checkstyle to v10.23.0 (#7237) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- buildSrc/src/main/kotlin/otel.java-conventions.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/buildSrc/src/main/kotlin/otel.java-conventions.gradle.kts b/buildSrc/src/main/kotlin/otel.java-conventions.gradle.kts index 7ae4951bf94..d1957a45ebd 100644 --- a/buildSrc/src/main/kotlin/otel.java-conventions.gradle.kts +++ b/buildSrc/src/main/kotlin/otel.java-conventions.gradle.kts @@ -42,7 +42,7 @@ java { checkstyle { configDirectory.set(file("$rootDir/buildscripts/")) - toolVersion = "10.22.0" + toolVersion = "10.23.0" isIgnoreFailures = false configProperties["rootDir"] = rootDir } From a7e92dfe81fb16050814bbdabd2ffc0674be82fd Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 2 Apr 2025 14:22:51 -0500 Subject: [PATCH 895/901] fix(deps): update dependency io.opentelemetry.semconv:opentelemetry-semconv-incubating to v1.32.0-alpha (#7240) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- dependencyManagement/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index 128b7f4b017..6d51ec0973b 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -84,7 +84,7 @@ val DEPENDENCIES = listOf( "io.github.netmikey.logunit:logunit-jul:2.0.0", "io.jaegertracing:jaeger-client:1.8.1", "io.opentelemetry.contrib:opentelemetry-aws-xray-propagator:1.45.0-alpha", - "io.opentelemetry.semconv:opentelemetry-semconv-incubating:1.31.0-alpha", + "io.opentelemetry.semconv:opentelemetry-semconv-incubating:1.32.0-alpha", "io.opentelemetry.proto:opentelemetry-proto:1.5.0-alpha", "io.opentracing:opentracing-api:0.33.0", "io.opentracing:opentracing-noop:0.33.0", From 8fe071afeec2e9463965f08374f5a457ae2e46f0 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 2 Apr 2025 15:33:01 -0500 Subject: [PATCH 896/901] fix(deps): update errorproneversion to v2.37.0 (#7211) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Co-authored-by: Jack Berg --- .../otel.errorprone-conventions.gradle.kts | 3 ++ .../customchecks/OtelInternalJavadocTest.java | 44 ++++++++++++++++--- .../InternalJavadocNegativeCases.java | 21 --------- .../InternalJavadocPositiveCases.java | 17 ------- dependencyManagement/build.gradle.kts | 2 +- 5 files changed, 43 insertions(+), 44 deletions(-) delete mode 100644 custom-checks/src/test/resources/io/opentelemetry/gradle/customchecks/internal/InternalJavadocNegativeCases.java delete mode 100644 custom-checks/src/test/resources/io/opentelemetry/gradle/customchecks/internal/InternalJavadocPositiveCases.java diff --git a/buildSrc/src/main/kotlin/otel.errorprone-conventions.gradle.kts b/buildSrc/src/main/kotlin/otel.errorprone-conventions.gradle.kts index be908aaae88..3943bc21bbe 100644 --- a/buildSrc/src/main/kotlin/otel.errorprone-conventions.gradle.kts +++ b/buildSrc/src/main/kotlin/otel.errorprone-conventions.gradle.kts @@ -87,6 +87,9 @@ tasks { // cognitive load is dubious. disable("YodaCondition") + // Text blocks are not supported in java 8 + disable("StringConcatToTextBlock") + if ((name.contains("Jmh") || name.contains("Test") || project.name.contains("testing-internal")) && !project.name.equals("custom-checks")) { // Allow underscore in test-type method names disable("MemberName") diff --git a/custom-checks/src/test/java/io/opentelemetry/gradle/customchecks/OtelInternalJavadocTest.java b/custom-checks/src/test/java/io/opentelemetry/gradle/customchecks/OtelInternalJavadocTest.java index ae26844ca72..34fbc46b6b6 100644 --- a/custom-checks/src/test/java/io/opentelemetry/gradle/customchecks/OtelInternalJavadocTest.java +++ b/custom-checks/src/test/java/io/opentelemetry/gradle/customchecks/OtelInternalJavadocTest.java @@ -11,14 +11,48 @@ class OtelInternalJavadocTest { @Test - void test() { - doTest("internal/InternalJavadocPositiveCases.java"); - doTest("internal/InternalJavadocNegativeCases.java"); + void positiveCases() { + CompilationTestHelper.newInstance(OtelInternalJavadoc.class, OtelInternalJavadocTest.class) + .addSourceLines( + "internal/InternalJavadocPositiveCases.java", + "/*", + " * Copyright The OpenTelemetry Authors", + " * SPDX-License-Identifier: Apache-2.0", + " */", + "package io.opentelemetry.gradle.customchecks.internal;", + "// BUG: Diagnostic contains: doesn't end with any of the applicable javadoc disclaimers", + "public class InternalJavadocPositiveCases {", + " // BUG: Diagnostic contains: doesn't end with any of the applicable javadoc disclaimers", + " public static class One {}", + " /** Doesn't have the disclaimer. */", + " // BUG: Diagnostic contains: doesn't end with any of the applicable javadoc disclaimers", + " public static class Two {}", + "}") + .doTest(); } - private static void doTest(String path) { + @Test + void negativeCases() { CompilationTestHelper.newInstance(OtelInternalJavadoc.class, OtelInternalJavadocTest.class) - .addSourceFile(path) + .addSourceLines( + "internal/InternalJavadocNegativeCases.java", + "/*", + " * Copyright The OpenTelemetry Authors", + " * SPDX-License-Identifier: Apache-2.0", + " */", + "package io.opentelemetry.gradle.customchecks.internal;", + "/**", + " * This class is internal and is hence not for public use. Its APIs are unstable and can change at", + " * any time.", + " */", + "public class InternalJavadocNegativeCases {", + " /**", + " * This class is internal and is hence not for public use. Its APIs are unstable and can change at", + " * any time.", + " */", + " public static class One {}", + " static class Two {}", + "}") .doTest(); } } diff --git a/custom-checks/src/test/resources/io/opentelemetry/gradle/customchecks/internal/InternalJavadocNegativeCases.java b/custom-checks/src/test/resources/io/opentelemetry/gradle/customchecks/internal/InternalJavadocNegativeCases.java deleted file mode 100644 index 973c13aa2a3..00000000000 --- a/custom-checks/src/test/resources/io/opentelemetry/gradle/customchecks/internal/InternalJavadocNegativeCases.java +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package io.opentelemetry.gradle.customchecks.internal; - -/** - * This class is internal and is hence not for public use. Its APIs are unstable and can change at - * any time. - */ -public class InternalJavadocNegativeCases { - - /** - * This class is internal and is hence not for public use. Its APIs are unstable and can change at - * any time. - */ - public static class One {} - - static class Two {} -} diff --git a/custom-checks/src/test/resources/io/opentelemetry/gradle/customchecks/internal/InternalJavadocPositiveCases.java b/custom-checks/src/test/resources/io/opentelemetry/gradle/customchecks/internal/InternalJavadocPositiveCases.java deleted file mode 100644 index f7a3042e4d6..00000000000 --- a/custom-checks/src/test/resources/io/opentelemetry/gradle/customchecks/internal/InternalJavadocPositiveCases.java +++ /dev/null @@ -1,17 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package io.opentelemetry.gradle.customchecks.internal; - -// BUG: Diagnostic contains: doesn't end with any of the applicable javadoc disclaimers -public class InternalJavadocPositiveCases { - - // BUG: Diagnostic contains: doesn't end with any of the applicable javadoc disclaimers - public static class One {} - - /** Doesn't have the disclaimer. */ - // BUG: Diagnostic contains: doesn't end with any of the applicable javadoc disclaimers - public static class Two {} -} diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index 6d51ec0973b..d3456720130 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -28,7 +28,7 @@ val DEPENDENCY_BOMS = listOf( ) val autoValueVersion = "1.11.0" -val errorProneVersion = "2.36.0" +val errorProneVersion = "2.37.0" val jmhVersion = "1.37" // Mockito 5.x.x requires Java 11 https://github.com/mockito/mockito/releases/tag/v5.0.0 val mockitoVersion = "4.11.0" From 184090914e0f0f47e7d68658cc3879ed1111a3d7 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 2 Apr 2025 15:39:40 -0500 Subject: [PATCH 897/901] fix(deps): update dependency jacoco to v0.8.13 (#7241) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- buildSrc/src/main/kotlin/otel.jacoco-conventions.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/buildSrc/src/main/kotlin/otel.jacoco-conventions.gradle.kts b/buildSrc/src/main/kotlin/otel.jacoco-conventions.gradle.kts index c99788df5fe..07c2f5e8d62 100644 --- a/buildSrc/src/main/kotlin/otel.jacoco-conventions.gradle.kts +++ b/buildSrc/src/main/kotlin/otel.jacoco-conventions.gradle.kts @@ -5,7 +5,7 @@ plugins { } jacoco { - toolVersion = "0.8.12" + toolVersion = "0.8.13" } // https://docs.gradle.org/current/samples/sample_jvm_multi_project_with_code_coverage.html From 4ecc0becfdb0529306cc198c6e300e59c2877e3d Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 4 Apr 2025 11:50:59 -0500 Subject: [PATCH 898/901] fix(deps): update dependency nl.jqno.equalsverifier:equalsverifier to v3.19.3 (#7247) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- dependencyManagement/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index d3456720130..d874c67a7e8 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -89,7 +89,7 @@ val DEPENDENCIES = listOf( "io.opentracing:opentracing-api:0.33.0", "io.opentracing:opentracing-noop:0.33.0", "junit:junit:4.13.2", - "nl.jqno.equalsverifier:equalsverifier:3.19.2", + "nl.jqno.equalsverifier:equalsverifier:3.19.3", "org.awaitility:awaitility:4.3.0", "org.bouncycastle:bcpkix-jdk15on:1.70", "org.codehaus.mojo:animal-sniffer-annotations:1.24", From 233e111a09ae03196d1005c43109f68b04844807 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 4 Apr 2025 11:53:05 -0500 Subject: [PATCH 899/901] fix(deps): update dependency io.netty:netty-bom to v4.2.0.final (#7244) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- dependencyManagement/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index d874c67a7e8..39b085f72f1 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -19,7 +19,7 @@ val DEPENDENCY_BOMS = listOf( "com.squareup.okhttp3:okhttp-bom:4.12.0", "com.squareup.okio:okio-bom:3.10.2", // applies to transitive dependencies of okhttp "io.grpc:grpc-bom:1.71.0", - "io.netty:netty-bom:4.1.119.Final", + "io.netty:netty-bom:4.2.0.Final", "io.zipkin.brave:brave-bom:6.1.0", "io.zipkin.reporter2:zipkin-reporter-bom:3.5.0", "org.assertj:assertj-bom:3.27.3", From b3126023dbbbe79a420a6ed4da623e7fad2b74a0 Mon Sep 17 00:00:00 2001 From: jack-berg <34418638+jack-berg@users.noreply.github.com> Date: Fri, 4 Apr 2025 14:14:04 -0500 Subject: [PATCH 900/901] Prepare for 1.49.0 release (#7248) --- CHANGELOG.md | 23 +++++++++++++++++++ .../OtlpHttpLogRecordExporterBuilder.java | 2 ++ .../OtlpHttpMetricExporterBuilder.java | 2 ++ .../trace/OtlpHttpSpanExporterBuilder.java | 2 ++ .../OtlpGrpcLogRecordExporterBuilder.java | 2 ++ .../OtlpGrpcMetricExporterBuilder.java | 2 ++ .../trace/OtlpGrpcSpanExporterBuilder.java | 2 ++ 7 files changed, 35 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 48869706d1a..95e9f1dd4e1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,29 @@ ## Unreleased +### SDK + +#### Trace + +* Avoid linear queue.size() calls in span producers by storing queue size separately + ([#7141](https://github.com/open-telemetry/opentelemetry-java/pull/7141)) + +#### Exporters + +* OTLP: Add support for setting exporter executor service + ([#7152](https://github.com/open-telemetry/opentelemetry-java/pull/7152)) +* OTLP: Refine delay jitter for exponential backoff + ([#7206](https://github.com/open-telemetry/opentelemetry-java/pull/7206)) + +#### Extensions + +* Autoconfigure: Remove support for otel.experimental.exporter.otlp.retry.enabled + ([#7200](https://github.com/open-telemetry/opentelemetry-java/pull/7200)) +* Autoconfigure: Add stable cardinality limit property otel.java.metrics.cardinality.limit + ([#7199](https://github.com/open-telemetry/opentelemetry-java/pull/7199)) +* Incubator: Add declarative config model customizer SPI + ([#7118](https://github.com/open-telemetry/opentelemetry-java/pull/7118)) + ## Version 1.48.0 (2025-03-07) ### API diff --git a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/logs/OtlpHttpLogRecordExporterBuilder.java b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/logs/OtlpHttpLogRecordExporterBuilder.java index e9cabecb870..1ba267c7235 100644 --- a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/logs/OtlpHttpLogRecordExporterBuilder.java +++ b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/logs/OtlpHttpLogRecordExporterBuilder.java @@ -243,6 +243,8 @@ public OtlpHttpLogRecordExporterBuilder setServiceClassLoader(ClassLoader servic *

      NOTE: By calling this method, you are opting into managing the lifecycle of the {@code * executorService}. {@link ExecutorService#shutdown()} will NOT be called when this exporter is * shutdown. + * + * @since 1.49.0 */ public OtlpHttpLogRecordExporterBuilder setExecutorService(ExecutorService executorService) { requireNonNull(executorService, "executorService"); diff --git a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/metrics/OtlpHttpMetricExporterBuilder.java b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/metrics/OtlpHttpMetricExporterBuilder.java index 3073e8fc12c..dc5d5c667b4 100644 --- a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/metrics/OtlpHttpMetricExporterBuilder.java +++ b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/metrics/OtlpHttpMetricExporterBuilder.java @@ -271,6 +271,8 @@ public OtlpHttpMetricExporterBuilder setServiceClassLoader(ClassLoader serviceCl *

      NOTE: By calling this method, you are opting into managing the lifecycle of the {@code * executorService}. {@link ExecutorService#shutdown()} will NOT be called when this exporter is * shutdown. + * + * @since 1.49.0 */ public OtlpHttpMetricExporterBuilder setExecutorService(ExecutorService executorService) { requireNonNull(executorService, "executorService"); diff --git a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/trace/OtlpHttpSpanExporterBuilder.java b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/trace/OtlpHttpSpanExporterBuilder.java index cdb262e4ca0..11bd7192db9 100644 --- a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/trace/OtlpHttpSpanExporterBuilder.java +++ b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/trace/OtlpHttpSpanExporterBuilder.java @@ -244,6 +244,8 @@ public OtlpHttpSpanExporterBuilder setServiceClassLoader(ClassLoader serviceClas *

      NOTE: By calling this method, you are opting into managing the lifecycle of the {@code * executorService}. {@link ExecutorService#shutdown()} will NOT be called when this exporter is * shutdown. + * + * @since 1.49.0 */ public OtlpHttpSpanExporterBuilder setExecutorService(ExecutorService executorService) { requireNonNull(executorService, "executorService"); diff --git a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/logs/OtlpGrpcLogRecordExporterBuilder.java b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/logs/OtlpGrpcLogRecordExporterBuilder.java index a42d991926b..a26629ed7f4 100644 --- a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/logs/OtlpGrpcLogRecordExporterBuilder.java +++ b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/logs/OtlpGrpcLogRecordExporterBuilder.java @@ -276,6 +276,8 @@ public OtlpGrpcLogRecordExporterBuilder setServiceClassLoader(ClassLoader servic *

      NOTE: By calling this method, you are opting into managing the lifecycle of the {@code * executorService}. {@link ExecutorService#shutdown()} will NOT be called when this exporter is * shutdown. + * + * @since 1.49.0 */ public OtlpGrpcLogRecordExporterBuilder setExecutorService(ExecutorService executorService) { requireNonNull(executorService, "executorService"); diff --git a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/metrics/OtlpGrpcMetricExporterBuilder.java b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/metrics/OtlpGrpcMetricExporterBuilder.java index a93ee626dde..d6062d26621 100644 --- a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/metrics/OtlpGrpcMetricExporterBuilder.java +++ b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/metrics/OtlpGrpcMetricExporterBuilder.java @@ -304,6 +304,8 @@ public OtlpGrpcMetricExporterBuilder setServiceClassLoader(ClassLoader serviceCl *

      NOTE: By calling this method, you are opting into managing the lifecycle of the {@code * executorService}. {@link ExecutorService#shutdown()} will NOT be called when this exporter is * shutdown. + * + * @since 1.49.0 */ public OtlpGrpcMetricExporterBuilder setExecutorService(ExecutorService executorService) { requireNonNull(executorService, "executorService"); diff --git a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/trace/OtlpGrpcSpanExporterBuilder.java b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/trace/OtlpGrpcSpanExporterBuilder.java index 1b2649df15b..d7452606d74 100644 --- a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/trace/OtlpGrpcSpanExporterBuilder.java +++ b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/trace/OtlpGrpcSpanExporterBuilder.java @@ -273,6 +273,8 @@ public OtlpGrpcSpanExporterBuilder setServiceClassLoader(ClassLoader serviceClas *

      NOTE: By calling this method, you are opting into managing the lifecycle of the {@code * executorService}. {@link ExecutorService#shutdown()} will NOT be called when this exporter is * shutdown. + * + * @since 1.49.0 */ public OtlpGrpcSpanExporterBuilder setExecutorService(ExecutorService executorService) { requireNonNull(executorService, "executorService"); From 85c0cf2ada06f807869665cd569e0c668dc39fdd Mon Sep 17 00:00:00 2001 From: OpenTelemetry Bot <107717825+opentelemetrybot@users.noreply.github.com> Date: Fri, 4 Apr 2025 13:20:44 -0700 Subject: [PATCH 901/901] [release/v1.49.x] Prepare release 1.49.0 (#7250) --- CHANGELOG.md | 2 +- version.gradle.kts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 95e9f1dd4e1..b48b4ab0eaf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,6 @@ # Changelog -## Unreleased +## Version 1.49.0 (2025-04-04) ### SDK diff --git a/version.gradle.kts b/version.gradle.kts index ea6092c8622..7ddd8b3d82f 100644 --- a/version.gradle.kts +++ b/version.gradle.kts @@ -1,4 +1,4 @@ -val snapshot = true +val snapshot = false allprojects { var ver = "1.49.0"